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

Side by Side Diff: ui/file_manager/video_player/js/video_player.js

Issue 313273002: Video Player: Supports multiple files (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 6 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
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 'use strict'; 5 'use strict';
6 6
7 /** 7 /**
8 * @param {Element} playerContainer Main container. 8 * @param {Element} playerContainer Main container.
9 * @param {Element} videoContainer Container for the video element. 9 * @param {Element} videoContainer Container for the video element.
10 * @param {Element} controlsContainer Container for video controls. 10 * @param {Element} controlsContainer Container for video controls.
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 util.toggleFullScreen(appWindow, !util.isFullScreen(appWindow)); 103 util.toggleFullScreen(appWindow, !util.isFullScreen(appWindow));
104 }; 104 };
105 105
106 /** 106 /**
107 * @constructor 107 * @constructor
108 */ 108 */
109 function VideoPlayer() { 109 function VideoPlayer() {
110 this.controls_ = null; 110 this.controls_ = null;
111 this.videoElement_ = null; 111 this.videoElement_ = null;
112 this.videos_ = null; 112 this.videos_ = null;
113 this.currentPos_ = 0;
113 114
114 Object.seal(this); 115 Object.seal(this);
115 } 116 }
116 117
117 VideoPlayer.prototype = { 118 VideoPlayer.prototype = {
118 get controls() { 119 get controls() {
119 return this.controls_; 120 return this.controls_;
120 } 121 }
121 }; 122 };
122 123
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 161
161 this.controls_ = new FullWindowVideoControls( 162 this.controls_ = new FullWindowVideoControls(
162 document.querySelector('#video-player'), 163 document.querySelector('#video-player'),
163 document.querySelector('#video-container'), 164 document.querySelector('#video-container'),
164 document.querySelector('#controls')); 165 document.querySelector('#controls'));
165 166
166 var reloadVideo = function(e) { 167 var reloadVideo = function(e) {
167 if (this.controls_.decodeErrorOccured && 168 if (this.controls_.decodeErrorOccured &&
168 // Ignore shortcut keys 169 // Ignore shortcut keys
169 !e.ctrlKey && !e.altKey && !e.shiftKey && !e.metaKey) { 170 !e.ctrlKey && !e.altKey && !e.shiftKey && !e.metaKey) {
170 this.playVideo(); 171 this.reloadCurrentVideo_();
171 e.preventDefault(); 172 e.preventDefault();
172 } 173 }
173 }.wrap(this); 174 }.wrap(this);
174 175
176 var arrowRight = document.querySelector('.arrow-box .arrow.right');
177 arrowRight.addEventListener('click', this.advance_.wrap(this, 1));
178 var arrowLeft = document.querySelector('.arrow-box .arrow.left');
179 arrowLeft.addEventListener('click', this.advance_.wrap(this, 0));
180
181 var videoPlayerElement = document.querySelector('#video-player');
182 if (videos.length > 1)
183 videoPlayerElement.setAttribute('multiple', true);
184 else
185 videoPlayerElement.removeAttribute('multiple');
186
175 document.addEventListener('keydown', reloadVideo, true); 187 document.addEventListener('keydown', reloadVideo, true);
176 document.addEventListener('click', reloadVideo, true); 188 document.addEventListener('click', reloadVideo, true);
177 }; 189 };
178 190
179 /** 191 /**
180 * Unloads the player. 192 * Unloads the player.
181 */ 193 */
182 function unload() { 194 function unload() {
183 if (!player.controls || !player.controls.getMedia()) 195 if (!player.controls || !player.controls.getMedia())
184 return; 196 return;
185 197
186 player.controls.savePosition(true /* exiting */); 198 player.controls.savePosition(true /* exiting */);
187 player.controls.cleanup(); 199 player.controls.cleanup();
188 } 200 }
189 201
190 /** 202 /**
191 * Loads the video file. 203 * Loads the video file.
192 * @param {string} url URL of the video file. 204 * @param {string} url URL of the video file.
193 * @param {string} title Title of the video file. 205 * @param {string} title Title of the video file.
194 * @param {function(number, number)=} opt_callback Completion callback. 206 * @param {function()=} opt_callback Completion callback.
195 * @private 207 * @private
196 */ 208 */
197 VideoPlayer.prototype.loadVideo_ = function(url, title, opt_callback) { 209 VideoPlayer.prototype.loadVideo_ = function(url, title, opt_callback) {
198 this.unloadVideo(); 210 this.unloadVideo();
199 211
200 document.title = title; 212 document.title = title;
201 213
202 document.querySelector('#title').innerText = title; 214 document.querySelector('#title').innerText = title;
203 215
216 var videoPlayerElement = document.querySelector('#video-player');
217 if (this.currentPos_ == (this.videos_.length - 1))
mtomasz 2014/06/06 03:41:43 nit: == -> ===
yoshiki 2014/06/06 08:02:23 Done.
218 videoPlayerElement.setAttribute('last-video', true);
219 else
220 videoPlayerElement.removeAttribute('last-video');
221
222 if (this.currentPos_ == 0)
223 videoPlayerElement.setAttribute('first-video', true);
224 else
225 videoPlayerElement.removeAttribute('first-video');
226
204 // Re-enables ui and hides error message if already displayed. 227 // Re-enables ui and hides error message if already displayed.
205 document.querySelector('#video-player').removeAttribute('disabled'); 228 document.querySelector('#video-player').removeAttribute('disabled');
206 document.querySelector('#error').removeAttribute('visible'); 229 document.querySelector('#error').removeAttribute('visible');
207 this.controls.inactivityWatcher.disabled = false; 230 this.controls.inactivityWatcher.disabled = false;
208 this.controls.decodeErrorOccured = false; 231 this.controls.decodeErrorOccured = false;
209 232
210 this.videoElement_ = document.createElement('video'); 233 this.videoElement_ = document.createElement('video');
211 document.querySelector('#video-container').appendChild(this.videoElement_); 234 document.querySelector('#video-container').appendChild(this.videoElement_);
212 this.controls.attachMedia(this.videoElement_); 235 this.controls.attachMedia(this.videoElement_);
213 236
214 this.videoElement_.src = url; 237 this.videoElement_.src = url;
215 this.videoElement_.load(); 238 this.videoElement_.load();
216 if (opt_callback) 239
217 this.videoElement_.addEventListener('loadedmetadata', opt_callback); 240 if (opt_callback) {
241 var handler = function(currentPos) {
242 if (currentPos === this.currentPos_)
243 opt_callback();
244 this.videoElement_.removeEventListener('loadedmetadata', handler);
245 }.wrap(this, this.currentPos_);
246
247 this.videoElement_.addEventListener('loadedmetadata', handler);
248 }
218 }; 249 };
219 250
220 /** 251 /**
221 * Plays the video. 252 * Plays the first video.
222 */ 253 */
223 VideoPlayer.prototype.playVideo = function() { 254 VideoPlayer.prototype.playFirstVideo = function() {
224 var currentVideo = this.videos_[0]; 255 this.currentPos_ = 0;
225 this.loadVideo_(currentVideo.fileUrl, 256 this.reloadCurrentVideo_(this.onFirstVideoReady_.wrap(this));
226 currentVideo.entry.name,
227 this.onVideoReady_.wrap(this));
228 }; 257 };
229 258
230 /** 259 /**
231 * Unloads the current video. 260 * Unloads the current video.
232 */ 261 */
233 VideoPlayer.prototype.unloadVideo = function() { 262 VideoPlayer.prototype.unloadVideo = function() {
234 // Detach the previous video element, if exists. 263 // Detach the previous video element, if exists.
235 if (this.videoElement_) 264 if (this.videoElement_)
236 this.videoElement_.parentNode.removeChild(this.videoElement_); 265 this.videoElement_.parentNode.removeChild(this.videoElement_);
237 this.videoElement_ = null; 266 this.videoElement_ = null;
238 }; 267 };
239 268
240 /** 269 /**
241 * Called when the video is ready after starting to load. 270 * Called when the first video is ready after starting to load.
242 * @private 271 * @private
243 */ 272 */
244 VideoPlayer.prototype.onVideoReady_ = function() { 273 VideoPlayer.prototype.onFirstVideoReady_ = function() {
245 // TODO: chrome.app.window soon will be able to resize the content area. 274 // TODO: chrome.app.window soon will be able to resize the content area.
246 // Until then use approximate title bar height. 275 // Until then use approximate title bar height.
247 var TITLE_HEIGHT = 33; 276 var TITLE_HEIGHT = 33;
248 277
249 var videoWidth = this.videoElement_.videoWidth; 278 var videoWidth = this.videoElement_.videoWidth;
250 var videoHeight = this.videoElement_.videoHeight; 279 var videoHeight = this.videoElement_.videoHeight;
251 280
252 var aspect = videoWidth / videoHeight; 281 var aspect = videoWidth / videoHeight;
253 var newWidth = videoWidth; 282 var newWidth = videoWidth;
254 var newHeight = videoHeight + TITLE_HEIGHT; 283 var newHeight = videoHeight + TITLE_HEIGHT;
(...skipping 23 matching lines...) Expand all
278 var appWindow = chrome.app.window.current(); 307 var appWindow = chrome.app.window.current();
279 appWindow.resizeTo(newWidth, newHeight); 308 appWindow.resizeTo(newWidth, newHeight);
280 appWindow.moveTo(oldLeft - (newWidth - oldWidth) / 2, 309 appWindow.moveTo(oldLeft - (newWidth - oldWidth) / 2,
281 oldTop - (newHeight - oldHeight) / 2); 310 oldTop - (newHeight - oldHeight) / 2);
282 appWindow.show(); 311 appWindow.show();
283 312
284 this.videoElement_.play(); 313 this.videoElement_.play();
285 }; 314 };
286 315
287 /** 316 /**
317 * Advances to the next (or previous) track.
318 *
319 * @param {boolean} direction True to the next, false to the previous.
320 * @private
321 */
322 VideoPlayer.prototype.advance_ = function(direction) {
323 var newPos = this.currentPos_ + (direction ? 1 : -1);
324 if (newPos < 0 || this.videos_.length <= newPos)
mtomasz 2014/06/06 03:41:43 optional: newPos <= this.videos_.length? It is har
yoshiki 2014/06/06 08:02:23 Done. I don't have a strong opinion.
325 return;
326
327 this.currentPos_ = newPos;
328 this.reloadCurrentVideo_(function() {
329 this.videoElement_.play();
330 }.wrap(this));
331 };
332
333 /**
334 * Reloads the current video.
335 *
mtomasz 2014/06/06 03:41:43 Please be consistent with \n in jsdoc. In #344 the
yoshiki 2014/06/06 08:02:22 Done.
336 * @param {function()=} opt_callback Completion callback.
337 * @private
338 */
339 VideoPlayer.prototype.reloadCurrentVideo_ = function(opt_callback) {
340 var currentVideo = this.videos_[this.currentPos_];
341 this.loadVideo_(currentVideo.fileUrl, currentVideo.entry.name, opt_callback);
342 };
343
344 /**
288 * Initialize the list of videos. 345 * Initialize the list of videos.
289 * @param {function(Array.<Object>)} callback Called with the video list when 346 * @param {function(Array.<Object>)} callback Called with the video list when
290 * it is ready. 347 * it is ready.
291 **/ 348 */
292 function initVideos(callback) { 349 function initVideos(callback) {
293 if (window.videos) { 350 if (window.videos) {
294 var videos = window.videos; 351 var videos = window.videos;
295 window.videos = null; 352 window.videos = null;
296 callback(videos); 353 callback(videos);
297 return; 354 return;
298 } 355 }
299 356
300 chrome.runtime.onMessage.addListener( 357 chrome.runtime.onMessage.addListener(
301 function(request, sender, sendResponse) { 358 function(request, sender, sendResponse) {
302 var videos = window.videos; 359 var videos = window.videos;
303 window.videos = null; 360 window.videos = null;
304 callback(videos); 361 callback(videos);
305 }); 362 });
306 } 363 }
307 364
308 var player = new VideoPlayer(); 365 var player = new VideoPlayer();
309 366
310 /** 367 /**
311 * Initializes the strings. 368 * Initializes the strings.
312 * @param {function()} callback Called when the sting data is ready. 369 * @param {function()} callback Called when the sting data is ready.
313 **/ 370 */
314 function initStrings(callback) { 371 function initStrings(callback) {
315 chrome.fileBrowserPrivate.getStrings(function(strings) { 372 chrome.fileBrowserPrivate.getStrings(function(strings) {
316 loadTimeData.data = strings; 373 loadTimeData.data = strings;
317 callback(); 374 callback();
318 }); 375 });
319 } 376 }
320 377
321 var initPromise = Promise.all( 378 var initPromise = Promise.all(
322 [new Promise(initVideos.wrap(null)), 379 [new Promise(initVideos.wrap(null)),
323 new Promise(initStrings.wrap(null)), 380 new Promise(initStrings.wrap(null)),
324 new Promise(util.addPageLoadHandler.wrap(null))]); 381 new Promise(util.addPageLoadHandler.wrap(null))]);
325 382
326 initPromise.then(function(results) { 383 initPromise.then(function(results) {
327 var videos = results[0]; 384 var videos = results[0];
328 player.prepare(videos); 385 player.prepare(videos);
329 return new Promise(player.playVideo.wrap(player)); 386 return new Promise(player.playFirstVideo.wrap(player));
330 }); 387 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698