hls.js 1.5.10-0.canary.10326 → 1.5.10
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 +3 -4
- package/dist/hls-demo.js +38 -41
- package/dist/hls-demo.js.map +1 -1
- package/dist/hls.js +2194 -3476
- package/dist/hls.js.d.ts +85 -108
- package/dist/hls.js.map +1 -1
- package/dist/hls.light.js +3137 -3784
- package/dist/hls.light.js.map +1 -1
- package/dist/hls.light.min.js +1 -1
- package/dist/hls.light.min.js.map +1 -1
- package/dist/hls.light.mjs +1256 -1928
- package/dist/hls.light.mjs.map +1 -1
- package/dist/hls.min.js +1 -1
- package/dist/hls.min.js.map +1 -1
- package/dist/hls.mjs +4182 -5487
- package/dist/hls.mjs.map +1 -1
- package/dist/hls.worker.js +1 -1
- package/dist/hls.worker.js.map +1 -1
- package/package.json +35 -35
- package/src/config.ts +2 -3
- package/src/controller/abr-controller.ts +20 -24
- package/src/controller/audio-stream-controller.ts +74 -68
- package/src/controller/audio-track-controller.ts +1 -1
- package/src/controller/base-playlist-controller.ts +10 -27
- package/src/controller/base-stream-controller.ts +38 -160
- package/src/controller/buffer-controller.ts +92 -230
- package/src/controller/buffer-operation-queue.ts +19 -16
- package/src/controller/cap-level-controller.ts +2 -3
- package/src/controller/cmcd-controller.ts +14 -51
- package/src/controller/content-steering-controller.ts +15 -29
- package/src/controller/eme-controller.ts +23 -10
- package/src/controller/error-controller.ts +8 -6
- package/src/controller/fps-controller.ts +3 -8
- package/src/controller/fragment-tracker.ts +11 -15
- package/src/controller/gap-controller.ts +16 -43
- package/src/controller/id3-track-controller.ts +7 -7
- package/src/controller/latency-controller.ts +11 -9
- package/src/controller/level-controller.ts +19 -37
- package/src/controller/stream-controller.ts +32 -37
- package/src/controller/subtitle-stream-controller.ts +40 -28
- package/src/controller/subtitle-track-controller.ts +3 -5
- package/src/controller/timeline-controller.ts +21 -19
- package/src/crypt/aes-crypto.ts +2 -21
- package/src/crypt/decrypter.ts +16 -32
- package/src/crypt/fast-aes-key.ts +5 -28
- package/src/demux/audio/aacdemuxer.ts +2 -2
- package/src/demux/audio/ac3-demuxer.ts +3 -4
- package/src/demux/audio/adts.ts +4 -9
- package/src/demux/audio/base-audio-demuxer.ts +14 -16
- package/src/demux/audio/mp3demuxer.ts +3 -4
- package/src/demux/audio/mpegaudio.ts +1 -1
- package/src/demux/id3.ts +411 -0
- package/src/demux/mp4demuxer.ts +7 -7
- package/src/demux/sample-aes.ts +0 -2
- package/src/demux/transmuxer-interface.ts +12 -4
- package/src/demux/transmuxer-worker.ts +4 -4
- package/src/demux/transmuxer.ts +3 -16
- package/src/demux/tsdemuxer.ts +38 -75
- package/src/demux/video/avc-video-parser.ts +119 -208
- package/src/demux/video/base-video-parser.ts +18 -147
- package/src/demux/video/exp-golomb.ts +208 -0
- package/src/events.ts +1 -8
- package/src/exports-named.ts +1 -1
- package/src/hls.ts +38 -61
- package/src/loader/fragment-loader.ts +3 -10
- package/src/loader/key-loader.ts +1 -3
- package/src/loader/level-key.ts +9 -10
- package/src/loader/playlist-loader.ts +5 -4
- package/src/remux/mp4-generator.ts +1 -196
- package/src/remux/mp4-remuxer.ts +8 -24
- package/src/task-loop.ts +2 -5
- package/src/types/component-api.ts +1 -3
- package/src/types/demuxer.ts +0 -4
- package/src/types/events.ts +0 -4
- package/src/types/remuxer.ts +1 -1
- package/src/utils/buffer-helper.ts +31 -12
- package/src/utils/cea-608-parser.ts +3 -1
- package/src/utils/codecs.ts +5 -34
- package/src/utils/fetch-loader.ts +1 -1
- package/src/utils/imsc1-ttml-parser.ts +1 -1
- package/src/utils/keysystem-util.ts +6 -1
- package/src/utils/logger.ts +23 -58
- package/src/utils/mp4-tools.ts +3 -5
- package/src/utils/webvtt-parser.ts +1 -1
- package/src/crypt/decrypter-aes-mode.ts +0 -4
- package/src/demux/video/hevc-video-parser.ts +0 -749
- package/src/utils/encryption-methods-util.ts +0 -21
- package/src/utils/utf8-utils.ts +0 -18
package/src/crypt/aes-crypto.ts
CHANGED
@@ -1,32 +1,13 @@
|
|
1
|
-
import { DecrypterAesMode } from './decrypter-aes-mode';
|
2
|
-
|
3
1
|
export default class AESCrypto {
|
4
2
|
private subtle: SubtleCrypto;
|
5
3
|
private aesIV: Uint8Array;
|
6
|
-
private aesMode: DecrypterAesMode;
|
7
4
|
|
8
|
-
constructor(subtle: SubtleCrypto, iv: Uint8Array
|
5
|
+
constructor(subtle: SubtleCrypto, iv: Uint8Array) {
|
9
6
|
this.subtle = subtle;
|
10
7
|
this.aesIV = iv;
|
11
|
-
this.aesMode = aesMode;
|
12
8
|
}
|
13
9
|
|
14
10
|
decrypt(data: ArrayBuffer, key: CryptoKey) {
|
15
|
-
|
16
|
-
case DecrypterAesMode.cbc:
|
17
|
-
return this.subtle.decrypt(
|
18
|
-
{ name: 'AES-CBC', iv: this.aesIV },
|
19
|
-
key,
|
20
|
-
data,
|
21
|
-
);
|
22
|
-
case DecrypterAesMode.ctr:
|
23
|
-
return this.subtle.decrypt(
|
24
|
-
{ name: 'AES-CTR', counter: this.aesIV, length: 64 }, //64 : NIST SP800-38A standard suggests that the counter should occupy half of the counter block
|
25
|
-
key,
|
26
|
-
data,
|
27
|
-
);
|
28
|
-
default:
|
29
|
-
throw new Error(`[AESCrypto] invalid aes mode ${this.aesMode}`);
|
30
|
-
}
|
11
|
+
return this.subtle.decrypt({ name: 'AES-CBC', iv: this.aesIV }, key, data);
|
31
12
|
}
|
32
13
|
}
|
package/src/crypt/decrypter.ts
CHANGED
@@ -4,7 +4,6 @@ import AESDecryptor, { removePadding } from './aes-decryptor';
|
|
4
4
|
import { logger } from '../utils/logger';
|
5
5
|
import { appendUint8Array } from '../utils/mp4-tools';
|
6
6
|
import { sliceUint8 } from '../utils/typed-array';
|
7
|
-
import { DecrypterAesMode } from './decrypter-aes-mode';
|
8
7
|
import type { HlsConfig } from '../config';
|
9
8
|
|
10
9
|
const CHUNK_SIZE = 16; // 16 bytes, 128 bits
|
@@ -20,10 +19,9 @@ export default class Decrypter {
|
|
20
19
|
private currentIV: ArrayBuffer | null = null;
|
21
20
|
private currentResult: ArrayBuffer | null = null;
|
22
21
|
private useSoftware: boolean;
|
23
|
-
private enableSoftwareAES: boolean;
|
24
22
|
|
25
23
|
constructor(config: HlsConfig, { removePKCS7Padding = true } = {}) {
|
26
|
-
this.
|
24
|
+
this.useSoftware = config.enableSoftwareAES;
|
27
25
|
this.removePKCS7Padding = removePKCS7Padding;
|
28
26
|
// built in decryptor expects PKCS7 padding
|
29
27
|
if (removePKCS7Padding) {
|
@@ -38,6 +36,7 @@ export default class Decrypter {
|
|
38
36
|
/* no-op */
|
39
37
|
}
|
40
38
|
}
|
39
|
+
|
41
40
|
this.useSoftware = !this.subtle;
|
42
41
|
}
|
43
42
|
|
@@ -82,11 +81,10 @@ export default class Decrypter {
|
|
82
81
|
data: Uint8Array | ArrayBuffer,
|
83
82
|
key: ArrayBuffer,
|
84
83
|
iv: ArrayBuffer,
|
85
|
-
aesMode: DecrypterAesMode,
|
86
84
|
): Promise<ArrayBuffer> {
|
87
85
|
if (this.useSoftware) {
|
88
86
|
return new Promise((resolve, reject) => {
|
89
|
-
this.softwareDecrypt(new Uint8Array(data), key, iv
|
87
|
+
this.softwareDecrypt(new Uint8Array(data), key, iv);
|
90
88
|
const decryptResult = this.flush();
|
91
89
|
if (decryptResult) {
|
92
90
|
resolve(decryptResult.buffer);
|
@@ -95,7 +93,7 @@ export default class Decrypter {
|
|
95
93
|
}
|
96
94
|
});
|
97
95
|
}
|
98
|
-
return this.webCryptoDecrypt(new Uint8Array(data), key, iv
|
96
|
+
return this.webCryptoDecrypt(new Uint8Array(data), key, iv);
|
99
97
|
}
|
100
98
|
|
101
99
|
// Software decryption is progressive. Progressive decryption may not return a result on each call. Any cached
|
@@ -104,13 +102,8 @@ export default class Decrypter {
|
|
104
102
|
data: Uint8Array,
|
105
103
|
key: ArrayBuffer,
|
106
104
|
iv: ArrayBuffer,
|
107
|
-
aesMode: DecrypterAesMode,
|
108
105
|
): ArrayBuffer | null {
|
109
106
|
const { currentIV, currentResult, remainderData } = this;
|
110
|
-
if (aesMode !== DecrypterAesMode.cbc || key.byteLength !== 16) {
|
111
|
-
logger.warn('SoftwareDecrypt: can only handle AES-128-CBC');
|
112
|
-
return null;
|
113
|
-
}
|
114
107
|
this.logOnce('JS AES decrypt');
|
115
108
|
// The output is staggered during progressive parsing - the current result is cached, and emitted on the next call
|
116
109
|
// This is done in order to strip PKCS7 padding, which is found at the end of each segment. We only know we've reached
|
@@ -153,24 +146,23 @@ export default class Decrypter {
|
|
153
146
|
data: Uint8Array,
|
154
147
|
key: ArrayBuffer,
|
155
148
|
iv: ArrayBuffer,
|
156
|
-
aesMode: DecrypterAesMode,
|
157
149
|
): Promise<ArrayBuffer> {
|
158
150
|
if (this.key !== key || !this.fastAesKey) {
|
159
151
|
if (!this.subtle) {
|
160
|
-
return Promise.resolve(this.onWebCryptoError(data, key, iv
|
152
|
+
return Promise.resolve(this.onWebCryptoError(data, key, iv));
|
161
153
|
}
|
162
154
|
this.key = key;
|
163
|
-
this.fastAesKey = new FastAESKey(this.subtle, key
|
155
|
+
this.fastAesKey = new FastAESKey(this.subtle, key);
|
164
156
|
}
|
165
157
|
return this.fastAesKey
|
166
158
|
.expandKey()
|
167
|
-
.then((aesKey
|
159
|
+
.then((aesKey) => {
|
168
160
|
// decrypt using web crypto
|
169
161
|
if (!this.subtle) {
|
170
162
|
return Promise.reject(new Error('web crypto not initialized'));
|
171
163
|
}
|
172
164
|
this.logOnce('WebCrypto AES decrypt');
|
173
|
-
const crypto = new AESCrypto(this.subtle, new Uint8Array(iv)
|
165
|
+
const crypto = new AESCrypto(this.subtle, new Uint8Array(iv));
|
174
166
|
return crypto.decrypt(data.buffer, aesKey);
|
175
167
|
})
|
176
168
|
.catch((err) => {
|
@@ -178,7 +170,7 @@ export default class Decrypter {
|
|
178
170
|
`[decrypter]: WebCrypto Error, disable WebCrypto API, ${err.name}: ${err.message}`,
|
179
171
|
);
|
180
172
|
|
181
|
-
return this.onWebCryptoError(data, key, iv
|
173
|
+
return this.onWebCryptoError(data, key, iv);
|
182
174
|
});
|
183
175
|
}
|
184
176
|
|
@@ -186,23 +178,15 @@ export default class Decrypter {
|
|
186
178
|
data: Uint8Array,
|
187
179
|
key: ArrayBuffer,
|
188
180
|
iv: ArrayBuffer,
|
189
|
-
aesMode: DecrypterAesMode,
|
190
181
|
): ArrayBuffer | never {
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
if (decryptResult) {
|
198
|
-
return decryptResult.buffer;
|
199
|
-
}
|
182
|
+
this.useSoftware = true;
|
183
|
+
this.logEnabled = true;
|
184
|
+
this.softwareDecrypt(data, key, iv);
|
185
|
+
const decryptResult = this.flush();
|
186
|
+
if (decryptResult) {
|
187
|
+
return decryptResult.buffer;
|
200
188
|
}
|
201
|
-
throw new Error(
|
202
|
-
'WebCrypto' +
|
203
|
-
(enableSoftwareAES ? ' and softwareDecrypt' : '') +
|
204
|
-
': failed to decrypt data',
|
205
|
-
);
|
189
|
+
throw new Error('WebCrypto and softwareDecrypt: failed to decrypt data');
|
206
190
|
}
|
207
191
|
|
208
192
|
private getValidChunk(data: Uint8Array): Uint8Array {
|
@@ -1,39 +1,16 @@
|
|
1
|
-
import { DecrypterAesMode } from './decrypter-aes-mode';
|
2
|
-
|
3
1
|
export default class FastAESKey {
|
4
2
|
private subtle: SubtleCrypto;
|
5
3
|
private key: ArrayBuffer;
|
6
|
-
private aesMode: DecrypterAesMode;
|
7
4
|
|
8
|
-
constructor(
|
9
|
-
subtle: SubtleCrypto,
|
10
|
-
key: ArrayBuffer,
|
11
|
-
aesMode: DecrypterAesMode,
|
12
|
-
) {
|
5
|
+
constructor(subtle: SubtleCrypto, key: ArrayBuffer) {
|
13
6
|
this.subtle = subtle;
|
14
7
|
this.key = key;
|
15
|
-
this.aesMode = aesMode;
|
16
8
|
}
|
17
9
|
|
18
10
|
expandKey() {
|
19
|
-
|
20
|
-
|
21
|
-
'
|
22
|
-
|
23
|
-
{ name: subtleAlgoName },
|
24
|
-
false,
|
25
|
-
['encrypt', 'decrypt'],
|
26
|
-
);
|
27
|
-
}
|
28
|
-
}
|
29
|
-
|
30
|
-
function getSubtleAlgoName(aesMode: DecrypterAesMode) {
|
31
|
-
switch (aesMode) {
|
32
|
-
case DecrypterAesMode.cbc:
|
33
|
-
return 'AES-CBC';
|
34
|
-
case DecrypterAesMode.ctr:
|
35
|
-
return 'AES-CTR';
|
36
|
-
default:
|
37
|
-
throw new Error(`[FastAESKey] invalid aes mode ${aesMode}`);
|
11
|
+
return this.subtle.importKey('raw', this.key, { name: 'AES-CBC' }, false, [
|
12
|
+
'encrypt',
|
13
|
+
'decrypt',
|
14
|
+
]);
|
38
15
|
}
|
39
16
|
}
|
@@ -5,7 +5,7 @@ import BaseAudioDemuxer from './base-audio-demuxer';
|
|
5
5
|
import * as ADTS from './adts';
|
6
6
|
import * as MpegAudio from './mpegaudio';
|
7
7
|
import { logger } from '../../utils/logger';
|
8
|
-
import
|
8
|
+
import * as ID3 from '../id3';
|
9
9
|
import type { HlsEventEmitter } from '../../events';
|
10
10
|
import type { HlsConfig } from '../../config';
|
11
11
|
|
@@ -51,7 +51,7 @@ class AACDemuxer extends BaseAudioDemuxer {
|
|
51
51
|
// Look for ADTS header | 1111 1111 | 1111 X00X | where X can be either 0 or 1
|
52
52
|
// Layer bits (position 14 and 15) in header should be always 0 for ADTS
|
53
53
|
// More info https://wiki.multimedia.cx/index.php?title=ADTS
|
54
|
-
const id3Data =
|
54
|
+
const id3Data = ID3.getID3Data(data, 0);
|
55
55
|
let offset = id3Data?.length || 0;
|
56
56
|
|
57
57
|
if (MpegAudio.probe(data, offset)) {
|
@@ -1,6 +1,5 @@
|
|
1
1
|
import BaseAudioDemuxer from './base-audio-demuxer';
|
2
|
-
import {
|
3
|
-
import { getId3Timestamp } from '@svta/common-media-library/id3/getId3Timestamp';
|
2
|
+
import { getID3Data, getTimeStamp } from '../id3';
|
4
3
|
import { getAudioBSID } from './dolby';
|
5
4
|
import type { HlsEventEmitter } from '../../events';
|
6
5
|
import type { AudioFrame, DemuxedAudioTrack } from '../../types/demuxer';
|
@@ -62,7 +61,7 @@ export class AC3Demuxer extends BaseAudioDemuxer {
|
|
62
61
|
return false;
|
63
62
|
}
|
64
63
|
|
65
|
-
const id3Data =
|
64
|
+
const id3Data = getID3Data(data, 0);
|
66
65
|
if (!id3Data) {
|
67
66
|
return false;
|
68
67
|
}
|
@@ -72,7 +71,7 @@ export class AC3Demuxer extends BaseAudioDemuxer {
|
|
72
71
|
if (
|
73
72
|
data[offset] === 0x0b &&
|
74
73
|
data[offset + 1] === 0x77 &&
|
75
|
-
|
74
|
+
getTimeStamp(id3Data) !== undefined &&
|
76
75
|
// check the bsid to confirm ac-3
|
77
76
|
getAudioBSID(data, offset) < 16
|
78
77
|
) {
|
package/src/demux/audio/adts.ts
CHANGED
@@ -17,7 +17,6 @@ type AudioConfig = {
|
|
17
17
|
samplerate: number;
|
18
18
|
channelCount: number;
|
19
19
|
codec: string;
|
20
|
-
parsedCodec: string;
|
21
20
|
manifestCodec: string;
|
22
21
|
};
|
23
22
|
|
@@ -33,7 +32,6 @@ export function getAudioConfig(
|
|
33
32
|
audioCodec: string,
|
34
33
|
): AudioConfig | void {
|
35
34
|
let adtsObjectType: number;
|
36
|
-
let originalAdtsObjectType: number;
|
37
35
|
let adtsExtensionSamplingIndex: number;
|
38
36
|
let adtsChannelConfig: number;
|
39
37
|
let config: number[];
|
@@ -44,8 +42,7 @@ export function getAudioConfig(
|
|
44
42
|
8000, 7350,
|
45
43
|
];
|
46
44
|
// byte 2
|
47
|
-
adtsObjectType =
|
48
|
-
((data[offset + 2] & 0xc0) >>> 6) + 1;
|
45
|
+
adtsObjectType = ((data[offset + 2] & 0xc0) >>> 6) + 1;
|
49
46
|
const adtsSamplingIndex = (data[offset + 2] & 0x3c) >>> 2;
|
50
47
|
if (adtsSamplingIndex > adtsSamplingRates.length - 1) {
|
51
48
|
const error = new Error(`invalid ADTS sampling index:${adtsSamplingIndex}`);
|
@@ -64,8 +61,8 @@ export function getAudioConfig(
|
|
64
61
|
logger.log(
|
65
62
|
`manifest codec:${audioCodec}, ADTS type:${adtsObjectType}, samplingIndex:${adtsSamplingIndex}`,
|
66
63
|
);
|
67
|
-
//
|
68
|
-
if (/firefox
|
64
|
+
// firefox: freq less than 24kHz = AAC SBR (HE-AAC)
|
65
|
+
if (/firefox/i.test(userAgent)) {
|
69
66
|
if (adtsSamplingIndex >= 6) {
|
70
67
|
adtsObjectType = 5;
|
71
68
|
config = new Array(4);
|
@@ -170,7 +167,6 @@ export function getAudioConfig(
|
|
170
167
|
samplerate: adtsSamplingRates[adtsSamplingIndex],
|
171
168
|
channelCount: adtsChannelConfig,
|
172
169
|
codec: 'mp4a.40.' + adtsObjectType,
|
173
|
-
parsedCodec: 'mp4a.40.' + originalAdtsObjectType,
|
174
170
|
manifestCodec,
|
175
171
|
};
|
176
172
|
}
|
@@ -248,9 +244,8 @@ export function initTrackConfig(
|
|
248
244
|
track.channelCount = config.channelCount;
|
249
245
|
track.codec = config.codec;
|
250
246
|
track.manifestCodec = config.manifestCodec;
|
251
|
-
track.parsedCodec = config.parsedCodec;
|
252
247
|
logger.log(
|
253
|
-
`parsed codec:${track.
|
248
|
+
`parsed codec:${track.codec}, rate:${config.samplerate}, channels:${config.channelCount}`,
|
254
249
|
);
|
255
250
|
}
|
256
251
|
}
|
@@ -1,21 +1,19 @@
|
|
1
|
+
import * as ID3 from '../id3';
|
1
2
|
import {
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
3
|
+
DemuxerResult,
|
4
|
+
Demuxer,
|
5
|
+
DemuxedAudioTrack,
|
6
|
+
AudioFrame,
|
7
|
+
DemuxedMetadataTrack,
|
8
|
+
DemuxedVideoTrackBase,
|
9
|
+
DemuxedUserdataTrack,
|
10
|
+
KeyData,
|
10
11
|
MetadataSchema,
|
11
12
|
} from '../../types/demuxer';
|
12
13
|
import { dummyTrack } from '../dummy-demuxed-track';
|
13
14
|
import { appendUint8Array } from '../../utils/mp4-tools';
|
14
15
|
import { sliceUint8 } from '../../utils/typed-array';
|
15
16
|
import { RationalTimestamp } from '../../utils/timescale-conversion';
|
16
|
-
import { getId3Data } from '@svta/common-media-library/id3/getId3Data';
|
17
|
-
import { getId3Timestamp } from '@svta/common-media-library/id3/getId3Timestamp';
|
18
|
-
import { canParseId3 } from '@svta/common-media-library/id3/canParseId3';
|
19
17
|
|
20
18
|
class BaseAudioDemuxer implements Demuxer {
|
21
19
|
protected _audioTrack!: DemuxedAudioTrack;
|
@@ -71,12 +69,12 @@ class BaseAudioDemuxer implements Demuxer {
|
|
71
69
|
this.cachedData = null;
|
72
70
|
}
|
73
71
|
|
74
|
-
let id3Data: Uint8Array | undefined =
|
72
|
+
let id3Data: Uint8Array | undefined = ID3.getID3Data(data, 0);
|
75
73
|
let offset = id3Data ? id3Data.length : 0;
|
76
74
|
let lastDataIndex;
|
77
75
|
const track = this._audioTrack;
|
78
76
|
const id3Track = this._id3Track;
|
79
|
-
const timestamp = id3Data ?
|
77
|
+
const timestamp = id3Data ? ID3.getTimeStamp(id3Data) : undefined;
|
80
78
|
const length = data.length;
|
81
79
|
|
82
80
|
if (
|
@@ -113,9 +111,9 @@ class BaseAudioDemuxer implements Demuxer {
|
|
113
111
|
} else {
|
114
112
|
offset = length;
|
115
113
|
}
|
116
|
-
} else if (
|
117
|
-
// after a canParse, a call to
|
118
|
-
id3Data =
|
114
|
+
} else if (ID3.canParse(data, offset)) {
|
115
|
+
// after a ID3.canParse, a call to ID3.getID3Data *should* always returns some data
|
116
|
+
id3Data = ID3.getID3Data(data, offset)!;
|
119
117
|
id3Track.samples.push({
|
120
118
|
pts: this.lastPTS,
|
121
119
|
dts: this.lastPTS,
|
@@ -2,11 +2,10 @@
|
|
2
2
|
* MP3 demuxer
|
3
3
|
*/
|
4
4
|
import BaseAudioDemuxer from './base-audio-demuxer';
|
5
|
+
import { getID3Data, getTimeStamp } from '../id3';
|
5
6
|
import { getAudioBSID } from './dolby';
|
6
7
|
import { logger } from '../../utils/logger';
|
7
8
|
import * as MpegAudio from './mpegaudio';
|
8
|
-
import { getId3Data } from '@svta/common-media-library/id3/getId3Data';
|
9
|
-
import { getId3Timestamp } from '@svta/common-media-library/id3/getId3Timestamp';
|
10
9
|
|
11
10
|
class MP3Demuxer extends BaseAudioDemuxer {
|
12
11
|
resetInitSegment(
|
@@ -40,7 +39,7 @@ class MP3Demuxer extends BaseAudioDemuxer {
|
|
40
39
|
// Look for MPEG header | 1111 1111 | 111X XYZX | where X can be either 0 or 1 and Y or Z should be 1
|
41
40
|
// Layer bits (position 14 and 15) in header should be always different from 0 (Layer I or Layer II or Layer III)
|
42
41
|
// More info http://www.mp3-tech.org/programmer/frame_header.html
|
43
|
-
const id3Data =
|
42
|
+
const id3Data = getID3Data(data, 0);
|
44
43
|
let offset = id3Data?.length || 0;
|
45
44
|
|
46
45
|
// Check for ac-3|ec-3 sync bytes and return false if present
|
@@ -48,7 +47,7 @@ class MP3Demuxer extends BaseAudioDemuxer {
|
|
48
47
|
id3Data &&
|
49
48
|
data[offset] === 0x0b &&
|
50
49
|
data[offset + 1] === 0x77 &&
|
51
|
-
|
50
|
+
getTimeStamp(id3Data) !== undefined &&
|
52
51
|
// check the bsid to confirm ac-3 or ec-3 (not mp3)
|
53
52
|
getAudioBSID(data, offset) <= 16
|
54
53
|
) {
|