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

Side by Side Diff: chrome/browser/resources/file_manager/js/media/video_player.js

Issue 39123003: [Files.app] Split the JavaScript files into subdirectories: common, background, and foreground (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fixed test failure. Created 7 years, 1 month 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 (c) 2012 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 /**
8 * Display error message.
9 * @param {string} message Message id.
10 */
11 function showErrorMessage(message) {
12 var errorBanner = document.querySelector('#error');
13 errorBanner.textContent =
14 loadTimeData.getString(message);
15 errorBanner.setAttribute('visible', 'true');
16
17 // The window is hidden if the video has not loaded yet.
18 chrome.app.window.current().show();
19 }
20
21 /**
22 * Handles playback (decoder) errors.
23 */
24 function onPlaybackError() {
25 showErrorMessage('GALLERY_VIDEO_DECODING_ERROR');
26 decodeErrorOccured = true;
27
28 // Disable inactivity watcher, and disable the ui, by hiding tools manually.
29 controls.inactivityWatcher.disabled = true;
30 document.querySelector('#video-player').setAttribute('disabled', 'true');
31
32 // Detach the video element, since it may be unreliable and reset stored
33 // current playback time.
34 controls.cleanup();
35 controls.clearState();
36
37 // Avoid reusing a video element.
38 video.parentNode.removeChild(video);
39 video = null;
40 }
41
42 /**
43 * @param {Element} playerContainer Main container.
44 * @param {Element} videoContainer Container for the video element.
45 * @param {Element} controlsContainer Container for video controls.
46 * @constructor
47 */
48 function FullWindowVideoControls(
49 playerContainer, videoContainer, controlsContainer) {
50 VideoControls.call(this,
51 controlsContainer,
52 onPlaybackError,
53 loadTimeData.getString.bind(loadTimeData),
54 this.toggleFullScreen_.bind(this),
55 videoContainer);
56
57 this.playerContainer_ = playerContainer;
58
59 this.updateStyle();
60 window.addEventListener('resize', this.updateStyle.bind(this));
61
62 document.addEventListener('keydown', function(e) {
63 if (e.keyIdentifier == 'U+0020') { // Space
64 this.togglePlayStateWithFeedback();
65 e.preventDefault();
66 }
67 if (e.keyIdentifier == 'U+001B') { // Escape
68 util.toggleFullScreen(
69 chrome.app.window.current(),
70 false); // Leave the full screen mode.
71 e.preventDefault();
72 }
73 }.bind(this));
74
75 // TODO(mtomasz): Simplify. crbug.com/254318.
76 videoContainer.addEventListener('click', function(e) {
77 if (e.ctrlKey) {
78 this.toggleLoopedModeWithFeedback(true);
79 if (!this.isPlaying())
80 this.togglePlayStateWithFeedback();
81 } else {
82 this.togglePlayStateWithFeedback();
83 }
84 }.bind(this));
85
86 this.inactivityWatcher_ = new MouseInactivityWatcher(playerContainer);
87 this.__defineGetter__('inactivityWatcher', function() {
88 return this.inactivityWatcher_;
89 });
90
91 this.inactivityWatcher_.check();
92 }
93
94 FullWindowVideoControls.prototype = { __proto__: VideoControls.prototype };
95
96 /**
97 * Save the current state so that it survives page/app reload.
98 */
99 FullWindowVideoControls.prototype.onPlayStateChanged = function() {
100 this.encodeState();
101 };
102
103 /**
104 * Restore the state after the video is loaded.
105 */
106 FullWindowVideoControls.prototype.restorePlayState = function() {
107 if (!this.decodeState()) {
108 VideoControls.prototype.restorePlayState.apply(this, arguments);
109 this.play();
110 }
111 };
112
113 /**
114 * Toggles the full screen mode.
115 * @private
116 */
117 FullWindowVideoControls.prototype.toggleFullScreen_ = function() {
118 var appWindow = chrome.app.window.current();
119 util.toggleFullScreen(appWindow, !util.isFullScreen(appWindow));
120 };
121
122 // TODO(mtomasz): Convert it to class members: crbug.com/171191.
123 var decodeErrorOccured;
124 var video;
125 var controls;
126 var metadataCache;
127 var volumeManager;
128 var selectedItemFilesystemPath;
129
130 /**
131 * Initialize the video player window.
132 */
133 function loadVideoPlayer() {
134 document.ondragstart = function(e) { e.preventDefault() };
135
136 chrome.fileBrowserPrivate.getStrings(function(strings) {
137 loadTimeData.data = strings;
138
139 controls = new FullWindowVideoControls(
140 document.querySelector('#video-player'),
141 document.querySelector('#video-container'),
142 document.querySelector('#controls'));
143
144 metadataCache = MetadataCache.createFull();
145 volumeManager = new VolumeManagerWrapper(
146 VolumeManagerWrapper.DriveEnabledStatus.DRIVE_ENABLED);
147 volumeManager.addEventListener('externally-unmounted',
148 onExternallyUnmounted);
149
150 // If the video player is starting before the first instance of the File
151 // Manager then it does not have access to filesystem URLs.
152 // Request it now.
153 volumeManager.ensureInitialized(reload);
154 var reloadVideo = function(e) {
155 if (decodeErrorOccured) {
156 reload();
157 e.preventDefault();
158 }
159 };
160
161 document.addEventListener('keydown', reloadVideo, true);
162 document.addEventListener('click', reloadVideo, true);
163 });
164 }
165
166 /**
167 * Closes video player when a volume containing the played item is unmounted.
168 * @param {Event} event The unmount event.
169 */
170 function onExternallyUnmounted(event) {
171 if (!selectedItemFilesystemPath)
172 return;
173 if (selectedItemFilesystemPath.indexOf(event.mountPath) == 0)
174 window.close();
175 }
176
177 /**
178 * Unload the player.
179 */
180 function unload() {
181 if (volumeManager)
182 volumeManager.dispose();
183
184 if (!controls.getMedia())
185 return;
186
187 controls.savePosition(true /* exiting */);
188 controls.cleanup();
189 }
190
191 /**
192 * Reload the player.
193 */
194 function reload() {
195 // Re-enable ui and hide error message if already displayed.
196 document.querySelector('#video-player').removeAttribute('disabled');
197 document.querySelector('#error').removeAttribute('visible');
198 controls.inactivityWatcher.disabled = false;
199 decodeErrorOccured = false;
200
201 var src;
202 if (window.appState) {
203 util.saveAppState();
204 src = window.appState.url;
205 } else {
206 src = document.location.search.substr(1);
207 }
208 if (!src) {
209 showErrorMessage('GALLERY_VIDEO_ERROR');
210 return;
211 }
212
213 document.title = decodeURIComponent(src.split('/').pop());
214
215 metadataCache.get(src, 'streaming', function(streaming) {
216 if (streaming && !navigator.onLine) {
217 showErrorMessage('GALLERY_VIDEO_OFFLINE');
218 return;
219 }
220
221 // Detach the previous video element, if exists.
222 if (video)
223 video.parentNode.removeChild(video);
224
225 video = document.createElement('video');
226 document.querySelector('#video-container').appendChild(video);
227 controls.attachMedia(video);
228
229 video.src = src;
230 video.load();
231 video.addEventListener('loadedmetadata', function() {
232 // TODO: chrome.app.window soon will be able to resize the content area.
233 // Until then use approximate title bar height.
234 var TITLE_HEIGHT = 28;
235
236 var aspect = video.videoWidth / video.videoHeight;
237 var newWidth = video.videoWidth;
238 var newHeight = video.videoHeight + TITLE_HEIGHT;
239
240 var shrinkX = newWidth / window.screen.availWidth;
241 var shrinkY = newHeight / window.screen.availHeight;
242 if (shrinkX > 1 || shrinkY > 1) {
243 if (shrinkY > shrinkX) {
244 newHeight = newHeight / shrinkY;
245 newWidth = (newHeight - TITLE_HEIGHT) * aspect;
246 } else {
247 newWidth = newWidth / shrinkX;
248 newHeight = newWidth / aspect + TITLE_HEIGHT;
249 }
250 }
251
252 var oldLeft = window.screenX;
253 var oldTop = window.screenY;
254 var oldWidth = window.outerWidth;
255 var oldHeight = window.outerHeight;
256
257 if (!oldWidth && !oldHeight) {
258 oldLeft = window.screen.availWidth / 2;
259 oldTop = window.screen.availHeight / 2;
260 }
261
262 var appWindow = chrome.app.window.current();
263 appWindow.resizeTo(newWidth, newHeight);
264 appWindow.moveTo(oldLeft - (newWidth - oldWidth) / 2,
265 oldTop - (newHeight - oldHeight) / 2);
266 appWindow.show();
267 });
268
269 // Resolve real filesystem path of the current video.
270 selectedItemFilesystemPath = null;
271 webkitResolveLocalFileSystemURL(src,
272 function(entry) {
273 if (video && video.src != src) return;
274 selectedItemFilesystemPath = entry.fullPath;
275 });
276 });
277 }
278
279 util.addPageLoadHandler(loadVideoPlayer);
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698