shaka-player 4.2.6 → 4.2.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.
Files changed (51) hide show
  1. package/.github/workflows/selenium-lab-tests.yaml +22 -0
  2. package/CHANGELOG.md +36 -0
  3. package/dist/deps.js +4 -3
  4. package/dist/locales.js +30 -30
  5. package/dist/shaka-player.compiled.d.ts +10 -0
  6. package/dist/shaka-player.compiled.debug.d.ts +10 -0
  7. package/dist/shaka-player.compiled.debug.externs.js +12 -0
  8. package/dist/shaka-player.compiled.debug.js +177 -166
  9. package/dist/shaka-player.compiled.debug.map +4 -4
  10. package/dist/shaka-player.compiled.externs.js +12 -0
  11. package/dist/shaka-player.compiled.js +672 -666
  12. package/dist/shaka-player.compiled.map +4 -4
  13. package/dist/shaka-player.ui.d.ts +10 -0
  14. package/dist/shaka-player.ui.debug.d.ts +10 -0
  15. package/dist/shaka-player.ui.debug.externs.js +12 -0
  16. package/dist/shaka-player.ui.debug.js +189 -179
  17. package/dist/shaka-player.ui.debug.map +4 -4
  18. package/dist/shaka-player.ui.externs.js +12 -0
  19. package/dist/shaka-player.ui.js +820 -815
  20. package/dist/shaka-player.ui.map +4 -4
  21. package/lib/dash/segment_template.js +17 -5
  22. package/lib/hls/hls_parser.js +53 -16
  23. package/lib/media/media_source_engine.js +34 -4
  24. package/lib/media/segment_index.js +5 -10
  25. package/lib/media/segment_reference.js +39 -0
  26. package/lib/media/streaming_engine.js +15 -3
  27. package/lib/player.js +7 -1
  28. package/lib/polyfill/media_capabilities.js +4 -1
  29. package/lib/text/simple_text_displayer.js +2 -64
  30. package/lib/text/text_utils.js +88 -0
  31. package/lib/text/ui_text_displayer.js +24 -9
  32. package/lib/text/vtt_text_parser.js +256 -95
  33. package/lib/text/web_vtt_generator.js +2 -52
  34. package/lib/util/dom_utils.js +3 -1
  35. package/lib/util/platform.js +8 -0
  36. package/lib/util/stream_utils.js +6 -0
  37. package/lib/util/timer.js +17 -0
  38. package/package.json +1 -1
  39. package/support.html +1 -0
  40. package/test/dash/dash_parser_manifest_unit.js +0 -36
  41. package/test/hls/hls_live_unit.js +8 -30
  42. package/test/hls/hls_parser_unit.js +30 -0
  43. package/test/media/segment_index_unit.js +28 -0
  44. package/test/player_integration.js +27 -0
  45. package/test/player_unit.js +4 -2
  46. package/test/test/util/layout_tests.js +433 -0
  47. package/test/test/util/util.js +0 -120
  48. package/test/{ui → text}/text_displayer_layout_unit.js +59 -235
  49. package/test/text/ui_text_displayer_unit.js +72 -4
  50. package/test/text/vtt_text_parser_unit.js +123 -6
  51. package/test/text/web_vtt_layout_integration.js +528 -0
@@ -338,15 +338,13 @@ describe('UITextDisplayer', () => {
338
338
  it('hides and shows nested cues at appropriate times', () => {
339
339
  const parentCue1 = new shaka.text.Cue(0, 100, '');
340
340
  const cue1 = new shaka.text.Cue(0, 50, 'One');
341
- parentCue1.nestedCues.push(cue1);
342
341
  const cue2 = new shaka.text.Cue(25, 75, 'Two');
343
- parentCue1.nestedCues.push(cue2);
344
342
  const cue3 = new shaka.text.Cue(50, 100, 'Three');
345
- parentCue1.nestedCues.push(cue3);
343
+ parentCue1.nestedCues = [cue1, cue2, cue3];
346
344
 
347
345
  const parentCue2 = new shaka.text.Cue(90, 190, '');
348
346
  const cue4 = new shaka.text.Cue(90, 130, 'Four');
349
- parentCue2.nestedCues.push(cue4);
347
+ parentCue2.nestedCues = [cue4];
350
348
 
351
349
  textDisplayer.setTextVisibility(true);
352
350
  textDisplayer.append([parentCue1, parentCue2]);
@@ -537,4 +535,74 @@ describe('UITextDisplayer', () => {
537
535
  '.shaka-text-region');
538
536
  expect(allRegionElements.length).toBe(1);
539
537
  });
538
+
539
+ it('creates separate regions when dimensions differ but id same', () => {
540
+ const identicalRegionId = 'regionId';
541
+
542
+ const cueRegion1 = new shaka.text.CueRegion();
543
+ const cueRegion2 = new shaka.text.CueRegion();
544
+ cueRegion1.id = identicalRegionId;
545
+ cueRegion2.id = identicalRegionId;
546
+
547
+ cueRegion1.height = 80;
548
+ cueRegion1.heightUnits = shaka.text.CueRegion.units.PERCENTAGE;
549
+ cueRegion1.width = 80;
550
+ cueRegion1.widthUnits = shaka.text.CueRegion.units.PERCENTAGE;
551
+
552
+ cueRegion2.height = 160; // the only difference!
553
+ cueRegion2.heightUnits = shaka.text.CueRegion.units.PERCENTAGE;
554
+ cueRegion2.width = 80;
555
+ cueRegion2.widthUnits = shaka.text.CueRegion.units.PERCENTAGE;
556
+
557
+ cueRegion1.viewportAnchorX = 10;
558
+ cueRegion1.viewportAnchorY = 10;
559
+ cueRegion1.viewportAnchorUnits = shaka.text.CueRegion.units.PERCENTAGE;
560
+
561
+ cueRegion2.viewportAnchorX = 10;
562
+ cueRegion2.viewportAnchorY = 10;
563
+ cueRegion2.viewportAnchorUnits = shaka.text.CueRegion.units.PERCENTAGE;
564
+
565
+ // These all attach to the same region, but only one region element should
566
+ // be created.
567
+ const firstBatchOfCues = [
568
+ new shaka.text.Cue(0, 100, ''),
569
+ new shaka.text.Cue(0, 100, ''),
570
+ new shaka.text.Cue(0, 100, ''),
571
+ ];
572
+ for (const cue of firstBatchOfCues) {
573
+ cue.displayAlign = shaka.text.Cue.displayAlign.CENTER;
574
+ cue.region = cueRegion1;
575
+ }
576
+
577
+ // Another batch for the other region
578
+ const secondBatchOfCues = [
579
+ new shaka.text.Cue(0, 100, ''),
580
+ new shaka.text.Cue(0, 100, ''),
581
+ new shaka.text.Cue(0, 100, ''),
582
+ ];
583
+ for (const cue of secondBatchOfCues) {
584
+ cue.displayAlign = shaka.text.Cue.displayAlign.CENTER;
585
+ cue.region = cueRegion2;
586
+ }
587
+
588
+ textDisplayer.setTextVisibility(true);
589
+ textDisplayer.append(firstBatchOfCues);
590
+ textDisplayer.append(secondBatchOfCues);
591
+ updateCaptions();
592
+
593
+ const textContainer = videoContainer.querySelector('.shaka-text-container');
594
+ const allRegionElements = textContainer.querySelectorAll(
595
+ '.shaka-text-region');
596
+
597
+ // Verify that the nested cues are attached to respective region element.
598
+ expect(allRegionElements.length).toBe(2);
599
+
600
+ const childrenOfOne = Array.from(allRegionElements[0].childNodes).filter(
601
+ (e) => e.nodeType == Node.ELEMENT_NODE);
602
+ expect(childrenOfOne.length).toBe(3);
603
+
604
+ const childrenOfTwo = Array.from(allRegionElements[1].childNodes).filter(
605
+ (e) => e.nodeType == Node.ELEMENT_NODE);
606
+ expect(childrenOfTwo.length).toBe(3);
607
+ });
540
608
  });
@@ -849,6 +849,17 @@ describe('VttTextParser', () => {
849
849
  {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0});
850
850
  });
851
851
 
852
+ it('support escaped html payload', () => {
853
+ verifyHelper(
854
+ [
855
+ {startTime: 20.1, endTime: 40.505, payload: '"Test & 1"\u{a0}'},
856
+ ],
857
+ 'WEBVTT\n\n' +
858
+ '00:00:20.100 --> 00:00:40.505\n' +
859
+ '"Test & 1" ',
860
+ {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0});
861
+ });
862
+
852
863
  it('supports specific style blocks', () => {
853
864
  verifyHelper(
854
865
  [
@@ -986,25 +997,32 @@ describe('VttTextParser', () => {
986
997
  {
987
998
  startTime: 80,
988
999
  endTime: 90,
989
- payload: '<b><c.lime>Parse fail 1</b></c>',
1000
+ payload: '<b><c.lime>Parse fail 1</b></c.lime>',
990
1001
  nestedCues: [],
991
1002
  },
992
1003
  {
993
1004
  startTime: 90,
994
1005
  endTime: 100,
995
- payload: '<c.lime><b>Parse fail 2</c></b>',
1006
+ payload: '<c.lime><b>Parse fail 2</c.lime></b>',
996
1007
  nestedCues: [],
997
1008
  },
998
1009
  {
999
1010
  startTime: 100,
1000
1011
  endTime: 110,
1001
- payload: '<c.lime>forward slash 1/2 in text</c>',
1002
- nestedCues: [],
1012
+ payload: '',
1013
+ nestedCues: [
1014
+ {
1015
+ startTime: 100,
1016
+ endTime: 110,
1017
+ payload: 'forward slash 1/2 in text',
1018
+ color: '#0F0',
1019
+ },
1020
+ ],
1003
1021
  },
1004
1022
  {
1005
1023
  startTime: 110,
1006
1024
  endTime: 120,
1007
- payload: '<c.lime>less or more < > in text</c>',
1025
+ payload: '<c.lime>less or more < > in text</c.lime>',
1008
1026
  nestedCues: [],
1009
1027
  },
1010
1028
  ],
@@ -1056,6 +1074,53 @@ describe('VttTextParser', () => {
1056
1074
  {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0});
1057
1075
  });
1058
1076
 
1077
+ it('supports voice style blocks', () => {
1078
+ verifyHelper(
1079
+ [
1080
+ {
1081
+ startTime: 20,
1082
+ endTime: 40,
1083
+ payload: '',
1084
+ nestedCues: [
1085
+ {
1086
+ startTime: 20,
1087
+ endTime: 40,
1088
+ payload: 'Test',
1089
+ color: 'cyan',
1090
+ },
1091
+ ],
1092
+ },
1093
+ {
1094
+ startTime: 40,
1095
+ endTime: 50,
1096
+ payload: '',
1097
+ nestedCues: [
1098
+ {
1099
+ startTime: 40,
1100
+ endTime: 50,
1101
+ payload: 'Test',
1102
+ color: 'red',
1103
+ },
1104
+ {
1105
+ startTime: 40,
1106
+ endTime: 50,
1107
+ payload: '2',
1108
+ fontStyle: Cue.fontStyle.ITALIC,
1109
+ },
1110
+ ],
1111
+ },
1112
+ ],
1113
+ 'WEBVTT\n\n' +
1114
+ 'STYLE\n' +
1115
+ '::cue(v[voice="Shaka"]) { color: cyan; }\n' +
1116
+ '::cue(v[voice=ShakaBis]) { color: red; }\n\n' +
1117
+ '00:00:20.000 --> 00:00:40.000\n' +
1118
+ '<v Shaka>Test\n\n' +
1119
+ '00:00:40.000 --> 00:00:50.000\n' +
1120
+ '<v ShakaBis>Test</v><i>2</i>',
1121
+ {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0});
1122
+ });
1123
+
1059
1124
  it('supports default color overriding', () => {
1060
1125
  verifyHelper(
1061
1126
  [
@@ -1076,12 +1141,64 @@ describe('VttTextParser', () => {
1076
1141
  ],
1077
1142
  'WEBVTT\n\n' +
1078
1143
  'STYLE\n' +
1079
- '::cue(bg_blue) { font-size: 10px; background-color: #FF0 }\n\n' +
1144
+ '::cue(.bg_blue) { font-size: 10px; background-color: #FF0 }\n\n' +
1080
1145
  '00:00:10.000 --> 00:00:20.000\n' +
1081
1146
  '<c.red.bg_blue>Example 1</c>\n\n',
1082
1147
  {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0});
1083
1148
  });
1084
1149
 
1150
+ // https://github.com/shaka-project/shaka-player/issues/4479
1151
+ it('keep styles when there are line breaks', () => {
1152
+ verifyHelper(
1153
+ [
1154
+ {
1155
+ startTime: 10, endTime: 20,
1156
+ payload: '',
1157
+ nestedCues: [
1158
+ {
1159
+ startTime: 10,
1160
+ endTime: 20,
1161
+ payload: '1',
1162
+ color: '#F0F',
1163
+ },
1164
+ {
1165
+ startTime: 10,
1166
+ endTime: 20,
1167
+ payload: '',
1168
+ lineBreak: true,
1169
+ },
1170
+ {
1171
+ startTime: 10,
1172
+ endTime: 20,
1173
+ payload: '2',
1174
+ color: '#F0F',
1175
+ fontStyle: Cue.fontStyle.ITALIC,
1176
+ },
1177
+ ],
1178
+ },
1179
+ ],
1180
+ 'WEBVTT\n\n' +
1181
+ '00:00:10.000 --> 00:00:20.000\n' +
1182
+ '<c.magenta>1</c><br/><c.magenta><i>2</i></c>\n\n',
1183
+ {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0});
1184
+ });
1185
+
1186
+ it('does not fail on REGION blocks', () => {
1187
+ verifyHelper(
1188
+ [
1189
+ {
1190
+ startTime: 10, endTime: 20,
1191
+ payload: 'test',
1192
+ },
1193
+ ],
1194
+ 'WEBVTT\n\n' +
1195
+ 'REGION\n' +
1196
+ 'id:1\n\n' +
1197
+ '00:00:10.000 --> 00:00:20.000\n' +
1198
+ 'test\n\n',
1199
+ {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0});
1200
+ });
1201
+
1085
1202
  /**
1086
1203
  * @param {!Array} cues
1087
1204
  * @param {string} text