Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / tools / chrome_proxy / integration_tests / videowrapper.js
blob242b77645650b66b63cd527530e83d33a3869f55
1 // Copyright 2015 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.
5 // This script finds the first video element on a page and collect metrics
6 // for that element. This is based on src/tools/perf/metrics/media.js.
8 (function() {
9   // VideoWrapper attaches event listeners to collect metrics.
10   // The constructor starts playing the video.
11   function VideoWrapper(element) {
12     if (!(element instanceof HTMLVideoElement))
13       throw new Error('Unrecognized video element type ' + element);
14     metrics['ready'] = false;
15     this.element = element;
16     element.loop = false;
17     // Set the basic event handlers for this HTML5 video element.
18     this.element.addEventListener('loadedmetadata', this.onLoaded.bind(this));
19     this.element.addEventListener('canplay', this.onCanplay.bind(this));
20     this.element.addEventListener('ended', this.onEnded.bind(this));
21     this.playbackTimer = new Timer();
22     element.play()
23   }
25   VideoWrapper.prototype.onLoaded = function(e) {
26     if (this.element.readyState == HTMLMediaElement.HAVE_NOTHING) {
27       return
28     }
29     metrics['ready'] = true;
30     metrics['video_height'] = this.element.videoHeight;
31     metrics['video_width'] = this.element.videoWidth;
32     metrics['video_duration'] = this.element.duration;
33     window.__chromeProxyVideoLoaded = true;
34   };
36   VideoWrapper.prototype.onCanplay = function(event) {
37     metrics['time_to_play_ms'] = this.playbackTimer.stop();
38   };
40   VideoWrapper.prototype.onEnded = function(event) {
41     var time_to_end = this.playbackTimer.stop() - metrics['time_to_play_ms'];
42     metrics['buffering_time_ms'] = time_to_end - this.element.duration * 1000;
43     metrics['decoded_audio_bytes'] = this.element.webkitAudioDecodedByteCount;
44     metrics['decoded_video_bytes'] = this.element.webkitVideoDecodedByteCount;
45     metrics['decoded_frames'] = this.element.webkitDecodedFrameCount;
46     metrics['dropped_frames'] = this.element.webkitDroppedFrameCount;
47     window.__chromeProxyVideoEnded = true;
48   };
50   function MediaMetric(element) {
51     if (element instanceof HTMLMediaElement)
52       return new VideoWrapper(element);
53     throw new Error('Unrecognized media element type.');
54   }
56   function Timer() {
57     this.start();
58   }
60   Timer.prototype = {
61     start: function() {
62       this.start_ = getCurrentTime();
63     },
65     stop: function() {
66       // Return delta time since start in millisecs.
67       return Math.round((getCurrentTime() - this.start_) * 1000) / 1000;
68     }
69   };
71   function getCurrentTime() {
72     if (window.performance)
73       return (performance.now ||
74               performance.mozNow ||
75               performance.msNow ||
76               performance.oNow ||
77               performance.webkitNow).call(window.performance);
78     else
79       return Date.now();
80   }
82   function createVideoWrappersForDocument() {
83     var videos = document.querySelectorAll('video');
84     switch (videos.length) {
85     case 0:
86       throw new Error('Page has no videos.');
87     case 1:
88       break;
89     default:
90       throw new Error('Page too many videos: ' + videos.length.toString());
91     }
92     new VideoWrapper(videos[0])
93   }
95   metrics = {};
96   window.__chromeProxyCreateVideoWrappers = createVideoWrappersForDocument;
97   window.__chromeProxyVideoMetrics = metrics;
98   window.__chromeProxyVideoLoaded = false;
99   window.__chromeProxyVideoEnded = false;
100 })();