普通文本  |  85行  |  2.73 KB

# Copyright 2013 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import logging
import os

from metrics import Metric


class MediaMetric(Metric):
  """MediaMetric class injects and calls JS responsible for recording metrics.

  Default media metrics are collected for every media element in the page,
  such as decoded_frame_count, dropped_frame_count, decoded_video_bytes, and
  decoded_audio_bytes.
  """

  def __init__(self, tab):
    super(MediaMetric, self).__init__()
    with open(os.path.join(os.path.dirname(__file__), 'media.js')) as f:
      js = f.read()
      tab.ExecuteJavaScript(js)
    self._results = None
    self._skip_basic_metrics = False

  def Start(self, page, tab):
    """Create the media metrics for all media elements in the document."""
    if hasattr(page, 'skip_basic_metrics'):
      self._skip_basic_metrics = page.skip_basic_metrics
    tab.ExecuteJavaScript('window.__createMediaMetricsForDocument()')

  def Stop(self, page, tab):
    self._results = tab.EvaluateJavaScript('window.__getAllMetrics()')

  def AddResults(self, tab, results):
    """Reports all recorded metrics as Telemetry perf results."""
    trace_names = []
    for media_metric in self._results:
      trace_names.append(self._AddResultsForMediaElement(media_metric, results))

    return '_'.join(trace_names) or tab.url

  def _AddResultsForMediaElement(self, media_metric, results):
    """Reports metrics for one media element.

    Media metrics contain an ID identifying the media element and values:
    media_metric = {
      'id': 'video_1',
      'metrics': {
          'time_to_play': 120,
          'decoded_bytes': 13233,
          ...
      }
    }
    """
    def AddOneResult(metric, unit):
      metrics = media_metric['metrics']
      for m in metrics:
        if m.startswith(metric):
          special_label = m[len(metric):]
          if isinstance(metrics[m], list):
            values = [float(v) for v in metrics[m]]
          else:
            values = float(metrics[m])
          results.Add(trace + special_label, unit, values,
                      chart_name=metric, data_type='default')

    trace = media_metric['id']
    if not trace:
      logging.error('Metrics ID is missing in results.')
      return

    if not self._skip_basic_metrics:
      AddOneResult('buffering_time', 'ms')
      AddOneResult('decoded_audio_bytes', 'bytes')
      AddOneResult('decoded_video_bytes', 'bytes')
      AddOneResult('decoded_frame_count', 'frames')
      AddOneResult('dropped_frame_count', 'frames')
      AddOneResult('time_to_play', 'ms')

    AddOneResult('avg_loop_time', 'ms')
    AddOneResult('seek', 'ms')
    AddOneResult('mse', 'ms')
    return trace