Chromium Code Reviews| Index: tools/chrome_proxy/integration_tests/videowrapper.js |
| diff --git a/tools/chrome_proxy/integration_tests/videowrapper.js b/tools/chrome_proxy/integration_tests/videowrapper.js |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..6028da6f04f18683d757b2d07b9f3072ca924090 |
| --- /dev/null |
| +++ b/tools/chrome_proxy/integration_tests/videowrapper.js |
| @@ -0,0 +1,101 @@ |
| +// Copyright 2013 The Chromium Authors. All rights reserved. |
|
bolian
2015/04/10 21:00:03
2015
Tom Bergan
2015/04/10 21:14:46
Done.
|
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +// This script finds the first video element on a page and collect metrics |
| +// for that element. This is based on src/tools/perf/metrics/media.js. |
| + |
| +(function() { |
| + // VideoWrapper attaches event listeners to collect metrics. |
| + // The constructor starts playing the video. |
| + function VideoWrapper(element) { |
| + if (!(element instanceof HTMLVideoElement)) |
| + throw new Error('Unrecognized video element type ' + element); |
| + metrics['ready'] = false; |
| + this.element = element; |
| + element.loop = false; |
| + // Set the basic event handlers for this HTML5 video element. |
| + this.element.addEventListener('loadedmetadata', this.onLoaded.bind(this)); |
| + this.element.addEventListener('canplay', this.onCanplay.bind(this)); |
| + this.element.addEventListener('ended', this.onEnded.bind(this)); |
| + this.playbackTimer = new Timer(); |
| + element.play() |
| + } |
| + |
| + VideoWrapper.prototype.onLoaded = function(e) { |
| + if (this.element.readyState == HTMLMediaElement.HAVE_NOTHING) { |
| + return |
| + } |
| + metrics['ready'] = true; |
| + metrics['video_height'] = this.element.videoHeight; |
| + metrics['video_width'] = this.element.videoWidth; |
| + metrics['video_duration'] = this.element.duration; |
| + window.__chromeProxyVideoLoaded = true; |
| + }; |
| + |
| + VideoWrapper.prototype.onCanplay = function(event) { |
| + metrics['time_to_play_ms'] = this.playbackTimer.stop(); |
| + }; |
| + |
| + VideoWrapper.prototype.onEnded = function(event) { |
| + var time_to_end = this.playbackTimer.stop() - metrics['time_to_play_ms']; |
| + metrics['buffering_time_ms'] = time_to_end - this.element.duration * 1000; |
| + metrics['decoded_audio_bytes'] = this.element.webkitAudioDecodedByteCount; |
| + metrics['decoded_video_bytes'] = this.element.webkitVideoDecodedByteCount; |
| + metrics['decoded_frames'] = this.element.webkitDecodedFrameCount; |
| + metrics['dropped_frames'] = this.element.webkitDroppedFrameCount; |
| + window.__chromeProxyVideoEnded = true; |
| + }; |
| + |
| + function MediaMetric(element) { |
| + if (element instanceof HTMLMediaElement) |
| + return new VideoWrapper(element); |
| + throw new Error('Unrecognized media element type.'); |
| + } |
| + |
| + function Timer() { |
| + this.start_ = 0; |
|
bolian
2015/04/10 21:00:03
delete this line?
Tom Bergan
2015/04/10 21:14:46
I think uninitialized fields default to null? See
bolian
2015/04/10 21:46:29
I mean this.start() will initialize it, so we don'
Tom Bergan
2015/04/10 23:41:04
Done.
|
| + this.start(); |
| + } |
| + |
| + Timer.prototype = { |
| + start: function() { |
| + this.start_ = getCurrentTime(); |
| + }, |
| + |
| + stop: function() { |
| + // Return delta time since start in millisecs. |
|
bolian
2015/04/10 21:00:03
this is in seconds but with precision to ms?
Tom Bergan
2015/04/10 21:14:46
window.performance.now returns a double in ms. Thi
bolian
2015/04/10 21:46:29
ok. lg as is.
Tom Bergan
2015/04/10 23:41:04
Acknowledged.
|
| + return Math.round((getCurrentTime() - this.start_) * 1000) / 1000; |
| + } |
| + }; |
| + |
| + function getCurrentTime() { |
| + if (window.performance) |
|
bolian
2015/04/10 21:00:03
For chrome only, we don't this complexity?
Tom Bergan
2015/04/10 21:14:46
I don't know why all this code is here. I copied f
bolian
2015/04/10 21:46:29
Probably they copy from general js library to supp
sclittle
2015/04/10 23:01:49
Either way seems fine to me, but I'd recommend kee
Tom Bergan
2015/04/10 23:41:04
Acknowledged.
|
| + return (performance.now || |
| + performance.mozNow || |
| + performance.msNow || |
| + performance.oNow || |
| + performance.webkitNow).call(window.performance); |
| + else |
| + return Date.now(); |
| + } |
| + |
| + function createVideoWrappersForDocument() { |
| + var videos = document.querySelectorAll('video'); |
| + switch (videos.length) { |
| + case 0: |
| + throw new Error('Page has no videos.'); |
| + case 1: |
| + break; |
| + default: |
| + throw new Error('Page too many videos: ' + videos.length.toString()); |
| + } |
| + new VideoWrapper(videos[0]) |
| + } |
| + |
| + metrics = {}; |
| + window.__chromeProxyCreateVideoWrappers = createVideoWrappersForDocument; |
| + window.__chromeProxyVideoMetrics = metrics; |
| + window.__chromeProxyVideoLoaded = false; |
| + window.__chromeProxyVideoEnded = false; |
| +})(); |