0

I am complete new in Adaptive streaming over HTTP . I have little bit experience in HTML and JavaScript . Initially I have read lot of documents for DASH and Adaptive streaming over HTTP . I have understood lot of new things . Now i want to create my custom video player for adaptive streaming in HTML 5 . I have gonethrough some of the following documents . My findings are

  • Media Source Extensions (MSE) is a JavaScript API that lets you build streams for playback from segments of audio or video .
  • We can use MSE related APIs in javascript for the implementation of adaptive streaming in HTML 5.
  • Dash.js library an open-source MPEG-DASH player implemented entirely in JavaScript .

I have gone through

Now my aim is to create custom DASH client player with following features

  • Create a Media player on any browser
  • Parsing MPD file
  • Decode audio/video data
  • Segment parsing
  • Add content to the video player

Now my understanding is Dash.js is doing all the above steps with JavaScript . Isn't ? Now My doubts are

  1. Is Dash.js is creating media player with MSE API's ?
  2. Can i adaptive stream over HTTP with out MSE ?
  3. If not , How can i work this on old browsers ? (Non-MSE compliance browser)

Finally how can i write a custom video player for adaptive streaming with out any libraries ? Can you Please suggest Any useful links or tutorials ?

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
user2986042
  • 1,098
  • 2
  • 16
  • 37
  • See [How to use Blob URL, MediaSource or other methods to play concatenated Blobs of media fragments?](https://stackoverflow.com/questions/45217962/), [How to use “segments” mode at SourceBuffer of MediaSource to render same result at Chomium, Chorme and Firefox?](https://stackoverflow.com/questions/46379009/how-to-use-segments-mode-at-sourcebuffer-of-mediasource-to-render-same-result), [How to Enable audio track change in – guest271314 Jan 12 '18 at 07:37
  • 1
    1, yes. 2, no. 3, plug-ins like flash or silver light. – szatmary Jan 12 '18 at 16:05

1 Answers1

0

I have added sample MSE project here: https://github.com/thowfeeq178/MediaSourceExtention

checkout the example in the github or below:

// BBB : https://dash.akamaized.net/akamai/bbb_30fps/bbb_30fps.mpd

var baseUrl = "https://dash.akamaized.net/akamai/bbb_30fps/";
var initUrl = baseUrl + "bbb_30fps_480x270_600k/bbb_30fps_480x270_600k_0.m4v";

var initAudioUrl = baseUrl + "bbb_a64k/bbb_a64k_0.m4a";

var templateUrl =
  baseUrl + "bbb_30fps_480x270_600k/bbb_30fps_480x270_600k_$Number$.m4v";
var templateUrlForAudio = baseUrl + "bbb_a64k/bbb_a64k_$Number$.m4a";
var sourceBuffer;
var audioSourceBuffer;
var index = 0;
var audioIndex = 0;
var numberOfChunks = 159;
var video = document.querySelector("video");
var ms = new MediaSource();

function onPageLoad() {
  console.log("page loaded ..");
  if (!window.MediaSource) {
    console.error("No Media Source API available");
    return;
  }
  // making source controlled by JS using MS
  video.src = window.URL.createObjectURL(ms);
  ms.addEventListener("sourceopen", onMediaSourceOpen);
}

function onMediaSourceOpen() {
  // create source buffer
  sourceBuffer = ms.addSourceBuffer('video/mp4; codecs="avc1.4d401f"');
  audioSourceBuffer = ms.addSourceBuffer('audio/mp4; codecs="mp4a.40.5"');
  // when ever one segment is loaded go for next
  sourceBuffer.addEventListener("updateend", nextSegment);
  audioSourceBuffer.addEventListener("updateend", nextAudioSegment);
  // fire init segemnts
  GET(initUrl, appendToBuffer);
  GET(initAudioUrl, appendToAudioBuffer);

  // play
  video.play();
}

// get next segment based on index and append, once everything loaded unlisten to the event
function nextSegment() {
  var url = templateUrl.replace("$Number$", index);
  GET(url, appendToBuffer);
  index++;
  if (index > numberOfChunks) {
    sourceBuffer.removeEventListener("updateend", nextSegment);
  }
}

// get next audio segment based on index and append, once everything loaded unlisten to the event
function nextAudioSegment() {
  var audioUrl = templateUrlForAudio.replace("$Number$", audioIndex);
  GET(audioUrl, appendToAudioBuffer);
  audioIndex++;
  if (index > numberOfChunks) {
    audioSourceBuffer.removeEventListener("updateend", nextAudioSegment);
  }
}

// add to existing source
function appendToBuffer(videoChunk) {
  if (videoChunk) {
    sourceBuffer.appendBuffer(new Uint8Array(videoChunk));
  }
}

function appendToAudioBuffer(audioChunk) {
  if (audioChunk) {
    audioSourceBuffer.appendBuffer(new Uint8Array(audioChunk));
  }
}

// just network thing
function GET(url, callback) {
  var xhr = new XMLHttpRequest();
  xhr.open("GET", url);
  xhr.responseType = "arraybuffer";

  xhr.onload = function(e) {
    if (xhr.status != 200) {
      console.warn("Unexpected status code " + xhr.status + " for " + url);
      return false;
    }
    callback(xhr.response);
  };

  xhr.send();
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <title>MSE Demo</title>
</head>

<body onload="onPageLoad()">
  <h1>MSE Demo</h1>
  <div>
    <video muted controls width="80%"></video>
  </div>

</body>

</html>
thowfeeq
  • 233
  • 2
  • 8