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

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: Separete the image files from this patch 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 (c) 2013 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 value.
mtomasz 2014/01/23 08:05:09 nit: Please add a unit (ms?)
yoshiki 2014/01/24 15:34:19 Done.
116 * @param {number} newValue new value.
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, true);
mtomasz 2014/01/23 08:05:09 Can we use an enum instead? It is hard to understa
yoshiki 2014/01/24 15:34:19 Done.
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_(true, true);
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, 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, 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().
mtomasz 2014/01/23 08:05:09 @private missing
yoshiki 2014/01/24 15:34:19 Done.
180 */
181 onAudioStatusUpdate_: function() {
182 this.audioController.time = this.audioElement.currentTime * 1000;
183 this.audioController.duration = this.audioElement.duration * 1000;
184 this.audioController.playing = !this.audioElement.paused;
185 },
186
187 /**
188 * Go to the previous or the next track.
189 * @param {boolean} forward True if next, false if previous.
mtomasz 2014/01/23 08:05:09 One @param missing.
yoshiki 2014/01/24 15:34:19 Done.
190 * @private
191 */
192 advance_: function(forward, repeat) {
193 this.cancelAutoAdvance_();
194
195 var nextTrackIndex = this.trackList.getNextTrackIndex(forward);
196 var nextTrack = this.trackList.tracks[nextTrackIndex];
197 var isNextTrackAvailable = this.trackList.isNextTrackAvailable(forward);
198
199 this.trackList.currentTrackIndex = nextTrackIndex;
200
201 if (isNextTrackAvailable || repeat && nextTrack) {
202 this.audioElement.src = nextTrack.url;
203 this.audioElement.play();
204 } else {
205 this.audioElement.pause();
206 }
207 },
208
209 /**
210 * Timeout ID of auto advance. Used internally in scheduleAutoAdvance_() and
211 * cancelAutoAdvance_().
mtomasz 2014/01/23 08:05:09 No indent for jsdoc descriptions.
yoshiki 2014/01/24 15:34:19 Done.
mtomasz 2014/01/27 01:09:24 The indent still looks off.
212 * @type {number}
213 * @private
214 */
215 autoAdvanceTimer_: null,
216
217 /**
218 * Schedule automatic advance to the next track after a timeout.
mtomasz 2014/01/23 08:05:09 ditto: jsdoc missing
yoshiki 2014/01/24 15:34:19 Done.
219 * @private
220 */
221 scheduleAutoAdvance_: function(forward, repeat) {
222 this.cancelAutoAdvance_();
223 this.autoAdvanceTimer_ = setTimeout(
224 function() {
225 this.autoAdvanceTimer_ = null;
226 // We are advancing only if the next track is not known to be invalid.
227 // This prevents an endless auto-advancing in the case when all tracks
228 // are invalid (we will only visit each track once).
229 this.advance_(forward, repeat, true /* only if valid */);
230 }.bind(this),
231 3000);
mtomasz 2014/01/23 08:05:09 Why do we need a timeout? I think users don't expe
yoshiki 2014/01/24 15:34:19 This gap happens when error is happened and the pl
232 },
233
234 /**
235 * Cancel the scheduled auto advance.
236 * @private
237 */
238 cancelAutoAdvance_: function() {
239 if (this.autoAdvanceTimer_) {
240 clearTimeout(this.autoAdvanceTimer_);
241 this.autoAdvanceTimer_ = null;
242 }
243 },
244
245 set currentTrackIndex(value) {
246 this.trackList.currentTrackIndex = value;
247 },
248 get currentTrackIndex() {
249 return this.trackList.currentTrackIndex;
250 },
251
252 /**
253 * Setter of 'tracks' property.
254 *
255 * This ends current operation including playback, and restarts playback if
mtomasz 2014/01/23 08:05:09 jsdoc missing.
yoshiki 2014/01/24 15:34:19 Done.
256 * necessary.
257 */
258 set tracks(tracks) {
259 if (this.trackList.tracks === tracks)
260 return;
261
262 this.cancelAutoAdvance_();
263
264 this.trackList.tracks = tracks;
265 var currentTrack = this.trackList.getCurrentTrack();
266 if (currentTrack && currentTrack.url != this.audioElement.src) {
267 this.audioElement.src = currentTrack.url;
268 this.audioElement.play();
269 }
270 },
271
272 /**
273 * Getter of 'tracks' property.
mtomasz 2014/01/23 08:05:09 ditto: jsdoc missing
yoshiki 2014/01/24 15:34:19 Done.
274 * This returns 'tracks' in the track list element.
275 */
276 get tracks() {
277 return this.trackList ? this.trackList.tracks : null;
278 },
279
280 /**
281 * Returns whether the track list is expanded or not.
282 */
283 isExpanded: function() {
284 return this.audioController.playlistExpanded;
285 },
286
287 /**
288 * Expands or collapse the track list.
289 */
290 expand: function(expand) {
291 this.audioController.playlistExpanded = !!expand;
292 }
293 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698