| Index: chrome/browser/resources/media_internals/media_internals.js
|
| diff --git a/chrome/browser/resources/media_internals/media_internals.js b/chrome/browser/resources/media_internals/media_internals.js
|
| index 5d80b289547ec1aa2cc44a2d2848ee461ea0ddb4..7218c06b8d8596c554c6f6bdf9ee337043d65822 100644
|
| --- a/chrome/browser/resources/media_internals/media_internals.js
|
| +++ b/chrome/browser/resources/media_internals/media_internals.js
|
| @@ -3,14 +3,22 @@
|
| // found in the LICENSE file.
|
|
|
| <include src="cache_entry.js"/>
|
| -<include src="item_store.js"/>
|
| <include src="disjoint_range_set.js"/>
|
| +<include src="event_list.js"/>
|
| +<include src="item_store.js"/>
|
| +<include src="media_player.js"/>
|
| +<include src="metrics.js"/>
|
| +<include src="util.js"/>
|
|
|
| cr.define('media', function() {
|
| + 'use strict';
|
|
|
| // Stores information on open audio streams, referenced by id.
|
| var audioStreams = new media.ItemStore;
|
|
|
| + // Active media players, indexed by 'render_id:player_id'.
|
| + var mediaPlayers = {};
|
| +
|
| // Cached files indexed by key and source id.
|
| var cacheEntriesByKey = {};
|
| var cacheEntries = {};
|
| @@ -26,27 +34,31 @@ cr.define('media', function() {
|
| var audioStreamDiv;
|
| var cacheDiv;
|
|
|
| + // A timer used to limit the rate of redrawing the Media Players section.
|
| + var redrawTimer = null;
|
| +
|
| /**
|
| * Initialize variables and ask MediaInternals for all its data.
|
| */
|
| - initialize = function() {
|
| + function initialize() {
|
| audioStreamDiv = document.getElementById('audio-streams');
|
| cacheDiv = document.getElementById('cache-entries');
|
| +
|
| // Get information about all currently active media.
|
| chrome.send('getEverything');
|
| - };
|
| + }
|
|
|
| /**
|
| * Write the set of audio streams to the DOM.
|
| */
|
| - printAudioStreams = function() {
|
| + function printAudioStreams() {
|
|
|
| /**
|
| * Render a single stream as a <li>.
|
| * @param {Object} stream The stream to render.
|
| * @return {HTMLElement} A <li> containing the stream information.
|
| */
|
| - printStream = function(stream) {
|
| + function printStream(stream) {
|
| var out = document.createElement('li');
|
| out.id = stream.id;
|
| out.className = 'audio-stream';
|
| @@ -54,9 +66,10 @@ cr.define('media', function() {
|
|
|
| out.textContent += 'Audio stream ' + stream.id.split('.')[1];
|
| out.textContent += ' is ' + (stream.playing ? 'playing' : 'paused');
|
| - out.textContent += ' at ' + Math.round(stream.volume * 100) + '% volume.';
|
| + out.textContent += ' at ' + (stream.volume * 100).toFixed(0);
|
| + out.textContent += '% volume.';
|
| return out;
|
| - };
|
| + }
|
|
|
| var out = document.createElement('ul');
|
| audioStreams.map(printStream).forEach(function(s) {
|
| @@ -65,12 +78,22 @@ cr.define('media', function() {
|
|
|
| audioStreamDiv.textContent = '';
|
| audioStreamDiv.appendChild(out);
|
| - };
|
| + }
|
| +
|
| + /**
|
| + * Redraw each MediaPlayer.
|
| + */
|
| + function printMediaPlayers() {
|
| + for (var key in mediaPlayers) {
|
| + mediaPlayers[key].redraw();
|
| + }
|
| + redrawTimer = null;
|
| + }
|
|
|
| /**
|
| * Write the set of sparse CacheEntries to the DOM.
|
| */
|
| - printSparseCacheEntries = function() {
|
| + function printSparseCacheEntries() {
|
| var out = document.createElement('ul');
|
| for (var key in cacheEntriesByKey) {
|
| if (cacheEntriesByKey[key].sparse)
|
| @@ -79,17 +102,17 @@ cr.define('media', function() {
|
|
|
| cacheDiv.textContent = '';
|
| cacheDiv.appendChild(out);
|
| - };
|
| + }
|
|
|
| /**
|
| * Receiving data for an audio stream.
|
| * Add it to audioStreams and update the page.
|
| * @param {Object} stream JSON representation of an audio stream.
|
| */
|
| - addAudioStream = function(stream) {
|
| + function addAudioStream(stream) {
|
| audioStreams.addItem(stream);
|
| printAudioStreams();
|
| - };
|
| + }
|
|
|
| /**
|
| * Receiving all data.
|
| @@ -97,32 +120,47 @@ cr.define('media', function() {
|
| * @param {Object} stuff JSON containing lists of data.
|
| * @param {Object} stuff.audio_streams A dictionary of audio streams.
|
| */
|
| - onReceiveEverything = function(stuff) {
|
| + function onReceiveEverything(stuff) {
|
| audioStreams.addItems(stuff.audio_streams);
|
| printAudioStreams();
|
| - };
|
| + }
|
|
|
| /**
|
| * Removing an item from the appropriate store.
|
| * @param {string} id The id of the item to be removed, in the format
|
| * "item_type.identifying_info".
|
| */
|
| - onItemDeleted = function(id) {
|
| + function onItemDeleted(id) {
|
| var type = id.split('.')[0];
|
| switch (type) {
|
| - case 'audio_streams':
|
| - audioStreams.removeItem(id);
|
| - printAudioStreams();
|
| - break;
|
| + case 'audio_streams':
|
| + audioStreams.removeItem(id);
|
| + printAudioStreams();
|
| + break;
|
| }
|
| - };
|
| + }
|
| +
|
| + /**
|
| + * A render process has ended, delete any media players associated with it.
|
| + * @param {number} renderer The id of the render process.
|
| + */
|
| + function onRendererTerminated(renderer) {
|
| + for (var key in mediaPlayers) {
|
| + if (mediaPlayers[key].renderer == renderer) {
|
| + document.getElementById('media-players').removeChild(mediaPlayers[key]);
|
| + delete mediaPlayers[key];
|
| + break;
|
| + }
|
| + }
|
| + printMediaPlayers();
|
| + }
|
|
|
| /**
|
| * Receiving net events.
|
| * Update cache information and update that section of the page.
|
| * @param {Array} updates A list of net events that have occurred.
|
| */
|
| - onNetUpdate = function(updates) {
|
| + function onNetUpdate(updates) {
|
| updates.forEach(function(update) {
|
| var id = update.source.id;
|
| if (!cacheEntries[id])
|
| @@ -166,7 +204,7 @@ cr.define('media', function() {
|
| delete requestURLs[update.source.id];
|
| if (range && key) {
|
| if (!cacheEntriesByKey[key]) {
|
| - cacheEntriesByKey[key] = new CacheEntry;
|
| + cacheEntriesByKey[key] = new media.CacheEntry;
|
| cacheEntriesByKey[key].key = key;
|
| }
|
| cacheEntriesByKey[key].size = range[1];
|
| @@ -176,7 +214,7 @@ cr.define('media', function() {
|
| });
|
|
|
| printSparseCacheEntries();
|
| - };
|
| + }
|
|
|
| /**
|
| * Receiving values for constants. Store them for later use.
|
| @@ -184,29 +222,58 @@ cr.define('media', function() {
|
| * @param {Object} constants.eventTypes A dictionary of event name -> int.
|
| * @param {Object} constants.eventPhases A dictionary of event phase -> int.
|
| */
|
| - onReceiveConstants = function(constants) {
|
| + function onReceiveConstants(constants) {
|
| var events = constants.eventTypes;
|
| - for (var e in events)
|
| + for (var e in events) {
|
| eventTypes[events[e]] = e;
|
| + }
|
|
|
| var phases = constants.eventPhases;
|
| - for (var p in phases)
|
| + for (var p in phases) {
|
| eventPhases[phases[p]] = p;
|
| - };
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * Receiving notification of a media event.
|
| + * @param {Object} event The json representation of a MediaLogEvent.
|
| + */
|
| + function onMediaEvent(event) {
|
| + var source = event.renderer + ':' + event.player;
|
| + var item = mediaPlayers[source] ||
|
| + new media.MediaPlayer({id: source, renderer: event.renderer});
|
| + mediaPlayers[source] = item;
|
| + item.addEvent(event);
|
| +
|
| + // Both media and net events could provide the size of the file.
|
| + // Media takes priority, but keep the size in both places synchronized.
|
| + if (cacheEntriesByKey[item.properties.url]) {
|
| + item.properties.total_bytes = item.properties.total_bytes ||
|
| + cacheEntriesByKey[item.properties.url].size;
|
| + cacheEntriesByKey[item.properties.url].size = item.properties.total_bytes;
|
| + }
|
| +
|
| + // Events tend to arrive in groups; don't redraw the page too often.
|
| + if (!redrawTimer)
|
| + redrawTimer = setTimeout(printMediaPlayers, 50);
|
| + }
|
|
|
| return {
|
| initialize: initialize,
|
| addAudioStream: addAudioStream,
|
| + cacheEntriesByKey: cacheEntriesByKey,
|
| onReceiveEverything: onReceiveEverything,
|
| onItemDeleted: onItemDeleted,
|
| + onRendererTerminated: onRendererTerminated,
|
| onNetUpdate: onNetUpdate,
|
| onReceiveConstants: onReceiveConstants,
|
| + onMediaEvent: onMediaEvent
|
| };
|
| });
|
|
|
| /**
|
| * Initialize everything once we have access to the DOM.
|
| */
|
| -window.onload = function() {
|
| +document.addEventListener('DOMContentLoaded', function() {
|
| media.initialize();
|
| -};
|
| +});
|
|
|