Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ Do not specify supported browsers and their versions in code comments or prose,

- The "media" directory contains examples and demos showing how to use HTML and DOM [media elements and APIs](https://developer.mozilla.org/docs/Web/Media).

- The "media-source-extensions" directory contains examples demonstrating the [Media Source Extensions API](https://developer.mozilla.org/docs/Web/API/Media_Source_Extensions_API). It includes a [ManagedMediaSource demo](https://mdn.github.io/dom-examples/media-source-extensions/managed-media-source/) showing how to set up a `ManagedMediaSource`, listen for `startstreaming`/`endstreaming` events, and log `bufferedchange` events.

- The "navigation-api" directory contains a basic example that demonstrates some features of the [Navigation API](https://developer.mozilla.org/en-US/docs/Web/API/Navigation_API). [Run the demo live](https://mdn.github.io/dom-examples/navigation-api/).

- The "notifications" directory contains one example showing how to make and handle persistent notifications, and another showing how to make and handle non-persistent notifications, using the [Notifications API](https://developer.mozilla.org/en-US/docs/Web/API/Notifications_API).
Expand Down
5 changes: 5 additions & 0 deletions media-source-extensions/managed-media-source/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# ManagedMediaSource demo

This example demonstrates how to use the [ManagedMediaSource](https://developer.mozilla.org/en-US/docs/Web/API/ManagedMediaSource) interface to set up a managed media source, attach it to a video element, and respond to `startstreaming` and `endstreaming` events to control when media data is fetched. It also listens for `bufferedchange` events on the `ManagedSourceBuffer` and logs the added time ranges.

[See the example live](https://mdn.github.io/dom-examples/media-source-extensions/managed-media-source/).
103 changes: 103 additions & 0 deletions media-source-extensions/managed-media-source/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>ManagedMediaSource demo</title>
<style>
body {
font-family: system-ui, sans-serif;
max-width: 460px;
margin: 1rem auto;
padding: 0 1rem;
}

video {
display: block;
width: 100%;
margin-bottom: 1rem;
background: #000;
}

output {
display: block;
white-space: pre;
height: 6rem;
overflow-y: auto;
border: 1px solid #ccc;
border-radius: 4px;
padding: 0.5rem;
font-family: monospace;
font-size: 0.85rem;
line-height: 1.4;
}

.not-supported {
padding: 1rem;
background: #fff3cd;
border: 1px solid #ffc107;
border-radius: 4px;
}
</style>
</head>
<body>
<h1>ManagedMediaSource demo</h1>
<video controls width="400" height="225"></video>
<output id="log"></output>

<!--
Used in:
- https://developer.mozilla.org/en-US/docs/Web/API/ManagedMediaSource
-->

<script>
const output = document.querySelector("#log");
function log(msg) {
output.textContent += msg + "\n";
output.scrollTop = output.scrollHeight;
}

const videoUrl =
"https://mdn.github.io/shared-assets/videos/flower-fragmented.mp4";
const mediaType = 'video/mp4; codecs="avc1.64001F, mp4a.40.2"';
const video = document.querySelector("video");

if (!window.ManagedMediaSource?.isTypeSupported(mediaType)) {
log("ManagedMediaSource is not supported in this browser.");
document.querySelector("video").style.display = "none";
output.classList.add("not-supported");
} else {
const source = new ManagedMediaSource();
video.disableRemotePlayback = true;
video.src = URL.createObjectURL(source);

video.addEventListener("canplay", () =>
log("canplay — video is ready"),
);

source.addEventListener("sourceopen", () => {
const sourceBuffer = source.addSourceBuffer(mediaType);

sourceBuffer.addEventListener("bufferedchange", (event) => {
for (let i = 0; i < event.addedRanges.length; i++) {
log(
`Buffered: ${event.addedRanges.start(i).toFixed(2)}s – ${event.addedRanges.end(i).toFixed(2)}s`,
);
}
});

source.addEventListener("startstreaming", async () => {
log("startstreaming — fetching media data…");
const response = await fetch(videoUrl);
const data = await response.arrayBuffer();
sourceBuffer.appendBuffer(data);
});

source.addEventListener("endstreaming", () => {
log("endstreaming — enough data buffered");
});
});
}
</script>
</body>
</html>