From a1678ce9c35afd5bd6cc9d03c782c8735c73aa21 Mon Sep 17 00:00:00 2001 From: Gary Katsevman Date: Tue, 16 Aug 2022 15:13:06 -0400 Subject: [PATCH 1/3] feat: rename many things to main. BREAKING CHANGE: rename PlaylistController BREAKING CHANGE: rename HAVE_MASTER to HAVE_MAIN_MANIFEST BREAKING CHANGE: playlist loaders updateMain and .main prop rename BREAKING CHANGE: manifest.js exports mainForMedia and addPropertiesToMain BREAKING CHANGE: rename media groups prop to isMainPlaylist BREAKING CHANGE: rename property to mainPlaylistLoader_ BREAKING CHANGE: rename to PlaylistController#main() --- COLLABORATOR_GUIDE.md | 8 +- CONTRIBUTING.md | 2 +- README.md | 22 +- design/media-groups.md | 8 +- docs/README.md | 15 +- docs/a-walk-through-vhs.md | 82 +- docs/arch.md | 2 +- docs/bitrate-switching.md | 2 +- docs/dash-playlist-loader.md | 20 +- docs/glossary.md | 4 +- ...aylist-loader-mpc-mg-sequence.plantuml.png | Bin 172762 -> 0 bytes ...sh-playlist-loader-pc-mg-sequence.puml.png | Bin 0 -> 168904 bytes .../dash-playlist-loader-states.nomnoml.svg | 24 +- ...aylist-loader-mpc-mg-sequence.plantuml.png | Bin 165647 -> 0 bytes .../playlist-loader-pc-mg-sequence.puml.png | Bin 0 -> 161278 bytes .../images/playlist-loader-states.nomnoml.svg | 4 +- ... dash-playlist-loader-pc-mg-sequence.puml} | 22 +- .../dash-playlist-loader-states.nomnoml.txt | 4 +- ...r-master-video-alt-audio-sequence.plantuml | 246 --- ...ml => playlist-loader-pc-mg-sequence.puml} | 22 +- .../playlist-loader-states.nomnoml.txt | 4 +- docs/lhls/index.md | 4 +- docs/lhls/transmux-before-append-changes.md | 2 +- docs/multiple-alternative-audio-tracks.md | 30 +- docs/playlist-loader.md | 8 +- docs/troubleshooting.md | 2 +- package-lock.json | 128 +- package.json | 7 +- scripts/index.js | 34 +- src/dash-playlist-loader.js | 232 +-- src/manifest.js | 100 +- src/media-groups.js | 68 +- src/playback-watcher.js | 26 +- ...t-controller.js => playlist-controller.js} | 154 +- src/playlist-loader.js | 70 +- src/playlist-selectors.js | 44 +- src/playlist.js | 32 +- src/rendition-mixin.js | 20 +- src/segment-loader.js | 2 +- src/util/codecs.js | 24 +- src/videojs-http-streaming.js | 132 +- test/dash-playlist-loader.test.js | 538 ++--- test/loader-common.js | 6 +- test/manifest.test.js | 122 +- ...aster-captions.m3u8 => main-captions.m3u8} | 2 +- ...ter-subtitles.m3u8 => main-subtitles.m3u8} | 2 +- test/manifests/{master.m3u8 => main.m3u8} | 2 +- test/manifests/streamInfInvalid.m3u8 | 2 +- test/media-groups.test.js | 132 +- test/playback-watcher.test.js | 86 +- ...er.test.js => playlist-controller.test.js} | 1730 ++++++++--------- test/playlist-loader.test.js | 300 +-- test/playlist-selectors.test.js | 100 +- test/playlist.test.js | 30 +- test/rendition-mixin.test.js | 46 +- test/segment-loader.test.js | 4 +- test/util/codecs.test.js | 34 +- test/videojs-http-streaming.test.js | 670 +++---- utils/stats/index.html | 24 +- utils/switcher/run-simulation.js | 16 +- 60 files changed, 2611 insertions(+), 2845 deletions(-) delete mode 100644 docs/images/dash-playlist-loader-mpc-mg-sequence.plantuml.png create mode 100644 docs/images/dash-playlist-loader-pc-mg-sequence.puml.png delete mode 100644 docs/images/playlist-loader-mpc-mg-sequence.plantuml.png create mode 100644 docs/images/playlist-loader-pc-mg-sequence.puml.png rename docs/images/sources/{dash-playlist-loader-mpc-mg-sequence.plantuml => dash-playlist-loader-pc-mg-sequence.puml} (81%) delete mode 100644 docs/images/sources/new-playlist-loader-master-video-alt-audio-sequence.plantuml rename docs/images/sources/{playlist-loader-mpc-mg-sequence.plantuml => playlist-loader-pc-mg-sequence.puml} (83%) rename src/{master-playlist-controller.js => playlist-controller.js} (93%) rename test/manifests/{master-captions.m3u8 => main-captions.m3u8} (93%) rename test/manifests/{master-subtitles.m3u8 => main-subtitles.m3u8} (94%) rename test/manifests/{master.m3u8 => main.m3u8} (84%) rename test/{master-playlist-controller.test.js => playlist-controller.test.js} (75%) diff --git a/COLLABORATOR_GUIDE.md b/COLLABORATOR_GUIDE.md index 7ce3f3058..55c6321e7 100644 --- a/COLLABORATOR_GUIDE.md +++ b/COLLABORATOR_GUIDE.md @@ -81,7 +81,7 @@ Afterwards, you want to push the commit and the tag to the repo. It's necessary to do this before running `npm publish` because our GitHub release automation relies on the commit being available on GitHub. ```sh -git push --follow-tags origin master +git push --follow-tags origin main ``` Publish to npm. @@ -90,15 +90,15 @@ Publish to npm. npm publish ``` -After it's done, [create a release in github](https://github.com/videojs/http-streaming/releases/new) with latest tag, no title, description copied from [the changelog](https://github.com/videojs/http-streaming/blob/master/CHANGELOG.md), and the .min.js and .js dist files attached. +After it's done, [create a release in github](https://github.com/videojs/http-streaming/releases/new) with latest tag, no title, description copied from [the changelog](https://github.com/videojs/http-streaming/blob/main/CHANGELOG.md), and the .min.js and .js dist files attached. If it's a large enough release, consider writing a blog post as well. ## Doc credit -This collaborator guide was heavily inspired by [node.js's guide](https://github.com/nodejs/node/blob/master/COLLABORATOR_GUIDE.md) and [video.js's guide](https://github.com/videojs/video.js/blob/master/COLLABORATOR_GUIDE.md) +This collaborator guide was heavily inspired by [node.js's guide](https://github.com/nodejs/node/blob/main/COLLABORATOR_GUIDE.md) and [video.js's guide](https://github.com/videojs/video.js/blob/main/COLLABORATOR_GUIDE.md) -[conventions]: https://github.com/videojs/conventional-changelog-videojs/blob/master/convention.md +[conventions]: https://github.com/videojs/conventional-changelog-videojs/blob/main/convention.md [vjs npm]: http://npmjs.com/org/videojs diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 175d9765e..02ed26474 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -27,4 +27,4 @@ Testing is a crucial part of any software project. For all but the most trivial [karma]: http://karma-runner.github.io/ [local]: http://localhost:9999/test/ -[conventions]: https://github.com/videojs/generator-videojs-plugin/blob/master/docs/conventions.md +[conventions]: https://github.com/videojs/generator-videojs-plugin/blob/main/docs/conventions.md diff --git a/README.md b/README.md index f8f5a47d2..a3a89787a 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ Video.js Compatibility: 6.0, 7.0 - [Format](#format) - [Example](#example) - [Runtime Properties](#runtime-properties) - - [vhs.playlists.master](#vhsplaylistsmaster) + - [vhs.playlists.main](#vhsplaylistsmain) - [vhs.playlists.media](#vhsplaylistsmedia) - [vhs.systemBandwidth](#vhssystembandwidth) - [vhs.bandwidth](#vhsbandwidth) @@ -172,7 +172,7 @@ This plugin does not support Flash playback. Instead, it is recommended that use DRM is supported through [videojs-contrib-eme](https://github.com/videojs/videojs-contrib-eme). In order to use DRM, include the videojs-contrib-eme plug, [initialize it](https://github.com/videojs/videojs-contrib-eme#initialization), and add options to either the [plugin](https://github.com/videojs/videojs-contrib-eme#plugin-options) or the [source](https://github.com/videojs/videojs-contrib-eme#source-options). -Detailed option information can be found in the [videojs-contrib-eme README](https://github.com/videojs/videojs-contrib-eme/blob/master/README.md). +Detailed option information can be found in the [videojs-contrib-eme README](https://github.com/videojs/videojs-contrib-eme/blob/main/README.md). ## Documentation [HTTP Live Streaming](https://developer.apple.com/streaming/) (HLS) has @@ -522,11 +522,11 @@ work across all the media types that video.js supports. If you're deploying videojs-http-streaming on your own website and want to make a couple tweaks though, go for it! -#### vhs.playlists.master +#### vhs.playlists.main Type: `object` -An object representing the parsed master playlist. If a media playlist -is loaded directly, a master playlist with only one entry will be +An object representing the parsed main playlist. If a media playlist +is loaded directly, a main playlist with only one entry will be created. #### vhs.playlists.media @@ -537,7 +537,7 @@ media playlist. The active media playlist is referred to when additional video data needs to be downloaded. Calling this function with no arguments returns the parsed playlist object for the active media playlist. Calling this function with a playlist object from the -master playlist or a URI string as specified in the master playlist +main playlist or a URI string as specified in the main playlist will kick off an asynchronous load of the specified media playlist. Once it has been retreived, it will become the active media playlist. @@ -577,7 +577,7 @@ A function that returns the media playlist object to use to download the next segment. It is invoked by the tech immediately before a new segment is downloaded. You can override this function to provide your adaptive streaming logic. You must, however, be sure to return a valid -media playlist object that is present in `player.tech().vhs.master`. +media playlist object that is present in `player.tech().vhs.main`. Overridding this function with your own is very powerful but is overkill for many purposes. Most of the time, you should use the much simpler @@ -691,7 +691,7 @@ This object contains a summary of HLS and player related stats. | currentSource | object | The source object. Has the structure `{src: 'url', type: 'mimetype'}` | | currentTech | string | The name of the tech in use | | duration | number | Duration of the video in seconds | -| master | object | The [master playlist object](#vhsplaylistsmaster) | +| main | object | The [main playlist object](#vhsplaylistsmain) | | playerDimensions | object | Contains the width and height of the player | | seekable | array | List of time ranges that the player can seek to | | timestamp | number | Timestamp of when `vhs.stats` was accessed | @@ -732,7 +732,7 @@ player.on('ready', () => { ``` Note that these events are triggered as soon as a case is encountered, and often only -once. For example, the `vhs-demuxed` usage event will be triggered as soon as the master +once. For example, the `vhs-demuxed` usage event will be triggered as soon as the main manifest is downloaded and parsed, and will not be triggered again. #### Presence Stats @@ -741,11 +741,11 @@ Each of the following usage events are fired once per source if (and when) detec | Name | Description | | ------------- | ------------- | -| vhs-webvtt | master manifest has at least one segmented WebVTT playlist | +| vhs-webvtt | main manifest has at least one segmented WebVTT playlist | | vhs-aes | a playlist is AES encrypted | | vhs-fmp4 | a playlist used fMP4 segments | | vhs-demuxed | audio and video are demuxed by default | -| vhs-alternate-audio | alternate audio available in the master manifest | +| vhs-alternate-audio | alternate audio available in the main manifest | | vhs-playlist-cue-tags | a playlist used cue tags (see useCueTags(#usecuetags) for details) | | vhs-bandwidth-from-local-storage | starting bandwidth was retrieved from local storage (see useBandwidthFromLocalStorage(#useBandwidthFromLocalStorage) for details) | | vhs-throughput-from-local-storage | starting throughput was retrieved from local storage (see useBandwidthFromLocalStorage(#useBandwidthFromLocalStorage) for details) | diff --git a/design/media-groups.md b/design/media-groups.md index 3faa29d8a..5dbeec63d 100644 --- a/design/media-groups.md +++ b/design/media-groups.md @@ -9,10 +9,10 @@ These are used to represent: Currently, [MediaGroups][mg] interacts with several different classes, which can be difficult to follow and has cause bugs in the past. These components are: - multiple [DashPlaylistLoaders][dpl] or [PlaylistLoaders][pl] -- [MasterPlaylistController][mpc] +- [PlaylistController][PC] - multiple [SegmentLoaders][sl] -[MediaGroups][mg] are **setup** by the `loadedmetadata` handler for the `masterPlaylistLoader` (video playlist loader) of a source; contained in the [MasterPlaylistController][mpc] (MPC). The [MPC] will pass in an `audioSegmentLoader` and `subtitleSegmentLoader` to be shared by the `AUDIO` and `SUBTITLE` mediaGroups respectively. +[MediaGroups][mg] are **setup** by the `loadedmetadata` handler for the `mainPlaylistLoader` (video playlist loader) of a source; contained in the [PlaylistController][PC] (PC). The [PC] will pass in an `audioSegmentLoader` and `subtitleSegmentLoader` to be shared by the `AUDIO` and `SUBTITLE` mediaGroups respectively. This **setup** includes creating either [DashPlaylistLoaders][dpl] or [PlaylistLoaders][pl] for each track described in the manifest and a corresponding HTML Track (either audio or text). @@ -34,10 +34,10 @@ Currently, videojs-http-streaming (VHS) does not support multiple video tracks. ## Future Ideas -Considering that we could have multiple tracks of all media types, it may be the most accurate to **always** use MediaGroups for all content. This would include HLS without alternate audio tracks and DASH for all cases. In this way, the MasterPlaylistController could delegate much of the interaction handling for the PlaylistLoaders and SegmentLoaders to the MediaGroups class which would act as a specialized controller. +Considering that we could have multiple tracks of all media types, it may be the most accurate to **always** use MediaGroups for all content. This would include HLS without alternate audio tracks and DASH for all cases. In this way, the PlaylistController could delegate much of the interaction handling for the PlaylistLoaders and SegmentLoaders to the MediaGroups class which would act as a specialized controller. [dpl]: ../src/dash-playlist-loader.js [mg]: ../src/media-groups.js [pl]: ../src/playlist-loader.js -[mpc]: ../src/master-playlist-controller.js +[PC]: ../src/playlist-controller.js [sl]: ../src/segment-loader.js diff --git a/docs/README.md b/docs/README.md index 0772d80b5..2c82c41ff 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,3 +1,14 @@ + + + +- [Overview](#overview) + - [HTTP Live Streaming](#http-live-streaming) + - [Dynamic Adaptive Streaming over HTTP](#dynamic-adaptive-streaming-over-http) +- [Further Documentation](#further-documentation) +- [Helpful Tools](#helpful-tools) + + + # Overview This project supports both [HLS][hls] and [MPEG-DASH][dash] playback in the video.js player. This document is intended as a primer for anyone interested in contributing or just better understanding how bits from a server get turned into video on their display. @@ -7,11 +18,11 @@ This project supports both [HLS][hls] and [MPEG-DASH][dash] playback in the vide - Delivered over HTTP(S): it uses the standard application protocol of the web to deliver all its data - Segmented: longer videos are broken up into smaller chunks which can be downloaded independently and switched between at runtime -A standard HLS stream consists of a *Master Playlist* which references one or more *Media Playlists*. Each Media Playlist contains one or more sequential video segments. All these components form a logical hierarchy that informs the player of the different quality levels of the video available and how to address the individual segments of video at each of those levels: +A standard HLS stream consists of a *Main Playlist* which references one or more *Media Playlists*. Each Media Playlist contains one or more sequential video segments. All these components form a logical hierarchy that informs the player of the different quality levels of the video available and how to address the individual segments of video at each of those levels: ![HLS Format](images/hls-format.png) -HLS streams can be delivered in two different modes: a "static" mode for videos that can be played back from any point, often referred to as video-on-demand (VOD); or a "live" mode where later portions of the video become available as time goes by. In the static mode, the Master and Media playlists are fixed. The player is guaranteed that the set of video segments referenced by those playlists will not change over time. +HLS streams can be delivered in two different modes: a "static" mode for videos that can be played back from any point, often referred to as video-on-demand (VOD); or a "live" mode where later portions of the video become available as time goes by. In the static mode, the Main and Media playlists are fixed. The player is guaranteed that the set of video segments referenced by those playlists will not change over time. Live mode can work in one of two ways. For truly live events, the most common configuration is for each individual Media Playlist to only include the latest video segment and a small number of consecutive previous segments. In this mode, the player may be able to seek backwards a short time in the video but probably not all the way back to the beginning. In the other live configuration, new video segments can be appended to the Media Playlists but older segments are never removed. This configuration allows the player to seek back to the beginning of the stream at any time during the broadcast and transitions seamlessly to the static stream type when the event finishes. diff --git a/docs/a-walk-through-vhs.md b/docs/a-walk-through-vhs.md index 0a1c4e941..80be4440e 100644 --- a/docs/a-walk-through-vhs.md +++ b/docs/a-walk-through-vhs.md @@ -58,25 +58,23 @@ flowchart TD > * most EME handling for DRM and setup of the [videojs-contrib-eme plugin](https://github.com/videojs/videojs-contrib-eme) > * mapping/handling of options passed down via Video.js -## MasterPlaylistController +## PlaylistController -One critical object that `VhsHandler`'s constructor creates is a new `MasterPlaylistController`. +One critical object that `VhsHandler`'s constructor creates is a new `PlaylistController`. ```mermaid flowchart TD VhsSourceHandler --> VhsHandler - VhsHandler --> MasterPlaylistController + VhsHandler --> PlaylistController ``` -`MasterPlaylistController` is not a great name, and has grown in size to be a bit unwieldy, but it's the hub of VHS. Eventually, it should be broken into smaller pieces, but for now, it handles the creation and management of most of the other VHS modules. Its code can be found in [src/master-playlist-controller.js](https://github.com/videojs/http-streaming/blob/0964cb4827d9e80aa36f2fa29e35dad92ca84111/src/master-playlist-controller.js). +`PlaylistController` is not a great name, and has grown in size to be a bit unwieldy, but it's the hub of VHS. Eventually, it should be broken into smaller pieces, but for now, it handles the creation and management of most of the other VHS modules. Its code can be found in [src/playlist-controller.js](/src/playlist-controller.js). -The best way to think of `MasterPlaylistController` is as Tron's Master Control Program, though hopefully it isn't as evil. +`PlaylistController` is a lot to say. So we often refer to it as PC. -`MasterPlaylistController` is a lot to say. So we often refer to it as MPC. +If you need to find a place where different modules communicate, you will probably end up in PC. Just about all of `VhsHandler` that doesn't interface with Video.js or other plugins, interfaces with PC. -If you need to find a place where different modules communicate, you will probably end up in MPC. Just about all of `VhsHandler` that doesn't interface with Video.js or other plugins, interfaces with MPC. - -MPC's [constructor](https://github.com/videojs/http-streaming/blob/0964cb4827d9e80aa36f2fa29e35dad92ca84111/src/master-playlist-controller.js#L148) does a lot. Instead of listing all of the things it does, let's go step-by-step through the main ones, passing the source we had above. +PC's [constructor](/src/playlist-controller.js#L148) does a lot. Instead of listing all of the things it does, let's go step-by-step through the main ones, passing the source we had above. ```html @@ -84,18 +82,18 @@ MPC's [constructor](https://github.com/videojs/http-streaming/blob/0964cb4827d9e ``` -Looking at the `` tag, `VhsSourceHandler` already used the "type" to tell Video.js that it could handle the source. `VhsHandler` took the manifest URL, in this case "manifest.m3u8" and provided it to the constructor of MPC. +Looking at the `` tag, `VhsSourceHandler` already used the "type" to tell Video.js that it could handle the source. `VhsHandler` took the manifest URL, in this case "manifest.m3u8" and provided it to the constructor of PC. -The first thing that MPC must do is download that source, but it doesn't make the request itself. Instead, it creates [this.masterPlaylistLoader_](https://github.com/videojs/http-streaming/blob/0964cb4827d9e80aa36f2fa29e35dad92ca84111/src/master-playlist-controller.js#L264-L266). +The first thing that PC must do is download that source, but it doesn't make the request itself. Instead, it creates [this.mainPlaylistLoader_](/src/laylist-controller.js#L263-L265). ```mermaid flowchart TD VhsSourceHandler --> VhsHandler - VhsHandler --> MasterPlaylistController - MasterPlaylistController --> PlaylistLoader + VhsHandler --> PlaylistController + PlaylistController --> PlaylistLoader ``` -`masterPlaylistLoader_` is an instance of either the [HLS PlaylistLoader](https://github.com/videojs/http-streaming/blob/0964cb4827d9e80aa36f2fa29e35dad92ca84111/src/playlist-loader.js#L379) or the [DashPlaylistLoader](https://github.com/videojs/http-streaming/blob/0964cb4827d9e80aa36f2fa29e35dad92ca84111/src/dash-playlist-loader.js#L259). +`mainPlaylistLoader_` is an instance of either the [HLS PlaylistLoader](/src/playlist-loader.js#L379) or the [DashPlaylistLoader](/src/dash-playlist-loader.js#L259). The names betray their use. They load the playlist. The URL ("manifest.m3u8" here) is given, and the manifest/playlist is downloaded and parsed. If the content is live, the playlist loader also handles refreshing the manifest. For HLS, where manifests point to other manifests, the playlist loader requests those as well. @@ -117,9 +115,9 @@ Manifest { } ``` -Many properties are removed for simplicity. This is a top level manifest (often referred to as a master or main manifest), and within it there are playlists, each playlist being a Manifest itself. Since the JSON "schema" for main and media playlists is the same, you will see irrelevant properties within any given manifest object. For instance, you might see a `targetDuration` property on the main manifest object, though a main manifest doesn't have a target duration. You can ignore irrelevant properties. Eventually they should be cleaned up, and a proper schema defined for manifest objects. +Many properties are removed for simplicity. This is a top level manifest (often referred to as a main manifest or a multivariant manifest [from the HLS spec]), and within it there are playlists, each playlist being a Manifest itself. Since the JSON "schema" for main and media playlists is the same, you will see irrelevant properties within any given manifest object. For instance, you might see a `targetDuration` property on the main manifest object, though a main manifest doesn't have a target duration. You can ignore irrelevant properties. Eventually they should be cleaned up, and a proper schema defined for manifest objects. -MPC will also use `masterPlaylistLoader_` to select which media playlist is active (e.g., the 720p rendition or the 480p rendition), so that `masterPlaylistLoader_` will only need to refresh that individual playlist if the stream is live. +PC will also use `mainPlaylistLoader_` to select which media playlist is active (e.g., the 720p rendition or the 480p rendition), so that `mainPlaylistLoader_` will only need to refresh that individual playlist if the stream is live. > :information_source: **Future Work** > @@ -129,26 +127,26 @@ MPC will also use `masterPlaylistLoader_` to select which media playlist is acti ### Media Source Extensions -The next thing MPC needs to do is set up a media source for [Media Source Extensions](https://www.w3.org/TR/media-source/). Specifically, it needs to create [this.mediaSource](https://github.com/videojs/http-streaming/blob/0964cb4827d9e80aa36f2fa29e35dad92ca84111/src/master-playlist-controller.js#L210) and its associated [source buffers](https://github.com/videojs/http-streaming/blob/main/src/master-playlist-controller.js#L1818). These are where audio and video data will be appended, so that the browser has content to play. But those aren't used directly. Because source buffers can only handle one operation at a time, [this.sourceUpdater_](https://github.com/videojs/http-streaming/blob/0964cb4827d9e80aa36f2fa29e35dad92ca84111/src/master-playlist-controller.js#L234) is created. `sourceUpdater_` is a queue for operations performed on the source buffers. That's pretty much it. So all of the MSE pieces for appending get wrapped up in `sourceUpdater_`. +The next thing PC needs to do is set up a media source for [Media Source Extensions](https://www.w3.org/TR/media-source/). Specifically, it needs to create [this.mediaSource](/src/playlist-controller.js#L208) and its associated [source buffers](/src/playlist-controller.js#L1814). These are where audio and video data will be appended, so that the browser has content to play. But those aren't used directly. Because source buffers can only handle one operation at a time, [this.sourceUpdater_](/src/playlist-controller.js#L232) is created. `sourceUpdater_` is a queue for operations performed on the source buffers. That's pretty much it. So all of the MSE pieces for appending get wrapped up in `sourceUpdater_`. ## Segment Loaders The SourceUpdater created for MSE above is passed to the segment loaders. -[this.mainSegmentLoader_](https://github.com/videojs/http-streaming/blob/0964cb4827d9e80aa36f2fa29e35dad92ca84111/src/master-playlist-controller.js#L271-L275) is used for muxed content (audio and video in one segment) and for audio or video only streams. +[this.mainSegmentLoader_](/src/playlist-controller.js#L270-L274) is used for muxed content (audio and video in one segment) and for audio or video only streams. -[this.audioSegmentLoader_](https://github.com/videojs/http-streaming/blob/0964cb4827d9e80aa36f2fa29e35dad92ca84111/src/master-playlist-controller.js#L278-L281) is used when the content is demuxed (audio and video in separate playlists). +[this.audioSegmentLoader_](/src/playlist-controller.js#L277-L280) is used when the content is demuxed (audio and video in separate playlists). ```mermaid flowchart TD VhsSourceHandler --> VhsHandler - VhsHandler --> MasterPlaylistController - MasterPlaylistController --> PlaylistLoader - MasterPlaylistController --> SourceUpdater - MasterPlaylistController --> SegmentLoader + VhsHandler --> PlaylistController + PlaylistController --> PlaylistLoader + PlaylistController --> SourceUpdater + PlaylistController --> SegmentLoader ``` -Besides options and the `sourceUpdater_` from MPC, the segment loaders are given a [playlist](https://github.com/videojs/http-streaming/blob/0964cb4827d9e80aa36f2fa29e35dad92ca84111/src/segment-loader.js#L988). This playlist is a media playlist from the `masterPlaylistLoader_`. So looking back at our parsed manifest object: +Besides options and the `sourceUpdater_` from PC, the segment loaders are given a [playlist](https://github.com/videojs/http-streaming/blob/0964cb4827d9e80aa36f2fa29e35dad92ca84111/src/segment-loader.js#L988). This playlist is a media playlist from the `mainPlaylistLoader_`. So looking back at our parsed manifest object: ``` Manifest { @@ -174,19 +172,19 @@ VHS uses a strategy called `mediaIndex++` for choosing the next segment, see [he If there are no seeks or rendition changes, `chooseNextRequest_` will rely on the `mediaIndex++` strategy. -If there are seeks or rendition changes, then `chooseNextRequest_` will look at segment timing values via the `SyncController` (created previously in MPC), the current time, and the buffer, to determine what the next segment should be, and what it's start time should be (to position it on the timeline). +If there are seeks or rendition changes, then `chooseNextRequest_` will look at segment timing values via the `SyncController` (created previously in PC), the current time, and the buffer, to determine what the next segment should be, and what it's start time should be (to position it on the timeline). ```mermaid flowchart TD VhsSourceHandler --> VhsHandler - VhsHandler --> MasterPlaylistController - MasterPlaylistController --> PlaylistLoader - MasterPlaylistController --> SourceUpdater - MasterPlaylistController --> SegmentLoader + VhsHandler --> PlaylistController + PlaylistController --> PlaylistLoader + PlaylistController --> SourceUpdater + PlaylistController --> SegmentLoader SegmentLoader --> SyncController ``` -The `SyncController` has various [strategies](https://github.com/videojs/http-streaming/blob/0964cb4827d9e80aa36f2fa29e35dad92ca84111/src/sync-controller.js#L16) for ensuring that different renditions, which can have different media sequence and segment timing values, can be positioned on the playback timeline successfully. (It is also be [used by MPC](https://github.com/videojs/http-streaming/blob/0964cb4827d9e80aa36f2fa29e35dad92ca84111/src/master-playlist-controller.js#L1477) to establish a `seekable` range.) +The `SyncController` has various [strategies](https://github.com/videojs/http-streaming/blob/0964cb4827d9e80aa36f2fa29e35dad92ca84111/src/sync-controller.js#L16) for ensuring that different renditions, which can have different media sequence and segment timing values, can be positioned on the playback timeline successfully. (It is also be [used by PC](/src/playlist-controller.js#L1472) to establish a `seekable` range.) ### Downloading and Appending Segments @@ -196,10 +194,10 @@ If the buffer is not full, and a segment was chosen, then `SegmentLoader` will d ```mermaid flowchart TD VhsSourceHandler --> VhsHandler - VhsHandler --> MasterPlaylistController - MasterPlaylistController --> PlaylistLoader - MasterPlaylistController --> SourceUpdater - MasterPlaylistController --> SegmentLoader + VhsHandler --> PlaylistController + PlaylistController --> PlaylistLoader + PlaylistController --> SourceUpdater + PlaylistController --> SegmentLoader SegmentLoader --> SyncController SegmentLoader --> mediaSegmentRequest ``` @@ -213,10 +211,10 @@ When the `SegmentLoader` receives segment data events, it can append the data to ```mermaid flowchart TD VhsSourceHandler --> VhsHandler - VhsHandler --> MasterPlaylistController - MasterPlaylistController --> PlaylistLoader - MasterPlaylistController --> SourceUpdater - MasterPlaylistController --> SegmentLoader + VhsHandler --> PlaylistController + PlaylistController --> PlaylistLoader + PlaylistController --> SourceUpdater + PlaylistController --> SegmentLoader SegmentLoader --> SyncController SegmentLoader --> mediaSegmentRequest SegmentLoader --> SourceUpdater @@ -231,10 +229,10 @@ Besides downloading segments, `mediaSegmentRequest` [decrypts](https://github.co ```mermaid flowchart TD VhsSourceHandler --> VhsHandler - VhsHandler --> MasterPlaylistController - MasterPlaylistController --> PlaylistLoader - MasterPlaylistController --> SourceUpdater - MasterPlaylistController --> SegmentLoader + VhsHandler --> PlaylistController + PlaylistController --> PlaylistLoader + PlaylistController --> SourceUpdater + PlaylistController --> SegmentLoader SegmentLoader --> SyncController SegmentLoader --> mediaSegmentRequest SegmentLoader --> SourceUpdater diff --git a/docs/arch.md b/docs/arch.md index 994757fda..d68d1bbac 100644 --- a/docs/arch.md +++ b/docs/arch.md @@ -13,7 +13,7 @@ The [playlist loader](../src/playlist-loader.js) handles all of the details of r During VOD playback, the loader will move quickly to the HAVE_METADATA state and then stay there unless a quality switch request sends it to SWITCHING_MEDIA while it fetches an alternate playlist. The loader enters the HAVE_CURRENT_METADATA when a live stream is detected and it's time to refresh the current media playlist to find out about new video segments. ### HLS Tech -Currently, the HLS project integrates with [video.js](http://www.videojs.com/) as a [tech](https://github.com/videojs/video.js/blob/master/docs/guides/tech.md). That means it's responsible for providing an interface that closely mirrors the `