shaka-player 4.3.11 → 4.3.13

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.
Files changed (62) hide show
  1. package/.github/workflows/deflake.yaml +8 -5
  2. package/.github/workflows/release-please.yaml +47 -7
  3. package/.github/workflows/shaka-bot-commands/command-test.sh +1 -1
  4. package/CHANGELOG.md +34 -0
  5. package/CONTRIBUTORS +1 -0
  6. package/demo/common/asset.js +5 -0
  7. package/demo/common/assets.js +16 -1
  8. package/demo/common/message_ids.js +1 -0
  9. package/demo/custom.js +5 -5
  10. package/demo/locales/en.json +1 -0
  11. package/demo/locales/source.json +4 -0
  12. package/demo/main.js +1 -1
  13. package/dist/demo.compiled.debug.js +58 -56
  14. package/dist/demo.compiled.debug.map +3 -3
  15. package/dist/demo.compiled.js +58 -56
  16. package/dist/demo.compiled.map +3 -3
  17. package/dist/locales.js +30 -30
  18. package/dist/receiver.compiled.debug.js +24 -22
  19. package/dist/receiver.compiled.debug.map +3 -3
  20. package/dist/receiver.compiled.js +24 -22
  21. package/dist/receiver.compiled.map +3 -3
  22. package/dist/shaka-player.compiled.d.ts +258 -258
  23. package/dist/shaka-player.compiled.debug.d.ts +258 -258
  24. package/dist/shaka-player.compiled.debug.externs.js +6 -4
  25. package/dist/shaka-player.compiled.debug.js +58 -59
  26. package/dist/shaka-player.compiled.debug.map +3 -3
  27. package/dist/shaka-player.compiled.externs.js +6 -4
  28. package/dist/shaka-player.compiled.js +700 -699
  29. package/dist/shaka-player.compiled.map +3 -3
  30. package/dist/shaka-player.ui.d.ts +302 -302
  31. package/dist/shaka-player.ui.debug.d.ts +302 -302
  32. package/dist/shaka-player.ui.debug.externs.js +6 -4
  33. package/dist/shaka-player.ui.debug.js +205 -206
  34. package/dist/shaka-player.ui.debug.map +3 -3
  35. package/dist/shaka-player.ui.externs.js +6 -4
  36. package/dist/shaka-player.ui.js +867 -866
  37. package/dist/shaka-player.ui.map +3 -3
  38. package/docs/tutorials/faq.md +1 -1
  39. package/docs/tutorials/offline.md +1 -1
  40. package/lib/dash/dash_parser.js +4 -1
  41. package/lib/hls/hls_parser.js +60 -24
  42. package/lib/media/segment_reference.js +11 -5
  43. package/lib/media/streaming_engine.js +15 -25
  44. package/lib/player.js +8 -57
  45. package/lib/text/ttml_text_parser.js +2 -1
  46. package/lib/text/ui_text_displayer.js +49 -3
  47. package/lib/util/cmcd_manager.js +6 -1
  48. package/lib/util/manifest_parser_utils.js +10 -4
  49. package/lib/util/player_configuration.js +2 -2
  50. package/lib/util/stream_utils.js +13 -11
  51. package/lib/util/ts_parser.js +3 -3
  52. package/package.json +2 -2
  53. package/test/dash/dash_parser_manifest_unit.js +5 -0
  54. package/test/dash/dash_parser_segment_base_unit.js +5 -0
  55. package/test/dash/dash_parser_segment_list_unit.js +21 -17
  56. package/test/dash/dash_parser_segment_template_unit.js +5 -0
  57. package/test/hls/hls_live_unit.js +33 -0
  58. package/test/hls/hls_parser_unit.js +2 -57
  59. package/test/test/util/dash_parser_util.js +16 -7
  60. package/test/text/ttml_text_parser_unit.js +3 -4
  61. package/test/text/web_vtt_layout_integration.js +0 -1
  62. package/test/util/ts_parser_unit.js +1 -1
@@ -1442,22 +1442,23 @@ shaka.util.StreamUtils = class {
1442
1442
 
1443
1443
  /**
1444
1444
  * Chooses streams according to the given config.
1445
+ * Works both for Stream and Track types due to their similarities.
1445
1446
  *
1446
- * @param {!Array.<shaka.extern.Stream>} streams
1447
+ * @param {!Array<!shaka.extern.Stream>|!Array<!shaka.extern.Track>} streams
1447
1448
  * @param {string} preferredLanguage
1448
1449
  * @param {string} preferredRole
1449
1450
  * @param {boolean} preferredForced
1450
- * @return {!Array.<!shaka.extern.Stream>}
1451
+ * @return {!Array<!shaka.extern.Stream>|!Array<!shaka.extern.Track>}
1451
1452
  */
1452
1453
  static filterStreamsByLanguageAndRole(
1453
1454
  streams, preferredLanguage, preferredRole, preferredForced) {
1454
1455
  const LanguageUtils = shaka.util.LanguageUtils;
1455
1456
 
1456
- /** @type {!Array.<!shaka.extern.Stream>} */
1457
+ /** @type {!Array<!shaka.extern.Stream>|!Array<!shaka.extern.Track>} */
1457
1458
  let chosen = streams;
1458
1459
 
1459
1460
  // Start with the set of primary streams.
1460
- /** @type {!Array.<!shaka.extern.Stream>} */
1461
+ /** @type {!Array<!shaka.extern.Stream>|!Array<!shaka.extern.Track>} */
1461
1462
  const primary = streams.filter((stream) => {
1462
1463
  return stream.primary;
1463
1464
  });
@@ -1497,7 +1498,7 @@ shaka.util.StreamUtils = class {
1497
1498
 
1498
1499
  // Now refine the choice based on role preference.
1499
1500
  if (preferredRole) {
1500
- const roleMatches = shaka.util.StreamUtils.filterTextStreamsByRole_(
1501
+ const roleMatches = shaka.util.StreamUtils.filterStreamsByRole_(
1501
1502
  chosen, preferredRole);
1502
1503
  if (roleMatches.length) {
1503
1504
  return roleMatches;
@@ -1525,20 +1526,21 @@ shaka.util.StreamUtils = class {
1525
1526
  if (!allRoles.length) {
1526
1527
  return chosen;
1527
1528
  }
1528
- return shaka.util.StreamUtils.filterTextStreamsByRole_(chosen, allRoles[0]);
1529
+ return shaka.util.StreamUtils.filterStreamsByRole_(chosen, allRoles[0]);
1529
1530
  }
1530
1531
 
1531
1532
 
1532
1533
  /**
1533
- * Filter text Streams by role.
1534
+ * Filter Streams by role.
1535
+ * Works both for Stream and Track types due to their similarities.
1534
1536
  *
1535
- * @param {!Array.<shaka.extern.Stream>} textStreams
1537
+ * @param {!Array<!shaka.extern.Stream>|!Array<!shaka.extern.Track>} streams
1536
1538
  * @param {string} preferredRole
1537
- * @return {!Array.<shaka.extern.Stream>}
1539
+ * @return {!Array<!shaka.extern.Stream>|!Array<!shaka.extern.Track>}
1538
1540
  * @private
1539
1541
  */
1540
- static filterTextStreamsByRole_(textStreams, preferredRole) {
1541
- return textStreams.filter((stream) => {
1542
+ static filterStreamsByRole_(streams, preferredRole) {
1543
+ return streams.filter((stream) => {
1542
1544
  return stream.roles.includes(preferredRole);
1543
1545
  });
1544
1546
  }
@@ -122,15 +122,15 @@ shaka.util.TsParser = class {
122
122
  // for example
123
123
  // NOTE this is only the PID of the track as found in TS,
124
124
  // but we are not using this for MP4 track IDs.
125
- if (this.videoPid_ == null) {
125
+ if (parsedPIDs.video != -1) {
126
126
  this.videoPid_ = parsedPIDs.video;
127
127
  this.videoCodec_ = parsedPIDs.videoCodec;
128
128
  }
129
- if (this.audioPid_ == null) {
129
+ if (parsedPIDs.audio != -1) {
130
130
  this.audioPid_ = parsedPIDs.audio;
131
131
  this.audioCodec_ = parsedPIDs.audioCodec;
132
132
  }
133
- if (this.id3Pid_ == null) {
133
+ if (parsedPIDs.id3 != -1) {
134
134
  this.id3Pid_ = parsedPIDs.id3;
135
135
  }
136
136
 
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": "4.3.11",
4
+ "version": "4.3.13",
5
5
  "homepage": "https://github.com/shaka-project/shaka-player",
6
6
  "author": "Google",
7
7
  "maintainers": [
@@ -42,7 +42,7 @@
42
42
  "karma-coverage": "^2.2.0",
43
43
  "karma-jasmine": "^4.0.1",
44
44
  "karma-jasmine-ajax": "^0.1.13",
45
- "karma-local-wd-launcher": "^1.6.4",
45
+ "karma-local-wd-launcher": "^1.6.6",
46
46
  "karma-opera-launcher": "^1.0.0",
47
47
  "karma-sourcemap-loader": "^0.3.8",
48
48
  "karma-spec-reporter": "^0.0.34",
@@ -57,6 +57,11 @@ describe('DashParser Manifest', () => {
57
57
  };
58
58
  });
59
59
 
60
+ afterEach(() => {
61
+ // Dash parser stop is synchronous.
62
+ parser.stop();
63
+ });
64
+
60
65
  /**
61
66
  * Makes a series of tests for the given manifest type.
62
67
  *
@@ -43,6 +43,11 @@ describe('DashParser SegmentBase', () => {
43
43
  };
44
44
  });
45
45
 
46
+ afterEach(() => {
47
+ // Dash parser stop is synchronous.
48
+ parser.stop();
49
+ });
50
+
46
51
  it('requests init data for WebM', async () => {
47
52
  const source = [
48
53
  '<MPD mediaPresentationDuration="PT75S">',
@@ -351,24 +351,28 @@ describe('DashParser SegmentList', () => {
351
351
  updateDuration: () => {},
352
352
  newDrmInfo: (stream) => {},
353
353
  };
354
- const manifest = await dashParser.start('dummy://foo', playerInterface);
355
- const stream = manifest.variants[0].video;
356
- await stream.createSegmentIndex();
357
- goog.asserts.assert(stream.segmentIndex, 'Expected index to be created');
354
+ try {
355
+ const manifest = await dashParser.start('dummy://foo', playerInterface);
356
+ const stream = manifest.variants[0].video;
357
+ await stream.createSegmentIndex();
358
+ goog.asserts.assert(stream.segmentIndex, 'Expected index to be created');
358
359
 
359
- // Don't use Dash.testSegmentIndex since it uses SegmentIndex.find, which
360
- // doesn't reproduce this issue. We want to use Array.from which uses the
361
- // iterator.
362
- const expected = [
363
- ManifestParser.makeReference('s1.mp4', 0, 10, baseUri),
364
- ManifestParser.makeReference('s2.mp4', 10, 20, baseUri),
365
- ManifestParser.makeReference('s3.mp4', 20, 30, baseUri),
360
+ // Don't use Dash.testSegmentIndex since it uses SegmentIndex.find, which
361
+ // doesn't reproduce this issue. We want to use Array.from which uses
362
+ // the iterator.
363
+ const expected = [
364
+ ManifestParser.makeReference('s1.mp4', 0, 10, baseUri),
365
+ ManifestParser.makeReference('s2.mp4', 10, 20, baseUri),
366
+ ManifestParser.makeReference('s3.mp4', 20, 30, baseUri),
366
367
 
367
- ManifestParser.makeReference('s3.mp4', 30, 40, baseUri),
368
- ManifestParser.makeReference('s4.mp4', 40, 50, baseUri),
369
- ManifestParser.makeReference('s5.mp4', 50, 60, baseUri),
370
- ];
371
- const actual = Array.from(stream.segmentIndex);
372
- expect(actual).toEqual(expected);
368
+ ManifestParser.makeReference('s3.mp4', 30, 40, baseUri),
369
+ ManifestParser.makeReference('s4.mp4', 40, 50, baseUri),
370
+ ManifestParser.makeReference('s5.mp4', 50, 60, baseUri),
371
+ ];
372
+ const actual = Array.from(stream.segmentIndex);
373
+ expect(actual).toEqual(expected);
374
+ } finally {
375
+ dashParser.stop();
376
+ }
373
377
  });
374
378
  });
@@ -52,6 +52,11 @@ describe('DashParser SegmentTemplate', () => {
52
52
  };
53
53
  });
54
54
 
55
+ afterEach(() => {
56
+ // Dash parser stop is synchronous.
57
+ parser.stop();
58
+ });
59
+
55
60
  shaka.test.Dash.makeTimelineTests(
56
61
  'SegmentTemplate', 'media="s$Number$.mp4"', []);
57
62
 
@@ -501,10 +501,43 @@ describe('HlsParser live', () => {
501
501
 
502
502
  it('sets 3 times target duration as presentation delay if not configured',
503
503
  async () => {
504
+ const media = [
505
+ '#EXTM3U\n',
506
+ '#EXT-X-TARGETDURATION:5\n',
507
+ '#EXT-X-MAP:URI="init.mp4",BYTERANGE="616@0"\n',
508
+ '#EXT-X-MEDIA-SEQUENCE:0\n',
509
+ '#EXTINF:2,\n',
510
+ 'main.mp4\n',
511
+ '#EXTINF:2,\n',
512
+ 'main.mp4\n',
513
+ '#EXTINF:2,\n',
514
+ 'main.mp4\n',
515
+ '#EXTINF:2,\n',
516
+ 'main.mp4\n',
517
+ '#EXTINF:2,\n',
518
+ 'main.mp4\n',
519
+ '#EXTINF:2,\n',
520
+ 'main.mp4\n',
521
+ ].join('');
504
522
  const manifest = await testInitialManifest(master, media);
505
523
  expect(manifest.presentationTimeline.getDelay()).toBe(15);
506
524
  });
507
525
 
526
+ it('sets 1 times target duration as presentation delay if there are not enough segments', async () => { // eslint-disable-line max-len
527
+ const media = [
528
+ '#EXTM3U\n',
529
+ '#EXT-X-TARGETDURATION:5\n',
530
+ '#EXT-X-MAP:URI="init.mp4",BYTERANGE="616@0"\n',
531
+ '#EXT-X-MEDIA-SEQUENCE:0\n',
532
+ '#EXTINF:2,\n',
533
+ 'main.mp4\n',
534
+ '#EXTINF:2,\n',
535
+ 'main.mp4\n',
536
+ ].join('');
537
+ const manifest = await testInitialManifest(master, media);
538
+ expect(manifest.presentationTimeline.getDelay()).toBe(5);
539
+ });
540
+
508
541
  it('sets presentation delay for low latency mode', async () => {
509
542
  const mediaWithLowLatency = [
510
543
  '#EXTM3U\n',
@@ -1114,63 +1114,6 @@ describe('HlsParser', () => {
1114
1114
  expect(references[6].discontinuitySequence).toBe(3);
1115
1115
  });
1116
1116
 
1117
- it('sets reference timetampOffset based on discontinuity start time',
1118
- async () => {
1119
- const master = [
1120
- '#EXTM3U\n',
1121
- '#EXT-X-STREAM-INF:BANDWIDTH=2000000,CODECS="avc1"\n',
1122
- 'video\n',
1123
- ].join('');
1124
-
1125
- const media = [
1126
- '#EXTM3U\n',
1127
- '#EXT-X-VERSION:3\n',
1128
- '#EXT-X-TARGETDURATION:5\n',
1129
- '#EXT-X-MEDIA-SEQUENCE:0\n',
1130
- '#EXTINF:3,\n',
1131
- 'clip0-video-0.ts\n',
1132
- '#EXTINF:1,\n',
1133
- 'clip0-video-1.ts\n',
1134
- '#EXT-X-DISCONTINUITY\n',
1135
- '#EXTINF:2,\n',
1136
- 'clip1-video-1.ts\n',
1137
- '#EXTINF:3,\n',
1138
- 'clip1-video-2.ts\n',
1139
- '#EXT-X-DISCONTINUITY\n',
1140
- '#EXTINF:1,\n',
1141
- 'media-clip2-video-0.ts\n',
1142
- '#EXTINF:1,\n',
1143
- 'media-clip2-video-1.ts\n',
1144
- '#EXT-X-DISCONTINUITY\n',
1145
- '#EXTINF:4,\n',
1146
- 'media-clip3-video-1.ts\n',
1147
- '#EXT-X-ENDLIST\n',
1148
- ].join('');
1149
-
1150
- fakeNetEngine
1151
- .setResponseText('test:/master', master)
1152
- .setResponseText('test:/video', media);
1153
-
1154
- const manifest = await parser.start('test:/master', playerInterface);
1155
- await manifest.variants[0].video.createSegmentIndex();
1156
-
1157
- const segmentIndex = manifest.variants[0].video.segmentIndex;
1158
- const references = [];
1159
-
1160
- for (let i = 0; i < 7; i++) {
1161
- references.push(segmentIndex.get(i));
1162
- }
1163
-
1164
- expect(references[0].timestampOffset).toBe(0);
1165
- expect(references[1].timestampOffset).toBe(0);
1166
- expect(references[2].timestampOffset).toBe(4);
1167
- expect(references[3].timestampOffset).toBe(4);
1168
- expect(references[4].timestampOffset).toBe(9);
1169
- expect(references[5].timestampOffset).toBe(9);
1170
- expect(references[6].timestampOffset).toBe(11);
1171
- },
1172
- );
1173
-
1174
1117
  it('parses characteristics from audio tags', async () => {
1175
1118
  const master = [
1176
1119
  '#EXTM3U\n',
@@ -3132,8 +3075,10 @@ describe('HlsParser', () => {
3132
3075
 
3133
3076
  const firstMp4Segment = mp4AesEncryptionVideo.segmentIndex.get(0);
3134
3077
  expect(firstMp4Segment.hlsAes128Key).toBeDefined();
3078
+ expect(firstMp4Segment.initSegmentReference.hlsAes128Key).toBeDefined();
3135
3079
  const secondMp4Segment = mp4AesEncryptionVideo.segmentIndex.get(1);
3136
3080
  expect(secondMp4Segment.hlsAes128Key).toBeNull();
3081
+ expect(secondMp4Segment.initSegmentReference.hlsAes128Key).toBeDefined();
3137
3082
 
3138
3083
  const tsAesEncryptionVideo = actual.variants[2].video;
3139
3084
  await tsAesEncryptionVideo.createSegmentIndex();
@@ -46,11 +46,15 @@ shaka.test.Dash = class {
46
46
  updateDuration: () => {},
47
47
  newDrmInfo: (stream) => {},
48
48
  };
49
- const manifest = await dashParser.start('dummy://foo', playerInterface);
50
- const stream = manifest.variants[0].video;
51
- await stream.createSegmentIndex();
49
+ try {
50
+ const manifest = await dashParser.start('dummy://foo', playerInterface);
51
+ const stream = manifest.variants[0].video;
52
+ await stream.createSegmentIndex();
52
53
 
53
- shaka.test.ManifestParser.verifySegmentIndex(stream, references);
54
+ shaka.test.ManifestParser.verifySegmentIndex(stream, references);
55
+ } finally {
56
+ dashParser.stop();
57
+ }
54
58
  }
55
59
 
56
60
  /**
@@ -82,9 +86,14 @@ shaka.test.Dash = class {
82
86
  updateDuration: () => {},
83
87
  newDrmInfo: (stream) => {},
84
88
  };
85
- const p = dashParser.start('dummy://foo', playerInterface);
86
- await expectAsync(p).toBeRejectedWith(
87
- shaka.test.Util.jasmineError(expectedError));
89
+
90
+ try {
91
+ const p = dashParser.start('dummy://foo', playerInterface);
92
+ await expectAsync(p).toBeRejectedWith(
93
+ shaka.test.Util.jasmineError(expectedError));
94
+ } finally {
95
+ dashParser.stop();
96
+ }
88
97
  }
89
98
 
90
99
  /**
@@ -1866,9 +1866,8 @@ describe('TtmlTextParser', () => {
1866
1866
  endTime: 60,
1867
1867
  payload: '',
1868
1868
  fontSize: '15px',
1869
- // Styles from regionStyle should apply only to the nested cue.
1870
- backgroundColor: '',
1871
- color: '',
1869
+ backgroundColor: 'transparent',
1870
+ color: 'blue',
1872
1871
  displayAlign: Cue.displayAlign.CENTER,
1873
1872
  textAlign: Cue.textAlign.CENTER,
1874
1873
 
@@ -1970,7 +1969,7 @@ describe('TtmlTextParser', () => {
1970
1969
  startTime: 0,
1971
1970
  endTime: 60,
1972
1971
  payload: '',
1973
- fontSize: '',
1972
+ fontSize: '16px',
1974
1973
  nestedCues: [
1975
1974
  {
1976
1975
  startTime: 0,
@@ -213,7 +213,6 @@ filterDescribe('WebVTT layout', shaka.test.TextLayoutTests.supported, () => {
213
213
  await helper.checkScreenshot('line-negative-2');
214
214
  });
215
215
 
216
- // FIXME: UI version is wrong: not positioned by line
217
216
  it('line 0', async () => {
218
217
  parseAndDisplay([
219
218
  'WEBVTT\n',
@@ -72,6 +72,6 @@ describe('TsParser', () => {
72
72
  const codecs = new shaka.util.TsParser().parse(tsSegment)
73
73
  .getCodecs();
74
74
  expect(codecs.audio).toBe('aac');
75
- expect(codecs.video).toBe('');
75
+ expect(codecs.video).toBe(null);
76
76
  });
77
77
  });