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.
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;
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();
25 VideoWrapper.prototype.onLoaded = function(e) {
26 if (this.element.readyState == HTMLMediaElement.HAVE_NOTHING) {
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;
36 VideoWrapper.prototype.onCanplay = function(event) {
37 metrics['time_to_play_ms'] = this.playbackTimer.stop();
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;
50 function MediaMetric(element) {
51 if (element instanceof HTMLMediaElement)
52 return new VideoWrapper(element);
53 throw new Error('Unrecognized media element type.');
62 this.start_ = getCurrentTime();
66 // Return delta time since start in millisecs.
67 return Math.round((getCurrentTime() - this.start_) * 1000) / 1000;
71 function getCurrentTime() {
72 if (window.performance)
73 return (performance.now ||
77 performance.webkitNow).call(window.performance);
82 function createVideoWrappersForDocument() {
83 var videos = document.querySelectorAll('video');
84 switch (videos.length) {
86 throw new Error('Page has no videos.');
90 throw new Error('Page too many videos: ' + videos.length.toString());
92 new VideoWrapper(videos[0])
96 window.__chromeProxyCreateVideoWrappers = createVideoWrappersForDocument;
97 window.__chromeProxyVideoMetrics = metrics;
98 window.__chromeProxyVideoLoaded = false;
99 window.__chromeProxyVideoEnded = false;