Skip to content

Commit

Permalink
feat(HLS): Containerless format support
Browse files Browse the repository at this point in the history
This adds code to allow Shaka Player to play media in sequence
mode, an alternate playback mode that makes the browser ignore
media timestamps, when playing HLS media.
This is important for containerless media formats, as they do not
contain such timestamps.
Changing HLS to not require timestamps also means that we no
longer need to fetch media segments in order to get the start
time, which should lower bandwidth usage and startup delay.
In initial tests, on a simulated 3G network, load latency went down
from an average 3.16s to 2.61s on the HLS version of "Big Buck Bunny:
the Dark Truths of a Video Dev Cartoon"; an improvement of about 17%.

Issue #2337

Change-Id: I507898d74ae30ddfb1bddf8dce643780949fbd9b
  • Loading branch information
michellezhuogg authored and theodab committed Feb 8, 2022
1 parent 6d76a13 commit 36d0b54
Show file tree
Hide file tree
Showing 32 changed files with 275 additions and 1,321 deletions.
3 changes: 1 addition & 2 deletions README.md
Expand Up @@ -123,12 +123,11 @@ HLS features supported:
- CEA-608/708 captions
- Encrypted content with PlayReady and Widevine
- Encrypted content with FairPlay (Safari on macOS and iOS 12+ only)
- Raw AAC, MP3, etc (without an MP4 container)

HLS features **not** supported:
- Key rotation: https://github.com/google/shaka-player/issues/917
- I-frame-only playlists: https://github.com/google/shaka-player/issues/742
- Raw AAC, MP3, etc (without an MP4 container):
https://github.com/google/shaka-player/issues/2337
- Low-latency streaming with blocking playlist reload

[mux.js]: https://github.com/videojs/mux.js/releases
Expand Down
1 change: 0 additions & 1 deletion demo/common/message_ids.js
Expand Up @@ -187,7 +187,6 @@ shakaDemo.MessageIds = {
IGNORE_DASH_SUGGESTED_PRESENTATION_DELAY: 'DEMO_IGNORE_DASH_SUGGESTED_PRESENTATION_DELAY',
IGNORE_HLS_IMAGE_FAILURES: 'DEMO_IGNORE_HLS_IMAGE_FAILURES',
IGNORE_HLS_TEXT_FAILURES: 'DEMO_IGNORE_HLS_TEXT_FAILURES',
USE_FULL_SEGMENTS_FOR_START_TIME: 'DEMO_USE_FULL_SEGMENTS_FOR_START_TIME',
IGNORE_MIN_BUFFER_TIME: 'DEMO_IGNORE_MIN_BUFFER_TIME',
IGNORE_TEXT_FAILURES: 'DEMO_IGNORE_TEXT_FAILURES',
INACCURATE_MANIFEST_TOLERANCE: 'DEMO_INACCURATE_MANIFEST_TOLERANCE',
Expand Down
2 changes: 0 additions & 2 deletions demo/config.js
Expand Up @@ -209,8 +209,6 @@ shakaDemo.Config = class {
'manifest.hls.ignoreTextStreamFailures')
.addBoolInput_(MessageIds.IGNORE_HLS_IMAGE_FAILURES,
'manifest.hls.ignoreImageStreamFailures')
.addBoolInput_(MessageIds.USE_FULL_SEGMENTS_FOR_START_TIME,
'manifest.hls.useFullSegmentsForStartTime')
.addTextInput_(MessageIds.DEFAULT_AUDIO_CODEC,
'manifest.hls.defaultAudioCodec')
.addTextInput_(MessageIds.DEFAULT_VIDEO_CODEC,
Expand Down
1 change: 0 additions & 1 deletion demo/locales/en.json
Expand Up @@ -221,7 +221,6 @@
"DEMO_UPDATE_EXPIRATION_TIME": "Update expiration time",
"DEMO_UPDATE_INTERVAL_SECONDS": "Update interval seconds",
"DEMO_UPLYNK": "Verizon Digital Media Services",
"DEMO_USE_FULL_SEGMENTS_FOR_START_TIME": "Use Full Segments For Start Time",
"DEMO_USE_HEADERS": "Use Headers",
"DEMO_USE_NATIVE_HLS_SAFARI": "Use native HLS on Safari",
"DEMO_USE_PERSISTENT_LICENSES": "Use Persistent Licenses",
Expand Down
4 changes: 0 additions & 4 deletions demo/locales/source.json
Expand Up @@ -395,10 +395,6 @@
"description": "The label on a field that allows users to provide a video id for a custom asset.",
"message": "Video ID (for VOD DAI Content)"
},
"DEMO_USE_FULL_SEGMENTS_FOR_START_TIME": {
"description": "The name of a configuration value.",
"message": "Use Full Segments For Start Time"
},
"DEMO_IGNORE_MIN_BUFFER_TIME": {
"description": "The name of a configuration value.",
"message": "Ignore Min Buffer Time"
Expand Down
11 changes: 0 additions & 11 deletions docs/tutorials/faq.md
Expand Up @@ -43,17 +43,6 @@ headers in the response. Additionally, with some manifests, we will send a
This can also happen with mixed-content restrictions. If the site is using
`https:`, then your manifest and segments must also.

*Sending `Range` header at the start of HLS playback can be disabled using this config:*
```
player.configure({
manifest: {
hls: {
useFullSegmentsForStartTime: true,
},
},
})
```

<hr>

**Q:** I am getting `REQUESTED_KEY_SYSTEM_CONFIG_UNAVAILABLE` or error code
Expand Down
6 changes: 5 additions & 1 deletion externs/shaka/manifest.js
Expand Up @@ -17,7 +17,8 @@
* textStreams: !Array.<shaka.extern.Stream>,
* imageStreams: !Array.<shaka.extern.Stream>,
* offlineSessionIds: !Array.<string>,
* minBufferTime: number
* minBufferTime: number,
* sequenceMode: boolean
* }}
*
* @description
Expand Down Expand Up @@ -72,6 +73,9 @@
* The minimum number of seconds of content that must be buffered before
* playback can begin. Can be overridden by a higher value from the Player
* configuration.
* @property {boolean} sequenceMode
* If true, we will append the media segments using sequence mode; that is to
* say, ignoring any timestamps inside the media files.
*
* @exportDoc
*/
Expand Down
6 changes: 5 additions & 1 deletion externs/shaka/offline.js
Expand Up @@ -73,7 +73,8 @@ shaka.extern.StoredContent;
* sessionIds: !Array.<string>,
* drmInfo: ?shaka.extern.DrmInfo,
* appMetadata: Object,
* isIncomplete: (boolean|undefined)
* isIncomplete: (boolean|undefined),
* sequenceMode: (boolean|undefined)
* }}
*
* @property {number} creationTime
Expand All @@ -98,6 +99,9 @@ shaka.extern.StoredContent;
* A metadata object passed from the application.
* @property {(boolean|undefined)} isIncomplete
* If true, the content is still downloading.
* @property {(boolean|undefined)} sequenceMode
* If true, we will append the media segments using sequence mode; that is to
* say, ignoring any timestamps inside the media files.
*/
shaka.extern.ManifestDB;

Expand Down
4 changes: 0 additions & 4 deletions externs/shaka/player.js
Expand Up @@ -746,7 +746,6 @@ shaka.extern.DashManifestConfiguration;
* @typedef {{
* ignoreTextStreamFailures: boolean,
* ignoreImageStreamFailures: boolean,
* useFullSegmentsForStartTime: boolean,
* defaultAudioCodec: string,
* defaultVideoCodec: string
* }}
Expand All @@ -757,9 +756,6 @@ shaka.extern.DashManifestConfiguration;
* @property {boolean} ignoreImageStreamFailures
* If <code>true</code>, ignore any errors in a image stream and filter out
* those streams.
* @property {boolean} useFullSegmentsForStartTime
* If <code>true</code>, force HlsParser to use a full segment request for
* determining start time in case the server does not support partial requests
* @property {string} defaultAudioCodec
* The default audio codec if it is not specified in the HLS playlist.
* <i>Defaults to <code>'mp4a.40.2'</code>.</i>
Expand Down
15 changes: 15 additions & 0 deletions externs/sourcebuffer.js
@@ -0,0 +1,15 @@
/*! @license
* Shaka Player
* Copyright 2016 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/

/**
* @fileoverview Externs for SourceBuffer which are missing from the Closure
* compiler.
*
* @externs
*/

/** @type {string} */
SourceBuffer.prototype.mode;
1 change: 1 addition & 0 deletions lib/dash/dash_parser.js
Expand Up @@ -497,6 +497,7 @@ shaka.dash.DashParser = class {
imageStreams: this.periodCombiner_.getImageStreams(),
offlineSessionIds: [],
minBufferTime: minBufferTime || 0,
sequenceMode: false,
};

// We only need to do clock sync when we're using presentation start
Expand Down

0 comments on commit 36d0b54

Please sign in to comment.