@remotion/media-parser 4.0.237 → 4.0.239
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/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 +1 -1
- package/dist/esm/index.mjs +1288 -252
- 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-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/index.d.ts +2 -0
- package/dist/metadata/get-metadata.js +3 -0
- package/dist/options.d.ts +3 -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/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
|
@@ -6,6 +6,7 @@ const get_fps_1 = require("../../get-fps");
|
|
|
6
6
|
const get_sample_aspect_ratio_1 = require("../../get-sample-aspect-ratio");
|
|
7
7
|
const get_video_codec_1 = require("../../get-video-codec");
|
|
8
8
|
const get_actual_number_of_channels_1 = require("./get-actual-number-of-channels");
|
|
9
|
+
const get_video_codec_from_iso_track_1 = require("./get-video-codec-from-iso-track");
|
|
9
10
|
const traversal_1 = require("./traversal");
|
|
10
11
|
const makeBaseMediaTrack = (trakBox) => {
|
|
11
12
|
var _a, _b, _c, _d;
|
|
@@ -99,7 +100,7 @@ const makeBaseMediaTrack = (trakBox) => {
|
|
|
99
100
|
primaries: null,
|
|
100
101
|
transferCharacteristics: null,
|
|
101
102
|
},
|
|
102
|
-
codecWithoutConfig: (0,
|
|
103
|
+
codecWithoutConfig: (0, get_video_codec_from_iso_track_1.getVideoCodecFromIsoTrak)(trakBox),
|
|
103
104
|
fps: (0, get_fps_1.getFpsFromMp4TrakBox)(trakBox),
|
|
104
105
|
};
|
|
105
106
|
return track;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.parseMdat = void 0;
|
|
4
|
+
const convert_audio_or_video_sample_1 = require("../../../convert-audio-or-video-sample");
|
|
4
5
|
const get_tracks_1 = require("../../../get-tracks");
|
|
5
6
|
const get_sample_positions_from_track_1 = require("../get-sample-positions-from-track");
|
|
6
7
|
const traversal_1 = require("../traversal");
|
|
@@ -76,35 +77,28 @@ const parseMdat = async ({ data, size, fileOffset, existingBoxes, options, signa
|
|
|
76
77
|
break;
|
|
77
78
|
}
|
|
78
79
|
const bytes = data.getSlice(samplesWithIndex.samplePosition.size);
|
|
79
|
-
const
|
|
80
|
-
samplesWithIndex.track.timescale;
|
|
81
|
-
const duration = (samplesWithIndex.samplePosition.duration * 1000000) /
|
|
82
|
-
samplesWithIndex.track.timescale;
|
|
83
|
-
const cts = (samplesWithIndex.samplePosition.cts * 1000000) /
|
|
84
|
-
samplesWithIndex.track.timescale;
|
|
85
|
-
const dts = (samplesWithIndex.samplePosition.dts * 1000000) /
|
|
86
|
-
samplesWithIndex.track.timescale;
|
|
80
|
+
const { cts, dts, duration } = samplesWithIndex.samplePosition;
|
|
87
81
|
if (samplesWithIndex.track.type === 'audio') {
|
|
88
|
-
await options.parserState.onAudioSample(samplesWithIndex.track.trackId, {
|
|
82
|
+
await options.parserState.onAudioSample(samplesWithIndex.track.trackId, (0, convert_audio_or_video_sample_1.convertAudioOrVideoSampleToWebCodecsTimestamps)({
|
|
89
83
|
data: bytes,
|
|
90
|
-
timestamp,
|
|
84
|
+
timestamp: cts,
|
|
91
85
|
duration,
|
|
92
86
|
cts,
|
|
93
87
|
dts,
|
|
94
88
|
trackId: samplesWithIndex.track.trackId,
|
|
95
89
|
type: samplesWithIndex.samplePosition.isKeyframe ? 'key' : 'delta',
|
|
96
|
-
});
|
|
90
|
+
}, samplesWithIndex.track.timescale));
|
|
97
91
|
}
|
|
98
92
|
if (samplesWithIndex.track.type === 'video') {
|
|
99
|
-
await options.parserState.onVideoSample(samplesWithIndex.track.trackId, {
|
|
93
|
+
await options.parserState.onVideoSample(samplesWithIndex.track.trackId, (0, convert_audio_or_video_sample_1.convertAudioOrVideoSampleToWebCodecsTimestamps)({
|
|
100
94
|
data: bytes,
|
|
101
|
-
timestamp,
|
|
95
|
+
timestamp: cts,
|
|
102
96
|
duration,
|
|
103
97
|
cts,
|
|
104
98
|
dts,
|
|
105
99
|
trackId: samplesWithIndex.track.trackId,
|
|
106
100
|
type: samplesWithIndex.samplePosition.isKeyframe ? 'key' : 'delta',
|
|
107
|
-
});
|
|
101
|
+
}, samplesWithIndex.track.timescale));
|
|
108
102
|
}
|
|
109
103
|
const remaining = size - (data.counter.getOffset() - fileOffset);
|
|
110
104
|
data.removeBytesRead();
|
|
@@ -396,8 +396,8 @@ const processBox = async ({ iterator, allowIncompleteBoxes, parsedBoxes, options
|
|
|
396
396
|
if (transformedTrack) {
|
|
397
397
|
await (0, register_track_1.registerTrack)({
|
|
398
398
|
options,
|
|
399
|
-
state: options.parserState,
|
|
400
399
|
track: transformedTrack,
|
|
400
|
+
container: 'mp4',
|
|
401
401
|
});
|
|
402
402
|
}
|
|
403
403
|
return {
|
|
@@ -98,8 +98,8 @@ const parseRiffBody = async ({ iterator, structure, maxOffset, options, }) => {
|
|
|
98
98
|
});
|
|
99
99
|
await (0, register_track_1.registerTrack)({
|
|
100
100
|
options,
|
|
101
|
-
state: options.parserState,
|
|
102
101
|
track: audioTrack,
|
|
102
|
+
container: 'avi',
|
|
103
103
|
});
|
|
104
104
|
}
|
|
105
105
|
if (options.onVideoTrack && strf.type === 'strf-box-video') {
|
|
@@ -110,8 +110,8 @@ const parseRiffBody = async ({ iterator, structure, maxOffset, options, }) => {
|
|
|
110
110
|
});
|
|
111
111
|
(0, register_track_1.registerVideoTrackWhenProfileIsAvailable)({
|
|
112
112
|
options,
|
|
113
|
-
state: options.parserState,
|
|
114
113
|
track: videoTrack,
|
|
114
|
+
container: 'avi',
|
|
115
115
|
});
|
|
116
116
|
}
|
|
117
117
|
options.nextTrackIndex++;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.parseMovi = exports.handleChunk = void 0;
|
|
4
|
+
const convert_audio_or_video_sample_1 = require("../../convert-audio-or-video-sample");
|
|
5
|
+
const key_1 = require("../avc/key");
|
|
4
6
|
const parse_avc_1 = require("../avc/parse-avc");
|
|
5
|
-
const timescale_1 = require("./timescale");
|
|
6
7
|
const traversal_1 = require("./traversal");
|
|
7
8
|
const getStrhForIndex = (structure, trackId) => {
|
|
8
9
|
const boxes = (0, traversal_1.getStrlBoxes)(structure);
|
|
@@ -24,29 +25,26 @@ const handleChunk = async ({ iterator, options, structure, ckId, ckSize, }) => {
|
|
|
24
25
|
const samplesPerSecond = strh.rate / strh.scale;
|
|
25
26
|
const nthSample = options.parserState.getSamplesForTrack(trackId);
|
|
26
27
|
const timeInSec = nthSample / samplesPerSecond;
|
|
27
|
-
const timestamp = Math.floor(timeInSec
|
|
28
|
-
const duration = Math.floor(
|
|
28
|
+
const timestamp = Math.floor(timeInSec);
|
|
29
|
+
const duration = Math.floor(1 / samplesPerSecond);
|
|
29
30
|
const data = iterator.getSlice(ckSize);
|
|
30
31
|
const infos = (0, parse_avc_1.parseAvc)(data);
|
|
31
|
-
const keyOrDelta =
|
|
32
|
-
if (!keyOrDelta) {
|
|
33
|
-
throw new Error('expected avc to contain info about key or delta');
|
|
34
|
-
}
|
|
32
|
+
const keyOrDelta = (0, key_1.getKeyFrameOrDeltaFromAvcInfo)(infos);
|
|
35
33
|
const avcProfile = infos.find((i) => i.type === 'avc-profile');
|
|
36
34
|
const ppsProfile = infos.find((i) => i.type === 'avc-pps');
|
|
37
35
|
if (avcProfile && ppsProfile) {
|
|
38
36
|
await options.parserState.onProfile({ pps: ppsProfile, sps: avcProfile });
|
|
39
37
|
options.parserState.tracks.setIsDone();
|
|
40
38
|
}
|
|
41
|
-
await options.parserState.onVideoSample(trackId, {
|
|
39
|
+
await options.parserState.onVideoSample(trackId, (0, convert_audio_or_video_sample_1.convertAudioOrVideoSampleToWebCodecsTimestamps)({
|
|
42
40
|
cts: timestamp,
|
|
43
41
|
dts: timestamp,
|
|
44
42
|
data,
|
|
45
43
|
duration,
|
|
46
44
|
timestamp,
|
|
47
45
|
trackId,
|
|
48
|
-
type: keyOrDelta
|
|
49
|
-
});
|
|
46
|
+
type: keyOrDelta,
|
|
47
|
+
}, 1));
|
|
50
48
|
return;
|
|
51
49
|
}
|
|
52
50
|
const audioChunk = ckId.match(/^([0-9]{2})wb$/);
|
|
@@ -56,9 +54,9 @@ const handleChunk = async ({ iterator, options, structure, ckId, ckSize, }) => {
|
|
|
56
54
|
const samplesPerSecond = strh.rate / strh.scale;
|
|
57
55
|
const nthSample = options.parserState.getSamplesForTrack(trackId);
|
|
58
56
|
const timeInSec = nthSample / samplesPerSecond;
|
|
59
|
-
const timestamp = timeInSec
|
|
60
|
-
const duration =
|
|
61
|
-
await options.parserState.onAudioSample(trackId, {
|
|
57
|
+
const timestamp = timeInSec;
|
|
58
|
+
const duration = 1 / samplesPerSecond;
|
|
59
|
+
await options.parserState.onAudioSample(trackId, (0, convert_audio_or_video_sample_1.convertAudioOrVideoSampleToWebCodecsTimestamps)({
|
|
62
60
|
cts: timestamp,
|
|
63
61
|
dts: timestamp,
|
|
64
62
|
data: iterator.getSlice(ckSize),
|
|
@@ -66,7 +64,7 @@ const handleChunk = async ({ iterator, options, structure, ckId, ckSize, }) => {
|
|
|
66
64
|
timestamp,
|
|
67
65
|
trackId,
|
|
68
66
|
type: 'key',
|
|
69
|
-
});
|
|
67
|
+
}, 1));
|
|
70
68
|
}
|
|
71
69
|
};
|
|
72
70
|
exports.handleChunk = handleChunk;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.readAdtsHeader = void 0;
|
|
4
|
+
const aac_codecprivate_1 = require("../../aac-codecprivate");
|
|
5
|
+
const buffer_iterator_1 = require("../../buffer-iterator");
|
|
6
|
+
const readAdtsHeader = (buffer) => {
|
|
7
|
+
if (buffer.byteLength < 9) {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
const iterator = (0, buffer_iterator_1.getArrayBufferIterator)(buffer, buffer.byteLength);
|
|
11
|
+
iterator.startReadingBits();
|
|
12
|
+
const bits = iterator.getBits(12);
|
|
13
|
+
if (bits !== 0xfff) {
|
|
14
|
+
throw new Error('Invalid ADTS header ');
|
|
15
|
+
}
|
|
16
|
+
// MPEG Version, set to 0 for MPEG-4 and 1 for MPEG-2.
|
|
17
|
+
const id = iterator.getBits(1);
|
|
18
|
+
if (id !== 0) {
|
|
19
|
+
throw new Error('Only supporting MPEG-4 for .ts');
|
|
20
|
+
}
|
|
21
|
+
const layer = iterator.getBits(2);
|
|
22
|
+
if (layer !== 0) {
|
|
23
|
+
throw new Error('Only supporting layer 0 for .ts');
|
|
24
|
+
}
|
|
25
|
+
const protectionAbsent = iterator.getBits(1); // protection absent
|
|
26
|
+
const audioObjectType = iterator.getBits(2); // 1 = 'AAC-LC'
|
|
27
|
+
const samplingFrequencyIndex = iterator.getBits(4);
|
|
28
|
+
const sampleRate = (0, aac_codecprivate_1.getSampleRateFromSampleFrequencyIndex)(samplingFrequencyIndex);
|
|
29
|
+
iterator.getBits(1); // private bit
|
|
30
|
+
const channelConfiguration = iterator.getBits(3);
|
|
31
|
+
const codecPrivate = (0, aac_codecprivate_1.createAacCodecPrivate)({
|
|
32
|
+
audioObjectType,
|
|
33
|
+
sampleRate,
|
|
34
|
+
channelConfiguration,
|
|
35
|
+
});
|
|
36
|
+
iterator.getBits(1); // originality
|
|
37
|
+
iterator.getBits(1); // home
|
|
38
|
+
iterator.getBits(1); // copyright bit
|
|
39
|
+
iterator.getBits(1); // copy start
|
|
40
|
+
const frameLength = iterator.getBits(13); // frame length
|
|
41
|
+
iterator.getBits(11); // buffer fullness
|
|
42
|
+
iterator.getBits(2); // number of AAC frames minus 1
|
|
43
|
+
if (!protectionAbsent) {
|
|
44
|
+
iterator.getBits(16); // crc
|
|
45
|
+
}
|
|
46
|
+
iterator.stopReadingBits();
|
|
47
|
+
iterator.destroy();
|
|
48
|
+
return {
|
|
49
|
+
frameLength,
|
|
50
|
+
codecPrivate,
|
|
51
|
+
channelConfiguration,
|
|
52
|
+
sampleRate,
|
|
53
|
+
audioObjectType,
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
exports.readAdtsHeader = readAdtsHeader;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { TransportStreamProgramAssociationTableEntry } from './parse-pat';
|
|
2
|
+
import type { TransportStreamEntry } from './parse-pmt';
|
|
3
|
+
export type TransportStreamAdaptationField = {
|
|
4
|
+
adaptationFieldLength: number;
|
|
5
|
+
discontinuityIndicator: number;
|
|
6
|
+
randomAccessIndicator: number;
|
|
7
|
+
elementaryStreamPriorityIndicator: number;
|
|
8
|
+
pcrFlag: number;
|
|
9
|
+
opcrFlag: number;
|
|
10
|
+
splicingPointFlag: number;
|
|
11
|
+
transportPrivateDataFlag: number;
|
|
12
|
+
adaptationFieldExtensionFlag: number;
|
|
13
|
+
};
|
|
14
|
+
export type TransportStreamHeader = {
|
|
15
|
+
syncByte: number;
|
|
16
|
+
transportErrorIndicator: number;
|
|
17
|
+
payloadUnitStartIndicator: number;
|
|
18
|
+
transportPriority: number;
|
|
19
|
+
packetIdentifier: number;
|
|
20
|
+
transportScramblingControl: number;
|
|
21
|
+
adaptationFieldControl1: number;
|
|
22
|
+
adaptationFieldControl2: number;
|
|
23
|
+
continuityCounter: number;
|
|
24
|
+
adaptionField: TransportStreamAdaptationField | null;
|
|
25
|
+
pointerField: number | null;
|
|
26
|
+
};
|
|
27
|
+
export type TransportStreamGenericBox = {
|
|
28
|
+
header: TransportStreamHeader;
|
|
29
|
+
type: 'transport-stream-generic-box';
|
|
30
|
+
};
|
|
31
|
+
export type TransportStreamPATBox = {
|
|
32
|
+
type: 'transport-stream-pat-box';
|
|
33
|
+
tableId: string;
|
|
34
|
+
pat: TransportStreamProgramAssociationTableEntry[];
|
|
35
|
+
};
|
|
36
|
+
export type TransportStreamPMTBox = {
|
|
37
|
+
type: 'transport-stream-pmt-box';
|
|
38
|
+
tableId: number;
|
|
39
|
+
streams: TransportStreamEntry[];
|
|
40
|
+
};
|
|
41
|
+
export type TransportStreamBox = TransportStreamGenericBox | TransportStreamPATBox | TransportStreamPMTBox;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getRestOfPacket = exports.discardRestOfPacket = void 0;
|
|
4
|
+
const discardRestOfPacket = (iterator) => {
|
|
5
|
+
const next188 = 188 - (iterator.counter.getOffset() % 188);
|
|
6
|
+
iterator.discard(next188);
|
|
7
|
+
};
|
|
8
|
+
exports.discardRestOfPacket = discardRestOfPacket;
|
|
9
|
+
const getRestOfPacket = (iterator) => {
|
|
10
|
+
const next188 = 188 - (iterator.counter.getOffset() % 188);
|
|
11
|
+
return iterator.getSlice(next188);
|
|
12
|
+
};
|
|
13
|
+
exports.getRestOfPacket = getRestOfPacket;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.findNextSeparator = void 0;
|
|
4
|
+
function findSubarrayIndex(array, subarray) {
|
|
5
|
+
const subarrayLength = subarray.length;
|
|
6
|
+
const arrayLength = array.length;
|
|
7
|
+
for (let i = 0; i <= arrayLength - subarrayLength; i++) {
|
|
8
|
+
let match = true;
|
|
9
|
+
for (let j = 0; j < subarrayLength; j++) {
|
|
10
|
+
if (array[i + j] !== subarray[j]) {
|
|
11
|
+
match = false;
|
|
12
|
+
break;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
if (match) {
|
|
16
|
+
if (subarray[i - 1] === 0) {
|
|
17
|
+
i--;
|
|
18
|
+
}
|
|
19
|
+
return i; // Return the starting index of the subarray
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return -1; // Return -1 if subarray is not found
|
|
23
|
+
}
|
|
24
|
+
const findNextSeparator = (restOfPacket, transportStreamEntry) => {
|
|
25
|
+
if (transportStreamEntry.streamType === 27) {
|
|
26
|
+
return findSubarrayIndex(restOfPacket, new Uint8Array([0, 0, 1, 9]));
|
|
27
|
+
}
|
|
28
|
+
throw new Error(`Unsupported stream ID ${transportStreamEntry.streamType}`);
|
|
29
|
+
};
|
|
30
|
+
exports.findNextSeparator = findNextSeparator;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { TransportStreamStructure } from '../../parse-result';
|
|
2
|
+
import type { ParserState } from '../../state/parser-state';
|
|
3
|
+
import type { AllTracks } from '../riff/get-tracks-from-avi';
|
|
4
|
+
export declare const getTracksFromTransportStream: (structure: TransportStreamStructure, parserState: ParserState) => AllTracks;
|
|
5
|
+
export declare const hasAllTracksFromTransportStream: (structure: TransportStreamStructure, parserState: ParserState) => boolean;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.hasAllTracksFromTransportStream = exports.getTracksFromTransportStream = void 0;
|
|
4
|
+
const truthy_1 = require("../../truthy");
|
|
5
|
+
const traversal_1 = require("./traversal");
|
|
6
|
+
const getTracksFromTransportStream = (structure, parserState) => {
|
|
7
|
+
const programMapTable = (0, traversal_1.findProgramMapTableOrThrow)(structure);
|
|
8
|
+
const parserTracks = parserState.tracks.getTracks();
|
|
9
|
+
const mapped = programMapTable.streams
|
|
10
|
+
.map((stream) => {
|
|
11
|
+
return parserTracks.find((track) => track.trackId === stream.pid);
|
|
12
|
+
})
|
|
13
|
+
.filter(truthy_1.truthy);
|
|
14
|
+
if (mapped.length !== programMapTable.streams.length) {
|
|
15
|
+
throw new Error('Not all tracks found');
|
|
16
|
+
}
|
|
17
|
+
return {
|
|
18
|
+
videoTracks: mapped.filter((track) => track.type === 'video'),
|
|
19
|
+
audioTracks: mapped.filter((track) => track.type === 'audio'),
|
|
20
|
+
otherTracks: [],
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
exports.getTracksFromTransportStream = getTracksFromTransportStream;
|
|
24
|
+
const hasAllTracksFromTransportStream = (structure, parserState) => {
|
|
25
|
+
try {
|
|
26
|
+
(0, exports.getTracksFromTransportStream)(structure, parserState);
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
catch (_a) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
exports.hasAllTracksFromTransportStream = hasAllTracksFromTransportStream;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ParserContext } from '../../parser-context';
|
|
2
|
+
import type { TransportStreamPacketBuffer } from './process-stream-buffers';
|
|
3
|
+
export declare const handleAacPacket: ({ streamBuffer, options, programId, }: {
|
|
4
|
+
streamBuffer: TransportStreamPacketBuffer;
|
|
5
|
+
options: ParserContext;
|
|
6
|
+
programId: number;
|
|
7
|
+
}) => Promise<void>;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.handleAacPacket = void 0;
|
|
4
|
+
const aac_codecprivate_1 = require("../../aac-codecprivate");
|
|
5
|
+
const convert_audio_or_video_sample_1 = require("../../convert-audio-or-video-sample");
|
|
6
|
+
const register_track_1 = require("../../register-track");
|
|
7
|
+
const adts_header_1 = require("./adts-header");
|
|
8
|
+
const handle_avc_packet_1 = require("./handle-avc-packet");
|
|
9
|
+
const handleAacPacket = async ({ streamBuffer, options, programId, }) => {
|
|
10
|
+
var _a;
|
|
11
|
+
const adtsHeader = (0, adts_header_1.readAdtsHeader)(streamBuffer.buffer);
|
|
12
|
+
if (!adtsHeader) {
|
|
13
|
+
throw new Error('Invalid ADTS header - too short');
|
|
14
|
+
}
|
|
15
|
+
const { channelConfiguration, codecPrivate, sampleRate, audioObjectType } = adtsHeader;
|
|
16
|
+
const isTrackRegistered = options.parserState.tracks.getTracks().find((t) => {
|
|
17
|
+
return t.trackId === programId;
|
|
18
|
+
});
|
|
19
|
+
if (!isTrackRegistered) {
|
|
20
|
+
const track = {
|
|
21
|
+
type: 'audio',
|
|
22
|
+
codecPrivate,
|
|
23
|
+
trackId: programId,
|
|
24
|
+
trakBox: null,
|
|
25
|
+
timescale: handle_avc_packet_1.MPEG_TIMESCALE,
|
|
26
|
+
codecWithoutConfig: 'aac',
|
|
27
|
+
codec: (0, aac_codecprivate_1.mapAudioObjectTypeToCodecString)(audioObjectType),
|
|
28
|
+
// https://www.w3.org/TR/webcodecs-aac-codec-registration/
|
|
29
|
+
description: undefined,
|
|
30
|
+
numberOfChannels: channelConfiguration,
|
|
31
|
+
sampleRate,
|
|
32
|
+
};
|
|
33
|
+
await (0, register_track_1.registerTrack)({
|
|
34
|
+
track,
|
|
35
|
+
options,
|
|
36
|
+
container: 'transport-stream',
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
const sample = {
|
|
40
|
+
cts: streamBuffer.pesHeader.pts,
|
|
41
|
+
dts: (_a = streamBuffer.pesHeader.dts) !== null && _a !== void 0 ? _a : streamBuffer.pesHeader.pts,
|
|
42
|
+
timestamp: streamBuffer.pesHeader.pts,
|
|
43
|
+
duration: undefined,
|
|
44
|
+
data: new Uint8Array(streamBuffer.buffer),
|
|
45
|
+
trackId: programId,
|
|
46
|
+
type: 'key',
|
|
47
|
+
};
|
|
48
|
+
await options.parserState.onAudioSample(programId, (0, convert_audio_or_video_sample_1.convertAudioOrVideoSampleToWebCodecsTimestamps)(sample, handle_avc_packet_1.MPEG_TIMESCALE));
|
|
49
|
+
};
|
|
50
|
+
exports.handleAacPacket = handleAacPacket;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ParserContext } from '../../parser-context';
|
|
2
|
+
import type { TransportStreamPacketBuffer } from './process-stream-buffers';
|
|
3
|
+
export declare const MPEG_TIMESCALE = 90000;
|
|
4
|
+
export declare const handleAvcPacket: ({ streamBuffer, programId, options, }: {
|
|
5
|
+
streamBuffer: TransportStreamPacketBuffer;
|
|
6
|
+
programId: number;
|
|
7
|
+
options: ParserContext;
|
|
8
|
+
}) => Promise<void>;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.handleAvcPacket = exports.MPEG_TIMESCALE = void 0;
|
|
4
|
+
const convert_audio_or_video_sample_1 = require("../../convert-audio-or-video-sample");
|
|
5
|
+
const register_track_1 = require("../../register-track");
|
|
6
|
+
const codec_private_1 = require("../avc/codec-private");
|
|
7
|
+
const codec_string_1 = require("../avc/codec-string");
|
|
8
|
+
const interpret_sps_1 = require("../avc/interpret-sps");
|
|
9
|
+
const key_1 = require("../avc/key");
|
|
10
|
+
const parse_avc_1 = require("../avc/parse-avc");
|
|
11
|
+
const sps_and_pps_1 = require("../avc/sps-and-pps");
|
|
12
|
+
exports.MPEG_TIMESCALE = 90000;
|
|
13
|
+
const handleAvcPacket = async ({ streamBuffer, programId, options, }) => {
|
|
14
|
+
var _a;
|
|
15
|
+
const avc = (0, parse_avc_1.parseAvc)(streamBuffer.buffer);
|
|
16
|
+
const isTrackRegistered = options.parserState.tracks.getTracks().find((t) => {
|
|
17
|
+
return t.trackId === programId;
|
|
18
|
+
});
|
|
19
|
+
if (!isTrackRegistered) {
|
|
20
|
+
const spsAndPps = (0, sps_and_pps_1.getSpsAndPps)(avc);
|
|
21
|
+
const dimensions = (0, interpret_sps_1.getDimensionsFromSps)(spsAndPps.sps.spsData);
|
|
22
|
+
const sampleAspectRatio = (0, interpret_sps_1.getSampleAspectRatioFromSps)(spsAndPps.sps.spsData);
|
|
23
|
+
const track = {
|
|
24
|
+
rotation: 0,
|
|
25
|
+
trackId: programId,
|
|
26
|
+
type: 'video',
|
|
27
|
+
timescale: exports.MPEG_TIMESCALE,
|
|
28
|
+
codec: (0, codec_string_1.getCodecStringFromSpsAndPps)(spsAndPps.sps),
|
|
29
|
+
codecPrivate: (0, codec_private_1.getAvccBoxContent)(spsAndPps),
|
|
30
|
+
fps: null,
|
|
31
|
+
codedWidth: dimensions.width,
|
|
32
|
+
codedHeight: dimensions.height,
|
|
33
|
+
height: dimensions.height,
|
|
34
|
+
width: dimensions.width,
|
|
35
|
+
displayAspectWidth: dimensions.width,
|
|
36
|
+
displayAspectHeight: dimensions.height,
|
|
37
|
+
trakBox: null,
|
|
38
|
+
codecWithoutConfig: 'h264',
|
|
39
|
+
description: undefined,
|
|
40
|
+
sampleAspectRatio: {
|
|
41
|
+
denominator: sampleAspectRatio.height,
|
|
42
|
+
numerator: sampleAspectRatio.width,
|
|
43
|
+
},
|
|
44
|
+
color: (0, interpret_sps_1.getVideoColorFromSps)(spsAndPps.sps.spsData),
|
|
45
|
+
};
|
|
46
|
+
await (0, register_track_1.registerTrack)({ track, options, container: 'transport-stream' });
|
|
47
|
+
}
|
|
48
|
+
// sample for webcodecs needs to be in nano seconds
|
|
49
|
+
const sample = {
|
|
50
|
+
cts: streamBuffer.pesHeader.pts,
|
|
51
|
+
dts: (_a = streamBuffer.pesHeader.dts) !== null && _a !== void 0 ? _a : streamBuffer.pesHeader.pts,
|
|
52
|
+
timestamp: streamBuffer.pesHeader.pts,
|
|
53
|
+
duration: undefined,
|
|
54
|
+
data: new Uint8Array(streamBuffer.buffer),
|
|
55
|
+
trackId: programId,
|
|
56
|
+
type: (0, key_1.getKeyFrameOrDeltaFromAvcInfo)(avc),
|
|
57
|
+
};
|
|
58
|
+
await options.parserState.onVideoSample(programId, (0, convert_audio_or_video_sample_1.convertAudioOrVideoSampleToWebCodecsTimestamps)(sample, exports.MPEG_TIMESCALE));
|
|
59
|
+
};
|
|
60
|
+
exports.handleAvcPacket = handleAvcPacket;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { PacketPes } from './parse-pes';
|
|
2
|
+
export declare const makeNextPesHeaderStore: () => {
|
|
3
|
+
setNextPesHeader: (pesHeader: PacketPes) => void;
|
|
4
|
+
getNextPesHeader: () => PacketPes;
|
|
5
|
+
};
|
|
6
|
+
export type NextPesHeaderStore = ReturnType<typeof makeNextPesHeaderStore>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.makeNextPesHeaderStore = void 0;
|
|
4
|
+
const makeNextPesHeaderStore = () => {
|
|
5
|
+
let nextPesHeader = null;
|
|
6
|
+
return {
|
|
7
|
+
setNextPesHeader: (pesHeader) => {
|
|
8
|
+
nextPesHeader = pesHeader;
|
|
9
|
+
},
|
|
10
|
+
getNextPesHeader: () => {
|
|
11
|
+
if (!nextPesHeader) {
|
|
12
|
+
throw new Error('No next PES header found');
|
|
13
|
+
}
|
|
14
|
+
return nextPesHeader;
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
exports.makeNextPesHeaderStore = makeNextPesHeaderStore;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { BufferIterator } from '../../buffer-iterator';
|
|
2
|
+
import type { TransportStreamStructure } from '../../parse-result';
|
|
3
|
+
import type { ParserContext } from '../../parser-context';
|
|
4
|
+
import type { TransportStreamBox } from './boxes';
|
|
5
|
+
import type { NextPesHeaderStore } from './next-pes-header-store';
|
|
6
|
+
import { type StreamBufferMap } from './process-stream-buffers';
|
|
7
|
+
export declare const parsePacket: ({ iterator, structure, streamBuffers, parserContext, nextPesHeaderStore, }: {
|
|
8
|
+
iterator: BufferIterator;
|
|
9
|
+
structure: TransportStreamStructure;
|
|
10
|
+
streamBuffers: StreamBufferMap;
|
|
11
|
+
parserContext: ParserContext;
|
|
12
|
+
nextPesHeaderStore: NextPesHeaderStore;
|
|
13
|
+
}) => Promise<TransportStreamBox | null>;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parsePacket = void 0;
|
|
4
|
+
const parse_pat_1 = require("./parse-pat");
|
|
5
|
+
const parse_pes_1 = require("./parse-pes");
|
|
6
|
+
const parse_pmt_1 = require("./parse-pmt");
|
|
7
|
+
const parse_stream_packet_1 = require("./parse-stream-packet");
|
|
8
|
+
const traversal_1 = require("./traversal");
|
|
9
|
+
const parsePacket = async ({ iterator, structure, streamBuffers, parserContext, nextPesHeaderStore, }) => {
|
|
10
|
+
const offset = iterator.counter.getOffset();
|
|
11
|
+
const syncByte = iterator.getUint8();
|
|
12
|
+
if (syncByte !== 0x47) {
|
|
13
|
+
throw new Error('Invalid sync byte');
|
|
14
|
+
}
|
|
15
|
+
iterator.startReadingBits();
|
|
16
|
+
iterator.getBits(1); // transport error indicator
|
|
17
|
+
const payloadUnitStartIndicator = iterator.getBits(1);
|
|
18
|
+
iterator.getBits(1); // transport priority
|
|
19
|
+
const programId = iterator.getBits(13);
|
|
20
|
+
iterator.getBits(2); // transport scrambling control
|
|
21
|
+
const adaptationFieldControl1 = iterator.getBits(1); // adaptation field control 1
|
|
22
|
+
iterator.getBits(1); // adaptation field control 2
|
|
23
|
+
iterator.getBits(4); // continuity counter
|
|
24
|
+
iterator.stopReadingBits();
|
|
25
|
+
if (adaptationFieldControl1 === 1) {
|
|
26
|
+
iterator.startReadingBits();
|
|
27
|
+
const adaptationFieldLength = iterator.getBits(8);
|
|
28
|
+
const headerOffset = iterator.counter.getOffset();
|
|
29
|
+
if (adaptationFieldLength > 0) {
|
|
30
|
+
iterator.getBits(1); // discontinuity indicator
|
|
31
|
+
iterator.getBits(1); // random access indicator
|
|
32
|
+
iterator.getBits(1); // elementary stream priority indicator
|
|
33
|
+
iterator.getBits(1); // PCR flag
|
|
34
|
+
iterator.getBits(1); // OPCR flag
|
|
35
|
+
iterator.getBits(1); // splicing point flag
|
|
36
|
+
iterator.getBits(1); // transport private data flag
|
|
37
|
+
iterator.getBits(1); // adaptation field extension flag
|
|
38
|
+
}
|
|
39
|
+
const remaining = adaptationFieldLength - (iterator.counter.getOffset() - headerOffset);
|
|
40
|
+
iterator.stopReadingBits();
|
|
41
|
+
const toDiscard = Math.max(0, remaining);
|
|
42
|
+
iterator.discard(toDiscard);
|
|
43
|
+
}
|
|
44
|
+
const read = iterator.counter.getOffset() - offset;
|
|
45
|
+
if (read === 188) {
|
|
46
|
+
return Promise.resolve(null);
|
|
47
|
+
}
|
|
48
|
+
const pat = structure.boxes.find((b) => b.type === 'transport-stream-pmt-box');
|
|
49
|
+
const isPes = payloadUnitStartIndicator && (pat === null || pat === void 0 ? void 0 : pat.streams.find((e) => e.pid === programId));
|
|
50
|
+
if (isPes) {
|
|
51
|
+
const packetPes = (0, parse_pes_1.parsePes)(iterator);
|
|
52
|
+
nextPesHeaderStore.setNextPesHeader(packetPes);
|
|
53
|
+
}
|
|
54
|
+
else if (payloadUnitStartIndicator === 1) {
|
|
55
|
+
iterator.getUint8(); // pointerField
|
|
56
|
+
}
|
|
57
|
+
if (programId === 0) {
|
|
58
|
+
return Promise.resolve((0, parse_pat_1.parsePat)(iterator));
|
|
59
|
+
}
|
|
60
|
+
const program = (0, traversal_1.getProgramForId)(structure, programId);
|
|
61
|
+
if (program) {
|
|
62
|
+
const pmt = (0, parse_pmt_1.parsePmt)(iterator);
|
|
63
|
+
return Promise.resolve(pmt);
|
|
64
|
+
}
|
|
65
|
+
const stream = (0, traversal_1.getStreamForId)(structure, programId);
|
|
66
|
+
if (stream) {
|
|
67
|
+
await (0, parse_stream_packet_1.parseStream)({
|
|
68
|
+
iterator,
|
|
69
|
+
transportStreamEntry: stream,
|
|
70
|
+
streamBuffers,
|
|
71
|
+
nextPesHeader: nextPesHeaderStore.getNextPesHeader(),
|
|
72
|
+
parserContext,
|
|
73
|
+
programId,
|
|
74
|
+
structure,
|
|
75
|
+
});
|
|
76
|
+
return Promise.resolve(null);
|
|
77
|
+
}
|
|
78
|
+
throw new Error('Unknown packet identifier');
|
|
79
|
+
};
|
|
80
|
+
exports.parsePacket = parsePacket;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { BufferIterator } from '../../buffer-iterator';
|
|
2
|
+
import type { TransportStreamPATBox } from './boxes';
|
|
3
|
+
export type TransportStreamProgramAssociationTableEntry = {
|
|
4
|
+
type: 'transport-stream-program-association-table';
|
|
5
|
+
programNumber: number;
|
|
6
|
+
programMapIdentifier: number;
|
|
7
|
+
};
|
|
8
|
+
export declare const parsePat: (iterator: BufferIterator) => TransportStreamPATBox;
|