<!DOCTYPE HTML> <html i18n-values="dir:textdirection;"> <head> <meta charset="utf-8"> <title>Media Player</title> <style type="text/css"> body { overflow: hidden; background: black; } .error { left: 0; right: 0; color: white; bottom: 38px; position: absolute; } .glow { left: 0; right: 0; bottom: 30px; height: 8px; opacity: .4; position: absolute; background: -webkit-linear-gradient(transparent, white); } .audiotitle { left: 0; right: 0; text-align: center; position: absolute; color: white; top: 100px; } .progress { -webkit-appearance: sliderthumb-horizontal; position: absolute; background: transparent; left: 93px; right: 120px; bottom: -2px; height: 30px; z-index: 99999; border-left: 1px solid #424242; } .playercontrolsbox { bottom: 0; left: 0; height: 30px; right: 0; position: absolute; } .videocontrols { top: 0; left: 0; z-index: 999; height: 100%; opacity: .9; right: 0; position: absolute; background: -webkit-linear-gradient(#323232, #070707); } .sliderback { bottom: 12px; left: 93px; right: 120px; height: 5px; position: absolute; border-radius: 3px; background: -webkit-linear-gradient(#ced9fa, #e8ecf9); border: 1px solid #ffffff; } .sliderplayed { height: 100%; width:0; left: -1px; top: -1px; border-radius: 3px; border: 1px solid #9ca5b7; position: absolute; background: -webkit-linear-gradient(#4a5d84, #232c3d); } .sliderloaded { height: 100%; width:0; left: -1px; top: -1px; border-radius: 3px; position: absolute; background: #6a799a; border: 1px solid #ffffff; } .audiocontrols { top: 0; left: 0; z-index: 999; height: 100%; opacity: .9; right: 0; position: absolute; background: -webkit-linear-gradient(#323232, #070707); } .soundbutton { position: absolute; right: 30px; bottom: 0; border-left: 1px solid #424242; border-right: 1px solid black; } .soundiconhigh { background: url('shared/images/mediaplayer_vol_high.png'); } .soundiconmuted { background: url('shared/images/mediaplayer_vol_mute.png'); } .soundiconhigh, .soundiconmuted { background-repeat: no-repeat; background-position: 6px 8px; } .volume { position: absolute; bottom: 30px; height: 80px; width: 30px; right: 30px; z-index: 99999; background: black; background: -webkit-linear-gradient(#323232, #070707); } .fullscreen { position: absolute; right: 60px; bottom: 0; border-left: 1px solid #424242; border-right: 1px solid black; } .fullscreenicon { background: url('shared/images/mediaplayer_full_screen.png'); background-repeat: no-repeat; background-position: 6px 8px; } .fullscreenexiticon { background: url('shared/images/mediaplayer_full_screen_exit.png'); background-repeat: no-repeat; background-position: 6px 8px; } .volumeslider { -webkit-appearance: slider-vertical; position: absolute; left: 0; right: 0; bottom: 0; top: 0; } .playbutton { position: absolute; left: 30px; bottom: 0; border-left: 1px solid #424242; border-right: 1px solid black; } .playicon { background: url('shared/images/mediaplayer_play.png'); background-repeat: no-repeat; background-position: 9px 8px; } .pausebutton { position: absolute; left: 30px; bottom: 0; border-left: 1px solid #424242; border-right: 1px solid black; } .pauseicon { background: url('shared/images/mediaplayer_pause.png'); background-repeat: no-repeat; background-position: 9px 8px; } .prevbutton { position: absolute; left: 0; bottom: 0; border-right: 1px solid black; } .previcon { background: url('shared/images/mediaplayer_prev.png'); background-repeat: no-repeat; background-position: 6px 8px; } .playbackvideoelement { width: 100%; height: 100%; position: absolute; left: 0; top: 0; } .duration { right: 90px; color: white; position: absolute; top: 8.5px; font-size: .6em; height: 30px; } .playbackaudioelement { width: 100%; height: 100%; position: absolute; left: 0; top: 0; } .nextbutton { position: absolute; left: 60px; bottom: 0; border-left: 1px solid #424242; border-right: 1px solid black; } .nexticon { background: url('shared/images/mediaplayer_next.png'); background-repeat: no-repeat; background-position: 6px 8px; } .playlistbutton { position: absolute; right: 0; bottom: 0; border-left: 1px solid #424242; border-right: 1px solid black; } .playlisticon { background: url('shared/images/mediaplayer_playlist.png'); background-repeat: no-repeat; background-position: 6px 8px; } .controlbutton { z-index: 9999; cursor: pointer; width: 28px; height: 30px; } .controlbutton:hover { background: -webkit-linear-gradient(#6a7eac, #000); } .icon { width: 100%; height: 100%; z-index: 9999; } </style> <script src="shared/js/local_strings.js"></script> <script src="shared/js/media_common.js"></script> <script> function $(o) { return document.getElementById(o); } var videoPlaybackElement = null; var audioPlaybackElement = null; var currentPlaylist = null; var currentItem = -1; var savedVolumeValue = 0; var hideVolumeTimerId = 0; var localStrings; var fullScreen = false; /////////////////////////////////////////////////////////////////////////////// // Document Functions: /** * Window onload handler, sets up the page. */ function load() { document.body.addEventListener('dragover', function(e) { if (e.preventDefault) e.preventDefault(); }); document.body.addEventListener('drop', function(e) { if (e.preventDefault) e.preventDefault(); }); document.body.addEventListener('keydown', onkeydown); localStrings = new LocalStrings(); chrome.send('getCurrentPlaylist', []); } function onMediaProgress() { var element = getMediaElement(); var current = element.currentTime; var duration = element.duration; var progress = $('progress'); progress.value = (current*100)/duration; var played = $('sliderplayed'); played.style.width = '' + progress.value + '%'; if (progress.value == 100) { onMediaComplete(); } } function onLoadedProgress(e) { var element = $('sliderloaded'); if (e.lengthComputable) { element.style.display = 'block'; var percent = (e.loaded * 100) / e.total; element.style.width = '' + percent + '%'; } else { element.style.display = 'none'; } } function onMediaError(e) { console.log('Got new error'); console.log(e); chrome.send('playbackError', ['Error playing back', currentPlaylist[currentItem].path]); if (currentPlaylist.length == 1) { $('error').textContent = localStrings.getString('errorstring'); } else { chrome.send("showPlaylist", []); } onMediaComplete(); } function onMediaComplete() { currentItem ++; if (currentItem >= currentPlaylist.length) { currentItem -= 1; var element = getMediaElement(); if (!getMediaElement().error) { element.currentTime = 0; element.pause(); onMediaProgress(); } onMediaPause(); return; } var mediaElement = getMediaElement(); mediaElement.removeEventListener("progress", onLoadedProgress, true); mediaElement.removeEventListener("timeupdate", onMediaProgress, true); mediaElement.removeEventListener("durationchange", onMetadataAvail, true); // MediaElement.removeEventListener("ended", onMediaComplete, true); mediaElement.removeEventListener("play", onMediaPlay, true); mediaElement.removeEventListener("pause", onMediaPause, true); mediaElement.onerror = undefined; chrome.send('currentOffsetChanged', ['' + currentItem]); playMediaFile(currentPlaylist[currentItem].path); } function onMediaPlay() { var pausebutton = $('pausebutton'); var playbutton = $('playbutton'); pausebutton.style.display = 'block'; playbutton.style.display = 'none'; } function onMediaPause() { var pausebutton = $('pausebutton'); var playbutton = $('playbutton'); playbutton.style.display = 'block'; pausebutton.style.display = 'none'; } function setupMediaEvents(element) { element.addEventListener("progress", onLoadedProgress, true); element.addEventListener("timeupdate", onMediaProgress, true); element.addEventListener("durationchange", onMetadataAvail, true); // element.addEventListener("ended", onMediaComplete, true); element.onerror = onMediaError; element.addEventListener("play", onMediaPlay, true); element.addEventListener("pause", onMediaPause, true); element.oncontextmenu = function() { return false; }; } function getMediaElement() { var mediaElement; if (videoPlaybackElement) { mediaElement = videoPlaybackElement; } else { mediaElement = audioPlaybackElement; } return mediaElement; } function playPauseButtonClick() { var mediaElement = getMediaElement(); if (mediaElement.paused || mediaElement.ended) { mediaElement.play(); } else { mediaElement.pause(); } } function prevButtonClick() { var element = getMediaElement(); if (element.currentTime > 6) { element.currentTime = 0; return; } currentItem --; if (currentItem < 0) { currentItem = -1; return; } chrome.send('currentOffsetChanged', ['' + currentItem]); playMediaFile(currentPlaylist[currentItem].path); } function nextButtonClick() { currentItem ++; if (currentItem >= currentPlaylist.length) { currentItem = -1; return; } chrome.send('currentOffsetChanged', ['' + currentItem]); playMediaFile(currentPlaylist[currentItem].path); } function userChangedProgress() { var val = $('progress').value; var element = getMediaElement(); if (element.seekable && element.duration) { var current = (progress.value * element.duration)/100; element.currentTime = current; } } function changeVolumeVisibility(visible) { var volume = $('volume'); volume.style.display = visible ? 'block' : 'none'; } function showVolume() { if (hideVolumeTimerId) { clearTimeout(hideVolumeTimerId); hideVolumeTimerId = 0; } changeVolumeVisibility(true); } function hideVolume() { if (!hideVolumeTimerId) hideVolumeTimerId = setTimeout('changeVolumeVisibility(false)', 500); } function volumeChange() { var volumeslider = $('volumeslider'); var element = getMediaElement(); element.volume = (volumeslider.value/100); var soundicon = $('soundicon'); soundicon.className = soundicon.className.replace( /soundicon.*/, element.volume > 0 ? 'soundiconhigh' : 'soundiconmuted'); } function muteVolume(mute) { var volumeslider = $('volumeslider'); var element = getMediaElement(); if (mute) { savedVolumeValue = volumeslider.value; volumeslider.value = 0; volumeChange(); } else { volumeslider.value = savedVolumeValue; volumeChange(); } } function toggleVolumeMute() { muteVolume($('volumeslider').value != 0); } function getPathAndFilenameForPath(path) { return path.match(/(.*)[\/\\]([^\/\\]+)\.\w+$/); } var hidingControlsAnimation = null; const INACTIVITY_TIMEOUT = 5000; const INACTIVITY_CHECK_INTERVAL = 1000; const ANIMATION_DURATION = 1500; const ANIMATION_STEP = 50; function HidingControlsAnimation() { this.offsetPercent = 0; this.recentActivity = Date.now(); this.inactivityInterval = setInterval(this.checkInactivity.bind(this), INACTIVITY_CHECK_INTERVAL); this.onActivityClosure = this.onActivity.bind(this); document.body.addEventListener('mousemove', this.onActivityClosure); document.body.addEventListener('mousedown', this.onActivityClosure); document.body.addEventListener('keydown', this.onActivityClosure); } HidingControlsAnimation.prototype = { cleanup: function () { this.stopAnimation(); clearInterval(this.inactivityInterval); document.body.removeEventListener('mousemove', this.onActivityClosure); document.body.removeEventListener('mousedown', this.onActivityClosure); document.body.removeEventListener('keydown', this.onActivityClosure); }, onActivity: function() { this.recentActivity = Date.now(); // If not fully visible, start sliding up (or reverse sliding down). if (this.offsetPercent != 0) this.startAnimation(-1); }, checkInactivity: function() { if ((Date.now() - this.recentActivity) > INACTIVITY_TIMEOUT) { // If fully visible start sliding down. if (this.offsetPercent == 0) this.startAnimation(1); } }, startAnimation: function (direction) { this.direction = direction; this.startOffset = this.offsetPercent; this.startTime = Date.now(); if (!this.animationInterval) this.animationInterval = setInterval(this.doAnimation.bind(this), ANIMATION_STEP); }, doAnimation: function () { var phase = (Date.now() - this.startTime) / ANIMATION_DURATION; var newOffsetPercent = this.startOffset + this.direction * phase * 100; if (newOffsetPercent <= 0) { this.offsetPercent = 0; this.stopAnimation(); } else if (newOffsetPercent >= 100){ this.offsetPercent = 100; this.stopAnimation(); } else { this.offsetPercent = Math.round(newOffsetPercent); } $('playercontrols').style.top = this.offsetPercent + '%'; }, stopAnimation: function () { if (this.animationInterval) { clearInterval(this.animationInterval); this.animationInterval = null; } } }; function setupPlaybackControls() { var element = $('playercontrols'); playercontrols.innerHTML = ''; // clear out other var controlsclass = ''; if (hidingControlsAnimation) { hidingControlsAnimation.cleanup(); hidingControlsAnimation = null; } if (videoPlaybackElement != null) { controlsclass = 'video'; element.className = 'videocontrols'; hidingControlsAnimation = new HidingControlsAnimation(); } else if (audioPlaybackElement != null) { controlsclass = 'audio'; element.className = 'audiocontrols'; } var playbutton = document.createElement('div'); playbutton.id = 'playbutton'; playbutton.className = controlsclass + ' controlbutton playbutton'; playbutton.onclick = playPauseButtonClick; var playicon = document.createElement('div'); playicon.className = 'icon playicon'; playbutton.appendChild(playicon); element.appendChild(playbutton); var pausebutton = document.createElement('div'); pausebutton.id = 'pausebutton'; pausebutton.className = controlsclass + ' controlbutton pausebutton'; pausebutton.onclick = playPauseButtonClick; var pauseicon = document.createElement('div'); pauseicon.className = 'icon pauseicon'; pausebutton.appendChild(pauseicon); element.appendChild(pausebutton); var nextbutton = document.createElement('div'); nextbutton.id = 'nextbutton'; nextbutton.className = controlsclass + ' controlbutton nextbutton'; nextbutton.onclick = nextButtonClick; var nexticon = document.createElement('div'); nexticon.className = 'icon nexticon'; nextbutton.appendChild(nexticon); element.appendChild(nextbutton); var prevbutton = document.createElement('div'); prevbutton.id = 'prevbutton'; prevbutton.className = controlsclass + ' controlbutton prevbutton'; prevbutton.onclick = prevButtonClick; var previcon = document.createElement('div'); previcon.className = 'icon previcon'; prevbutton.appendChild(previcon); element.appendChild(prevbutton); var playlistbutton = document.createElement('div'); playlistbutton.id = 'playlistbutton'; playlistbutton.className = ' controlbutton playlistbutton'; playlistbutton.onclick = togglePlaylist; var playlisticon = document.createElement('div'); playlisticon.className = 'icon playlisticon'; playlistbutton.appendChild(playlisticon); element.appendChild(playlistbutton); var slider = document.createElement('input'); slider.type = 'range'; slider.id = 'progress'; slider.className = controlsclass + ' progress'; slider.onchange = userChangedProgress; element.appendChild(slider); var sliderback = document.createElement('div'); sliderback.className = 'sliderback'; element.appendChild(sliderback); var loaded = document.createElement('div'); loaded.id = 'sliderloaded'; loaded.className = 'sliderloaded'; sliderback.appendChild(loaded); var played = document.createElement('div'); played.id = 'sliderplayed'; played.className = 'sliderplayed'; sliderback.appendChild(played); var soundbutton = document.createElement('div'); soundbutton.id = 'soundbutton'; soundbutton.className = controlsclass + ' controlbutton soundbutton'; soundbutton.onclick = toggleVolumeMute; soundbutton.onmouseover = showVolume; soundbutton.onmouseout = hideVolume; var soundicon = document.createElement('div'); soundicon.id = 'soundicon'; soundicon.className = 'icon soundiconhigh'; soundbutton.appendChild(soundicon); element.appendChild(soundbutton); var fullscreen = document.createElement('div'); fullscreen.id = 'fullscreen'; fullscreen.className = controlsclass + ' controlbutton fullscreen'; fullscreen.onclick = toggleFullscreen; var fullscreenicon = document.createElement('div'); fullscreenicon.id = 'fullscreenicon'; fullscreenicon.className = 'icon fullscreenicon'; fullscreen.appendChild(fullscreenicon); element.appendChild(fullscreen); var volume = document.createElement('div'); volume.id = 'volume'; volume.className = controlsclass + ' volume'; volume.style.display = 'none'; volume.onmouseover = showVolume; volume.onmouseout = hideVolume; var volumeslider = document.createElement('input'); volumeslider.type = 'range'; volumeslider.id = 'volumeslider'; volumeslider.className = 'volumeslider'; volumeslider.onchange = volumeChange; volume.appendChild(volumeslider); document.body.appendChild(volume); volumeChange(); var duration = document.createElement('div'); duration.id = 'duration'; duration.className = 'duration'; element.appendChild(duration); } function playAudioFile(uri) { if (videoPlaybackElement != null) { videoPlaybackElement.onerror = undefined; document.body.removeChild(videoPlaybackElement); videoPlaybackElement = null; } if (audioPlaybackElement == null) { audioPlaybackElement = document.createElement('audio'); audioPlaybackElement.className = 'playbackaudioelement'; audioPlaybackElement.autoplay = true; audioPlaybackElement.controls = false; setupMediaEvents(audioPlaybackElement); audioPlaybackElement.src = uri; setupPlaybackControls(); document.body.appendChild(audioPlaybackElement); var paths = getPathAndFilenameForPath(uri); $('title').textContent = decodeURI(paths[2]); } else { setupMediaEvents(audioPlaybackElement); audioPlaybackElement.src = uri; audioPlaybackElement.load(); audioPlaybackElement.play(); var paths = getPathAndFilenameForPath(uri); $('title').textContent = decodeURI(paths[2]); } } function onkeydown(event) { const ESCAPE_KEY_CODE = 27; const SPACE_KEY_CODE = 32; switch (event.keyCode) { case ESCAPE_KEY_CODE: if (fullScreen) toggleFullscreen(); break; case SPACE_KEY_CODE: playPauseButtonClick(); break; } } function toggleFullscreen() { fullScreen = !fullScreen; var fullscreenicon = $('fullscreenicon'); if (fullScreen) { fullscreenicon.classList.remove('fullscreenicon'); fullscreenicon.classList.add('fullscreenexiticon'); } else { fullscreenicon.classList.remove('fullscreenexiticon'); fullscreenicon.classList.add('fullscreenicon'); } chrome.send('toggleFullscreen', ['']); } function onMetadataAvail() { var element = getMediaElement(); var duration = element.duration; if (duration) { var durString = '' + Math.floor((duration / 60)) + ':' + (Math.floor(duration) % 60); var durDiv = $('duration'); durDiv.textContent = durString; } } function playVideoFile(uri) { if (audioPlaybackElement != null) { document.body.removeChild(audioPlaybackElement); audioPlaybackElement = null; } if (videoPlaybackElement == null) { videoPlaybackElement = document.createElement('video'); videoPlaybackElement.className = 'playbackvideoelement'; videoPlaybackElement.autoplay = true; videoPlaybackElement.controls = false; setupMediaEvents(videoPlaybackElement); videoPlaybackElement.src = uri; videoPlaybackElement.load(); var toggleButton = document.createElement('div'); toggleButton.className = 'fullscreentoggle'; toggleButton.id = 'fullscreentoggle'; toggleButton.onclick = toggleFullscreen; document.body.appendChild(toggleButton); setupPlaybackControls(); document.body.appendChild(videoPlaybackElement); } else { setupMediaEvents(videoPlaybackElement); videoPlaybackElement.src = uri; videoPlaybackElement.load(); videoPlaybackElement.currentTime = 0; videoPlaybackElement.play(); } } function stopAllPlayback() { var element = getMediaElement(); if (element != null) { element.pause(); } } function playlistChanged(info, playlist) { if (info.force) { currentPlaylist = playlist; stopAllPlayback(); if (playlist.length >= 1) { if (info.currentOffset) { currentItem = info.currentOffset; } else { currentItem = 0; } var item = playlist[currentItem]; chrome.send('currentOffsetChanged', ['' + currentItem]); playMediaFile(item.path); } } else { var media = getMediaElement(); currentPlaylist = playlist; // Only need to handle the case where we are not playing // since if it is currently playing, it will just move // to the next file when the current is complete. if (media == null) { for (var x = 0; x < playlist.length; x++) { if (playlist[x].path == info.path) { // found the newly added item. currentItem = x; chrome.send('currentOffsetChanged', ['' + currentItem]); playMediaFile(playlist[x].path); return; } } if (playlist.length > 0) { currentItem = 0; chrome.send('currentOffsetChanged', ['' + currentItem]); playMediaFile(playlist[0].path); } } } } function togglePlaylist() { chrome.send("togglePlaylist", []); } function playMediaFile(url) { $('error').textContent = ''; console.log('playfile '+url); $('title').textContent = ''; if (pathIsVideoFile(url) ) { playVideoFile(url); } else if(pathIsAudioFile(url)) { playAudioFile(url); } else { alert('file unknown:' + url); } } </script> <body onload='load();' onselectstart='return false'> <div id='error' class='error'></div> <div id='title' class='audiotitle'></div> <div id='glow' class='glow'></div> <div class='playercontrolsbox'> <div id='playercontrols'> </div> </div> </body> </html>