JSMpeg.VideoElement = (function(){ "use strict"; var VideoElement = function(element) { var url = element.dataset.url; if (!url) { throw ("VideoElement has no `data-url` attribute"); } // Setup the div container, canvas and play button var addStyles = function(element, styles) { for (var name in styles) { element.style[name] = styles[name]; } }; this.container = element; addStyles(this.container, { display: 'inline-block', position: 'relative', minWidth: '80px', minHeight: '80px' }); this.canvas = document.createElement('canvas'); this.canvas.width = 960; this.canvas.height = 540; addStyles(this.canvas, { display: 'block', width: '100%' }); this.container.appendChild(this.canvas); this.playButton = document.createElement('div'); this.playButton.innerHTML = VideoElement.PLAY_BUTTON; addStyles(this.playButton, { zIndex: 2, position: 'absolute', top: '0', bottom: '0', left: '0', right: '0', maxWidth: '75px', maxHeight: '75px', margin: 'auto', opacity: '0.7', cursor: 'pointer' }); this.container.appendChild(this.playButton); // Parse the data-options - we try to decode the values as json. This way // we can get proper boolean and number values. If JSON.parse() fails, // treat it as a string. var options = {canvas: this.canvas}; for (var option in element.dataset) { try { options[option] = JSON.parse(element.dataset[option]); } catch(err) { options[option] = element.dataset[option]; } } // Create the player instance this.player = new JSMpeg.Player(url, options); element.playerInstance = this.player; // Setup the poster element, if any if (options.poster && !options.autoplay && !this.player.options.streaming) { options.decodeFirstFrame = false; this.poster = new Image(); this.poster.src = options.poster; this.poster.addEventListener('load', this.posterLoaded) addStyles(this.poster, { display: 'block', zIndex: 1, position: 'absolute', top: 0, left: 0, bottom: 0, right: 0 }); this.container.appendChild(this.poster); } // Add the click handler if this video is pausable if (!this.player.options.streaming) { this.container.addEventListener('click', this.onClick.bind(this)); } // Hide the play button if this video immediately begins playing if (options.autoplay || this.player.options.streaming) { this.playButton.style.display = 'none'; } // Set up the unlock audio buton for iOS devices. iOS only allows us to // play audio after a user action has initiated playing. For autoplay or // streaming players we set up a muted speaker icon as the button. For all // others, we can simply use the play button. if (this.player.audioOut && !this.player.audioOut.unlocked) { var unlockAudioElement = this.container; if (options.autoplay || this.player.options.streaming) { this.unmuteButton = document.createElement('div'); this.unmuteButton.innerHTML = VideoElement.UNMUTE_BUTTON; addStyles(this.unmuteButton, { zIndex: 2, position: 'absolute', bottom: '10px', right: '20px', width: '75px', height: '75px', margin: 'auto', opacity: '0.7', cursor: 'pointer' }); this.container.appendChild(this.unmuteButton); unlockAudioElement = this.unmuteButton; } this.unlockAudioBound = this.onUnlockAudio.bind(this, unlockAudioElement); unlockAudioElement.addEventListener('touchstart', this.unlockAudioBound, false); unlockAudioElement.addEventListener('click', this.unlockAudioBound, true); } }; VideoElement.prototype.onUnlockAudio = function(element, ev) { if (this.unmuteButton) { ev.preventDefault(); ev.stopPropagation(); } this.player.audioOut.unlock(function(){ if (this.unmuteButton) { this.unmuteButton.style.display = 'none'; } element.removeEventListener('touchstart', this.unlockAudioBound); element.removeEventListener('click', this.unlockAudioBound); }.bind(this)); }; VideoElement.prototype.onClick = function(ev) { if (this.player.isPlaying) { this.player.pause(); this.playButton.style.display = 'block'; } else { this.player.play(); this.playButton.style.display = 'none'; if (this.poster) { this.poster.style.display = 'none'; } } }; VideoElement.PLAY_BUTTON = '' + '' + '' + ''; VideoElement.UNMUTE_BUTTON = '' + '' + '' + '' + '' + '' + ''; return VideoElement; })();