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

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: Addressed comments Created 6 years, 11 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 // Cpyright 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 * Initialize 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 * Register 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 prev 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 * Go 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 * Schedule automatic advance to the next track after a timeout.
mtomasz 2014/01/27 01:09:24 Schedule -> Schedules
yoshiki 2014/01/27 07:12:08 Done.
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 * Cancel the scheduled auto advance.
mtomasz 2014/01/27 01:09:24 Cancel -> Cancels and so on for method names.
yoshiki 2014/01/27 07:12:08 Done.
240 * @private
241 */
242 cancelAutoAdvance_: function() {
243 if (this.autoAdvanceTimer_) {
244 clearTimeout(this.autoAdvanceTimer_);
245 this.autoAdvanceTimer_ = null;
246 }
247 },
248
249 set currentTrackIndex(value) {
mtomasz 2014/01/27 01:09:24 nit: Please add a simple jsdoc. Without descriptio
yoshiki 2014/01/27 07:12:08 Done.
250 this.trackList.currentTrackIndex = value;
251 },
252 get currentTrackIndex() {
253 return this.trackList.currentTrackIndex;
254 },
255
256 /**
257 * Setter of 'tracks' property.
258 *
259 * This ends current operation including playback, and restarts playback if
260 * necessary.
261 *
262 * @type {Array.<AudioPlayer.TrackInfo>}
263 */
264 set tracks(tracks) {
265 if (this.trackList.tracks === tracks)
266 return;
267
268 this.cancelAutoAdvance_();
269
270 this.trackList.tracks = tracks;
271 var currentTrack = this.trackList.getCurrentTrack();
272 if (currentTrack && currentTrack.url != this.audioElement.src) {
273 this.audioElement.src = currentTrack.url;
274 this.audioElement.play();
275 }
276 },
277
278 /**
279 * Getter of 'tracks' property.
280 * This returns 'tracks' in the track list element.
281 *
282 * @type {Array.<AudioPlayer.TrackInfo>}
283 */
284 get tracks() {
285 return this.trackList ? this.trackList.tracks : null;
286 },
287
288 /**
289 * Returns whether the track list is expanded or not.
mtomasz 2014/01/27 01:09:24 jsdoc missing
yoshiki 2014/01/27 07:12:08 Done.
290 */
291 isExpanded: function() {
292 return this.audioController.playlistExpanded;
293 },
294
295 /**
296 * Expands or collapse the track list.
mtomasz 2014/01/27 01:09:24 ditto, please check jsdocs.
yoshiki 2014/01/27 07:12:08 Done.
297 */
298 expand: function(expand) {
299 this.audioController.playlistExpanded = !!expand;
300 }
301 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698