Dash.js: Implement Common-Media-Client-Data specification

Created on 5 Feb 2020  ·  9Comments  ·  Source: Dash-Industry-Forum/dash.js

The CTA is about to complete the Common-Media-Client-Data specification. This specification details a common query arg (or request header) which is used my media players to convey useful information to CDNs. The draft spec is accessible here: https://docs.google.com/document/d/1S_Dj_aHVnbWnjeJYMfLU1D6tZoqYdgHT1stfznBvxig

I chair the work group at CTA which is developing this spec. I was hoping to get an early reference implementation of it, as an indicator of the level of effort involved in implementing the spec in a media player.

The request is
a) Add a new property to mediaPlayer sendCMCDHeader: Boolean, false by default
b) Add a check box in the reference player to turn this on
c) Add as many of the optional keys as are feasible within one sprint, especially those that are easily accessible with current code structure. The sid (session ID) is required. The 'nor' next-object-request would be most interesting too.

During the implementation, let me know if any of the suggested key values would be difficult to obtain for a media player, as we may modify the spec accordingly if that is the case.

Cheers
Will Law

Feature Request

Most helpful comment

Thanks for the great progress and the updates on the new encoding.

v=1,sid="b248658d-1d1a-4039-91d0-8c08ba597da5",cid="21cf726cfe3d937b5f974f72bb5bd06a",did="dash.js-cmcd-default-id",st="v",br=130,ot="a",d=1997,mtp=20170,dl=28011

Some minor corrections

  1. The st and ot keys have values whose types are Tokens and not Strings, hence they must not be quoted. Correct usage would be st=v,ot=a,
  2. For the default did string, can you include the dash.js version? Also no need to add in "cmcd-default-id". Something like "dash.js-v3.0.2" would be sufficient and concise.

Answers to your questions:

  1. "rtp: How does the client decide on an optimal value? Isn't this related to the "dl" parameter? Or should rtp use the @minBufferTime attribute? I think a concrete example or additional guidelines would be useful here".
    Firstly, no need to include this parameter in this first implementation. This is an advanced use-case, in which the player will instruct the CDN to not over-deliver the asset. It would likely be expressed as a fixed multiple of the encoded bitrate "br" . So you would open up a config setting setting for dash.js that would define the mutiple to be used and only if that property was set, would a rtp key be added to each CMCD payload with a value of br*multiple.
  1. "nor: Problem here is that dash.js loads segments sequentially. Means, when segment n has been appended to the buffer then the request for segment n+1 is generated. Consequently, we do not know about the request for segment n+1 when doing the request for segment n.
    nnr: Similar to nor, might be possible for low latency streaming though. Got to check this."
    Hmm, this is indeed an issue. Prefetch is a super-useful feature that can increase CDN performance, however your point about the next object being calculated just-in-time is a good one. For now, leave this feature out. Maybe at the f2f we can discuss a inexpensive way for the player to figure this out.

Thanks for adding this in the next release. It will certainly help the chicken/egg problem of getting adoption and implementation of the spec, as now we have a tool that CDNs can use to drive test traffic.

All 9 comments

@wilaw : As I am starting to look into this. Can you provide a sample MPD hosted on Akamai CDN that does not reject preflight requests with the new header? As an example:
Request header field common-media-client-data is not allowed by Access-Control-Allow-Headers in preflight response

The spec allows two modes of operation - custom header (which requires preflight auth) and query args. The query arg mode is really intended for MSE-based usage due to the limitations you have pointed out with headers. Therefore, please only implement the query arg mode i.e attach a custom query argument to each object request. This should not require any special permissions from the server.

Update: We have implemented some aspects of the specification. This includes:

  • Added a CMCD option to the reference landing page. It includes the possibility to enable the CMCD reporting as well as setting sid,cid,did. Right now the sid is mandatory, no query parameters will be attached to the outgoing requests if the sid is not specified.
  • The following parameters are implemented:

    • Session ID (sid): must be specified via UI or the settings object

    • Content ID (cid): must be specified via UI or the settings object

    • Device ID (did): must be specified via UI or the settings object

    • Object duration (d): Has to be verified against low latency streams

    • Measured Throughput (mtp)

    • Encoded Bitrate (br)

    • Deadline (dl): Calculated via: bufferlevel divided by playback rate

    • Playback rate (pr)

    • Object type (ot): Requests to the license server are currently not enhanced with cmcd parameters

    • Streaming Format (sf): Only DASH and Smooth Streaming

We have pushed a branch here: https://github.com/fraunhoferfokus/dash.js/tree/feature-cmcd

Before we merge the current version to the main repo the following steps are required

  • Write unit tests for the new model
  • Make sure the described parameters are reset correctly when a new video is started
  • Provide a demo in the samples folder
  • Discuss potential problems with parameters like nor in this thread

Great progress! Some additional comments:

  1. If SID is not specified, can you autogenerate a UUID for the playback session? Some sample code shown below
function create_UUID(){
    var dt = new Date().getTime();
    var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
        var r = (dt + Math.random()*16)%16 | 0;
        dt = Math.floor(dt/16);
        return (c=='x' ? r :(r&0x3|0x8)).toString(16);
    });
    return uuid;
}
  1. If CID is not specified, can you autogenerate by doing a MD5 (or other) hash of the manifest URL?

  2. if DID is not specified, can you insert something like "dash.js-v3.0.2"

  3. For "bs" - buffer state, can you at least flag a buffer risk if buffer < segment duration, or buffer empty if in fact you are rebuffering?

Cheers
Will

In last CMCD meeting this week, the spec had a change to make it compliant with an upcoming IETF standard https://httpwg.org/http-extensions/draft-ietf-httpbis-header-structure.html for header structure. As a result, the payload is now constructed with the following changes

  • Use = as key/value separator
  • Use comma as delimiter.
  • String types must include double quotes
  • Query arg value must be URLEncoded.

Example Header:

Common-Media-Client-Data: sid=”6e2fb550-c457-11e9-bb97-0800200c9a66”,rtp=15000,d=4004,ot=v,sf=d

Equivalent example query arg (which dash.js should use):

?Common-Media-Client-Data=%E2%80%9D6e2fb550-c457-11e9-bb97-0800200c9a66%E2%80%9D%2Crtp%3D15000%2Cd%3D4004%2Cot%3Dv%2Csf%3Dd

Sorry for this update mid-sprint. It should not change again before publication. Hopefully the required changes are small and mostly around formatting.

Update on the status:

  • Added a sample to the samples page: samples > advanced > cmcd
  • Added JSDoc to Settings.js
  • Reset CMCD Model in MediaPlayer when new content is attached
  • sid,cid and did are generated when not provided by the user
  • bs is implemented providing all four values (1-4) as defined in the spec
  • Use = as key/value separator
  • Put string types in double quotes

An example request from the new samples page: https://dash.akamaized.net/envivio/EnvivioDash3/v4_258-270146-i-15.m4s?Common-Media-Client-Data=v%3D1%2Csid%3D%22b248658d-1d1a-4039-91d0-8c08ba597da5%22%2Ccid%3D%2221cf726cfe3d937b5f974f72bb5bd06a%22%2Cdid%3D%22dash.js-cmcd-default-id%22%2Cst%3D%22v%22%2Cbr%3D130%2Cot%3D%22a%22%2Cd%3D1997%2Cmtp%3D20170%2Cdl%3D28011

Regarding the missing parameters:

  • rtp: How does the client decide on an optimal value? Isn't this related to the "dl" parameter? Or should rtp use the @minBufferTime attribute? I think a concrete example or additional guidelines would be useful here.
  • nor: Problem here is that dash.js loads segments sequentially. Means, when segment n has been appended to the buffer then the request for segment n+1 is generated. Consequently, we do not know about the request for segment n+1 when doing the request for segment n.
  • nnr: Similar to nor, might be possible for low latency streaming though. Got to check this.

I will add the current implementation for this PR to the next release. In my opinion it has a state in which users can test/use it. In addition, it should not have an impact on the general behavior of the player.

Thanks for the great progress and the updates on the new encoding.

v=1,sid="b248658d-1d1a-4039-91d0-8c08ba597da5",cid="21cf726cfe3d937b5f974f72bb5bd06a",did="dash.js-cmcd-default-id",st="v",br=130,ot="a",d=1997,mtp=20170,dl=28011

Some minor corrections

  1. The st and ot keys have values whose types are Tokens and not Strings, hence they must not be quoted. Correct usage would be st=v,ot=a,
  2. For the default did string, can you include the dash.js version? Also no need to add in "cmcd-default-id". Something like "dash.js-v3.0.2" would be sufficient and concise.

Answers to your questions:

  1. "rtp: How does the client decide on an optimal value? Isn't this related to the "dl" parameter? Or should rtp use the @minBufferTime attribute? I think a concrete example or additional guidelines would be useful here".
    Firstly, no need to include this parameter in this first implementation. This is an advanced use-case, in which the player will instruct the CDN to not over-deliver the asset. It would likely be expressed as a fixed multiple of the encoded bitrate "br" . So you would open up a config setting setting for dash.js that would define the mutiple to be used and only if that property was set, would a rtp key be added to each CMCD payload with a value of br*multiple.
  1. "nor: Problem here is that dash.js loads segments sequentially. Means, when segment n has been appended to the buffer then the request for segment n+1 is generated. Consequently, we do not know about the request for segment n+1 when doing the request for segment n.
    nnr: Similar to nor, might be possible for low latency streaming though. Got to check this."
    Hmm, this is indeed an issue. Prefetch is a super-useful feature that can increase CDN performance, however your point about the next object being calculated just-in-time is a good one. For now, leave this feature out. Maybe at the f2f we can discuss a inexpensive way for the player to figure this out.

Thanks for adding this in the next release. It will certainly help the chicken/egg problem of getting adoption and implementation of the spec, as now we have a tool that CDNs can use to drive test traffic.

Can I close this issue for now and we open a new one once we continue working on rtp and nor parameters?

Absolutely. Thanks for the work on this. There may be changes once the spec gets finalized (it went to community review this week with dash.js as the example player) , but I'll open a new issue for those in the future.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

lioun1729 picture lioun1729  ·  6Comments

NguyenTungs picture NguyenTungs  ·  5Comments

bbert picture bbert  ·  5Comments

redd29 picture redd29  ·  4Comments

budziq picture budziq  ·  5Comments