Created
August 3, 2018 15:23
-
-
Save peaBerberian/2cada8ee1559965ebe62d5792148db60 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const INIT_AUDIO_URL = "https://bitmovin-a.akamaihd.net/content/sintel/audio/stereo/en/128kbit/init.mp4"; | |
| const INIT_VIDEO_URL = "https://bitmovin-a.akamaihd.net/content/sintel/video/500kbit/init.mp4"; | |
| const VIDEO_SEGMENTS = [ | |
| "https://bitmovin-a.akamaihd.net/content/sintel/video/500kbit/segment_1.m4s", | |
| ]; | |
| const AUDIO_SEGMENTS = [ | |
| "https://bitmovin-a.akamaihd.net/content/sintel/audio/stereo/en/128kbit/segment_1.m4s", | |
| ]; | |
| const VIDEO_CODEC = "video/mp4; codecs=\"avc1.42E01E\""; | |
| const AUDIO_CODEC = "audio/mp4; codecs=\"mp4a.40.2\""; | |
| const videoElement = document.getElementsByTagName("video")[0]; | |
| function startStream() { | |
| const mediaSource = new MediaSource(); | |
| videoElement.src = URL.createObjectURL(mediaSource); | |
| mediaSource.addEventListener("sourceopen", onSourceOpen); | |
| } | |
| function onSourceOpen() { | |
| const mediaSource = this; | |
| const audioSourceBuffer = mediaSource.addSourceBuffer(AUDIO_CODEC); | |
| const videoSourceBuffer = mediaSource.addSourceBuffer(VIDEO_CODEC); | |
| let audioSegmentStep = 0; | |
| let videoSegmentStep = 0; | |
| videoSourceBuffer.addEventListener("update", function() { | |
| if (videoSegmentStep >= VIDEO_SEGMENTS.length) { | |
| return; | |
| } | |
| const newVideoSegmentURL = VIDEO_SEGMENTS[videoSegmentStep++]; | |
| if (!newVideoSegmentURL) { | |
| return; | |
| } | |
| fetchAndPushSegment(newVideoSegmentURL, videoSourceBuffer); | |
| }); | |
| audioSourceBuffer.addEventListener("update", function() { | |
| if (audioSegmentStep >= AUDIO_SEGMENTS.length) { | |
| return; | |
| } | |
| const newVideoSegmentURL = AUDIO_SEGMENTS[audioSegmentStep++]; | |
| if (!newVideoSegmentURL) { | |
| return; | |
| } | |
| fetchAndPushSegment(newVideoSegmentURL, audioSourceBuffer); | |
| }); | |
| Promise.all([ | |
| getURL(INIT_AUDIO_URL), | |
| getURL(INIT_VIDEO_URL), | |
| ]).then(([audioInitSegment, videoInitSegment]) => { | |
| videoSourceBuffer.appendBuffer(videoInitSegment); | |
| audioSourceBuffer.appendBuffer(audioInitSegment); | |
| }); | |
| } | |
| /** | |
| * @param {string} url | |
| * @param {SourceBuffer} sourceBuffer | |
| */ | |
| function fetchAndPushSegment(url, sourceBuffer) { | |
| getURL(url).then(arrayBuffer => { | |
| sourceBuffer.appendBuffer(arrayBuffer); | |
| }); | |
| } | |
| /** | |
| * @param {string} url | |
| * @returns {Promise.<ArrayBuffer>} | |
| */ | |
| function getURL(url) { | |
| return new Promise((resolve, reject) => { | |
| const xhr = new XMLHttpRequest; | |
| xhr.open("get", url); | |
| xhr.responseType = "arraybuffer"; | |
| xhr.onerror = function(err) { | |
| reject(err); | |
| }; | |
| xhr.onload = function () { | |
| if (xhr.readyState === 4) { | |
| if (xhr.status >= 200 && xhr.status < 300) { | |
| resolve(xhr.response); | |
| } else { | |
| reject(new Error("XHR status:" + xhr.status)); | |
| } | |
| } | |
| }; | |
| xhr.send(); | |
| }); | |
| } | |
| window.startStream = startStream; |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Some minimal MSE implementation to debug basic segment issues on various browsers:
startStream()This script will then download all segments and push them in order (first initialisation segments then the video and audio segments in parallel, one by one).