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

Side by Side Diff: ui/file_manager/image_loader/request.js

Issue 1842313005: Don't load all bytes of video when generating thumbnails. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 * @typedef {{ 6 * @typedef {{
7 * cache: (boolean|undefined), 7 * cache: (boolean|undefined),
8 * priority: (number|undefined), 8 * priority: (number|undefined),
9 * taskId: number, 9 * taskId: number,
10 * timestamp: (number|undefined), 10 * timestamp: (number|undefined),
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 }.bind(this); 239 }.bind(this);
240 240
241 // Download data urls directly since they are not supported by XmlHttpRequest. 241 // Download data urls directly since they are not supported by XmlHttpRequest.
242 var dataUrlMatches = this.request_.url.match(/^data:([^,;]*)[,;]/); 242 var dataUrlMatches = this.request_.url.match(/^data:([^,;]*)[,;]/);
243 if (dataUrlMatches) { 243 if (dataUrlMatches) {
244 this.image_.src = this.request_.url; 244 this.image_.src = this.request_.url;
245 this.contentType_ = dataUrlMatches[1]; 245 this.contentType_ = dataUrlMatches[1];
246 return; 246 return;
247 } 247 }
248 248
249 var fileType = FileType.getTypeForName(this.request_.url);
250
249 // Load RAW images by using Piex loader instead of XHR. 251 // Load RAW images by using Piex loader instead of XHR.
250 var fileType = FileType.getTypeForName(this.request_.url);
251 if (fileType.type === 'raw') { 252 if (fileType.type === 'raw') {
252 var timer = metrics.getTracker().startTiming( 253 var timer = metrics.getTracker().startTiming(
253 metrics.Categories.INTERNALS, 254 metrics.Categories.INTERNALS,
254 metrics.timing.Variables.EXTRACT_THUMBNAIL_FROM_RAW, 255 metrics.timing.Variables.EXTRACT_THUMBNAIL_FROM_RAW,
255 fileType.subtype); 256 fileType.subtype);
256 this.piexLoader_.load(this.request_.url).then(function(data) { 257 this.piexLoader_.load(this.request_.url).then(function(data) {
257 timer.send(); 258 timer.send();
258 var blob = new Blob([data.thumbnail], {type: 'image/jpeg'}); 259 var blob = new Blob([data.thumbnail], {type: 'image/jpeg'});
259 var url = URL.createObjectURL(blob); 260 var url = URL.createObjectURL(blob);
260 this.image_.src = url; 261 this.image_.src = url;
261 this.request_.orientation = data.orientation; 262 this.request_.orientation = data.orientation;
262 this.request_.colorSpace = data.colorSpace; 263 this.request_.colorSpace = data.colorSpace;
263 }.bind(this), function(error) { 264 }.bind(this), function(error) {
264 console.error('PiexLoaderError: ', error); 265 console.error('PiexLoaderError: ', error);
265 onFailure(); 266 onFailure();
266 }); 267 });
267 return; 268 return;
268 } 269 }
269 270
271 // Load video thumbnails by using video tag instead of XHR.
272 if (fileType.type === 'video') {
273 this.createVideoThumbnailUrl_(this.request_.url).then(function(url) {
274 this.image_.src = url;
275 }.bind(this)).catch(function(error) {
276 console.error('Video thumbnail error: ', error);
277 onFailure();
278 });
279 return;
280 }
281
270 // Fetch the image via authorized XHR and parse it. 282 // Fetch the image via authorized XHR and parse it.
271 var parseImage = function(contentType, blob) { 283 var parseImage = function(contentType, blob) {
272 if (contentType) 284 if (contentType)
273 this.contentType_ = contentType; 285 this.contentType_ = contentType;
274 if (fileType.type === 'video') { 286 this.image_.src = URL.createObjectURL(blob);
275 this.createThumbnailUrl_(blob).then(function(url) {
276 this.image_.src = url;
277 }.bind(this), onFailure);
278 } else {
279 this.image_.src = URL.createObjectURL(blob);
280 }
281 }.bind(this); 287 }.bind(this);
282 288
283 // Request raw data via XHR. 289 // Request raw data via XHR.
284 this.xhr_.load(this.request_.url, parseImage, onFailure); 290 this.xhr_.load(this.request_.url, parseImage, onFailure);
285 }; 291 };
286 292
287 /** 293 /**
288 * Creates a video thumbnail data url from video file. 294 * Creates a video thumbnail data url from video file.
289 * 295 *
290 * @param {!Blob} blob Blob object of video file 296 * @param {string} url Video URL.
291 * @return {!Promise<!string>} Promise that resolves with the data url of video 297 * @return {!Promise<Blob>} Promise that resolves with the data url of video
292 * thumbnail. 298 * thumbnail.
293 * @private 299 * @private
294 */ 300 */
295 ImageRequest.prototype.createThumbnailUrl_ = function(blob) { 301 ImageRequest.prototype.createVideoThumbnailUrl_ = function(url) {
296 var url = URL.createObjectURL(blob);
297 var video = document.createElement('video'); 302 var video = document.createElement('video');
298 return new Promise(function(resolve, reject) { 303 return new Promise(function(resolve, reject) {
299 video.addEventListener('canplay', resolve); 304 video.addEventListener('canplay', resolve);
300 video.addEventListener('error', reject); 305 video.addEventListener('error', reject);
301 video.currentTime = ImageRequest.VIDEO_THUMBNAIL_POSITION; 306 video.currentTime = ImageRequest.VIDEO_THUMBNAIL_POSITION;
302 video.preload = 'auto'; 307 video.preload = 'auto';
303 video.src = url; 308 video.src = url;
304 }).then(function() { 309 }).then(function() {
305 URL.revokeObjectURL(url);
306 var canvas = document.createElement('canvas'); 310 var canvas = document.createElement('canvas');
307 canvas.width = video.videoWidth; 311 canvas.width = video.videoWidth;
308 canvas.height = video.videoHeight; 312 canvas.height = video.videoHeight;
309 canvas.getContext('2d').drawImage(video, 0, 0); 313 canvas.getContext('2d').drawImage(video, 0, 0);
310 return canvas.toDataURL(); 314 return canvas.toDataURL();
311 }, function(errev) {
312 URL.revokeObjectURL(url);
313 console.error(errev);
314 return Promise.reject(errev);
315 }); 315 });
316 }; 316 };
317 317
318 /** 318 /**
319 * Creates a XmlHttpRequest wrapper with injected OAuth2 authentication headers. 319 * Creates a XmlHttpRequest wrapper with injected OAuth2 authentication headers.
320 * @constructor 320 * @constructor
321 */ 321 */
322 function AuthorizedXHR() { 322 function AuthorizedXHR() {
323 this.xhr_ = null; 323 this.xhr_ = null;
324 this.aborted_ = false; 324 this.aborted_ = false;
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
582 this.image_.src = 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAA' + 582 this.image_.src = 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAA' +
583 'ABAAEAAAICTAEAOw=='; 583 'ABAAEAAAICTAEAOw==';
584 584
585 this.xhr_.onload = function() {}; 585 this.xhr_.onload = function() {};
586 this.xhr_.abort(); 586 this.xhr_.abort();
587 587
588 // Dispose memory allocated by Canvas. 588 // Dispose memory allocated by Canvas.
589 this.canvas_.width = 0; 589 this.canvas_.width = 0;
590 this.canvas_.height = 0; 590 this.canvas_.height = 0;
591 }; 591 };
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698