Analytics

ExoPlayer は、再生分析のさまざまなニーズに対応します。最終的に アナリティクスとは、データを収集、解釈、集計、要約することです。 することができます。このデータはデバイス上の ログを記録、デバッグしたり、今後の再生決定を通知したり、 全デバイスの再生を監視できます

通常、分析システムではまずイベントを収集して処理する必要がある 意味のあるものにする:

  • イベントの収集: これを行うには、ExoPlayerAnalyticsListener を登録します。 作成します。登録されたアナリティクス リスナーは、セッション中に発生したイベントを受信します。 プレーヤーの使用状況。各イベントは対応するメディアに関連付けられます。 アイテムの情報に加えて、再生位置、タイムスタンプ メタデータを含んでいます。
  • イベント処理: 一部の分析システムでは、未加工のイベントがサーバーにアップロードされ、 サーバーサイドで行われる処理です。また、VPC フローログで その方が簡単であったり、送信できる情報の量が アップロードする必要があります。ExoPlayer は PlaybackStatsListener を提供します。 次の処理ステップを実行できます。 <ph type="x-smartling-placeholder">
      </ph>
    1. イベントの解釈: 分析に役立てるには、イベントに 単一の再生のコンテキストで解釈されます。たとえば、未加工の STATE_BUFFERING へのプレーヤー状態変化のイベントは、 初期バッファリング、再バッファリング、シーク後に発生するバッファリングなどが該当します。
    2. 状態トラッキング: このステップではイベントをカウンタに変換します。たとえば 状態変化イベントはカウンタに変換して 各再生状態における課金額を表します。その結果、基本的な一連の分析データが 値を指定します。
    3. 集計: このステップでは、複数の分析データ 通常はカウンタを追加します。
    4. サマリー指標の計算: 特に有用な指標の多くは、 平均を計算する、または基本的な分析データの値を できます。サマリー指標は、単一または複数の指標について計算できます。 再生回数です。

AnalyticsListener によるイベント コレクション

プレーヤーの未加工の再生イベントは AnalyticsListener に報告されます。 あります。簡単に独自のリスナーを追加し、 確認する方法:

Kotlin

exoPlayer.addAnalyticsListener(
  object : AnalyticsListener {
    override fun onPlaybackStateChanged(
      eventTime: EventTime, @Player.State state: Int
    ) {}

    override fun onDroppedVideoFrames(
      eventTime: EventTime,
      droppedFrames: Int,
      elapsedMs: Long,
    ) {}
  }
)

Java

exoPlayer.addAnalyticsListener(
    new AnalyticsListener() {
      @Override
      public void onPlaybackStateChanged(
          EventTime eventTime, @Player.State int state) {}

      @Override
      public void onDroppedVideoFrames(
          EventTime eventTime, int droppedFrames, long elapsedMs) {}
    });

各コールバックに渡される EventTime は、イベントをメディアに関連付けます。 アイテム、再生位置、タイムスタンプ メタデータを含んでいます。

  • realtimeMs: イベントの実時間。
  • timelinewindowIndexmediaPeriodId: 再生リストと イベントが属する再生リスト内のアイテムです。mediaPeriodId オプションの追加情報が含まれます。たとえば、 イベントはアイテム内の広告に属します。
  • eventPlaybackPositionMs: イベントが発生したときのアイテムの再生位置 発生しました。
  • currentTimelinecurrentWindowIndexcurrentMediaPeriodIdcurrentPlaybackPositionMs: 上記と同じ。ただし、現在再生中のアイテム用。「 現在再生中のアイテムが、イベントの宛先のアイテムと異なる場合があります たとえば、イベントが次のイベントの事前バッファリングに対応する場合など、 指定します。

PlaybackStatsListener を使用したイベント処理

PlaybackStatsListener はオンデバイスを実装する AnalyticsListener です。 使用します。カウンタと導出を使用して PlaybackStats を計算します。 次の指標が含まれます。

  • 概要指標(合計再生時間など)。
  • アダプティブ再生品質の指標(動画の平均解像度など)。
  • レンダリング品質の指標(フレーム ドロップの割合など)。
  • リソース使用量の指標(ネットワーク経由で読み取られたバイト数など)。

利用可能な数と導出の指標の完全なリストについては、 PlaybackStats Javadoc

PlaybackStatsListener では、メディア アイテムごとに個別の PlaybackStats が計算されます。 各アイテムに挿入されるクライアントサイド広告ですマイページ 完了したことを通知するために PlaybackStatsListener にコールバックを提供できます。 呼び出され、コールバックに渡された EventTime を使用して、 再生が終了しました。分析データを集計して、 複数回再生されることがあります。また、PlaybackStats にクエリを実行して、 現在の再生セッションをいつでも確認できます。 PlaybackStatsListener.getPlaybackStats()

Kotlin

exoPlayer.addAnalyticsListener(
  PlaybackStatsListener(/* keepHistory= */ true) {
    eventTime: EventTime?,
    playbackStats: PlaybackStats?,
    -> // Analytics data for the session started at `eventTime` is ready.
  }
)

Java

exoPlayer.addAnalyticsListener(
    new PlaybackStatsListener(
        /* keepHistory= */ true,
        (eventTime, playbackStats) -> {
          // Analytics data for the session started at `eventTime` is ready.
        }));

PlaybackStatsListener のコンストラクタは、完全な状態を保持するオプションを提供します。 処理されたイベントの履歴です。ただし、これにより未知のメモリ オーバーヘッドが発生する可能性があります。 イベントの数に応じて異なります。そのため、 処理の全履歴にアクセスする必要がある場合にのみ オンにしてください イベントに絞り込むことができます。

なお、PlaybackStats は、拡張された状態セットを使用して、 メディアの状態だけでなく、ユーザーの再生意図や 再生が中断または終了した理由などの情報を取得できます。

再生状態 プレイするユーザーの意図 プレイするつもりはない
再生前 JOINING_FOREGROUND NOT_STARTEDJOINING_BACKGROUND
アクティブ再生 PLAYING
再生の中断 BUFFERINGSEEKING PAUSEDPAUSED_BUFFERINGSUPPRESSEDSUPPRESSED_BUFFERINGINTERRUPTED_BY_AD
終了状態 ENDEDSTOPPEDFAILEDABANDONED

ユーザーがプレイしたタイミングを区別するには、ユーザーがプレイする意思があるかどうかが重要 パッシブな待機時間から再生の続きをアクティブに待機している時間のことです。たとえば PlaybackStats.getTotalWaitTimeMs は、実行された合計時間を返します。 JOINING_FOREGROUNDBUFFERINGSEEKING の各ステータスが表示されますが、 再生が一時停止されました。同様に、PlaybackStats.getTotalPlayAndWaitTimeMs は ユーザーがプレイを意図した場合の合計時間、つまり 待機時間と PLAYING 状態で費やされた合計時間です。

処理済みイベントと解釈済みイベント

PlaybackStatsListener を使用して、処理済みイベントと解釈済みイベントを記録できます。 keepHistory=true に置き換えます。結果の PlaybackStats には、 次のイベントリスト:

  • playbackStateHistory: 拡張再生状態の順序付きリスト。 適用を開始したEventTime。また、 PlaybackStats.getPlaybackStateAtTime: 特定の壁の状態を検索します。 時計の時刻です。
  • mediaTimeHistory: 実時間とメディア時刻のペアの履歴。 その時点でメディアのどの部分が再生されていたかを再構築できます。Google Chat では PlaybackStats.getMediaTimeMsAtRealtimeMs を使用して再生を検索します。 特定の実時間での位置を表すことができます。
  • videoFormatHistoryaudioFormatHistory: 動画の順序付きリスト 再生中に使用されたオーディオ形式を、開始元の EventTime で 使用されます。
  • fatalErrorHistorynonFatalErrorHistory: 致命的なエラーと 発生した非致命的なエラーを EventTime で解決します。致命的なエラーは 一方、致命的でないエラーは復元可能な場合があります。

単一再生の分析データ

このデータは、PlaybackStatsListener を使用すると自動的に収集されます。 keepHistory=false に置き換えます。最終的な値は公開フィールドです。 PlaybackStats Javadoc と再生状態の継続時間をご覧ください getPlaybackStateDurationMs から返されます。参考情報として、 値を返す getTotalPlayTimeMsgetTotalWaitTimeMs などのメソッド 特定の再生状態の組み合わせの再生時間。

Kotlin

Log.d(
  "DEBUG",
  "Playback summary: " +
    "play time = " +
    playbackStats.totalPlayTimeMs +
    ", rebuffers = " +
    playbackStats.totalRebufferCount
)

Java

Log.d(
    "DEBUG",
    "Playback summary: "
        + "play time = "
        + playbackStats.getTotalPlayTimeMs()
        + ", rebuffers = "
        + playbackStats.totalRebufferCount);

複数の再生の分析データを集約する

次の呼び出しによって、複数の PlaybackStats を組み合わせることができます。 PlaybackStats.merge。結果の PlaybackStats には、集計値、 結合されたすべての再生のデータです。なお、 個別に再生イベントを発生させることも可能です。

PlaybackStatsListener.getCombinedPlaybackStats を使用すると、 全期間に収集されたすべての分析データの集計ビュー PlaybackStatsListener

計算済みサマリー指標

基本的な分析データに加えて、PlaybackStats には多くのメソッドが用意されています。 サマリー指標を計算できます

Kotlin

Log.d(
  "DEBUG",
  "Additional calculated summary metrics: " +
    "average video bitrate = " +
    playbackStats.meanVideoFormatBitrate +
    ", mean time between rebuffers = " +
    playbackStats.meanTimeBetweenRebuffers
)

Java

Log.d(
    "DEBUG",
    "Additional calculated summary metrics: "
        + "average video bitrate = "
        + playbackStats.getMeanVideoFormatBitrate()
        + ", mean time between rebuffers = "
        + playbackStats.getMeanTimeBetweenRebuffers());

高度なトピック

分析データと再生メタデータの関連付け

個々の再生の分析データを収集する場合は、 再生分析データを、対象のメディアに関するメタデータと 表示されます。

メディア固有のメタデータは MediaItem.Builder.setTag で設定することをおすすめします。 メディアタグは、未加工のイベントと未加工のイベントについてレポートされる EventTime の一部です。 PlaybackStats が終了したので、 対応するアナリティクス データ:

Kotlin

PlaybackStatsListener(/* keepHistory= */ false) {
  eventTime: EventTime,
  playbackStats: PlaybackStats ->
  val mediaTag =
    eventTime.timeline
      .getWindow(eventTime.windowIndex, Timeline.Window())
      .mediaItem
      .localConfiguration
      ?.tag
    // Report playbackStats with mediaTag metadata.
}

Java

new PlaybackStatsListener(
    /* keepHistory= */ false,
    (eventTime, playbackStats) -> {
      Object mediaTag =
          eventTime.timeline.getWindow(eventTime.windowIndex, new Timeline.Window())
              .mediaItem
              .localConfiguration
              .tag;
      // Report playbackStats with mediaTag metadata.
    });

カスタム分析イベントの報告

分析データにカスタム イベントを追加する必要がある場合は、 独自のデータ構造で分析し、レポート対象のイベントと PlaybackStats 遅くなります。必要に応じて、DefaultAnalyticsCollector を拡張できます カスタム イベント用に EventTime インスタンスを生成し、 登録済みのリスナーに割り当てる必要があります。

Kotlin

private interface ExtendedListener : AnalyticsListener {
  fun onCustomEvent(eventTime: EventTime)
}

private class ExtendedCollector : DefaultAnalyticsCollector(Clock.DEFAULT) {
  fun customEvent() {
    val eventTime = generateCurrentPlayerMediaPeriodEventTime()
    sendEvent(eventTime, CUSTOM_EVENT_ID) { listener: AnalyticsListener ->
      if (listener is ExtendedListener) {
        listener.onCustomEvent(eventTime)
      }
    }
  }
}

// Usage - Setup and listener registration.
val player = ExoPlayer.Builder(context).setAnalyticsCollector(ExtendedCollector()).build()
player.addAnalyticsListener(
  object : ExtendedListener {
    override fun onCustomEvent(eventTime: EventTime?) {
      // Save custom event for analytics data.
    }
  }
)
// Usage - Triggering the custom event.
(player.analyticsCollector as ExtendedCollector).customEvent()

Java

private interface ExtendedListener extends AnalyticsListener {
  void onCustomEvent(EventTime eventTime);
}

private static class ExtendedCollector extends DefaultAnalyticsCollector {
  public ExtendedCollector() {
    super(Clock.DEFAULT);
  }

  public void customEvent() {
    AnalyticsListener.EventTime eventTime = generateCurrentPlayerMediaPeriodEventTime();
    sendEvent(
        eventTime,
        CUSTOM_EVENT_ID,
        listener -> {
          if (listener instanceof ExtendedListener) {
            ((ExtendedListener) listener).onCustomEvent(eventTime);
          }
        });
  }
}

// Usage - Setup and listener registration.
ExoPlayer player =
    new ExoPlayer.Builder(context).setAnalyticsCollector(new ExtendedCollector()).build();
player.addAnalyticsListener(
    (ExtendedListener) eventTime -> {
      // Save custom event for analytics data.
    });
// Usage - Triggering the custom event.
((ExtendedCollector) player.getAnalyticsCollector()).customEvent();