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

Side by Side Diff: tools/perf/perf_tools/media_metrics.js

Issue 16854013: Telemetry media_measurement plus play action and tests. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: remove media files (submitted separately) Created 7 years, 5 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 | Annotate | Revision Log
« no previous file with comments | « tools/perf/perf_tools/media_measurement.py ('k') | tools/perf/perf_tools/media_metrics.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2013 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.
4
5 // This file contains common utilities to find video/audio elements on a page
6 // and collect metrics for each.
7
8 (function() {
9 // MediaMetric class responsible for collecting metrics on a media element.
10 // It attaches required event listeners in order to collect different metrics.
11 function MediaMetricBase(element) {
12 checkElementIsNotBound(element);
13 this.metrics = {};
14 this.id = '';
15 this.element = element;
16 // Listen to when a Telemetry 'Play' action gets called.
17 // TODO(shadi): Add event listeners for other media actions here.
18 if (this.element)
19 this.element.addEventListener('willPlay', this.onWillPlay, false);
20 }
21
22 MediaMetricBase.prototype.getMetrics = function() {
23 return this.metrics;
24 };
25
26 MediaMetricBase.prototype.getSummary = function() {
27 return {
28 'id': this.id,
29 'metrics': this.getMetrics()
30 };
31 };
32
33 MediaMetricBase.prototype.onWillPlay = function() {
34 this.playbackTimer = new Timer();
35 };
36
37 function HTMLMediaMetric(element) {
38 MediaMetricBase.prototype.constructor.call(this, element);
39 // Set the basic event handlers for HTML5 media element.
40 var metric = this;
41 function onVideoLoad(event) {
42 // If a 'Play' action is performed, then playback_timer != undefined.
43 if (metric.playbackTimer == undefined)
44 metric.playbackTimer = new Timer();
45 }
46 // For the cases where autoplay=true, and without a 'play' action, we want
47 // to start playbackTimer at 'play' or 'loadedmetadata' events.
48 this.element.addEventListener('play', onVideoLoad);
49 this.element.addEventListener('loadedmetadata', onVideoLoad);
50 this.element.addEventListener('playing', function(e) {
51 metric.onPlaying(e);
52 });
53 this.element.addEventListener('ended', function(e) {
54 metric.onEnded(e);
55 });
56 this.setID();
57 }
58
59 HTMLMediaMetric.prototype = new MediaMetricBase();
60 HTMLMediaMetric.prototype.constructor = HTMLMediaMetric;
61 HTMLMediaMetric.prototype.setID = function() {
62 if (this.element.src)
63 this.id = this.element.src.substring(this.element.src.lastIndexOf("/")+1);
64 else if (this.element.id)
65 this.id = this.element.id;
66 else
67 this.id = 'media_' + window.__globalCounter++;
68 };
69
70 HTMLMediaMetric.prototype.getMetrics = function() {
71 this.metrics['decoded_frame_count'] = this.element.webkitDecodedFrameCount;
72 this.metrics['dropped_frame_count'] = this.element.webkitDroppedFrameCount;
73 this.metrics['decoded_video_bytes'] =
74 this.element.webkitVideoDecodedByteCount;
75 this.metrics['decoded_audio_bytes'] =
76 this.element.webkitAudioDecodedByteCount;
77 return this.metrics;
78 };
79
80 HTMLMediaMetric.prototype.onPlaying = function(event) {
81 // Playing event can fire more than once if seeking.
82 if (!this.metrics['time_to_play'])
83 this.metrics['time_to_play'] = this.playbackTimer.stop();
84 };
85
86 HTMLMediaMetric.prototype.onEnded = function(event) {
87 this.metrics['playback_time'] = this.playbackTimer.stop();
88 };
89
90 function MediaMetric(element) {
91 if (element instanceof HTMLMediaElement)
92 return new HTMLMediaMetric(element);
93 throw new Error('Unrecognized media element type.');
94 }
95
96 function Timer() {
97 this.start_ = 0;
98 this.start();
99 }
100
101 Timer.prototype = {
102 start: function() {
103 this.start_ = getCurrentTime();
104 },
105
106 stop: function() {
107 // Return delta time since start in secs.
108 return ((getCurrentTime() - this.start_) / 1000).toFixed(3);
109 }
110 };
111
112 function checkElementIsNotBound(element) {
113 if (!element)
114 return;
115 for (var i = 0; i < window.__mediaMetrics.length; i++) {
116 if (window.__mediaMetrics[i].element == element)
117 throw new Error('Can not create MediaMetric for same element twice.');
118 }
119 }
120
121 function createMediaMetricsForDocument() {
122 // Searches for all video and audio elements on the page and creates a
123 // corresponding media metric instance for each.
124 var mediaElements = document.querySelectorAll('video, audio');
125 for (var i = 0; i < mediaElements.length; i++)
126 window.__mediaMetrics.push(new MediaMetric(mediaElements[i]));
127 }
128
129 function getCurrentTime() {
130 if (window.performance)
131 return (performance.now ||
132 performance.mozNow ||
133 performance.msNow ||
134 performance.oNow ||
135 performance.webkitNow).call(window.performance);
136 else
137 return Date.now();
138 }
139
140 function getAllMetrics() {
141 // Returns a summary (info + metrics) for all media metrics.
142 var metrics = [];
143 for (var i = 0; i < window.__mediaMetrics.length; i++)
144 metrics.push(window.__mediaMetrics[i].getSummary());
145 return metrics;
146 }
147
148 window.__globalCounter = 0;
149 window.__mediaMetrics = [];
150 window.__getAllMetrics = getAllMetrics;
151 window.__createMediaMetricsForDocument = createMediaMetricsForDocument;
152 })();
OLDNEW
« no previous file with comments | « tools/perf/perf_tools/media_measurement.py ('k') | tools/perf/perf_tools/media_metrics.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698