Last active
November 10, 2023 04:30
-
-
Save andremichelle/91b4180c10a4f86928fb32fab6b34687 to your computer and use it in GitHub Desktop.
This code enables efficient looping of WebM videos by streaming and caching them in memory. It prevents the browser from repeatedly streaming the video when the loop property triggers a restart, ensuring a smooth and resource-friendly playback experience.
This file contains 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
// Tested on all major browsers (Macbook Pro), Fails on IOS (https://caniuse.com/?search=MediaSource) | |
export const streamAndCacheMediaSource = (videoElement: HTMLVideoElement, url: string): void => { | |
const MimeCodec = "video/webm; codecs=\"vp9\"" | |
if (!MediaSource.isTypeSupported(MimeCodec)) {throw new Error(`${MimeCodec} is not supported`)} | |
const mediaSource = new MediaSource() | |
mediaSource.addEventListener("sourceopen", async () => { | |
if (mediaSource.readyState !== "open") {throw new Error("readyState not open")} | |
const sourceBuffer = mediaSource.addSourceBuffer(MimeCodec) | |
sourceBuffer.mode = "sequence" | |
sourceBuffer.addEventListener("error", () => {throw new Error("Unknown error. Check 'chrome://media-internals/'")}) | |
fetch(url).then(async (response: Response) => { | |
const reader = response.body!.getReader() | |
while (true) { | |
const result = await reader.read() | |
if (result.done) { | |
mediaSource.endOfStream() | |
break | |
} else { | |
await new Promise<void>((resolve) => { | |
sourceBuffer.appendBuffer(result.value) | |
sourceBuffer.addEventListener("update", () => resolve(), { once: true }) | |
}) | |
} | |
} | |
}) | |
}) | |
videoElement.src = URL.createObjectURL(mediaSource) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment