@remotion/media-parser 4.0.271 → 4.0.273
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/containers/flac/get-channel-count.d.ts +1 -1
- package/dist/containers/flac/get-metadata-from-flac.d.ts +1 -1
- package/dist/containers/iso-base-media/get-seeking-from-mp4.d.ts +5 -0
- package/dist/containers/iso-base-media/get-seeking-from-mp4.js +50 -0
- package/dist/containers/m3u/iterate-over-segment-files.d.ts +2 -2
- package/dist/containers/m3u/iterate-over-segment-files.js +32 -28
- package/dist/containers/m3u/parse-directive.js +14 -0
- package/dist/containers/m3u/run-over-m3u.js +60 -46
- package/dist/containers/m3u/sample-sorter.d.ts +2 -0
- package/dist/containers/m3u/sample-sorter.js +13 -1
- package/dist/containers/m3u/types.d.ts +8 -1
- package/dist/containers/transport-stream/get-tracks.d.ts +2 -0
- package/dist/containers/transport-stream/get-tracks.js +6 -2
- package/dist/containers/transport-stream/parse-pmt.js +5 -5
- package/dist/containers/transport-stream/process-stream-buffers.js +2 -1
- package/dist/esm/index.mjs +64 -20
- package/dist/esm/worker-server-entry.mjs +63 -19
- package/dist/esm/worker-web-entry.mjs +63 -19
- package/dist/fields.d.ts +63 -0
- package/dist/fields.js +1 -0
- package/dist/get-seeking-info.d.ts +5 -0
- package/dist/get-seeking-info.js +24 -0
- package/dist/index.d.ts +3 -0
- package/dist/seeking-info.d.ts +8 -0
- package/dist/seeking-info.js +1 -0
- package/dist/state/has-tracks-section.d.ts +2 -2
- package/dist/state/has-tracks-section.js +4 -2
- package/dist/state/m3u-state.d.ts +3 -0
- package/dist/state/m3u-state.js +4 -1
- package/dist/state/parser-state.d.ts +3 -0
- package/dist/state/parser-state.js +1 -0
- package/dist/state/sample-callbacks.d.ts +3 -2
- package/dist/state/sample-callbacks.js +2 -2
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +3 -3
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { BufferIterator } from '../../buffer-iterator';
|
|
2
|
-
export declare const getChannelCount: (iterator: BufferIterator) => 2 | 8 | 1 | 7 | 3 |
|
|
2
|
+
export declare const getChannelCount: (iterator: BufferIterator) => 2 | 8 | 1 | 7 | 3 | 5 | 4 | 6;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { FlacStructure } from './types';
|
|
2
|
-
export declare const getMetadataFromFlac: (structure: FlacStructure) => import("../..").
|
|
2
|
+
export declare const getMetadataFromFlac: (structure: FlacStructure) => import("../..").MediaParserMetadataEntry[] | null;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { SamplePosition } from '../../get-sample-positions';
|
|
2
|
+
import type { IsoBaseMediaSeekingInfo, SeekingInfo } from '../../seeking-info';
|
|
3
|
+
import type { ParserState } from '../../state/parser-state';
|
|
4
|
+
export declare const getSeekingInfoFromMp4: (state: ParserState) => SeekingInfo | null;
|
|
5
|
+
export declare const getSeekingByteFromIsoBaseMedia: (info: IsoBaseMediaSeekingInfo, time: number) => SamplePosition;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { getTracksFromMoovBox } from '../../get-tracks';
|
|
2
|
+
import { getSamplePositionsFromTrack } from './get-sample-positions-from-track';
|
|
3
|
+
import { getMoofBoxes, getMoovBoxFromState } from './traversal';
|
|
4
|
+
export const getSeekingInfoFromMp4 = (state) => {
|
|
5
|
+
const structure = state.getIsoStructure();
|
|
6
|
+
const moovAtom = getMoovBoxFromState(state);
|
|
7
|
+
const moofBoxes = getMoofBoxes(structure.boxes);
|
|
8
|
+
if (!moovAtom) {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
return {
|
|
12
|
+
type: 'iso-base-media-seeking-info',
|
|
13
|
+
moovBox: moovAtom,
|
|
14
|
+
moofBoxes,
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
export const getSeekingByteFromIsoBaseMedia = (info, time) => {
|
|
18
|
+
const tracks = getTracksFromMoovBox(info.moovBox);
|
|
19
|
+
const allTracks = [
|
|
20
|
+
...tracks.videoTracks,
|
|
21
|
+
...tracks.audioTracks,
|
|
22
|
+
...tracks.otherTracks,
|
|
23
|
+
];
|
|
24
|
+
let byte = 0;
|
|
25
|
+
let sam = null;
|
|
26
|
+
for (const t of allTracks) {
|
|
27
|
+
const { timescale: ts, type } = t;
|
|
28
|
+
if (type !== 'video') {
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
const samplePositions = getSamplePositionsFromTrack({
|
|
32
|
+
trakBox: t.trakBox,
|
|
33
|
+
moofBoxes: info.moofBoxes,
|
|
34
|
+
});
|
|
35
|
+
for (const sample of samplePositions) {
|
|
36
|
+
const timestamp = sample.cts / ts;
|
|
37
|
+
if (timestamp <= time &&
|
|
38
|
+
byte < sample.offset &&
|
|
39
|
+
type === 'video' &&
|
|
40
|
+
sample.isKeyframe) {
|
|
41
|
+
byte = sample.offset;
|
|
42
|
+
sam = sample;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if (!sam) {
|
|
47
|
+
throw new Error('No sample found');
|
|
48
|
+
}
|
|
49
|
+
return sam;
|
|
50
|
+
};
|
|
@@ -7,8 +7,8 @@ import type { OnAudioSample, OnVideoSample } from '../../webcodec-sample-types';
|
|
|
7
7
|
import type { M3uStructure } from './types';
|
|
8
8
|
export declare const iteratorOverSegmentFiles: ({ structure, onVideoTrack, m3uState, onAudioTrack, onDoneWithTracks, playlistUrl, logLevel, parentController, onInitialProgress, readerInterface, }: {
|
|
9
9
|
structure: M3uStructure;
|
|
10
|
-
onVideoTrack: (track: VideoTrack) => Promise<OnVideoSample | null
|
|
11
|
-
onAudioTrack: (track: AudioTrack) => Promise<OnAudioSample | null
|
|
10
|
+
onVideoTrack: null | ((track: VideoTrack) => Promise<OnVideoSample | null>);
|
|
11
|
+
onAudioTrack: null | ((track: AudioTrack) => Promise<OnAudioSample | null>);
|
|
12
12
|
onDoneWithTracks: () => void;
|
|
13
13
|
m3uState: M3uState;
|
|
14
14
|
playlistUrl: string;
|
|
@@ -52,36 +52,40 @@ export const iteratorOverSegmentFiles = async ({ structure, onVideoTrack, m3uSta
|
|
|
52
52
|
return null;
|
|
53
53
|
}
|
|
54
54
|
},
|
|
55
|
-
onAudioTrack:
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
const
|
|
59
|
-
if (
|
|
60
|
-
|
|
61
|
-
|
|
55
|
+
onAudioTrack: onAudioTrack === null
|
|
56
|
+
? null
|
|
57
|
+
: async ({ track }) => {
|
|
58
|
+
const callbackOrFalse = m3uState.hasEmittedAudioTrack(playlistUrl);
|
|
59
|
+
if (callbackOrFalse === false) {
|
|
60
|
+
const callback = await onAudioTrack(track);
|
|
61
|
+
if (!callback) {
|
|
62
|
+
m3uState.setHasEmittedAudioTrack(playlistUrl, null);
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
m3uState.setHasEmittedAudioTrack(playlistUrl, callback);
|
|
66
|
+
return (sample) => {
|
|
67
|
+
return callback(sample);
|
|
68
|
+
};
|
|
62
69
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
m3uState.setHasEmittedVideoTrack(playlistUrl,
|
|
76
|
-
return
|
|
70
|
+
return callbackOrFalse;
|
|
71
|
+
},
|
|
72
|
+
onVideoTrack: onVideoTrack === null
|
|
73
|
+
? null
|
|
74
|
+
: async ({ track }) => {
|
|
75
|
+
const callbackOrFalse = m3uState.hasEmittedVideoTrack(playlistUrl);
|
|
76
|
+
if (callbackOrFalse === false) {
|
|
77
|
+
const callback = await onVideoTrack(track);
|
|
78
|
+
if (!callback) {
|
|
79
|
+
m3uState.setHasEmittedVideoTrack(playlistUrl, null);
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
m3uState.setHasEmittedVideoTrack(playlistUrl, callback);
|
|
83
|
+
return (sample) => {
|
|
84
|
+
return callback(sample);
|
|
85
|
+
};
|
|
77
86
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
return callback(sample);
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
return callbackOrFalse;
|
|
84
|
-
},
|
|
87
|
+
return callbackOrFalse;
|
|
88
|
+
},
|
|
85
89
|
reader: readerInterface,
|
|
86
90
|
mp4HeaderSegment,
|
|
87
91
|
});
|
|
@@ -82,6 +82,20 @@ export const parseM3uDirective = (str) => {
|
|
|
82
82
|
const res = parseStreamInf(value);
|
|
83
83
|
return res;
|
|
84
84
|
}
|
|
85
|
+
if (directive === '#EXT-X-I-FRAME-STREAM-INF') {
|
|
86
|
+
return {
|
|
87
|
+
type: 'm3u-i-frame-stream-info',
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
if (directive === '#EXT-X-ALLOW-CACHE') {
|
|
91
|
+
if (!value) {
|
|
92
|
+
throw new Error('#EXT-X-ALLOW-CACHE directive must have a value');
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
type: 'm3u-allow-cache',
|
|
96
|
+
allowsCache: value === 'YES',
|
|
97
|
+
};
|
|
98
|
+
}
|
|
85
99
|
if (directive === '#EXT-X-MAP') {
|
|
86
100
|
if (!value) {
|
|
87
101
|
throw new Error('#EXT-X-MAP directive must have a value');
|
|
@@ -2,6 +2,16 @@ import { Log } from '../../log';
|
|
|
2
2
|
import { registerAudioTrack, registerVideoTrack } from '../../register-track';
|
|
3
3
|
import { iteratorOverSegmentFiles } from './iterate-over-segment-files';
|
|
4
4
|
export const runOverM3u = async ({ state, structure, playlistUrl, logLevel, }) => {
|
|
5
|
+
const tracksDone = state.m3u.getTrackDone(playlistUrl);
|
|
6
|
+
const hasAudioStreamToConsider = state.m3u.sampleSorter.hasAudioStreamToConsider(playlistUrl);
|
|
7
|
+
const hasVideoStreamToConsider = state.m3u.sampleSorter.hasVideoStreamToConsider(playlistUrl);
|
|
8
|
+
const audioDone = !hasAudioStreamToConsider && tracksDone;
|
|
9
|
+
const videoDone = !hasVideoStreamToConsider && tracksDone;
|
|
10
|
+
const bothDone = audioDone && videoDone;
|
|
11
|
+
if (bothDone) {
|
|
12
|
+
state.m3u.setAllChunksProcessed(playlistUrl);
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
5
15
|
const existingRun = state.m3u.getM3uStreamRun(playlistUrl);
|
|
6
16
|
if (existingRun) {
|
|
7
17
|
Log.trace(logLevel, 'Existing M3U parsing process found for', playlistUrl);
|
|
@@ -28,52 +38,56 @@ export const runOverM3u = async ({ state, structure, playlistUrl, logLevel, }) =
|
|
|
28
38
|
state.callbacks.tracks.setIsDone(state.logLevel);
|
|
29
39
|
}
|
|
30
40
|
},
|
|
31
|
-
onAudioTrack:
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
trackId
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
41
|
+
onAudioTrack: audioDone
|
|
42
|
+
? null
|
|
43
|
+
: async (track) => {
|
|
44
|
+
const existingTracks = state.callbacks.tracks.getTracks();
|
|
45
|
+
let { trackId } = track;
|
|
46
|
+
while (existingTracks.find((t) => t.trackId === trackId)) {
|
|
47
|
+
trackId++;
|
|
48
|
+
}
|
|
49
|
+
const onAudioSample = await registerAudioTrack({
|
|
50
|
+
container: 'm3u8',
|
|
51
|
+
state,
|
|
52
|
+
track: {
|
|
53
|
+
...track,
|
|
54
|
+
trackId,
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
state.m3u.sampleSorter.addToStreamWithTrack(playlistUrl);
|
|
58
|
+
if (onAudioSample === null) {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
state.m3u.sampleSorter.addAudioStreamToConsider(playlistUrl, onAudioSample);
|
|
62
|
+
return async (sample) => {
|
|
63
|
+
await state.m3u.sampleSorter.addAudioSample(playlistUrl, sample);
|
|
64
|
+
};
|
|
65
|
+
},
|
|
66
|
+
onVideoTrack: videoDone
|
|
67
|
+
? null
|
|
68
|
+
: async (track) => {
|
|
69
|
+
const existingTracks = state.callbacks.tracks.getTracks();
|
|
70
|
+
let { trackId } = track;
|
|
71
|
+
while (existingTracks.find((t) => t.trackId === trackId)) {
|
|
72
|
+
trackId++;
|
|
73
|
+
}
|
|
74
|
+
const onVideoSample = await registerVideoTrack({
|
|
75
|
+
container: 'm3u8',
|
|
76
|
+
state,
|
|
77
|
+
track: {
|
|
78
|
+
...track,
|
|
79
|
+
trackId,
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
state.m3u.sampleSorter.addToStreamWithTrack(playlistUrl);
|
|
83
|
+
if (onVideoSample === null) {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
state.m3u.sampleSorter.addVideoStreamToConsider(playlistUrl, onVideoSample);
|
|
87
|
+
return async (sample) => {
|
|
88
|
+
await state.m3u.sampleSorter.addVideoSample(playlistUrl, sample);
|
|
89
|
+
};
|
|
90
|
+
},
|
|
77
91
|
m3uState: state.m3u,
|
|
78
92
|
parentController: state.controller,
|
|
79
93
|
readerInterface: state.readerInterface,
|
|
@@ -7,6 +7,8 @@ export declare const sampleSorter: ({ logLevel, getAllChunksProcessedForPlaylist
|
|
|
7
7
|
addToStreamWithTrack: (src: string) => void;
|
|
8
8
|
addVideoStreamToConsider: (src: string, callback: OnVideoSample) => void;
|
|
9
9
|
addAudioStreamToConsider: (src: string, callback: OnAudioSample) => void;
|
|
10
|
+
hasAudioStreamToConsider: (src: string) => boolean;
|
|
11
|
+
hasVideoStreamToConsider: (src: string) => boolean;
|
|
10
12
|
addAudioSample: (src: string, sample: AudioOrVideoSample) => Promise<void>;
|
|
11
13
|
addVideoSample: (src: string, sample: AudioOrVideoSample) => Promise<void>;
|
|
12
14
|
getNextStreamToRun: (streams: string[]) => string;
|
|
@@ -14,6 +14,12 @@ export const sampleSorter = ({ logLevel, getAllChunksProcessedForPlaylist, }) =>
|
|
|
14
14
|
addAudioStreamToConsider: (src, callback) => {
|
|
15
15
|
audioCallbacks[src] = callback;
|
|
16
16
|
},
|
|
17
|
+
hasAudioStreamToConsider: (src) => {
|
|
18
|
+
return Boolean(audioCallbacks[src]);
|
|
19
|
+
},
|
|
20
|
+
hasVideoStreamToConsider: (src) => {
|
|
21
|
+
return Boolean(videoCallbacks[src]);
|
|
22
|
+
},
|
|
17
23
|
addAudioSample: async (src, sample) => {
|
|
18
24
|
const callback = audioCallbacks[src];
|
|
19
25
|
if (!callback) {
|
|
@@ -25,7 +31,7 @@ export const sampleSorter = ({ logLevel, getAllChunksProcessedForPlaylist, }) =>
|
|
|
25
31
|
addVideoSample: async (src, sample) => {
|
|
26
32
|
const callback = videoCallbacks[src];
|
|
27
33
|
if (!callback) {
|
|
28
|
-
throw new Error('No callback found for
|
|
34
|
+
throw new Error('No callback found for video sample.');
|
|
29
35
|
}
|
|
30
36
|
latestSample[src] = sample.dts;
|
|
31
37
|
await callback(sample);
|
|
@@ -33,6 +39,9 @@ export const sampleSorter = ({ logLevel, getAllChunksProcessedForPlaylist, }) =>
|
|
|
33
39
|
getNextStreamToRun: (streams) => {
|
|
34
40
|
var _a, _b, _c;
|
|
35
41
|
for (const stream of streams) {
|
|
42
|
+
if (getAllChunksProcessedForPlaylist(stream)) {
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
36
45
|
// If a stream does not have a track yet, work on that
|
|
37
46
|
if (!streamsWithTracks.includes(stream)) {
|
|
38
47
|
Log.trace(logLevel, `Did not yet detect track of ${stream}, working on that`);
|
|
@@ -49,6 +58,9 @@ export const sampleSorter = ({ logLevel, getAllChunksProcessedForPlaylist, }) =>
|
|
|
49
58
|
}
|
|
50
59
|
}
|
|
51
60
|
for (const stream of streams) {
|
|
61
|
+
if (getAllChunksProcessedForPlaylist(stream)) {
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
52
64
|
if (((_c = latestSample[stream]) !== null && _c !== void 0 ? _c : 0) === smallestDts) {
|
|
53
65
|
Log.trace(logLevel, `Working on ${stream} because it has the smallest DTS`);
|
|
54
66
|
return stream;
|
|
@@ -40,6 +40,9 @@ export type M3uDiscontinuitySequence = {
|
|
|
40
40
|
type: 'm3u-discontinuity-sequence';
|
|
41
41
|
value: number;
|
|
42
42
|
};
|
|
43
|
+
export type M3uIFrameStreamInfo = {
|
|
44
|
+
type: 'm3u-i-frame-stream-info';
|
|
45
|
+
};
|
|
43
46
|
export type M3uMap = {
|
|
44
47
|
type: 'm3u-map';
|
|
45
48
|
value: string;
|
|
@@ -69,7 +72,11 @@ export type M3uTextValue = {
|
|
|
69
72
|
type: 'm3u-text-value';
|
|
70
73
|
value: string;
|
|
71
74
|
};
|
|
72
|
-
export type
|
|
75
|
+
export type M3uAllowCache = {
|
|
76
|
+
type: 'm3u-allow-cache';
|
|
77
|
+
allowsCache: boolean;
|
|
78
|
+
};
|
|
79
|
+
export type M3uBox = M3uHeader | M3uPlaylist | M3uVersion | M3uIndependentSegments | M3uStreamInfo | M3uTargetDuration | M3uPlaylistType | M3uExtInf | M3uMedia | M3uMediaInfo | M3uEndList | M3uMediaSequence | M3uDiscontinuitySequence | M3uMap | M3uIFrameStreamInfo | M3uTextValue | M3uAllowCache;
|
|
73
80
|
export type M3uStructure = {
|
|
74
81
|
type: 'm3u';
|
|
75
82
|
boxes: M3uBox[];
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { ParserState } from '../../state/parser-state';
|
|
2
2
|
import type { AllTracks } from '../riff/get-tracks-from-avi';
|
|
3
|
+
import type { TransportStreamEntry } from './parse-pmt';
|
|
4
|
+
export declare const filterStreamsBySupportedTypes: (streams: TransportStreamEntry[]) => TransportStreamEntry[];
|
|
3
5
|
export declare const getTracksFromTransportStream: (parserState: ParserState) => AllTracks;
|
|
4
6
|
export declare const hasAllTracksFromTransportStream: (parserState: ParserState) => boolean;
|
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
import { truthy } from '../../truthy';
|
|
2
2
|
import { findProgramMapTableOrThrow } from './traversal';
|
|
3
|
+
export const filterStreamsBySupportedTypes = (streams) => {
|
|
4
|
+
return streams.filter((stream) => stream.streamType === 27 || stream.streamType === 15);
|
|
5
|
+
};
|
|
3
6
|
export const getTracksFromTransportStream = (parserState) => {
|
|
4
7
|
const structure = parserState.getTsStructure();
|
|
5
8
|
const programMapTable = findProgramMapTableOrThrow(structure);
|
|
6
9
|
const parserTracks = parserState.callbacks.tracks.getTracks();
|
|
7
|
-
const mapped = programMapTable.streams
|
|
10
|
+
const mapped = filterStreamsBySupportedTypes(programMapTable.streams)
|
|
8
11
|
.map((stream) => {
|
|
9
12
|
return parserTracks.find((track) => track.trackId === stream.pid);
|
|
10
13
|
})
|
|
11
14
|
.filter(truthy);
|
|
12
|
-
if (mapped.length !==
|
|
15
|
+
if (mapped.length !==
|
|
16
|
+
filterStreamsBySupportedTypes(programMapTable.streams).length) {
|
|
13
17
|
throw new Error('Not all tracks found');
|
|
14
18
|
}
|
|
15
19
|
return {
|
|
@@ -8,11 +8,12 @@ const parsePmtTable = ({ iterator, tableId, sectionLength, }) => {
|
|
|
8
8
|
const sectionNumber = iterator.getBits(8);
|
|
9
9
|
const lastSectionNumber = iterator.getBits(8);
|
|
10
10
|
const tables = [];
|
|
11
|
+
iterator.getBits(3); // reserved
|
|
12
|
+
iterator.getBits(13); // PCR PID
|
|
13
|
+
iterator.getBits(4); // reserved
|
|
14
|
+
const programInfoLength = iterator.getBits(12);
|
|
15
|
+
iterator.getBits(programInfoLength * 8); // program descriptor
|
|
11
16
|
for (let i = sectionNumber; i <= lastSectionNumber; i++) {
|
|
12
|
-
iterator.getBits(3); // reserved
|
|
13
|
-
iterator.getBits(13); // PCR PID
|
|
14
|
-
iterator.getBits(4); // reserved
|
|
15
|
-
const programInfoLength = iterator.getBits(12);
|
|
16
17
|
const streams = [];
|
|
17
18
|
while (true) {
|
|
18
19
|
const streamType = iterator.getBits(8);
|
|
@@ -22,7 +23,6 @@ const parsePmtTable = ({ iterator, tableId, sectionLength, }) => {
|
|
|
22
23
|
const esInfoLength = iterator.getBits(12);
|
|
23
24
|
iterator.getBits(esInfoLength * 8);
|
|
24
25
|
streams.push({ streamType, pid: elementaryPid });
|
|
25
|
-
iterator.getBits(programInfoLength * 8); // program descriptor
|
|
26
26
|
const remaining = sectionLength - (iterator.counter.getOffset() - start);
|
|
27
27
|
if (remaining <= 4) {
|
|
28
28
|
break;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { filterStreamsBySupportedTypes } from './get-tracks';
|
|
1
2
|
import { handleAacPacket } from './handle-aac-packet';
|
|
2
3
|
import { handleAvcPacket } from './handle-avc-packet';
|
|
3
4
|
import { findProgramMapTableOrThrow, getStreamForId } from './traversal';
|
|
@@ -27,7 +28,7 @@ export const processStreamBuffer = async ({ streamBuffer, state, programId, stru
|
|
|
27
28
|
if (!state.callbacks.tracks.hasAllTracks()) {
|
|
28
29
|
const tracksRegistered = state.callbacks.tracks.getTracks().length;
|
|
29
30
|
const { streams } = findProgramMapTableOrThrow(structure);
|
|
30
|
-
if (streams.length === tracksRegistered) {
|
|
31
|
+
if (filterStreamsBySupportedTypes(streams).length === tracksRegistered) {
|
|
31
32
|
state.callbacks.tracks.setIsDone(state.logLevel);
|
|
32
33
|
}
|
|
33
34
|
}
|