| Index: chrome/browser/resources/file_manager/js/media/audio_player.js
|
| diff --git a/chrome/browser/resources/file_manager/js/media/audio_player.js b/chrome/browser/resources/file_manager/js/media/audio_player.js
|
| index b5fe9d0d9eacd9bbd4b1b09552abc8a40359fd1a..7fba47773087d0201f7d09c5ee70306dd5cb71cd 100644
|
| --- a/chrome/browser/resources/file_manager/js/media/audio_player.js
|
| +++ b/chrome/browser/resources/file_manager/js/media/audio_player.js
|
| @@ -43,7 +43,7 @@ function AudioPlayer(container) {
|
| createChild('title-button collapse').addEventListener(
|
| 'click', this.onExpandCollapse_.bind(this));
|
|
|
| - this.audioControls_ = new AudioControls(
|
| + this.audioControls_ = new FullWindowAudioControls(
|
| createChild(), this.advance_.bind(this), this.onError_.bind(this));
|
|
|
| this.audioControls_.attachMedia(createChild('', 'audio'));
|
| @@ -58,6 +58,16 @@ function AudioPlayer(container) {
|
| }
|
|
|
| /**
|
| + * Key in the local storage for the list of track urls.
|
| + */
|
| +AudioPlayer.PLAYLIST_KEY = 'audioPlaylist';
|
| +
|
| +/**
|
| + * Key in the local storage for the number of the current track.
|
| + */
|
| +AudioPlayer.TRACK_KEY = 'audioTrack';
|
| +
|
| +/**
|
| * Initial load method (static).
|
| */
|
| AudioPlayer.load = function() {
|
| @@ -71,7 +81,10 @@ AudioPlayer.load = function() {
|
| function getPlaylist() {
|
| chrome.mediaPlayerPrivate.getPlaylist(player.load.bind(player));
|
| }
|
| - getPlaylist();
|
| + if (document.location.hash) // The window is reloading, restore the state.
|
| + player.load(null);
|
| + else
|
| + getPlaylist();
|
| chrome.mediaPlayerPrivate.onPlaylistChanged.addListener(getPlaylist);
|
| });
|
| };
|
| @@ -81,6 +94,24 @@ AudioPlayer.load = function() {
|
| * @param {Playlist} playlist Playlist object passed via mediaPlayerPrivate.
|
| */
|
| AudioPlayer.prototype.load = function(playlist) {
|
| + if (!playlist || !playlist.items.length) {
|
| + // playlist is null if the window is being reloaded.
|
| + // playlist is empty if ChromeOS has restarted with the Audio Player open.
|
| + // Restore the playlist from the local storage. Restore the player state
|
| + // encoded in the page location.
|
| + try {
|
| + playlist = {
|
| + items: JSON.parse(localStorage[AudioPlayer.PLAYLIST_KEY]),
|
| + position: Number(localStorage[AudioPlayer.TRACK_KEY]),
|
| + restore: true
|
| + };
|
| + } catch (ignore) {}
|
| + } else {
|
| + // Remember the playlist for the restart.
|
| + localStorage[AudioPlayer.PLAYLIST_KEY] = JSON.stringify(playlist.items);
|
| + localStorage[AudioPlayer.TRACK_KEY] = playlist.position;
|
| + }
|
| +
|
| this.playlistGeneration_++;
|
|
|
| this.audioControls_.pause();
|
| @@ -92,7 +123,7 @@ AudioPlayer.prototype.load = function(playlist) {
|
| this.invalidTracks_ = {};
|
| this.cancelAutoAdvance_();
|
|
|
| - if (this.urls_.length == 1)
|
| + if (this.urls_.length <= 1)
|
| this.container_.classList.add('single-track');
|
| else
|
| this.container_.classList.remove('single-track');
|
| @@ -105,6 +136,9 @@ AudioPlayer.prototype.load = function(playlist) {
|
| this.trackListItems_ = [];
|
| this.trackStackItems_ = [];
|
|
|
| + if (this.urls_.length == 0)
|
| + return;
|
| +
|
| for (var i = 0; i != this.urls_.length; i++) {
|
| var url = this.urls_[i];
|
| var onClick = this.select_.bind(this, i);
|
| @@ -114,7 +148,7 @@ AudioPlayer.prototype.load = function(playlist) {
|
| new AudioPlayer.TrackInfo(this.trackStack_, url, onClick));
|
| }
|
|
|
| - this.select_(playlist.position);
|
| + this.select_(playlist.position, playlist.restore);
|
|
|
| // This class will be removed if at least one track has art.
|
| this.container_.classList.add('noart');
|
| @@ -154,26 +188,27 @@ AudioPlayer.prototype.displayMetadata_ = function(track, metadata, opt_error) {
|
| /**
|
| * Select a new track to play.
|
| * @param {number} newTrack New track number.
|
| + * @param {boolean} opt_restoreState True if restoring the play state from URL.
|
| * @private
|
| */
|
| -AudioPlayer.prototype.select_ = function(newTrack) {
|
| +AudioPlayer.prototype.select_ = function(newTrack, opt_restoreState) {
|
| if (this.currentTrack_ == newTrack) return;
|
|
|
| this.changeSelectionInList_(this.currentTrack_, newTrack);
|
| this.changeSelectionInStack_(this.currentTrack_, newTrack);
|
|
|
| this.currentTrack_ = newTrack;
|
| + localStorage[AudioPlayer.TRACK_KEY] = this.currentTrack_;
|
| +
|
| this.scrollToCurrent_(false);
|
|
|
| var url = this.urls_[this.currentTrack_];
|
| this.fetchMetadata_(url, function(metadata) {
|
| - var media = this.audioControls_.getMedia();
|
| // Do not try no stream when offline.
|
| - media.src =
|
| + var src =
|
| (navigator.onLine && metadata.streaming && metadata.streaming.url) ||
|
| url;
|
| - media.load();
|
| - this.audioControls_.play();
|
| + this.audioControls_.load(src, opt_restoreState);
|
| }.bind(this));
|
| };
|
|
|
| @@ -448,3 +483,48 @@ AudioPlayer.TrackInfo.prototype.setMetadata = function(
|
| this.artist_.textContent =
|
| error || metadata.media.artist || this.getDefaultArtist();
|
| };
|
| +
|
| +/**
|
| + * Audio controls specific for the Audio Player.
|
| + *
|
| + * @param {HTMLElement} container Parent container.
|
| + * @param {function(boolean)} advanceTrack Parameter: true=forward.
|
| + * @param {function} onError Error handler.
|
| + * @constructor
|
| + */
|
| +function FullWindowAudioControls(container, advanceTrack, onError) {
|
| + AudioControls.apply(this, arguments);
|
| +}
|
| +
|
| +FullWindowAudioControls.prototype = { __proto__: AudioControls.prototype };
|
| +
|
| +/**
|
| + * Enable play state restore from the location hash.
|
| + * @param {string} src Source URL.
|
| + * @param {boolean} restore True if need to restore the play state.
|
| + */
|
| +FullWindowAudioControls.prototype.load = function(src, restore) {
|
| + this.media_.src = src;
|
| + this.media_.load();
|
| + this.restoreWhenLoaded_ = restore;
|
| +};
|
| +
|
| +/**
|
| + * Save the current play state in the location hash so that it survives
|
| + * the page reload.
|
| + */
|
| +FullWindowAudioControls.prototype.onPlayStateChanged = function() {
|
| + this.encodeStateIntoLocation();
|
| +};
|
| +
|
| +/**
|
| + * Restore the Save the play state from the location hash.
|
| + */
|
| +FullWindowAudioControls.prototype.restorePlayState = function() {
|
| + if (this.restoreWhenLoaded_) {
|
| + this.restoreWhenLoaded_ = false; // This should only work once.
|
| + if (this.decodeStateFromLocation())
|
| + return;
|
| + }
|
| + this.play();
|
| +};
|
|
|