Before we continue we need to understand what is Dash Playback?
We already have covered a detailed blog for the “MPEG-DASH: Dynamic Adaptive Streaming Over HTTP Explained” so here we just gonna brush up on the core part of Dash Playback Tech
DASH stand for Dynamic Adaptive Streaming over HTTP, as the name suggests it’s it has the “Dynamic” bit rate and is “adaptive” to Network performance, that is it changes the bit rate according to network to keep the video playing. Higher the video bitrate higher the video quality.
Working of Dash Playback contains majorly three steps
- Segmentation & Encoding
In this step video is divided into many segments of fewer seconds and index file to keep the track of all the segmentation is created, this index file is also known as the manifest file.
Segments are encoded in various encoding and video quality levels for smaller to bigger files size and the manifest file is updated. Dash Support any encoding standards
- Delivery
When the video starts streaming, the device first fetches the index file (manifest file) and then it fetches the proper segment of video one by one from the server using HTTP/HTTPS by accounting for the network performance.
- Decoding and Playback
Device on receiving the segments decoded each segment and provide the data to the player for video playback.
If during the playback the network performance changes then the player also changes the segment request of high/low quality depending on the network performance. This makes the video playback adaptive to network performance.
Is Dash playback secure for video?
Dash playback is not secure by default, it’s just a technology for adaptive media playback, it does not contain any encryption standards to secure your video, what secure the video is the DRM services. If you want to learn more about the DRM we already have a blog for this “What is DRM Technology, its Working & Video Content Protection Types”
Vdocipher provides Dash + Secure Video playback
When dash playback is added with DRM solution it not only provides reliable video playback irrespective of network performance but also the secure video playback.
But here’s a catch you won’t be able to serve all your customer with just Dash cause Dash is not majorly supported by the Apple device. For the apple device, you have another playback technology like Dash called HLS and then you have to choose the DRM service that serves the Apple device,
So we at vdocipher player provide the complete package in Plug and play, which handles all complexity of secure video playback
List Other Dash Player without secure video playback?
- Dash.js
Dash.js is an open-source HTML5 Video player based on MPEG_DASH and built by the own dash industry forum to demonstrate a production-ready framework for Dash Playback.
It is based on the Media Source Extension API by w3c and provides a simple user interface with tons of information to debug the video stream for error.
Sample code for using Dash.js :
<!doctype html> <html> <head> <title>Dash.js Rocks</title> <style> video { width: 640px; height: 360px; } </style> </head> <body> <div> <video data-dashjs-player autoplay src="https://dash.akamaized.net/envivio/EnvivioDash3/manifest.mpd" controls> </video> </div> <script src="yourPathToDash/dash.all.min.js"></script> </body> </html>
- Exoplayer:
Exoplayer video player on application level for android, it is alternative to Android’s MediaPlayer API for providing better features and customization, it has feature like persistent caching and custom rendered.
Android’s MediaPlayer API is fixed to the android version of the device, whereas Exoplayer can be updated via playstore application update
We’ve also written a blog on how to stream videos on iOS using AVPlayer, do check it out to know more about video streaming in iOS.
How to build the Dash player
Dash player functionality is to fetch the manifest file, parse it and play all segments one by one.
It can be processed in 7 steps:
- Get the video element reference
- Create media source
- Create ObjectURL from the media source and add to source of video
- Set the mime type for media source via addSourceBuffer
- Fetch the manifest file and parse and store all required data in variable
- Initialize the video with first segment
- Use event `timeupdate` to continuously update the source with all other segments
// Create media source const videoEl = document.getElementById("my-video"); const mediaSource = new MediaSource(); const sourceUrl = URL.createObjectURL(mediaSource); videoEl.src = sourceUrl; let videoSource; let segCheck; let currentSegmentIndex = 0; let lastTime; // get mainfest file const xmlData = await fetch("MANIFEST_URL_FROM_SERVER") .then((r) => r.text()) .then((xml) => parser.parseFromString(xml, "text/xml", 0)); // extract data from manifest file const file = xmlData.querySelectorAll("BaseURL")[0].textContent.toString(); const rep = xmlData.querySelectorAll("Representation"); const type = rep[0].getAttribute("mimeType"); const codecs = rep[0].getAttribute("codecs"); const width = rep[0].getAttribute("width"); const height = rep[0].getAttribute("height"); const bandwidth = rep[0].getAttribute("bandwidth"); const ini = xmlData.querySelectorAll("Initialization"); const initialization = ini[0].getAttribute("range"); const segments = xmlData.querySelectorAll("SegmentURL"); const segList = xmlData.querySelectorAll("SegmentList"); let segDuration = segList[0].getAttribute("duration"); // wait for media source to ready mediaSource.addEventListener( "sourceopen", function (e) { try { videoSource = mediaSource.addSourceBuffer("video/mp4"); initVideo(initialization, file); } catch (e) { log("Exception calling addSourceBuffer for video", e); return; } }, false ); // init the video with first segment async function initVideo(range, url) { const segmentVideoBuffer = await fetch(url, { header: `Range: "bytes=${range}"`, }); B.appendBuffer(new Uint8Array(segmentVideoBuffer)); videoEl.addEventListener("timeupdate", playSegment); } // play all segment one by one if necessary function playSegment() { if (index < segments.length && videoEl.currentTime - lastTime >= segCheck) { const range = segments[index].getAttribute("mediaRange").toString(); segCheck = (timeToDownload(range) * 0.8).toFixed(3); const segmentVideoBuffer = await fetch(url, { header: `Range: "bytes=${range}"`, }); videoSource.appendBuffer(new Uint8Array(segmentVideoBuffer)); segCheck = (timeToDownload(range) * 0.8).toFixed(3); lastTime = videoElement.currentTime; } } // Helper function timeToDownload(range) { const [start, end] = range.split("-"); return ((end - start) * 8) / bandwidth; }
Supercharge Your Business with Videos
At VdoCipher we maintain the strongest content protection for videos. We also deliver the best viewer experience with brand friendly customisations. We'd love to hear from you, and help boost your video streaming business.
Javascript Developer, open-source enthusiast, keep things simple and sweet.