通用媒体客户端数据 (CMCD)

媒体播放器客户端可以随每个对象请求将有价值的信息传输到内容分发网络 (CDN)。传输这些数据可以改进服务质量 (QoS) 监控、自适应流量优化和传送性能,最终提升消费者体验。

ExoPlayer 中的实现基于 CTA-5004 中定义的规范。

Exoplayer 中的 CMCD 支持

系统只能为自适应流式传输格式(例如 DASHHLSSmoothStreaming)启用 ExoPlayer 中的 CMCD 支持。

CMCD 数据键

CMCD 数据键分为四种不同的类型:

  • CMCD-请求:其值因请求而异的键。
  • CMCD-Object:值因所请求的对象而异的键。
  • CMCD 状态:其值不会因每个请求或对象而异的键。
  • 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