@remotion/media-parser 4.0.271 → 4.0.272
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/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/index.d.ts +3 -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;
|
|
@@ -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
|
}
|
package/dist/esm/index.mjs
CHANGED
|
@@ -2479,14 +2479,17 @@ var getStreamForId = (structure, packetIdentifier) => {
|
|
|
2479
2479
|
};
|
|
2480
2480
|
|
|
2481
2481
|
// src/containers/transport-stream/get-tracks.ts
|
|
2482
|
+
var filterStreamsBySupportedTypes = (streams) => {
|
|
2483
|
+
return streams.filter((stream) => stream.streamType === 27 || stream.streamType === 15);
|
|
2484
|
+
};
|
|
2482
2485
|
var getTracksFromTransportStream = (parserState) => {
|
|
2483
2486
|
const structure = parserState.getTsStructure();
|
|
2484
2487
|
const programMapTable = findProgramMapTableOrThrow(structure);
|
|
2485
2488
|
const parserTracks = parserState.callbacks.tracks.getTracks();
|
|
2486
|
-
const mapped = programMapTable.streams.map((stream) => {
|
|
2489
|
+
const mapped = filterStreamsBySupportedTypes(programMapTable.streams).map((stream) => {
|
|
2487
2490
|
return parserTracks.find((track) => track.trackId === stream.pid);
|
|
2488
2491
|
}).filter(truthy);
|
|
2489
|
-
if (mapped.length !== programMapTable.streams.length) {
|
|
2492
|
+
if (mapped.length !== filterStreamsBySupportedTypes(programMapTable.streams).length) {
|
|
2490
2493
|
throw new Error("Not all tracks found");
|
|
2491
2494
|
}
|
|
2492
2495
|
return {
|
|
@@ -8322,6 +8325,12 @@ var sampleSorter = ({
|
|
|
8322
8325
|
addAudioStreamToConsider: (src, callback) => {
|
|
8323
8326
|
audioCallbacks[src] = callback;
|
|
8324
8327
|
},
|
|
8328
|
+
hasAudioStreamToConsider: (src) => {
|
|
8329
|
+
return Boolean(audioCallbacks[src]);
|
|
8330
|
+
},
|
|
8331
|
+
hasVideoStreamToConsider: (src) => {
|
|
8332
|
+
return Boolean(videoCallbacks[src]);
|
|
8333
|
+
},
|
|
8325
8334
|
addAudioSample: async (src, sample) => {
|
|
8326
8335
|
const callback = audioCallbacks[src];
|
|
8327
8336
|
if (!callback) {
|
|
@@ -8333,13 +8342,16 @@ var sampleSorter = ({
|
|
|
8333
8342
|
addVideoSample: async (src, sample) => {
|
|
8334
8343
|
const callback = videoCallbacks[src];
|
|
8335
8344
|
if (!callback) {
|
|
8336
|
-
throw new Error("No callback found for
|
|
8345
|
+
throw new Error("No callback found for video sample.");
|
|
8337
8346
|
}
|
|
8338
8347
|
latestSample[src] = sample.dts;
|
|
8339
8348
|
await callback(sample);
|
|
8340
8349
|
},
|
|
8341
8350
|
getNextStreamToRun: (streams) => {
|
|
8342
8351
|
for (const stream of streams) {
|
|
8352
|
+
if (getAllChunksProcessedForPlaylist(stream)) {
|
|
8353
|
+
continue;
|
|
8354
|
+
}
|
|
8343
8355
|
if (!streamsWithTracks.includes(stream)) {
|
|
8344
8356
|
Log.trace(logLevel, `Did not yet detect track of ${stream}, working on that`);
|
|
8345
8357
|
return stream;
|
|
@@ -8355,6 +8367,9 @@ var sampleSorter = ({
|
|
|
8355
8367
|
}
|
|
8356
8368
|
}
|
|
8357
8369
|
for (const stream of streams) {
|
|
8370
|
+
if (getAllChunksProcessedForPlaylist(stream)) {
|
|
8371
|
+
continue;
|
|
8372
|
+
}
|
|
8358
8373
|
if ((latestSample[stream] ?? 0) === smallestDts) {
|
|
8359
8374
|
Log.trace(logLevel, `Working on ${stream} because it has the smallest DTS`);
|
|
8360
8375
|
return stream;
|
|
@@ -8426,7 +8441,7 @@ var m3uState = (logLevel) => {
|
|
|
8426
8441
|
setHasEmittedDoneWithTracks: (src) => {
|
|
8427
8442
|
hasEmittedDoneWithTracks[src] = true;
|
|
8428
8443
|
},
|
|
8429
|
-
hasEmittedDoneWithTracks: (src) => hasEmittedDoneWithTracks[src],
|
|
8444
|
+
hasEmittedDoneWithTracks: (src) => hasEmittedDoneWithTracks[src] !== undefined,
|
|
8430
8445
|
setReadyToIterateOverM3u: () => {
|
|
8431
8446
|
readyToIterateOverM3u = true;
|
|
8432
8447
|
},
|
|
@@ -8458,6 +8473,9 @@ var m3uState = (logLevel) => {
|
|
|
8458
8473
|
const selectedPlaylists = getSelectedPlaylists();
|
|
8459
8474
|
return selectedPlaylists.every((url) => tracksDone[url]);
|
|
8460
8475
|
},
|
|
8476
|
+
getTrackDone: (playlistUrl) => {
|
|
8477
|
+
return tracksDone[playlistUrl];
|
|
8478
|
+
},
|
|
8461
8479
|
getM3uStreamRun: (playlistUrl) => m3uStreamRuns[playlistUrl] ?? null,
|
|
8462
8480
|
abortM3UStreamRuns: () => {
|
|
8463
8481
|
const values = Object.values(m3uStreamRuns);
|
|
@@ -8564,7 +8582,7 @@ var makeCanSkipTracksState = ({
|
|
|
8564
8582
|
};
|
|
8565
8583
|
|
|
8566
8584
|
// src/state/has-tracks-section.ts
|
|
8567
|
-
var makeTracksSectionState = (canSkipTracksState) => {
|
|
8585
|
+
var makeTracksSectionState = (canSkipTracksState, src) => {
|
|
8568
8586
|
const tracks2 = [];
|
|
8569
8587
|
let doneWithTracks = false;
|
|
8570
8588
|
return {
|
|
@@ -8589,7 +8607,7 @@ var makeTracksSectionState = (canSkipTracksState) => {
|
|
|
8589
8607
|
return;
|
|
8590
8608
|
}
|
|
8591
8609
|
if (!doneWithTracks) {
|
|
8592
|
-
throw new Error("Error in Media Parser: End of parsing has been reached, but no tracks have been found");
|
|
8610
|
+
throw new Error("Error in Media Parser: End of parsing of " + src + " has been reached, but no tracks have been found ");
|
|
8593
8611
|
}
|
|
8594
8612
|
}
|
|
8595
8613
|
};
|
|
@@ -8604,7 +8622,8 @@ var sampleCallback = ({
|
|
|
8604
8622
|
keyframes,
|
|
8605
8623
|
emittedFields,
|
|
8606
8624
|
slowDurationAndFpsState,
|
|
8607
|
-
structure
|
|
8625
|
+
structure,
|
|
8626
|
+
src
|
|
8608
8627
|
}) => {
|
|
8609
8628
|
const videoSampleCallbacks = {};
|
|
8610
8629
|
const audioSampleCallbacks = {};
|
|
@@ -8616,7 +8635,7 @@ var sampleCallback = ({
|
|
|
8616
8635
|
hasVideoTrackHandlers,
|
|
8617
8636
|
structure
|
|
8618
8637
|
});
|
|
8619
|
-
const tracksState = makeTracksSectionState(canSkipTracksState);
|
|
8638
|
+
const tracksState = makeTracksSectionState(canSkipTracksState, src);
|
|
8620
8639
|
const samplesForTrack = {};
|
|
8621
8640
|
return {
|
|
8622
8641
|
registerVideoSampleCallback: async (id, callback) => {
|
|
@@ -9065,7 +9084,8 @@ var makeParserState = ({
|
|
|
9065
9084
|
keyframes,
|
|
9066
9085
|
emittedFields,
|
|
9067
9086
|
slowDurationAndFpsState: slowDurationAndFps,
|
|
9068
|
-
structure
|
|
9087
|
+
structure,
|
|
9088
|
+
src
|
|
9069
9089
|
}),
|
|
9070
9090
|
getInternalStats: () => ({
|
|
9071
9091
|
skippedBytes,
|
|
@@ -9420,6 +9440,20 @@ var parseM3uDirective = (str) => {
|
|
|
9420
9440
|
const res = parseStreamInf(value);
|
|
9421
9441
|
return res;
|
|
9422
9442
|
}
|
|
9443
|
+
if (directive === "#EXT-X-I-FRAME-STREAM-INF") {
|
|
9444
|
+
return {
|
|
9445
|
+
type: "m3u-i-frame-stream-info"
|
|
9446
|
+
};
|
|
9447
|
+
}
|
|
9448
|
+
if (directive === "#EXT-X-ALLOW-CACHE") {
|
|
9449
|
+
if (!value) {
|
|
9450
|
+
throw new Error("#EXT-X-ALLOW-CACHE directive must have a value");
|
|
9451
|
+
}
|
|
9452
|
+
return {
|
|
9453
|
+
type: "m3u-allow-cache",
|
|
9454
|
+
allowsCache: value === "YES"
|
|
9455
|
+
};
|
|
9456
|
+
}
|
|
9423
9457
|
if (directive === "#EXT-X-MAP") {
|
|
9424
9458
|
if (!value) {
|
|
9425
9459
|
throw new Error("#EXT-X-MAP directive must have a value");
|
|
@@ -9993,7 +10027,7 @@ var iteratorOverSegmentFiles = async ({
|
|
|
9993
10027
|
return null;
|
|
9994
10028
|
}
|
|
9995
10029
|
},
|
|
9996
|
-
onAudioTrack: async ({ track }) => {
|
|
10030
|
+
onAudioTrack: onAudioTrack === null ? null : async ({ track }) => {
|
|
9997
10031
|
const callbackOrFalse = m3uState2.hasEmittedAudioTrack(playlistUrl);
|
|
9998
10032
|
if (callbackOrFalse === false) {
|
|
9999
10033
|
const callback = await onAudioTrack(track);
|
|
@@ -10008,7 +10042,7 @@ var iteratorOverSegmentFiles = async ({
|
|
|
10008
10042
|
}
|
|
10009
10043
|
return callbackOrFalse;
|
|
10010
10044
|
},
|
|
10011
|
-
onVideoTrack: async ({ track }) => {
|
|
10045
|
+
onVideoTrack: onVideoTrack === null ? null : async ({ track }) => {
|
|
10012
10046
|
const callbackOrFalse = m3uState2.hasEmittedVideoTrack(playlistUrl);
|
|
10013
10047
|
if (callbackOrFalse === false) {
|
|
10014
10048
|
const callback = await onVideoTrack(track);
|
|
@@ -10052,6 +10086,16 @@ var runOverM3u = async ({
|
|
|
10052
10086
|
playlistUrl,
|
|
10053
10087
|
logLevel
|
|
10054
10088
|
}) => {
|
|
10089
|
+
const tracksDone = state.m3u.getTrackDone(playlistUrl);
|
|
10090
|
+
const hasAudioStreamToConsider = state.m3u.sampleSorter.hasAudioStreamToConsider(playlistUrl);
|
|
10091
|
+
const hasVideoStreamToConsider = state.m3u.sampleSorter.hasVideoStreamToConsider(playlistUrl);
|
|
10092
|
+
const audioDone = !hasAudioStreamToConsider && tracksDone;
|
|
10093
|
+
const videoDone = !hasVideoStreamToConsider && tracksDone;
|
|
10094
|
+
const bothDone = audioDone && videoDone;
|
|
10095
|
+
if (bothDone) {
|
|
10096
|
+
state.m3u.setAllChunksProcessed(playlistUrl);
|
|
10097
|
+
return;
|
|
10098
|
+
}
|
|
10055
10099
|
const existingRun = state.m3u.getM3uStreamRun(playlistUrl);
|
|
10056
10100
|
if (existingRun) {
|
|
10057
10101
|
Log.trace(logLevel, "Existing M3U parsing process found for", playlistUrl);
|
|
@@ -10078,7 +10122,7 @@ var runOverM3u = async ({
|
|
|
10078
10122
|
state.callbacks.tracks.setIsDone(state.logLevel);
|
|
10079
10123
|
}
|
|
10080
10124
|
},
|
|
10081
|
-
onAudioTrack: async (track) => {
|
|
10125
|
+
onAudioTrack: audioDone ? null : async (track) => {
|
|
10082
10126
|
const existingTracks = state.callbacks.tracks.getTracks();
|
|
10083
10127
|
let { trackId } = track;
|
|
10084
10128
|
while (existingTracks.find((t) => t.trackId === trackId)) {
|
|
@@ -10101,7 +10145,7 @@ var runOverM3u = async ({
|
|
|
10101
10145
|
await state.m3u.sampleSorter.addAudioSample(playlistUrl, sample);
|
|
10102
10146
|
};
|
|
10103
10147
|
},
|
|
10104
|
-
onVideoTrack: async (track) => {
|
|
10148
|
+
onVideoTrack: videoDone ? null : async (track) => {
|
|
10105
10149
|
const existingTracks = state.callbacks.tracks.getTracks();
|
|
10106
10150
|
let { trackId } = track;
|
|
10107
10151
|
while (existingTracks.find((t) => t.trackId === trackId)) {
|
|
@@ -11175,11 +11219,12 @@ var parsePmtTable = ({
|
|
|
11175
11219
|
const sectionNumber = iterator.getBits(8);
|
|
11176
11220
|
const lastSectionNumber = iterator.getBits(8);
|
|
11177
11221
|
const tables = [];
|
|
11222
|
+
iterator.getBits(3);
|
|
11223
|
+
iterator.getBits(13);
|
|
11224
|
+
iterator.getBits(4);
|
|
11225
|
+
const programInfoLength = iterator.getBits(12);
|
|
11226
|
+
iterator.getBits(programInfoLength * 8);
|
|
11178
11227
|
for (let i = sectionNumber;i <= lastSectionNumber; i++) {
|
|
11179
|
-
iterator.getBits(3);
|
|
11180
|
-
iterator.getBits(13);
|
|
11181
|
-
iterator.getBits(4);
|
|
11182
|
-
const programInfoLength = iterator.getBits(12);
|
|
11183
11228
|
const streams = [];
|
|
11184
11229
|
while (true) {
|
|
11185
11230
|
const streamType = iterator.getBits(8);
|
|
@@ -11189,7 +11234,6 @@ var parsePmtTable = ({
|
|
|
11189
11234
|
const esInfoLength = iterator.getBits(12);
|
|
11190
11235
|
iterator.getBits(esInfoLength * 8);
|
|
11191
11236
|
streams.push({ streamType, pid: elementaryPid });
|
|
11192
|
-
iterator.getBits(programInfoLength * 8);
|
|
11193
11237
|
const remaining = sectionLength - (iterator.counter.getOffset() - start);
|
|
11194
11238
|
if (remaining <= 4) {
|
|
11195
11239
|
break;
|
|
@@ -11476,7 +11520,7 @@ var processStreamBuffer = async ({
|
|
|
11476
11520
|
if (!state.callbacks.tracks.hasAllTracks()) {
|
|
11477
11521
|
const tracksRegistered = state.callbacks.tracks.getTracks().length;
|
|
11478
11522
|
const { streams } = findProgramMapTableOrThrow(structure);
|
|
11479
|
-
if (streams.length === tracksRegistered) {
|
|
11523
|
+
if (filterStreamsBySupportedTypes(streams).length === tracksRegistered) {
|
|
11480
11524
|
state.callbacks.tracks.setIsDone(state.logLevel);
|
|
11481
11525
|
}
|
|
11482
11526
|
}
|
|
@@ -12957,7 +13001,7 @@ var downloadAndParseMedia = async (options) => {
|
|
|
12957
13001
|
return returnValue;
|
|
12958
13002
|
};
|
|
12959
13003
|
// src/version.ts
|
|
12960
|
-
var VERSION = "4.0.
|
|
13004
|
+
var VERSION = "4.0.272";
|
|
12961
13005
|
|
|
12962
13006
|
// src/index.ts
|
|
12963
13007
|
var MediaParserInternals = {
|
|
@@ -3131,14 +3131,17 @@ var getStreamForId = (structure, packetIdentifier) => {
|
|
|
3131
3131
|
};
|
|
3132
3132
|
|
|
3133
3133
|
// src/containers/transport-stream/get-tracks.ts
|
|
3134
|
+
var filterStreamsBySupportedTypes = (streams) => {
|
|
3135
|
+
return streams.filter((stream) => stream.streamType === 27 || stream.streamType === 15);
|
|
3136
|
+
};
|
|
3134
3137
|
var getTracksFromTransportStream = (parserState) => {
|
|
3135
3138
|
const structure = parserState.getTsStructure();
|
|
3136
3139
|
const programMapTable = findProgramMapTableOrThrow(structure);
|
|
3137
3140
|
const parserTracks = parserState.callbacks.tracks.getTracks();
|
|
3138
|
-
const mapped = programMapTable.streams.map((stream) => {
|
|
3141
|
+
const mapped = filterStreamsBySupportedTypes(programMapTable.streams).map((stream) => {
|
|
3139
3142
|
return parserTracks.find((track) => track.trackId === stream.pid);
|
|
3140
3143
|
}).filter(truthy);
|
|
3141
|
-
if (mapped.length !== programMapTable.streams.length) {
|
|
3144
|
+
if (mapped.length !== filterStreamsBySupportedTypes(programMapTable.streams).length) {
|
|
3142
3145
|
throw new Error("Not all tracks found");
|
|
3143
3146
|
}
|
|
3144
3147
|
return {
|
|
@@ -6516,6 +6519,12 @@ var sampleSorter = ({
|
|
|
6516
6519
|
addAudioStreamToConsider: (src, callback) => {
|
|
6517
6520
|
audioCallbacks[src] = callback;
|
|
6518
6521
|
},
|
|
6522
|
+
hasAudioStreamToConsider: (src) => {
|
|
6523
|
+
return Boolean(audioCallbacks[src]);
|
|
6524
|
+
},
|
|
6525
|
+
hasVideoStreamToConsider: (src) => {
|
|
6526
|
+
return Boolean(videoCallbacks[src]);
|
|
6527
|
+
},
|
|
6519
6528
|
addAudioSample: async (src, sample) => {
|
|
6520
6529
|
const callback = audioCallbacks[src];
|
|
6521
6530
|
if (!callback) {
|
|
@@ -6527,13 +6536,16 @@ var sampleSorter = ({
|
|
|
6527
6536
|
addVideoSample: async (src, sample) => {
|
|
6528
6537
|
const callback = videoCallbacks[src];
|
|
6529
6538
|
if (!callback) {
|
|
6530
|
-
throw new Error("No callback found for
|
|
6539
|
+
throw new Error("No callback found for video sample.");
|
|
6531
6540
|
}
|
|
6532
6541
|
latestSample[src] = sample.dts;
|
|
6533
6542
|
await callback(sample);
|
|
6534
6543
|
},
|
|
6535
6544
|
getNextStreamToRun: (streams) => {
|
|
6536
6545
|
for (const stream of streams) {
|
|
6546
|
+
if (getAllChunksProcessedForPlaylist(stream)) {
|
|
6547
|
+
continue;
|
|
6548
|
+
}
|
|
6537
6549
|
if (!streamsWithTracks.includes(stream)) {
|
|
6538
6550
|
Log.trace(logLevel, `Did not yet detect track of ${stream}, working on that`);
|
|
6539
6551
|
return stream;
|
|
@@ -6549,6 +6561,9 @@ var sampleSorter = ({
|
|
|
6549
6561
|
}
|
|
6550
6562
|
}
|
|
6551
6563
|
for (const stream of streams) {
|
|
6564
|
+
if (getAllChunksProcessedForPlaylist(stream)) {
|
|
6565
|
+
continue;
|
|
6566
|
+
}
|
|
6552
6567
|
if ((latestSample[stream] ?? 0) === smallestDts) {
|
|
6553
6568
|
Log.trace(logLevel, `Working on ${stream} because it has the smallest DTS`);
|
|
6554
6569
|
return stream;
|
|
@@ -6620,7 +6635,7 @@ var m3uState = (logLevel) => {
|
|
|
6620
6635
|
setHasEmittedDoneWithTracks: (src) => {
|
|
6621
6636
|
hasEmittedDoneWithTracks[src] = true;
|
|
6622
6637
|
},
|
|
6623
|
-
hasEmittedDoneWithTracks: (src) => hasEmittedDoneWithTracks[src],
|
|
6638
|
+
hasEmittedDoneWithTracks: (src) => hasEmittedDoneWithTracks[src] !== undefined,
|
|
6624
6639
|
setReadyToIterateOverM3u: () => {
|
|
6625
6640
|
readyToIterateOverM3u = true;
|
|
6626
6641
|
},
|
|
@@ -6652,6 +6667,9 @@ var m3uState = (logLevel) => {
|
|
|
6652
6667
|
const selectedPlaylists = getSelectedPlaylists();
|
|
6653
6668
|
return selectedPlaylists.every((url) => tracksDone[url]);
|
|
6654
6669
|
},
|
|
6670
|
+
getTrackDone: (playlistUrl) => {
|
|
6671
|
+
return tracksDone[playlistUrl];
|
|
6672
|
+
},
|
|
6655
6673
|
getM3uStreamRun: (playlistUrl) => m3uStreamRuns[playlistUrl] ?? null,
|
|
6656
6674
|
abortM3UStreamRuns: () => {
|
|
6657
6675
|
const values = Object.values(m3uStreamRuns);
|
|
@@ -6758,7 +6776,7 @@ var makeCanSkipTracksState = ({
|
|
|
6758
6776
|
};
|
|
6759
6777
|
|
|
6760
6778
|
// src/state/has-tracks-section.ts
|
|
6761
|
-
var makeTracksSectionState = (canSkipTracksState) => {
|
|
6779
|
+
var makeTracksSectionState = (canSkipTracksState, src) => {
|
|
6762
6780
|
const tracks2 = [];
|
|
6763
6781
|
let doneWithTracks = false;
|
|
6764
6782
|
return {
|
|
@@ -6783,7 +6801,7 @@ var makeTracksSectionState = (canSkipTracksState) => {
|
|
|
6783
6801
|
return;
|
|
6784
6802
|
}
|
|
6785
6803
|
if (!doneWithTracks) {
|
|
6786
|
-
throw new Error("Error in Media Parser: End of parsing has been reached, but no tracks have been found");
|
|
6804
|
+
throw new Error("Error in Media Parser: End of parsing of " + src + " has been reached, but no tracks have been found ");
|
|
6787
6805
|
}
|
|
6788
6806
|
}
|
|
6789
6807
|
};
|
|
@@ -6798,7 +6816,8 @@ var sampleCallback = ({
|
|
|
6798
6816
|
keyframes,
|
|
6799
6817
|
emittedFields,
|
|
6800
6818
|
slowDurationAndFpsState,
|
|
6801
|
-
structure
|
|
6819
|
+
structure,
|
|
6820
|
+
src
|
|
6802
6821
|
}) => {
|
|
6803
6822
|
const videoSampleCallbacks = {};
|
|
6804
6823
|
const audioSampleCallbacks = {};
|
|
@@ -6810,7 +6829,7 @@ var sampleCallback = ({
|
|
|
6810
6829
|
hasVideoTrackHandlers,
|
|
6811
6830
|
structure
|
|
6812
6831
|
});
|
|
6813
|
-
const tracksState = makeTracksSectionState(canSkipTracksState);
|
|
6832
|
+
const tracksState = makeTracksSectionState(canSkipTracksState, src);
|
|
6814
6833
|
const samplesForTrack = {};
|
|
6815
6834
|
return {
|
|
6816
6835
|
registerVideoSampleCallback: async (id, callback) => {
|
|
@@ -7259,7 +7278,8 @@ var makeParserState = ({
|
|
|
7259
7278
|
keyframes,
|
|
7260
7279
|
emittedFields,
|
|
7261
7280
|
slowDurationAndFpsState: slowDurationAndFps,
|
|
7262
|
-
structure
|
|
7281
|
+
structure,
|
|
7282
|
+
src
|
|
7263
7283
|
}),
|
|
7264
7284
|
getInternalStats: () => ({
|
|
7265
7285
|
skippedBytes,
|
|
@@ -9242,6 +9262,20 @@ var parseM3uDirective = (str) => {
|
|
|
9242
9262
|
const res = parseStreamInf(value);
|
|
9243
9263
|
return res;
|
|
9244
9264
|
}
|
|
9265
|
+
if (directive === "#EXT-X-I-FRAME-STREAM-INF") {
|
|
9266
|
+
return {
|
|
9267
|
+
type: "m3u-i-frame-stream-info"
|
|
9268
|
+
};
|
|
9269
|
+
}
|
|
9270
|
+
if (directive === "#EXT-X-ALLOW-CACHE") {
|
|
9271
|
+
if (!value) {
|
|
9272
|
+
throw new Error("#EXT-X-ALLOW-CACHE directive must have a value");
|
|
9273
|
+
}
|
|
9274
|
+
return {
|
|
9275
|
+
type: "m3u-allow-cache",
|
|
9276
|
+
allowsCache: value === "YES"
|
|
9277
|
+
};
|
|
9278
|
+
}
|
|
9245
9279
|
if (directive === "#EXT-X-MAP") {
|
|
9246
9280
|
if (!value) {
|
|
9247
9281
|
throw new Error("#EXT-X-MAP directive must have a value");
|
|
@@ -9548,7 +9582,7 @@ var iteratorOverSegmentFiles = async ({
|
|
|
9548
9582
|
return null;
|
|
9549
9583
|
}
|
|
9550
9584
|
},
|
|
9551
|
-
onAudioTrack: async ({ track }) => {
|
|
9585
|
+
onAudioTrack: onAudioTrack === null ? null : async ({ track }) => {
|
|
9552
9586
|
const callbackOrFalse = m3uState2.hasEmittedAudioTrack(playlistUrl);
|
|
9553
9587
|
if (callbackOrFalse === false) {
|
|
9554
9588
|
const callback = await onAudioTrack(track);
|
|
@@ -9563,7 +9597,7 @@ var iteratorOverSegmentFiles = async ({
|
|
|
9563
9597
|
}
|
|
9564
9598
|
return callbackOrFalse;
|
|
9565
9599
|
},
|
|
9566
|
-
onVideoTrack: async ({ track }) => {
|
|
9600
|
+
onVideoTrack: onVideoTrack === null ? null : async ({ track }) => {
|
|
9567
9601
|
const callbackOrFalse = m3uState2.hasEmittedVideoTrack(playlistUrl);
|
|
9568
9602
|
if (callbackOrFalse === false) {
|
|
9569
9603
|
const callback = await onVideoTrack(track);
|
|
@@ -9607,6 +9641,16 @@ var runOverM3u = async ({
|
|
|
9607
9641
|
playlistUrl,
|
|
9608
9642
|
logLevel
|
|
9609
9643
|
}) => {
|
|
9644
|
+
const tracksDone = state.m3u.getTrackDone(playlistUrl);
|
|
9645
|
+
const hasAudioStreamToConsider = state.m3u.sampleSorter.hasAudioStreamToConsider(playlistUrl);
|
|
9646
|
+
const hasVideoStreamToConsider = state.m3u.sampleSorter.hasVideoStreamToConsider(playlistUrl);
|
|
9647
|
+
const audioDone = !hasAudioStreamToConsider && tracksDone;
|
|
9648
|
+
const videoDone = !hasVideoStreamToConsider && tracksDone;
|
|
9649
|
+
const bothDone = audioDone && videoDone;
|
|
9650
|
+
if (bothDone) {
|
|
9651
|
+
state.m3u.setAllChunksProcessed(playlistUrl);
|
|
9652
|
+
return;
|
|
9653
|
+
}
|
|
9610
9654
|
const existingRun = state.m3u.getM3uStreamRun(playlistUrl);
|
|
9611
9655
|
if (existingRun) {
|
|
9612
9656
|
Log.trace(logLevel, "Existing M3U parsing process found for", playlistUrl);
|
|
@@ -9633,7 +9677,7 @@ var runOverM3u = async ({
|
|
|
9633
9677
|
state.callbacks.tracks.setIsDone(state.logLevel);
|
|
9634
9678
|
}
|
|
9635
9679
|
},
|
|
9636
|
-
onAudioTrack: async (track) => {
|
|
9680
|
+
onAudioTrack: audioDone ? null : async (track) => {
|
|
9637
9681
|
const existingTracks = state.callbacks.tracks.getTracks();
|
|
9638
9682
|
let { trackId } = track;
|
|
9639
9683
|
while (existingTracks.find((t) => t.trackId === trackId)) {
|
|
@@ -9656,7 +9700,7 @@ var runOverM3u = async ({
|
|
|
9656
9700
|
await state.m3u.sampleSorter.addAudioSample(playlistUrl, sample);
|
|
9657
9701
|
};
|
|
9658
9702
|
},
|
|
9659
|
-
onVideoTrack: async (track) => {
|
|
9703
|
+
onVideoTrack: videoDone ? null : async (track) => {
|
|
9660
9704
|
const existingTracks = state.callbacks.tracks.getTracks();
|
|
9661
9705
|
let { trackId } = track;
|
|
9662
9706
|
while (existingTracks.find((t) => t.trackId === trackId)) {
|
|
@@ -10959,11 +11003,12 @@ var parsePmtTable = ({
|
|
|
10959
11003
|
const sectionNumber = iterator.getBits(8);
|
|
10960
11004
|
const lastSectionNumber = iterator.getBits(8);
|
|
10961
11005
|
const tables = [];
|
|
11006
|
+
iterator.getBits(3);
|
|
11007
|
+
iterator.getBits(13);
|
|
11008
|
+
iterator.getBits(4);
|
|
11009
|
+
const programInfoLength = iterator.getBits(12);
|
|
11010
|
+
iterator.getBits(programInfoLength * 8);
|
|
10962
11011
|
for (let i = sectionNumber;i <= lastSectionNumber; i++) {
|
|
10963
|
-
iterator.getBits(3);
|
|
10964
|
-
iterator.getBits(13);
|
|
10965
|
-
iterator.getBits(4);
|
|
10966
|
-
const programInfoLength = iterator.getBits(12);
|
|
10967
11012
|
const streams = [];
|
|
10968
11013
|
while (true) {
|
|
10969
11014
|
const streamType = iterator.getBits(8);
|
|
@@ -10973,7 +11018,6 @@ var parsePmtTable = ({
|
|
|
10973
11018
|
const esInfoLength = iterator.getBits(12);
|
|
10974
11019
|
iterator.getBits(esInfoLength * 8);
|
|
10975
11020
|
streams.push({ streamType, pid: elementaryPid });
|
|
10976
|
-
iterator.getBits(programInfoLength * 8);
|
|
10977
11021
|
const remaining = sectionLength - (iterator.counter.getOffset() - start);
|
|
10978
11022
|
if (remaining <= 4) {
|
|
10979
11023
|
break;
|
|
@@ -11260,7 +11304,7 @@ var processStreamBuffer = async ({
|
|
|
11260
11304
|
if (!state.callbacks.tracks.hasAllTracks()) {
|
|
11261
11305
|
const tracksRegistered = state.callbacks.tracks.getTracks().length;
|
|
11262
11306
|
const { streams } = findProgramMapTableOrThrow(structure);
|
|
11263
|
-
if (streams.length === tracksRegistered) {
|
|
11307
|
+
if (filterStreamsBySupportedTypes(streams).length === tracksRegistered) {
|
|
11264
11308
|
state.callbacks.tracks.setIsDone(state.logLevel);
|
|
11265
11309
|
}
|
|
11266
11310
|
}
|
|
@@ -3066,14 +3066,17 @@ var getStreamForId = (structure, packetIdentifier) => {
|
|
|
3066
3066
|
};
|
|
3067
3067
|
|
|
3068
3068
|
// src/containers/transport-stream/get-tracks.ts
|
|
3069
|
+
var filterStreamsBySupportedTypes = (streams) => {
|
|
3070
|
+
return streams.filter((stream) => stream.streamType === 27 || stream.streamType === 15);
|
|
3071
|
+
};
|
|
3069
3072
|
var getTracksFromTransportStream = (parserState) => {
|
|
3070
3073
|
const structure = parserState.getTsStructure();
|
|
3071
3074
|
const programMapTable = findProgramMapTableOrThrow(structure);
|
|
3072
3075
|
const parserTracks = parserState.callbacks.tracks.getTracks();
|
|
3073
|
-
const mapped = programMapTable.streams.map((stream) => {
|
|
3076
|
+
const mapped = filterStreamsBySupportedTypes(programMapTable.streams).map((stream) => {
|
|
3074
3077
|
return parserTracks.find((track) => track.trackId === stream.pid);
|
|
3075
3078
|
}).filter(truthy);
|
|
3076
|
-
if (mapped.length !== programMapTable.streams.length) {
|
|
3079
|
+
if (mapped.length !== filterStreamsBySupportedTypes(programMapTable.streams).length) {
|
|
3077
3080
|
throw new Error("Not all tracks found");
|
|
3078
3081
|
}
|
|
3079
3082
|
return {
|
|
@@ -6451,6 +6454,12 @@ var sampleSorter = ({
|
|
|
6451
6454
|
addAudioStreamToConsider: (src, callback) => {
|
|
6452
6455
|
audioCallbacks[src] = callback;
|
|
6453
6456
|
},
|
|
6457
|
+
hasAudioStreamToConsider: (src) => {
|
|
6458
|
+
return Boolean(audioCallbacks[src]);
|
|
6459
|
+
},
|
|
6460
|
+
hasVideoStreamToConsider: (src) => {
|
|
6461
|
+
return Boolean(videoCallbacks[src]);
|
|
6462
|
+
},
|
|
6454
6463
|
addAudioSample: async (src, sample) => {
|
|
6455
6464
|
const callback = audioCallbacks[src];
|
|
6456
6465
|
if (!callback) {
|
|
@@ -6462,13 +6471,16 @@ var sampleSorter = ({
|
|
|
6462
6471
|
addVideoSample: async (src, sample) => {
|
|
6463
6472
|
const callback = videoCallbacks[src];
|
|
6464
6473
|
if (!callback) {
|
|
6465
|
-
throw new Error("No callback found for
|
|
6474
|
+
throw new Error("No callback found for video sample.");
|
|
6466
6475
|
}
|
|
6467
6476
|
latestSample[src] = sample.dts;
|
|
6468
6477
|
await callback(sample);
|
|
6469
6478
|
},
|
|
6470
6479
|
getNextStreamToRun: (streams) => {
|
|
6471
6480
|
for (const stream of streams) {
|
|
6481
|
+
if (getAllChunksProcessedForPlaylist(stream)) {
|
|
6482
|
+
continue;
|
|
6483
|
+
}
|
|
6472
6484
|
if (!streamsWithTracks.includes(stream)) {
|
|
6473
6485
|
Log.trace(logLevel, `Did not yet detect track of ${stream}, working on that`);
|
|
6474
6486
|
return stream;
|
|
@@ -6484,6 +6496,9 @@ var sampleSorter = ({
|
|
|
6484
6496
|
}
|
|
6485
6497
|
}
|
|
6486
6498
|
for (const stream of streams) {
|
|
6499
|
+
if (getAllChunksProcessedForPlaylist(stream)) {
|
|
6500
|
+
continue;
|
|
6501
|
+
}
|
|
6487
6502
|
if ((latestSample[stream] ?? 0) === smallestDts) {
|
|
6488
6503
|
Log.trace(logLevel, `Working on ${stream} because it has the smallest DTS`);
|
|
6489
6504
|
return stream;
|
|
@@ -6555,7 +6570,7 @@ var m3uState = (logLevel) => {
|
|
|
6555
6570
|
setHasEmittedDoneWithTracks: (src) => {
|
|
6556
6571
|
hasEmittedDoneWithTracks[src] = true;
|
|
6557
6572
|
},
|
|
6558
|
-
hasEmittedDoneWithTracks: (src) => hasEmittedDoneWithTracks[src],
|
|
6573
|
+
hasEmittedDoneWithTracks: (src) => hasEmittedDoneWithTracks[src] !== undefined,
|
|
6559
6574
|
setReadyToIterateOverM3u: () => {
|
|
6560
6575
|
readyToIterateOverM3u = true;
|
|
6561
6576
|
},
|
|
@@ -6587,6 +6602,9 @@ var m3uState = (logLevel) => {
|
|
|
6587
6602
|
const selectedPlaylists = getSelectedPlaylists();
|
|
6588
6603
|
return selectedPlaylists.every((url) => tracksDone[url]);
|
|
6589
6604
|
},
|
|
6605
|
+
getTrackDone: (playlistUrl) => {
|
|
6606
|
+
return tracksDone[playlistUrl];
|
|
6607
|
+
},
|
|
6590
6608
|
getM3uStreamRun: (playlistUrl) => m3uStreamRuns[playlistUrl] ?? null,
|
|
6591
6609
|
abortM3UStreamRuns: () => {
|
|
6592
6610
|
const values = Object.values(m3uStreamRuns);
|
|
@@ -6693,7 +6711,7 @@ var makeCanSkipTracksState = ({
|
|
|
6693
6711
|
};
|
|
6694
6712
|
|
|
6695
6713
|
// src/state/has-tracks-section.ts
|
|
6696
|
-
var makeTracksSectionState = (canSkipTracksState) => {
|
|
6714
|
+
var makeTracksSectionState = (canSkipTracksState, src) => {
|
|
6697
6715
|
const tracks2 = [];
|
|
6698
6716
|
let doneWithTracks = false;
|
|
6699
6717
|
return {
|
|
@@ -6718,7 +6736,7 @@ var makeTracksSectionState = (canSkipTracksState) => {
|
|
|
6718
6736
|
return;
|
|
6719
6737
|
}
|
|
6720
6738
|
if (!doneWithTracks) {
|
|
6721
|
-
throw new Error("Error in Media Parser: End of parsing has been reached, but no tracks have been found");
|
|
6739
|
+
throw new Error("Error in Media Parser: End of parsing of " + src + " has been reached, but no tracks have been found ");
|
|
6722
6740
|
}
|
|
6723
6741
|
}
|
|
6724
6742
|
};
|
|
@@ -6733,7 +6751,8 @@ var sampleCallback = ({
|
|
|
6733
6751
|
keyframes,
|
|
6734
6752
|
emittedFields,
|
|
6735
6753
|
slowDurationAndFpsState,
|
|
6736
|
-
structure
|
|
6754
|
+
structure,
|
|
6755
|
+
src
|
|
6737
6756
|
}) => {
|
|
6738
6757
|
const videoSampleCallbacks = {};
|
|
6739
6758
|
const audioSampleCallbacks = {};
|
|
@@ -6745,7 +6764,7 @@ var sampleCallback = ({
|
|
|
6745
6764
|
hasVideoTrackHandlers,
|
|
6746
6765
|
structure
|
|
6747
6766
|
});
|
|
6748
|
-
const tracksState = makeTracksSectionState(canSkipTracksState);
|
|
6767
|
+
const tracksState = makeTracksSectionState(canSkipTracksState, src);
|
|
6749
6768
|
const samplesForTrack = {};
|
|
6750
6769
|
return {
|
|
6751
6770
|
registerVideoSampleCallback: async (id, callback) => {
|
|
@@ -7194,7 +7213,8 @@ var makeParserState = ({
|
|
|
7194
7213
|
keyframes,
|
|
7195
7214
|
emittedFields,
|
|
7196
7215
|
slowDurationAndFpsState: slowDurationAndFps,
|
|
7197
|
-
structure
|
|
7216
|
+
structure,
|
|
7217
|
+
src
|
|
7198
7218
|
}),
|
|
7199
7219
|
getInternalStats: () => ({
|
|
7200
7220
|
skippedBytes,
|
|
@@ -9177,6 +9197,20 @@ var parseM3uDirective = (str) => {
|
|
|
9177
9197
|
const res = parseStreamInf(value);
|
|
9178
9198
|
return res;
|
|
9179
9199
|
}
|
|
9200
|
+
if (directive === "#EXT-X-I-FRAME-STREAM-INF") {
|
|
9201
|
+
return {
|
|
9202
|
+
type: "m3u-i-frame-stream-info"
|
|
9203
|
+
};
|
|
9204
|
+
}
|
|
9205
|
+
if (directive === "#EXT-X-ALLOW-CACHE") {
|
|
9206
|
+
if (!value) {
|
|
9207
|
+
throw new Error("#EXT-X-ALLOW-CACHE directive must have a value");
|
|
9208
|
+
}
|
|
9209
|
+
return {
|
|
9210
|
+
type: "m3u-allow-cache",
|
|
9211
|
+
allowsCache: value === "YES"
|
|
9212
|
+
};
|
|
9213
|
+
}
|
|
9180
9214
|
if (directive === "#EXT-X-MAP") {
|
|
9181
9215
|
if (!value) {
|
|
9182
9216
|
throw new Error("#EXT-X-MAP directive must have a value");
|
|
@@ -9461,7 +9495,7 @@ var iteratorOverSegmentFiles = async ({
|
|
|
9461
9495
|
return null;
|
|
9462
9496
|
}
|
|
9463
9497
|
},
|
|
9464
|
-
onAudioTrack: async ({ track }) => {
|
|
9498
|
+
onAudioTrack: onAudioTrack === null ? null : async ({ track }) => {
|
|
9465
9499
|
const callbackOrFalse = m3uState2.hasEmittedAudioTrack(playlistUrl);
|
|
9466
9500
|
if (callbackOrFalse === false) {
|
|
9467
9501
|
const callback = await onAudioTrack(track);
|
|
@@ -9476,7 +9510,7 @@ var iteratorOverSegmentFiles = async ({
|
|
|
9476
9510
|
}
|
|
9477
9511
|
return callbackOrFalse;
|
|
9478
9512
|
},
|
|
9479
|
-
onVideoTrack: async ({ track }) => {
|
|
9513
|
+
onVideoTrack: onVideoTrack === null ? null : async ({ track }) => {
|
|
9480
9514
|
const callbackOrFalse = m3uState2.hasEmittedVideoTrack(playlistUrl);
|
|
9481
9515
|
if (callbackOrFalse === false) {
|
|
9482
9516
|
const callback = await onVideoTrack(track);
|
|
@@ -9520,6 +9554,16 @@ var runOverM3u = async ({
|
|
|
9520
9554
|
playlistUrl,
|
|
9521
9555
|
logLevel
|
|
9522
9556
|
}) => {
|
|
9557
|
+
const tracksDone = state.m3u.getTrackDone(playlistUrl);
|
|
9558
|
+
const hasAudioStreamToConsider = state.m3u.sampleSorter.hasAudioStreamToConsider(playlistUrl);
|
|
9559
|
+
const hasVideoStreamToConsider = state.m3u.sampleSorter.hasVideoStreamToConsider(playlistUrl);
|
|
9560
|
+
const audioDone = !hasAudioStreamToConsider && tracksDone;
|
|
9561
|
+
const videoDone = !hasVideoStreamToConsider && tracksDone;
|
|
9562
|
+
const bothDone = audioDone && videoDone;
|
|
9563
|
+
if (bothDone) {
|
|
9564
|
+
state.m3u.setAllChunksProcessed(playlistUrl);
|
|
9565
|
+
return;
|
|
9566
|
+
}
|
|
9523
9567
|
const existingRun = state.m3u.getM3uStreamRun(playlistUrl);
|
|
9524
9568
|
if (existingRun) {
|
|
9525
9569
|
Log.trace(logLevel, "Existing M3U parsing process found for", playlistUrl);
|
|
@@ -9546,7 +9590,7 @@ var runOverM3u = async ({
|
|
|
9546
9590
|
state.callbacks.tracks.setIsDone(state.logLevel);
|
|
9547
9591
|
}
|
|
9548
9592
|
},
|
|
9549
|
-
onAudioTrack: async (track) => {
|
|
9593
|
+
onAudioTrack: audioDone ? null : async (track) => {
|
|
9550
9594
|
const existingTracks = state.callbacks.tracks.getTracks();
|
|
9551
9595
|
let { trackId } = track;
|
|
9552
9596
|
while (existingTracks.find((t) => t.trackId === trackId)) {
|
|
@@ -9569,7 +9613,7 @@ var runOverM3u = async ({
|
|
|
9569
9613
|
await state.m3u.sampleSorter.addAudioSample(playlistUrl, sample);
|
|
9570
9614
|
};
|
|
9571
9615
|
},
|
|
9572
|
-
onVideoTrack: async (track) => {
|
|
9616
|
+
onVideoTrack: videoDone ? null : async (track) => {
|
|
9573
9617
|
const existingTracks = state.callbacks.tracks.getTracks();
|
|
9574
9618
|
let { trackId } = track;
|
|
9575
9619
|
while (existingTracks.find((t) => t.trackId === trackId)) {
|
|
@@ -10872,11 +10916,12 @@ var parsePmtTable = ({
|
|
|
10872
10916
|
const sectionNumber = iterator.getBits(8);
|
|
10873
10917
|
const lastSectionNumber = iterator.getBits(8);
|
|
10874
10918
|
const tables = [];
|
|
10919
|
+
iterator.getBits(3);
|
|
10920
|
+
iterator.getBits(13);
|
|
10921
|
+
iterator.getBits(4);
|
|
10922
|
+
const programInfoLength = iterator.getBits(12);
|
|
10923
|
+
iterator.getBits(programInfoLength * 8);
|
|
10875
10924
|
for (let i = sectionNumber;i <= lastSectionNumber; i++) {
|
|
10876
|
-
iterator.getBits(3);
|
|
10877
|
-
iterator.getBits(13);
|
|
10878
|
-
iterator.getBits(4);
|
|
10879
|
-
const programInfoLength = iterator.getBits(12);
|
|
10880
10925
|
const streams = [];
|
|
10881
10926
|
while (true) {
|
|
10882
10927
|
const streamType = iterator.getBits(8);
|
|
@@ -10886,7 +10931,6 @@ var parsePmtTable = ({
|
|
|
10886
10931
|
const esInfoLength = iterator.getBits(12);
|
|
10887
10932
|
iterator.getBits(esInfoLength * 8);
|
|
10888
10933
|
streams.push({ streamType, pid: elementaryPid });
|
|
10889
|
-
iterator.getBits(programInfoLength * 8);
|
|
10890
10934
|
const remaining = sectionLength - (iterator.counter.getOffset() - start);
|
|
10891
10935
|
if (remaining <= 4) {
|
|
10892
10936
|
break;
|
|
@@ -11173,7 +11217,7 @@ var processStreamBuffer = async ({
|
|
|
11173
11217
|
if (!state.callbacks.tracks.hasAllTracks()) {
|
|
11174
11218
|
const tracksRegistered = state.callbacks.tracks.getTracks().length;
|
|
11175
11219
|
const { streams } = findProgramMapTableOrThrow(structure);
|
|
11176
|
-
if (streams.length === tracksRegistered) {
|
|
11220
|
+
if (filterStreamsBySupportedTypes(streams).length === tracksRegistered) {
|
|
11177
11221
|
state.callbacks.tracks.setIsDone(state.logLevel);
|
|
11178
11222
|
}
|
|
11179
11223
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -940,6 +940,7 @@ export declare const MediaParserInternals: {
|
|
|
940
940
|
hasFinishedManifest: () => boolean;
|
|
941
941
|
setM3uStreamRun: (playlistUrl: string, run: import("./state/m3u-state").ExistingM3uRun | null) => void;
|
|
942
942
|
setTracksDone: (playlistUrl: string) => boolean;
|
|
943
|
+
getTrackDone: (playlistUrl: string) => boolean;
|
|
943
944
|
getM3uStreamRun: (playlistUrl: string) => import("./state/m3u-state").ExistingM3uRun;
|
|
944
945
|
abortM3UStreamRuns: () => void;
|
|
945
946
|
setAssociatedPlaylists: (playlists: import("./containers/m3u/get-streams").M3uAssociatedPlaylist[]) => void;
|
|
@@ -949,6 +950,8 @@ export declare const MediaParserInternals: {
|
|
|
949
950
|
addToStreamWithTrack: (src: string) => void;
|
|
950
951
|
addVideoStreamToConsider: (src: string, callback: import("./webcodec-sample-types").OnVideoSample) => void;
|
|
951
952
|
addAudioStreamToConsider: (src: string, callback: import("./webcodec-sample-types").OnAudioSample) => void;
|
|
953
|
+
hasAudioStreamToConsider: (src: string) => boolean;
|
|
954
|
+
hasVideoStreamToConsider: (src: string) => boolean;
|
|
952
955
|
addAudioSample: (src: string, sample: import("./webcodec-sample-types").AudioOrVideoSample) => Promise<void>;
|
|
953
956
|
addVideoSample: (src: string, sample: import("./webcodec-sample-types").AudioOrVideoSample) => Promise<void>;
|
|
954
957
|
getNextStreamToRun: (streams: string[]) => string;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { Track } from '../get-tracks';
|
|
2
2
|
import type { LogLevel } from '../log';
|
|
3
|
-
import type { Options, ParseMediaFields } from '../options';
|
|
3
|
+
import type { Options, ParseMediaFields, ParseMediaSrc } from '../options';
|
|
4
4
|
import type { CanSkipTracksState } from './can-skip-tracks';
|
|
5
|
-
export declare const makeTracksSectionState: (canSkipTracksState: CanSkipTracksState) => {
|
|
5
|
+
export declare const makeTracksSectionState: (canSkipTracksState: CanSkipTracksState, src: ParseMediaSrc) => {
|
|
6
6
|
hasAllTracks: () => boolean;
|
|
7
7
|
getIsDone: () => boolean;
|
|
8
8
|
setIsDone: (logLevel: LogLevel) => void;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Log } from '../log';
|
|
2
|
-
export const makeTracksSectionState = (canSkipTracksState) => {
|
|
2
|
+
export const makeTracksSectionState = (canSkipTracksState, src) => {
|
|
3
3
|
const tracks = [];
|
|
4
4
|
let doneWithTracks = false;
|
|
5
5
|
return {
|
|
@@ -24,7 +24,9 @@ export const makeTracksSectionState = (canSkipTracksState) => {
|
|
|
24
24
|
return;
|
|
25
25
|
}
|
|
26
26
|
if (!doneWithTracks) {
|
|
27
|
-
throw new Error('Error in Media Parser: End of parsing
|
|
27
|
+
throw new Error('Error in Media Parser: End of parsing of ' +
|
|
28
|
+
src +
|
|
29
|
+
' has been reached, but no tracks have been found ');
|
|
28
30
|
}
|
|
29
31
|
},
|
|
30
32
|
};
|
|
@@ -31,6 +31,7 @@ export declare const m3uState: (logLevel: LogLevel) => {
|
|
|
31
31
|
hasFinishedManifest: () => boolean;
|
|
32
32
|
setM3uStreamRun: (playlistUrl: string, run: ExistingM3uRun | null) => void;
|
|
33
33
|
setTracksDone: (playlistUrl: string) => boolean;
|
|
34
|
+
getTrackDone: (playlistUrl: string) => boolean;
|
|
34
35
|
getM3uStreamRun: (playlistUrl: string) => ExistingM3uRun;
|
|
35
36
|
abortM3UStreamRuns: () => void;
|
|
36
37
|
setAssociatedPlaylists: (playlists: M3uAssociatedPlaylist[]) => void;
|
|
@@ -40,6 +41,8 @@ export declare const m3uState: (logLevel: LogLevel) => {
|
|
|
40
41
|
addToStreamWithTrack: (src: string) => void;
|
|
41
42
|
addVideoStreamToConsider: (src: string, callback: OnVideoSample) => void;
|
|
42
43
|
addAudioStreamToConsider: (src: string, callback: OnAudioSample) => void;
|
|
44
|
+
hasAudioStreamToConsider: (src: string) => boolean;
|
|
45
|
+
hasVideoStreamToConsider: (src: string) => boolean;
|
|
43
46
|
addAudioSample: (src: string, sample: import("../webcodec-sample-types").AudioOrVideoSample) => Promise<void>;
|
|
44
47
|
addVideoSample: (src: string, sample: import("../webcodec-sample-types").AudioOrVideoSample) => Promise<void>;
|
|
45
48
|
getNextStreamToRun: (streams: string[]) => string;
|
package/dist/state/m3u-state.js
CHANGED
|
@@ -62,7 +62,7 @@ export const m3uState = (logLevel) => {
|
|
|
62
62
|
setHasEmittedDoneWithTracks: (src) => {
|
|
63
63
|
hasEmittedDoneWithTracks[src] = true;
|
|
64
64
|
},
|
|
65
|
-
hasEmittedDoneWithTracks: (src) => hasEmittedDoneWithTracks[src],
|
|
65
|
+
hasEmittedDoneWithTracks: (src) => hasEmittedDoneWithTracks[src] !== undefined,
|
|
66
66
|
setReadyToIterateOverM3u: () => {
|
|
67
67
|
readyToIterateOverM3u = true;
|
|
68
68
|
},
|
|
@@ -94,6 +94,9 @@ export const m3uState = (logLevel) => {
|
|
|
94
94
|
const selectedPlaylists = getSelectedPlaylists();
|
|
95
95
|
return selectedPlaylists.every((url) => tracksDone[url]);
|
|
96
96
|
},
|
|
97
|
+
getTrackDone: (playlistUrl) => {
|
|
98
|
+
return tracksDone[playlistUrl];
|
|
99
|
+
},
|
|
97
100
|
getM3uStreamRun: (playlistUrl) => { var _a; return (_a = m3uStreamRuns[playlistUrl]) !== null && _a !== void 0 ? _a : null; },
|
|
98
101
|
abortM3UStreamRuns: () => {
|
|
99
102
|
const values = Object.values(m3uStreamRuns);
|
|
@@ -226,6 +226,7 @@ export declare const makeParserState: ({ hasAudioTrackHandlers, hasVideoTrackHan
|
|
|
226
226
|
hasFinishedManifest: () => boolean;
|
|
227
227
|
setM3uStreamRun: (playlistUrl: string, run: import("./m3u-state").ExistingM3uRun | null) => void;
|
|
228
228
|
setTracksDone: (playlistUrl: string) => boolean;
|
|
229
|
+
getTrackDone: (playlistUrl: string) => boolean;
|
|
229
230
|
getM3uStreamRun: (playlistUrl: string) => import("./m3u-state").ExistingM3uRun;
|
|
230
231
|
abortM3UStreamRuns: () => void;
|
|
231
232
|
setAssociatedPlaylists: (playlists: import("..").M3uAssociatedPlaylist[]) => void;
|
|
@@ -235,6 +236,8 @@ export declare const makeParserState: ({ hasAudioTrackHandlers, hasVideoTrackHan
|
|
|
235
236
|
addToStreamWithTrack: (src: string) => void;
|
|
236
237
|
addVideoStreamToConsider: (src: string, callback: import("../webcodec-sample-types").OnVideoSample) => void;
|
|
237
238
|
addAudioStreamToConsider: (src: string, callback: import("../webcodec-sample-types").OnAudioSample) => void;
|
|
239
|
+
hasAudioStreamToConsider: (src: string) => boolean;
|
|
240
|
+
hasVideoStreamToConsider: (src: string) => boolean;
|
|
238
241
|
addAudioSample: (src: string, sample: import("../webcodec-sample-types").AudioOrVideoSample) => Promise<void>;
|
|
239
242
|
addVideoSample: (src: string, sample: import("../webcodec-sample-types").AudioOrVideoSample) => Promise<void>;
|
|
240
243
|
getNextStreamToRun: (streams: string[]) => string;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { MediaParserController } from '../media-parser-controller';
|
|
2
|
-
import type { AllOptions, Options, ParseMediaFields } from '../options';
|
|
2
|
+
import type { AllOptions, Options, ParseMediaFields, ParseMediaSrc } from '../options';
|
|
3
3
|
import type { AudioOrVideoSample, OnAudioSample, OnVideoSample } from '../webcodec-sample-types';
|
|
4
4
|
import { type KeyframesState } from './keyframes';
|
|
5
5
|
import type { SlowDurationAndFpsState } from './slow-duration-fps';
|
|
6
6
|
import type { StructureState } from './structure';
|
|
7
|
-
export declare const sampleCallback: ({ controller, hasAudioTrackHandlers, hasVideoTrackHandlers, fields, keyframes, emittedFields, slowDurationAndFpsState, structure, }: {
|
|
7
|
+
export declare const sampleCallback: ({ controller, hasAudioTrackHandlers, hasVideoTrackHandlers, fields, keyframes, emittedFields, slowDurationAndFpsState, structure, src, }: {
|
|
8
8
|
controller: MediaParserController;
|
|
9
9
|
hasAudioTrackHandlers: boolean;
|
|
10
10
|
hasVideoTrackHandlers: boolean;
|
|
@@ -13,6 +13,7 @@ export declare const sampleCallback: ({ controller, hasAudioTrackHandlers, hasVi
|
|
|
13
13
|
emittedFields: AllOptions<ParseMediaFields>;
|
|
14
14
|
slowDurationAndFpsState: SlowDurationAndFpsState;
|
|
15
15
|
structure: StructureState;
|
|
16
|
+
src: ParseMediaSrc;
|
|
16
17
|
}) => {
|
|
17
18
|
registerVideoSampleCallback: (id: number, callback: OnVideoSample | null) => Promise<void>;
|
|
18
19
|
onAudioSample: (trackId: number, audioSample: AudioOrVideoSample) => Promise<void>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { makeCanSkipTracksState } from './can-skip-tracks';
|
|
2
2
|
import { makeTracksSectionState } from './has-tracks-section';
|
|
3
3
|
import { needsToIterateOverSamples } from './need-samples-for-fields';
|
|
4
|
-
export const sampleCallback = ({ controller, hasAudioTrackHandlers, hasVideoTrackHandlers, fields, keyframes, emittedFields, slowDurationAndFpsState, structure, }) => {
|
|
4
|
+
export const sampleCallback = ({ controller, hasAudioTrackHandlers, hasVideoTrackHandlers, fields, keyframes, emittedFields, slowDurationAndFpsState, structure, src, }) => {
|
|
5
5
|
const videoSampleCallbacks = {};
|
|
6
6
|
const audioSampleCallbacks = {};
|
|
7
7
|
const queuedAudioSamples = {};
|
|
@@ -12,7 +12,7 @@ export const sampleCallback = ({ controller, hasAudioTrackHandlers, hasVideoTrac
|
|
|
12
12
|
hasVideoTrackHandlers,
|
|
13
13
|
structure,
|
|
14
14
|
});
|
|
15
|
-
const tracksState = makeTracksSectionState(canSkipTracksState);
|
|
15
|
+
const tracksState = makeTracksSectionState(canSkipTracksState, src);
|
|
16
16
|
const samplesForTrack = {};
|
|
17
17
|
return {
|
|
18
18
|
registerVideoSampleCallback: async (id, callback) => {
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VERSION = "4.0.
|
|
1
|
+
export declare const VERSION = "4.0.272";
|
package/dist/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Automatically generated on publish
|
|
2
|
-
export const VERSION = '4.0.
|
|
2
|
+
export const VERSION = '4.0.272';
|
package/package.json
CHANGED
|
@@ -3,15 +3,15 @@
|
|
|
3
3
|
"url": "https://github.com/remotion-dev/remotion/tree/main/packages/media-parser"
|
|
4
4
|
},
|
|
5
5
|
"name": "@remotion/media-parser",
|
|
6
|
-
"version": "4.0.
|
|
6
|
+
"version": "4.0.272",
|
|
7
7
|
"main": "dist/index.js",
|
|
8
8
|
"sideEffects": false,
|
|
9
9
|
"devDependencies": {
|
|
10
10
|
"@types/wicg-file-system-access": "2023.10.5",
|
|
11
11
|
"eslint": "9.19.0",
|
|
12
12
|
"@types/bun": "1.2.0",
|
|
13
|
-
"@remotion/example-videos": "4.0.
|
|
14
|
-
"@remotion/eslint-config-internal": "4.0.
|
|
13
|
+
"@remotion/example-videos": "4.0.272",
|
|
14
|
+
"@remotion/eslint-config-internal": "4.0.272"
|
|
15
15
|
},
|
|
16
16
|
"publishConfig": {
|
|
17
17
|
"access": "public"
|