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

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

Issue 19482009: Telemetry media Seek action and metrics. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add base media action class and JS code. 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 | « no previous file | 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
1 // Copyright 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // This file contains common utilities to find video/audio elements on a page 5 // This file contains common utilities to find video/audio elements on a page
6 // and collect metrics for each. 6 // and collect metrics for each.
7 7
8 (function() { 8 (function() {
9 // MediaMetric class responsible for collecting metrics on a media element. 9 // MediaMetric class responsible for collecting metrics on a media element.
10 // It attaches required event listeners in order to collect different metrics. 10 // It attaches required event listeners in order to collect different metrics.
11 function MediaMetricBase(element) { 11 function MediaMetricBase(element) {
12 checkElementIsNotBound(element); 12 checkElementIsNotBound(element);
13 this.metrics = {}; 13 this.metrics = {};
14 this.id = ''; 14 this.id = '';
15 this.element = element; 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 } 16 }
21 17
22 MediaMetricBase.prototype.getMetrics = function() { 18 MediaMetricBase.prototype.getMetrics = function() {
23 return this.metrics; 19 return this.metrics;
24 }; 20 };
25 21
26 MediaMetricBase.prototype.getSummary = function() { 22 MediaMetricBase.prototype.getSummary = function() {
27 return { 23 return {
28 'id': this.id, 24 'id': this.id,
29 'metrics': this.getMetrics() 25 'metrics': this.getMetrics()
30 }; 26 };
31 }; 27 };
32 28
33 MediaMetricBase.prototype.onWillPlay = function() {
34 this.playbackTimer = new Timer();
35 };
36
37 function HTMLMediaMetric(element) { 29 function HTMLMediaMetric(element) {
38 MediaMetricBase.prototype.constructor.call(this, element); 30 MediaMetricBase.prototype.constructor.call(this, element);
39 // Set the basic event handlers for HTML5 media element. 31 // Set the basic event handlers for HTML5 media element.
40 var metric = this; 32 var metric = this;
41 function onVideoLoad(event) { 33 function onVideoLoad(event) {
42 // If a 'Play' action is performed, then playback_timer != undefined. 34 // If a 'Play' action is performed, then playback_timer != undefined.
43 if (metric.playbackTimer == undefined) 35 if (metric.playbackTimer == undefined)
44 metric.playbackTimer = new Timer(); 36 metric.playbackTimer = new Timer();
45 } 37 }
46 // For the cases where autoplay=true, and without a 'play' action, we want 38 // For the cases where autoplay=true, and without a 'play' action, we want
47 // to start playbackTimer at 'play' or 'loadedmetadata' events. 39 // to start playbackTimer at 'play' or 'loadedmetadata' events.
48 this.element.addEventListener('play', onVideoLoad); 40 this.element.addEventListener('play', onVideoLoad);
49 this.element.addEventListener('loadedmetadata', onVideoLoad); 41 this.element.addEventListener('loadedmetadata', onVideoLoad);
50 this.element.addEventListener('playing', function(e) { 42 this.element.addEventListener('playing', function(e) {
51 metric.onPlaying(e); 43 metric.onPlaying(e);
52 }); 44 });
53 this.element.addEventListener('ended', function(e) { 45 this.element.addEventListener('ended', function(e) {
54 metric.onEnded(e); 46 metric.onEnded(e);
55 }); 47 });
56 this.setID(); 48 this.setID();
49
50 // Listen to when a Telemetry actions gets called.
51 this.element.addEventListener('willPlay', function (e) {
52 metric.onWillPlay(e);
53 }, false);
54 this.element.addEventListener('willSeek', function (e) {
55 metric.onWillSeek(e);
56 }, false);
57 } 57 }
58 58
59 HTMLMediaMetric.prototype = new MediaMetricBase(); 59 HTMLMediaMetric.prototype = new MediaMetricBase();
60 HTMLMediaMetric.prototype.constructor = HTMLMediaMetric; 60 HTMLMediaMetric.prototype.constructor = HTMLMediaMetric;
61
61 HTMLMediaMetric.prototype.setID = function() { 62 HTMLMediaMetric.prototype.setID = function() {
62 if (this.element.src) 63 if (this.element.src)
63 this.id = this.element.src.substring(this.element.src.lastIndexOf("/")+1); 64 this.id = this.element.src.substring(this.element.src.lastIndexOf("/")+1);
64 else if (this.element.id) 65 else if (this.element.id)
65 this.id = this.element.id; 66 this.id = this.element.id;
66 else 67 else
67 this.id = 'media_' + window.__globalCounter++; 68 this.id = 'media_' + window.__globalCounter++;
68 }; 69 };
69 70
70 HTMLMediaMetric.prototype.getMetrics = function() { 71 HTMLMediaMetric.prototype.onWillPlay = function(e) {
71 this.metrics['decoded_frame_count'] = this.element.webkitDecodedFrameCount; 72 this.playbackTimer = new Timer();
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 }; 73 };
79 74
75 HTMLMediaMetric.prototype.onWillSeek = function(e) {
76 var seekLabel = '';
77 if (e.seekLabel)
78 seekLabel = '_' + e.seekLabel;
79 var metric = this;
80 var onSeeked = function(e) {
81 metric.appendMetric('seek' + seekLabel, metric.seekTimer.stop())
82 e.target.removeEventListener('seeked', onSeeked);
83 };
84 this.seekTimer = new Timer();
85 this.element.addEventListener('seeked', onSeeked);
86 };
87
88 HTMLMediaMetric.prototype.appendMetric = function(metric, value) {
89 if (!this.metrics[metric])
90 this.metrics[metric] = [];
91 this.metrics[metric].push(value);
92 }
93
80 HTMLMediaMetric.prototype.onPlaying = function(event) { 94 HTMLMediaMetric.prototype.onPlaying = function(event) {
81 // Playing event can fire more than once if seeking. 95 // Playing event can fire more than once if seeking.
82 if (!this.metrics['time_to_play']) 96 if (!this.metrics['time_to_play'])
83 this.metrics['time_to_play'] = this.playbackTimer.stop(); 97 this.metrics['time_to_play'] = this.playbackTimer.stop();
84 }; 98 };
85 99
86 HTMLMediaMetric.prototype.onEnded = function(event) { 100 HTMLMediaMetric.prototype.onEnded = function(event) {
87 this.metrics['playback_time'] = this.playbackTimer.stop(); 101 this.metrics['playback_time'] = this.playbackTimer.stop();
88 }; 102 };
89 103
104 HTMLMediaMetric.prototype.getMetrics = function() {
105 this.metrics['decoded_frame_count'] = this.element.webkitDecodedFrameCount;
106 this.metrics['dropped_frame_count'] = this.element.webkitDroppedFrameCount;
107 this.metrics['decoded_video_bytes'] =
108 this.element.webkitVideoDecodedByteCount;
109 this.metrics['decoded_audio_bytes'] =
110 this.element.webkitAudioDecodedByteCount;
111 return this.metrics;
112 };
113
90 function MediaMetric(element) { 114 function MediaMetric(element) {
91 if (element instanceof HTMLMediaElement) 115 if (element instanceof HTMLMediaElement)
92 return new HTMLMediaMetric(element); 116 return new HTMLMediaMetric(element);
93 throw new Error('Unrecognized media element type.'); 117 throw new Error('Unrecognized media element type.');
94 } 118 }
95 119
96 function Timer() { 120 function Timer() {
97 this.start_ = 0; 121 this.start_ = 0;
98 this.start(); 122 this.start();
99 } 123 }
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 for (var i = 0; i < window.__mediaMetrics.length; i++) 167 for (var i = 0; i < window.__mediaMetrics.length; i++)
144 metrics.push(window.__mediaMetrics[i].getSummary()); 168 metrics.push(window.__mediaMetrics[i].getSummary());
145 return metrics; 169 return metrics;
146 } 170 }
147 171
148 window.__globalCounter = 0; 172 window.__globalCounter = 0;
149 window.__mediaMetrics = []; 173 window.__mediaMetrics = [];
150 window.__getAllMetrics = getAllMetrics; 174 window.__getAllMetrics = getAllMetrics;
151 window.__createMediaMetricsForDocument = createMediaMetricsForDocument; 175 window.__createMediaMetricsForDocument = createMediaMetricsForDocument;
152 })(); 176 })();
OLDNEW
« no previous file with comments | « no previous file | tools/perf/perf_tools/media_metrics.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698