@remotion/media-parser 4.0.237 → 4.0.240
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/dist/aac-codecprivate.d.ts +2 -9
- package/dist/aac-codecprivate.js +69 -34
- package/dist/add-avc-profile-to-track.js +4 -23
- package/dist/boxes/avc/codec-private.d.ts +2 -0
- package/dist/boxes/avc/codec-private.js +28 -0
- package/dist/boxes/avc/codec-string.d.ts +2 -0
- package/dist/boxes/avc/codec-string.js +7 -0
- package/dist/boxes/avc/color.d.ts +6 -0
- package/dist/boxes/avc/color.js +39 -0
- package/dist/boxes/avc/interpret-sps.d.ts +11 -0
- package/dist/boxes/avc/interpret-sps.js +44 -0
- package/dist/boxes/avc/key.d.ts +2 -0
- package/dist/boxes/avc/key.js +11 -0
- package/dist/boxes/avc/parse-avc.d.ts +36 -3
- package/dist/boxes/avc/parse-avc.js +161 -4
- package/dist/boxes/avc/sps-and-pps.d.ts +3 -0
- package/dist/boxes/avc/sps-and-pps.js +12 -0
- package/dist/boxes/iso-base-media/get-video-codec-from-iso-track.d.ts +2 -0
- package/dist/boxes/iso-base-media/get-video-codec-from-iso-track.js +55 -0
- package/dist/boxes/iso-base-media/make-track.js +2 -1
- package/dist/boxes/iso-base-media/mdat/mdat.js +8 -14
- package/dist/boxes/iso-base-media/process-box.js +1 -1
- package/dist/boxes/riff/parse-box.js +2 -2
- package/dist/boxes/riff/parse-movi.js +12 -14
- package/dist/boxes/transport-stream/adts-header.d.ts +7 -0
- package/dist/boxes/transport-stream/adts-header.js +56 -0
- package/dist/boxes/transport-stream/boxes.d.ts +41 -0
- package/dist/boxes/transport-stream/boxes.js +2 -0
- package/dist/boxes/transport-stream/discard-rest-of-packet.d.ts +3 -0
- package/dist/boxes/transport-stream/discard-rest-of-packet.js +13 -0
- package/dist/boxes/transport-stream/find-separator.d.ts +2 -0
- package/dist/boxes/transport-stream/find-separator.js +30 -0
- package/dist/boxes/transport-stream/get-tracks.d.ts +5 -0
- package/dist/boxes/transport-stream/get-tracks.js +33 -0
- package/dist/boxes/transport-stream/handle-aac-packet.d.ts +7 -0
- package/dist/boxes/transport-stream/handle-aac-packet.js +50 -0
- package/dist/boxes/transport-stream/handle-avc-packet.d.ts +8 -0
- package/dist/boxes/transport-stream/handle-avc-packet.js +60 -0
- package/dist/boxes/transport-stream/next-pes-header-store.d.ts +6 -0
- package/dist/boxes/transport-stream/next-pes-header-store.js +18 -0
- package/dist/boxes/transport-stream/parse-packet.d.ts +13 -0
- package/dist/boxes/transport-stream/parse-packet.js +80 -0
- package/dist/boxes/transport-stream/parse-pat.d.ts +8 -0
- package/dist/boxes/transport-stream/parse-pat.js +49 -0
- package/dist/boxes/transport-stream/parse-pes.d.ts +8 -0
- package/dist/boxes/transport-stream/parse-pes.js +76 -0
- package/dist/boxes/transport-stream/parse-pmt.d.ts +11 -0
- package/dist/boxes/transport-stream/parse-pmt.js +64 -0
- package/dist/boxes/transport-stream/parse-stream-packet.d.ts +15 -0
- package/dist/boxes/transport-stream/parse-stream-packet.js +107 -0
- package/dist/boxes/transport-stream/parse-transport-stream.d.ts +14 -0
- package/dist/boxes/transport-stream/parse-transport-stream.js +72 -0
- package/dist/boxes/transport-stream/process-stream-buffers.d.ts +19 -0
- package/dist/boxes/transport-stream/process-stream-buffers.js +42 -0
- package/dist/boxes/transport-stream/traversal.d.ts +6 -0
- package/dist/boxes/transport-stream/traversal.js +30 -0
- package/dist/boxes/webm/ebml.d.ts +1 -1
- package/dist/boxes/webm/parse-ebml.js +1 -1
- package/dist/buffer-iterator.d.ts +2 -0
- package/dist/buffer-iterator.js +25 -0
- package/dist/convert-audio-or-video-sample.d.ts +2 -0
- package/dist/convert-audio-or-video-sample.js +17 -0
- package/dist/create/iso-base-media/create-iso-base-media.js +38 -19
- package/dist/create/iso-base-media/trak/mdia/minf/create-stbl.js +7 -1
- package/dist/create/iso-base-media/trak/mdia/minf/stbl/create-stts.js +3 -0
- package/dist/create/media-fn.d.ts +0 -1
- package/dist/create/progress-tracker.d.ts +2 -0
- package/dist/create/progress-tracker.js +32 -8
- package/dist/emit-available-info.js +13 -2
- package/dist/esm/index.mjs +1325 -247
- package/dist/get-container.d.ts +1 -1
- package/dist/get-container.js +3 -0
- package/dist/get-duration.js +4 -1
- package/dist/get-fps.js +8 -2
- package/dist/get-location.d.ts +13 -0
- package/dist/get-location.js +40 -0
- package/dist/get-tracks.d.ts +4 -3
- package/dist/get-tracks.js +9 -2
- package/dist/get-video-codec.d.ts +1 -2
- package/dist/get-video-codec.js +9 -148
- package/dist/has-all-info.js +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/metadata/get-metadata.js +3 -0
- package/dist/options.d.ts +11 -3
- package/dist/parse-media.js +3 -3
- package/dist/parse-result.d.ts +7 -2
- package/dist/parse-video.js +15 -0
- package/dist/register-track.d.ts +5 -5
- package/dist/register-track.js +16 -10
- package/dist/state/can-skip-tracks.js +1 -0
- package/dist/state/has-tracks-section.d.ts +3 -0
- package/dist/state/has-tracks-section.js +5 -0
- package/dist/state/parser-state.d.ts +2 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/webcodec-sample-types.d.ts +9 -2
- package/package.json +3 -3
- package/dist/add-new-matroska-tracks.d.ts +0 -13
- package/dist/add-new-matroska-tracks.js +0 -29
- package/dist/boxes/iso-base-media/meta/keys.d.ts +0 -10
- package/dist/boxes/iso-base-media/meta/keys.js +0 -17
- package/dist/boxes/iso-base-media/meta/list.d.ts +0 -12
- package/dist/boxes/iso-base-media/meta/list.js +0 -33
- package/dist/boxes/riff/strf.d.ts +0 -7
- package/dist/boxes/riff/strf.js +0 -67
- package/dist/create/mp3/create-mp3.d.ts +0 -2
- package/dist/create/mp3/create-mp3.js +0 -49
- package/dist/get-metadata.d.ts +0 -7
- package/dist/get-metadata.js +0 -63
- package/dist/parser-state.d.ts +0 -33
- package/dist/parser-state.js +0 -162
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// https://en.wikipedia.org/wiki/Program-specific_information
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.parsePat = void 0;
|
|
5
|
+
const discard_rest_of_packet_1 = require("./discard-rest-of-packet");
|
|
6
|
+
const parsePatTable = (iterator, tableId) => {
|
|
7
|
+
iterator.getUint16(); // table ID extension
|
|
8
|
+
iterator.startReadingBits();
|
|
9
|
+
iterator.getBits(7); // reserved
|
|
10
|
+
iterator.getBits(1); // current / next indicator;
|
|
11
|
+
const sectionNumber = iterator.getBits(8);
|
|
12
|
+
const lastSectionNumber = iterator.getBits(8);
|
|
13
|
+
if (tableId !== 0) {
|
|
14
|
+
throw new Error('Invalid table ID: ' + tableId);
|
|
15
|
+
}
|
|
16
|
+
const tables = [];
|
|
17
|
+
for (let i = sectionNumber; i <= lastSectionNumber; i++) {
|
|
18
|
+
const programNumber = iterator.getBits(16); // program number
|
|
19
|
+
iterator.getBits(3); // reserved
|
|
20
|
+
const programMapIdentifier = iterator.getBits(13); // program map PID
|
|
21
|
+
tables.push({
|
|
22
|
+
type: 'transport-stream-program-association-table',
|
|
23
|
+
programNumber,
|
|
24
|
+
programMapIdentifier,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
iterator.stopReadingBits();
|
|
28
|
+
return {
|
|
29
|
+
type: 'transport-stream-pat-box',
|
|
30
|
+
tableId: tableId.toString(16),
|
|
31
|
+
pat: tables,
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
const parsePat = (iterator) => {
|
|
35
|
+
iterator.startReadingBits();
|
|
36
|
+
const tableId = iterator.getBits(8);
|
|
37
|
+
iterator.getBits(1); // syntax indicator
|
|
38
|
+
iterator.getBits(1); // private bit
|
|
39
|
+
iterator.getBits(4);
|
|
40
|
+
const sectionLength = iterator.getBits(10);
|
|
41
|
+
if (sectionLength > 1021) {
|
|
42
|
+
throw new Error('Invalid section length');
|
|
43
|
+
}
|
|
44
|
+
iterator.stopReadingBits();
|
|
45
|
+
const tables = parsePatTable(iterator, tableId);
|
|
46
|
+
(0, discard_rest_of_packet_1.discardRestOfPacket)(iterator);
|
|
47
|
+
return tables;
|
|
48
|
+
};
|
|
49
|
+
exports.parsePat = parsePat;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parsePes = void 0;
|
|
4
|
+
const parsePes = (iterator) => {
|
|
5
|
+
const ident = iterator.getUint24();
|
|
6
|
+
if (ident !== 0x000001) {
|
|
7
|
+
throw new Error(`Unexpected PES packet start code: ${ident.toString(16)}`);
|
|
8
|
+
}
|
|
9
|
+
const streamId = iterator.getUint8();
|
|
10
|
+
iterator.getUint16(); // PES packet length, is most of the time 0, so useless
|
|
11
|
+
iterator.startReadingBits();
|
|
12
|
+
const markerBits = iterator.getBits(2);
|
|
13
|
+
if (markerBits !== 0b10) {
|
|
14
|
+
throw new Error(`Invalid marker bits: ${markerBits}`);
|
|
15
|
+
}
|
|
16
|
+
const scrambled = iterator.getBits(2);
|
|
17
|
+
if (scrambled !== 0b00) {
|
|
18
|
+
throw new Error(`Only supporting non-scrambled streams`);
|
|
19
|
+
}
|
|
20
|
+
const priority = iterator.getBits(1);
|
|
21
|
+
iterator.getBits(1); // data alignment indicator
|
|
22
|
+
iterator.getBits(1); // copy right
|
|
23
|
+
iterator.getBits(1); // original or copy
|
|
24
|
+
const ptsPresent = iterator.getBits(1);
|
|
25
|
+
const dtsPresent = iterator.getBits(1);
|
|
26
|
+
if (!ptsPresent && dtsPresent) {
|
|
27
|
+
throw new Error(`DTS is present but not PTS, this is not allowed in the spec`);
|
|
28
|
+
}
|
|
29
|
+
iterator.getBits(1); // escr flag
|
|
30
|
+
iterator.getBits(1); // es rate flag
|
|
31
|
+
iterator.getBits(1); // dsm trick mode flag
|
|
32
|
+
iterator.getBits(1); // additional copy info flag
|
|
33
|
+
iterator.getBits(1); // crc flag
|
|
34
|
+
iterator.getBits(1); // extension flag
|
|
35
|
+
const pesHeaderLength = iterator.getBits(8);
|
|
36
|
+
const offset = iterator.counter.getOffset();
|
|
37
|
+
let pts = null;
|
|
38
|
+
if (!ptsPresent) {
|
|
39
|
+
throw new Error(`PTS is required`);
|
|
40
|
+
}
|
|
41
|
+
const fourBits = iterator.getBits(4);
|
|
42
|
+
if (fourBits !== 0b0011 && fourBits !== 0b0010) {
|
|
43
|
+
throw new Error(`Invalid PTS marker bits: ${fourBits}`);
|
|
44
|
+
}
|
|
45
|
+
const pts1 = iterator.getBits(3);
|
|
46
|
+
iterator.getBits(1); // marker bit
|
|
47
|
+
const pts2 = iterator.getBits(15);
|
|
48
|
+
iterator.getBits(1); // marker bit
|
|
49
|
+
const pts3 = iterator.getBits(15);
|
|
50
|
+
iterator.getBits(1); // marker bit
|
|
51
|
+
pts = (pts1 << 30) | (pts2 << 15) | pts3;
|
|
52
|
+
let dts = null;
|
|
53
|
+
if (dtsPresent) {
|
|
54
|
+
const _fourBits = iterator.getBits(4);
|
|
55
|
+
if (_fourBits !== 0b0001) {
|
|
56
|
+
throw new Error(`Invalid DTS marker bits: ${_fourBits}`);
|
|
57
|
+
}
|
|
58
|
+
const dts1 = iterator.getBits(3);
|
|
59
|
+
iterator.getBits(1); // marker bit
|
|
60
|
+
const dts2 = iterator.getBits(15);
|
|
61
|
+
iterator.getBits(1); // marker bit
|
|
62
|
+
const dts3 = iterator.getBits(15);
|
|
63
|
+
iterator.getBits(1); // marker bit
|
|
64
|
+
dts = (dts1 << 30) | (dts2 << 15) | dts3;
|
|
65
|
+
}
|
|
66
|
+
iterator.stopReadingBits();
|
|
67
|
+
iterator.discard(pesHeaderLength - (iterator.counter.getOffset() - offset));
|
|
68
|
+
const packet = {
|
|
69
|
+
dts,
|
|
70
|
+
pts,
|
|
71
|
+
streamId,
|
|
72
|
+
priority,
|
|
73
|
+
};
|
|
74
|
+
return packet;
|
|
75
|
+
};
|
|
76
|
+
exports.parsePes = parsePes;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { BufferIterator } from '../../buffer-iterator';
|
|
2
|
+
import type { TransportStreamPMTBox } from './boxes';
|
|
3
|
+
export type TransportStreamEntry = {
|
|
4
|
+
streamType: number;
|
|
5
|
+
pid: number;
|
|
6
|
+
};
|
|
7
|
+
export type TransportStreamProgramMapTable = {
|
|
8
|
+
type: 'transport-stream-program-map-table';
|
|
9
|
+
streams: TransportStreamEntry[];
|
|
10
|
+
};
|
|
11
|
+
export declare const parsePmt: (iterator: BufferIterator) => TransportStreamPMTBox;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parsePmt = void 0;
|
|
4
|
+
const discard_rest_of_packet_1 = require("./discard-rest-of-packet");
|
|
5
|
+
const parsePmtTable = ({ iterator, tableId, sectionLength, }) => {
|
|
6
|
+
const start = iterator.counter.getOffset();
|
|
7
|
+
iterator.getUint16(); // table ID extension
|
|
8
|
+
iterator.startReadingBits();
|
|
9
|
+
iterator.getBits(7); // reserved
|
|
10
|
+
iterator.getBits(1); // current / next indicator;
|
|
11
|
+
const sectionNumber = iterator.getBits(8);
|
|
12
|
+
const lastSectionNumber = iterator.getBits(8);
|
|
13
|
+
const tables = [];
|
|
14
|
+
for (let i = sectionNumber; i <= lastSectionNumber; i++) {
|
|
15
|
+
iterator.getBits(3); // reserved
|
|
16
|
+
iterator.getBits(13); // PCR PID
|
|
17
|
+
iterator.getBits(4); // reserved
|
|
18
|
+
const programInfoLength = iterator.getBits(12);
|
|
19
|
+
const streams = [];
|
|
20
|
+
while (true) {
|
|
21
|
+
const streamType = iterator.getBits(8);
|
|
22
|
+
iterator.getBits(3); // reserved
|
|
23
|
+
const elementaryPid = iterator.getBits(13);
|
|
24
|
+
iterator.getBits(4); // reserved
|
|
25
|
+
const esInfoLength = iterator.getBits(12);
|
|
26
|
+
iterator.getBits(esInfoLength * 8);
|
|
27
|
+
streams.push({ streamType, pid: elementaryPid });
|
|
28
|
+
iterator.getBits(programInfoLength * 8); // program descriptor
|
|
29
|
+
const remaining = sectionLength - (iterator.counter.getOffset() - start);
|
|
30
|
+
if (remaining <= 4) {
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
tables.push({
|
|
35
|
+
type: 'transport-stream-program-map-table',
|
|
36
|
+
streams,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
if (tables.length !== 1) {
|
|
40
|
+
throw new Error('Does not PMT table with more than 1 entry, uncommon');
|
|
41
|
+
}
|
|
42
|
+
iterator.stopReadingBits();
|
|
43
|
+
return {
|
|
44
|
+
type: 'transport-stream-pmt-box',
|
|
45
|
+
tableId,
|
|
46
|
+
streams: tables[0].streams,
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
const parsePmt = (iterator) => {
|
|
50
|
+
iterator.startReadingBits();
|
|
51
|
+
const tableId = iterator.getBits(8);
|
|
52
|
+
iterator.getBits(1); // syntax indicator
|
|
53
|
+
iterator.getBits(1); // private bit
|
|
54
|
+
iterator.getBits(4);
|
|
55
|
+
const sectionLength = iterator.getBits(10);
|
|
56
|
+
if (sectionLength > 1021) {
|
|
57
|
+
throw new Error('Invalid section length');
|
|
58
|
+
}
|
|
59
|
+
iterator.stopReadingBits();
|
|
60
|
+
const tables = parsePmtTable({ iterator, tableId, sectionLength });
|
|
61
|
+
(0, discard_rest_of_packet_1.discardRestOfPacket)(iterator);
|
|
62
|
+
return tables;
|
|
63
|
+
};
|
|
64
|
+
exports.parsePmt = parsePmt;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { BufferIterator } from '../../buffer-iterator';
|
|
2
|
+
import type { TransportStreamStructure } from '../../parse-result';
|
|
3
|
+
import type { ParserContext } from '../../parser-context';
|
|
4
|
+
import type { PacketPes } from './parse-pes';
|
|
5
|
+
import type { TransportStreamEntry } from './parse-pmt';
|
|
6
|
+
import { type StreamBufferMap } from './process-stream-buffers';
|
|
7
|
+
export declare const parseStream: ({ iterator, transportStreamEntry, streamBuffers, parserContext, programId, structure, nextPesHeader, }: {
|
|
8
|
+
iterator: BufferIterator;
|
|
9
|
+
transportStreamEntry: TransportStreamEntry;
|
|
10
|
+
streamBuffers: StreamBufferMap;
|
|
11
|
+
parserContext: ParserContext;
|
|
12
|
+
programId: number;
|
|
13
|
+
structure: TransportStreamStructure;
|
|
14
|
+
nextPesHeader: PacketPes;
|
|
15
|
+
}) => Promise<void>;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseStream = void 0;
|
|
4
|
+
const make_header_1 = require("../webm/make-header");
|
|
5
|
+
const adts_header_1 = require("./adts-header");
|
|
6
|
+
const discard_rest_of_packet_1 = require("./discard-rest-of-packet");
|
|
7
|
+
const find_separator_1 = require("./find-separator");
|
|
8
|
+
const process_stream_buffers_1 = require("./process-stream-buffers");
|
|
9
|
+
const parseAdtsStream = async ({ restOfPacket, transportStreamEntry, streamBuffers, nextPesHeader, options, structure, }) => {
|
|
10
|
+
var _a, _b;
|
|
11
|
+
const streamBuffer = streamBuffers.get(transportStreamEntry.pid);
|
|
12
|
+
if (!streamBuffer) {
|
|
13
|
+
streamBuffers.set(transportStreamEntry.pid, {
|
|
14
|
+
buffer: restOfPacket,
|
|
15
|
+
pesHeader: nextPesHeader,
|
|
16
|
+
});
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
const expectedLength = (_b = (_a = (0, adts_header_1.readAdtsHeader)(streamBuffer.buffer)) === null || _a === void 0 ? void 0 : _a.frameLength) !== null && _b !== void 0 ? _b : null;
|
|
20
|
+
const bytesToTake = expectedLength
|
|
21
|
+
? Math.min(restOfPacket.length, expectedLength - streamBuffer.buffer.byteLength)
|
|
22
|
+
: restOfPacket.length;
|
|
23
|
+
streamBuffer.buffer = (0, make_header_1.combineUint8Arrays)([
|
|
24
|
+
streamBuffer.buffer,
|
|
25
|
+
restOfPacket.slice(0, bytesToTake),
|
|
26
|
+
]);
|
|
27
|
+
if (expectedLength === streamBuffer.buffer.byteLength) {
|
|
28
|
+
await (0, process_stream_buffers_1.processStreamBuffer)({
|
|
29
|
+
streamBuffer,
|
|
30
|
+
programId: transportStreamEntry.pid,
|
|
31
|
+
options,
|
|
32
|
+
structure,
|
|
33
|
+
});
|
|
34
|
+
const rest = restOfPacket.slice(bytesToTake);
|
|
35
|
+
streamBuffers.set(transportStreamEntry.pid, {
|
|
36
|
+
buffer: rest,
|
|
37
|
+
pesHeader: nextPesHeader,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
const parseAvcStream = async ({ restOfPacket, transportStreamEntry, streamBuffers, nextPesHeader, programId, parserContext, structure, }) => {
|
|
42
|
+
const indexOfSeparator = (0, find_separator_1.findNextSeparator)(restOfPacket, transportStreamEntry);
|
|
43
|
+
const streamBuffer = streamBuffers.get(transportStreamEntry.pid);
|
|
44
|
+
if (indexOfSeparator === -1) {
|
|
45
|
+
if (streamBuffer) {
|
|
46
|
+
streamBuffer.buffer = (0, make_header_1.combineUint8Arrays)([
|
|
47
|
+
streamBuffer.buffer,
|
|
48
|
+
restOfPacket,
|
|
49
|
+
]);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
streamBuffers.set(programId, {
|
|
53
|
+
pesHeader: nextPesHeader,
|
|
54
|
+
buffer: restOfPacket,
|
|
55
|
+
});
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
if (streamBuffer) {
|
|
59
|
+
const packet = restOfPacket.slice(0, indexOfSeparator);
|
|
60
|
+
streamBuffer.buffer = (0, make_header_1.combineUint8Arrays)([streamBuffer.buffer, packet]);
|
|
61
|
+
await (0, process_stream_buffers_1.processStreamBuffer)({
|
|
62
|
+
options: parserContext,
|
|
63
|
+
streamBuffer,
|
|
64
|
+
programId,
|
|
65
|
+
structure,
|
|
66
|
+
});
|
|
67
|
+
const rest = restOfPacket.slice(indexOfSeparator);
|
|
68
|
+
streamBuffers.set(programId, {
|
|
69
|
+
pesHeader: nextPesHeader,
|
|
70
|
+
buffer: rest,
|
|
71
|
+
});
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
if (indexOfSeparator !== 0) {
|
|
75
|
+
throw new Error('No stream buffer found but new separator is not at the beginning');
|
|
76
|
+
}
|
|
77
|
+
streamBuffers.set(programId, {
|
|
78
|
+
pesHeader: nextPesHeader,
|
|
79
|
+
buffer: restOfPacket.slice(indexOfSeparator),
|
|
80
|
+
});
|
|
81
|
+
};
|
|
82
|
+
const parseStream = ({ iterator, transportStreamEntry, streamBuffers, parserContext, programId, structure, nextPesHeader, }) => {
|
|
83
|
+
const restOfPacket = (0, discard_rest_of_packet_1.getRestOfPacket)(iterator);
|
|
84
|
+
if (transportStreamEntry.streamType === 27) {
|
|
85
|
+
return parseAvcStream({
|
|
86
|
+
restOfPacket,
|
|
87
|
+
transportStreamEntry,
|
|
88
|
+
streamBuffers,
|
|
89
|
+
nextPesHeader,
|
|
90
|
+
parserContext,
|
|
91
|
+
programId,
|
|
92
|
+
structure,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
if (transportStreamEntry.streamType === 15) {
|
|
96
|
+
return parseAdtsStream({
|
|
97
|
+
restOfPacket,
|
|
98
|
+
transportStreamEntry,
|
|
99
|
+
streamBuffers,
|
|
100
|
+
nextPesHeader,
|
|
101
|
+
options: parserContext,
|
|
102
|
+
structure,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
throw new Error(`Unsupported stream type ${transportStreamEntry.streamType}`);
|
|
106
|
+
};
|
|
107
|
+
exports.parseStream = parseStream;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { BufferIterator } from '../../buffer-iterator';
|
|
2
|
+
import type { Options, ParseMediaFields } from '../../options';
|
|
3
|
+
import type { ParseResult, TransportStreamStructure } from '../../parse-result';
|
|
4
|
+
import type { ParserContext } from '../../parser-context';
|
|
5
|
+
import type { NextPesHeaderStore } from './next-pes-header-store';
|
|
6
|
+
import { type StreamBufferMap } from './process-stream-buffers';
|
|
7
|
+
export declare const parseTransportStream: ({ iterator, parserContext, structure, streamBuffers, fields, nextPesHeaderStore, }: {
|
|
8
|
+
iterator: BufferIterator;
|
|
9
|
+
parserContext: ParserContext;
|
|
10
|
+
structure: TransportStreamStructure;
|
|
11
|
+
streamBuffers: StreamBufferMap;
|
|
12
|
+
fields: Options<ParseMediaFields>;
|
|
13
|
+
nextPesHeaderStore: NextPesHeaderStore;
|
|
14
|
+
}) => Promise<ParseResult<TransportStreamStructure>>;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseTransportStream = void 0;
|
|
4
|
+
const has_all_info_1 = require("../../has-all-info");
|
|
5
|
+
const parse_packet_1 = require("./parse-packet");
|
|
6
|
+
const process_stream_buffers_1 = require("./process-stream-buffers");
|
|
7
|
+
const parseTransportStream = async ({ iterator, parserContext, structure, streamBuffers, fields, nextPesHeaderStore, }) => {
|
|
8
|
+
if (iterator.bytesRemaining() === 0) {
|
|
9
|
+
await (0, process_stream_buffers_1.processFinalStreamBuffers)({
|
|
10
|
+
streamBufferMap: streamBuffers,
|
|
11
|
+
parserContext,
|
|
12
|
+
structure,
|
|
13
|
+
});
|
|
14
|
+
return Promise.resolve({
|
|
15
|
+
status: 'done',
|
|
16
|
+
segments: structure,
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
while (true) {
|
|
20
|
+
if ((0, has_all_info_1.hasAllInfo)({
|
|
21
|
+
fields,
|
|
22
|
+
state: parserContext.parserState,
|
|
23
|
+
structure,
|
|
24
|
+
})) {
|
|
25
|
+
break;
|
|
26
|
+
}
|
|
27
|
+
if (iterator.bytesRemaining() < 188) {
|
|
28
|
+
return Promise.resolve({
|
|
29
|
+
status: 'incomplete',
|
|
30
|
+
segments: structure,
|
|
31
|
+
skipTo: null,
|
|
32
|
+
continueParsing: () => {
|
|
33
|
+
return (0, exports.parseTransportStream)({
|
|
34
|
+
iterator,
|
|
35
|
+
parserContext,
|
|
36
|
+
structure,
|
|
37
|
+
streamBuffers,
|
|
38
|
+
fields,
|
|
39
|
+
nextPesHeaderStore,
|
|
40
|
+
});
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
const packet = await (0, parse_packet_1.parsePacket)({
|
|
45
|
+
iterator,
|
|
46
|
+
structure,
|
|
47
|
+
streamBuffers,
|
|
48
|
+
parserContext,
|
|
49
|
+
nextPesHeaderStore,
|
|
50
|
+
});
|
|
51
|
+
if (packet) {
|
|
52
|
+
structure.boxes.push(packet);
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return Promise.resolve({
|
|
57
|
+
segments: structure,
|
|
58
|
+
status: 'incomplete',
|
|
59
|
+
continueParsing() {
|
|
60
|
+
return (0, exports.parseTransportStream)({
|
|
61
|
+
iterator,
|
|
62
|
+
parserContext,
|
|
63
|
+
structure,
|
|
64
|
+
streamBuffers,
|
|
65
|
+
fields,
|
|
66
|
+
nextPesHeaderStore,
|
|
67
|
+
});
|
|
68
|
+
},
|
|
69
|
+
skipTo: null,
|
|
70
|
+
});
|
|
71
|
+
};
|
|
72
|
+
exports.parseTransportStream = parseTransportStream;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { TransportStreamStructure } from '../../parse-result';
|
|
2
|
+
import type { ParserContext } from '../../parser-context';
|
|
3
|
+
import type { PacketPes } from './parse-pes';
|
|
4
|
+
export type TransportStreamPacketBuffer = {
|
|
5
|
+
buffer: Uint8Array;
|
|
6
|
+
pesHeader: PacketPes;
|
|
7
|
+
};
|
|
8
|
+
export type StreamBufferMap = Map<number, TransportStreamPacketBuffer>;
|
|
9
|
+
export declare const processStreamBuffer: ({ streamBuffer, options, programId, structure, }: {
|
|
10
|
+
streamBuffer: TransportStreamPacketBuffer;
|
|
11
|
+
options: ParserContext;
|
|
12
|
+
programId: number;
|
|
13
|
+
structure: TransportStreamStructure;
|
|
14
|
+
}) => Promise<void>;
|
|
15
|
+
export declare const processFinalStreamBuffers: ({ streamBufferMap, parserContext, structure, }: {
|
|
16
|
+
streamBufferMap: StreamBufferMap;
|
|
17
|
+
parserContext: ParserContext;
|
|
18
|
+
structure: TransportStreamStructure;
|
|
19
|
+
}) => Promise<void>;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.processFinalStreamBuffers = exports.processStreamBuffer = void 0;
|
|
4
|
+
const handle_aac_packet_1 = require("./handle-aac-packet");
|
|
5
|
+
const handle_avc_packet_1 = require("./handle-avc-packet");
|
|
6
|
+
const traversal_1 = require("./traversal");
|
|
7
|
+
const processStreamBuffer = async ({ streamBuffer, options, programId, structure, }) => {
|
|
8
|
+
const stream = (0, traversal_1.getStreamForId)(structure, programId);
|
|
9
|
+
if (!stream) {
|
|
10
|
+
throw new Error('No stream found');
|
|
11
|
+
}
|
|
12
|
+
// 27 = AVC / H.264 Video
|
|
13
|
+
if (stream.streamType === 27) {
|
|
14
|
+
await (0, handle_avc_packet_1.handleAvcPacket)({ programId, streamBuffer, options });
|
|
15
|
+
}
|
|
16
|
+
// 15 = AAC / ADTS
|
|
17
|
+
else if (stream.streamType === 15) {
|
|
18
|
+
await (0, handle_aac_packet_1.handleAacPacket)({ streamBuffer, options, programId });
|
|
19
|
+
}
|
|
20
|
+
if (!options.parserState.tracks.hasAllTracks()) {
|
|
21
|
+
const tracksRegistered = options.parserState.tracks.getTracks().length;
|
|
22
|
+
const { streams } = (0, traversal_1.findProgramMapTableOrThrow)(structure);
|
|
23
|
+
if (streams.length === tracksRegistered) {
|
|
24
|
+
options.parserState.tracks.setIsDone();
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
exports.processStreamBuffer = processStreamBuffer;
|
|
29
|
+
const processFinalStreamBuffers = async ({ streamBufferMap, parserContext, structure, }) => {
|
|
30
|
+
for (const [programId, buffer] of streamBufferMap) {
|
|
31
|
+
if (buffer.buffer.byteLength > 0) {
|
|
32
|
+
await (0, exports.processStreamBuffer)({
|
|
33
|
+
streamBuffer: buffer,
|
|
34
|
+
options: parserContext,
|
|
35
|
+
programId,
|
|
36
|
+
structure,
|
|
37
|
+
});
|
|
38
|
+
streamBufferMap.delete(programId);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
exports.processFinalStreamBuffers = processFinalStreamBuffers;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { TransportStreamStructure } from '../../parse-result';
|
|
2
|
+
import type { TransportStreamProgramAssociationTableEntry } from './parse-pat';
|
|
3
|
+
import type { TransportStreamEntry } from './parse-pmt';
|
|
4
|
+
export declare const findProgramMapTableOrThrow: (structure: TransportStreamStructure) => import("./boxes").TransportStreamPMTBox;
|
|
5
|
+
export declare const getProgramForId: (structure: TransportStreamStructure, packetIdentifier: number) => TransportStreamProgramAssociationTableEntry | null;
|
|
6
|
+
export declare const getStreamForId: (structure: TransportStreamStructure, packetIdentifier: number) => TransportStreamEntry | null;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getStreamForId = exports.getProgramForId = exports.findProgramMapTableOrThrow = void 0;
|
|
4
|
+
const findProgramAssociationTableOrThrow = (structure) => {
|
|
5
|
+
const box = structure.boxes.find((b) => b.type === 'transport-stream-pat-box');
|
|
6
|
+
if (!box) {
|
|
7
|
+
throw new Error('No PAT box found');
|
|
8
|
+
}
|
|
9
|
+
return box;
|
|
10
|
+
};
|
|
11
|
+
const findProgramMapTableOrThrow = (structure) => {
|
|
12
|
+
const box = structure.boxes.find((b) => b.type === 'transport-stream-pmt-box');
|
|
13
|
+
if (!box) {
|
|
14
|
+
throw new Error('No PMT box found');
|
|
15
|
+
}
|
|
16
|
+
return box;
|
|
17
|
+
};
|
|
18
|
+
exports.findProgramMapTableOrThrow = findProgramMapTableOrThrow;
|
|
19
|
+
const getProgramForId = (structure, packetIdentifier) => {
|
|
20
|
+
const box = findProgramAssociationTableOrThrow(structure);
|
|
21
|
+
const entry = box.pat.find((e) => e.programMapIdentifier === packetIdentifier);
|
|
22
|
+
return entry !== null && entry !== void 0 ? entry : null;
|
|
23
|
+
};
|
|
24
|
+
exports.getProgramForId = getProgramForId;
|
|
25
|
+
const getStreamForId = (structure, packetIdentifier) => {
|
|
26
|
+
const box = (0, exports.findProgramMapTableOrThrow)(structure);
|
|
27
|
+
const entry = box.streams.find((e) => e.pid === packetIdentifier);
|
|
28
|
+
return entry !== null && entry !== void 0 ? entry : null;
|
|
29
|
+
};
|
|
30
|
+
exports.getStreamForId = getStreamForId;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const measureEBMLVarInt: (value: number) =>
|
|
1
|
+
export declare const measureEBMLVarInt: (value: number) => 3 | 1 | 2 | 4 | 6 | 5;
|
|
2
2
|
export declare const getVariableInt: (value: number, minWidth: number | null) => Uint8Array;
|
|
@@ -117,9 +117,9 @@ const postprocessEbml = async ({ offset, ebml, parserContext, }) => {
|
|
|
117
117
|
});
|
|
118
118
|
if (track) {
|
|
119
119
|
await (0, register_track_1.registerTrack)({
|
|
120
|
-
state: parserContext.parserState,
|
|
121
120
|
options: parserContext,
|
|
122
121
|
track,
|
|
122
|
+
container: 'webm',
|
|
123
123
|
});
|
|
124
124
|
}
|
|
125
125
|
}
|
|
@@ -64,5 +64,7 @@ export declare const getArrayBufferIterator: (initialData: Uint8Array, maxBytes:
|
|
|
64
64
|
discardRest: () => void;
|
|
65
65
|
expectNoMoreBytes: () => void;
|
|
66
66
|
};
|
|
67
|
+
isTransportStream: () => boolean;
|
|
68
|
+
readExpGolomb: () => number;
|
|
67
69
|
};
|
|
68
70
|
export type BufferIterator = ReturnType<typeof getArrayBufferIterator>;
|
package/dist/buffer-iterator.js
CHANGED
|
@@ -223,6 +223,9 @@ const getArrayBufferIterator = (initialData, maxBytes) => {
|
|
|
223
223
|
const isMp3 = () => {
|
|
224
224
|
return matchesPattern(mpegPattern)(data.subarray(0, 4));
|
|
225
225
|
};
|
|
226
|
+
const isTransportStream = () => {
|
|
227
|
+
return data[0] === 0x47;
|
|
228
|
+
};
|
|
226
229
|
const removeBytesRead = () => {
|
|
227
230
|
if (!discardAllowed) {
|
|
228
231
|
return;
|
|
@@ -262,6 +265,23 @@ const getArrayBufferIterator = (initialData, maxBytes) => {
|
|
|
262
265
|
removeBytesRead();
|
|
263
266
|
}
|
|
264
267
|
};
|
|
268
|
+
const readExpGolomb = () => {
|
|
269
|
+
if (!bitReadingMode) {
|
|
270
|
+
throw new Error('Not in bit reading mode');
|
|
271
|
+
}
|
|
272
|
+
let zerosCount = 0;
|
|
273
|
+
// Step 1: Count the number of leading zeros
|
|
274
|
+
while (getBits(1) === 0) {
|
|
275
|
+
zerosCount++;
|
|
276
|
+
}
|
|
277
|
+
// Step 2: Read the suffix
|
|
278
|
+
let suffix = 0;
|
|
279
|
+
for (let i = 0; i < zerosCount; i++) {
|
|
280
|
+
suffix = (suffix << 1) | getBits(1);
|
|
281
|
+
}
|
|
282
|
+
// Step 3: Calculate the value
|
|
283
|
+
return (1 << zerosCount) - 1 + suffix;
|
|
284
|
+
};
|
|
265
285
|
const peekB = (length) => {
|
|
266
286
|
// eslint-disable-next-line no-console
|
|
267
287
|
console.log([...getSlice(length)].map((b) => b.toString(16).padStart(2, '0')));
|
|
@@ -286,9 +306,12 @@ const getArrayBufferIterator = (initialData, maxBytes) => {
|
|
|
286
306
|
let bitIndex = 0;
|
|
287
307
|
const stopReadingBits = () => {
|
|
288
308
|
bitIndex = 0;
|
|
309
|
+
bitReadingMode = false;
|
|
289
310
|
};
|
|
290
311
|
let byteToShift = 0;
|
|
312
|
+
let bitReadingMode = false;
|
|
291
313
|
const startReadingBits = () => {
|
|
314
|
+
bitReadingMode = true;
|
|
292
315
|
byteToShift = getUint8();
|
|
293
316
|
};
|
|
294
317
|
const getBits = (bits) => {
|
|
@@ -514,6 +537,8 @@ const getArrayBufferIterator = (initialData, maxBytes) => {
|
|
|
514
537
|
disallowDiscard,
|
|
515
538
|
allowDiscard,
|
|
516
539
|
startBox,
|
|
540
|
+
isTransportStream,
|
|
541
|
+
readExpGolomb,
|
|
517
542
|
};
|
|
518
543
|
};
|
|
519
544
|
exports.getArrayBufferIterator = getArrayBufferIterator;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.convertAudioOrVideoSampleToWebCodecsTimestamps = void 0;
|
|
4
|
+
const convertAudioOrVideoSampleToWebCodecsTimestamps = (sample, timescale) => {
|
|
5
|
+
var _a;
|
|
6
|
+
const { cts, dts, timestamp } = sample;
|
|
7
|
+
return {
|
|
8
|
+
cts: (cts * 1000000) / timescale,
|
|
9
|
+
dts: (dts * 1000000) / timescale,
|
|
10
|
+
timestamp: (timestamp * 1000000) / timescale,
|
|
11
|
+
duration: (((_a = sample.duration) !== null && _a !== void 0 ? _a : 0) * 1000000) / timescale,
|
|
12
|
+
data: sample.data,
|
|
13
|
+
trackId: sample.trackId,
|
|
14
|
+
type: sample.type,
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
exports.convertAudioOrVideoSampleToWebCodecsTimestamps = convertAudioOrVideoSampleToWebCodecsTimestamps;
|