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

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: Split measurement JS from action JS. Wrap JS access in Py class. Add more unit tests. Created 7 years, 6 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
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 MediaMetric(element) {
nduca 2013/07/09 23:07:19 should a MediaMetricBase base class, a HTML5Media
shadi 2013/07/11 00:49:13 PTAL. I kept all fields common to any media metric
12 this.metrics = {};
13 this.info = {};
14 this.element = element;
15 this.isHTML5 = element instanceof HTMLMediaElement;
nduca 2013/07/09 23:07:19 this could be a getter on MediaMetric.
shadi 2013/07/11 00:49:13 This is avoided with subclasses.
16 // Listen to when a Telemetry 'Play' action gets called.
17 this.element.addEventListener('willPlay', this.onWillPlay, false);
18 if (this.isHTML5)
19 this.initHTML5();
nduca 2013/07/09 23:07:19 what happens if you accidentally bind a media metr
shadi 2013/07/11 00:49:13 Done.
20 }
nduca 2013/07/09 23:07:19 should you explode if this isnt' html5?
shadi 2013/07/11 00:49:13 not really. If there are no html5 elements in the
21
22 MediaMetric.prototype.onWillPlay = function() {
23 this.ttp_timer = new Timer();
nduca 2013/07/09 23:07:19 name this fully
shadi 2013/07/11 00:49:13 Done.
24 };
25
26 MediaMetric.prototype.initHTML5 = function() {
27 // Set the basic event handlers for HTML5 media element.
28 var metric = this;
29 function onVideoLoad(event) {
30 // If a 'Play' action is performed, then ttp_time != undefined.
31 if (metric.ttp_timer == undefined)
32 metric.ttp_timer = new Timer();
33 }
34 // For the cases where autoplay=true, and without a 'play' action, we want
35 // to start ttp_timer at 'play' or 'loadedmetadata' events.
36 this.element.addEventListener('play', onVideoLoad);
37 this.element.addEventListener('loadedmetadata', onVideoLoad);
38 this.element.addEventListener('playing', function(e) {
39 metric.onPlaying(e);
40 });
41 this.element.addEventListener('ended', function(e) {
42 metric.onEnded(e);
43 });
44 };
45
46 MediaMetric.prototype.onPlaying = function(event) {
47 // Playing event can fire more than once if seeking.
48 if (!this.metrics['ttp'])
49 this.metrics['ttp'] = [this.ttp_timer.stop(), 'sec'];
50 };
51
52 MediaMetric.prototype.onEnded = function(event) {
53 this.metrics['playback_time'] = [this.ttp_timer.stop(), 'sec'];
54 };
55
56 MediaMetric.prototype.getElementInfo = function() {
57 // Return information about the media element for this metric.
58 if (this.element.id)
59 this.info['id'] = this.element.id;
60 if (this.isHTML5) {
61 // Add interesting media specific tags.
62 if (this.element.src)
63 this.info['src'] = this.element.src;
64 }
65 return this.info;
66 };
67
68 MediaMetric.prototype.getMetrics = function() {
69 // Returns all collected metrics for the element
70 if (this.isHTML5) {
71 this.metrics['decoded_frame_count'] =
72 [this.element.webkitDecodedFrameCount, 'frames'];
73 this.metrics['dropped_frame_count'] =
74 [this.element.webkitDroppedFrameCount, 'frames'];
75 this.metrics['decoded_video_bytes'] =
76 [this.element.webkitVideoDecodedByteCount, 'bytes'];
77 this.metrics['decoded_audio_bytes'] =
78 [this.element.webkitAudioDecodedByteCount, 'bytes'];
79 }
80 return this.metrics;
81 };
82
83 MediaMetric.prototype.getSummary = function() {
84 return {
85 'info': this.getElementInfo(),
86 'metrics': this.getMetrics()
87 };
88 };
89
90 function Timer() {
nduca 2013/07/09 23:07:19 why does this not call start()? and why not just
shadi 2013/07/11 00:49:13 It is usually the case where you need to start the
91 this.start_ = getCurrentTime();
92 this.times_ = [];
93 }
94
95 Timer.prototype = {
96 start: function() {
97 this.start_ = getCurrentTime();
98 },
99
100 stop: function() {
101 // Store time logs in secs.
102 var delta = (getCurrentTime() - this.start_) / 1000;
103 this.times_.push(delta);
104 return delta;
105 }
106 };
107
108 function LoadMediaMetrics() {
nduca 2013/07/09 23:07:19 This isn't really loading. createMediaMetricsForDo
shadi 2013/07/11 00:49:13 Done.
109 // Searches for all video and audio elements on the page and creates a
110 // corresponding media metric instance for each.
111 var media = document.querySelectorAll('video, audio');
nduca 2013/07/09 23:07:19 mediaElements
shadi 2013/07/11 00:49:13 Done.
112 for (var i = 0; i < media.length; i++) {
nduca 2013/07/09 23:07:19 one liners dont get {}
shadi 2013/07/11 00:49:13 Done.
113 mediaMetrics.push(new MediaMetric(media[i]));
nduca 2013/07/09 23:07:19 explicitly say window.__mediaMetrics perhaps inste
shadi 2013/07/11 00:49:13 Done.
114 }
115 }
116
117 function getCurrentTime() {
118 if (window.performance)
119 return (performance.now ||
120 performance.mozNow ||
121 performance.msNow ||
122 performance.oNow ||
123 performance.webkitNow).call(window.performance);
124 else
125 return Date().getTime();
nduca 2013/07/09 23:07:19 Date.now()? does't create garbage...
shadi 2013/07/11 00:49:13 Done.
126 }
127
128 function getAllMetrics() {
129 // Returns a summary (info + metrics) for all media metrics.
130 var metrics = [];
131 for (var i = 0; i < mediaMetrics.length; i++) {
nduca 2013/07/09 23:07:19 one line fors get no bracez
shadi 2013/07/11 00:49:13 Done.
132 metrics.push(mediaMetrics[i].getSummary());
133 }
134 return metrics;
135 }
136
137 // Stores metrics for all media elements on the page upon loading.
138 var mediaMetrics = [];
139 window.__mediaMetrics = mediaMetrics;
140 window.__getAllMetrics = getAllMetrics;
141 LoadMediaMetrics();
nduca 2013/07/09 23:07:19 you should keep injection of the script separate f
shadi 2013/07/11 00:49:13 Is there a good reason for this? Is there a case w
142 })();
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698