Skip to content

Instantly share code, notes, and snippets.

@alpgul
Created May 26, 2024 15:28
Show Gist options
  • Save alpgul/1a19c5db2a1020e5dc5023826b617535 to your computer and use it in GitHub Desktop.
Save alpgul/1a19c5db2a1020e5dc5023826b617535 to your computer and use it in GitHub Desktop.
MediaSource Demo
<!DOCTYPE html>
<html>
<head>
<title>MediaSource Demo</title>
</head>
<body>
<script>
const video = document.createElement("video");
document.body.append(video);
video.autoplay = true;
video.controls = true;
async function loadMediaSourceChunks(
url,
downloadChunkSize,
downloadTimeout
) {
try {
const mediaSource = new MediaSource();
const blob = URL.createObjectURL(mediaSource);
video.src = blob;
mediaSource.addEventListener(
"sourceopen",
() => {
URL.revokeObjectURL(video.src);
fetchChunk(mediaSource, url, downloadChunkSize, downloadTimeout);
},
{ once: true }
);
} catch (error) {
console.error("Error:", error);
}
}
async function fetchChunk(mediaSource, url, chunkSize) {
let start = 0;
let response = await fetch(url, {
headers: { Range: `bytes=${start}-${start + chunkSize - 1}` },
});
let length = parseInt(response.headers.get("Content-Length"));
let [range, size] = (response.headers.get("Content-Range") || "")
.replace(/bytes\s*/, "")
.split("/");
let cursor = parseInt(range.split("-").pop());
let sourceBuffer = mediaSource.addSourceBuffer(
response.headers.get("Content-Type") +
'; codecs="avc1.42E01E, mp4a.40.2"'
);
let end = size ? parseInt(size) : length;
start = cursor ? cursor + 1 : start + length + 1;
arrayBuffer = await response.arrayBuffer();
sourceBuffer.addEventListener(
"updateend",
() => {
if (
start >= end - 1 &&
!sourceBuffer.updating &&
mediaSource.readyState === "open"
) {
mediaSource.endOfStream();
}
video.play();
},
{ once: true }
);
sourceBuffer.appendBuffer(arrayBuffer);
while (start < end) {
response = await fetch(url, {
headers: { Range: `bytes=${start}-${start + chunkSize - 1}` },
});
let length = parseInt(response.headers.get("Content-Length"));
let [range, size] = (response.headers.get("Content-Range") || "")
.replace(/bytes\s*/, "")
.split("/");
let cursor = parseInt(range.split("-").pop());
start = cursor ? cursor + 1 : start + length + 1;
arrayBuffer = await response.arrayBuffer();
sourceBuffer = mediaSource.sourceBuffers[0];
sourceBuffer.addEventListener(
"updateend",
() => {
if (
start >= end - 1 &&
!sourceBuffer.updating &&
mediaSource.readyState === "open"
) {
mediaSource.endOfStream();
}
},
{ once: true }
);
sourceBuffer.appendBuffer(arrayBuffer);
}
}
loadMediaSourceChunks("./video.mp4", 100000);//https://github.com/mdn/dom-examples/blob/main/sourcebuffer/frag_bunny.mp4
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment