Index

hasplayer.js

hasplayer.js is a javascript implementation of a video player based on the W3C premium extensions, i.e. MSE and EME.

hasplayer.js is an extension of the dash.js project with the aim of supporting additional http adaptive streaming protocols such as Microsoft Smooth Streaming protocol and Apple Http Live Streaming.

If your intent is to use the player code without contributing back to this project, then use the MASTER branch which holds the approved and stable public releases.

If your goal is to improve or extend the code and contribute back to this project, then you should make your changes in, and submit a pull request against, the DEVELOPMENT branch.

Getting Started

Create a video element somewhere in your html. For our purposes, make sure to set the controls property to true.

<video id="videoPlayer" controls="true"></video>

Add hasplayer.js to the end of the body.

<body>
  ...
  <script src="yourPathToHasplayer/hasplayer.js"></script>
</body>

Now comes the good stuff. We need to create an MediaPlayer. Then we need to initialize it, attach it to our "videoPlayer" and then tell it where to get the video from. We will do this in an anonymous self executing function, that way it will run as soon as the page loads. So, here is how we do it:

(function(){
    var stream = {
        url: "http://playready.directtaps.net/smoothstreaming/SSWSS720H264/SuperSpeedway_720.ism/Manifest"
    };
    var mediaPlayer = new MediaPlayer();
    MediaPlayer.init(document.querySelector("#videoPlayer"));
    MediaPlayer.load(stream);
})();

When it is all done, it should look similar to this:

<!doctype html>
<html>
    <head>
        <title>hasplayer.js Rocks</title>
    </head>
    <body>
        <div>
            <video id="videoPlayer" controls="true"></video>
        </div>
        <script src="yourPathToHasplayer/hasplayer.js"></script>
        <script>
            (function(){
                var stream = {
                    url: "http://playready.directtaps.net/smoothstreaming/SSWSS720H264/SuperSpeedway_720.ism/Manifest"
                };
                var mediaPlayer = new MediaPlayer();
                mediaPlayer.init(document.querySelector("#videoPlayer"));
                mediaPlayer.load(stream);
            })();
        </script>
    </body>
</html>

DRM Video Stream

In the case of protected content, here is an example illustrating setting of the protection data:

<!doctype html>
<html>
    <head>
        <title>Hasplayer.js Rocks</title>
    </head>
    <body>
        <div>
            <video id="videoPlayer" controls="true"></video>
        </div>
        <script src="yourPathToHasplayer/hasplayer.js"></script>
        <script>
            (function(){
                var stream = {
                    url: "http://playready.directtaps.net/smoothstreaming/SSWSS720H264/SuperSpeedway_720.ism/Manifest",
                    protData: {
                        com.microsoft.playready: {
                            laURL: "http://roap.purplecast.us/test/services/StandardPlayReadyAquireLicenseByContent.cfm?distrib=olps",
                            customData: "B2C99B73-CA41-4003-84A3AA16CE92B304"
                        }
                    }
                };
                var mediaPlayer = new MediaPlayer();
                mediaPlayer.init(document.querySelector("#videoPlayer"));
                mediaPlayer.load(stream);
            })();
        </script>
    </body>
</html>

Events

MediaPlayer offers events to be notified of differents events on video streaming. Those events are, for a part, sent by the HTML5 video element, and for an other part, sent by hasPlayer.js.

function registerMediaPlayerEvents() {
    // MediaPlayer events
    mediaPlayer.addEventListener("error", onError);
    mediaPlayer.addEventListener("warning", onWarning);
    mediaPlayer.addEventListener("cueEnter", onCueEnter);
    mediaPlayer.addEventListener("cueExit", onCueExit);
    mediaPlayer.addEventListener("play_bitrate", onPlayBitrateChanged);
    mediaPlayer.addEventListener("download_bitrate", onDownloadBitrateChanged);
    mediaPlayer.addEventListener("manifestUrlUpdate", onManifestUrlUpdate);
    mediaPlayer.addEventListener("metricAdded", onMetricAdded);
    mediaPlayer.addEventListener("metricChanged", onMetricChanged);
    mediaPlayer.addEventListener("bufferLevel_updated", onBufferLevelUpdated);
    mediaPlayer.addEventListener("state_changed", onStateChanged);
    // <video> element events
    mediaPlayer.addEventListener("loadeddata", onload);
    mediaPlayer.addEventListener("play", onPlay);
    mediaPlayer.addEventListener("pause", onPause);
    mediaPlayer.addEventListener("timeupdate", onTimeUpdate);
    mediaPlayer.addEventListener("volumechange", onVolumeChange);
};

For instance, callback function looks like this :

function onPlayBitrateChanged(e) {
    handlePlayBitrate(e.detail.bitrate, e.detail.time);
};

Errors

The following table provides the list of the errors and warnings that can be notified by the MediaPlayer (see MediaPlayer's addEventListener() function).

Category Event type Code Message Description Callback 'event' parameter format Comment
HTML5_VIDEO ERROR MEDIA_ERR_ABORTED <video> error: fetching process aborted The fetching process for the media resource was aborted by the user agent at the user's request {
code: <code>,
message: <message>
}

HTML5_VIDEO ERROR MEDIA_ERR_NETWORK <video> error: network error A network error caused the user agent to stop fetching the media resource {
code: <code>,
message: <message>
}

HTML5_VIDEO ERROR MEDIA_ERR_DECODE <video> error: media decoding error An error of some description occurred while decoding the media {
code: <code>,
message: <message>
}

HTML5_VIDEO ERROR MEDIA_ERR_SRC_NOT_SUPPORTED <video> error: media format not supported The media resource indicated by the src attribute was not suitable {
code: <code>,
message: <message>
}

HTML5_VIDEO ERROR MEDIA_ERR_ENCRYPTED <video> error: media is encrypted
or
Media is encrypted and no key is available
The media is encrypted and no valid key is available to decrypt the media {
code: <code>,
message: <message>
}

MSE ERROR CAPABILITY_ERR_MEDIASOURCE MediaSource extension not supported by the browser The MediaSource API is not available in the browser {
code: <code>,
message: <message>
}

MSE ERROR MEDIA_ERR_CODEC_CREATE_MEDIASOURCE Failed to create MediaSource An error occurred while creatingthe MediaSource object, due to system error {
code: <code>,
message: <message>,
data: {
name: <error name>,
message: <error message>
}

MSE ERROR
WARNING
MEDIA_ERR_CODEC_UNSUPPORTED (Video/Audio/Text) Codec is not supported The codec is unsupported neither by the HTMLMediaElement nor the MSE MediaSource, or the codec is unsupported by the MediaPlayer.
ERROR for audio/video tracks.
WARNING for text tracks.
{
code: <code>,
message: <message>,
data: {
codec: <codec>
}
}
# Event type:
- ERROR for video and audio tracks
- WARNING for text tracks
MSE ERROR
WARNING
MEDIA_ERR_CREATE_SOURCEBUFFER Failed to create audio/video/text source buffer Failed to add a source buffer the media source, the provided MIME type is not supported.
ERROR for audio/video tracks.
WARNING for text tracks.
{
code: <code>,
message: <message>,
data: {
code: <DOMException code>,
name: <DOMException name>,
message: <DOMException message>
}
}
# Event type:
- ERROR for video and audio tracks
- WARNING for text tracks

# Possible DOMException:
- InvalidAccessError: MediaSource not available or not ready, or invalid input MIME type
- QuotaExceededError: no more SourceBuffer can be created or unsupported configuration of SourceBuffers
MSE ERROR MEDIA_ERR_APPEND_SOURCEBUFFER Failed to append data into audio/video/text source buffer Failed to append data into source buffer {
code: <code>,
message: <message>,
data: {
code: <DOMException code>,
name: <DOMException name>,
message: <DOMException message>
}
}
# Possible DOMException:
- InvalidStateError: appending is performed while source buffer is still processing some operation
- QuotaExceededError: no more data can be appended (browser memory limitation)
MSE WARNING MEDIA_ERR_REMOVE_SOURCEBUFFER Failed to remove data from audio/video source buffer Failed to remove data from source buffer {
code: <code>,
message: <message>,
data: {
code: <DOMException code>,
name: <DOMException name>,
message: <DOMException message>
}
}
# Possible DOMException:
- InvalidStateError: removing is performed while source buffer is still processing some operation
MEDIA_PLAYER ERROR
WARNING
DOWNLOAD_ERR_MANIFEST Failed to download manifest Failed to download manifest file {
code: <code>,
message: <message>,
data: {
url: <URL of the manifest>,
status: <HTTP status code>
}
}
# Event type:
- ERROR when failed to download main manifest file
- WARNING when failed to refresh manifest (MSS language switch, HLS manifest update, …)
MEDIA_PLAYER ERROR MANIFEST_ERR_PARSE Failed to parse manifest An XML parsing error occurred while parsing the manifest. {
code: <code>,
message: <message>,
data: {
url: <URL of the manifest>
}
}

MEDIA_PLAYER ERROR MANIFEST_ERR_NO_STREAM No stream/period is provided in the manifest The manifest contains no stream/period description {
code: <code>,
message: <message>
}{
code: <code>,
message: <message>
}
# Applies only for MPEG DASH streams
MEDIA_PLAYER ERROR MANIFEST_ERR_NO_VIDEO No video data in manifest No video track is provided in the manifest {
code: <code>,
message: <message>
}{
code: <code>,
message: <message>
}

MEDIA_PLAYER WARNING MANIFEST_ERR_NO_AUDIO No audio data in manifest No audio track is provided in the manifest {
code: <code>,
message: <message>
}{
code: <code>,
message: <message>
}

MEDIA_PLAYER ERROR
WARNING
DOWNLOAD_ERR_CONTENT Failed to download media segment Failed to download a media segment file {
code: <code>,
message: <message>,
data: {
url: <URL of the segment>,
status: <HTTP status code>
}
}
# When a segment download fails, a warning is raised

# Afterwards, when the buffer becomes underflow, the session si reloaded

# Then, when a third segment download fails, an error is raised

# For text tracks only warnings are raised
EME ERROR CAPABILITY_ERR_MEDIAKEYS EME not supported/enabled Content is signalized protected but EME is not supported/enabled {
code: <code>
message: <message>
}

EME ERROR MEDIA_KEYSYSERR_ACCESS_DENIED No KeySystem/CDM available
{
code: <code>,
message: <message>,
data: {
keySystems: [{
schemeIdUri: <KS scheme id uri>,
systemString: <KS name>
}]
}
}
# 'data.ks' contains array of signalized Key Systems

# Applies on Chrome if EME is disabled (see chrome://flags)
EME ERROR MEDIA_KEYMESSERR_NO_SESSION Failed to create MediaKeys session Failed to create a MediaKey session or to load an existing MediaKey session {
code: <code>,
message: <message>,
data: {
reason: <reason>,
error: {
code: <error code>,
name: <error name>,
message: <error message>
}
}
}

EME ERROR MEDIA_KEYMESSERR_LICENSER_UNKNOWN No licenser URL specified No licenser URL is specified:
- neither in input stream's protection data information
- nor in content's DRM initialization Data

EME ERROR MEDIA_KEYMESSERR_NO_CHALLENGE No licenser challenge from CDM key message The challenge returned by the CDM is not valid according to the Key System {
code: <code>,
message: <message>
}

EME ERROR MEDIA_KEYMESSERR_LICENSER_ERROR License request failed License request failed. The http request failed or the licenser server returned an error. {
code: <code>,
message: <message>,
data: {
url: <URL of the licenser>,
status: <HTTP status code>,
error: {
code: <licenser error code>,
name: <licenser error name>,
message: <licenser error message>
}
}

EME ERROR MEDIA_KEYERR Error while providing license to the CDM
{
code: <code>,
message: <message>,
code: <DOMException code>,
name: <DOMException name>,
message: <DOMException message>
}
# Applies only for Chrome
EME ERROR MEDIA_KEYERR_UNKNOWN An unspecified error occurred. This value is used for errors that don't match any of the following codes
{
code: <code>,
message: <message>
}
# Applies only for IE11 and Edge
EME ERROR MEDIA_KEYERR_CLIENT The Key System could not be installed or updated
{
code: <code>,
message: <message>
}
# Applies only for IE11 and Edge
EME ERROR MEDIA_KEYERR_SERVICE The message passed into addKey indicated an error from the license service
{
code: <code>,
message: <message>
}
# Applies only for IE11 and Edge
EME ERROR MEDIA_KEYERR_OUTPUT There is no available output device with the required characteristics for the content protection system
{
code: <code>,
message: <message>
}
# Applies only for IE11 and Edge
EME ERROR MEDIA_KEYERR_HARDWARECHANGE A hardware configuration change caused a content protection error
{
code: <code>,
message: <message>
}
# Applies only for IE11 and Edge
EME ERROR MEDIA_KEYERR_DOMAIN An error occurred in a multi-device domain licensing configuration. The most common error is a failure to join the domain
{
code: <code>,
message: <message>
}
# Applies only for IE11 and Edge