Home | History | Annotate | Download | only in resources
      1 <!DOCTYPE HTML>
      2 <html i18n-values="dir:textdirection;">
      3 <head>
      4 <meta charset="utf-8">
      5 <title>Media Player</title>
      6 <style type="text/css">
      7 
      8 body {
      9   overflow: hidden;
     10   background: black;
     11 }
     12 
     13 .error {
     14   left: 0;
     15   right: 0;
     16   color: white;
     17   bottom: 38px;
     18   position: absolute;
     19 }
     20 
     21 .glow {
     22   left: 0;
     23   right: 0;
     24   bottom: 30px;
     25   height: 8px;
     26   opacity: .4;
     27   position: absolute;
     28   background: -webkit-linear-gradient(transparent, white);
     29 }
     30 
     31 .audiotitle {
     32   left: 0;
     33   right: 0;
     34   text-align: center;
     35   position: absolute;
     36   color: white;
     37   top: 100px;
     38 }
     39 
     40 .progress {
     41   -webkit-appearance: sliderthumb-horizontal;
     42   position: absolute;
     43   background: transparent;
     44   left: 93px;
     45   right: 120px;
     46   bottom: -2px;
     47   height: 30px;
     48   z-index: 99999;
     49   border-left: 1px solid #424242;
     50 }
     51 
     52 .playercontrolsbox {
     53   bottom: 0;
     54   left: 0;
     55   height: 30px;
     56   right: 0;
     57   position: absolute;
     58 }
     59 
     60 .videocontrols {
     61   top: 0;
     62   left: 0;
     63   z-index: 999;
     64   height: 100%;
     65   opacity: .9;
     66   right: 0;
     67   position: absolute;
     68   background: -webkit-linear-gradient(#323232, #070707);
     69 }
     70 
     71 .sliderback {
     72   bottom: 12px;
     73   left: 93px;
     74   right: 120px;
     75   height: 5px;
     76   position: absolute;
     77   border-radius: 3px;
     78   background: -webkit-linear-gradient(#ced9fa, #e8ecf9);
     79   border: 1px solid #ffffff;
     80 }
     81 
     82 .sliderplayed {
     83   height: 100%;
     84   width:0;
     85   left: -1px;
     86   top: -1px;
     87   border-radius: 3px;
     88   border: 1px solid #9ca5b7;
     89   position: absolute;
     90   background: -webkit-linear-gradient(#4a5d84, #232c3d);
     91 }
     92 
     93 .sliderloaded {
     94   height: 100%;
     95   width:0;
     96   left: -1px;
     97   top: -1px;
     98   border-radius: 3px;
     99   position: absolute;
    100   background: #6a799a;
    101   border: 1px solid #ffffff;
    102 }
    103 
    104 .audiocontrols {
    105   top: 0;
    106   left: 0;
    107   z-index: 999;
    108   height: 100%;
    109   opacity: .9;
    110   right: 0;
    111   position: absolute;
    112   background: -webkit-linear-gradient(#323232, #070707);
    113 }
    114 
    115 .soundbutton {
    116   position: absolute;
    117   right: 30px;
    118   bottom: 0;
    119   border-left: 1px solid #424242;
    120   border-right: 1px solid black;
    121 }
    122 
    123 .soundiconhigh {
    124   background: url('shared/images/mediaplayer_vol_high.png');
    125 }
    126 
    127 .soundiconmuted {
    128   background: url('shared/images/mediaplayer_vol_mute.png');
    129 }
    130 
    131 .soundiconhigh,
    132 .soundiconmuted {
    133   background-repeat: no-repeat;
    134   background-position: 6px 8px;
    135 }
    136 
    137 .volume {
    138   position: absolute;
    139   bottom: 30px;
    140   height: 80px;
    141   width: 30px;
    142   right: 30px;
    143   z-index: 99999;
    144   background: black;
    145   background: -webkit-linear-gradient(#323232, #070707);
    146 }
    147 
    148 .fullscreen {
    149   position: absolute;
    150   right: 60px;
    151   bottom: 0;
    152   border-left: 1px solid #424242;
    153   border-right: 1px solid black;
    154 }
    155 
    156 .fullscreenicon {
    157   background: url('shared/images/mediaplayer_full_screen.png');
    158   background-repeat: no-repeat;
    159   background-position: 6px 8px;
    160 }
    161 
    162 .fullscreenexiticon {
    163   background: url('shared/images/mediaplayer_full_screen_exit.png');
    164   background-repeat: no-repeat;
    165   background-position: 6px 8px;
    166 }
    167 
    168 .volumeslider {
    169   -webkit-appearance: slider-vertical;
    170   position: absolute;
    171   left: 0;
    172   right: 0;
    173   bottom: 0;
    174   top: 0;
    175 }
    176 
    177 .playbutton {
    178   position: absolute;
    179   left: 30px;
    180   bottom: 0;
    181   border-left: 1px solid #424242;
    182   border-right: 1px solid black;
    183 }
    184 
    185 .playicon {
    186   background: url('shared/images/mediaplayer_play.png');
    187   background-repeat: no-repeat;
    188   background-position: 9px 8px;
    189 }
    190 
    191 .pausebutton {
    192   position: absolute;
    193   left: 30px;
    194   bottom: 0;
    195   border-left: 1px solid #424242;
    196   border-right: 1px solid black;
    197 }
    198 
    199 .pauseicon {
    200   background: url('shared/images/mediaplayer_pause.png');
    201   background-repeat: no-repeat;
    202   background-position: 9px 8px;
    203 }
    204 
    205 .prevbutton {
    206   position: absolute;
    207   left: 0;
    208   bottom: 0;
    209   border-right: 1px solid black;
    210 }
    211 
    212 .previcon {
    213   background: url('shared/images/mediaplayer_prev.png');
    214   background-repeat: no-repeat;
    215   background-position: 6px 8px;
    216 }
    217 
    218 .playbackvideoelement {
    219   width: 100%;
    220   height: 100%;
    221   position: absolute;
    222   left: 0;
    223   top: 0;
    224 }
    225 
    226 .duration {
    227   right: 90px;
    228   color: white;
    229   position: absolute;
    230   top: 8.5px;
    231   font-size: .6em;
    232   height: 30px;
    233 }
    234 
    235 .playbackaudioelement {
    236   width: 100%;
    237   height: 100%;
    238   position: absolute;
    239   left: 0;
    240   top: 0;
    241 }
    242 
    243 .nextbutton {
    244   position: absolute;
    245   left: 60px;
    246   bottom: 0;
    247   border-left: 1px solid #424242;
    248   border-right: 1px solid black;
    249 }
    250 
    251 .nexticon {
    252   background: url('shared/images/mediaplayer_next.png');
    253   background-repeat: no-repeat;
    254   background-position: 6px 8px;
    255 }
    256 
    257 .playlistbutton {
    258   position: absolute;
    259   right: 0;
    260   bottom: 0;
    261   border-left: 1px solid #424242;
    262   border-right: 1px solid black;
    263 }
    264 
    265 .playlisticon {
    266   background: url('shared/images/mediaplayer_playlist.png');
    267   background-repeat: no-repeat;
    268   background-position: 6px 8px;
    269 }
    270 
    271 .controlbutton {
    272   z-index: 9999;
    273   cursor: pointer;
    274   width: 28px;
    275   height: 30px;
    276 }
    277 
    278 .controlbutton:hover {
    279   background: -webkit-linear-gradient(#6a7eac, #000);
    280 }
    281 
    282 .icon {
    283   width: 100%;
    284   height: 100%;
    285   z-index: 9999;
    286 }
    287 
    288 </style>
    289 <script src="shared/js/local_strings.js"></script>
    290 <script src="shared/js/media_common.js"></script>
    291 <script>
    292 
    293 function $(o) {
    294   return document.getElementById(o);
    295 }
    296 
    297 var videoPlaybackElement = null;
    298 var audioPlaybackElement = null;
    299 var currentPlaylist = null;
    300 var currentItem = -1;
    301 var savedVolumeValue = 0;
    302 var hideVolumeTimerId = 0;
    303 var localStrings;
    304 var fullScreen = false;
    305 
    306 ///////////////////////////////////////////////////////////////////////////////
    307 // Document Functions:
    308 /**
    309  * Window onload handler, sets up the page.
    310  */
    311 function load() {
    312   document.body.addEventListener('dragover', function(e) {
    313     if (e.preventDefault) e.preventDefault();
    314   });
    315   document.body.addEventListener('drop', function(e) {
    316     if (e.preventDefault) e.preventDefault();
    317   });
    318   document.body.addEventListener('keydown', onkeydown);
    319 
    320   localStrings = new LocalStrings();
    321   chrome.send('getCurrentPlaylist', []);
    322 }
    323 
    324 function onMediaProgress() {
    325   var element = getMediaElement();
    326   var current = element.currentTime;
    327   var duration = element.duration;
    328   var progress = $('progress');
    329   progress.value = (current*100)/duration;
    330   var played = $('sliderplayed');
    331   played.style.width = '' + progress.value + '%';
    332   if (progress.value == 100) {
    333     onMediaComplete();
    334   }
    335 }
    336 
    337 function onLoadedProgress(e) {
    338   var element = $('sliderloaded');
    339   if (e.lengthComputable) {
    340     element.style.display = 'block';
    341     var percent = (e.loaded * 100) / e.total;
    342     element.style.width = '' + percent + '%';
    343   } else {
    344     element.style.display = 'none';
    345   }
    346 }
    347 
    348 function onMediaError(e) {
    349   console.log('Got new error');
    350   console.log(e);
    351   chrome.send('playbackError', ['Error playing back',
    352       currentPlaylist[currentItem].path]);
    353   if (currentPlaylist.length == 1) {
    354     $('error').textContent = localStrings.getString('errorstring');
    355   } else {
    356     chrome.send("showPlaylist", []);
    357   }
    358   onMediaComplete();
    359 }
    360 
    361 function onMediaComplete() {
    362   currentItem ++;
    363   if (currentItem >= currentPlaylist.length) {
    364     currentItem -= 1;
    365     var element = getMediaElement();
    366     if (!getMediaElement().error) {
    367       element.currentTime = 0;
    368       element.pause();
    369       onMediaProgress();
    370     }
    371     onMediaPause();
    372     return;
    373   }
    374   var mediaElement = getMediaElement();
    375   mediaElement.removeEventListener("progress", onLoadedProgress, true);
    376   mediaElement.removeEventListener("timeupdate", onMediaProgress, true);
    377   mediaElement.removeEventListener("durationchange", onMetadataAvail, true);
    378   // MediaElement.removeEventListener("ended", onMediaComplete, true);
    379   mediaElement.removeEventListener("play", onMediaPlay, true);
    380   mediaElement.removeEventListener("pause", onMediaPause, true);
    381   mediaElement.onerror = undefined;
    382   chrome.send('currentOffsetChanged', ['' + currentItem]);
    383   playMediaFile(currentPlaylist[currentItem].path);
    384 }
    385 
    386 function onMediaPlay() {
    387   var pausebutton = $('pausebutton');
    388   var playbutton = $('playbutton');
    389   pausebutton.style.display = 'block';
    390   playbutton.style.display = 'none';
    391 }
    392 
    393 function onMediaPause() {
    394   var pausebutton = $('pausebutton');
    395   var playbutton = $('playbutton');
    396   playbutton.style.display = 'block';
    397   pausebutton.style.display = 'none';
    398 }
    399 
    400 function setupMediaEvents(element) {
    401   element.addEventListener("progress", onLoadedProgress, true);
    402   element.addEventListener("timeupdate", onMediaProgress, true);
    403   element.addEventListener("durationchange", onMetadataAvail, true);
    404   // element.addEventListener("ended", onMediaComplete, true);
    405   element.onerror = onMediaError;
    406   element.addEventListener("play", onMediaPlay, true);
    407   element.addEventListener("pause", onMediaPause, true);
    408   element.oncontextmenu = function() {
    409      return false;
    410   };
    411 }
    412 
    413 function getMediaElement() {
    414   var mediaElement;
    415   if (videoPlaybackElement) {
    416     mediaElement = videoPlaybackElement;
    417   } else {
    418     mediaElement = audioPlaybackElement;
    419   }
    420   return mediaElement;
    421 }
    422 
    423 function playPauseButtonClick() {
    424   var mediaElement = getMediaElement();
    425   if (mediaElement.paused || mediaElement.ended) {
    426     mediaElement.play();
    427   } else {
    428     mediaElement.pause();
    429   }
    430 }
    431 
    432 function prevButtonClick() {
    433   var element = getMediaElement();
    434   if (element.currentTime > 6) {
    435     element.currentTime = 0;
    436     return;
    437   }
    438   currentItem --;
    439   if (currentItem < 0) {
    440     currentItem = -1;
    441     return;
    442   }
    443   chrome.send('currentOffsetChanged', ['' + currentItem]);
    444   playMediaFile(currentPlaylist[currentItem].path);
    445 }
    446 
    447 function nextButtonClick() {
    448   currentItem ++;
    449   if (currentItem >= currentPlaylist.length) {
    450     currentItem = -1;
    451     return;
    452   }
    453   chrome.send('currentOffsetChanged', ['' + currentItem]);
    454   playMediaFile(currentPlaylist[currentItem].path);
    455 }
    456 
    457 function userChangedProgress() {
    458   var val = $('progress').value;
    459   var element = getMediaElement();
    460   if (element.seekable && element.duration) {
    461     var current = (progress.value * element.duration)/100;
    462     element.currentTime = current;
    463   }
    464 }
    465 
    466 function changeVolumeVisibility(visible) {
    467   var volume = $('volume');
    468   volume.style.display = visible ? 'block' : 'none';
    469 }
    470 
    471 function showVolume() {
    472   if (hideVolumeTimerId) {
    473     clearTimeout(hideVolumeTimerId);
    474     hideVolumeTimerId = 0;
    475   }
    476 
    477   changeVolumeVisibility(true);
    478 }
    479 
    480 function hideVolume() {
    481   if (!hideVolumeTimerId)
    482     hideVolumeTimerId = setTimeout('changeVolumeVisibility(false)', 500);
    483 }
    484 
    485 function volumeChange() {
    486   var volumeslider = $('volumeslider');
    487   var element = getMediaElement();
    488   element.volume = (volumeslider.value/100);
    489 
    490   var soundicon = $('soundicon');
    491   soundicon.className = soundicon.className.replace(
    492       /soundicon.*/,
    493       element.volume > 0 ? 'soundiconhigh' : 'soundiconmuted');
    494 }
    495 
    496 function muteVolume(mute) {
    497   var volumeslider = $('volumeslider');
    498   var element = getMediaElement();
    499   if (mute) {
    500     savedVolumeValue = volumeslider.value;
    501     volumeslider.value = 0;
    502     volumeChange();
    503   } else {
    504     volumeslider.value = savedVolumeValue;
    505     volumeChange();
    506   }
    507 }
    508 
    509 function toggleVolumeMute() {
    510   muteVolume($('volumeslider').value != 0);
    511 }
    512 
    513 function getPathAndFilenameForPath(path) {
    514   return path.match(/(.*)[\/\\]([^\/\\]+)\.\w+$/);
    515 }
    516 
    517 
    518 var hidingControlsAnimation = null;
    519 
    520 const INACTIVITY_TIMEOUT = 5000;
    521 const INACTIVITY_CHECK_INTERVAL = 1000;
    522 const ANIMATION_DURATION = 1500;
    523 const ANIMATION_STEP = 50;
    524 
    525 function HidingControlsAnimation() {
    526   this.offsetPercent = 0;
    527   this.recentActivity = Date.now();
    528 
    529   this.inactivityInterval = setInterval(this.checkInactivity.bind(this),
    530                                         INACTIVITY_CHECK_INTERVAL);
    531 
    532   this.onActivityClosure = this.onActivity.bind(this);
    533   document.body.addEventListener('mousemove', this.onActivityClosure);
    534   document.body.addEventListener('mousedown', this.onActivityClosure);
    535   document.body.addEventListener('keydown', this.onActivityClosure);
    536 }
    537 
    538 HidingControlsAnimation.prototype = {
    539 
    540     cleanup: function () {
    541       this.stopAnimation();
    542       clearInterval(this.inactivityInterval);
    543       document.body.removeEventListener('mousemove', this.onActivityClosure);
    544       document.body.removeEventListener('mousedown', this.onActivityClosure);
    545       document.body.removeEventListener('keydown', this.onActivityClosure);
    546     },
    547 
    548     onActivity: function() {
    549       this.recentActivity = Date.now();
    550       // If not fully visible, start sliding up (or reverse sliding down).
    551       if (this.offsetPercent != 0)
    552         this.startAnimation(-1);
    553     },
    554 
    555     checkInactivity: function() {
    556       if ((Date.now() - this.recentActivity) > INACTIVITY_TIMEOUT) {
    557       // If fully visible start sliding down.
    558       if (this.offsetPercent == 0)
    559           this.startAnimation(1);
    560       }
    561     },
    562 
    563     startAnimation: function (direction) {
    564       this.direction = direction;
    565       this.startOffset = this.offsetPercent;
    566       this.startTime = Date.now();
    567       if (!this.animationInterval)
    568         this.animationInterval = setInterval(this.doAnimation.bind(this),
    569                                              ANIMATION_STEP);
    570     },
    571 
    572     doAnimation: function () {
    573       var phase = (Date.now() - this.startTime) / ANIMATION_DURATION;
    574 
    575       var newOffsetPercent = this.startOffset + this.direction * phase * 100;
    576 
    577       if (newOffsetPercent <= 0) {
    578         this.offsetPercent = 0;
    579         this.stopAnimation();
    580       } else if (newOffsetPercent >= 100){
    581         this.offsetPercent = 100;
    582         this.stopAnimation();
    583       } else {
    584         this.offsetPercent = Math.round(newOffsetPercent);
    585       }
    586 
    587       $('playercontrols').style.top = this.offsetPercent + '%';
    588     },
    589 
    590     stopAnimation: function () {
    591       if (this.animationInterval) {
    592         clearInterval(this.animationInterval);
    593         this.animationInterval = null;
    594       }
    595     }
    596 };
    597 
    598 function setupPlaybackControls() {
    599   var element = $('playercontrols');
    600   playercontrols.innerHTML = ''; // clear out other
    601   var controlsclass = '';
    602   if (hidingControlsAnimation) {
    603     hidingControlsAnimation.cleanup();
    604     hidingControlsAnimation = null;
    605   }
    606   if (videoPlaybackElement != null) {
    607     controlsclass = 'video';
    608     element.className = 'videocontrols';
    609     hidingControlsAnimation = new HidingControlsAnimation();
    610   } else if (audioPlaybackElement != null) {
    611     controlsclass = 'audio';
    612     element.className = 'audiocontrols';
    613   }
    614 
    615   var playbutton = document.createElement('div');
    616   playbutton.id = 'playbutton';
    617   playbutton.className = controlsclass + ' controlbutton playbutton';
    618   playbutton.onclick = playPauseButtonClick;
    619   var playicon = document.createElement('div');
    620   playicon.className = 'icon playicon';
    621   playbutton.appendChild(playicon);
    622   element.appendChild(playbutton);
    623 
    624 
    625   var pausebutton = document.createElement('div');
    626   pausebutton.id = 'pausebutton';
    627   pausebutton.className = controlsclass + ' controlbutton pausebutton';
    628   pausebutton.onclick = playPauseButtonClick;
    629   var pauseicon = document.createElement('div');
    630   pauseicon.className = 'icon pauseicon';
    631   pausebutton.appendChild(pauseicon);
    632   element.appendChild(pausebutton);
    633 
    634   var nextbutton = document.createElement('div');
    635   nextbutton.id = 'nextbutton';
    636   nextbutton.className = controlsclass + ' controlbutton nextbutton';
    637   nextbutton.onclick = nextButtonClick;
    638   var nexticon = document.createElement('div');
    639   nexticon.className = 'icon nexticon';
    640   nextbutton.appendChild(nexticon);
    641   element.appendChild(nextbutton);
    642 
    643   var prevbutton = document.createElement('div');
    644   prevbutton.id = 'prevbutton';
    645   prevbutton.className = controlsclass + ' controlbutton prevbutton';
    646   prevbutton.onclick = prevButtonClick;
    647   var previcon = document.createElement('div');
    648   previcon.className = 'icon previcon';
    649   prevbutton.appendChild(previcon);
    650   element.appendChild(prevbutton);
    651 
    652   var playlistbutton = document.createElement('div');
    653   playlistbutton.id = 'playlistbutton';
    654   playlistbutton.className = ' controlbutton playlistbutton';
    655   playlistbutton.onclick = togglePlaylist;
    656   var playlisticon = document.createElement('div');
    657   playlisticon.className = 'icon playlisticon';
    658   playlistbutton.appendChild(playlisticon);
    659   element.appendChild(playlistbutton);
    660 
    661   var slider = document.createElement('input');
    662   slider.type = 'range';
    663   slider.id = 'progress';
    664   slider.className = controlsclass + ' progress';
    665   slider.onchange = userChangedProgress;
    666   element.appendChild(slider);
    667 
    668   var sliderback = document.createElement('div');
    669   sliderback.className = 'sliderback';
    670   element.appendChild(sliderback);
    671 
    672   var loaded = document.createElement('div');
    673   loaded.id = 'sliderloaded';
    674   loaded.className = 'sliderloaded';
    675   sliderback.appendChild(loaded);
    676 
    677   var played = document.createElement('div');
    678   played.id = 'sliderplayed';
    679   played.className = 'sliderplayed';
    680   sliderback.appendChild(played);
    681 
    682   var soundbutton = document.createElement('div');
    683   soundbutton.id = 'soundbutton';
    684   soundbutton.className = controlsclass + ' controlbutton soundbutton';
    685   soundbutton.onclick = toggleVolumeMute;
    686   soundbutton.onmouseover = showVolume;
    687   soundbutton.onmouseout = hideVolume;
    688   var soundicon = document.createElement('div');
    689   soundicon.id = 'soundicon';
    690   soundicon.className = 'icon soundiconhigh';
    691   soundbutton.appendChild(soundicon);
    692   element.appendChild(soundbutton);
    693 
    694   var fullscreen = document.createElement('div');
    695   fullscreen.id = 'fullscreen';
    696   fullscreen.className = controlsclass + ' controlbutton fullscreen';
    697   fullscreen.onclick = toggleFullscreen;
    698   var fullscreenicon = document.createElement('div');
    699   fullscreenicon.id = 'fullscreenicon';
    700   fullscreenicon.className = 'icon fullscreenicon';
    701   fullscreen.appendChild(fullscreenicon);
    702   element.appendChild(fullscreen);
    703 
    704   var volume = document.createElement('div');
    705   volume.id = 'volume';
    706   volume.className = controlsclass + ' volume';
    707   volume.style.display = 'none';
    708   volume.onmouseover = showVolume;
    709   volume.onmouseout = hideVolume;
    710   var volumeslider = document.createElement('input');
    711   volumeslider.type = 'range';
    712   volumeslider.id = 'volumeslider';
    713   volumeslider.className = 'volumeslider';
    714   volumeslider.onchange = volumeChange;
    715   volume.appendChild(volumeslider);
    716   document.body.appendChild(volume);
    717   volumeChange();
    718 
    719   var duration = document.createElement('div');
    720   duration.id = 'duration';
    721   duration.className = 'duration';
    722   element.appendChild(duration);
    723 }
    724 
    725 function playAudioFile(uri) {
    726   if (videoPlaybackElement != null) {
    727     videoPlaybackElement.onerror = undefined;
    728     document.body.removeChild(videoPlaybackElement);
    729     videoPlaybackElement = null;
    730   }
    731   if (audioPlaybackElement == null) {
    732     audioPlaybackElement = document.createElement('audio');
    733     audioPlaybackElement.className = 'playbackaudioelement';
    734     audioPlaybackElement.autoplay = true;
    735     audioPlaybackElement.controls = false;
    736     setupMediaEvents(audioPlaybackElement);
    737     audioPlaybackElement.src = uri;
    738     setupPlaybackControls();
    739     document.body.appendChild(audioPlaybackElement);
    740     var paths = getPathAndFilenameForPath(uri);
    741     $('title').textContent = decodeURI(paths[2]);
    742   } else {
    743     setupMediaEvents(audioPlaybackElement);
    744     audioPlaybackElement.src = uri;
    745     audioPlaybackElement.load();
    746     audioPlaybackElement.play();
    747     var paths = getPathAndFilenameForPath(uri);
    748     $('title').textContent = decodeURI(paths[2]);
    749   }
    750 }
    751 
    752 function onkeydown(event) {
    753   const ESCAPE_KEY_CODE = 27;
    754   const SPACE_KEY_CODE = 32;
    755   switch (event.keyCode) {
    756     case ESCAPE_KEY_CODE:
    757       if (fullScreen)
    758         toggleFullscreen();
    759       break;
    760 
    761     case SPACE_KEY_CODE:
    762       playPauseButtonClick();
    763       break;
    764   }
    765 }
    766 
    767 function toggleFullscreen() {
    768   fullScreen = !fullScreen;
    769   var fullscreenicon = $('fullscreenicon');
    770   if (fullScreen) {
    771     fullscreenicon.classList.remove('fullscreenicon');
    772     fullscreenicon.classList.add('fullscreenexiticon');
    773   }
    774   else {
    775     fullscreenicon.classList.remove('fullscreenexiticon');
    776     fullscreenicon.classList.add('fullscreenicon');
    777   }
    778   chrome.send('toggleFullscreen', ['']);
    779 }
    780 
    781 function onMetadataAvail() {
    782   var element = getMediaElement();
    783   var duration = element.duration;
    784   if (duration) {
    785     var durString = '' + Math.floor((duration / 60)) + ':' + (Math.floor(duration) % 60);
    786     var durDiv = $('duration');
    787     durDiv.textContent = durString;
    788   }
    789 }
    790 
    791 function playVideoFile(uri) {
    792   if (audioPlaybackElement != null) {
    793     document.body.removeChild(audioPlaybackElement);
    794     audioPlaybackElement = null;
    795   }
    796   if (videoPlaybackElement == null) {
    797     videoPlaybackElement = document.createElement('video');
    798     videoPlaybackElement.className = 'playbackvideoelement';
    799     videoPlaybackElement.autoplay = true;
    800     videoPlaybackElement.controls = false;
    801     setupMediaEvents(videoPlaybackElement);
    802     videoPlaybackElement.src = uri;
    803     videoPlaybackElement.load();
    804     var toggleButton = document.createElement('div');
    805     toggleButton.className = 'fullscreentoggle';
    806     toggleButton.id = 'fullscreentoggle';
    807     toggleButton.onclick = toggleFullscreen;
    808     document.body.appendChild(toggleButton);
    809     setupPlaybackControls();
    810     document.body.appendChild(videoPlaybackElement);
    811   } else {
    812     setupMediaEvents(videoPlaybackElement);
    813     videoPlaybackElement.src = uri;
    814     videoPlaybackElement.load();
    815     videoPlaybackElement.currentTime = 0;
    816     videoPlaybackElement.play();
    817   }
    818 }
    819 
    820 function stopAllPlayback() {
    821   var element = getMediaElement();
    822   if (element != null) {
    823     element.pause();
    824   }
    825 }
    826 
    827 function playlistChanged(info, playlist) {
    828   if (info.force) {
    829     currentPlaylist = playlist;
    830     stopAllPlayback();
    831     if (playlist.length >= 1) {
    832       if (info.currentOffset) {
    833         currentItem = info.currentOffset;
    834       } else {
    835         currentItem = 0;
    836       }
    837       var item = playlist[currentItem];
    838       chrome.send('currentOffsetChanged', ['' + currentItem]);
    839       playMediaFile(item.path);
    840     }
    841   } else {
    842     var media = getMediaElement();
    843     currentPlaylist = playlist;
    844     // Only need to handle the case where we are not playing
    845     // since if it is currently playing, it will just move
    846     // to the next file when the current is complete.
    847     if (media == null) {
    848       for (var x = 0; x < playlist.length; x++) {
    849         if (playlist[x].path == info.path) {
    850           // found the newly added item.
    851           currentItem = x;
    852           chrome.send('currentOffsetChanged', ['' + currentItem]);
    853           playMediaFile(playlist[x].path);
    854           return;
    855         }
    856       }
    857       if (playlist.length > 0) {
    858         currentItem = 0;
    859         chrome.send('currentOffsetChanged', ['' + currentItem]);
    860         playMediaFile(playlist[0].path);
    861       }
    862     }
    863   }
    864 }
    865 
    866 function togglePlaylist() {
    867   chrome.send("togglePlaylist", []);
    868 }
    869 
    870 function playMediaFile(url) {
    871   $('error').textContent = '';
    872   console.log('playfile '+url);
    873   $('title').textContent = '';
    874   if (pathIsVideoFile(url) ) {
    875     playVideoFile(url);
    876   } else if(pathIsAudioFile(url)) {
    877     playAudioFile(url);
    878   } else {
    879     alert('file unknown:' + url);
    880   }
    881 }
    882 
    883 </script>
    884 <body onload='load();' onselectstart='return false'>
    885 <div id='error' class='error'></div>
    886 <div id='title' class='audiotitle'></div>
    887 <div id='glow' class='glow'></div>
    888 <div class='playercontrolsbox'>
    889   <div id='playercontrols'>
    890   </div>
    891 </div>
    892 </body>
    893 </html>
    894