shaka-player 3.3.5 → 3.3.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/release-please.yaml +3 -2
- package/AUTHORS +1 -0
- package/CHANGELOG.md +32 -0
- package/CONTRIBUTORS +3 -0
- package/README.md +20 -6
- package/demo/demo.less +0 -1
- package/demo/index.html +0 -2
- package/demo/main.js +3 -3
- package/dist/controls.css +3 -3
- package/dist/controls.css.map +1 -1
- package/dist/demo.compiled.debug.js +2 -2
- package/dist/demo.compiled.debug.map +2 -2
- package/dist/demo.compiled.js +2 -2
- package/dist/demo.compiled.map +2 -2
- package/dist/demo.css +1 -1
- package/dist/demo.css.map +1 -1
- package/dist/deps.js +3 -3
- package/dist/locales.js +30 -30
- package/dist/shaka-player.compiled.d.ts +248 -237
- package/dist/shaka-player.compiled.debug.d.ts +248 -237
- package/dist/shaka-player.compiled.debug.externs.js +48 -37
- package/dist/shaka-player.compiled.debug.js +38 -33
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +48 -37
- package/dist/shaka-player.compiled.js +771 -770
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +292 -281
- package/dist/shaka-player.ui.debug.d.ts +292 -281
- package/dist/shaka-player.ui.debug.externs.js +48 -37
- package/dist/shaka-player.ui.debug.js +40 -35
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +48 -37
- package/dist/shaka-player.ui.js +883 -882
- package/dist/shaka-player.ui.map +4 -4
- package/docs/tutorials/welcome.md +6 -3
- package/lib/abr/simple_abr_manager.js +2 -1
- package/lib/dash/dash_parser.js +5 -0
- package/lib/hls/hls_parser.js +20 -5
- package/lib/media/drm_engine.js +3 -0
- package/lib/media/presentation_timeline.js +24 -1
- package/lib/player.js +1 -1
- package/lib/polyfill/media_capabilities.js +1 -0
- package/lib/polyfill/videoplaybackquality.js +3 -1
- package/lib/util/mime_utils.js +14 -5
- package/lib/util/platform.js +41 -1
- package/lib/util/stream_utils.js +1 -0
- package/lib/util/string_utils.js +56 -14
- package/maintained-branches.md +15 -0
- package/package.json +2 -4
- package/test/hls/hls_live_unit.js +60 -7
- package/ui/less/containers.less +1 -1
- package/ui/less/general.less +1 -1
- package/ui/less/range_elements.less +1 -0
- package/.github/pull_request_template.md +0 -10
- package/app-engine/README.md +0 -9
- package/app-engine/demo-version-index/README.md +0 -14
- package/app-engine/demo-version-index/app.yaml +0 -2
- package/app-engine/demo-version-index/main.py +0 -162
- package/app-engine/demo-version-index/requirements.txt +0 -6
- package/app-engine/demo-version-index/templates/index.html +0 -114
- package/app-engine/shaka-player-demo/README.md +0 -18
- package/app-engine/shaka-player-demo/app.yaml +0 -61
- package/app-engine/shaka-player-demo/main.py +0 -95
- package/app-engine/shaka-player-demo/posters/10yo.png +0 -0
- package/app-engine/shaka-player-demo/posters/10yo.xcf +0 -0
- package/app-engine/shaka-player-demo/posters/1yo.jpg +0 -0
- package/app-engine/shaka-player-demo/posters/2yo.png +0 -0
- package/app-engine/shaka-player-demo/posters/2yo.xcf +0 -0
- package/app-engine/shaka-player-demo/posters/3yo.png +0 -0
- package/app-engine/shaka-player-demo/posters/3yo.xcf +0 -0
- package/app-engine/shaka-player-demo/posters/4yo.png +0 -0
- package/app-engine/shaka-player-demo/posters/4yo.xcf +0 -0
- package/app-engine/shaka-player-demo/posters/5yo.png +0 -0
- package/app-engine/shaka-player-demo/posters/5yo.xcf +0 -0
- package/app-engine/shaka-player-demo/posters/6yo.png +0 -0
- package/app-engine/shaka-player-demo/posters/6yo.xcf +0 -0
- package/app-engine/shaka-player-demo/posters/7yo.png +0 -0
- package/app-engine/shaka-player-demo/posters/7yo.xcf +0 -0
- package/app-engine/shaka-player-demo/posters/8yo.png +0 -0
- package/app-engine/shaka-player-demo/posters/8yo.xcf +0 -0
- package/app-engine/shaka-player-demo/posters/9yo.png +0 -0
- package/app-engine/shaka-player-demo/posters/9yo.xcf +0 -0
- package/app-engine/shaka-player-demo/posters/audioOnly.gif +0 -0
- package/app-engine/shaka-player-demo/posters/audioRickRoll.gif +0 -0
- package/app-engine/shaka-player-demo/posters/colorbars.gif +0 -0
- package/app-engine/shaka-player-demo/posters/fireworks.jpg +0 -0
- package/app-engine/shaka-player-demo/posters/party-hat.png +0 -0
- package/app-engine/shaka-player-demo/posters/sources.txt +0 -46
- package/app-engine/shaka-player-demo/posters/standard.png +0 -0
- package/app-engine/shaka-player-demo/posters/trek.jpg +0 -0
- package/app-engine/shaka-player-demo/posters/valentines.png +0 -0
- package/app-engine/shaka-player-demo/posters/zombie.jpg +0 -0
- package/app-engine/shaka-player-demo/posters.py +0 -110
- package/app-engine/shaka-player-demo/requirements.txt +0 -5
- package/app-engine/shaka-player-demo/time.txt +0 -1
- package/build/README.md +0 -127
- package/build/__init__.py +0 -0
- package/build/all.py +0 -150
- package/build/apps.py +0 -186
- package/build/build.py +0 -392
- package/build/check.py +0 -354
- package/build/checkversion.py +0 -84
- package/build/compiler.py +0 -513
- package/build/conformance.textproto +0 -335
- package/build/docker/Dockerfile +0 -20
- package/build/docker/docker-compose.yml +0 -10
- package/build/docs.py +0 -54
- package/build/eslint-plugin-shaka-rules/arg-comment-spacing.js +0 -72
- package/build/eslint-plugin-shaka-rules/index.js +0 -24
- package/build/eslint-plugin-shaka-rules/package.json +0 -7
- package/build/eslint-plugin-shaka-rules/private.js +0 -109
- package/build/gendeps.py +0 -71
- package/build/generateExterns.js +0 -867
- package/build/generateLocalizations.py +0 -262
- package/build/generateTsDefs.py +0 -137
- package/build/install-linux-prereqs.sh +0 -136
- package/build/license-header +0 -5
- package/build/misspellings.txt +0 -38
- package/build/pixelsChanged.js +0 -35
- package/build/shaka-lab.yaml +0 -163
- package/build/shakaBuildHelpers.py +0 -356
- package/build/stats.py +0 -816
- package/build/subprocessWindowsPatch.py +0 -103
- package/build/test.py +0 -541
- package/build/types/ads +0 -8
- package/build/types/cast +0 -6
- package/build/types/cea +0 -13
- package/build/types/complete +0 -9
- package/build/types/core +0 -108
- package/build/types/dash +0 -8
- package/build/types/hls +0 -9
- package/build/types/manifests +0 -5
- package/build/types/networking +0 -6
- package/build/types/offline +0 -22
- package/build/types/polyfill +0 -21
- package/build/types/text +0 -11
- package/build/types/ui +0 -39
- package/build/updateScreenshots.py +0 -85
- package/build/wrapper.template.js +0 -52
|
@@ -98,11 +98,14 @@ You can find a full list of available browsers with `--browsers help`, and you
|
|
|
98
98
|
can find a complete list of testing options with `--help`.
|
|
99
99
|
|
|
100
100
|
|
|
101
|
-
####
|
|
101
|
+
#### Announcements
|
|
102
102
|
|
|
103
|
-
|
|
103
|
+
To subscribe to new releases on GitHub, you can follow
|
|
104
|
+
[instructions from this blog](https://www.jessesquires.com/blog/2020/07/30/github-tip-watching-releases/).
|
|
105
|
+
|
|
106
|
+
To receive infrequent announcements and surveys from us, you can join our
|
|
104
107
|
[mailing list](https://groups.google.com/forum/#!forum/shaka-player-users).
|
|
105
|
-
The list is very low volume.
|
|
108
|
+
The list is very low volume, and can only be written to by us.
|
|
106
109
|
|
|
107
110
|
|
|
108
111
|
#### Continue the Tutorials
|
|
@@ -219,8 +219,9 @@ shaka.abr.SimpleAbrManager = class {
|
|
|
219
219
|
* @export
|
|
220
220
|
*/
|
|
221
221
|
getBandwidthEstimate() {
|
|
222
|
+
const defaultBandwidthEstimate = this.getDefaultBandwidth_();
|
|
222
223
|
return this.bandwidthEstimator_.getBandwidthEstimate(
|
|
223
|
-
|
|
224
|
+
defaultBandwidthEstimate);
|
|
224
225
|
}
|
|
225
226
|
|
|
226
227
|
|
package/lib/dash/dash_parser.js
CHANGED
|
@@ -512,6 +512,11 @@ shaka.dash.DashParser = class {
|
|
|
512
512
|
}
|
|
513
513
|
presentationTimeline.setClockOffset(offset);
|
|
514
514
|
}
|
|
515
|
+
|
|
516
|
+
// This is the first point where we have a meaningful presentation start
|
|
517
|
+
// time, and we need to tell PresentationTimeline that so that it can
|
|
518
|
+
// maintain consistency from here on.
|
|
519
|
+
presentationTimeline.lockStartTime();
|
|
515
520
|
} else {
|
|
516
521
|
// Just update the variants and text streams, which may change as periods
|
|
517
522
|
// are added or removed.
|
package/lib/hls/hls_parser.js
CHANGED
|
@@ -549,8 +549,14 @@ shaka.hls.HlsParser = class {
|
|
|
549
549
|
for (const stream of streamsToNotify) {
|
|
550
550
|
this.segmentsToNotifyByStream_.push(stream.segmentIndex.references);
|
|
551
551
|
}
|
|
552
|
+
|
|
552
553
|
this.notifySegments_();
|
|
553
554
|
|
|
555
|
+
// This is the first point where we have a meaningful presentation start
|
|
556
|
+
// time, and we need to tell PresentationTimeline that so that it can
|
|
557
|
+
// maintain consistency from here on.
|
|
558
|
+
this.presentationTimeline_.lockStartTime();
|
|
559
|
+
|
|
554
560
|
// This asserts that the live edge is being calculated from segment times.
|
|
555
561
|
// For VOD and event streams, this check should still pass.
|
|
556
562
|
goog.asserts.assert(
|
|
@@ -1663,8 +1669,6 @@ shaka.hls.HlsParser = class {
|
|
|
1663
1669
|
/* presentationStartTime= */ null, /* delay= */ 0);
|
|
1664
1670
|
this.presentationTimeline_.setStatic(true);
|
|
1665
1671
|
}
|
|
1666
|
-
|
|
1667
|
-
this.notifySegments_();
|
|
1668
1672
|
}
|
|
1669
1673
|
|
|
1670
1674
|
/**
|
|
@@ -1778,9 +1782,20 @@ shaka.hls.HlsParser = class {
|
|
|
1778
1782
|
const pPreviousReference = i == 0 ?
|
|
1779
1783
|
previousReference : partialSegmentRefs[partialSegmentRefs.length - 1];
|
|
1780
1784
|
const pStartTime = (i == 0) ? startTime : pPreviousReference.endTime;
|
|
1781
|
-
|
|
1782
|
-
//
|
|
1783
|
-
//
|
|
1785
|
+
|
|
1786
|
+
// If DURATION is missing from this partial segment, use the target
|
|
1787
|
+
// partial duration from the top of the playlist, which is a required
|
|
1788
|
+
// attribute for content with partial segments.
|
|
1789
|
+
const pDuration = Number(item.getAttributeValue('DURATION')) ||
|
|
1790
|
+
this.partialTargetDuration_;
|
|
1791
|
+
|
|
1792
|
+
// If for some reason we have neither an explicit duration, nor a target
|
|
1793
|
+
// partial duration, we should SKIP this partial segment to avoid
|
|
1794
|
+
// duplicating content in the presentation timeline.
|
|
1795
|
+
if (!pDuration) {
|
|
1796
|
+
continue;
|
|
1797
|
+
}
|
|
1798
|
+
|
|
1784
1799
|
const pEndTime = pStartTime + pDuration;
|
|
1785
1800
|
|
|
1786
1801
|
let pStartByte = 0;
|
package/lib/media/drm_engine.js
CHANGED
|
@@ -1372,6 +1372,9 @@ shaka.media.DrmEngine = class {
|
|
|
1372
1372
|
}
|
|
1373
1373
|
return;
|
|
1374
1374
|
}
|
|
1375
|
+
if (this.destroyer_.destroyed()) {
|
|
1376
|
+
return;
|
|
1377
|
+
}
|
|
1375
1378
|
|
|
1376
1379
|
const updateEvent = new shaka.util.FakeEvent('drmsessionupdate');
|
|
1377
1380
|
this.playerInterface_.onEvent(updateEvent);
|
|
@@ -93,6 +93,9 @@ shaka.media.PresentationTimeline = class {
|
|
|
93
93
|
* @private {number}
|
|
94
94
|
*/
|
|
95
95
|
this.availabilityTimeOffset_ = 0;
|
|
96
|
+
|
|
97
|
+
/** @private {boolean} */
|
|
98
|
+
this.startTimeLocked_ = false;
|
|
96
99
|
}
|
|
97
100
|
|
|
98
101
|
|
|
@@ -229,7 +232,8 @@ shaka.media.PresentationTimeline = class {
|
|
|
229
232
|
this.maxSegmentEndTime_ =
|
|
230
233
|
Math.max(this.maxSegmentEndTime_, lastReferenceEndTime);
|
|
231
234
|
|
|
232
|
-
if (this.presentationStartTime_ != null && this.autoCorrectDrift_
|
|
235
|
+
if (this.presentationStartTime_ != null && this.autoCorrectDrift_ &&
|
|
236
|
+
!this.startTimeLocked_) {
|
|
233
237
|
// Since we have explicit segment end times, calculate a presentation
|
|
234
238
|
// start based on them. This start time accounts for drift.
|
|
235
239
|
// Date.now() is in milliseconds, from which we compute "now" in seconds.
|
|
@@ -243,6 +247,25 @@ shaka.media.PresentationTimeline = class {
|
|
|
243
247
|
}
|
|
244
248
|
|
|
245
249
|
|
|
250
|
+
/**
|
|
251
|
+
* Lock the presentation timeline's start time. After this is called, no
|
|
252
|
+
* further adjustments to presentationStartTime_ will be permitted.
|
|
253
|
+
*
|
|
254
|
+
* This should be called after all Periods have been parsed, and all calls to
|
|
255
|
+
* notifySegments() from the initial manifest parse have been made.
|
|
256
|
+
*
|
|
257
|
+
* Without this, we can get assertion failures in SegmentIndex for certain
|
|
258
|
+
* DAI content. If DAI adds ad segments to the manifest faster than
|
|
259
|
+
* real-time, adjustments to presentationStartTime_ can cause availability
|
|
260
|
+
* windows to jump around on updates.
|
|
261
|
+
*
|
|
262
|
+
* @export
|
|
263
|
+
*/
|
|
264
|
+
lockStartTime() {
|
|
265
|
+
this.startTimeLocked_ = true;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
|
|
246
269
|
/**
|
|
247
270
|
* Gives PresentationTimeline a Stream's minimum segment start time.
|
|
248
271
|
*
|
package/lib/player.js
CHANGED
|
@@ -6634,7 +6634,7 @@ shaka.Player.TYPICAL_BUFFERING_THRESHOLD_ = 0.5;
|
|
|
6634
6634
|
* @define {string} A version number taken from git at compile time.
|
|
6635
6635
|
* @export
|
|
6636
6636
|
*/
|
|
6637
|
-
shaka.Player.version = 'v3.3.
|
|
6637
|
+
shaka.Player.version = 'v3.3.8-uncompiled';
|
|
6638
6638
|
|
|
6639
6639
|
// Initialize the deprecation system using the version string we just set
|
|
6640
6640
|
// on the player.
|
|
@@ -39,6 +39,7 @@ shaka.polyfill.MediaCapabilities = class {
|
|
|
39
39
|
// Browsers.
|
|
40
40
|
if (!shaka.util.Platform.isChromecast() &&
|
|
41
41
|
!shaka.util.Platform.isApple() &&
|
|
42
|
+
!shaka.util.Platform.isPS4() &&
|
|
42
43
|
!shaka.util.Platform.isPS5() &&
|
|
43
44
|
navigator.mediaCapabilities) {
|
|
44
45
|
shaka.log.info(
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
goog.provide('shaka.polyfill.VideoPlaybackQuality');
|
|
8
8
|
|
|
9
9
|
goog.require('shaka.polyfill');
|
|
10
|
+
goog.require('shaka.util.Platform');
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
/**
|
|
@@ -33,7 +34,8 @@ shaka.polyfill.VideoPlaybackQuality = class {
|
|
|
33
34
|
return;
|
|
34
35
|
}
|
|
35
36
|
|
|
36
|
-
if ('webkitDroppedFrameCount' in proto
|
|
37
|
+
if ('webkitDroppedFrameCount' in proto ||
|
|
38
|
+
shaka.util.Platform.isWebOS3()) {
|
|
37
39
|
proto.getVideoPlaybackQuality =
|
|
38
40
|
shaka.polyfill.VideoPlaybackQuality.webkit_;
|
|
39
41
|
}
|
package/lib/util/mime_utils.js
CHANGED
|
@@ -8,6 +8,7 @@ goog.provide('shaka.util.MimeUtils');
|
|
|
8
8
|
|
|
9
9
|
goog.require('shaka.dependencies');
|
|
10
10
|
goog.require('shaka.media.Transmuxer');
|
|
11
|
+
goog.require('shaka.util.ManifestParserUtils');
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* @summary A set of utility functions for dealing with MIME types.
|
|
@@ -32,6 +33,8 @@ shaka.util.MimeUtils = class {
|
|
|
32
33
|
/**
|
|
33
34
|
* Takes a MIME type and a codecs string and produces the full MIME
|
|
34
35
|
* type. If it's a transport stream, convert its codecs to MP4 codecs.
|
|
36
|
+
* Otherwise for multiplexed content, convert the video MIME types to
|
|
37
|
+
* their audio equivalents if the content type is audio.
|
|
35
38
|
*
|
|
36
39
|
* @param {string} mimeType
|
|
37
40
|
* @param {string} codecs
|
|
@@ -40,13 +43,19 @@ shaka.util.MimeUtils = class {
|
|
|
40
43
|
*/
|
|
41
44
|
static getFullOrConvertedType(mimeType, codecs, contentType) {
|
|
42
45
|
const fullMimeType = shaka.util.MimeUtils.getFullType(mimeType, codecs);
|
|
46
|
+
const ContentType = shaka.util.ManifestParserUtils.ContentType;
|
|
43
47
|
|
|
44
|
-
if (
|
|
45
|
-
|
|
46
|
-
|
|
48
|
+
if (shaka.media.Transmuxer.isTsContainer(fullMimeType)) {
|
|
49
|
+
if (shaka.dependencies.muxjs()) {
|
|
50
|
+
return shaka.media.Transmuxer.convertTsCodecs(
|
|
51
|
+
contentType, fullMimeType);
|
|
52
|
+
}
|
|
53
|
+
} else if (contentType == ContentType.AUDIO) {
|
|
54
|
+
// video/mp2t is the correct mime type for TS audio, so only replace the
|
|
55
|
+
// word "video" with "audio" for non-TS audio content.
|
|
56
|
+
return fullMimeType.replace('video', 'audio');
|
|
47
57
|
}
|
|
48
|
-
|
|
49
|
-
return shaka.media.Transmuxer.convertTsCodecs(contentType, fullMimeType);
|
|
58
|
+
return fullMimeType;
|
|
50
59
|
}
|
|
51
60
|
|
|
52
61
|
|
package/lib/util/platform.js
CHANGED
|
@@ -142,6 +142,18 @@ shaka.util.Platform = class {
|
|
|
142
142
|
return shaka.util.Platform.userAgentContains_('Web0S');
|
|
143
143
|
}
|
|
144
144
|
|
|
145
|
+
/**
|
|
146
|
+
* Check if the current platform is a WebOS 3.
|
|
147
|
+
*
|
|
148
|
+
* @return {boolean}
|
|
149
|
+
*/
|
|
150
|
+
static isWebOS3() {
|
|
151
|
+
// See: http://webostv.developer.lge.com/discover/specifications/web-engine/
|
|
152
|
+
return shaka.util.Platform.userAgentContains_('Web0S') &&
|
|
153
|
+
shaka.util.Platform.userAgentContains_(
|
|
154
|
+
'Chrome/38.0.2125.122 Safari/537.36');
|
|
155
|
+
}
|
|
156
|
+
|
|
145
157
|
/**
|
|
146
158
|
* Check if the current platform is a Google Chromecast.
|
|
147
159
|
*
|
|
@@ -175,7 +187,9 @@ shaka.util.Platform = class {
|
|
|
175
187
|
*/
|
|
176
188
|
static isApple() {
|
|
177
189
|
return !!navigator.vendor && navigator.vendor.includes('Apple') &&
|
|
178
|
-
!shaka.util.Platform.isTizen()
|
|
190
|
+
!shaka.util.Platform.isTizen() &&
|
|
191
|
+
!shaka.util.Platform.isEOS() &&
|
|
192
|
+
!shaka.util.Platform.isPS4();
|
|
179
193
|
}
|
|
180
194
|
|
|
181
195
|
/**
|
|
@@ -191,6 +205,13 @@ shaka.util.Platform = class {
|
|
|
191
205
|
return shaka.util.Platform.userAgentContains_('PlayStation 5');
|
|
192
206
|
}
|
|
193
207
|
|
|
208
|
+
/**
|
|
209
|
+
* Check if the current platform is Playstation 4.
|
|
210
|
+
*/
|
|
211
|
+
static isPS4() {
|
|
212
|
+
return shaka.util.Platform.userAgentContains_('PlayStation 4');
|
|
213
|
+
}
|
|
214
|
+
|
|
194
215
|
/**
|
|
195
216
|
* Returns a major version number for Safari, or Safari-based iOS browsers.
|
|
196
217
|
*
|
|
@@ -228,6 +249,25 @@ shaka.util.Platform = class {
|
|
|
228
249
|
return null;
|
|
229
250
|
}
|
|
230
251
|
|
|
252
|
+
/**
|
|
253
|
+
* Check if the current platform is Apple Safari
|
|
254
|
+
* or Safari-based iOS browsers.
|
|
255
|
+
*
|
|
256
|
+
* @return {boolean}
|
|
257
|
+
*/
|
|
258
|
+
static isSafari() {
|
|
259
|
+
return !!shaka.util.Platform.safariVersion();
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Check if the current platform is an EOS set-top box.
|
|
264
|
+
*
|
|
265
|
+
* @return {boolean}
|
|
266
|
+
*/
|
|
267
|
+
static isEOS() {
|
|
268
|
+
return shaka.util.Platform.userAgentContains_('PC=EOS');
|
|
269
|
+
}
|
|
270
|
+
|
|
231
271
|
/**
|
|
232
272
|
* Guesses if the platform is a mobile one (iOS or Android).
|
|
233
273
|
*
|
package/lib/util/stream_utils.js
CHANGED
|
@@ -981,6 +981,7 @@ shaka.util.StreamUtils = class {
|
|
|
981
981
|
track.channelsCount = audio.channelsCount;
|
|
982
982
|
track.audioSamplingRate = audio.audioSamplingRate;
|
|
983
983
|
track.audioBandwidth = audio.bandwidth || null;
|
|
984
|
+
track.spatialAudio = audio.spatialAudio;
|
|
984
985
|
track.label = audio.label;
|
|
985
986
|
track.audioRoles = audio.roles;
|
|
986
987
|
}
|
package/lib/util/string_utils.js
CHANGED
|
@@ -11,6 +11,7 @@ goog.require('shaka.log');
|
|
|
11
11
|
goog.require('shaka.util.BufferUtils');
|
|
12
12
|
goog.require('shaka.util.Error');
|
|
13
13
|
goog.require('shaka.util.Lazy');
|
|
14
|
+
goog.require('shaka.util.Platform');
|
|
14
15
|
|
|
15
16
|
|
|
16
17
|
/**
|
|
@@ -36,19 +37,38 @@ shaka.util.StringUtils = class {
|
|
|
36
37
|
if (uint8[0] == 0xef && uint8[1] == 0xbb && uint8[2] == 0xbf) {
|
|
37
38
|
uint8 = uint8.subarray(3);
|
|
38
39
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
40
|
+
if (window.TextDecoder && !shaka.util.Platform.isPS4()) {
|
|
41
|
+
// Use the TextDecoder interface to decode the text. This has the
|
|
42
|
+
// advantage compared to the previously-standard decodeUriComponent that
|
|
43
|
+
// it will continue parsing even if it finds an invalid UTF8 character,
|
|
44
|
+
// rather than stop and throw an error.
|
|
45
|
+
const utf8decoder = new TextDecoder();
|
|
46
|
+
const decoded = utf8decoder.decode(uint8);
|
|
47
|
+
if (decoded.includes('\uFFFD')) {
|
|
48
|
+
shaka.log.alwaysError('Decoded string contains an "unknown character' +
|
|
49
|
+
'" codepoint. That probably means the UTF8 ' +
|
|
50
|
+
'encoding was incorrect!');
|
|
51
|
+
}
|
|
52
|
+
return decoded;
|
|
53
|
+
} else {
|
|
54
|
+
// http://stackoverflow.com/a/13691499
|
|
55
|
+
const utf8 = shaka.util.StringUtils.fromCharCode(uint8);
|
|
56
|
+
// This converts each character in the string to an escape sequence. If
|
|
57
|
+
// the character is in the ASCII range, it is not converted; otherwise it
|
|
58
|
+
// is converted to a URI escape sequence.
|
|
59
|
+
// Example: '\x67\x35\xe3\x82\xac' -> 'g#%E3%82%AC'
|
|
60
|
+
const escaped = escape(utf8);
|
|
61
|
+
// Decode the escaped sequence. This will interpret UTF-8 sequences into
|
|
62
|
+
// the correct character.
|
|
63
|
+
// Example: 'g#%E3%82%AC' -> 'g#€'
|
|
64
|
+
try {
|
|
65
|
+
return decodeURIComponent(escaped);
|
|
66
|
+
} catch (e) {
|
|
67
|
+
throw new shaka.util.Error(
|
|
68
|
+
shaka.util.Error.Severity.CRITICAL, shaka.util.Error.Category.TEXT,
|
|
69
|
+
shaka.util.Error.Code.BAD_ENCODING);
|
|
70
|
+
}
|
|
50
71
|
}
|
|
51
|
-
return decoded;
|
|
52
72
|
}
|
|
53
73
|
|
|
54
74
|
|
|
@@ -141,8 +161,30 @@ shaka.util.StringUtils = class {
|
|
|
141
161
|
* @export
|
|
142
162
|
*/
|
|
143
163
|
static toUTF8(str) {
|
|
144
|
-
|
|
145
|
-
|
|
164
|
+
if (window.TextEncoder && !shaka.util.Platform.isPS4()) {
|
|
165
|
+
const utf8Encoder = new TextEncoder();
|
|
166
|
+
return shaka.util.BufferUtils.toArrayBuffer(utf8Encoder.encode(str));
|
|
167
|
+
} else {
|
|
168
|
+
// http://stackoverflow.com/a/13691499
|
|
169
|
+
// Converts the given string to a URI encoded string. If a character
|
|
170
|
+
// falls in the ASCII range, it is not converted; otherwise it will be
|
|
171
|
+
// converted to a series of URI escape sequences according to UTF-8.
|
|
172
|
+
// Example: 'g#€' -> 'g#%E3%82%AC'
|
|
173
|
+
const encoded = encodeURIComponent(str);
|
|
174
|
+
// Convert each escape sequence individually into a character. Each
|
|
175
|
+
// escape sequence is interpreted as a code-point, so if an escape
|
|
176
|
+
// sequence happens to be part of a multi-byte sequence, each byte will
|
|
177
|
+
// be converted to a single character.
|
|
178
|
+
// Example: 'g#%E3%82%AC' -> '\x67\x35\xe3\x82\xac'
|
|
179
|
+
const utf8 = unescape(encoded);
|
|
180
|
+
|
|
181
|
+
const result = new Uint8Array(utf8.length);
|
|
182
|
+
for (let i = 0; i < utf8.length; i++) {
|
|
183
|
+
const item = utf8[i];
|
|
184
|
+
result[i] = item.charCodeAt(0);
|
|
185
|
+
}
|
|
186
|
+
return shaka.util.BufferUtils.toArrayBuffer(result);
|
|
187
|
+
}
|
|
146
188
|
}
|
|
147
189
|
|
|
148
190
|
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Maintained Shaka Player Branches
|
|
2
|
+
|
|
3
|
+
We are currently maintaining the following branches of Shaka Player:
|
|
4
|
+
|
|
5
|
+
- v4.1 (latest)
|
|
6
|
+
- v4.0 (previous)
|
|
7
|
+
- v3.3 (LTS until April 30, 2023)
|
|
8
|
+
- v3.2 (in use by the Cast Application Framework)
|
|
9
|
+
|
|
10
|
+
Other branches are no longer receiving bug fixes, and we recommend you upgrade
|
|
11
|
+
to a maintained branch. For details on upgrading, please see our
|
|
12
|
+
[upgrade guide](https://shaka-player-demo.appspot.com/docs/api/tutorial-upgrade.html).
|
|
13
|
+
|
|
14
|
+
For more information on how these branches are chosen, please refer to our
|
|
15
|
+
[Branch Maintenance Policy](https://shaka-project.github.io/maintenance/shaka-player.html#branch-maintenance-policy).
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shaka-player",
|
|
3
3
|
"description": "DASH/EME video player library",
|
|
4
|
-
"version": "3.3.
|
|
4
|
+
"version": "3.3.8",
|
|
5
5
|
"homepage": "https://github.com/shaka-project/shaka-player",
|
|
6
6
|
"author": "Google",
|
|
7
7
|
"maintainers": [
|
|
@@ -27,7 +27,6 @@
|
|
|
27
27
|
"eslint-config-google": "^0.14.0",
|
|
28
28
|
"eslint-plugin-shaka-rules": "file:./build/eslint-plugin-shaka-rules",
|
|
29
29
|
"esprima": "^4.0.1",
|
|
30
|
-
"fastestsmallesttextencoderdecoder": "^1.0.22",
|
|
31
30
|
"fontfaceonload": "^1.0.2",
|
|
32
31
|
"google-closure-compiler-java": "^20220301.0.0",
|
|
33
32
|
"google-closure-deps": "https://gitpkg.now.sh/google/closure-library/closure-deps?d7736da6",
|
|
@@ -50,7 +49,7 @@
|
|
|
50
49
|
"less": "https://gitpkg.now.sh/joeyparrish/less.js/packages/less?28c63a43",
|
|
51
50
|
"less-plugin-clean-css": "github:austingardner/less-plugin-clean-css#4e9e77bf",
|
|
52
51
|
"material-design-lite": "^1.3.0",
|
|
53
|
-
"mux.js": "^
|
|
52
|
+
"mux.js": "^6.2.0",
|
|
54
53
|
"open-sans-fonts": "^1.6.2",
|
|
55
54
|
"postcss-less": "^6.0.0",
|
|
56
55
|
"pwacompat": "^2.0.17",
|
|
@@ -71,7 +70,6 @@
|
|
|
71
70
|
"dialog-polyfill/dist/dialog-polyfill.js",
|
|
72
71
|
"eme-encryption-scheme-polyfill/index.js",
|
|
73
72
|
"es6-promise-polyfill/promise.min.js",
|
|
74
|
-
"fastestsmallesttextencoderdecoder/EncoderDecoderTogether.min.js",
|
|
75
73
|
"google-closure-library/closure/goog/base.js",
|
|
76
74
|
"less/dist/less.js",
|
|
77
75
|
"material-design-lite/dist/material.indigo-blue.min.css",
|
|
@@ -632,11 +632,13 @@ describe('HlsParser live', () => {
|
|
|
632
632
|
expect(ref.startTime).not.toBeLessThan(rolloverOffset);
|
|
633
633
|
});
|
|
634
634
|
|
|
635
|
+
// Test for https://github.com/shaka-project/shaka-player/issues/4223
|
|
635
636
|
it('parses streams with partial and preload hinted segments', async () => {
|
|
636
637
|
playerInterface.isLowLatencyMode = () => true;
|
|
637
638
|
const mediaWithPartialSegments = [
|
|
638
639
|
'#EXTM3U\n',
|
|
639
640
|
'#EXT-X-TARGETDURATION:5\n',
|
|
641
|
+
'#EXT-X-PART-INF:PART-TARGET=1.5\n',
|
|
640
642
|
'#EXT-X-MAP:URI="init.mp4",BYTERANGE="616@0"\n',
|
|
641
643
|
'#EXT-X-MEDIA-SEQUENCE:0\n',
|
|
642
644
|
// ref includes partialRef, partialRef2
|
|
@@ -670,6 +672,11 @@ describe('HlsParser live', () => {
|
|
|
670
672
|
segmentDataStartTime + 4, /* baseUri= */ '', /* startByte= */ 200,
|
|
671
673
|
/* endByte= */ 429);
|
|
672
674
|
|
|
675
|
+
const ref = ManifestParser.makeReference(
|
|
676
|
+
'test:/main.mp4', segmentDataStartTime, segmentDataStartTime + 4,
|
|
677
|
+
/* baseUri= */ '', /* startByte= */ 0, /* endByte= */ 429,
|
|
678
|
+
/* timestampOffset= */ 0, [partialRef, partialRef2]);
|
|
679
|
+
|
|
673
680
|
const partialRef3 = ManifestParser.makeReference(
|
|
674
681
|
'test:/partial.mp4', segmentDataStartTime + 4,
|
|
675
682
|
segmentDataStartTime + 6,
|
|
@@ -679,17 +686,12 @@ describe('HlsParser live', () => {
|
|
|
679
686
|
// so its startTime and endTime are the same.
|
|
680
687
|
const preloadRef = ManifestParser.makeReference(
|
|
681
688
|
'test:/partial.mp4', segmentDataStartTime + 6,
|
|
682
|
-
segmentDataStartTime +
|
|
689
|
+
segmentDataStartTime + 7.5,
|
|
683
690
|
/* baseUri= */ '', /* startByte= */ 210, /* endByte= */ null);
|
|
684
691
|
|
|
685
|
-
const ref = ManifestParser.makeReference(
|
|
686
|
-
'test:/main.mp4', segmentDataStartTime, segmentDataStartTime + 4,
|
|
687
|
-
/* baseUri= */ '', /* startByte= */ 0, /* endByte= */ 429,
|
|
688
|
-
/* timestampOffset= */ 0, [partialRef, partialRef2]);
|
|
689
|
-
|
|
690
692
|
// ref2 is not fully published yet, so it doesn't have a segment uri.
|
|
691
693
|
const ref2 = ManifestParser.makeReference(
|
|
692
|
-
'', segmentDataStartTime + 4, segmentDataStartTime +
|
|
694
|
+
'', segmentDataStartTime + 4, segmentDataStartTime + 7.5,
|
|
693
695
|
/* baseUri= */ '', /* startByte= */ 0, /* endByte= */ null,
|
|
694
696
|
/* timestampOffset= */ 0, [partialRef3, preloadRef]);
|
|
695
697
|
|
|
@@ -699,6 +701,56 @@ describe('HlsParser live', () => {
|
|
|
699
701
|
ManifestParser.verifySegmentIndex(video, [ref, ref2]);
|
|
700
702
|
});
|
|
701
703
|
|
|
704
|
+
// Test for https://github.com/shaka-project/shaka-player/issues/4223
|
|
705
|
+
it('ignores preload hinted segments without target duration', async () => {
|
|
706
|
+
playerInterface.isLowLatencyMode = () => true;
|
|
707
|
+
|
|
708
|
+
// Missing PART-TARGET, so preload hints are skipped.
|
|
709
|
+
const mediaWithPartialSegments = [
|
|
710
|
+
'#EXTM3U\n',
|
|
711
|
+
'#EXT-X-TARGETDURATION:5\n',
|
|
712
|
+
'#EXT-X-MAP:URI="init.mp4",BYTERANGE="616@0"\n',
|
|
713
|
+
'#EXT-X-MEDIA-SEQUENCE:0\n',
|
|
714
|
+
'#EXTINF:4,\n',
|
|
715
|
+
// ref1
|
|
716
|
+
'main.mp4\n',
|
|
717
|
+
// ref2 includes partialRef, but not preloadRef
|
|
718
|
+
// partialRef
|
|
719
|
+
'#EXT-X-PART:DURATION=2,URI="partial.mp4",BYTERANGE=210@0\n',
|
|
720
|
+
// preloadRef
|
|
721
|
+
'#EXT-X-PRELOAD-HINT:TYPE=PART,URI="partial.mp4",BYTERANGE-START=210\n',
|
|
722
|
+
].join('');
|
|
723
|
+
|
|
724
|
+
fakeNetEngine
|
|
725
|
+
.setResponseText('test:/master', master)
|
|
726
|
+
.setResponseText('test:/video', mediaWithPartialSegments)
|
|
727
|
+
.setResponseValue('test:/init.mp4', initSegmentData)
|
|
728
|
+
.setResponseValue('test:/main.mp4', segmentData)
|
|
729
|
+
.setResponseValue('test:/partial.mp4', segmentData)
|
|
730
|
+
.setResponseValue('test:/partial2.mp4', segmentData);
|
|
731
|
+
|
|
732
|
+
const ref1 = ManifestParser.makeReference(
|
|
733
|
+
'test:/main.mp4', segmentDataStartTime, segmentDataStartTime + 4,
|
|
734
|
+
/* baseUri= */ '', /* startByte= */ 0, /* endByte= */ null,
|
|
735
|
+
/* timestampOffset= */ 0, []);
|
|
736
|
+
|
|
737
|
+
const partialRef = ManifestParser.makeReference(
|
|
738
|
+
'test:/partial.mp4', segmentDataStartTime + 4,
|
|
739
|
+
segmentDataStartTime + 6,
|
|
740
|
+
/* baseUri= */ '', /* startByte= */ 0, /* endByte= */ 209);
|
|
741
|
+
|
|
742
|
+
// ref2 is not fully published yet, so it doesn't have a segment uri.
|
|
743
|
+
const ref2 = ManifestParser.makeReference(
|
|
744
|
+
'', segmentDataStartTime + 4, segmentDataStartTime + 6,
|
|
745
|
+
/* baseUri= */ '', /* startByte= */ 0, /* endByte= */ 209,
|
|
746
|
+
/* timestampOffset= */ 0, [partialRef]);
|
|
747
|
+
|
|
748
|
+
const manifest = await parser.start('test:/master', playerInterface);
|
|
749
|
+
const video = manifest.variants[0].video;
|
|
750
|
+
await video.createSegmentIndex();
|
|
751
|
+
ManifestParser.verifySegmentIndex(video, [ref1, ref2]);
|
|
752
|
+
});
|
|
753
|
+
|
|
702
754
|
// Test for https://github.com/shaka-project/shaka-player/issues/4185
|
|
703
755
|
it('does not fail on preload hints with LL mode off', async () => {
|
|
704
756
|
// LL mode must be off for this test!
|
|
@@ -708,6 +760,7 @@ describe('HlsParser live', () => {
|
|
|
708
760
|
'#EXTM3U\n',
|
|
709
761
|
'#EXT-X-TARGETDURATION:5\n',
|
|
710
762
|
'#EXT-X-MAP:URI="init.mp4",BYTERANGE="616@0"\n',
|
|
763
|
+
'#EXT-X-PART-INF:PART-TARGET=1.5\n',
|
|
711
764
|
'#EXTINF:4,\n',
|
|
712
765
|
'main.mp4\n',
|
|
713
766
|
'#EXT-X-PART:DURATION=2,URI="partial.mp4",BYTERANGE=210@0\n',
|
package/ui/less/containers.less
CHANGED
|
@@ -161,7 +161,7 @@
|
|
|
161
161
|
/* Consistent margins (external) and padding (internal) between controls. */
|
|
162
162
|
.bottom-panels-elements-margin();
|
|
163
163
|
|
|
164
|
-
padding: 0;
|
|
164
|
+
padding: 0 5px;
|
|
165
165
|
|
|
166
166
|
/* Transparent backgrounds, no borders, and a pointer when you mouse over
|
|
167
167
|
* them. */
|
package/ui/less/general.less
CHANGED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
<!--
|
|
2
|
-
Please remember to:
|
|
3
|
-
|
|
4
|
-
1. Use Conventional Commits syntax (fix: ..., feat: ..., etc.) in commits and
|
|
5
|
-
PR title (https://www.conventionalcommits.org/)
|
|
6
|
-
2. Tag any related or fixed issues ("Issue #123", "Closes #420")
|
|
7
|
-
3. Sign the Google CLA if you haven't (https://cla.developers.google.com)
|
|
8
|
-
|
|
9
|
-
You may delete this comment from the PR description.
|
|
10
|
-
-->
|
package/app-engine/README.md
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
# Google App Engine Code
|
|
2
|
-
|
|
3
|
-
This folder contains source code for the services we run on Google App Engine
|
|
4
|
-
(appspot.com).
|
|
5
|
-
|
|
6
|
-
- shaka-player-demo: Our hosted demo on https://shaka-player-demo.appspot.com/
|
|
7
|
-
|
|
8
|
-
- demo-version-index: An index of Shaka Player releases and demos, hosted at
|
|
9
|
-
https://index-dot-shaka-player-demo.appspot.com/
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
# Google App Engine Version Index
|
|
2
|
-
|
|
3
|
-
This folder contains everything necessary to host an index of Shaka Player
|
|
4
|
-
releases and demos at https://index-dot-shaka-player-demo.appspot.com/
|
|
5
|
-
|
|
6
|
-
- app.yaml: App Engine config file. Defines the runtime (Python 3).
|
|
7
|
-
|
|
8
|
-
- main.py: A python service that queries available versions and generates the
|
|
9
|
-
index from a template.
|
|
10
|
-
|
|
11
|
-
- requirements.txt: Used by App Engine to install the necessary Python server
|
|
12
|
-
requirements (Flask, App Engine API).
|
|
13
|
-
|
|
14
|
-
- templates/index.html: A Jinja2 template used to generate the index HTML.
|