Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 * @fileoverview MediaControls class implements media playback controls | 6 * @fileoverview MediaControls class implements media playback controls |
| 7 * that exist outside of the audio/video HTML element. | 7 * that exist outside of the audio/video HTML element. |
| 8 */ | 8 */ |
| 9 | 9 |
| 10 /** | 10 /** |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 50 */ | 50 */ |
| 51 this.textBanner_ = null; | 51 this.textBanner_ = null; |
| 52 | 52 |
| 53 /** | 53 /** |
| 54 * @type {HTMLElement} | 54 * @type {HTMLElement} |
| 55 * @private | 55 * @private |
| 56 */ | 56 */ |
| 57 this.soundButton_ = null; | 57 this.soundButton_ = null; |
| 58 | 58 |
| 59 /** | 59 /** |
| 60 * @type {HTMLElement} | |
| 61 * @private | |
| 62 */ | |
| 63 this.subtitlesButton_ = null; | |
| 64 | |
| 65 /** | |
| 66 * @private {TextTrack} | |
| 67 */ | |
| 68 this.subtitlesTrack_ = null; | |
| 69 | |
| 70 /** | |
| 60 * @type {boolean} | 71 * @type {boolean} |
| 61 * @private | 72 * @private |
| 62 */ | 73 */ |
| 63 this.resumeAfterDrag_ = false; | 74 this.resumeAfterDrag_ = false; |
| 64 | 75 |
| 65 /** | 76 /** |
| 66 * @type {HTMLElement} | 77 * @type {HTMLElement} |
| 67 * @private | 78 * @private |
| 68 */ | 79 */ |
| 69 this.currentTime_ = null; | 80 this.currentTime_ = null; |
| (...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 511 | 522 |
| 512 /** | 523 /** |
| 513 * @private | 524 * @private |
| 514 */ | 525 */ |
| 515 MediaControls.prototype.onVolumeDrag_ = function() { | 526 MediaControls.prototype.onVolumeDrag_ = function() { |
| 516 if (this.media_.volume !== 0) { | 527 if (this.media_.volume !== 0) { |
| 517 this.savedVolume_ = this.media_.volume; | 528 this.savedVolume_ = this.media_.volume; |
| 518 } | 529 } |
| 519 }; | 530 }; |
| 520 | 531 |
| 532 /** | |
| 533 * Initializes subtitles button. | |
| 534 */ | |
| 535 MediaControls.prototype.initSubtitlesButton = function() { | |
| 536 this.subtitlesTrack_ = null; | |
| 537 this.subtitlesButton_ = | |
| 538 this.createButton('subtitles', this.onSubtitlesButtonClicked_.bind(this)); | |
| 539 this.subtitlesButton_.setAttribute('aria-label', | |
| 540 str('VIDEO_PLAYER_SUBTITLES_BUTTON_LABEL')); | |
| 541 }; | |
| 542 | |
| 543 /** | |
| 544 * @param {Event} event Mouse click event. | |
| 545 * @private | |
| 546 */ | |
| 547 MediaControls.prototype.onSubtitlesButtonClicked_ = function(event) { | |
| 548 if (!this.subtitlesTrack_) { | |
| 549 return; | |
| 550 } | |
| 551 this.toggleSubtitlesMode_(this.subtitlesTrack_.mode === 'hidden'); | |
| 552 }; | |
| 553 | |
| 554 /** | |
| 555 * @param {boolean} on Whether enabled or not. | |
| 556 * @private | |
| 557 */ | |
| 558 MediaControls.prototype.toggleSubtitlesMode_ = function(on) { | |
| 559 if (!this.subtitlesTrack_) { | |
| 560 return; | |
| 561 } | |
| 562 if (on) { | |
| 563 this.subtitlesTrack_.mode = 'showing'; | |
| 564 this.subtitlesButton_.setAttribute('showing', ''); | |
| 565 } else { | |
| 566 this.subtitlesTrack_.mode = 'hidden'; | |
| 567 this.subtitlesButton_.removeAttribute('showing'); | |
| 568 } | |
| 569 }; | |
| 570 | |
| 571 /** | |
| 572 * @param {TextTrack} track Subtitles track | |
| 573 * @private | |
| 574 */ | |
| 575 MediaControls.prototype.attachTextTrack_ = function(track) { | |
| 576 this.subtitlesTrack_ = track; | |
| 577 if (this.subtitlesTrack_) { | |
| 578 this.toggleSubtitlesMode_(true); | |
| 579 this.subtitlesButton_.removeAttribute('unavailable'); | |
| 580 } else { | |
| 581 this.subtitlesButton_.setAttribute('unavailable', ''); | |
| 582 } | |
| 583 }; | |
| 584 | |
| 585 /** | |
| 586 * @private | |
| 587 */ | |
| 588 MediaControls.prototype.detachTextTrack_ = function() { | |
| 589 this.subtitlesTrack_ = null; | |
| 590 }; | |
| 591 | |
| 521 /* | 592 /* |
| 522 * Media event handlers. | 593 * Media event handlers. |
| 523 */ | 594 */ |
| 524 | 595 |
| 525 /** | 596 /** |
| 526 * Attach a media element. | 597 * Attach a media element. |
| 527 * | 598 * |
| 528 * @param {!HTMLMediaElement} mediaElement The media element to control. | 599 * @param {!HTMLMediaElement} mediaElement The media element to control. |
| 529 */ | 600 */ |
| 530 MediaControls.prototype.attachMedia = function(mediaElement) { | 601 MediaControls.prototype.attachMedia = function(mediaElement) { |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 541 this.textBanner_.removeAttribute('visible'); | 612 this.textBanner_.removeAttribute('visible'); |
| 542 | 613 |
| 543 // Reflect the media state in the UI. | 614 // Reflect the media state in the UI. |
| 544 this.onMediaDuration_(); | 615 this.onMediaDuration_(); |
| 545 this.onMediaPlay_(this.isPlaying()); | 616 this.onMediaPlay_(this.isPlaying()); |
| 546 this.onMediaProgress_(); | 617 this.onMediaProgress_(); |
| 547 if (this.volume_) { | 618 if (this.volume_) { |
| 548 /* Copy the user selected volume to the new media element. */ | 619 /* Copy the user selected volume to the new media element. */ |
| 549 this.savedVolume_ = this.media_.volume = this.volume_.ratio; | 620 this.savedVolume_ = this.media_.volume = this.volume_.ratio; |
| 550 } | 621 } |
| 622 if (this.media_.textTracks.length > 0) { | |
| 623 this.attachTextTrack_(this.media_.textTracks[0]); | |
| 624 }else{ | |
|
yoshiki
2016/03/25 13:18:41
nit: spaces before and after "else".
ryoh
2016/03/28 00:27:14
Done.
| |
| 625 this.attachTextTrack_(null); | |
| 626 } | |
| 551 }; | 627 }; |
| 552 | 628 |
| 553 /** | 629 /** |
| 554 * Detach media event handlers. | 630 * Detach media event handlers. |
| 555 */ | 631 */ |
| 556 MediaControls.prototype.detachMedia = function() { | 632 MediaControls.prototype.detachMedia = function() { |
| 557 if (!this.media_) | 633 if (!this.media_) |
| 558 return; | 634 return; |
| 559 | 635 |
| 560 this.media_.removeEventListener('play', this.onMediaPlayBound_); | 636 this.media_.removeEventListener('play', this.onMediaPlayBound_); |
| 561 this.media_.removeEventListener('pause', this.onMediaPauseBound_); | 637 this.media_.removeEventListener('pause', this.onMediaPauseBound_); |
| 562 this.media_.removeEventListener('durationchange', this.onMediaDurationBound_); | 638 this.media_.removeEventListener('durationchange', this.onMediaDurationBound_); |
| 563 this.media_.removeEventListener('timeupdate', this.onMediaProgressBound_); | 639 this.media_.removeEventListener('timeupdate', this.onMediaProgressBound_); |
| 564 this.media_.removeEventListener('error', this.onMediaError_); | 640 this.media_.removeEventListener('error', this.onMediaError_); |
| 565 | 641 |
| 566 this.media_ = null; | 642 this.media_ = null; |
| 643 this.detachTextTrack_(); | |
| 567 }; | 644 }; |
| 568 | 645 |
| 569 /** | 646 /** |
| 570 * Force-empty the media pipeline. This is a workaround for crbug.com/149957. | 647 * Force-empty the media pipeline. This is a workaround for crbug.com/149957. |
| 571 * The document is not going to be GC-ed until the last Files app window closes, | 648 * The document is not going to be GC-ed until the last Files app window closes, |
| 572 * but we want the media pipeline to deinitialize ASAP to minimize leakage. | 649 * but we want the media pipeline to deinitialize ASAP to minimize leakage. |
| 573 */ | 650 */ |
| 574 MediaControls.prototype.cleanup = function() { | 651 MediaControls.prototype.cleanup = function() { |
| 575 if (!this.media_) | 652 if (!this.media_) |
| 576 return; | 653 return; |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 736 * @extends {MediaControls} | 813 * @extends {MediaControls} |
| 737 */ | 814 */ |
| 738 function VideoControls( | 815 function VideoControls( |
| 739 containerElement, onMediaError, opt_fullScreenToggle, opt_stateIconParent) { | 816 containerElement, onMediaError, opt_fullScreenToggle, opt_stateIconParent) { |
| 740 MediaControls.call(this, containerElement, onMediaError); | 817 MediaControls.call(this, containerElement, onMediaError); |
| 741 | 818 |
| 742 this.container_.classList.add('video-controls'); | 819 this.container_.classList.add('video-controls'); |
| 743 this.initPlayButton(); | 820 this.initPlayButton(); |
| 744 this.initTimeControls(); | 821 this.initTimeControls(); |
| 745 this.initVolumeControls(); | 822 this.initVolumeControls(); |
| 823 this.initSubtitlesButton(); | |
| 746 | 824 |
| 747 // Create the cast button. | 825 // Create the cast button. |
| 748 // We need to use <button> since cr.ui.MenuButton.decorate modifies prototype | 826 // We need to use <button> since cr.ui.MenuButton.decorate modifies prototype |
| 749 // chain, by which <files-icon-button> will not work correctly. | 827 // chain, by which <files-icon-button> will not work correctly. |
| 750 // TODO(fukino): Find a way to use files-icon-button consistently. | 828 // TODO(fukino): Find a way to use files-icon-button consistently. |
| 751 this.castButton_ = this.createControl( | 829 this.castButton_ = this.createControl( |
| 752 'cast media-button', undefined, 'button'); | 830 'cast media-button', undefined, 'button'); |
| 753 this.castButton_.setAttribute('menu', '#cast-menu'); | 831 this.castButton_.setAttribute('menu', '#cast-menu'); |
| 754 this.castButton_.setAttribute('aria-label', str('VIDEO_PLAYER_PLAY_ON')); | 832 this.castButton_.setAttribute('aria-label', str('VIDEO_PLAYER_PLAY_ON')); |
| 755 this.castButton_.setAttribute('state', MediaControls.ButtonStateType.DEFAULT); | 833 this.castButton_.setAttribute('state', MediaControls.ButtonStateType.DEFAULT); |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 963 } else { | 1041 } else { |
| 964 this.container_.removeAttribute('fullscreen'); | 1042 this.container_.removeAttribute('fullscreen'); |
| 965 } | 1043 } |
| 966 | 1044 |
| 967 if (this.fullscreenButton_) { | 1045 if (this.fullscreenButton_) { |
| 968 this.fullscreenButton_.setAttribute('aria-label', | 1046 this.fullscreenButton_.setAttribute('aria-label', |
| 969 fullscreen ? str('VIDEO_PLAYER_EXIT_FULL_SCREEN_BUTTON_LABEL') | 1047 fullscreen ? str('VIDEO_PLAYER_EXIT_FULL_SCREEN_BUTTON_LABEL') |
| 970 : str('VIDEO_PLAYER_FULL_SCREEN_BUTTON_LABEL'));; | 1048 : str('VIDEO_PLAYER_FULL_SCREEN_BUTTON_LABEL'));; |
| 971 } | 1049 } |
| 972 }; | 1050 }; |
| OLD | NEW |