Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 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 * @constructor | 6 * @constructor |
| 7 * @extends {PolymerElement} | 7 * @extends {PolymerElement} |
| 8 */ | 8 */ |
| 9 var AudioPlayerElement = function() {}; | 9 var AudioPlayerElement = function() {}; |
| 10 | 10 |
| 11 AudioPlayerElement.prototype = { | 11 AudioPlayerElement.prototype = { |
| 12 // Child Elements | 12 is: 'audio-player', |
| 13 audioController: null, | |
| 14 audioElement: null, | |
| 15 trackList: null, | |
| 16 | 13 |
| 17 // Published values | 14 properties: { |
| 18 playing: true, | 15 /** |
| 19 currenttrackurl: '', | 16 * Flag whether the audio is playing or paused. True if playing, or false |
| 20 playcount: 0, | 17 * paused. |
| 18 */ | |
| 19 playing: { | |
| 20 type: Boolean, | |
| 21 observer: 'playingChanged', | |
| 22 reflectToAttribute: true | |
| 23 }, | |
| 21 | 24 |
| 22 // Attributes of the element (lower characters only). | 25 /** |
| 23 // These values must be used only to data binding and shouldn't be assigned | 26 * Current elapsed time in the current music in millisecond. |
| 24 // any value nowhere except in the handler. | 27 */ |
| 25 publish: { | 28 time: { |
| 26 playing: { | 29 type: Number, |
| 27 value: true, | 30 observer: 'timeChanged' |
| 28 reflect: true | |
| 29 }, | 31 }, |
| 32 | |
| 33 /** | |
| 34 * Whether the shuffle button is ON. | |
| 35 */ | |
| 36 shuffle: { | |
| 37 type: Boolean, | |
| 38 observer: 'shuffleChanged' | |
| 39 }, | |
| 40 | |
| 41 /** | |
| 42 * Whether the repeat button is ON. | |
| 43 */ | |
| 44 repeat: { | |
| 45 type: Boolean, | |
| 46 observer: 'repeatChanged' | |
| 47 }, | |
| 48 | |
| 49 /** | |
| 50 * The audio volume. 0 is silent, and 100 is maximum loud. | |
| 51 */ | |
| 52 volume: { | |
| 53 type: Number, | |
| 54 observer: 'volumeChanged' | |
| 55 }, | |
| 56 | |
| 57 /** | |
| 58 * Whether the expanded button is ON. | |
| 59 */ | |
| 60 expanded: { | |
| 61 type: Boolean, | |
| 62 observer: 'expandedChanged' | |
| 63 }, | |
| 64 | |
| 65 /** | |
| 66 * Track index of the current track. | |
| 67 */ | |
| 68 currentTrackIndex: { | |
| 69 type: Number, | |
| 70 observer: 'currentTrackIndexChanged' | |
| 71 }, | |
| 72 | |
| 73 /** | |
| 74 * Model object of the Audio Player. | |
| 75 * @type {AudioPlayerModel} | |
| 76 */ | |
| 77 model: { | |
| 78 type: Object, | |
| 79 value: null, | |
| 80 observer: 'modelChanged' | |
| 81 }, | |
| 82 | |
| 83 /** | |
| 84 * URL of the current track. (exposed publicly for tests) | |
| 85 */ | |
| 30 currenttrackurl: { | 86 currenttrackurl: { |
| 87 type: String, | |
| 31 value: '', | 88 value: '', |
| 32 reflect: true | 89 reflectToAttribute: true |
| 33 }, | 90 }, |
| 91 | |
| 92 /** | |
| 93 * The number of played tracks. (exposed publicly for tests) | |
| 94 */ | |
| 34 playcount: { | 95 playcount: { |
| 96 type: Number, | |
| 35 value: 0, | 97 value: 0, |
| 36 reflect: true | 98 reflectToAttribute: true |
| 37 } | 99 } |
| 38 }, | 100 }, |
| 39 | 101 |
| 40 /** | 102 /** |
| 41 * Model object of the Audio Player. | 103 * Handles change event for shuffle mode. |
| 42 * @type {AudioPlayerModel} | 104 * @param {boolean} shuffle |
| 43 */ | 105 */ |
| 44 model: null, | 106 shuffleChanged: function(shuffle) { |
| 107 if (this.model) | |
| 108 this.model.shuffle = shuffle; | |
| 109 }, | |
| 110 | |
| 111 /** | |
| 112 * Handles change event for repeat mode. | |
| 113 * @param {boolean} repeat | |
| 114 */ | |
| 115 repeatChanged: function(repeat) { | |
| 116 if (this.model) | |
| 117 this.model.repeat = repeat; | |
| 118 }, | |
| 119 | |
| 120 /** | |
| 121 * Handles change event for audio volume. | |
| 122 * @param {boolean} volume | |
| 123 */ | |
| 124 volumeChanged: function(volume) { | |
| 125 if (this.model) | |
| 126 this.model.volume = volume; | |
| 127 }, | |
| 128 | |
| 129 /** | |
| 130 * Handles change event for expanded state of track list. | |
| 131 */ | |
| 132 expandedChanged: function(expanded) { | |
| 133 if (this.model) | |
| 134 this.model.expanded = expanded; | |
| 135 }, | |
| 45 | 136 |
| 46 /** | 137 /** |
| 47 * Initializes an element. This method is called automatically when the | 138 * Initializes an element. This method is called automatically when the |
| 48 * element is ready. | 139 * element is ready. |
| 49 */ | 140 */ |
| 50 ready: function() { | 141 ready: function() { |
| 51 this.audioController = this.$.audioController; | |
| 52 this.audioElement = this.$.audio; | |
| 53 this.trackList = this.$.trackList; | |
| 54 | |
| 55 this.addEventListener('keydown', this.onKeyDown_.bind(this)); | 142 this.addEventListener('keydown', this.onKeyDown_.bind(this)); |
| 56 | 143 |
| 57 this.audioElement.volume = 0; // Temporary initial volume. | 144 this.$.audio.volume = 0; // Temporary initial volume. |
| 58 this.audioElement.addEventListener('ended', this.onAudioEnded.bind(this)); | 145 this.$.audio.addEventListener('ended', this.onAudioEnded.bind(this)); |
| 59 this.audioElement.addEventListener('error', this.onAudioError.bind(this)); | 146 this.$.audio.addEventListener('error', this.onAudioError.bind(this)); |
| 60 | 147 |
| 61 var onAudioStatusUpdatedBound = this.onAudioStatusUpdate_.bind(this); | 148 var onAudioStatusUpdatedBound = this.onAudioStatusUpdate_.bind(this); |
| 62 this.audioElement.addEventListener('timeupdate', onAudioStatusUpdatedBound); | 149 this.$.audio.addEventListener('timeupdate', onAudioStatusUpdatedBound); |
| 63 this.audioElement.addEventListener('ended', onAudioStatusUpdatedBound); | 150 this.$.audio.addEventListener('ended', onAudioStatusUpdatedBound); |
| 64 this.audioElement.addEventListener('play', onAudioStatusUpdatedBound); | 151 this.$.audio.addEventListener('play', onAudioStatusUpdatedBound); |
| 65 this.audioElement.addEventListener('pause', onAudioStatusUpdatedBound); | 152 this.$.audio.addEventListener('pause', onAudioStatusUpdatedBound); |
| 66 this.audioElement.addEventListener('suspend', onAudioStatusUpdatedBound); | 153 this.$.audio.addEventListener('suspend', onAudioStatusUpdatedBound); |
| 67 this.audioElement.addEventListener('abort', onAudioStatusUpdatedBound); | 154 this.$.audio.addEventListener('abort', onAudioStatusUpdatedBound); |
| 68 this.audioElement.addEventListener('error', onAudioStatusUpdatedBound); | 155 this.$.audio.addEventListener('error', onAudioStatusUpdatedBound); |
| 69 this.audioElement.addEventListener('emptied', onAudioStatusUpdatedBound); | 156 this.$.audio.addEventListener('emptied', onAudioStatusUpdatedBound); |
| 70 this.audioElement.addEventListener('stalled', onAudioStatusUpdatedBound); | 157 this.$.audio.addEventListener('stalled', onAudioStatusUpdatedBound); |
| 71 }, | |
| 72 | |
| 73 /** | |
| 74 * Registers handlers for changing of external variables | |
| 75 */ | |
| 76 observe: { | |
| 77 'trackList.currentTrackIndex': 'onCurrentTrackIndexChanged', | |
| 78 'audioController.playing': 'onControllerPlayingChanged', | |
| 79 'audioController.time': 'onControllerTimeChanged', | |
| 80 'model.volume': 'onVolumeChanged', | |
| 81 }, | 158 }, |
| 82 | 159 |
| 83 /** | 160 /** |
| 84 * Invoked when trackList.currentTrackIndex is changed. | 161 * Invoked when trackList.currentTrackIndex is changed. |
| 162 * @param {number} newValue new value. | |
| 85 * @param {number} oldValue old value. | 163 * @param {number} oldValue old value. |
| 86 * @param {number} newValue new value. | |
| 87 */ | 164 */ |
| 88 onCurrentTrackIndexChanged: function(oldValue, newValue) { | 165 currentTrackIndexChanged: function(newValue, oldValue) { |
| 89 var currentTrackUrl = ''; | 166 var currentTrackUrl = ''; |
| 90 | 167 |
| 91 if (oldValue != newValue) { | 168 if (oldValue != newValue) { |
| 92 var currentTrack = this.trackList.getCurrentTrack(); | 169 var currentTrack = this.$.trackList.getCurrentTrack(); |
| 93 if (currentTrack && currentTrack.url != this.audioElement.src) { | 170 if (currentTrack && currentTrack.url != this.$.audio.src) { |
| 94 this.audioElement.src = currentTrack.url; | 171 this.$.audio.src = currentTrack.url; |
| 95 currentTrackUrl = this.audioElement.src; | 172 currentTrackUrl = this.$.audio.src; |
| 96 if (this.audioController.playing) | 173 if (this.playing) |
| 97 this.audioElement.play(); | 174 this.$.audio.play(); |
| 98 } | 175 } |
| 99 } | 176 } |
| 100 | 177 |
| 101 // The attributes may be being watched, so we change it at the last. | 178 // The attributes may be being watched, so we change it at the last. |
| 102 this.currenttrackurl = currentTrackUrl; | 179 this.currenttrackurl = currentTrackUrl; |
| 103 }, | 180 }, |
| 104 | 181 |
| 105 /** | 182 /** |
| 106 * Invoked when audioController.playing is changed. | 183 * Invoked when playing is changed. |
| 184 * @param {boolean} newValue new value. | |
| 107 * @param {boolean} oldValue old value. | 185 * @param {boolean} oldValue old value. |
| 108 * @param {boolean} newValue new value. | |
| 109 */ | 186 */ |
| 110 onControllerPlayingChanged: function(oldValue, newValue) { | 187 playingChanged: function(newValue, oldValue) { |
| 111 this.playing = newValue; | |
| 112 | |
| 113 if (newValue) { | 188 if (newValue) { |
| 114 if (!this.audioElement.src) { | 189 if (!this.$.audio.src) { |
| 115 var currentTrack = this.trackList.getCurrentTrack(); | 190 var currentTrack = this.$.trackList.getCurrentTrack(); |
| 116 if (currentTrack && currentTrack.url != this.audioElement.src) { | 191 if (currentTrack && currentTrack.url != this.$.audio.src) { |
| 117 this.audioElement.src = currentTrack.url; | 192 this.$.audio.src = currentTrack.url; |
| 118 } | 193 } |
| 119 } | 194 } |
| 120 | 195 |
| 121 if (this.audioElement.src) { | 196 if (this.$.audio.src) { |
| 122 this.currenttrackurl = this.audioElement.src; | 197 this.currenttrackurl = this.$.audio.src; |
| 123 this.audioElement.play(); | 198 this.$.audio.play(); |
| 124 return; | 199 return; |
| 125 } | 200 } |
| 126 } | 201 } |
| 127 | 202 |
| 128 // When the new status is "stopped". | 203 // When the new status is "stopped". |
| 129 this.cancelAutoAdvance_(); | 204 this.cancelAutoAdvance_(); |
| 130 this.audioElement.pause(); | 205 this.$.audio.pause(); |
| 131 this.currenttrackurl = ''; | 206 this.currenttrackurl = ''; |
| 132 this.lastAudioUpdateTime_ = null; | 207 this.lastAudioUpdateTime_ = null; |
| 133 }, | 208 }, |
| 134 | 209 |
| 135 /** | 210 /** |
| 136 * Invoked when audioController.volume is changed. | 211 * Invoked when the model changed. |
| 137 * @param {number} oldValue old value. | 212 * @param {AudioPlayerModel} newModel New model. |
| 138 * @param {number} newValue new value. | 213 * @param {AudioPlayerModel} oldModel Old model. |
| 139 */ | 214 */ |
| 140 onVolumeChanged: function(oldValue, newValue) { | 215 modelChanged: function(newModel, oldModel) { |
| 141 this.audioElement.volume = newValue / 100; | 216 // Setting up the UI |
| 217 if (newModel !== oldModel && newModel) { | |
| 218 this.shuffle = newModel.shuffle; | |
| 219 this.repeat = newModel.repeat; | |
| 220 this.volume = newModel.volume; | |
| 221 this.expanded = newModel.expanded; | |
| 222 } | |
| 142 }, | 223 }, |
| 143 | 224 |
| 144 /** | 225 /** |
| 145 * Invoked when the model changed. | 226 * Invoked when time is changed. |
| 146 * @param {AudioPlayerModel} oldValue Old Value. | 227 * @param {number} newValue new time (in ms). |
| 147 * @param {AudioPlayerModel} newValue New Value. | 228 * @param {number} oldValue old time (in ms). |
| 148 */ | 229 */ |
| 149 modelChanged: function(oldValue, newValue) { | 230 timeChanged: function(newValue, oldValue) { |
| 150 this.trackList.model = newValue; | |
| 151 this.audioController.model = newValue; | |
| 152 | |
| 153 // Invoke the handler manually. | |
| 154 this.onVolumeChanged(0, newValue.volume); | |
| 155 }, | |
| 156 | |
| 157 /** | |
| 158 * Invoked when audioController.time is changed. | |
| 159 * @param {number} oldValue old time (in ms). | |
| 160 * @param {number} newValue new time (in ms). | |
| 161 */ | |
| 162 onControllerTimeChanged: function(oldValue, newValue) { | |
| 163 // Ignores updates from the audio element. | 231 // Ignores updates from the audio element. |
| 164 if (this.lastAudioUpdateTime_ === newValue) | 232 if (this.lastAudioUpdateTime_ === newValue) |
| 165 return; | 233 return; |
| 166 | 234 |
| 167 if (this.audioElement.readyState !== 0) | 235 if (this.$.audio.readyState !== 0) |
| 168 this.audioElement.currentTime = this.audioController.time / 1000; | 236 this.$.audio.currentTime = this.time / 1000; |
| 169 }, | 237 }, |
| 170 | 238 |
| 171 /** | 239 /** |
| 172 * Invoked when the next button in the controller is clicked. | 240 * Invoked when the next button in the controller is clicked. |
| 173 * This handler is registered in the 'on-click' attribute of the element. | 241 * This handler is registered in the 'on-click' attribute of the element. |
| 174 */ | 242 */ |
| 175 onControllerNextClicked: function() { | 243 onControllerNextClicked: function() { |
| 176 this.advance_(true /* forward */, true /* repeat */); | 244 this.advance_(true /* forward */, true /* repeat */); |
| 177 }, | 245 }, |
| 178 | 246 |
| 179 /** | 247 /** |
| 180 * Invoked when the previous button in the controller is clicked. | 248 * Invoked when the previous button in the controller is clicked. |
| 181 * This handler is registered in the 'on-click' attribute of the element. | 249 * This handler is registered in the 'on-click' attribute of the element. |
| 182 */ | 250 */ |
| 183 onControllerPreviousClicked: function() { | 251 onControllerPreviousClicked: function() { |
| 184 this.advance_(false /* forward */, true /* repeat */); | 252 this.advance_(false /* forward */, true /* repeat */); |
| 185 }, | 253 }, |
| 186 | 254 |
| 187 /** | 255 /** |
| 188 * Invoked when the playback in the audio element is ended. | 256 * Invoked when the playback in the audio element is ended. |
| 189 * This handler is registered in this.ready(). | 257 * This handler is registered in this.ready(). |
| 190 */ | 258 */ |
| 191 onAudioEnded: function() { | 259 onAudioEnded: function() { |
| 192 this.playcount++; | 260 this.playcount++; |
| 193 this.advance_(true /* forward */, this.model.repeat); | 261 this.advance_(true /* forward */, this.repeat); |
| 194 }, | 262 }, |
| 195 | 263 |
| 196 /** | 264 /** |
| 197 * Invoked when the playback in the audio element gets error. | 265 * Invoked when the playback in the audio element gets error. |
| 198 * This handler is registered in this.ready(). | 266 * This handler is registered in this.ready(). |
| 199 */ | 267 */ |
| 200 onAudioError: function() { | 268 onAudioError: function() { |
| 201 this.scheduleAutoAdvance_(true /* forward */, this.model.repeat); | 269 this.scheduleAutoAdvance_(true /* forward */, this.repeat); |
| 202 }, | 270 }, |
| 203 | 271 |
| 204 /** | 272 /** |
| 205 * Invoked when the time of playback in the audio element is updated. | 273 * Invoked when the time of playback in the audio element is updated. |
| 206 * This handler is registered in this.ready(). | 274 * This handler is registered in this.ready(). |
| 207 * @private | 275 * @private |
| 208 */ | 276 */ |
| 209 onAudioStatusUpdate_: function() { | 277 onAudioStatusUpdate_: function() { |
| 210 this.audioController.time = | 278 this.time = |
| 211 (this.lastAudioUpdateTime_ = this.audioElement.currentTime * 1000); | 279 (this.lastAudioUpdateTime_ = this.$.audio.currentTime * 1000); |
|
yawano
2015/06/10 07:15:38
nit: Can we put this in one line?
fukino
2015/06/10 07:18:13
Done.
| |
| 212 this.audioController.duration = this.audioElement.duration * 1000; | 280 this.duration = this.$.audio.duration * 1000; |
| 213 this.audioController.playing = !this.audioElement.paused; | 281 this.playing = !this.$.audio.paused; |
| 214 }, | 282 }, |
| 215 | 283 |
| 216 /** | 284 /** |
| 217 * Invoked when receiving a request to replay the current music from the track | 285 * Invoked when receiving a request to replay the current music from the track |
| 218 * list element. | 286 * list element. |
| 219 */ | 287 */ |
| 220 onReplayCurrentTrack: function() { | 288 onReplayCurrentTrack: function() { |
| 221 // Changes the current time back to the beginning, regardless of the current | 289 // Changes the current time back to the beginning, regardless of the current |
| 222 // status (playing or paused). | 290 // status (playing or paused). |
| 223 this.audioElement.currentTime = 0; | 291 this.$.audio.currentTime = 0; |
| 224 this.audioController.time = 0; | 292 this.time = 0; |
| 225 }, | 293 }, |
| 226 | 294 |
| 227 /** | 295 /** |
| 228 * Goes to the previous or the next track. | 296 * Goes to the previous or the next track. |
| 229 * @param {boolean} forward True if next, false if previous. | 297 * @param {boolean} forward True if next, false if previous. |
| 230 * @param {boolean} repeat True if repeat-mode is enabled. False otherwise. | 298 * @param {boolean} repeat True if repeat-mode is enabled. False otherwise. |
| 231 * @private | 299 * @private |
| 232 */ | 300 */ |
| 233 advance_: function(forward, repeat) { | 301 advance_: function(forward, repeat) { |
| 234 this.cancelAutoAdvance_(); | 302 this.cancelAutoAdvance_(); |
| 235 | 303 |
| 236 var nextTrackIndex = this.trackList.getNextTrackIndex(forward, true); | 304 var nextTrackIndex = this.$.trackList.getNextTrackIndex(forward, true); |
| 237 var isNextTrackAvailable = | 305 var isNextTrackAvailable = |
| 238 (this.trackList.getNextTrackIndex(forward, repeat) !== -1); | 306 (this.$.trackList.getNextTrackIndex(forward, repeat) !== -1); |
| 239 | 307 |
| 240 this.audioController.playing = isNextTrackAvailable; | 308 this.playing = isNextTrackAvailable; |
| 241 | 309 |
| 242 // If there is only a single file in the list, 'currentTrackInde' is not | 310 // If there is only a single file in the list, 'currentTrackInde' is not |
| 243 // changed and the handler is not invoked. Instead, plays here. | 311 // changed and the handler is not invoked. Instead, plays here. |
| 244 // TODO(yoshiki): clean up the code around here. | 312 // TODO(yoshiki): clean up the code around here. |
| 245 if (isNextTrackAvailable && | 313 if (isNextTrackAvailable && |
| 246 this.trackList.currentTrackIndex == nextTrackIndex) { | 314 this.$.trackList.currentTrackIndex == nextTrackIndex) { |
| 247 this.audioElement.play(); | 315 this.$.audio.play(); |
| 248 } | 316 } |
| 249 | 317 |
| 250 this.trackList.currentTrackIndex = nextTrackIndex; | 318 this.$.trackList.currentTrackIndex = nextTrackIndex; |
| 251 }, | 319 }, |
| 252 | 320 |
| 253 /** | 321 /** |
| 254 * Timeout ID of auto advance. Used internally in scheduleAutoAdvance_() and | 322 * Timeout ID of auto advance. Used internally in scheduleAutoAdvance_() and |
| 255 * cancelAutoAdvance_(). | 323 * cancelAutoAdvance_(). |
| 256 * @type {number?} | 324 * @type {number?} |
| 257 * @private | 325 * @private |
| 258 */ | 326 */ |
| 259 autoAdvanceTimer_: null, | 327 autoAdvanceTimer_: null, |
| 260 | 328 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 296 * @private | 364 * @private |
| 297 */ | 365 */ |
| 298 cancelAutoAdvance_: function() { | 366 cancelAutoAdvance_: function() { |
| 299 if (this.autoAdvanceTimer_) { | 367 if (this.autoAdvanceTimer_) { |
| 300 clearTimeout(this.autoAdvanceTimer_); | 368 clearTimeout(this.autoAdvanceTimer_); |
| 301 this.autoAdvanceTimer_ = null; | 369 this.autoAdvanceTimer_ = null; |
| 302 } | 370 } |
| 303 }, | 371 }, |
| 304 | 372 |
| 305 /** | 373 /** |
| 306 * The index of the current track. | |
| 307 * If the list has no tracks, the value must be -1. | |
| 308 * | |
| 309 * @type {number} | |
| 310 */ | |
| 311 get currentTrackIndex() { | |
| 312 return this.trackList.currentTrackIndex; | |
| 313 }, | |
| 314 set currentTrackIndex(value) { | |
| 315 this.trackList.currentTrackIndex = value; | |
| 316 }, | |
| 317 | |
| 318 /** | |
| 319 * The list of the tracks in the playlist. | 374 * The list of the tracks in the playlist. |
| 320 * | 375 * |
| 321 * When it changed, current operation including playback is stopped and | 376 * When it changed, current operation including playback is stopped and |
| 322 * restarts playback with new tracks if necessary. | 377 * restarts playback with new tracks if necessary. |
| 323 * | 378 * |
| 324 * @type {Array<AudioPlayer.TrackInfo>} | 379 * @type {Array<AudioPlayer.TrackInfo>} |
| 325 */ | 380 */ |
| 326 get tracks() { | 381 get tracks() { |
| 327 return this.trackList ? this.trackList.tracks : null; | 382 return this.$.trackList ? this.$.trackList.tracks : null; |
| 328 }, | 383 }, |
| 329 set tracks(tracks) { | 384 set tracks(tracks) { |
| 330 if (this.trackList.tracks === tracks) | 385 if (this.$.trackList.tracks === tracks) |
| 331 return; | 386 return; |
| 332 | 387 |
| 333 this.cancelAutoAdvance_(); | 388 this.cancelAutoAdvance_(); |
| 334 | 389 |
| 335 this.trackList.tracks = tracks; | 390 this.$.trackList.tracks = tracks; |
| 336 var currentTrack = this.trackList.getCurrentTrack(); | 391 var currentTrack = this.$.trackList.getCurrentTrack(); |
| 337 if (currentTrack && currentTrack.url != this.audioElement.src) { | 392 if (currentTrack && currentTrack.url != this.$.audio.src) { |
| 338 this.audioElement.src = currentTrack.url; | 393 this.$.audio.src = currentTrack.url; |
| 339 this.audioElement.play(); | 394 this.$.audio.play(); |
| 340 } | 395 } |
| 341 }, | 396 }, |
| 342 | 397 |
| 343 /** | 398 /** |
| 344 * Invoked when the audio player is being unloaded. | 399 * Invoked when the audio player is being unloaded. |
| 345 */ | 400 */ |
| 346 onPageUnload: function() { | 401 onPageUnload: function() { |
| 347 this.audioElement.src = ''; // Hack to prevent crashing. | 402 this.$.audio.src = ''; // Hack to prevent crashing. |
| 348 }, | 403 }, |
| 349 | 404 |
| 350 /** | 405 /** |
| 351 * Invoked when the 'keydown' event is fired. | 406 * Invoked when the 'keydown' event is fired. |
| 352 * @param {Event} event The event object. | 407 * @param {Event} event The event object. |
| 353 */ | 408 */ |
| 354 onKeyDown_: function(event) { | 409 onKeyDown_: function(event) { |
| 355 switch (event.keyIdentifier) { | 410 switch (event.keyIdentifier) { |
| 356 case 'Up': | 411 case 'Up': |
| 357 if (this.audioController.volumeSliderShown && this.model.volume < 100) | 412 if (this.$.audioController.volumeSliderShown && this.model.volume < 100) |
| 358 this.model.volume += 1; | 413 this.model.volume += 1; |
| 359 break; | 414 break; |
| 360 case 'Down': | 415 case 'Down': |
| 361 if (this.audioController.volumeSliderShown && this.model.volume > 0) | 416 if (this.$.audioController.volumeSliderShown && this.model.volume > 0) |
| 362 this.model.volume -= 1; | 417 this.model.volume -= 1; |
| 363 break; | 418 break; |
| 364 case 'PageUp': | 419 case 'PageUp': |
| 365 if (this.audioController.volumeSliderShown && this.model.volume < 91) | 420 if (this.$.audioController.volumeSliderShown && this.model.volume < 91) |
| 366 this.model.volume += 10; | 421 this.model.volume += 10; |
| 367 break; | 422 break; |
| 368 case 'PageDown': | 423 case 'PageDown': |
| 369 if (this.audioController.volumeSliderShown && this.model.volume > 9) | 424 if (this.$.audioController.volumeSliderShown && this.model.volume > 9) |
| 370 this.model.volume -= 10; | 425 this.model.volume -= 10; |
| 371 break; | 426 break; |
| 372 case 'MediaNextTrack': | 427 case 'MediaNextTrack': |
| 373 this.onControllerNextClicked(); | 428 this.onControllerNextClicked(); |
| 374 break; | 429 break; |
| 375 case 'MediaPlayPause': | 430 case 'MediaPlayPause': |
| 376 var playing = this.audioController.playing; | 431 this.playing = !this.playing; |
| 377 this.onControllerPlayingChanged(playing, !playing); | |
| 378 break; | 432 break; |
| 379 case 'MediaPreviousTrack': | 433 case 'MediaPreviousTrack': |
| 380 this.onControllerPreviousClicked(); | 434 this.onControllerPreviousClicked(); |
| 381 break; | 435 break; |
| 382 case 'MediaStop': | 436 case 'MediaStop': |
| 383 // TODO: Define "Stop" behavior. | 437 // TODO: Define "Stop" behavior. |
| 384 break; | 438 break; |
| 385 } | 439 } |
| 386 }, | 440 }, |
| 441 | |
| 442 /** | |
| 443 * Computes volume value for audio element. (should be in [0.0, 1.0]) | |
| 444 * @param {number} volume Volume which is set in the UI. ([0, 100]) | |
| 445 * @return {number} | |
| 446 */ | |
| 447 computeAudioVolume_: function(volume) { | |
| 448 return volume / 100; | |
| 449 } | |
| 387 }; | 450 }; |
| 388 | 451 |
| 389 Polymer('audio-player', AudioPlayerElement.prototype); | 452 Polymer(AudioPlayerElement.prototype); |
| OLD | NEW |