Streaming

Here is how to generate streaming urls for your media.

There are two steps:

  • generating the URL
  • signing the URL to protect it (Signing a URL)

Embed URL

The embed URL is the easiest way to add videos to your own website using the Dailymotion Cloud video player. This solution will work on every desktop browser and iPhone/iPad devices.

The generic format of an embed URL is:

http://api.dmcloud.net/player/embed/<user_id>/<media_id>?auth=<auth_token>

URL elements:

  • user_id: this is your user id (e.g.: 4c1a4d3edede832bfd000003)
  • media_id: this is the id of the media (e.g.: 4c922386dede830447000009)
  • auth_token: the authentication token described in Signing a URL

The embed URL must be referenced in an iframe, here is an example HTML code:

<iframe width="848" height="480" frameborder="0" scrolling="no" src="http://api.dmcloud.net/player/embed/<user_id>/<media_id>?auth=<auth_token>"></iframe>

Optional embed url parameters

Here is the list of optional parameters you can add to the signed url’s query string.

  • preset: the player preset id (e.g.: preset=50c846f5dede831ceb000000)
  • autoplay: 1 to automatically play the video (default: 0)
  • chromeless: displays the player without any controls
  • lazy_loading: true not to load the Flash player by default (chromeless and autoplay must be false)
  • wmode: window mode
  • start: number of seconds where to start the video (e.g.: start=30)
  • force_asset_name: the name of the asset you want to stream (e.g.: mp4_h264_aac_fhd) (Transcoding)

Example:

http://api.dmcloud.net/player/embed/4e1dabbddede836ca7000000/50b33568dede8338d8000007?auth=1671181967-0-r5ud8bt5-26fb9a4e32e5a1ff94d062e80f755bb3&autoplay=1&start=2&preset=50c846f5dede831ceb000000

Embed and media type

When using an embed URL, the media type is defined according to the following descending order:

The asset with the highest priority determines the media type, and the assets with a lower priority are not available.

Thumbnail URL

The thumbnails URLs are useful when you want to display a still image of your video in you own website.

The generic format of a thumbnail URL is:

<base_url>/<user_id>/<media_id>/<asset_name>[-<version>].jpeg

URL elements:

  • base_url: http://static.dmcloud.net for HTTP and https://static-ssl.dmcloud.net for HTTPS
  • user_id: this is your user_id (e.g.: 4c1a4d3edede832bfd000003)
  • media_id: this is the id of the media (e.g.: 4c922386dede830447000009)
  • asset_name: the name of the jpeg_thumbnail you want (e.g.: jpeg_thumbnail_small) (Transcoding)
  • version (optional): a number used to force the asset cache flushing

You should note that thumbnails URLs are not signed.

Image resizer

We provide a dynamic image resizer and we highly recommend to use it instead of using the jpeg_thumbnail_(small|medium|large) assets.

To use our image resizer you only need to have the jpeg_thumbnail_source asset available.

Then you must generate a URL following the same guidelines except that the asset_name elements must use the following format:

thumb-[<width>]x[<height>][-f][-qXX]

Asset name elements:

  • width and height: the dimensions, you can provide one of them or both.
  • -f (optional): should we fit the image in the provided dimensions by cropping.
  • -qXX (optional): the quality of the jpeg from 10 to 90, lower values mean more compression so lighter files, defaults to 75.

Video URL

The media URLs are useful when you want to implement your own video player or directly access each media asset.

The generic format of a media URL is:

http://cdn.dmcloud.net/route/<protocol>/<user_id>/<media_id>/<asset_name>[-<version>][.<asset_extension>]?auth=<auth_token>

URL elements:

  • protocol: this is the streaming protocol
  • user_id: this is your user_id (e.g.: 4c1a4d3edede832bfd000003)
  • media_id: this is the id of the media (e.g.: 4c922386dede830447000009)
  • auth_token: the authentication token described in Signing a URL
  • asset_name: the name of the asset you want to stream (e.g.: mp4_h264_aac_fhd) (Transcoding)
  • version (optional): a number used to force the asset cache flushing
  • asset_extension: the extension of the asset, most of the time it is the first part of the asset name (e.g.: mp4); for the source asset, you must know the extension of your uploaded video

Note that when using the version parameter, its value should only change when the cache flushing is required (e.g.: when the source is modified). Therefore, the version value must never be random, otherwise there would not be any caching. We strongly suggest to store a version value on your side which is updated each time the media is modified (e.g.: the source is changed) and use its updated value to generate the new URL version (hence the parameter name).

Streaming protocols

Here is the list of available streaming protocols:

  • http: HTTP Download
  • hps: HTTP Progressive Streaming
  • hds: Adobe HTTP Dynamic Streaming
  • hls: Apple HTTP Live Streaming
  • ss: Microsoft Smooth Streaming

The hds, hls and ss protocols are only valid for Adaptive Bitrate Streaming (abs) assets.

In the case of abs assets, asset_extension may be omitted. You can however use the extension matching the protocols:

  • hls: m3u8
  • hds: f4m
  • dash: mpd

So, the URL format is:

http://cdn.dmcloud.net/route/(hds|hls|ss)/<user_id>/<media_id>/<asset_name>?auth=<auth_token>

Examples:

  • HTTP download url:

    http://cdn.dmcloud.net/route/http/4e1dabbddede836ca7000000/50b33568dede8338d8000007/mp4_h264_aac.mp4?auth=1671181967-0-r5ud8bt5-26fb9a4e32e5a1ff94d062e80f755bb3
  • HDS url:

    http://cdn.dmcloud.net/route/hds/4e1dabbddede836ca7000000/50b33568dede8338d8000007/abs?auth=1671181967-0-r5ud8bt5-26fb9a4e32e5a1ff94d062e80f755bb3

HTTP with adaptive assets

It is possible to stream abs assets with the HTTP protocol.

An abs asset is composed of multiple files and the asset_name follows a different scheme: abs_sXX where XX is a 2 digits number representing the abs stream (e.g.: abs_s00 for the first quality level, abs_s01 for the second, etc).

The URL format is:

http://cdn.dmcloud.net/route/http/<user_id>/<media_id>/abs_s<XX>.mp4?auth=<auth_token>

Example:

http://cdn.dmcloud.net/route/http/4e1dabbddede836ca7000000/50b33568dede8338d8000007/abs_s01.mp4?auth=1359481109-1-0c15c9ub-072c92733a37e9e67557cb502974005d

Client-side CDN URL resolution

Our CDN can deliver 2 types of responses:
  • 302 response
  • 200 response, with the final URL as text in the body

Why ?

Some clients (players, set-top boxes, connected TVs, OSMF, etc) can’t correctly follow (or do not follow) 302 responses. To solve this problem, we can provide the final URL as text in the response’s body to be read client-side.

The URL accepts a redirect parameter in the query string, to force the CDN’s response type to 200 by adding ‘redirect=0’.

Example:

http://cdn.dmcloud.net/route/http/4e268e8194a6f67e29000156/50caece39473990dd30676f4/mp4_h264_aac.mp4?auth=1356534962-3-7gcww41a-517185cf4105d29703da877f7df7a194&redirect=0

Many clients do not handle 302 responses with the Adaptive Bitrate Streaming asset abs.

Then it is recommended to use the redirect=0 query string parameter and read the URL from the response body client-side:

http://cdn.dmcloud.net/route/hds/4e268e8194a6f67e29000156/50caece39473990dd30676f4/abs?auth=1356534962-3-7gcww41a-517185cf4105d29703da877f7df7a194&redirect=0

Note:

The resolution should be performed at the very last moment before the media is played, since we count a view for each request to the CDN.

Examples

Here is a javascript example for client-side URL resolution (containing 3 types of resolution - JSONP, CORS, and CORS without jquery) for 302 responses:

<html>
  <body>
    <head>
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
    </head>
  </body>
  <script>
    var cdn_url = "http://cdn.dmcloud.net/route/hls/4c1a4d3edede832bfd000002/4ff4133bdede832137000000/live_1.m3u8?auth=1348768741-0-x94dnznr-42ce7003b70feab27a45df6586d68327";
    /* JSONP */
    $.ajax({
        url: cdn_url + "&redirect=0",
        dataType: "jsonp",
        success: function(url){ console.log(url); },
    })
    /* CORS */
    $.ajax({
        url: cdn_url + "&redirect=0",
        dataType: "text",
        success: function(url){ console.log(url); },
        xhrFields: { withCredentials: true }
    })
    var req = new XMLHttpRequest();
    req.open('GET', cdn_url + "&redirect=0", false);
    req.send(null);
    if(req.status == 200) {
        url = req.responseText;
        console.log(url);
    }
  </script>
</html>

This solution can obviously be adapted in any language.

Optional media url parameters

  • redirect: force the CDN’s response type, possible values:

    • 1 (default): returns a 302
    • 0: returns a 200, with the final URL as text in the body
  • filename: in the case of an HTTP download url, you can specify a filename (to be used by the browser to save the file)

Example:

http://cdn.dmcloud.net/route/http/4e1dabbddede836ca7000000/50b33568dede8338d8000007/mp4_h264_aac.mp4?auth=1671181967-0-r5ud8bt5-26fb9a4e32e5a1ff94d062e80f755bb3&filename=my_filename

Signing a URL

To sign a URL, the client needs a secret shared with Dailymotion Cloud. This secret is called client secret and is available in the back-office interface as the API key.

A signature is generated as follow:

md5sum = MD5(<sec-level><url-no-query><expires><nonce><secret><sec-data>[<pub-sec-data>])
signed_url = <url>?auth=<expires>-<sec>-<nonce>-<md5sum>[-<pub-sec-data>]
  • expires: an expiration timestamp.
  • sec-level: a security level mask.
  • url-no-query: the URL without the query string.
  • nonce: a 8 characters long random alphanumeric lowercase string to make the signature unique.
  • secret: the client secret.
  • sec-data: if sec-level doesn’t have the DELEGATED bit activated, this component contains concatenated informations for all activated sec levels. See Security Levels below.
  • pub-sec-data: some sec level data have to be passed in clear in the signature. To generate this component the parameters are serialized using x-www-form-urlencoded, compressed with gzip and encoded in base64.

The sec-level, url-no-query, expires, nonce, secret and optional params are concatenated as a string and a hexadecimal MD5 checksum is generated from the result. This checksum is then concatenated to other info separated by a dash and added to the query of the URL to sign using the ‘auth’ parameter.

Security Levels

The client must choose a security level for the signature. Security level defines the mechanism used by Dailymotion Cloud architecture to ensure the signed URL will be used by a single end-user. The different security levels are:

  • None: the signed URL will be valid for everyone
  • ASNUM: the signed URL will only be valid for the AS of the end-user. The ASNUM (for Autonomous System Number) stands for the network identification, each ISP have a different ASNUM for instance.
  • IP: the signed URL will only be valid for the IP of the end-user. This security level may wrongly block some users which have their internet access load-balanced between several proxies. This is the case in some office network or some ISPs.
  • User-Agent: used in addition to one of the two former levels, this level is a limit on the exact user-agent of the end-user. This is more secure but in some specific condition may lead to wrongly blocked users.
  • Use Once: the signed URL will only be usable once. Note: should not be used with stream URLs.
  • Country: the URL can only be queried from specified country(ies). The rule can be reversed to allow all countries except some.
  • Referer: the URL can only be queried if the Referer HTTP header contains a specified value. If the URL contains a Referer header with a different value, the request is refused. If the Referer header is missing, the request is accepted in order to prevent from false positives as some browsers, anti-virus or organization proxies may remove this header.
  • Referer strict: the URL can only be queried if the Referer HTTP header contains a specified value. If the URL contains a Referer header with a different value, the request is refused. If the Referer header is missing, the request is refused.
  • Delegate: this option instructs the signing algorithm that security level information won’t be embedded into the signature but gathered and locked at the first use (see First Access Locking Security Model below)
Name Mask Data
None 0 None
Delegate 1 << 0 None
ASNUM 1 << 1 The number part of the end-user AS prefixed by the ‘AS’ string (ie: as=AS41690)
IP 1 << 2 The end-user quad dotted IP address (ie: ip=195.8.215.138)
User-Agent 1 << 3 The end-user browser user-agent (parameter name is ua)
Use Once 1 << 4 None
Country 1 << 5 A coma seperated list of 2 characters long country codes in lowercase. If the list starts with a dash, the rule is inverted (ie: cc=fr,gb,de or cc=-fr,it). This data has to be stored in the pub-sec-data component
Referer 1 << 6 A space separated list of URL prefixes stored in the pub-sec-data component. (ex: rf=http://domain.com/a/+http:/domain.com/b/).
Referer strict 1 << 15 Same as Referer

Which security level to choose for which usage

In general, the None security level should never be used for video stream URLs. This security level should only be used for public embed video URLs distributed using the Dailymotion Cloud’s player or via a player using the Dailymotion Cloud player component (payload).

The ASNUM security level is recommended for most use-cases as it delivers a good tradeoff between security and compatibility. When the client chooses the ASNUM security level, the Delegate option has to be activated as the client has no secured way to determine the ASNUM of the end-user. If more security is needed, the ASNUM + User-Agent security level should be considered first. The by IP security level is unadvised as it may prevent end-user behind load-balanced transparent proxies from using the service efficiently.

For more complex needs, it is possible to restrict a video or a player to a list of countries. The list of countries is added to the additional data of the signature with the cc key and is a list of 2 characters country codes separated by comas (ex: fr,gb,de). If the list starts with a dash, the whole list is treated as a blacklist instead of a whitelist, i.e.: all the countries are allowed except the listed ones.

Finally, Referer based security level is available for embed player protection (it is meaningless for streams). This level of security isn’t very robust but is very easy to use. It only needs a list of URL prefixes passed in the public security data parameter with the rf parameter name and separated by spaces. If the delegated mode is used, the full URL (with query-string) of the first request will be used to lock the URL.

First Access Locking Security Model

Signed URL can be limited to the end-user’s ASNUM, IP or User-Agent by the client. The client may not have the same view those end-user information as Dailymotion Cloud, especially for ASNUM which is based on a frequently updated database of IP block -> ASNUM correspondances.

To prevent from false positive end-user locking, the client has the choice to not embed those informations in the signature, but only instruct the chosen security level as explained in the previous section “Generate a Signed URL”. It is the first time the Dailymotion Cloud server verify this signature that the security level will be stored and enforced for subsequent requests. This is the reason the signature contains a nonce, to ensure each signature is unique.

Upon the first signed URL request from the end-user with a security level other than “None”, the Dailymotion Cloud servers will store the signature together with the related security parameters of the chosen level when the Delegate security option is present. For instance, if the security level is ASNUM + User-Agent + Delegate, the Dailymotion Cloud server will gather end-user ASNUM and user-agent, and store it associated with the URL signature.

On the subsequent requests, the server will first check if the signature is present in the database, and will ensure the ASNUM and User-Agent information are equal to the current end-user’s. If something has changed, the access is forbidden.

Signing a URL with the API

The different SDK implement their own signing method, so that you can generate urls easily.

Here are the different methods:

  • Java: Helpers.sign_url()
  • PHP: CloudKey_Helpers::sign_url()
  • Python: cloudkey.sign_url()

Examples

Java:

import net.dmcloud.cloudkey.*;
import net.dmcloud.util.*;
import java.util.Date;
public class GetStreamUrl {
    private static String user_id = "";
    private static String api_key = "";
    private static String media_id = "";
    private static String protocol = "http";
    private static String asset_name = "mp4_h264_aac";
    private static String extension = ".mp4";
    private static int seclevel = 0;
    public static void getStreamUrl() {
        int expires = (int)((new Date().getTime() / 1000) + 3600 * 24 * 7);
        // We create the url
        String urlToSign = CloudKey.CDN_URL + "/route/" + protocol + "/" + user_id + "/" + media_id + "/" + asset_name + extension;
        try {
            // We sign the url
            String url = Helpers.sign_url(urlToSign, api_key, seclevel, "", "", "", null, null, expires);
            System.out.println(url);
        } catch(Exception e) {
            System.out.println("failed to get the stream url: " + e.getMessage());
        }
    }
    public static void main() {
        getStreamUrl();
    }
}

Python:

import time
from cloudkey import sign_url
user_id = ''
api_key = ''
media_id = ''
protocol = 'http'
asset_name = 'mp4_h264_aac'
extension = '.mp4'
seclevel = 0
expires = time.time() + 3600 * 24 * 7
# We create the url
url = 'http://cdn.dmcloud.net/route/%s/%s/%s/%s%s' % (protocol, user_id, media_id, asset_name, extension)
# We sign the url
url = sign_url(url, api_key, seclevel=seclevel, expires=expires)
print url

PHP:

require_once 'CloudKey.php';
$user_id = '';
$api_key = '';
$media_id = '';
$protocol = 'http';
$asset_name = 'mp4_h264_aac';
$extension = '.mp4';
$seclevel = 0;
$expires = time() + 3600 * 24 * 7;
// We create the url
$url = sprintf('http://cdn.dmcloud.net/route/%s/%s/%s/%s%s', $protocol, $user_id, $media_id, $asset_name, $extension);
// We sign the url
$url = CloudKey_Helpers::sign_url($url, $api_key, $seclevel, null, null, null, null, null, $expires);
print($url . "\n");

Table Of Contents