Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * @param {!HTMLElement} playerContainer Main container. | 6 * @param {!HTMLElement} playerContainer Main container. |
| 7 * @param {!HTMLElement} videoContainer Container for the video element. | 7 * @param {!HTMLElement} videoContainer Container for the video element. |
| 8 * @param {!HTMLElement} controlsContainer Container for video controls. | 8 * @param {!HTMLElement} controlsContainer Container for video controls. |
| 9 * @constructor | 9 * @constructor |
| 10 * @struct | 10 * @struct |
| (...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 270 arrowRight.addEventListener('click', this.advance_.wrap(this, 1)); | 270 arrowRight.addEventListener('click', this.advance_.wrap(this, 1)); |
| 271 var arrowLeft = queryRequiredElement('.arrow-box .arrow.left'); | 271 var arrowLeft = queryRequiredElement('.arrow-box .arrow.left'); |
| 272 arrowLeft.addEventListener('click', this.advance_.wrap(this, 0)); | 272 arrowLeft.addEventListener('click', this.advance_.wrap(this, 0)); |
| 273 | 273 |
| 274 var videoPlayerElement = getRequiredElement('video-player'); | 274 var videoPlayerElement = getRequiredElement('video-player'); |
| 275 if (videos.length > 1) | 275 if (videos.length > 1) |
| 276 videoPlayerElement.setAttribute('multiple', true); | 276 videoPlayerElement.setAttribute('multiple', true); |
| 277 else | 277 else |
| 278 videoPlayerElement.removeAttribute('multiple'); | 278 videoPlayerElement.removeAttribute('multiple'); |
| 279 | 279 |
| 280 var castButton = queryRequiredElement('.cast-button'); | |
| 281 castButton.addEventListener('click', | |
| 282 this.onCastButtonClicked_.wrap(this)); | |
| 283 | |
| 280 document.addEventListener('keydown', reloadVideo); | 284 document.addEventListener('keydown', reloadVideo); |
| 281 document.addEventListener('click', reloadVideo); | 285 document.addEventListener('click', reloadVideo); |
| 282 }; | 286 }; |
| 283 | 287 |
| 284 /** | 288 /** |
| 285 * Unloads the player. | 289 * Unloads the player. |
| 286 */ | 290 */ |
| 287 function unload() { | 291 function unload() { |
| 288 // Releases keep awake just in case (should be released on unloading video). | 292 // Releases keep awake just in case (should be released on unloading video). |
| 289 chrome.power.releaseKeepAwake(); | 293 chrome.power.releaseKeepAwake(); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 352 }) | 356 }) |
| 353 .catch(function() { | 357 .catch(function() { |
| 354 // Shows no image on error. | 358 // Shows no image on error. |
| 355 getRequiredElement('thumbnail').style.backgroundImage = ''; | 359 getRequiredElement('thumbnail').style.backgroundImage = ''; |
| 356 }); | 360 }); |
| 357 | 361 |
| 358 var videoElementInitializePromise; | 362 var videoElementInitializePromise; |
| 359 if (this.currentCast_) { | 363 if (this.currentCast_) { |
| 360 metrics.recordPlayType(metrics.PLAY_TYPE.CAST); | 364 metrics.recordPlayType(metrics.PLAY_TYPE.CAST); |
| 361 | 365 |
| 362 videoPlayerElement.setAttribute('casting', true); | |
| 363 | |
| 364 getRequiredElement('cast-name').textContent = | 366 getRequiredElement('cast-name').textContent = |
| 365 this.currentCast_.friendlyName; | 367 this.currentCast_.friendlyName; |
| 366 | 368 |
| 367 videoPlayerElement.setAttribute('castable', true); | 369 videoPlayerElement.setAttribute('castable', true); |
| 368 | 370 |
| 369 videoElementInitializePromise = media.isAvailableForCast() | 371 videoElementInitializePromise = media.isAvailableForCast() |
| 370 .then(function(result) { | 372 .then(function(result) { |
| 371 if (!result) | 373 if (!result) |
| 372 return Promise.reject('No casts are available.'); | 374 return Promise.reject('No casts are available.'); |
| 373 | 375 |
| 374 return new Promise(function(fulfill, reject) { | 376 return new Promise(function(fulfill, reject) { |
| 375 chrome.cast.requestSession( | 377 if (this.currentSession_) { |
| 376 fulfill, reject, undefined, this.currentCast_.label); | 378 fulfill(this.currentSession_); |
| 379 } else { | |
| 380 chrome.cast.requestSession( | |
| 381 fulfill, reject, undefined, this.currentCast_.label); | |
| 382 } | |
| 377 }.bind(this)).then(function(session) { | 383 }.bind(this)).then(function(session) { |
| 384 videoPlayerElement.setAttribute('casting', true); | |
| 378 session.addUpdateListener(this.onCastSessionUpdateBound_); | 385 session.addUpdateListener(this.onCastSessionUpdateBound_); |
| 379 | 386 |
| 380 this.currentSession_ = session; | 387 this.currentSession_ = session; |
| 381 this.videoElement_ = new CastVideoElement(media, session); | 388 this.videoElement_ = new CastVideoElement(media, session); |
| 382 }.bind(this)); | 389 }.bind(this)); |
| 383 }.bind(this)); | 390 }.bind(this)); |
| 384 } else { | 391 } else { |
| 385 metrics.recordPlayType(metrics.PLAY_TYPE.LOCAL); | 392 metrics.recordPlayType(metrics.PLAY_TYPE.LOCAL); |
| 386 videoPlayerElement.removeAttribute('casting'); | 393 videoPlayerElement.removeAttribute('casting'); |
| 387 | 394 |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 496 // If the element has dispose method, call it (CastVideoElement has it). | 503 // If the element has dispose method, call it (CastVideoElement has it). |
| 497 if (this.videoElement_.dispose) | 504 if (this.videoElement_.dispose) |
| 498 this.videoElement_.dispose(); | 505 this.videoElement_.dispose(); |
| 499 // Detach the previous video element, if exists. | 506 // Detach the previous video element, if exists. |
| 500 if (this.videoElement_.parentNode) | 507 if (this.videoElement_.parentNode) |
| 501 this.videoElement_.parentNode.removeChild(this.videoElement_); | 508 this.videoElement_.parentNode.removeChild(this.videoElement_); |
| 502 } | 509 } |
| 503 this.videoElement_ = null; | 510 this.videoElement_ = null; |
| 504 | 511 |
| 505 if (!opt_keepSession && this.currentSession_) { | 512 if (!opt_keepSession && this.currentSession_) { |
| 506 this.currentSession_.stop(callback, callback); | 513 if (this.currentSession_.status === chrome.cast.SessionStatus.CONNECTED) |
|
fukino
2016/05/18 05:02:21
bug fix: We should not request stop() if the curre
yoshiki
2016/05/19 07:23:37
nit: Please add a comment for that.
fukino
2016/05/19 08:11:06
Done.
| |
| 514 this.currentSession_.stop(callback, callback); | |
| 515 else | |
| 516 setTimeout(callback); | |
| 507 this.currentSession_.removeUpdateListener(this.onCastSessionUpdateBound_); | 517 this.currentSession_.removeUpdateListener(this.onCastSessionUpdateBound_); |
| 508 this.currentSession_ = null; | 518 this.currentSession_ = null; |
| 509 } else { | 519 } else { |
| 510 callback(); | 520 callback(); |
| 511 } | 521 } |
| 512 }.wrap(this)); | 522 }.wrap(this)); |
| 513 }; | 523 }; |
| 514 | 524 |
| 515 /** | 525 /** |
| 516 * Called when the first video is ready after starting to load. | 526 * Called when the first video is ready after starting to load. |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 646 item.castLabel = casts[i].label; | 656 item.castLabel = casts[i].label; |
| 647 item.addEventListener('activate', | 657 item.addEventListener('activate', |
| 648 this.onCastSelected_.wrap(this, casts[i])); | 658 this.onCastSelected_.wrap(this, casts[i])); |
| 649 menu.appendChild(item); | 659 menu.appendChild(item); |
| 650 } | 660 } |
| 651 this.updateCheckOnCastMenu_(); | 661 this.updateCheckOnCastMenu_(); |
| 652 videoPlayerElement.setAttribute('cast-available', true); | 662 videoPlayerElement.setAttribute('cast-available', true); |
| 653 }; | 663 }; |
| 654 | 664 |
| 655 /** | 665 /** |
| 666 * Tells the availability of cast receivers to VideoPlayeru topdate the | |
| 667 * visibility of the cast button.. | |
|
yoshiki
2016/05/19 07:23:37
nit: JSdoc for the argument.
fukino
2016/05/19 08:11:06
Done.
| |
| 668 */ | |
| 669 VideoPlayer.prototype.setCastAvailability = function(available) { | |
| 670 var videoPlayerElement = getRequiredElement('video-player'); | |
| 671 if (available) { | |
| 672 videoPlayerElement.setAttribute('mr-cast-available', true); | |
| 673 } else { | |
| 674 videoPlayerElement.removeAttribute('mr-cast-available'); | |
| 675 if (this.currentCast_) | |
| 676 this.onCurrentCastDisappear_(); | |
| 677 } | |
| 678 }; | |
| 679 | |
| 680 /** | |
| 681 * Handles click event on cast button to request a session. | |
| 682 * @private | |
| 683 */ | |
| 684 VideoPlayer.prototype.onCastButtonClicked_ = function() { | |
| 685 // This method is called only when Media Router is enabled. | |
| 686 // In this case, requestSession() will open a built-in dialog (not a dropdown | |
| 687 // menu) to choose the receiver, and callback is called with the session | |
| 688 // object after user's operation.. | |
| 689 chrome.cast.requestSession( | |
| 690 function(session) { | |
| 691 this.unloadVideo(true); | |
| 692 this.loadQueue_.run(function(callback) { | |
| 693 this.currentCast_ = { | |
| 694 label: session.receiver.label, | |
| 695 friendlyName: session.receiver.friendlyName | |
| 696 }; | |
| 697 this.currentSession_ = session; | |
| 698 this.reloadCurrentVideo(); | |
| 699 callback(); | |
| 700 }.bind(this)); | |
| 701 }.bind(this), | |
| 702 function(error) { | |
| 703 if (error.code !== chrome.cast.ErrorCode.CANCEL) | |
| 704 console.error('requestSession from cast button failed', error); | |
| 705 }); | |
| 706 }; | |
| 707 | |
| 708 /** | |
| 656 * Updates the check status of the cast menu items. | 709 * Updates the check status of the cast menu items. |
| 657 * @private | 710 * @private |
| 658 */ | 711 */ |
| 659 VideoPlayer.prototype.updateCheckOnCastMenu_ = function() { | 712 VideoPlayer.prototype.updateCheckOnCastMenu_ = function() { |
| 660 var menuItems = getRequiredElement('cast-menu').menuItems; | 713 var menuItems = getRequiredElement('cast-menu').menuItems; |
| 661 for (var i = 0; i < menuItems.length; i++) { | 714 for (var i = 0; i < menuItems.length; i++) { |
| 662 var item = menuItems[i]; | 715 var item = menuItems[i]; |
| 663 if (this.currentCast_ === null) { | 716 if (this.currentCast_ === null) { |
| 664 // Playing on this computer. | 717 // Playing on this computer. |
| 665 if (item.castLabel === '') | 718 if (item.castLabel === '') |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 689 this.controls.showErrorMessage('VIDEO_PLAYER_PLAYBACK_ERROR'); | 742 this.controls.showErrorMessage('VIDEO_PLAYER_PLAYBACK_ERROR'); |
| 690 this.unloadVideo(); | 743 this.unloadVideo(); |
| 691 }; | 744 }; |
| 692 | 745 |
| 693 /** | 746 /** |
| 694 * This method should be called when the session is updated. | 747 * This method should be called when the session is updated. |
| 695 * @param {boolean} alive Whether the session is alive or not. | 748 * @param {boolean} alive Whether the session is alive or not. |
| 696 * @private | 749 * @private |
| 697 */ | 750 */ |
| 698 VideoPlayer.prototype.onCastSessionUpdate_ = function(alive) { | 751 VideoPlayer.prototype.onCastSessionUpdate_ = function(alive) { |
| 699 if (!alive) | 752 if (!alive) { |
| 753 var videoPlayerElement = getRequiredElement('video-player'); | |
| 754 videoPlayerElement.removeAttribute('casting'); | |
| 755 | |
| 756 // Loads the current video in local player. | |
|
fukino
2016/05/18 05:02:21
bug fix: we need to switch to local player even wh
| |
| 700 this.unloadVideo(); | 757 this.unloadVideo(); |
| 758 this.loadQueue_.run(function(callback) { | |
| 759 this.currentCast_ = null; | |
| 760 if (!chrome.cast.usingPresentationApi) | |
| 761 this.updateCheckOnCastMenu_(); | |
| 762 this.reloadCurrentVideo(); | |
| 763 callback(); | |
| 764 }.wrap(this)); | |
| 765 } | |
| 701 }; | 766 }; |
| 702 | 767 |
| 703 /** | 768 /** |
| 704 * Updates the MouseInactivityWatcher's disable property to prevent control | 769 * Updates the MouseInactivityWatcher's disable property to prevent control |
| 705 * panel from being hidden in some situations. | 770 * panel from being hidden in some situations. |
| 706 * @private | 771 * @private |
| 707 */ | 772 */ |
| 708 VideoPlayer.prototype.updateInactivityWatcherState_ = function() { | 773 VideoPlayer.prototype.updateInactivityWatcherState_ = function() { |
| 709 var videoPlayerElement = getRequiredElement('video-player'); | 774 var videoPlayerElement = getRequiredElement('video-player'); |
| 710 // If any of following condition is met, we don't hide the tool bar. | 775 // If any of following condition is met, we don't hide the tool bar. |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 745 return new Promise(function(fulfill, reject) { | 810 return new Promise(function(fulfill, reject) { |
| 746 util.URLsToEntries(window.appState.items, function(entries) { | 811 util.URLsToEntries(window.appState.items, function(entries) { |
| 747 metrics.recordOpenVideoPlayerAction(); | 812 metrics.recordOpenVideoPlayerAction(); |
| 748 metrics.recordNumberOfOpenedFiles(entries.length); | 813 metrics.recordNumberOfOpenedFiles(entries.length); |
| 749 | 814 |
| 750 player.prepare(entries); | 815 player.prepare(entries); |
| 751 player.playFirstVideo(player, fulfill); | 816 player.playFirstVideo(player, fulfill); |
| 752 }.wrap()); | 817 }.wrap()); |
| 753 }.wrap()); | 818 }.wrap()); |
| 754 }.wrap()); | 819 }.wrap()); |
| OLD | NEW |