Media player clients can transmit valuable information to Content Delivery Networks (CDNs) with each object request. Transmitting that data can improve QoS monitoring, adaptive traffic optimization, and delivery performance, ultimately enhancing the consumer experience.
The implementation in ExoPlayer is based on the specification defined in CTA-5004.
CMCD support in Exoplayer
CMCD support in ExoPlayer can only be enabled for adaptive streaming formats, such as DASH, HLS, and SmoothStreaming.
CMCD data keys
CMCD data keys are classified into four distinct types:
- CMCD-Request: keys whose values vary with each request.
- CMCD-Object: keys whose values vary with the object being requested.
- CMCD-Status: keys whose values don't vary with every request or object.
- CMCD-Session: keys whose values are expected to be invariant over the life of the session.
Enable CMCD
To enable CMCD, you need to create an instance of CmcdConfiguration.Factory
and pass this to the MediaSource.Factory
which is used when building the
player. You can either use the default CmcdConfiguration.Factory
or provide
your own custom factory which is called each time an adaptive media source is
created for the given media item.
Enable CMCD with default configuration factory
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);
Enable CMCD with custom configuration factory
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(): Map<@CmcdConfiguration.HeaderKey String, String> { return ImmutableMap.Builder<@CmcdConfiguration.HeaderKey String, String>() .put(CmcdConfiguration.KEY_CMCD_OBJECT, "key1=stringValue") .buildOrThrow() } override fun getRequestedMaximumThroughputKbps(throughputKbps: Int): Int { return 5 * throughputKbps } } val sessionId = UUID.randomUUID().toString() val contentId = UUID.randomUUID().toString() return CmcdConfiguration(sessionId, contentId, cmcdRequestConfig) } } // Create media source factory and set your custom cmcdConfigurationFactory. val mediaSourceFactory = DefaultMediaSourceFactory(context) .setCmcdConfigurationFactory(cmcdConfigurationFactory)
Java
CmcdConfiguration.Factory cmcdConfigurationFactory = new CmcdConfiguration.Factory() { @Override public CmcdConfiguration createCmcdConfiguration(MediaItem mediaItem) { CmcdConfiguration.RequestConfig cmcdRequestConfig = new CmcdConfiguration.RequestConfig() { @Override public boolean isKeyAllowed(String key) { return key.equals("br") || key.equals("bl"); } @Override public Map<@CmcdConfiguration.HeaderKey String, String> getCustomData() { return new ImmutableMap.Builder<@CmcdConfiguration.HeaderKey String, String>() .put(CmcdConfiguration.KEY_CMCD_OBJECT, "key1=stringValue") .buildOrThrow(); } @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); } }; // Create media source factory and set your custom cmcdConfigurationFactory. MediaSource.Factory mediaSourceFactory = new DefaultMediaSourceFactory(context) .setCmcdConfigurationFactory(cmcdConfigurationFactory);
CMCD data examples
These examples illustrate valid data combinations sent as custom HTTP request headers when fetching media chunks:
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"
CMCD-Request:bl=21300,dl=18500,mtp=48100,nor="..%2F300kbps%2Ftrack.m4v",nrr="12323-48763",su
CMCD-Object:br=3200,d=4004,ot=v,tb=6000
CMCD-Status:bs,rtp=12000
CMCD-Session:cid="faec5fc2-ac30-11ea-bb37-0242ac130002",pr=1.08,sf=d,sid="6e2fb550-c457-11e9-bb97-0800200c9a66",st=v