Common Media Client Data (CMCD)

媒體播放器用戶端可以透過每個物件要求,將重要資訊傳輸至內容傳遞網路 (CDN)。傳輸這類資料可改善服務品質監控、自適應流量最佳化和傳輸效能,最終提升消費者體驗。

ExoPlayer 的實作方式是以 CTA-5004 中定義的規格為基礎。

Exoplayer 中的 CMCD 支援

ExoPlayer 僅支援自動調整串流格式 (例如 DASHHLSSmoothStreaming) 的 CMCD。

CMCD 資料鍵

CMCD 資料鍵分為四種不同類型:

  • CMCD-Request:值會隨每次請求而異的鍵。
  • CMCD-Object:值會隨要求物件而異的鍵。
  • CMCD-Status:值不會隨每個要求或物件而異的鍵。
  • CMCD-Session:值在工作階段生命週期內應保持不變的金鑰。

資料傳輸模式

CMCD 資料可透過下列其中一種方式傳輸:

  • 做為自訂 HTTP 要求標頭,這是預設行為。
  • 做為 HTTP 查詢引數。

啟用 CMCD

如要啟用 CMCD,您需要建立 CmcdConfiguration.Factory 的執行個體,並將其傳遞至建構播放器時使用的 MediaSource.Factory。您可以選擇使用預設的 CmcdConfiguration.Factory,也可以提供自訂工廠,系統每次為指定媒體項目建立自適應媒體來源時,都會呼叫該工廠。

使用預設設定工廠啟用 CMCD

Kotlin

// Create media source factory and set default cmcdConfigurationFactory.
val mediaSourceFactory =
  DefaultMediaSourceFactory(context)
    .setCmcdConfigurationFactory(CmcdConfiguration.Factory.DEFAULT)

Java

// Create media source factory and set default cmcdConfigurationFactory.
MediaSource.Factory mediaSourceFactory =
    new DefaultMediaSourceFactory(context)
        .setCmcdConfigurationFactory(CmcdConfiguration.Factory.DEFAULT);

使用自訂設定工廠啟用 CMCD

Kotlin

val cmcdConfigurationFactory =
  object : CmcdConfiguration.Factory {
    override fun createCmcdConfiguration(mediaItem: MediaItem): CmcdConfiguration {
      val cmcdRequestConfig =
        object : CmcdConfiguration.RequestConfig {
          override fun isKeyAllowed(key: String): Boolean {
            return key == "br" || key == "bl"
          }

          override fun getCustomData():
            ImmutableListMultimap<@CmcdConfiguration.HeaderKey String, String> {
            return ImmutableListMultimap.of(
              CmcdConfiguration.KEY_CMCD_OBJECT,
              "key1=stringValue",
            )
          }

          override fun getRequestedMaximumThroughputKbps(throughputKbps: Int): Int {
            return 5 * throughputKbps
          }
        }

      val sessionId = UUID.randomUUID().toString()
      val contentId = UUID.randomUUID().toString()

      return CmcdConfiguration(sessionId, contentId, cmcdRequestConfig, MODE_QUERY_PARAMETER)
    }
  }

// Create media source factory and set your custom cmcdConfigurationFactory.
val mediaSourceFactory =
  DefaultMediaSourceFactory(context).setCmcdConfigurationFactory(cmcdConfigurationFactory)

Java

CmcdConfiguration.Factory cmcdConfigurationFactory =
    mediaItem -> {
      CmcdConfiguration.RequestConfig cmcdRequestConfig =
          new CmcdConfiguration.RequestConfig() {
            @Override
            public boolean isKeyAllowed(String key) {
              return key.equals("br") || key.equals("bl");
            }

            @Override
            public ImmutableListMultimap<@HeaderKey String, String> getCustomData() {
              return ImmutableListMultimap.of(
                  CmcdConfiguration.KEY_CMCD_OBJECT, "key1=stringValue");
            }

            @Override
            public int getRequestedMaximumThroughputKbps(int throughputKbps) {
              return 5 * throughputKbps;
            }
          };

      String sessionId = UUID.randomUUID().toString();
      String contentId = UUID.randomUUID().toString();

      return new CmcdConfiguration(
          sessionId, contentId, cmcdRequestConfig, MODE_QUERY_PARAMETER);
    };

// Create media source factory and set your custom cmcdConfigurationFactory.
MediaSource.Factory mediaSourceFactory =
    new DefaultMediaSourceFactory(context)
        .setCmcdConfigurationFactory(cmcdConfigurationFactory);

CMCD 資料範例

以下範例說明擷取媒體區塊時傳送的有效資料組合:

  • 以自訂 HTTP 要求標頭的形式

       CMCD-Session:sid="6e2fb550-c457-11e9-bb97-0800200c9a66"
    
       CMCD-Request:mtp=25400 CMCD-Object:br=3200,d=4004,ot=v,tb=6000
       CMCD-Status:bs,rtp=15000
       CMCD-Session:sid="6e2fb550-c457-11e9-bb97-0800200c9a66"
    
  • 做為 HTTP 查詢引數

       ?CMCD=sid%3D%226e2fb550-c457-11e9-bb97-0800200c9a66%22
    
       ?CMCD=br%3D3200%2Cbs%2Cd%3D4004%2Cmtp%3D25400%2Cot%3Dv%2Crtp
       %3D15000%2Csid%3D%226e2fb550-c457-11e9-bb97-
       0800200c9a66%22%2Ctb%3D6000