diff --git a/media-source-respec.html b/media-source-respec.html index 147020c..2d8ba93 100644 --- a/media-source-respec.html +++ b/media-source-respec.html @@ -78,7 +78,7 @@ -
+On top of editorial updates, substantives changes since publication as a W3C Recommendation in November 2016 are the addition of a {{SourceBuffer/changeType()}} method to switch codecs, the possibility to create and use {{MediaSource}} objects off the main thread in dedicated workers, and the removal of the createObjectURL()
extension to the {{URL}} object following its integration in the File API [[FILEAPI]]. For a full list of changes done since the previous version, see the commits.
On top of editorial updates, substantives changes since publication as a W3C Recommendation in November 2016 are the addition of a {{SourceBuffer/changeType()}} method to switch codecs, the possibility to create and use {{MediaSource}} objects off the main thread in dedicated workers, the removal of the createObjectURL()
extension to the {{URL}} object following its integration in the File API [[FILEAPI]], and the addition of {{ManagedMediaSource}}, ManagedSourceBuffer}}, and {{BufferedChangeEvent}} interfaces supporting power-efficient streaming and active buffered media cleanup by the user agent. For a full list of changes done since the previous version, see the commits.
The working group maintains a list of all bug reports that the editors have not yet tried to address.
Implementors should be aware that this specification is not stable. Implementors who are not taking part in the discussions are likely to find the specification changing out from under them in incompatible ways. Vendors interested in implementing this specification before it eventually reaches the Candidate Recommendation stage should track the GitHub repository and take part in the discussions.
+On top of editorial updates, substantives changes since publication as a W3C Recommendation in
+ November 2016 are the addition of a {{SourceBuffer/changeType()}} method to switch codecs, the possibility to create and use {{MediaSource}} objects off the main thread in dedicated workers, the removal of the createObjectURL()
extension to the {{URL}} object following its integration in the File API [[FILEAPI]], and the addition of {{ManagedMediaSource}}, ManagedSourceBuffer}}, and {{BufferedChangeEvent}} interfaces supporting power-efficient streaming and active buffered media cleanup by the user agent. For a full list of changes done since the previous version, see the commits.
enum ReadyState { "closed", @@ -268,7 +270,6 @@MediaSource Object
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
|type| | {{DOMString}} | ✘ | ✘ |
removeSourceBuffer
Removes a {{SourceBuffer}} from {{MediaSource/sourceBuffers}}.
@@ -898,6 +892,7 @@+ A {{ManagedMediaSource}} is a {{MediaSource}} that actively manages its + memory content. Unlike a {{MediaSource}}, the [=user agent=] can evict content + through the [=ManagedMediaSource/memory + cleanup=] algorithm from its {{MediaSource/sourceBuffers}} (populated with {{ManagedSourceBuffer}}) + for any reason. +
+ ++ [Exposed=(Window,DedicatedWorker)] + interface ManagedMediaSource : MediaSource { + constructor(); + readonly attribute boolean streaming; + attribute EventHandler onstartstreaming; + attribute EventHandler onendstreaming; + }; ++ +
On getting:
+Event name | +Interface | +Dispatched when... | +
---|---|---|
+ startstreaming + | +{{Event}} | ++ A {{ManagedMediaSource}}'s {{ManagedMediaSource/streaming}} attribute changed from `false` to `true`. + | +
+ endstreaming + | +{{Event}} | ++ A {{ManagedMediaSource}}'s {{ManagedMediaSource/streaming}} attribute changed from `true` to `false`. + | +
+ The following steps are run periodically, whenever the [=MediaSource/SourceBuffer Monitoring=] algorithm is scheduled to run. +
++ Having enough managed data to ensure uninterrupted playback + is an implementation defined condition where the user agent determines that + it currently has enough data to play the presentation without stalling for a + meaningful period of time. This condition is constantly evaluated to determine + when to transition the value of {{ManagedMediaSource/streaming}}. These transitions + indicate when the user agent believes it has enough data buffered or it + needs more data respectively. +
++ Being able to retrieve and buffer data in an efficient way + is an implementation defined condition where the user agent determines that + it can fetch new data in an energy efficient manner while able to achieve the desired memory usage. +
++ [Exposed=(Window,DedicatedWorker)] + interface BufferedChangeEvent : Event { + constructor(DOMString type, BufferedChangeEventInit eventInitDict); + + [SameObject] readonly attribute TimeRanges addedRanges; + [SameObject] readonly attribute TimeRanges removedRanges; + }; + + dictionary BufferedChangeEventInit : EventInit { + TimeRanges addedRanges; + TimeRanges removedRanges; + }; ++
+ [Exposed=(Window,DedicatedWorker)] + interface ManagedSourceBuffer : SourceBuffer { + attribute EventHandler onbufferedchange; + }; ++
An [=event handler IDL attribute=] whose [=event handler event type=] is {{bufferedchange}}.
+Event name | +Interface | +Dispatched when... | +
---|---|---|
+ bufferedchange + | +{{Event}} | ++ The {{ManagedSourceBuffer}}'s buffered range changed following a + call to {{SourceBuffer/appendBuffer()}}, {{SourceBuffer/remove()}}, + {{MediaSource/endOfStream()}}, + or as a consequence of the user agent running the + [=ManagedSourceBuffer/memory cleanup=] algorithm. + | +
+ The following steps are run at the completion of all operations to the {{ManagedSourceBuffer}} + |buffer:ManagedSourceBuffer| that would cause a |buffer|'s {{SourceBuffer/buffered}} to change. + That is once {{SourceBuffer/appendBuffer()}}, {{SourceBuffer/remove()}} or + [=ManagedSourceBuffer/memory cleanup=] algorithm have completed. +
++ Implementations can use different strategies for selecting |removal ranges| + so web applications shouldn't depend on a specific behavior. The web + application would listen to the {{bufferedchange}} event to observe + whether portions of the buffered data have been evicted. +
+This section specifies what existing {{HTMLMediaElement}}.{{HTMLMediaElement/seekable}} and @@ -3162,7 +3436,65 @@
+ <script> + async function setUpVideoStream() { + // Specific video format and codec + const mediaType = 'video/mp4; codecs="mp4a.40.2,avc1.4d4015"'; + + // Check if the type of video format / codec is supported. + if (!window.ManagedMediaSource?.isTypeSupported(mediaType)) { + return; // Not supported, do something else. + } + + // Set up video and its managed source. + const video = document.createElement("video"); + const source = new ManagedMediaSource(); + + video.controls = true; + + await new Promise((resolve) => { + video.src = URL.createObjectURL(source); + source.addEventListener("sourceopen", resolve, { once: true }); + document.body.appendChild(video); + }); + + const sourceBuffer = source.addSourceBuffer(mediaType); + + // Set up the event handlers + sourceBuffer.onbufferedchange = (e) => { + console.log("onbufferedchange event fired."); + console.log(`Added Ranges: ${timeRangesToString(e.addedRanges)}`); + console.log(`Removed Ranges: ${timeRangesToString(e.removedRanges)}`); + }; + + source.onstartstreaming = async () => { + const response = await fetch("./videos/bipbop.mp4"); + const buffer = await response.arrayBuffer(); + await new Promise((resolve) => { + sourceBuffer.addEventListener("updateend", resolve, { once: true }); + sourceBuffer.appendBuffer(buffer); + }); + }; + source.onendstreaming = async () => { + // Stop fetching new segments here + }; + } + + // Helper function... + function timeRangesToString(timeRanges) { + const ranges = []; + for (let i = 0; i < timeRanges.length; i++) { + ranges.push([timeRanges.start(i), timeRanges.end(i)]); + } + return "[" + ranges.map(([start, end]) => `[${start}, ${end})` ) + "]"; + } + </script> + <body onload="setUpVideoStream()"></body> ++