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; |
+})(); |