OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 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. |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
116 | 116 |
117 HTMLMediaMetric.prototype.onEnded = function(event) { | 117 HTMLMediaMetric.prototype.onEnded = function(event) { |
118 var time_to_end = this.playbackTimer.stop() - this.metrics['time_to_play']; | 118 var time_to_end = this.playbackTimer.stop() - this.metrics['time_to_play']; |
119 // TODO(shadi): Measure buffering time more accurately using events such as | 119 // TODO(shadi): Measure buffering time more accurately using events such as |
120 // stalled, waiting, progress, etc. This works only when continuous playback | 120 // stalled, waiting, progress, etc. This works only when continuous playback |
121 // is used. | 121 // is used. |
122 this.metrics['buffering_time'] = time_to_end - this.element.duration * 1000; | 122 this.metrics['buffering_time'] = time_to_end - this.element.duration * 1000; |
123 }; | 123 }; |
124 | 124 |
125 HTMLMediaMetric.prototype.getMetrics = function() { | 125 HTMLMediaMetric.prototype.getMetrics = function() { |
126 this.metrics['decoded_frame_count'] = this.element.webkitDecodedFrameCount; | 126 var decodedFrames = this.element.webkitDecodedFrameCount; |
127 this.metrics['dropped_frame_count'] = this.element.webkitDroppedFrameCount; | 127 var droppedFrames = this.element.webkitDroppedFrameCount; |
| 128 // Audio media does not report decoded/dropped frame count |
| 129 if (decodedFrames != undefined) |
| 130 this.metrics['decoded_frame_count'] = decodedFrames; |
| 131 if (droppedFrames != undefined) |
| 132 this.metrics['dropped_frame_count'] = droppedFrames; |
128 this.metrics['decoded_video_bytes'] = | 133 this.metrics['decoded_video_bytes'] = |
129 this.element.webkitVideoDecodedByteCount; | 134 this.element.webkitVideoDecodedByteCount || 0; |
130 this.metrics['decoded_audio_bytes'] = | 135 this.metrics['decoded_audio_bytes'] = |
131 this.element.webkitAudioDecodedByteCount; | 136 this.element.webkitAudioDecodedByteCount || 0; |
132 return this.metrics; | 137 return this.metrics; |
133 }; | 138 }; |
134 | 139 |
135 function MediaMetric(element) { | 140 function MediaMetric(element) { |
136 if (element instanceof HTMLMediaElement) | 141 if (element instanceof HTMLMediaElement) |
137 return new HTMLMediaMetric(element); | 142 return new HTMLMediaMetric(element); |
138 throw new Error('Unrecognized media element type.'); | 143 throw new Error('Unrecognized media element type.'); |
139 } | 144 } |
140 | 145 |
141 function Timer() { | 146 function Timer() { |
142 this.start_ = 0; | 147 this.start_ = 0; |
143 this.start(); | 148 this.start(); |
144 } | 149 } |
145 | 150 |
146 Timer.prototype = { | 151 Timer.prototype = { |
147 start: function() { | 152 start: function() { |
148 this.start_ = getCurrentTime(); | 153 this.start_ = getCurrentTime(); |
149 }, | 154 }, |
150 | 155 |
151 stop: function() { | 156 stop: function() { |
152 // Return delta time since start in millisecs. | 157 // Return delta time since start in millisecs. |
153 return ((getCurrentTime() - this.start_)).toFixed(3); | 158 return ((getCurrentTime() - this.start_)).toFixed(3); |
154 } | 159 } |
155 }; | 160 }; |
156 | 161 |
157 function checkElementIsNotBound(element) { | 162 function checkElementIsNotBound(element) { |
158 if (!element) | 163 if (!element) |
159 return; | 164 return; |
| 165 if (getMediaMetric(element)) |
| 166 throw new Error('Can not create MediaMetric for same element twice.'); |
| 167 } |
| 168 |
| 169 function getMediaMetric(element) { |
160 for (var i = 0; i < window.__mediaMetrics.length; i++) { | 170 for (var i = 0; i < window.__mediaMetrics.length; i++) { |
161 if (window.__mediaMetrics[i].element == element) | 171 if (window.__mediaMetrics[i].element == element) |
162 throw new Error('Can not create MediaMetric for same element twice.'); | 172 return window.__mediaMetrics[i]; |
163 } | 173 } |
| 174 return null; |
164 } | 175 } |
165 | 176 |
166 function createMediaMetricsForDocument() { | 177 function createMediaMetricsForDocument() { |
167 // Searches for all video and audio elements on the page and creates a | 178 // Searches for all video and audio elements on the page and creates a |
168 // corresponding media metric instance for each. | 179 // corresponding media metric instance for each. |
169 var mediaElements = document.querySelectorAll('video, audio'); | 180 var mediaElements = document.querySelectorAll('video, audio'); |
170 for (var i = 0; i < mediaElements.length; i++) | 181 for (var i = 0; i < mediaElements.length; i++) |
171 window.__mediaMetrics.push(new MediaMetric(mediaElements[i])); | 182 window.__mediaMetrics.push(new MediaMetric(mediaElements[i])); |
172 } | 183 } |
173 | 184 |
(...skipping 11 matching lines...) Expand all Loading... |
185 function getAllMetrics() { | 196 function getAllMetrics() { |
186 // Returns a summary (info + metrics) for all media metrics. | 197 // Returns a summary (info + metrics) for all media metrics. |
187 var metrics = []; | 198 var metrics = []; |
188 for (var i = 0; i < window.__mediaMetrics.length; i++) | 199 for (var i = 0; i < window.__mediaMetrics.length; i++) |
189 metrics.push(window.__mediaMetrics[i].getSummary()); | 200 metrics.push(window.__mediaMetrics[i].getSummary()); |
190 return metrics; | 201 return metrics; |
191 } | 202 } |
192 | 203 |
193 window.__globalCounter = 0; | 204 window.__globalCounter = 0; |
194 window.__mediaMetrics = []; | 205 window.__mediaMetrics = []; |
| 206 window.__getMediaMetric = getMediaMetric; |
195 window.__getAllMetrics = getAllMetrics; | 207 window.__getAllMetrics = getAllMetrics; |
196 window.__createMediaMetricsForDocument = createMediaMetricsForDocument; | 208 window.__createMediaMetricsForDocument = createMediaMetricsForDocument; |
197 })(); | 209 })(); |
OLD | NEW |