Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(432)

Side by Side Diff: chrome/browser/resources/file_manager/audio_player/elements/audio_player.js

Issue 144883002: [Files.app] Initial implementation of new audio player (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Make the script/css files flattened. Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 'use strict';
6
7 Polymer('audio-player', {
8 /**
9 * Child Elements
10 */
11 audioController: null,
12 audioElement: null,
13 trackList: null,
14
15 /**
16 * Initializes an element. This method is called automatically when the
17 * element is ready.
18 */
19 ready: function() {
20 this.audioController = this.$.audioController;
21 this.audioElement = this.$.audio;
22 this.trackList = this.$.trackList;
23
24 this.audioElement.volume = this.audioController.volume / 100;
25 this.audioElement.addEventListener('ended', this.onAudioEnded.bind(this));
26 this.audioElement.addEventListener('error', this.onAudioError.bind(this));
27
28 var onAudioStatusUpdatedBound = this.onAudioStatusUpdate_.bind(this);
29 this.audioElement.addEventListener('timeupdate', onAudioStatusUpdatedBound);
30 this.audioElement.addEventListener('ended', onAudioStatusUpdatedBound);
31 this.audioElement.addEventListener('play', onAudioStatusUpdatedBound);
32 this.audioElement.addEventListener('pause', onAudioStatusUpdatedBound);
33 this.audioElement.addEventListener('suspend', onAudioStatusUpdatedBound);
34 this.audioElement.addEventListener('abort', onAudioStatusUpdatedBound);
35 this.audioElement.addEventListener('error', onAudioStatusUpdatedBound);
36 this.audioElement.addEventListener('emptied', onAudioStatusUpdatedBound);
37 this.audioElement.addEventListener('stalled', onAudioStatusUpdatedBound);
38 },
39
40 /**
41 * Registers handlers for changing of external variables
42 */
43 observe: {
44 'trackList.currentTrackIndex': 'onCurrentTrackIndexChanged',
45 'audioController.playlistExpanded': 'onPlayerExpandedChanged',
46 'audioController.playing': 'onControllerPlayingChanged',
47 'audioController.volume': 'onControllerVolumeChanged',
48 'audioController.time': 'onControllerTimeChanged',
49 'audioController.shuffle': 'onControllerShuffleChanged',
50 'audioController.repeat': 'onControllerRepeatChanged',
51 },
52
53 /**
54 * Invoked when trackList.currentTrackIndex is changed.
55 * @param {number} oldValue old value.
56 * @param {number} newValue new value.
57 */
58 onCurrentTrackIndexChanged: function(oldValue, newValue) {
59 if (oldValue != newValue) {
60 var currentTrack = this.trackList.getCurrentTrack();
61 if (currentTrack && currentTrack.url != this.audioElement.src) {
62 this.audioElement.src = currentTrack.url;
63 this.audioElement.play();
64 }
65 }
66 },
67
68 /**
69 * Invoked when audioController.playlistExpanded is changed.
70 * @param {boolean} oldValue old value.
71 * @param {boolean} newValue new value.
72 */
73 onPlayerExpandedChanged: function(oldValue, newValue) {
74 if (oldValue != newValue) {
75 this.trackList.expanded = newValue;
76 if (AudioPlayer.instance)
77 AudioPlayer.instance.syncExpanded();
78 }
79 },
80
81 /**
82 * Invoked when audioController.playing is changed.
83 * @param {boolean} oldValue old value.
84 * @param {boolean} newValue new value.
85 */
86 onControllerPlayingChanged: function(oldValue, newValue) {
87 if (newValue) {
88 if (!this.audioElement.src) {
89 var currentTrack = this.trackList.getCurrentTrack();
90 if (currentTrack && currentTrack.url != this.audioElement.src)
91 this.audioElement.src = currentTrack.url;
92 }
93
94 if (this.audioElement.src) {
95 this.audioElement.play();
96 return;
97 }
98 }
99
100 this.audioController.playing = false;
101 this.audioElement.pause();
102 },
103
104 /**
105 * Invoked when audioController.volume is changed.
106 * @param {number} oldValue old value.
107 * @param {number} newValue new value.
108 */
109 onControllerVolumeChanged: function(oldValue, newValue) {
110 this.audioElement.volume = newValue / 100;
111 },
112
113 /**
114 * Invoked when audioController.time is changed.
115 * @param {number} oldValue old time (in ms).
116 * @param {number} newValue new time (in ms).
117 */
118 onControllerTimeChanged: function(oldValue, newValue) {
119 // Ignore periodical updates and small amount change.
120 if (Math.abs(oldValue - newValue) <= 500)
121 return;
122
123 if (this.audioElement.readyState !== 0)
124 this.audioElement.currentTime = this.audioController.time / 1000;
125 },
126
127 /**
128 * Invoked when audioController.shuffle is changed.
129 * @param {boolean} oldValue old value.
130 * @param {boolean} newValue new value.
131 */
132 onControllerShuffleChanged: function(oldValue, newValue) {
133 // TODO(yoshiki): Implement shuffle mode.
134 },
135
136 /**
137 * Invoked when audioController.repeat is changed.
138 * @param {boolean} oldValue old value.
139 * @param {boolean} newValue new value.
140 */
141 onControllerRepeatChanged: function(oldValue, newValue) {
142 this.trackList.repeat = newValue;
143 },
144
145 /**
146 * Invoked when the next button in the controller is clicked.
147 * This handler is registered in the 'on-click' attribute of the element.
148 */
149 onControllerNextClicked: function() {
150 this.advance_(true /* forward */, true /* repeat */);
151 },
152
153 /**
154 * Invoked when the previous button in the controller is clicked.
155 * This handler is registered in the 'on-click' attribute of the element.
156 */
157 onControllerPreviousClicked: function() {
158 this.advance_(false /* forward */, true /* repeat */);
159 },
160
161 /**
162 * Invoked when the playback in the audio element is ended.
163 * This handler is registered in this.ready().
164 */
165 onAudioEnded: function() {
166 this.advance_(true /* forward */, this.audioController.repeat);
167 },
168
169 /**
170 * Invoked when the playback in the audio element gets error.
171 * This handler is registered in this.ready().
172 */
173 onAudioError: function() {
174 this.scheduleAutoAdvance_(true /* forward */, this.audioController.repeat);
175 },
176
177 /**
178 * Invoked when the time of playback in the audio element is updated.
179 * This handler is registered in this.ready().
180 * @private
181 */
182 onAudioStatusUpdate_: function() {
183 this.audioController.time = this.audioElement.currentTime * 1000;
184 this.audioController.duration = this.audioElement.duration * 1000;
185 this.audioController.playing = !this.audioElement.paused;
186 },
187
188 /**
189 * Goes to the previous or the next track.
190 * @param {boolean} forward True if next, false if previous.
191 * @param {boolean} repeat True if repeat-mode is enabled. False otherwise.
192 * @private
193 */
194 advance_: function(forward, repeat) {
195 this.cancelAutoAdvance_();
196
197 var nextTrackIndex = this.trackList.getNextTrackIndex(forward);
198 var nextTrack = this.trackList.tracks[nextTrackIndex];
199 var isNextTrackAvailable = this.trackList.isNextTrackAvailable(forward);
200
201 this.trackList.currentTrackIndex = nextTrackIndex;
202
203 if (isNextTrackAvailable || repeat && nextTrack) {
204 this.audioElement.src = nextTrack.url;
205 this.audioElement.play();
206 } else {
207 this.audioElement.pause();
208 }
209 },
210
211 /**
212 * Timeout ID of auto advance. Used internally in scheduleAutoAdvance_() and
213 * cancelAutoAdvance_().
214 * @type {number}
215 * @private
216 */
217 autoAdvanceTimer_: null,
218
219 /**
220 * Schedules automatic advance to the next track after a timeout.
221 * @param {boolean} forward True if next, false if previous.
222 * @param {boolean} repeat True if repeat-mode is enabled. False otherwise.
223 * @private
224 */
225 scheduleAutoAdvance_: function(forward, repeat) {
226 this.cancelAutoAdvance_();
227 this.autoAdvanceTimer_ = setTimeout(
228 function() {
229 this.autoAdvanceTimer_ = null;
230 // We are advancing only if the next track is not known to be invalid.
231 // This prevents an endless auto-advancing in the case when all tracks
232 // are invalid (we will only visit each track once).
233 this.advance_(forward, repeat, true /* only if valid */);
234 }.bind(this),
235 3000);
236 },
237
238 /**
239 * Cancels the scheduled auto advance.
240 * @private
241 */
242 cancelAutoAdvance_: function() {
243 if (this.autoAdvanceTimer_) {
244 clearTimeout(this.autoAdvanceTimer_);
245 this.autoAdvanceTimer_ = null;
246 }
247 },
248
249 /**
250 * The index of the current track.
251 * If the list has no tracks, the value must be -1.
252 *
253 * @type {number}
254 */
255 get currentTrackIndex() {
256 return this.trackList.currentTrackIndex;
257 },
258 set currentTrackIndex(value) {
259 this.trackList.currentTrackIndex = value;
260 },
261
262 /**
263 * The list of the tracks in the playlist.
264 *
265 * When it changed, current operation including playback is stopped and
266 * restarts playback with new tracks if necessary.
267 *
268 * @type {Array.<AudioPlayer.TrackInfo>}
269 */
270 get tracks() {
271 return this.trackList ? this.trackList.tracks : null;
272 },
273 set tracks(tracks) {
274 if (this.trackList.tracks === tracks)
275 return;
276
277 this.cancelAutoAdvance_();
278
279 this.trackList.tracks = tracks;
280 var currentTrack = this.trackList.getCurrentTrack();
281 if (currentTrack && currentTrack.url != this.audioElement.src) {
282 this.audioElement.src = currentTrack.url;
283 this.audioElement.play();
284 }
285 },
286
287 /**
288 * Returns whether the track list is expanded or not.
289 * @return {boolean} True if the list is expanded. False, otherwise.
290 */
291 isExpanded: function() {
292 return this.audioController.playlistExpanded;
293 },
294
295 /**
296 * Expands or collapse the track list.
297 * @param {boolean} True to expand the list, false to collapse.
298 */
299 expand: function(expand) {
300 this.audioController.playlistExpanded = !!expand;
301 },
302
303 /**
304 * Invoked when the audio player is being unloaded.
305 */
306 onPageUnload: function() {
307 this.audioElement.src = ''; // Hack to prevent crashing.
308 },
309 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698