Querying mediatype support

Not every mediatype is supported everywhere, so we need to detect what the playback system can do and adapt to it.

This lesson introduces you to API calls by which you can query whether a user agent and platform support the mediatypes we are about to play back. We will query the machine whether it can play Dolby AC-4, Dolby Digital Plus, and MPEG AAC.

mediatype signaling

To query the user agent for mediatype support, you need to tell it which mediatype you mean. All query methods below require that you identify the mediatype through a string called MIME type.

MIME types are more properly defined in RFC 2046, but for the purposes of this tutorial suffice it to say that the MIME type jointly identifies the container in which the media travels, as well as the format itself (the distinction being somewhat arbitrary). For all intents and purposes, the container format relevant to this tutorial is the ISO base media file format (ISO/IEC 14496-12), identified by either video/mp4 or audio/mp4, followed by a codecs string specific to the format. A typical MIME type would thus be audio/mp4; codecs=ec-3, meaning Dolby Digital Plus in an ISOBMFF container.

Note: ETSI TS 102 366 clause J.1.2, ETSI TS 103 190-1 clause F.1.2.1, and ETSI TS 103 190-2 clause E.13 provide details on MIME types of Dolby Audio.

Implementing fallback in media frameworks will teach you how to derive the MIME type from your assets.

W3C APIs for media support queries

User agents have three different methods to query mediatype support, in varying degrees of sophistication. Which one to use will depend on the choice of playback mechanism (using the HTML5 native media player vs. using the Media Source Extension API) which, in turn, depends on whether a given user agent supports the mechanism.

HTMLMediaElement: canPlayType()

The HTMLMediaElement canPlayType() method checks if the browser can play the specified mediatype. As input, this method takes one parameter containing above mentioned mediatype string.

function canPlay(mediatype) {
    return document.createElement('video').canPlayType(mediatype);
}         

The return value will be one of the following values:

"probably"
the browser most likely supports this mediatype
"maybe"
the browser might support this mediatype
"" (the empty string)
the browser does not support this mediatype

MediaSourceExtention: isTypeSupported()

The MediaSource.isTypeSupported() API static method returns a boolean value which is true if the given mimeType and (optional) codec are likely to be supported by your machine.

That is, if it can successfully create SourceBuffer objects for that mediatype. If the returned value is false, then your machine is certain that it cannot access media of the specified format.

function Mse(mediatype) {
    var result = null;
    if ('MediaSource' in window) {
        result = MediaSource.isTypeSupported(mediatype);
    }
    return result;
}
  1. Not all browsers support the Media Source Extensions, so it is important we check first.
  2. isTypeSupported is a synchronous call. This means that the answer will not be determined dynamically but is hard coded into the browser.

MediaCapabilitiesApi: decodingInfo()

As if two methods weren't enough, W3C has decided to standardize a third way to query for mediatype support. This third method comes with a few goodies, some of which will become important in Checking for immersive audio capability.

The MediaCapabilitiesApi in itself provides multiple methods. For our purposes, we use the decodingInfo() method to query for audio playback capabilities. In addition to the mediatype contained in the contentType-string, this method can take some more parameters as input via its configuration structure.

The MediaCapabilities.decodingInfo() method returns a promise with the tested media configuration's capabilities info. The info contains the three boolean properties supported, smooth, and powerefficient; for audio playback, testing for supported is sufficient.

async function Mca(mediatype) {
    var results = null;
    var mediaConfig = {
        type: 'media-source',
        audio: {
            contentType: mediatype,
            spatialRendering: false,
            channels: 2
        }
    }
                
    if ("mediaCapabilities" in navigator) {
        results = await navigator.mediaCapabilities.decodingInfo(mediaConfig);
    }
                
    return results;
}

Running the application, you should see a table indicating the responses of all methods from the respective mediatype strings. The responses will indicate the mediatype support of your specific setup.