19d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org// Copyright 2014 The Chromium Authors. All rights reserved. 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com// Use of this source code is governed by a BSD-style license that can be 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com// found in the LICENSE file. 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com'use strict'; 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 79d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org/** 89d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org * @param {Element} playerContainer Main container. 9ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * @param {Element} videoContainer Container for the video element. 109d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org * @param {Element} controlsContainer Container for video controls. 119d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org * @constructor 1269cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com */ 139d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.orgfunction FullWindowVideoControls( 14181e9bd9484ece4132e0cc5cfcff602134e5489dbsalomon@google.com playerContainer, videoContainer, controlsContainer) { 15383963280ddd13030331765fe88d2aefa3e32130bsalomon@google.com VideoControls.call(this, 16383963280ddd13030331765fe88d2aefa3e32130bsalomon@google.com controlsContainer, 17181e9bd9484ece4132e0cc5cfcff602134e5489dbsalomon@google.com this.onPlaybackError_.wrap(this), 18181e9bd9484ece4132e0cc5cfcff602134e5489dbsalomon@google.com loadTimeData.getString.wrap(loadTimeData), 19181e9bd9484ece4132e0cc5cfcff602134e5489dbsalomon@google.com this.toggleFullScreen_.wrap(this), 20181e9bd9484ece4132e0cc5cfcff602134e5489dbsalomon@google.com videoContainer); 21181e9bd9484ece4132e0cc5cfcff602134e5489dbsalomon@google.com 22181e9bd9484ece4132e0cc5cfcff602134e5489dbsalomon@google.com this.playerContainer_ = playerContainer; 23383963280ddd13030331765fe88d2aefa3e32130bsalomon@google.com this.decodeErrorOccured = false; 24383963280ddd13030331765fe88d2aefa3e32130bsalomon@google.com 25383963280ddd13030331765fe88d2aefa3e32130bsalomon@google.com this.casting = false; 26383963280ddd13030331765fe88d2aefa3e32130bsalomon@google.com 27383963280ddd13030331765fe88d2aefa3e32130bsalomon@google.com this.updateStyle(); 28383963280ddd13030331765fe88d2aefa3e32130bsalomon@google.com window.addEventListener('resize', this.updateStyle.wrap(this)); 29383963280ddd13030331765fe88d2aefa3e32130bsalomon@google.com document.addEventListener('keydown', function(e) { 30383963280ddd13030331765fe88d2aefa3e32130bsalomon@google.com switch (e.keyIdentifier) { 31383963280ddd13030331765fe88d2aefa3e32130bsalomon@google.com case 'U+0020': // Space 32181e9bd9484ece4132e0cc5cfcff602134e5489dbsalomon@google.com case 'MediaPlayPause': 33181e9bd9484ece4132e0cc5cfcff602134e5489dbsalomon@google.com this.togglePlayStateWithFeedback(); 34181e9bd9484ece4132e0cc5cfcff602134e5489dbsalomon@google.com break; 35181e9bd9484ece4132e0cc5cfcff602134e5489dbsalomon@google.com case 'U+001B': // Escape 36181e9bd9484ece4132e0cc5cfcff602134e5489dbsalomon@google.com util.toggleFullScreen( 37b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com chrome.app.window.current(), 38181e9bd9484ece4132e0cc5cfcff602134e5489dbsalomon@google.com false); // Leave the full screen mode. 399d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org break; 409d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org case 'Right': 41c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com case 'MediaNextTrack': 42c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com player.advance_(1); 43afec7ba75962517b17293799d3fc70d39fa7dbf2tomhudson@google.com break; 44c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com case 'Left': 45c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com case 'MediaPreviousTrack': 46c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com player.advance_(0); 479d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org break; 48c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com case 'MediaStop': 499d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org // TODO: Define "Stop" behavior. 509d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org break; 519d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org } 529d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org }.wrap(this)); 539d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org 549d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org // TODO(mtomasz): Simplify. crbug.com/254318. 552047f00e4698f83499ab91911999a65c21a951c9epoger@google.com var clickInProgress = false; 5661f3bde1ba114e7b39b53411f4aa31ed0875d159bsalomon@google.com videoContainer.addEventListener('click', function(e) { 5761f3bde1ba114e7b39b53411f4aa31ed0875d159bsalomon@google.com if (clickInProgress) 5861f3bde1ba114e7b39b53411f4aa31ed0875d159bsalomon@google.com return; 5961f3bde1ba114e7b39b53411f4aa31ed0875d159bsalomon@google.com 6061f3bde1ba114e7b39b53411f4aa31ed0875d159bsalomon@google.com clickInProgress = true; 6161f3bde1ba114e7b39b53411f4aa31ed0875d159bsalomon@google.com var togglePlayState = function() { 6261f3bde1ba114e7b39b53411f4aa31ed0875d159bsalomon@google.com clickInProgress = false; 6361f3bde1ba114e7b39b53411f4aa31ed0875d159bsalomon@google.com 649d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org if (e.ctrlKey) { 659d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org this.toggleLoopedModeWithFeedback(true); 669d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org if (!this.isPlaying()) 679d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org this.togglePlayStateWithFeedback(); 68c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com } else { 69c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com this.togglePlayStateWithFeedback(); 70c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com } 71c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com }.wrap(this); 72c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com 739d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org if (!this.media_) 749d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org player.reloadCurrentVideo(togglePlayState); 759d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org else 769d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org setTimeout(togglePlayState); 779d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org }.wrap(this)); 789d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org 799d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org this.inactivityWatcher_ = new MouseInactivityWatcher(playerContainer); 809d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org this.__defineGetter__('inactivityWatcher', function() { 817744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com return this.inactivityWatcher_; 827744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com }.wrap(this)); 839d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org 847744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com this.inactivityWatcher_.check(); 859d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org} 869d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org 879d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.orgFullWindowVideoControls.prototype = { __proto__: VideoControls.prototype }; 889d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org 899d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org/** 909d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org * Displays error message. 919d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org * 929d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org * @param {string} message Message id. 939d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org */ 94c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.comFullWindowVideoControls.prototype.showErrorMessage = function(message) { 95afec7ba75962517b17293799d3fc70d39fa7dbf2tomhudson@google.com var errorBanner = document.querySelector('#error'); 96c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com errorBanner.textContent = loadTimeData.getString(message); 97c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com errorBanner.setAttribute('visible', 'true'); 98c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com 99c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com // The window is hidden if the video has not loaded yet. 100c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com chrome.app.window.current().show(); 101c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com}; 1022047f00e4698f83499ab91911999a65c21a951c9epoger@google.com 103c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com/** 1049d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org * Handles playback (decoder) errors. 1059d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org * @param {MediaError} error Error object. 1062047f00e4698f83499ab91911999a65c21a951c9epoger@google.com * @private 10761f3bde1ba114e7b39b53411f4aa31ed0875d159bsalomon@google.com */ 10861f3bde1ba114e7b39b53411f4aa31ed0875d159bsalomon@google.comFullWindowVideoControls.prototype.onPlaybackError_ = function(error) { 10961f3bde1ba114e7b39b53411f4aa31ed0875d159bsalomon@google.com if (error.target && error.target.error && 11061f3bde1ba114e7b39b53411f4aa31ed0875d159bsalomon@google.com error.target.error.code === MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED) { 11161f3bde1ba114e7b39b53411f4aa31ed0875d159bsalomon@google.com if (this.casting) 11261f3bde1ba114e7b39b53411f4aa31ed0875d159bsalomon@google.com this.showErrorMessage('VIDEO_PLAYER_VIDEO_FILE_UNSUPPORTED_FOR_CAST'); 11361f3bde1ba114e7b39b53411f4aa31ed0875d159bsalomon@google.com else 11461f3bde1ba114e7b39b53411f4aa31ed0875d159bsalomon@google.com this.showErrorMessage('GALLERY_VIDEO_ERROR'); 1159d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org this.decodeErrorOccured = false; 1169d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org } else { 1179d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org this.showErrorMessage('GALLERY_VIDEO_DECODING_ERROR'); 1189d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org this.decodeErrorOccured = true; 119c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com } 120c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com 121c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com // Disable inactivity watcher, and disable the ui, by hiding tools manually. 122c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com this.inactivityWatcher.disabled = true; 123c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com document.querySelector('#video-player').setAttribute('disabled', 'true'); 124c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com 1259d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org // Detach the video element, since it may be unreliable and reset stored 1269d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org // current playback time. 1279d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org this.cleanup(); 1289d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org this.clearState(); 1299d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org 1309d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org // Avoid reusing a video element. 1319d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org player.unloadVideo(); 1329d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org}; 1337744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com 1347744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com/** 1357744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com * Toggles the full screen mode. 1369d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org * @private 1379d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org */ 1387744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.comFullWindowVideoControls.prototype.toggleFullScreen_ = function() { 1397744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com var appWindow = chrome.app.window.current(); 1409d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org util.toggleFullScreen(appWindow, !util.isFullScreen(appWindow)); 1417744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com}; 1429d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org 1439d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org/** 1449d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org * Media completion handler. 1459d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org */ 1469d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.orgFullWindowVideoControls.prototype.onMediaComplete = function() { 1479d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org VideoControls.prototype.onMediaComplete.apply(this, arguments); 14807f3ee10d34f09342abb93d758b5e151ff78f7a5reed@google.com if (!this.getMedia().loop) 14907f3ee10d34f09342abb93d758b5e151ff78f7a5reed@google.com player.advance_(1); 150c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com}; 151afec7ba75962517b17293799d3fc70d39fa7dbf2tomhudson@google.com 152c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com/** 153c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com * @constructor 154c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com */ 1559d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.orgfunction VideoPlayer() { 1569d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org this.controls_ = null; 1579d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org this.videoElement_ = null; 1589d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org this.videos_ = null; 1599d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org this.currentPos_ = 0; 160129b8e3237b80b9d258a8f48e8f54c0073cafbdcsenorblanco@chromium.org 1619d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org this.currentSession_ = null; 1629d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org this.currentCast_ = null; 1639d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org 16407f3ee10d34f09342abb93d758b5e151ff78f7a5reed@google.com this.loadQueue_ = new AsyncUtil.Queue(); 1659d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org 1669d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org this.onCastSessionUpdateBound_ = this.onCastSessionUpdate_.wrap(this); 1679d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org 1689d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org Object.seal(this); 1699d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org} 1709d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org 1719d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.orgVideoPlayer.prototype = { 1729d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org get controls() { 1739d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org return this.controls_; 1749d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org } 1759d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org}; 1769d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org 1779d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org/** 1789d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org * Initializes the video player window. This method must be called after DOM 1799d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org * initialization. 1809d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org * @param {Array.<Object.<string, Object>>} videos List of videos. 1819d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org */ 1829d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.orgVideoPlayer.prototype.prepare = function(videos) { 1839d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org this.videos_ = videos; 1849d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org 1859d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org var preventDefault = function(event) { event.preventDefault(); }.wrap(null); 1869d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org 1879d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org document.ondragstart = preventDefault; 1889d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org 18969cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com var maximizeButton = document.querySelector('.maximize-button'); 1901971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com maximizeButton.addEventListener( 19169cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com 'click', 19269cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com function(event) { 1935e9bf82814aa5d1503c39dd14c420d6db30055dcbsalomon@google.com var appWindow = chrome.app.window.current(); 1945e9bf82814aa5d1503c39dd14c420d6db30055dcbsalomon@google.com if (appWindow.isMaximized()) 1955e9bf82814aa5d1503c39dd14c420d6db30055dcbsalomon@google.com appWindow.restore(); 1961971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com else 197dc3c78076ea279d4f6d502b3b42471e9b2bba48ebsalomon@google.com appWindow.maximize(); 198dc3c78076ea279d4f6d502b3b42471e9b2bba48ebsalomon@google.com event.stopPropagation(); 199dc3c78076ea279d4f6d502b3b42471e9b2bba48ebsalomon@google.com }.wrap(null)); 200dc3c78076ea279d4f6d502b3b42471e9b2bba48ebsalomon@google.com maximizeButton.addEventListener('mousedown', preventDefault); 201dc3c78076ea279d4f6d502b3b42471e9b2bba48ebsalomon@google.com 20269cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com var minimizeButton = document.querySelector('.minimize-button'); 20369cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com minimizeButton.addEventListener( 20469cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com 'click', 2051971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com function(event) { 2061971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com chrome.app.window.current().minimize(); 2071971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com event.stopPropagation(); 2081971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com }.wrap(null)); 209dc3c78076ea279d4f6d502b3b42471e9b2bba48ebsalomon@google.com minimizeButton.addEventListener('mousedown', preventDefault); 210dc3c78076ea279d4f6d502b3b42471e9b2bba48ebsalomon@google.com 211dc3c78076ea279d4f6d502b3b42471e9b2bba48ebsalomon@google.com var closeButton = document.querySelector('.close-button'); 212dc3c78076ea279d4f6d502b3b42471e9b2bba48ebsalomon@google.com closeButton.addEventListener( 213dc3c78076ea279d4f6d502b3b42471e9b2bba48ebsalomon@google.com 'click', 214dc3c78076ea279d4f6d502b3b42471e9b2bba48ebsalomon@google.com function(event) { 215dc3c78076ea279d4f6d502b3b42471e9b2bba48ebsalomon@google.com close(); 216dc3c78076ea279d4f6d502b3b42471e9b2bba48ebsalomon@google.com event.stopPropagation(); 217dc3c78076ea279d4f6d502b3b42471e9b2bba48ebsalomon@google.com }.wrap(null)); 218dc3c78076ea279d4f6d502b3b42471e9b2bba48ebsalomon@google.com closeButton.addEventListener('mousedown', preventDefault); 219dc3c78076ea279d4f6d502b3b42471e9b2bba48ebsalomon@google.com 220dc3c78076ea279d4f6d502b3b42471e9b2bba48ebsalomon@google.com var menu = document.querySelector('#cast-menu'); 221dc3c78076ea279d4f6d502b3b42471e9b2bba48ebsalomon@google.com cr.ui.decorate(menu, cr.ui.Menu); 222dc3c78076ea279d4f6d502b3b42471e9b2bba48ebsalomon@google.com 223dc3c78076ea279d4f6d502b3b42471e9b2bba48ebsalomon@google.com this.controls_ = new FullWindowVideoControls( 224dc3c78076ea279d4f6d502b3b42471e9b2bba48ebsalomon@google.com document.querySelector('#video-player'), 225dc3c78076ea279d4f6d502b3b42471e9b2bba48ebsalomon@google.com document.querySelector('#video-container'), 22620e542e00eccaf7b9e81964692a47086e6aaf568bsalomon@google.com document.querySelector('#controls')); 22720e542e00eccaf7b9e81964692a47086e6aaf568bsalomon@google.com 22820e542e00eccaf7b9e81964692a47086e6aaf568bsalomon@google.com var reloadVideo = function(e) { 22920e542e00eccaf7b9e81964692a47086e6aaf568bsalomon@google.com if (this.controls_.decodeErrorOccured && 23020e542e00eccaf7b9e81964692a47086e6aaf568bsalomon@google.com // Ignore shortcut keys 231dc3c78076ea279d4f6d502b3b42471e9b2bba48ebsalomon@google.com !e.ctrlKey && !e.altKey && !e.shiftKey && !e.metaKey) { 2321971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com this.reloadCurrentVideo(function() { 2331971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com this.videoElement_.play(); 2341971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com }.wrap(this)); 2351971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com e.preventDefault(); 2361971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com } 2371971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com }.wrap(this); 2381971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com 2391971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com var arrowRight = document.querySelector('.arrow-box .arrow.right'); 240dc3c78076ea279d4f6d502b3b42471e9b2bba48ebsalomon@google.com arrowRight.addEventListener('click', this.advance_.wrap(this, 1)); 241dc3c78076ea279d4f6d502b3b42471e9b2bba48ebsalomon@google.com var arrowLeft = document.querySelector('.arrow-box .arrow.left'); 242dc3c78076ea279d4f6d502b3b42471e9b2bba48ebsalomon@google.com arrowLeft.addEventListener('click', this.advance_.wrap(this, 0)); 2431971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com 2441971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com var videoPlayerElement = document.querySelector('#video-player'); 245dc3c78076ea279d4f6d502b3b42471e9b2bba48ebsalomon@google.com if (videos.length > 1) 246dc3c78076ea279d4f6d502b3b42471e9b2bba48ebsalomon@google.com videoPlayerElement.setAttribute('multiple', true); 2471971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com else 2481971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com videoPlayerElement.removeAttribute('multiple'); 2491971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com 2501971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com document.addEventListener('keydown', reloadVideo); 2511971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com document.addEventListener('click', reloadVideo); 2521971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com}; 2531971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com 2541971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com/** 2551971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com * Unloads the player. 2561971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com */ 2571971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.comfunction unload() { 2581971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com // Releases keep awake just in case (should be released on unloading video). 2591971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com chrome.power.releaseKeepAwake(); 2601971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com 2611971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com if (!player.controls || !player.controls.getMedia()) 2621971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com return; 2631971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com 2641971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com player.controls.savePosition(true /* exiting */); 2651971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com player.controls.cleanup(); 2661971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com} 2671971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com 2681971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com/** 2691971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com * Loads the video file. 2701971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com * @param {Object} video Data of the video file. 2711971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com * @param {function()=} opt_callback Completion callback. 272dc3c78076ea279d4f6d502b3b42471e9b2bba48ebsalomon@google.com * @private 27369cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com */ 27469cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.comVideoPlayer.prototype.loadVideo_ = function(video, opt_callback) { 27569cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com this.unloadVideo(true); 27669cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com 27769cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com this.loadQueue_.run(function(callback) { 27869cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com document.title = video.title; 27969cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com 28069cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com document.querySelector('#title').innerText = video.title; 28169cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com 28269cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com var videoPlayerElement = document.querySelector('#video-player'); 28369cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com if (this.currentPos_ === (this.videos_.length - 1)) 28469cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com videoPlayerElement.setAttribute('last-video', true); 28569cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com else 28669cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com videoPlayerElement.removeAttribute('last-video'); 28769cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com 28869cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com if (this.currentPos_ === 0) 28969cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com videoPlayerElement.setAttribute('first-video', true); 29069cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com else 29169cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com videoPlayerElement.removeAttribute('first-video'); 29269cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com 29369cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com // Re-enables ui and hides error message if already displayed. 29469cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com document.querySelector('#video-player').removeAttribute('disabled'); 29569cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com document.querySelector('#error').removeAttribute('visible'); 29669cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com this.controls.detachMedia(); 29769cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com this.controls.inactivityWatcher.disabled = true; 29869cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com this.controls.decodeErrorOccured = false; 29969cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com this.controls.casting = !!this.currentCast_; 30069cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com 30169cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com videoPlayerElement.setAttribute('loading', true); 30269cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com 30369cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com var media = new MediaManager(video.entry); 30469cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com 30569cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com Promise.all([media.getThumbnail(), media.getToken()]) 30669cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com .then(function(results) { 30769cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com var url = results[0]; 30869cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com var token = results[1]; 30969cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com if (url && token) { 31069cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com document.querySelector('#thumbnail').style.backgroundImage = 31169cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com 'url(' + url + '&access_token=' + token + ')'; 31269cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com } else { 31369cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com document.querySelector('#thumbnail').style.backgroundImage = ''; 31469cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com } 31569cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com }) 31669cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com .catch(function() { 31769cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com // Shows no image on error. 31869cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com document.querySelector('#thumbnail').style.backgroundImage = ''; 31969cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com }); 32069cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com 32169cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com var videoElementInitializePromise; 32269cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com if (this.currentCast_) { 32369cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com videoPlayerElement.setAttribute('casting', true); 32469cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com 32569cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com document.querySelector('#cast-name').textContent = 32669cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com this.currentCast_.friendlyName; 32769cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com 32869cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com videoPlayerElement.setAttribute('castable', true); 32969cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com 33069cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com videoElementInitializePromise = media.isAvailableForCast() 33169cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com .then(function(result) { 33269cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com if (!result) 333 return Promise.reject('No casts are available.'); 334 335 return new Promise(function(fulfill, reject) { 336 chrome.cast.requestSession( 337 fulfill, reject, undefined, this.currentCast_.label); 338 }.bind(this)).then(function(session) { 339 session.addUpdateListener(this.onCastSessionUpdateBound_); 340 341 this.currentSession_ = session; 342 this.videoElement_ = new CastVideoElement(media, session); 343 this.controls.attachMedia(this.videoElement_); 344 }.bind(this)); 345 }.bind(this)); 346 } else { 347 videoPlayerElement.removeAttribute('casting'); 348 349 this.videoElement_ = document.createElement('video'); 350 document.querySelector('#video-container').appendChild( 351 this.videoElement_); 352 353 this.controls.attachMedia(this.videoElement_); 354 this.videoElement_.src = video.url; 355 356 media.isAvailableForCast().then(function(result) { 357 if (result) 358 videoPlayerElement.setAttribute('castable', true); 359 else 360 videoPlayerElement.removeAttribute('castable'); 361 }).catch(function() { 362 videoPlayerElement.setAttribute('castable', true); 363 }); 364 365 videoElementInitializePromise = Promise.resolve(); 366 } 367 368 videoElementInitializePromise 369 .then(function() { 370 var handler = function(currentPos) { 371 if (currentPos === this.currentPos_) { 372 if (opt_callback) 373 opt_callback(); 374 videoPlayerElement.removeAttribute('loading'); 375 this.controls.inactivityWatcher.disabled = false; 376 } 377 378 this.videoElement_.removeEventListener('loadedmetadata', handler); 379 }.wrap(this, this.currentPos_); 380 381 this.videoElement_.addEventListener('loadedmetadata', handler); 382 383 this.videoElement_.addEventListener('play', function() { 384 chrome.power.requestKeepAwake('display'); 385 }.wrap()); 386 this.videoElement_.addEventListener('pause', function() { 387 chrome.power.releaseKeepAwake(); 388 }.wrap()); 389 390 this.videoElement_.load(); 391 callback(); 392 }.bind(this)) 393 // In case of error. 394 .catch(function(error) { 395 videoPlayerElement.removeAttribute('loading'); 396 console.error('Failed to initialize the video element.', 397 error.stack || error); 398 this.controls_.showErrorMessage('GALLERY_VIDEO_ERROR'); 399 callback(); 400 }.bind(this)); 401 }.wrap(this)); 402}; 403 404/** 405 * Plays the first video. 406 */ 407VideoPlayer.prototype.playFirstVideo = function() { 408 this.currentPos_ = 0; 409 this.reloadCurrentVideo(this.onFirstVideoReady_.wrap(this)); 410}; 411 412/** 413 * Unloads the current video. 414 * @param {boolean=} opt_keepSession If true, keep using the current session. 415 * Otherwise, discards the session. 416 */ 417VideoPlayer.prototype.unloadVideo = function(opt_keepSession) { 418 this.loadQueue_.run(function(callback) { 419 chrome.power.releaseKeepAwake(); 420 421 // Detaches the media from the control. 422 this.controls.detachMedia(); 423 424 if (this.videoElement_) { 425 // If the element has dispose method, call it (CastVideoElement has it). 426 if (this.videoElement_.dispose) 427 this.videoElement_.dispose(); 428 // Detach the previous video element, if exists. 429 if (this.videoElement_.parentNode) 430 this.videoElement_.parentNode.removeChild(this.videoElement_); 431 } 432 this.videoElement_ = null; 433 434 if (!opt_keepSession && this.currentSession_) { 435 this.currentSession_.stop(callback, callback); 436 this.currentSession_.removeUpdateListener(this.onCastSessionUpdateBound_); 437 this.currentSession_ = null; 438 } else { 439 callback(); 440 } 441 }.wrap(this)); 442}; 443 444/** 445 * Called when the first video is ready after starting to load. 446 * @private 447 */ 448VideoPlayer.prototype.onFirstVideoReady_ = function() { 449 var videoWidth = this.videoElement_.videoWidth; 450 var videoHeight = this.videoElement_.videoHeight; 451 452 var aspect = videoWidth / videoHeight; 453 var newWidth = videoWidth; 454 var newHeight = videoHeight; 455 456 var shrinkX = newWidth / window.screen.availWidth; 457 var shrinkY = newHeight / window.screen.availHeight; 458 if (shrinkX > 1 || shrinkY > 1) { 459 if (shrinkY > shrinkX) { 460 newHeight = newHeight / shrinkY; 461 newWidth = newHeight * aspect; 462 } else { 463 newWidth = newWidth / shrinkX; 464 newHeight = newWidth / aspect; 465 } 466 } 467 468 var oldLeft = window.screenX; 469 var oldTop = window.screenY; 470 var oldWidth = window.outerWidth; 471 var oldHeight = window.outerHeight; 472 473 if (!oldWidth && !oldHeight) { 474 oldLeft = window.screen.availWidth / 2; 475 oldTop = window.screen.availHeight / 2; 476 } 477 478 var appWindow = chrome.app.window.current(); 479 appWindow.resizeTo(newWidth, newHeight); 480 appWindow.moveTo(oldLeft - (newWidth - oldWidth) / 2, 481 oldTop - (newHeight - oldHeight) / 2); 482 appWindow.show(); 483 484 this.videoElement_.play(); 485}; 486 487/** 488 * Advances to the next (or previous) track. 489 * 490 * @param {boolean} direction True to the next, false to the previous. 491 * @private 492 */ 493VideoPlayer.prototype.advance_ = function(direction) { 494 var newPos = this.currentPos_ + (direction ? 1 : -1); 495 if (0 <= newPos && newPos < this.videos_.length) { 496 this.currentPos_ = newPos; 497 this.reloadCurrentVideo(function() { 498 this.videoElement_.play(); 499 }.wrap(this)); 500 } 501}; 502 503/** 504 * Reloads the current video. 505 * 506 * @param {function()=} opt_callback Completion callback. 507 */ 508VideoPlayer.prototype.reloadCurrentVideo = function(opt_callback) { 509 var currentVideo = this.videos_[this.currentPos_]; 510 this.loadVideo_(currentVideo, opt_callback); 511}; 512 513/** 514 * Invokes when a menuitem in the cast menu is selected. 515 * @param {Object} cast Selected element in the list of casts. 516 * @private 517 */ 518VideoPlayer.prototype.onCastSelected_ = function(cast) { 519 // If the selected item is same as the current item, do nothing. 520 if ((this.currentCast_ && this.currentCast_.label) === (cast && cast.label)) 521 return; 522 523 this.unloadVideo(false); 524 525 // Waits for unloading video. 526 this.loadQueue_.run(function(callback) { 527 this.currentCast_ = cast || null; 528 this.updateCheckOnCastMenu_(); 529 this.reloadCurrentVideo(); 530 callback(); 531 }.wrap(this)); 532}; 533 534/** 535 * Set the list of casts. 536 * @param {Array.<Object>} casts List of casts. 537 */ 538VideoPlayer.prototype.setCastList = function(casts) { 539 var videoPlayerElement = document.querySelector('#video-player'); 540 var menu = document.querySelector('#cast-menu'); 541 menu.innerHTML = ''; 542 543 // TODO(yoshiki): Handle the case that the current cast disappears. 544 545 if (casts.length === 0) { 546 videoPlayerElement.removeAttribute('cast-available'); 547 if (this.currentCast_) 548 this.onCurrentCastDisappear_(); 549 return; 550 } 551 552 if (this.currentCast_) { 553 var currentCastAvailable = casts.some(function(cast) { 554 return this.currentCast_.label === cast.label; 555 }.wrap(this)); 556 557 if (!currentCastAvailable) 558 this.onCurrentCastDisappear_(); 559 } 560 561 var item = new cr.ui.MenuItem(); 562 item.label = loadTimeData.getString('VIDEO_PLAYER_PLAY_THIS_COMPUTER'); 563 item.setAttribute('aria-label', item.label); 564 item.castLabel = ''; 565 item.addEventListener('activate', this.onCastSelected_.wrap(this, null)); 566 menu.appendChild(item); 567 568 for (var i = 0; i < casts.length; i++) { 569 var item = new cr.ui.MenuItem(); 570 item.label = casts[i].friendlyName; 571 item.setAttribute('aria-label', item.label); 572 item.castLabel = casts[i].label; 573 item.addEventListener('activate', 574 this.onCastSelected_.wrap(this, casts[i])); 575 menu.appendChild(item); 576 } 577 this.updateCheckOnCastMenu_(); 578 videoPlayerElement.setAttribute('cast-available', true); 579}; 580 581/** 582 * Updates the check status of the cast menu items. 583 * @private 584 */ 585VideoPlayer.prototype.updateCheckOnCastMenu_ = function() { 586 var menu = document.querySelector('#cast-menu'); 587 var menuItems = menu.menuItems; 588 for (var i = 0; i < menuItems.length; i++) { 589 var item = menuItems[i]; 590 if (this.currentCast_ === null) { 591 // Playing on this computer. 592 if (item.castLabel === '') 593 item.checked = true; 594 else 595 item.checked = false; 596 } else { 597 // Playing on cast device. 598 if (item.castLabel === this.currentCast_.label) 599 item.checked = true; 600 else 601 item.checked = false; 602 } 603 } 604}; 605 606/** 607 * Called when the current cast is disappear from the cast list. 608 * @private 609 */ 610VideoPlayer.prototype.onCurrentCastDisappear_ = function() { 611 this.currentCast_ = null; 612 if (this.currentSession_) { 613 this.currentSession_.removeUpdateListener(this.onCastSessionUpdateBound_); 614 this.currentSession_ = null; 615 } 616 this.controls.showErrorMessage('GALLERY_VIDEO_DECODING_ERROR'); 617 this.unloadVideo(); 618}; 619 620/** 621 * This method should be called when the session is updated. 622 * @param {boolean} alive Whether the session is alive or not. 623 * @private 624 */ 625VideoPlayer.prototype.onCastSessionUpdate_ = function(alive) { 626 if (!alive) 627 this.unloadVideo(); 628}; 629 630/** 631 * Initialize the list of videos. 632 * @param {function(Array.<Object>)} callback Called with the video list when 633 * it is ready. 634 */ 635function initVideos(callback) { 636 if (window.videos) { 637 var videos = window.videos; 638 window.videos = null; 639 callback(videos); 640 return; 641 } 642 643 chrome.runtime.onMessage.addListener( 644 function(request, sender, sendResponse) { 645 var videos = window.videos; 646 window.videos = null; 647 callback(videos); 648 }.wrap(null)); 649} 650 651var player = new VideoPlayer(); 652 653/** 654 * Initializes the strings. 655 * @param {function()} callback Called when the sting data is ready. 656 */ 657function initStrings(callback) { 658 chrome.fileManagerPrivate.getStrings(function(strings) { 659 loadTimeData.data = strings; 660 i18nTemplate.process(document, loadTimeData); 661 callback(); 662 }.wrap(null)); 663} 664 665var initPromise = Promise.all( 666 [new Promise(initVideos.wrap(null)), 667 new Promise(initStrings.wrap(null)), 668 new Promise(util.addPageLoadHandler.wrap(null))]); 669 670initPromise.then(function(results) { 671 var videos = results[0]; 672 player.prepare(videos); 673 return new Promise(player.playFirstVideo.wrap(player)); 674}.wrap(null)); 675