@svta/cml-608 1.0.3 → 1.1.1
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/README.md +41 -0
- package/dist/index.d.ts +220 -196
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +411 -108
- package/dist/index.js.map +1 -1
- package/package.json +4 -1
package/dist/index.js
CHANGED
|
@@ -15,10 +15,46 @@ const VerboseLevel = {
|
|
|
15
15
|
DEBUG: 3,
|
|
16
16
|
DATA: 3
|
|
17
17
|
};
|
|
18
|
-
|
|
19
18
|
//#endregion
|
|
20
19
|
//#region src/CaptionsLogger.ts
|
|
21
20
|
/**
|
|
21
|
+
*
|
|
22
|
+
* This code was ported from the dash.js project at:
|
|
23
|
+
* https://github.com/Dash-Industry-Forum/dash.js/blob/development/externals/cea608-parser.js
|
|
24
|
+
* https://github.com/Dash-Industry-Forum/dash.js/commit/8269b26a761e0853bb21d78780ed945144ecdd4d#diff-71bc295a2d6b6b7093a1d3290d53a4b2
|
|
25
|
+
*
|
|
26
|
+
* The original copyright appears below:
|
|
27
|
+
*
|
|
28
|
+
* The copyright in this software is being made available under the BSD License,
|
|
29
|
+
* included below. This software may be subject to other third party and contributor
|
|
30
|
+
* rights, including patent rights, and no such rights are granted under this license.
|
|
31
|
+
*
|
|
32
|
+
* Copyright (c) 2015-2016, DASH Industry Forum.
|
|
33
|
+
* All rights reserved.
|
|
34
|
+
*
|
|
35
|
+
* Redistribution and use in source and binary forms, with or without modification,
|
|
36
|
+
* are permitted provided that the following conditions are met:
|
|
37
|
+
* 1. Redistributions of source code must retain the above copyright notice, this
|
|
38
|
+
* list of conditions and the following disclaimer.
|
|
39
|
+
* * Redistributions in binary form must reproduce the above copyright notice,
|
|
40
|
+
* this list of conditions and the following disclaimer in the documentation and/or
|
|
41
|
+
* other materials provided with the distribution.
|
|
42
|
+
* 2. Neither the name of Dash Industry Forum nor the names of its
|
|
43
|
+
* contributors may be used to endorse or promote products derived from this software
|
|
44
|
+
* without specific prior written permission.
|
|
45
|
+
*
|
|
46
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY
|
|
47
|
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
48
|
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
49
|
+
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
|
50
|
+
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
51
|
+
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
52
|
+
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
53
|
+
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
54
|
+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
55
|
+
* POSSIBILITY OF SUCH DAMAGE.
|
|
56
|
+
*/
|
|
57
|
+
/**
|
|
22
58
|
* CaptionsLogger. To be removed in the future.
|
|
23
59
|
*
|
|
24
60
|
* @public
|
|
@@ -35,7 +71,6 @@ var CaptionsLogger = class {
|
|
|
35
71
|
}
|
|
36
72
|
}
|
|
37
73
|
};
|
|
38
|
-
|
|
39
74
|
//#endregion
|
|
40
75
|
//#region src/PenState.ts
|
|
41
76
|
/**
|
|
@@ -81,10 +116,46 @@ var PenState = class {
|
|
|
81
116
|
this.flash = newPenState.flash;
|
|
82
117
|
}
|
|
83
118
|
};
|
|
84
|
-
|
|
85
119
|
//#endregion
|
|
86
120
|
//#region src/StyledUnicodeChar.ts
|
|
87
121
|
/**
|
|
122
|
+
*
|
|
123
|
+
* This code was ported from the dash.js project at:
|
|
124
|
+
* https://github.com/Dash-Industry-Forum/dash.js/blob/development/externals/cea608-parser.js
|
|
125
|
+
* https://github.com/Dash-Industry-Forum/dash.js/commit/8269b26a761e0853bb21d78780ed945144ecdd4d#diff-71bc295a2d6b6b7093a1d3290d53a4b2
|
|
126
|
+
*
|
|
127
|
+
* The original copyright appears below:
|
|
128
|
+
*
|
|
129
|
+
* The copyright in this software is being made available under the BSD License,
|
|
130
|
+
* included below. This software may be subject to other third party and contributor
|
|
131
|
+
* rights, including patent rights, and no such rights are granted under this license.
|
|
132
|
+
*
|
|
133
|
+
* Copyright (c) 2015-2016, DASH Industry Forum.
|
|
134
|
+
* All rights reserved.
|
|
135
|
+
*
|
|
136
|
+
* Redistribution and use in source and binary forms, with or without modification,
|
|
137
|
+
* are permitted provided that the following conditions are met:
|
|
138
|
+
* 1. Redistributions of source code must retain the above copyright notice, this
|
|
139
|
+
* list of conditions and the following disclaimer.
|
|
140
|
+
* * Redistributions in binary form must reproduce the above copyright notice,
|
|
141
|
+
* this list of conditions and the following disclaimer in the documentation and/or
|
|
142
|
+
* other materials provided with the distribution.
|
|
143
|
+
* 2. Neither the name of Dash Industry Forum nor the names of its
|
|
144
|
+
* contributors may be used to endorse or promote products derived from this software
|
|
145
|
+
* without specific prior written permission.
|
|
146
|
+
*
|
|
147
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY
|
|
148
|
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
149
|
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
150
|
+
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
|
151
|
+
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
152
|
+
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
153
|
+
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
154
|
+
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
155
|
+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
156
|
+
* POSSIBILITY OF SUCH DAMAGE.
|
|
157
|
+
*/
|
|
158
|
+
/**
|
|
88
159
|
* Unicode character with styling and background.
|
|
89
160
|
*
|
|
90
161
|
* @public
|
|
@@ -116,11 +187,6 @@ var StyledUnicodeChar = class {
|
|
|
116
187
|
return this.uchar === " " && this.penState.isDefault();
|
|
117
188
|
}
|
|
118
189
|
};
|
|
119
|
-
|
|
120
|
-
//#endregion
|
|
121
|
-
//#region src/utils/NR_COLS.ts
|
|
122
|
-
const NR_COLS = 100;
|
|
123
|
-
|
|
124
190
|
//#endregion
|
|
125
191
|
//#region src/utils/specialCea608CharsCodes.ts
|
|
126
192
|
/**
|
|
@@ -218,16 +284,51 @@ const specialCea608CharsCodes = {
|
|
|
218
284
|
206: 9495,
|
|
219
285
|
207: 9499
|
|
220
286
|
};
|
|
221
|
-
|
|
222
287
|
//#endregion
|
|
223
288
|
//#region src/utils/getCharForByte.ts
|
|
224
289
|
function getCharForByte(byte) {
|
|
225
290
|
return String.fromCharCode(specialCea608CharsCodes[byte] || byte);
|
|
226
291
|
}
|
|
227
|
-
|
|
228
292
|
//#endregion
|
|
229
293
|
//#region src/Row.ts
|
|
230
294
|
/**
|
|
295
|
+
*
|
|
296
|
+
* This code was ported from the dash.js project at:
|
|
297
|
+
* https://github.com/Dash-Industry-Forum/dash.js/blob/development/externals/cea608-parser.js
|
|
298
|
+
* https://github.com/Dash-Industry-Forum/dash.js/commit/8269b26a761e0853bb21d78780ed945144ecdd4d#diff-71bc295a2d6b6b7093a1d3290d53a4b2
|
|
299
|
+
*
|
|
300
|
+
* The original copyright appears below:
|
|
301
|
+
*
|
|
302
|
+
* The copyright in this software is being made available under the BSD License,
|
|
303
|
+
* included below. This software may be subject to other third party and contributor
|
|
304
|
+
* rights, including patent rights, and no such rights are granted under this license.
|
|
305
|
+
*
|
|
306
|
+
* Copyright (c) 2015-2016, DASH Industry Forum.
|
|
307
|
+
* All rights reserved.
|
|
308
|
+
*
|
|
309
|
+
* Redistribution and use in source and binary forms, with or without modification,
|
|
310
|
+
* are permitted provided that the following conditions are met:
|
|
311
|
+
* 1. Redistributions of source code must retain the above copyright notice, this
|
|
312
|
+
* list of conditions and the following disclaimer.
|
|
313
|
+
* * Redistributions in binary form must reproduce the above copyright notice,
|
|
314
|
+
* this list of conditions and the following disclaimer in the documentation and/or
|
|
315
|
+
* other materials provided with the distribution.
|
|
316
|
+
* 2. Neither the name of Dash Industry Forum nor the names of its
|
|
317
|
+
* contributors may be used to endorse or promote products derived from this software
|
|
318
|
+
* without specific prior written permission.
|
|
319
|
+
*
|
|
320
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY
|
|
321
|
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
322
|
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
323
|
+
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
|
324
|
+
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
325
|
+
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
326
|
+
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
327
|
+
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
328
|
+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
329
|
+
* POSSIBILITY OF SUCH DAMAGE.
|
|
330
|
+
*/
|
|
331
|
+
/**
|
|
231
332
|
* CTA-608 row consisting of NR_COLS instances of StyledUnicodeChar.
|
|
232
333
|
*
|
|
233
334
|
* @public
|
|
@@ -238,19 +339,19 @@ var Row = class {
|
|
|
238
339
|
this.cueStartTime = null;
|
|
239
340
|
this.pos = 0;
|
|
240
341
|
this.currPenState = new PenState();
|
|
241
|
-
for (let i = 0; i <
|
|
342
|
+
for (let i = 0; i < 100; i++) this.chars.push(new StyledUnicodeChar());
|
|
242
343
|
this.logger = logger;
|
|
243
344
|
}
|
|
244
345
|
equals(other) {
|
|
245
|
-
for (let i = 0; i <
|
|
346
|
+
for (let i = 0; i < 100; i++) if (!this.chars[i].equals(other.chars[i])) return false;
|
|
246
347
|
return true;
|
|
247
348
|
}
|
|
248
349
|
copy(other) {
|
|
249
|
-
for (let i = 0; i <
|
|
350
|
+
for (let i = 0; i < 100; i++) this.chars[i].copy(other.chars[i]);
|
|
250
351
|
}
|
|
251
352
|
isEmpty() {
|
|
252
353
|
let empty = true;
|
|
253
|
-
for (let i = 0; i <
|
|
354
|
+
for (let i = 0; i < 100; i++) if (!this.chars[i].isEmpty()) {
|
|
254
355
|
empty = false;
|
|
255
356
|
break;
|
|
256
357
|
}
|
|
@@ -264,9 +365,9 @@ var Row = class {
|
|
|
264
365
|
if (this.pos < 0) {
|
|
265
366
|
this.logger.log(VerboseLevel.DEBUG, "Negative cursor position " + this.pos);
|
|
266
367
|
this.pos = 0;
|
|
267
|
-
} else if (this.pos >
|
|
368
|
+
} else if (this.pos > 100) {
|
|
268
369
|
this.logger.log(VerboseLevel.DEBUG, "Too large cursor position " + this.pos);
|
|
269
|
-
this.pos =
|
|
370
|
+
this.pos = 100;
|
|
270
371
|
}
|
|
271
372
|
}
|
|
272
373
|
/**
|
|
@@ -287,7 +388,7 @@ var Row = class {
|
|
|
287
388
|
insertChar(byte) {
|
|
288
389
|
if (byte >= 144) this.backSpace();
|
|
289
390
|
const char = getCharForByte(byte);
|
|
290
|
-
if (this.pos >=
|
|
391
|
+
if (this.pos >= 100) {
|
|
291
392
|
this.logger.log(VerboseLevel.ERROR, () => "Cannot insert " + byte.toString(16) + " (" + char + ") at position " + this.pos + ". Skipping it!");
|
|
292
393
|
return;
|
|
293
394
|
}
|
|
@@ -296,7 +397,7 @@ var Row = class {
|
|
|
296
397
|
}
|
|
297
398
|
clearFromPos(startPos) {
|
|
298
399
|
let i;
|
|
299
|
-
for (i = startPos; i <
|
|
400
|
+
for (i = startPos; i < 100; i++) this.chars[i].reset();
|
|
300
401
|
}
|
|
301
402
|
clear() {
|
|
302
403
|
this.clearFromPos(0);
|
|
@@ -309,7 +410,7 @@ var Row = class {
|
|
|
309
410
|
getTextString() {
|
|
310
411
|
const chars = [];
|
|
311
412
|
let empty = true;
|
|
312
|
-
for (let i = 0; i <
|
|
413
|
+
for (let i = 0; i < 100; i++) {
|
|
313
414
|
const char = this.chars[i].uchar;
|
|
314
415
|
if (char !== " ") empty = false;
|
|
315
416
|
chars.push(char);
|
|
@@ -322,14 +423,46 @@ var Row = class {
|
|
|
322
423
|
this.chars[this.pos].setPenState(this.currPenState);
|
|
323
424
|
}
|
|
324
425
|
};
|
|
325
|
-
|
|
326
|
-
//#endregion
|
|
327
|
-
//#region src/utils/NR_ROWS.ts
|
|
328
|
-
const NR_ROWS = 15;
|
|
329
|
-
|
|
330
426
|
//#endregion
|
|
331
427
|
//#region src/CaptionScreen.ts
|
|
332
428
|
/**
|
|
429
|
+
*
|
|
430
|
+
* This code was ported from the dash.js project at:
|
|
431
|
+
* https://github.com/Dash-Industry-Forum/dash.js/blob/development/externals/cea608-parser.js
|
|
432
|
+
* https://github.com/Dash-Industry-Forum/dash.js/commit/8269b26a761e0853bb21d78780ed945144ecdd4d#diff-71bc295a2d6b6b7093a1d3290d53a4b2
|
|
433
|
+
*
|
|
434
|
+
* The original copyright appears below:
|
|
435
|
+
*
|
|
436
|
+
* The copyright in this software is being made available under the BSD License,
|
|
437
|
+
* included below. This software may be subject to other third party and contributor
|
|
438
|
+
* rights, including patent rights, and no such rights are granted under this license.
|
|
439
|
+
*
|
|
440
|
+
* Copyright (c) 2015-2016, DASH Industry Forum.
|
|
441
|
+
* All rights reserved.
|
|
442
|
+
*
|
|
443
|
+
* Redistribution and use in source and binary forms, with or without modification,
|
|
444
|
+
* are permitted provided that the following conditions are met:
|
|
445
|
+
* 1. Redistributions of source code must retain the above copyright notice, this
|
|
446
|
+
* list of conditions and the following disclaimer.
|
|
447
|
+
* * Redistributions in binary form must reproduce the above copyright notice,
|
|
448
|
+
* this list of conditions and the following disclaimer in the documentation and/or
|
|
449
|
+
* other materials provided with the distribution.
|
|
450
|
+
* 2. Neither the name of Dash Industry Forum nor the names of its
|
|
451
|
+
* contributors may be used to endorse or promote products derived from this software
|
|
452
|
+
* without specific prior written permission.
|
|
453
|
+
*
|
|
454
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY
|
|
455
|
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
456
|
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
457
|
+
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
|
458
|
+
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
459
|
+
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
460
|
+
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
461
|
+
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
462
|
+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
463
|
+
* POSSIBILITY OF SUCH DAMAGE.
|
|
464
|
+
*/
|
|
465
|
+
/**
|
|
333
466
|
* Keep a CTA-608 screen of 32x15 styled characters
|
|
334
467
|
*
|
|
335
468
|
* @public
|
|
@@ -337,30 +470,30 @@ const NR_ROWS = 15;
|
|
|
337
470
|
var CaptionScreen = class {
|
|
338
471
|
constructor(logger = new CaptionsLogger()) {
|
|
339
472
|
this.rows = [];
|
|
340
|
-
this.currRow =
|
|
473
|
+
this.currRow = 14;
|
|
341
474
|
this.nrRollUpRows = null;
|
|
342
475
|
this.lastOutputScreen = null;
|
|
343
|
-
for (let i = 0; i <
|
|
476
|
+
for (let i = 0; i < 15; i++) this.rows.push(new Row(logger));
|
|
344
477
|
this.logger = logger;
|
|
345
478
|
}
|
|
346
479
|
reset() {
|
|
347
|
-
for (let i = 0; i <
|
|
348
|
-
this.currRow =
|
|
480
|
+
for (let i = 0; i < 15; i++) this.rows[i].clear();
|
|
481
|
+
this.currRow = 14;
|
|
349
482
|
}
|
|
350
483
|
equals(other) {
|
|
351
484
|
let equal = true;
|
|
352
|
-
for (let i = 0; i <
|
|
485
|
+
for (let i = 0; i < 15; i++) if (!this.rows[i].equals(other.rows[i])) {
|
|
353
486
|
equal = false;
|
|
354
487
|
break;
|
|
355
488
|
}
|
|
356
489
|
return equal;
|
|
357
490
|
}
|
|
358
491
|
copy(other) {
|
|
359
|
-
for (let i = 0; i <
|
|
492
|
+
for (let i = 0; i < 15; i++) this.rows[i].copy(other.rows[i]);
|
|
360
493
|
}
|
|
361
494
|
isEmpty() {
|
|
362
495
|
let empty = true;
|
|
363
|
-
for (let i = 0; i <
|
|
496
|
+
for (let i = 0; i < 15; i++) if (!this.rows[i].isEmpty()) {
|
|
364
497
|
empty = false;
|
|
365
498
|
break;
|
|
366
499
|
}
|
|
@@ -393,7 +526,7 @@ var CaptionScreen = class {
|
|
|
393
526
|
let newRow = pacData.row - 1;
|
|
394
527
|
if (this.nrRollUpRows && newRow < this.nrRollUpRows - 1) newRow = this.nrRollUpRows - 1;
|
|
395
528
|
if (this.nrRollUpRows && this.currRow !== newRow) {
|
|
396
|
-
for (let i = 0; i <
|
|
529
|
+
for (let i = 0; i < 15; i++) this.rows[i].clear();
|
|
397
530
|
const topRowIndex = this.currRow + 1 - this.nrRollUpRows;
|
|
398
531
|
const lastOutputScreen = this.lastOutputScreen;
|
|
399
532
|
if (lastOutputScreen) {
|
|
@@ -451,7 +584,7 @@ var CaptionScreen = class {
|
|
|
451
584
|
const displayText = [];
|
|
452
585
|
let text = "";
|
|
453
586
|
let rowNr = -1;
|
|
454
|
-
for (let i = 0; i <
|
|
587
|
+
for (let i = 0; i < 15; i++) {
|
|
455
588
|
const rowText = this.rows[i].getTextString();
|
|
456
589
|
if (rowText) {
|
|
457
590
|
rowNr = i + 1;
|
|
@@ -459,15 +592,16 @@ var CaptionScreen = class {
|
|
|
459
592
|
else displayText.push(rowText.trim());
|
|
460
593
|
}
|
|
461
594
|
}
|
|
462
|
-
if (displayText.length > 0)
|
|
463
|
-
|
|
595
|
+
if (displayText.length > 0) {
|
|
596
|
+
if (asOneRow) text = "[" + displayText.join(" | ") + "]";
|
|
597
|
+
else text = displayText.join("\n");
|
|
598
|
+
}
|
|
464
599
|
return text;
|
|
465
600
|
}
|
|
466
601
|
getTextAndFormat() {
|
|
467
602
|
return this.rows;
|
|
468
603
|
}
|
|
469
604
|
};
|
|
470
|
-
|
|
471
605
|
//#endregion
|
|
472
606
|
//#region src/Cta608Channel.ts
|
|
473
607
|
/**
|
|
@@ -483,7 +617,7 @@ var Cta608Channel = class {
|
|
|
483
617
|
this.displayedMemory = new CaptionScreen(logger);
|
|
484
618
|
this.nonDisplayedMemory = new CaptionScreen(logger);
|
|
485
619
|
this.lastOutputScreen = new CaptionScreen(logger);
|
|
486
|
-
this.currRollUpRow = this.displayedMemory.rows[
|
|
620
|
+
this.currRollUpRow = this.displayedMemory.rows[14];
|
|
487
621
|
this.writeScreen = this.displayedMemory;
|
|
488
622
|
this.mode = null;
|
|
489
623
|
this.cueStartTime = null;
|
|
@@ -496,7 +630,7 @@ var Cta608Channel = class {
|
|
|
496
630
|
this.nonDisplayedMemory.reset();
|
|
497
631
|
this.lastOutputScreen.reset();
|
|
498
632
|
this.outputFilter?.reset?.();
|
|
499
|
-
this.currRollUpRow = this.displayedMemory.rows[
|
|
633
|
+
this.currRollUpRow = this.displayedMemory.rows[14];
|
|
500
634
|
this.writeScreen = this.displayedMemory;
|
|
501
635
|
this.mode = null;
|
|
502
636
|
this.cueStartTime = null;
|
|
@@ -645,7 +779,6 @@ var Cta608Channel = class {
|
|
|
645
779
|
}
|
|
646
780
|
}
|
|
647
781
|
};
|
|
648
|
-
|
|
649
782
|
//#endregion
|
|
650
783
|
//#region src/utils/backgroundColors.ts
|
|
651
784
|
const backgroundColors = [
|
|
@@ -659,7 +792,6 @@ const backgroundColors = [
|
|
|
659
792
|
"black",
|
|
660
793
|
"transparent"
|
|
661
794
|
];
|
|
662
|
-
|
|
663
795
|
//#endregion
|
|
664
796
|
//#region src/utils/createCmdHistory.ts
|
|
665
797
|
function createCmdHistory() {
|
|
@@ -668,13 +800,11 @@ function createCmdHistory() {
|
|
|
668
800
|
b: null
|
|
669
801
|
};
|
|
670
802
|
}
|
|
671
|
-
|
|
672
803
|
//#endregion
|
|
673
804
|
//#region src/utils/hasCmdRepeated.ts
|
|
674
805
|
function hasCmdRepeated(a, b, cmdHistory) {
|
|
675
806
|
return cmdHistory.a === a && cmdHistory.b === b;
|
|
676
807
|
}
|
|
677
|
-
|
|
678
808
|
//#endregion
|
|
679
809
|
//#region src/utils/numArrayToHexArray.ts
|
|
680
810
|
function numArrayToHexArray(numArray) {
|
|
@@ -682,7 +812,6 @@ function numArrayToHexArray(numArray) {
|
|
|
682
812
|
for (const num of numArray) hexArray.push(num.toString(16));
|
|
683
813
|
return hexArray;
|
|
684
814
|
}
|
|
685
|
-
|
|
686
815
|
//#endregion
|
|
687
816
|
//#region src/utils/rowsHighCh1.ts
|
|
688
817
|
const rowsHighCh1 = {
|
|
@@ -694,7 +823,6 @@ const rowsHighCh1 = {
|
|
|
694
823
|
19: 13,
|
|
695
824
|
20: 15
|
|
696
825
|
};
|
|
697
|
-
|
|
698
826
|
//#endregion
|
|
699
827
|
//#region src/utils/rowsHighCh2.ts
|
|
700
828
|
const rowsHighCh2 = {
|
|
@@ -706,7 +834,6 @@ const rowsHighCh2 = {
|
|
|
706
834
|
27: 13,
|
|
707
835
|
28: 15
|
|
708
836
|
};
|
|
709
|
-
|
|
710
837
|
//#endregion
|
|
711
838
|
//#region src/utils/rowsLowCh1.ts
|
|
712
839
|
const rowsLowCh1 = {
|
|
@@ -719,7 +846,6 @@ const rowsLowCh1 = {
|
|
|
719
846
|
19: 12,
|
|
720
847
|
20: 14
|
|
721
848
|
};
|
|
722
|
-
|
|
723
849
|
//#endregion
|
|
724
850
|
//#region src/utils/rowsLowCh2.ts
|
|
725
851
|
const rowsLowCh2 = {
|
|
@@ -732,17 +858,52 @@ const rowsLowCh2 = {
|
|
|
732
858
|
27: 12,
|
|
733
859
|
28: 14
|
|
734
860
|
};
|
|
735
|
-
|
|
736
861
|
//#endregion
|
|
737
862
|
//#region src/utils/setLastCmd.ts
|
|
738
863
|
function setLastCmd(a, b, cmdHistory) {
|
|
739
864
|
cmdHistory.a = a;
|
|
740
865
|
cmdHistory.b = b;
|
|
741
866
|
}
|
|
742
|
-
|
|
743
867
|
//#endregion
|
|
744
868
|
//#region src/Cta608Parser.ts
|
|
745
869
|
/**
|
|
870
|
+
*
|
|
871
|
+
* This code was ported from the dash.js project at:
|
|
872
|
+
* https://github.com/Dash-Industry-Forum/dash.js/blob/development/externals/cea608-parser.js
|
|
873
|
+
* https://github.com/Dash-Industry-Forum/dash.js/commit/8269b26a761e0853bb21d78780ed945144ecdd4d#diff-71bc295a2d6b6b7093a1d3290d53a4b2
|
|
874
|
+
*
|
|
875
|
+
* The original copyright appears below:
|
|
876
|
+
*
|
|
877
|
+
* The copyright in this software is being made available under the BSD License,
|
|
878
|
+
* included below. This software may be subject to other third party and contributor
|
|
879
|
+
* rights, including patent rights, and no such rights are granted under this license.
|
|
880
|
+
*
|
|
881
|
+
* Copyright (c) 2015-2016, DASH Industry Forum.
|
|
882
|
+
* All rights reserved.
|
|
883
|
+
*
|
|
884
|
+
* Redistribution and use in source and binary forms, with or without modification,
|
|
885
|
+
* are permitted provided that the following conditions are met:
|
|
886
|
+
* 1. Redistributions of source code must retain the above copyright notice, this
|
|
887
|
+
* list of conditions and the following disclaimer.
|
|
888
|
+
* * Redistributions in binary form must reproduce the above copyright notice,
|
|
889
|
+
* this list of conditions and the following disclaimer in the documentation and/or
|
|
890
|
+
* other materials provided with the distribution.
|
|
891
|
+
* 2. Neither the name of Dash Industry Forum nor the names of its
|
|
892
|
+
* contributors may be used to endorse or promote products derived from this software
|
|
893
|
+
* without specific prior written permission.
|
|
894
|
+
*
|
|
895
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY
|
|
896
|
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
897
|
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
898
|
+
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
|
899
|
+
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
900
|
+
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
901
|
+
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
902
|
+
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
903
|
+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
904
|
+
* POSSIBILITY OF SUCH DAMAGE.
|
|
905
|
+
*/
|
|
906
|
+
/**
|
|
746
907
|
* CEA-608 caption parser.
|
|
747
908
|
*
|
|
748
909
|
* @public
|
|
@@ -983,7 +1144,46 @@ var Cta608Parser = class {
|
|
|
983
1144
|
for (const channel of this.channels) if (channel) channel.cueSplitAtTime(t);
|
|
984
1145
|
}
|
|
985
1146
|
};
|
|
986
|
-
|
|
1147
|
+
//#endregion
|
|
1148
|
+
//#region src/utils/parseCcData.ts
|
|
1149
|
+
function isCCType(type) {
|
|
1150
|
+
return type === 0 || type === 1;
|
|
1151
|
+
}
|
|
1152
|
+
function isNonEmptyCCData(ccData1, ccData2) {
|
|
1153
|
+
return (ccData1 & 127) > 0 || (ccData2 & 127) > 0;
|
|
1154
|
+
}
|
|
1155
|
+
/**
|
|
1156
|
+
* Parse an ATSC A/53 Part 4 `cc_data()` structure into per-field byte pairs.
|
|
1157
|
+
*
|
|
1158
|
+
* The payload is identical for every carriage format — an AVC/HEVC/VVC SEI message and
|
|
1159
|
+
* an AV1 `metadata_itu_t_t35` OBU carry the same bytes under the same T.35/GA94
|
|
1160
|
+
* identifier — so this is the single parser shared by all of them. Only the envelope
|
|
1161
|
+
* around it differs.
|
|
1162
|
+
*
|
|
1163
|
+
* `cc_data()` is self-delimiting: `cc_count` states how many 3-byte constructs follow,
|
|
1164
|
+
* so anything after them (SEI `rbsp_trailing_bits`, an AV1 OBU `trailing_bits` byte) is
|
|
1165
|
+
* ignored without needing to be recognized.
|
|
1166
|
+
*
|
|
1167
|
+
* @param raw - The DataView holding the `cc_data()` structure
|
|
1168
|
+
* @param pos - The position of the first `cc_data()` byte, holding `cc_count`
|
|
1169
|
+
* @param endPos - The exclusive upper bound to read within
|
|
1170
|
+
* @param fieldData - Field 1 and field 2 byte arrays, appended to in place
|
|
1171
|
+
*/
|
|
1172
|
+
function parseCcData(raw, pos, endPos, fieldData) {
|
|
1173
|
+
if (pos + 2 > endPos) return;
|
|
1174
|
+
const ccCount = raw.getUint8(pos) & 31;
|
|
1175
|
+
let cursor = pos + 2;
|
|
1176
|
+
const ccEnd = Math.min(cursor + ccCount * 3, endPos);
|
|
1177
|
+
for (; cursor + 2 < ccEnd; cursor += 3) {
|
|
1178
|
+
const byte = raw.getUint8(cursor);
|
|
1179
|
+
if (!(byte & 4)) continue;
|
|
1180
|
+
const ccType = byte & 3;
|
|
1181
|
+
if (!isCCType(ccType)) continue;
|
|
1182
|
+
const ccData1 = raw.getUint8(cursor + 1);
|
|
1183
|
+
const ccData2 = raw.getUint8(cursor + 2);
|
|
1184
|
+
if (isNonEmptyCCData(ccData1, ccData2)) fieldData[ccType].push(ccData1, ccData2);
|
|
1185
|
+
}
|
|
1186
|
+
}
|
|
987
1187
|
//#endregion
|
|
988
1188
|
//#region src/extractCta608Data.ts
|
|
989
1189
|
/**
|
|
@@ -996,33 +1196,163 @@ var Cta608Parser = class {
|
|
|
996
1196
|
* @public
|
|
997
1197
|
*/
|
|
998
1198
|
function extractCta608Data(raw, cta608Range) {
|
|
999
|
-
let pos = cta608Range[0];
|
|
1000
1199
|
const fieldData = [[], []];
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1200
|
+
parseCcData(raw, cta608Range[0] + 8, cta608Range[0] + cta608Range[1], fieldData);
|
|
1201
|
+
return fieldData;
|
|
1202
|
+
}
|
|
1203
|
+
//#endregion
|
|
1204
|
+
//#region src/utils/isCta608UserData.ts
|
|
1205
|
+
/**
|
|
1206
|
+
* The 8-byte ATSC A/53 user identifier that prefixes a `cc_data()` payload, per
|
|
1207
|
+
* ANSI-SCTE 128: `itu_t_t35_country_code` (0xB5, USA), `terminal_provider_code`
|
|
1208
|
+
* (0x0031, ATSC), `terminal_provider_oriented_code` ('GA94'), and
|
|
1209
|
+
* `user_data_type_code` (0x03, cc_data).
|
|
1210
|
+
*
|
|
1211
|
+
* Both carriage formats use it unchanged — an AVC/HEVC/VVC
|
|
1212
|
+
* `user_data_registered_itu_t_t35` SEI message and an AV1 `metadata_itu_t_t35` OBU — so
|
|
1213
|
+
* this identifies CTA-608 user data for either.
|
|
1214
|
+
*
|
|
1215
|
+
* @param raw - The DataView holding the T.35 payload
|
|
1216
|
+
* @param pos - The position of `itu_t_t35_country_code`
|
|
1217
|
+
* @returns true when the 8 bytes at `pos` identify CTA-608 caption data
|
|
1218
|
+
*/
|
|
1219
|
+
function isCta608UserData(raw, pos) {
|
|
1220
|
+
return raw.getUint8(pos) === 181 && raw.getUint16(pos + 1) === 49 && raw.getUint32(pos + 3) === 1195456820 && raw.getUint8(pos + 7) === 3;
|
|
1221
|
+
}
|
|
1222
|
+
//#endregion
|
|
1223
|
+
//#region src/utils/obuHelpers.ts
|
|
1224
|
+
/**
|
|
1225
|
+
* AV1 `OBU_METADATA` unit type
|
|
1226
|
+
*/
|
|
1227
|
+
const OBU_METADATA = 5;
|
|
1228
|
+
/**
|
|
1229
|
+
* AV1 `METADATA_TYPE_ITUT_T35` metadata type
|
|
1230
|
+
*/
|
|
1231
|
+
const METADATA_TYPE_ITUT_T35 = 4;
|
|
1232
|
+
/**
|
|
1233
|
+
* The maximum number of bytes in an AV1 leb128() value
|
|
1234
|
+
*/
|
|
1235
|
+
const LEB128_MAX_BYTES = 8;
|
|
1236
|
+
/**
|
|
1237
|
+
* Read an AV1 `leb128()` variable-length integer (AV1 spec section 4.10.5): up to 8
|
|
1238
|
+
* bytes, 7 value bits each, least significant group first, with the high bit marking
|
|
1239
|
+
* continuation.
|
|
1240
|
+
*
|
|
1241
|
+
* Groups are combined by multiplication rather than by `<<`, because a leb128 value may
|
|
1242
|
+
* exceed the 32 bits a JavaScript shift operates on.
|
|
1243
|
+
*
|
|
1244
|
+
* @param raw - The DataView to read from
|
|
1245
|
+
* @param pos - The position of the first leb128 byte
|
|
1246
|
+
* @param endPos - The exclusive upper bound to read within
|
|
1247
|
+
* @returns The value and its byte length, or null when it is truncated or overlong
|
|
1248
|
+
*/
|
|
1249
|
+
function readLeb128(raw, pos, endPos) {
|
|
1250
|
+
let value = 0;
|
|
1251
|
+
for (let i = 0; i < LEB128_MAX_BYTES; i++) {
|
|
1252
|
+
if (pos + i >= endPos) return null;
|
|
1253
|
+
const byte = raw.getUint8(pos + i);
|
|
1254
|
+
value += (byte & 127) * 2 ** (i * 7);
|
|
1255
|
+
if (!(byte & 128)) return {
|
|
1256
|
+
value,
|
|
1257
|
+
size: i + 1
|
|
1258
|
+
};
|
|
1259
|
+
}
|
|
1260
|
+
return null;
|
|
1261
|
+
}
|
|
1262
|
+
/**
|
|
1263
|
+
* Detects whether an AV1 OBU header starts an `OBU_METADATA` unit and locates its
|
|
1264
|
+
* payload.
|
|
1265
|
+
*
|
|
1266
|
+
* The header is one byte — `obu_forbidden_bit` (1), `obu_type` (4),
|
|
1267
|
+
* `obu_extension_flag` (1), `obu_has_size_field` (1), `obu_reserved_1bit` (1) — followed
|
|
1268
|
+
* by an optional extension byte and, when `obu_has_size_field` is set, `obu_size` as a
|
|
1269
|
+
* leb128. An OBU without `obu_size` runs to the end of the temporal unit, which mp4
|
|
1270
|
+
* permits only for the final OBU in a sample.
|
|
1271
|
+
*
|
|
1272
|
+
* @param raw - The DataView containing the OBU
|
|
1273
|
+
* @param pos - The position of the OBU header byte
|
|
1274
|
+
* @param endPos - The exclusive end of the enclosing sample
|
|
1275
|
+
* @returns The payload bounds and whether this is a metadata OBU, or null if malformed
|
|
1276
|
+
*/
|
|
1277
|
+
function readObu(raw, pos, endPos) {
|
|
1278
|
+
const header = raw.getUint8(pos);
|
|
1279
|
+
if (header & 128) return null;
|
|
1280
|
+
let payloadStart = pos + 1;
|
|
1281
|
+
if (header & 4) payloadStart++;
|
|
1282
|
+
let payloadEnd = endPos;
|
|
1283
|
+
if (header & 2) {
|
|
1284
|
+
const obuSize = readLeb128(raw, payloadStart, endPos);
|
|
1285
|
+
if (!obuSize) return null;
|
|
1286
|
+
payloadStart += obuSize.size;
|
|
1287
|
+
payloadEnd = payloadStart + obuSize.value;
|
|
1288
|
+
if (payloadEnd > endPos) return null;
|
|
1289
|
+
}
|
|
1290
|
+
return {
|
|
1291
|
+
isMetadata: (header >> 3 & 15) === OBU_METADATA,
|
|
1292
|
+
payloadStart,
|
|
1293
|
+
payloadEnd
|
|
1294
|
+
};
|
|
1295
|
+
}
|
|
1296
|
+
/**
|
|
1297
|
+
* Parse CTA-608 field data out of an AV1 metadata OBU payload, ignoring metadata OBUs
|
|
1298
|
+
* of any other type.
|
|
1299
|
+
*
|
|
1300
|
+
* The payload is `metadata_type` as a leb128, then — for ITU-T T.35 — the 8-byte A/53
|
|
1301
|
+
* user identifier and the `cc_data()` structure. Unlike an SEI NAL unit an OBU carries
|
|
1302
|
+
* no emulation prevention, so the bytes are read verbatim.
|
|
1303
|
+
*
|
|
1304
|
+
* @param raw - The DataView containing the OBU payload
|
|
1305
|
+
* @param pos - The position of `metadata_type`
|
|
1306
|
+
* @param endPos - The exclusive end of the OBU payload
|
|
1307
|
+
* @param fieldData - Field 1 and field 2 byte arrays, appended to in place
|
|
1308
|
+
*/
|
|
1309
|
+
function parseCta608DataFromMetadataObu(raw, pos, endPos, fieldData) {
|
|
1310
|
+
const metadataType = readLeb128(raw, pos, endPos);
|
|
1311
|
+
if (!metadataType || metadataType.value !== METADATA_TYPE_ITUT_T35) return;
|
|
1312
|
+
const userDataStart = pos + metadataType.size;
|
|
1313
|
+
if (userDataStart + 10 > endPos || !isCta608UserData(raw, userDataStart)) return;
|
|
1314
|
+
parseCcData(raw, userDataStart + 8, endPos, fieldData);
|
|
1315
|
+
}
|
|
1316
|
+
//#endregion
|
|
1317
|
+
//#region src/extractCta608DataFromAv1Sample.ts
|
|
1318
|
+
/**
|
|
1319
|
+
* Extracts CTA-608 data from an AV1 (`av01`) sample.
|
|
1320
|
+
*
|
|
1321
|
+
* AV1 has no NAL units, so captions ride in an `metadata_itu_t_t35` OBU rather than in
|
|
1322
|
+
* an SEI message. The caption payload is unchanged — the same A/53 `cc_data()` under the
|
|
1323
|
+
* same T.35/GA94 identifier that {@link extractCta608DataFromSample} reads — so the
|
|
1324
|
+
* returned field data feeds {@link Cta608Parser} identically.
|
|
1325
|
+
*
|
|
1326
|
+
* This is a separate function rather than a codec branch inside
|
|
1327
|
+
* {@link extractCta608DataFromSample} because the two carriages are framed differently and
|
|
1328
|
+
* neither sample is self-identifying. A NAL unit sample puts a fixed-width big-endian
|
|
1329
|
+
* length in front of each unit, and that width is only known from `lengthSizeMinusOne` in
|
|
1330
|
+
* the `avcC`/`hvcC` config. An AV1 sample uses the low-overhead format, where each OBU
|
|
1331
|
+
* carries its own `obu_size` after the header — and may omit it on the last OBU. Select on
|
|
1332
|
+
* the sample entry type (`av01`) instead.
|
|
1333
|
+
*
|
|
1334
|
+
* @param raw - The DataView with media data
|
|
1335
|
+
* @param startPos - The start position of the sample within the DataView
|
|
1336
|
+
* @param sampleSize - The size of the sample in bytes
|
|
1337
|
+
* @returns fieldData array containing field 1 and field 2 data arrays
|
|
1338
|
+
*
|
|
1339
|
+
* @example
|
|
1340
|
+
* {@includeCode ../test/extractCta608DataFromAv1Sample.test.ts#example}
|
|
1341
|
+
*
|
|
1342
|
+
* @public
|
|
1343
|
+
*/
|
|
1344
|
+
function extractCta608DataFromAv1Sample(raw, startPos, sampleSize) {
|
|
1345
|
+
const fieldData = [[], []];
|
|
1346
|
+
const endPos = Math.min(startPos + sampleSize, raw.byteLength);
|
|
1347
|
+
let cursor = startPos;
|
|
1348
|
+
while (cursor < endPos) {
|
|
1349
|
+
const obu = readObu(raw, cursor, endPos);
|
|
1350
|
+
if (!obu) break;
|
|
1351
|
+
if (obu.isMetadata) parseCta608DataFromMetadataObu(raw, obu.payloadStart, obu.payloadEnd, fieldData);
|
|
1352
|
+
cursor = Math.max(obu.payloadEnd, cursor + 1);
|
|
1022
1353
|
}
|
|
1023
1354
|
return fieldData;
|
|
1024
1355
|
}
|
|
1025
|
-
|
|
1026
1356
|
//#endregion
|
|
1027
1357
|
//#region src/utils/seiHelpers.ts
|
|
1028
1358
|
function getSeiData(raw, startPos, endPos) {
|
|
@@ -1036,17 +1366,7 @@ function getSeiData(raw, startPos, endPos) {
|
|
|
1036
1366
|
}
|
|
1037
1367
|
function isCea608Sei(payloadType, payloadSize, sei, pos) {
|
|
1038
1368
|
if (payloadType !== 4 || payloadSize < 8) return false;
|
|
1039
|
-
|
|
1040
|
-
if (sei.getUint16(pos + 1) !== 49) return false;
|
|
1041
|
-
if (sei.getUint32(pos + 3) !== 1195456820) return false;
|
|
1042
|
-
if (sei.getUint8(pos + 7) !== 3) return false;
|
|
1043
|
-
return true;
|
|
1044
|
-
}
|
|
1045
|
-
function isCCType(type) {
|
|
1046
|
-
return type === 0 || type === 1;
|
|
1047
|
-
}
|
|
1048
|
-
function isNonEmptyCCData(ccData1, ccData2) {
|
|
1049
|
-
return (ccData1 & 127) > 0 || (ccData2 & 127) > 0;
|
|
1369
|
+
return isCta608UserData(sei, pos);
|
|
1050
1370
|
}
|
|
1051
1371
|
/**
|
|
1052
1372
|
* H.264 SEI NAL unit type
|
|
@@ -1113,25 +1433,10 @@ function parseCta608DataFromSei(sei, fieldData) {
|
|
|
1113
1433
|
do
|
|
1114
1434
|
payloadSize += now = sei.getUint8(cursor++);
|
|
1115
1435
|
while (now === 255);
|
|
1116
|
-
if (isCea608Sei(payloadType, payloadSize, sei, cursor))
|
|
1117
|
-
const pos = cursor + 10;
|
|
1118
|
-
const ccCount = pos + (sei.getUint8(pos - 2) & 31) * 3;
|
|
1119
|
-
for (let i = pos; i < ccCount; i += 3) {
|
|
1120
|
-
const byte = sei.getUint8(i);
|
|
1121
|
-
if (byte & 4) {
|
|
1122
|
-
const ccType = byte & 3;
|
|
1123
|
-
if (isCCType(ccType)) {
|
|
1124
|
-
const ccData1 = sei.getUint8(i + 1);
|
|
1125
|
-
const ccData2 = sei.getUint8(i + 2);
|
|
1126
|
-
if (isNonEmptyCCData(ccData1, ccData2)) fieldData[ccType].push(ccData1, ccData2);
|
|
1127
|
-
}
|
|
1128
|
-
}
|
|
1129
|
-
}
|
|
1130
|
-
}
|
|
1436
|
+
if (isCea608Sei(payloadType, payloadSize, sei, cursor)) parseCcData(sei, cursor + 8, cursor + payloadSize, fieldData);
|
|
1131
1437
|
cursor += payloadSize;
|
|
1132
1438
|
}
|
|
1133
1439
|
}
|
|
1134
|
-
|
|
1135
1440
|
//#endregion
|
|
1136
1441
|
//#region src/extractCta608DataFromSample.ts
|
|
1137
1442
|
/**
|
|
@@ -1160,7 +1465,6 @@ function extractCta608DataFromSample(raw, startPos, sampleSize) {
|
|
|
1160
1465
|
}
|
|
1161
1466
|
return fieldData;
|
|
1162
1467
|
}
|
|
1163
|
-
|
|
1164
1468
|
//#endregion
|
|
1165
1469
|
//#region src/findCta608Nalus.ts
|
|
1166
1470
|
/**
|
|
@@ -1176,12 +1480,12 @@ function extractCta608DataFromSample(raw, startPos, sampleSize) {
|
|
|
1176
1480
|
function findCta608Nalus(raw, startPos, size) {
|
|
1177
1481
|
let nalSize = 0, cursor = startPos;
|
|
1178
1482
|
const cta608NaluRanges = [];
|
|
1179
|
-
const isCTA608SEI = (payloadType, payloadSize, raw
|
|
1483
|
+
const isCTA608SEI = (payloadType, payloadSize, raw, pos) => {
|
|
1180
1484
|
if (payloadType !== 4 || payloadSize < 8) return null;
|
|
1181
|
-
const countryCode = raw
|
|
1182
|
-
const providerCode = raw
|
|
1183
|
-
const userIdentifier = raw
|
|
1184
|
-
const userDataTypeCode = raw
|
|
1485
|
+
const countryCode = raw.getUint8(pos);
|
|
1486
|
+
const providerCode = raw.getUint16(pos + 1);
|
|
1487
|
+
const userIdentifier = raw.getUint32(pos + 3);
|
|
1488
|
+
const userDataTypeCode = raw.getUint8(pos + 7);
|
|
1185
1489
|
return countryCode == 181 && providerCode == 49 && userIdentifier == 1195456820 && userDataTypeCode == 3;
|
|
1186
1490
|
};
|
|
1187
1491
|
while (cursor < startPos + size) {
|
|
@@ -1213,7 +1517,6 @@ function findCta608Nalus(raw, startPos, size) {
|
|
|
1213
1517
|
}
|
|
1214
1518
|
return cta608NaluRanges;
|
|
1215
1519
|
}
|
|
1216
|
-
|
|
1217
1520
|
//#endregion
|
|
1218
1521
|
//#region src/SccParser.ts
|
|
1219
1522
|
/**
|
|
@@ -1307,7 +1610,7 @@ var SccParser = class {
|
|
|
1307
1610
|
return this.nrLinesParsed;
|
|
1308
1611
|
}
|
|
1309
1612
|
};
|
|
1310
|
-
|
|
1311
1613
|
//#endregion
|
|
1312
|
-
export { CaptionScreen, CaptionsLogger, Cta608Channel, Cta608Parser, PenState, Row, SccParser, StyledUnicodeChar, VerboseLevel, extractCta608Data, extractCta608DataFromSample, findCta608Nalus };
|
|
1614
|
+
export { CaptionScreen, CaptionsLogger, Cta608Channel, Cta608Parser, PenState, Row, SccParser, StyledUnicodeChar, VerboseLevel, extractCta608Data, extractCta608DataFromAv1Sample, extractCta608DataFromSample, findCta608Nalus };
|
|
1615
|
+
|
|
1313
1616
|
//# sourceMappingURL=index.js.map
|