@remotion/media-parser 4.0.282 → 4.0.284
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/m3u/iterate-over-segment-files.js +2 -1
- package/dist/containers/transport-stream/process-audio.d.ts +21 -0
- package/dist/containers/transport-stream/process-audio.js +54 -0
- package/dist/containers/transport-stream/process-sample-if-possible.d.ts +2 -0
- package/dist/containers/transport-stream/process-sample-if-possible.js +62 -0
- package/dist/containers/transport-stream/process-video.d.ts +20 -0
- package/dist/containers/transport-stream/process-video.js +39 -0
- package/dist/containers/transport-stream/start-offset.d.ts +4 -0
- package/dist/containers/transport-stream/start-offset.js +13 -0
- package/dist/controller/emitter.js +2 -1
- package/dist/esm/index.mjs +16 -4
- package/dist/esm/server-worker.mjs +12 -1
- package/dist/esm/worker-server-entry.mjs +16 -4
- package/dist/esm/worker-web-entry.mjs +16 -4
- package/dist/esm/worker.mjs +12 -1
- package/dist/index.d.ts +1 -0
- package/dist/parse-media-on-worker-entry.js +3 -6
- package/dist/readers/state/aac-state.d.ts +13 -0
- package/dist/readers/state/aac-state.js +17 -0
- package/dist/readers/state/can-skip-tracks.d.ts +16 -0
- package/dist/readers/state/can-skip-tracks.js +60 -0
- package/dist/readers/state/current-reader.d.ts +6 -0
- package/dist/readers/state/current-reader.js +13 -0
- package/dist/readers/state/emitted-fields.d.ts +1 -0
- package/dist/readers/state/emitted-fields.js +37 -0
- package/dist/readers/state/flac-state.d.ts +4 -0
- package/dist/readers/state/flac-state.js +13 -0
- package/dist/readers/state/has-tracks-section.d.ts +14 -0
- package/dist/readers/state/has-tracks-section.js +37 -0
- package/dist/readers/state/images.d.ts +9 -0
- package/dist/readers/state/images.js +14 -0
- package/dist/readers/state/iso-base-media/cached-sample-positions.d.ts +12 -0
- package/dist/readers/state/iso-base-media/cached-sample-positions.js +46 -0
- package/dist/readers/state/iso-base-media/iso-state.d.ts +24 -0
- package/dist/readers/state/iso-base-media/iso-state.js +20 -0
- package/dist/readers/state/iso-base-media/lazy-mfra-load.d.ts +13 -0
- package/dist/readers/state/iso-base-media/lazy-mfra-load.js +29 -0
- package/dist/readers/state/iso-base-media/moov-box.d.ts +5 -0
- package/dist/readers/state/iso-base-media/moov-box.js +13 -0
- package/dist/readers/state/keyframes.d.ts +6 -0
- package/dist/readers/state/keyframes.js +15 -0
- package/dist/readers/state/m3u-state.d.ts +44 -0
- package/dist/readers/state/m3u-state.js +124 -0
- package/dist/readers/state/may-skip-video-data.d.ts +4 -0
- package/dist/readers/state/may-skip-video-data.js +18 -0
- package/dist/readers/state/mp3.d.ts +15 -0
- package/dist/readers/state/mp3.js +19 -0
- package/dist/readers/state/need-samples-for-fields.d.ts +6 -0
- package/dist/readers/state/need-samples-for-fields.js +39 -0
- package/dist/readers/state/parser-state.d.ts +252 -0
- package/dist/readers/state/parser-state.js +124 -0
- package/dist/readers/state/riff.d.ts +10 -0
- package/dist/readers/state/riff.js +32 -0
- package/dist/readers/state/sample-callbacks.d.ts +44 -0
- package/dist/readers/state/sample-callbacks.js +118 -0
- package/dist/readers/state/seek-infinite-loop.d.ts +5 -0
- package/dist/readers/state/seek-infinite-loop.js +22 -0
- package/dist/readers/state/slow-duration-fps.d.ts +11 -0
- package/dist/readers/state/slow-duration-fps.js +86 -0
- package/dist/readers/state/structure.d.ts +15 -0
- package/dist/readers/state/structure.js +78 -0
- package/dist/readers/state/timings.d.ts +8 -0
- package/dist/readers/state/timings.js +13 -0
- package/dist/readers/state/transport-stream/last-emitted-sample.d.ts +6 -0
- package/dist/readers/state/transport-stream/last-emitted-sample.js +16 -0
- package/dist/readers/state/transport-stream/next-pes-header-store.d.ts +6 -0
- package/dist/readers/state/transport-stream/next-pes-header-store.js +18 -0
- package/dist/readers/state/transport-stream/start-offset.d.ts +4 -0
- package/dist/readers/state/transport-stream/start-offset.js +13 -0
- package/dist/readers/state/transport-stream/transport-stream.d.ts +19 -0
- package/dist/readers/state/transport-stream/transport-stream.js +25 -0
- package/dist/readers/state/video-section.d.ts +33 -0
- package/dist/readers/state/video-section.js +65 -0
- package/dist/readers/state/webm.d.ts +28 -0
- package/dist/readers/state/webm.js +109 -0
- package/dist/state/iso-base-media/cached-sample-positions.d.ts +1 -1
- package/dist/state/parser-state.d.ts +1 -0
- package/dist/state/transport-stream/last-emitted-sample.d.ts +6 -0
- package/dist/state/transport-stream/last-emitted-sample.js +16 -0
- package/dist/state/transport-stream/next-pes-header-store.d.ts +6 -0
- package/dist/state/transport-stream/next-pes-header-store.js +18 -0
- package/dist/state/transport-stream/start-offset.d.ts +4 -0
- package/dist/state/transport-stream/start-offset.js +13 -0
- package/dist/state/transport-stream/transport-stream.d.ts +19 -0
- package/dist/state/transport-stream/transport-stream.js +24 -0
- package/dist/state/uml.d.ts +32 -0
- package/dist/state/uml.js +52 -0
- package/dist/state/video-section.d.ts +1 -0
- package/dist/state/video-section.js +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/with-resolvers.d.ts +5 -0
- package/dist/with-resolvers.js +13 -0
- package/dist/worker-server.js +2 -1
- package/dist/worker.js +1 -5
- package/package.json +3 -3
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
import type { AvcPPs, AvcProfileInfo } from '../containers/avc/parse-avc';
|
|
2
|
+
import type { SelectM3uAssociatedPlaylistsFn, SelectM3uStreamFn } from '../containers/m3u/select-stream';
|
|
3
|
+
import type { MediaParserController } from '../controller/media-parser-controller';
|
|
4
|
+
import type { Options, ParseMediaFields } from '../fields';
|
|
5
|
+
import { type LogLevel } from '../log';
|
|
6
|
+
import type { OnDiscardedData, ParseMediaCallbacks, ParseMediaMode, ParseMediaSrc } from '../options';
|
|
7
|
+
import type { IsoBaseMediaStructure } from '../parse-result';
|
|
8
|
+
import type { Reader, ReaderInterface } from '../readers/reader';
|
|
9
|
+
import type { OnAudioTrack, OnVideoTrack } from '../webcodec-sample-types';
|
|
10
|
+
export type InternalStats = {
|
|
11
|
+
skippedBytes: number;
|
|
12
|
+
finalCursorOffset: number;
|
|
13
|
+
};
|
|
14
|
+
export type SpsAndPps = {
|
|
15
|
+
sps: AvcProfileInfo;
|
|
16
|
+
pps: AvcPPs;
|
|
17
|
+
};
|
|
18
|
+
export declare const makeParserState: ({ hasAudioTrackHandlers, hasVideoTrackHandlers, controller, onAudioTrack, onVideoTrack, contentLength, logLevel, mode, src, readerInterface, onDiscardedData, selectM3uStreamFn, selectM3uAssociatedPlaylistsFn, mp4HeaderSegment, contentType, name, callbacks, fieldsInReturnValue, mimeType, initialReaderInstance, }: {
|
|
19
|
+
hasAudioTrackHandlers: boolean;
|
|
20
|
+
hasVideoTrackHandlers: boolean;
|
|
21
|
+
controller: MediaParserController;
|
|
22
|
+
onAudioTrack: OnAudioTrack | null;
|
|
23
|
+
onVideoTrack: OnVideoTrack | null;
|
|
24
|
+
contentLength: number;
|
|
25
|
+
logLevel: LogLevel;
|
|
26
|
+
mode: ParseMediaMode;
|
|
27
|
+
src: ParseMediaSrc;
|
|
28
|
+
readerInterface: ReaderInterface;
|
|
29
|
+
onDiscardedData: OnDiscardedData | null;
|
|
30
|
+
selectM3uStreamFn: SelectM3uStreamFn;
|
|
31
|
+
selectM3uAssociatedPlaylistsFn: SelectM3uAssociatedPlaylistsFn;
|
|
32
|
+
mp4HeaderSegment: IsoBaseMediaStructure | null;
|
|
33
|
+
contentType: string | null;
|
|
34
|
+
name: string;
|
|
35
|
+
callbacks: ParseMediaCallbacks;
|
|
36
|
+
fieldsInReturnValue: Options<ParseMediaFields>;
|
|
37
|
+
mimeType: string | null;
|
|
38
|
+
initialReaderInstance: Reader;
|
|
39
|
+
}) => {
|
|
40
|
+
riff: {
|
|
41
|
+
getAvcProfile: () => SpsAndPps | null;
|
|
42
|
+
onProfile: (profile: SpsAndPps) => Promise<void>;
|
|
43
|
+
registerOnAvcProfileCallback: (callback: (profile: SpsAndPps) => Promise<void>) => void;
|
|
44
|
+
getNextTrackIndex: () => number;
|
|
45
|
+
incrementNextTrackIndex: () => void;
|
|
46
|
+
};
|
|
47
|
+
transportStream: {
|
|
48
|
+
nextPesHeaderStore: {
|
|
49
|
+
setNextPesHeader: (pesHeader: AvcPPs) => void;
|
|
50
|
+
getNextPesHeader: () => any;
|
|
51
|
+
};
|
|
52
|
+
streamBuffers: Map<number, TransportStreamPacketBuffer>;
|
|
53
|
+
startOffset: {
|
|
54
|
+
getOffset: () => number;
|
|
55
|
+
setOffset: (newOffset: number) => void;
|
|
56
|
+
};
|
|
57
|
+
resetBeforeSeek: () => void;
|
|
58
|
+
lastEmittedSample: {
|
|
59
|
+
setLastEmittedSample: (sample: AvcPPs) => void;
|
|
60
|
+
getLastEmittedSample: () => any;
|
|
61
|
+
resetLastEmittedSample: () => void;
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
webm: {
|
|
65
|
+
onTrackEntrySegment: OnTrackEntrySegment;
|
|
66
|
+
getTrackInfoByNumber: (id: number) => TrackInfo;
|
|
67
|
+
setTimestampOffset: (byteOffset: number, timestamp: number) => void;
|
|
68
|
+
getTimestampOffsetForByteOffset: (byteOffset: number) => number | undefined;
|
|
69
|
+
timescale: null;
|
|
70
|
+
getTimescale: () => number;
|
|
71
|
+
setTimescale: (newTimescale: number) => void;
|
|
72
|
+
addSegment: (seg: Omit<import("./webm").SegmentSection, "index">) => void;
|
|
73
|
+
addCluster: (cluster: import("./webm").ClusterSection) => void;
|
|
74
|
+
isInsideSegment: (iterator: AvcPPs) => import("./webm").SegmentSection | null;
|
|
75
|
+
isInsideCluster: (iterator: AvcPPs) => import("./webm").ClusterSection | null;
|
|
76
|
+
setAvcProfileForTrackNumber: (trackNumber: number, avcProfile: AvcPPs) => void;
|
|
77
|
+
getAvcProfileForTrackNumber: (trackNumber: number) => AvcPPs | null;
|
|
78
|
+
};
|
|
79
|
+
iso: {
|
|
80
|
+
flatSamples: {
|
|
81
|
+
getSamples: (mdatStart: number) => import("./iso-base-media/cached-sample-positions").FlatSample[] | null;
|
|
82
|
+
setSamples: (mdatStart: number, samples: import("./iso-base-media/cached-sample-positions").FlatSample[]) => void;
|
|
83
|
+
};
|
|
84
|
+
moov: {
|
|
85
|
+
setMoovBox: (moov: AvcPPs) => void;
|
|
86
|
+
getMoovBox: () => any;
|
|
87
|
+
};
|
|
88
|
+
mfra: {
|
|
89
|
+
triggerLoad: () => Promise<IsoBaseMediaBox[] | null> | null;
|
|
90
|
+
};
|
|
91
|
+
};
|
|
92
|
+
mp3Info: {
|
|
93
|
+
getMp3Info: () => import("./mp3").Mp3Info | null;
|
|
94
|
+
setMp3Info: (info: import("./mp3").Mp3Info) => void;
|
|
95
|
+
getCbrMp3Info: () => import("./mp3").Mp3CbrInfo | null;
|
|
96
|
+
setCbrMp3Info: (info: import("./mp3").Mp3CbrInfo) => void;
|
|
97
|
+
};
|
|
98
|
+
aac: {
|
|
99
|
+
addSample: ({ offset, size }: {
|
|
100
|
+
offset: number;
|
|
101
|
+
size: number;
|
|
102
|
+
}) => {
|
|
103
|
+
offset: number;
|
|
104
|
+
index: number;
|
|
105
|
+
size: number;
|
|
106
|
+
};
|
|
107
|
+
getSamples: () => {
|
|
108
|
+
offset: number;
|
|
109
|
+
index: number;
|
|
110
|
+
size: number;
|
|
111
|
+
}[];
|
|
112
|
+
};
|
|
113
|
+
flac: {
|
|
114
|
+
setBlockingBitStrategy: (strategy: number) => void;
|
|
115
|
+
getBlockingBitStrategy: () => number | undefined;
|
|
116
|
+
};
|
|
117
|
+
m3u: {
|
|
118
|
+
setSelectedMainPlaylist: (stream: import("./m3u-state").M3uStreamOrInitialUrl) => void;
|
|
119
|
+
getSelectedMainPlaylist: () => import("./m3u-state").M3uStreamOrInitialUrl | null;
|
|
120
|
+
setHasEmittedVideoTrack: (src: string, callback: AvcPPs | null) => void;
|
|
121
|
+
hasEmittedVideoTrack: (src: string) => any;
|
|
122
|
+
setHasEmittedAudioTrack: (src: string, callback: AvcPPs | null) => void;
|
|
123
|
+
hasEmittedAudioTrack: (src: string) => any;
|
|
124
|
+
setHasEmittedDoneWithTracks: (src: string) => void;
|
|
125
|
+
hasEmittedDoneWithTracks: (src: string) => boolean;
|
|
126
|
+
setReadyToIterateOverM3u: () => void;
|
|
127
|
+
isReadyToIterateOverM3u: () => boolean;
|
|
128
|
+
setAllChunksProcessed: (src: string) => void;
|
|
129
|
+
getAllChunksProcessedForPlaylist: (src: string) => boolean;
|
|
130
|
+
getAllChunksProcessedOverall: () => boolean;
|
|
131
|
+
setHasFinishedManifest: () => void;
|
|
132
|
+
hasFinishedManifest: () => boolean;
|
|
133
|
+
setM3uStreamRun: (playlistUrl: string, run: import("./m3u-state").ExistingM3uRun | null) => void;
|
|
134
|
+
setTracksDone: (playlistUrl: string) => boolean;
|
|
135
|
+
getTrackDone: (playlistUrl: string) => boolean;
|
|
136
|
+
getM3uStreamRun: (playlistUrl: string) => import("./m3u-state").ExistingM3uRun;
|
|
137
|
+
abortM3UStreamRuns: () => void;
|
|
138
|
+
setAssociatedPlaylists: (playlists: AvcPPs[]) => void;
|
|
139
|
+
getAssociatedPlaylists: () => M3uAssociatedPlaylist[] | null;
|
|
140
|
+
getSelectedPlaylists: () => any[];
|
|
141
|
+
sampleSorter: any;
|
|
142
|
+
setMp4HeaderSegment: (playlistUrl: string, structure: AvcPPs) => void;
|
|
143
|
+
getMp4HeaderSegment: (playlistUrl: string) => IsoBaseMediaStructure;
|
|
144
|
+
};
|
|
145
|
+
timings: {
|
|
146
|
+
timeIterating: number;
|
|
147
|
+
timeReadingData: number;
|
|
148
|
+
timeSeeking: number;
|
|
149
|
+
timeCheckingIfDone: number;
|
|
150
|
+
timeFreeingData: number;
|
|
151
|
+
};
|
|
152
|
+
callbacks: {
|
|
153
|
+
registerVideoSampleCallback: (id: number, callback: AvcPPs | null) => Promise<void>;
|
|
154
|
+
onAudioSample: (trackId: number, audioSample: AvcPPs) => Promise<void>;
|
|
155
|
+
getSamplesForTrack: (trackId: number) => number;
|
|
156
|
+
onVideoSample: (trackId: number, videoSample: AvcPPs) => Promise<void>;
|
|
157
|
+
canSkipTracksState: {
|
|
158
|
+
canSkipTracks: () => boolean;
|
|
159
|
+
};
|
|
160
|
+
registerAudioSampleCallback: (id: number, callback: AvcPPs | null) => Promise<void>;
|
|
161
|
+
tracks: {
|
|
162
|
+
hasAllTracks: () => boolean;
|
|
163
|
+
getIsDone: () => boolean;
|
|
164
|
+
setIsDone: (logLevel: AvcPPs) => void;
|
|
165
|
+
addTrack: (track: AvcPPs) => void;
|
|
166
|
+
getTracks: () => Track[];
|
|
167
|
+
ensureHasTracksAtEnd: (fields: AvcPPs<AvcPPs>) => void;
|
|
168
|
+
};
|
|
169
|
+
audioSampleCallbacks: Record<number, OnAudioSample>;
|
|
170
|
+
videoSampleCallbacks: Record<number, OnVideoSample>;
|
|
171
|
+
hasAudioTrackHandlers: boolean;
|
|
172
|
+
hasVideoTrackHandlers: boolean;
|
|
173
|
+
};
|
|
174
|
+
getInternalStats: () => InternalStats;
|
|
175
|
+
getSkipBytes: () => number;
|
|
176
|
+
increaseSkippedBytes: (bytes: number) => void;
|
|
177
|
+
keyframes: {
|
|
178
|
+
addKeyframe: (keyframe: AvcPPs) => void;
|
|
179
|
+
getKeyframes: () => AvcPPs[];
|
|
180
|
+
};
|
|
181
|
+
structure: {
|
|
182
|
+
getStructureOrNull: () => any;
|
|
183
|
+
getStructure: () => any;
|
|
184
|
+
setStructure: (value: AvcPPs) => void;
|
|
185
|
+
getFlacStructure: () => any;
|
|
186
|
+
getIsoStructure: () => any;
|
|
187
|
+
getMp3Structure: () => any;
|
|
188
|
+
getM3uStructure: () => any;
|
|
189
|
+
getRiffStructure: () => any;
|
|
190
|
+
getTsStructure: () => any;
|
|
191
|
+
getWavStructure: () => any;
|
|
192
|
+
getMatroskaStructure: () => any;
|
|
193
|
+
};
|
|
194
|
+
onAudioTrack: any;
|
|
195
|
+
onVideoTrack: any;
|
|
196
|
+
emittedFields: AllOptions<ParseMediaFields>;
|
|
197
|
+
fields: any;
|
|
198
|
+
slowDurationAndFps: {
|
|
199
|
+
addVideoSample: (videoSample: AvcPPs) => void;
|
|
200
|
+
addAudioSample: (audioSample: AvcPPs) => void;
|
|
201
|
+
getSlowDurationInSeconds: () => number;
|
|
202
|
+
getFps: () => number;
|
|
203
|
+
getSlowNumberOfFrames: () => number;
|
|
204
|
+
getAudioBitrate: () => number | null;
|
|
205
|
+
getVideoBitrate: () => number | null;
|
|
206
|
+
};
|
|
207
|
+
contentLength: number;
|
|
208
|
+
images: {
|
|
209
|
+
images: import("./images").MediaParserEmbeddedImage[];
|
|
210
|
+
addImage: (image: import("./images").MediaParserEmbeddedImage) => void;
|
|
211
|
+
};
|
|
212
|
+
mediaSection: {
|
|
213
|
+
addMediaSection: (section: import("./video-section").MediaSection) => void;
|
|
214
|
+
getMediaSections: () => import("./video-section").MediaSection[];
|
|
215
|
+
isCurrentByteInMediaSection: (iterator: AvcPPs) => "no-section-defined" | "in-section" | "outside-section";
|
|
216
|
+
isByteInMediaSection: ({ position, mediaSections, }: {
|
|
217
|
+
position: number;
|
|
218
|
+
mediaSections: import("./video-section").MediaSection[];
|
|
219
|
+
}) => "no-section-defined" | "in-section" | "outside-section";
|
|
220
|
+
getCurrentMediaSection: ({ offset, mediaSections, }: {
|
|
221
|
+
offset: number;
|
|
222
|
+
mediaSections: import("./video-section").MediaSection[];
|
|
223
|
+
}) => import("./video-section").MediaSection | null;
|
|
224
|
+
getMediaSectionAssertOnlyOne: () => import("./video-section").MediaSection;
|
|
225
|
+
};
|
|
226
|
+
logLevel: LogLevel;
|
|
227
|
+
iterator: BufferIterator;
|
|
228
|
+
controller: MediaParserController;
|
|
229
|
+
mode: ParseMediaMode;
|
|
230
|
+
src: ParseMediaSrc;
|
|
231
|
+
readerInterface: ReaderInterface;
|
|
232
|
+
discardReadBytes: (force: boolean) => Promise<void>;
|
|
233
|
+
selectM3uStreamFn: SelectM3uStreamFn;
|
|
234
|
+
selectM3uAssociatedPlaylistsFn: SelectM3uAssociatedPlaylistsFn;
|
|
235
|
+
mp4HeaderSegment: any;
|
|
236
|
+
contentType: string | null;
|
|
237
|
+
name: string;
|
|
238
|
+
returnValue: ParseMediaResult<AllParseMediaFields>;
|
|
239
|
+
callbackFunctions: ParseMediaCallbacks;
|
|
240
|
+
fieldsInReturnValue: Options<ParseMediaFields>;
|
|
241
|
+
mimeType: string | null;
|
|
242
|
+
errored: Error | null;
|
|
243
|
+
currentReader: {
|
|
244
|
+
getCurrent: () => Reader;
|
|
245
|
+
setCurrent: (newReader: AvcPPs) => void;
|
|
246
|
+
};
|
|
247
|
+
seekInfiniteLoop: {
|
|
248
|
+
registerSeek: (byte: number) => void;
|
|
249
|
+
reset: () => void;
|
|
250
|
+
};
|
|
251
|
+
};
|
|
252
|
+
export type ParserState = ReturnType<typeof makeParserState>;
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.makeParserState = void 0;
|
|
4
|
+
const get_fields_from_callbacks_1 = require("../get-fields-from-callbacks");
|
|
5
|
+
const buffer_iterator_1 = require("../iterator/buffer-iterator");
|
|
6
|
+
const log_1 = require("../log");
|
|
7
|
+
const aac_state_1 = require("./aac-state");
|
|
8
|
+
const current_reader_1 = require("./current-reader");
|
|
9
|
+
const emitted_fields_1 = require("./emitted-fields");
|
|
10
|
+
const flac_state_1 = require("./flac-state");
|
|
11
|
+
const images_1 = require("./images");
|
|
12
|
+
const iso_state_1 = require("./iso-base-media/iso-state");
|
|
13
|
+
const keyframes_1 = require("./keyframes");
|
|
14
|
+
const m3u_state_1 = require("./m3u-state");
|
|
15
|
+
const mp3_1 = require("./mp3");
|
|
16
|
+
const riff_1 = require("./riff");
|
|
17
|
+
const sample_callbacks_1 = require("./sample-callbacks");
|
|
18
|
+
const seek_infinite_loop_1 = require("./seek-infinite-loop");
|
|
19
|
+
const slow_duration_fps_1 = require("./slow-duration-fps");
|
|
20
|
+
const structure_1 = require("./structure");
|
|
21
|
+
const timings_1 = require("./timings");
|
|
22
|
+
const transport_stream_1 = require("./transport-stream/transport-stream");
|
|
23
|
+
const video_section_1 = require("./video-section");
|
|
24
|
+
const webm_1 = require("./webm");
|
|
25
|
+
const makeParserState = ({ hasAudioTrackHandlers, hasVideoTrackHandlers, controller, onAudioTrack, onVideoTrack, contentLength, logLevel, mode, src, readerInterface, onDiscardedData, selectM3uStreamFn, selectM3uAssociatedPlaylistsFn, mp4HeaderSegment, contentType, name, callbacks, fieldsInReturnValue, mimeType, initialReaderInstance, }) => {
|
|
26
|
+
let skippedBytes = 0;
|
|
27
|
+
const returnValue = {};
|
|
28
|
+
const iterator = (0, buffer_iterator_1.getArrayBufferIterator)(new Uint8Array([]), contentLength);
|
|
29
|
+
const increaseSkippedBytes = (bytes) => {
|
|
30
|
+
skippedBytes += bytes;
|
|
31
|
+
};
|
|
32
|
+
const structure = (0, structure_1.structureState)();
|
|
33
|
+
const keyframes = (0, keyframes_1.keyframesState)();
|
|
34
|
+
const emittedFields = (0, emitted_fields_1.emittedState)();
|
|
35
|
+
const slowDurationAndFps = (0, slow_duration_fps_1.slowDurationAndFpsState)();
|
|
36
|
+
const mp3Info = (0, mp3_1.makeMp3State)();
|
|
37
|
+
const images = (0, images_1.imagesState)();
|
|
38
|
+
const timings = (0, timings_1.timingsState)();
|
|
39
|
+
const seekInfiniteLoop = (0, seek_infinite_loop_1.seekInfiniteLoopDetectionState)();
|
|
40
|
+
const currentReaderState = (0, current_reader_1.currentReader)(initialReaderInstance);
|
|
41
|
+
const errored = null;
|
|
42
|
+
const discardReadBytes = async (force) => {
|
|
43
|
+
const { bytesRemoved, removedData } = iterator.removeBytesRead(force, mode);
|
|
44
|
+
if (bytesRemoved) {
|
|
45
|
+
log_1.Log.verbose(logLevel, `Freed ${bytesRemoved} bytes`);
|
|
46
|
+
}
|
|
47
|
+
if (removedData && onDiscardedData) {
|
|
48
|
+
await onDiscardedData(removedData);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
const fields = (0, get_fields_from_callbacks_1.getFieldsFromCallback)({
|
|
52
|
+
fields: fieldsInReturnValue,
|
|
53
|
+
callbacks,
|
|
54
|
+
});
|
|
55
|
+
return {
|
|
56
|
+
riff: (0, riff_1.riffSpecificState)(),
|
|
57
|
+
transportStream: (0, transport_stream_1.transportStreamState)(),
|
|
58
|
+
webm: (0, webm_1.webmState)(),
|
|
59
|
+
iso: (0, iso_state_1.isoBaseMediaState)({
|
|
60
|
+
contentLength,
|
|
61
|
+
controller,
|
|
62
|
+
readerInterface,
|
|
63
|
+
src,
|
|
64
|
+
logLevel,
|
|
65
|
+
}),
|
|
66
|
+
mp3Info,
|
|
67
|
+
aac: (0, aac_state_1.aacState)(),
|
|
68
|
+
flac: (0, flac_state_1.flacState)(),
|
|
69
|
+
m3u: (0, m3u_state_1.m3uState)(logLevel),
|
|
70
|
+
timings,
|
|
71
|
+
callbacks: (0, sample_callbacks_1.sampleCallback)({
|
|
72
|
+
controller,
|
|
73
|
+
hasAudioTrackHandlers,
|
|
74
|
+
hasVideoTrackHandlers,
|
|
75
|
+
fields,
|
|
76
|
+
keyframes,
|
|
77
|
+
emittedFields,
|
|
78
|
+
slowDurationAndFpsState: slowDurationAndFps,
|
|
79
|
+
structure,
|
|
80
|
+
src,
|
|
81
|
+
seekSignal: controller._internals.seekSignal,
|
|
82
|
+
logLevel,
|
|
83
|
+
}),
|
|
84
|
+
getInternalStats: () => {
|
|
85
|
+
var _a;
|
|
86
|
+
return ({
|
|
87
|
+
skippedBytes,
|
|
88
|
+
finalCursorOffset: (_a = iterator.counter.getOffset()) !== null && _a !== void 0 ? _a : 0,
|
|
89
|
+
});
|
|
90
|
+
},
|
|
91
|
+
getSkipBytes: () => skippedBytes,
|
|
92
|
+
increaseSkippedBytes,
|
|
93
|
+
keyframes,
|
|
94
|
+
structure,
|
|
95
|
+
onAudioTrack,
|
|
96
|
+
onVideoTrack,
|
|
97
|
+
emittedFields,
|
|
98
|
+
fields,
|
|
99
|
+
slowDurationAndFps,
|
|
100
|
+
contentLength,
|
|
101
|
+
images,
|
|
102
|
+
mediaSection: (0, video_section_1.mediaSectionState)(),
|
|
103
|
+
logLevel,
|
|
104
|
+
iterator,
|
|
105
|
+
controller,
|
|
106
|
+
mode,
|
|
107
|
+
src,
|
|
108
|
+
readerInterface,
|
|
109
|
+
discardReadBytes,
|
|
110
|
+
selectM3uStreamFn,
|
|
111
|
+
selectM3uAssociatedPlaylistsFn,
|
|
112
|
+
mp4HeaderSegment,
|
|
113
|
+
contentType,
|
|
114
|
+
name,
|
|
115
|
+
returnValue,
|
|
116
|
+
callbackFunctions: callbacks,
|
|
117
|
+
fieldsInReturnValue,
|
|
118
|
+
mimeType,
|
|
119
|
+
errored: errored,
|
|
120
|
+
currentReader: currentReaderState,
|
|
121
|
+
seekInfiniteLoop,
|
|
122
|
+
};
|
|
123
|
+
};
|
|
124
|
+
exports.makeParserState = makeParserState;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { SpsAndPps } from './parser-state';
|
|
2
|
+
type AvcProfileInfoCallback = (profile: SpsAndPps) => Promise<void>;
|
|
3
|
+
export declare const riffSpecificState: () => {
|
|
4
|
+
getAvcProfile: () => SpsAndPps | null;
|
|
5
|
+
onProfile: (profile: SpsAndPps) => Promise<void>;
|
|
6
|
+
registerOnAvcProfileCallback: (callback: AvcProfileInfoCallback) => void;
|
|
7
|
+
getNextTrackIndex: () => number;
|
|
8
|
+
incrementNextTrackIndex: () => void;
|
|
9
|
+
};
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.riffSpecificState = void 0;
|
|
4
|
+
const riffSpecificState = () => {
|
|
5
|
+
let avcProfile = null;
|
|
6
|
+
let nextTrackIndex = 0;
|
|
7
|
+
const profileCallbacks = [];
|
|
8
|
+
const registerOnAvcProfileCallback = (callback) => {
|
|
9
|
+
profileCallbacks.push(callback);
|
|
10
|
+
};
|
|
11
|
+
const onProfile = async (profile) => {
|
|
12
|
+
avcProfile = profile;
|
|
13
|
+
for (const callback of profileCallbacks) {
|
|
14
|
+
await callback(profile);
|
|
15
|
+
}
|
|
16
|
+
profileCallbacks.length = 0;
|
|
17
|
+
};
|
|
18
|
+
return {
|
|
19
|
+
getAvcProfile: () => {
|
|
20
|
+
return avcProfile;
|
|
21
|
+
},
|
|
22
|
+
onProfile,
|
|
23
|
+
registerOnAvcProfileCallback,
|
|
24
|
+
getNextTrackIndex: () => {
|
|
25
|
+
return nextTrackIndex;
|
|
26
|
+
},
|
|
27
|
+
incrementNextTrackIndex: () => {
|
|
28
|
+
nextTrackIndex++;
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
exports.riffSpecificState = riffSpecificState;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { MediaParserController } from '../controller/media-parser-controller';
|
|
2
|
+
import type { SeekSignal } from '../controller/seek-signal';
|
|
3
|
+
import type { AllOptions, Options, ParseMediaFields } from '../fields';
|
|
4
|
+
import type { LogLevel } from '../log';
|
|
5
|
+
import type { ParseMediaSrc } from '../options';
|
|
6
|
+
import type { AudioOrVideoSample, OnAudioSample, OnVideoSample } from '../webcodec-sample-types';
|
|
7
|
+
import { type KeyframesState } from './keyframes';
|
|
8
|
+
import type { SlowDurationAndFpsState } from './slow-duration-fps';
|
|
9
|
+
import type { StructureState } from './structure';
|
|
10
|
+
export declare const sampleCallback: ({ controller, hasAudioTrackHandlers, hasVideoTrackHandlers, fields, keyframes, emittedFields, slowDurationAndFpsState, structure, src, seekSignal, logLevel, }: {
|
|
11
|
+
controller: MediaParserController;
|
|
12
|
+
hasAudioTrackHandlers: boolean;
|
|
13
|
+
hasVideoTrackHandlers: boolean;
|
|
14
|
+
fields: Options<ParseMediaFields>;
|
|
15
|
+
keyframes: KeyframesState;
|
|
16
|
+
emittedFields: AllOptions<ParseMediaFields>;
|
|
17
|
+
slowDurationAndFpsState: SlowDurationAndFpsState;
|
|
18
|
+
structure: StructureState;
|
|
19
|
+
src: ParseMediaSrc;
|
|
20
|
+
seekSignal: SeekSignal;
|
|
21
|
+
logLevel: LogLevel;
|
|
22
|
+
}) => {
|
|
23
|
+
registerVideoSampleCallback: (id: number, callback: OnVideoSample | null) => Promise<void>;
|
|
24
|
+
onAudioSample: (trackId: number, audioSample: AudioOrVideoSample) => Promise<void>;
|
|
25
|
+
getSamplesForTrack: (trackId: number) => number;
|
|
26
|
+
onVideoSample: (trackId: number, videoSample: AudioOrVideoSample) => Promise<void>;
|
|
27
|
+
canSkipTracksState: {
|
|
28
|
+
canSkipTracks: () => boolean;
|
|
29
|
+
};
|
|
30
|
+
registerAudioSampleCallback: (id: number, callback: OnAudioSample | null) => Promise<void>;
|
|
31
|
+
tracks: {
|
|
32
|
+
hasAllTracks: () => boolean;
|
|
33
|
+
getIsDone: () => boolean;
|
|
34
|
+
setIsDone: (logLevel: MediaParserController) => void;
|
|
35
|
+
addTrack: (track: MediaParserController) => void;
|
|
36
|
+
getTracks: () => Track[];
|
|
37
|
+
ensureHasTracksAtEnd: (fields: MediaParserController<MediaParserController>) => void;
|
|
38
|
+
};
|
|
39
|
+
audioSampleCallbacks: Record<number, OnAudioSample>;
|
|
40
|
+
videoSampleCallbacks: Record<number, OnVideoSample>;
|
|
41
|
+
hasAudioTrackHandlers: boolean;
|
|
42
|
+
hasVideoTrackHandlers: boolean;
|
|
43
|
+
};
|
|
44
|
+
export type SampleCallbacks = ReturnType<typeof sampleCallback>;
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sampleCallback = void 0;
|
|
4
|
+
const log_1 = require("../log");
|
|
5
|
+
const can_skip_tracks_1 = require("./can-skip-tracks");
|
|
6
|
+
const has_tracks_section_1 = require("./has-tracks-section");
|
|
7
|
+
const need_samples_for_fields_1 = require("./need-samples-for-fields");
|
|
8
|
+
const sampleCallback = ({ controller, hasAudioTrackHandlers, hasVideoTrackHandlers, fields, keyframes, emittedFields, slowDurationAndFpsState, structure, src, seekSignal, logLevel, }) => {
|
|
9
|
+
const videoSampleCallbacks = {};
|
|
10
|
+
const audioSampleCallbacks = {};
|
|
11
|
+
const queuedAudioSamples = {};
|
|
12
|
+
const queuedVideoSamples = {};
|
|
13
|
+
const canSkipTracksState = (0, can_skip_tracks_1.makeCanSkipTracksState)({
|
|
14
|
+
hasAudioTrackHandlers,
|
|
15
|
+
fields,
|
|
16
|
+
hasVideoTrackHandlers,
|
|
17
|
+
structure,
|
|
18
|
+
});
|
|
19
|
+
const tracksState = (0, has_tracks_section_1.makeTracksSectionState)(canSkipTracksState, src);
|
|
20
|
+
const samplesForTrack = {};
|
|
21
|
+
return {
|
|
22
|
+
registerVideoSampleCallback: async (id, callback) => {
|
|
23
|
+
var _a;
|
|
24
|
+
if (callback === null) {
|
|
25
|
+
delete videoSampleCallbacks[id];
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
videoSampleCallbacks[id] = callback;
|
|
29
|
+
for (const queued of (_a = queuedVideoSamples[id]) !== null && _a !== void 0 ? _a : []) {
|
|
30
|
+
await callback(queued);
|
|
31
|
+
}
|
|
32
|
+
queuedVideoSamples[id] = [];
|
|
33
|
+
},
|
|
34
|
+
onAudioSample: async (trackId, audioSample) => {
|
|
35
|
+
if (controller._internals.signal.aborted) {
|
|
36
|
+
throw new Error('Aborted');
|
|
37
|
+
}
|
|
38
|
+
if (typeof samplesForTrack[trackId] === 'undefined') {
|
|
39
|
+
samplesForTrack[trackId] = 0;
|
|
40
|
+
}
|
|
41
|
+
const callback = audioSampleCallbacks[trackId];
|
|
42
|
+
if (audioSample.data.length > 0) {
|
|
43
|
+
samplesForTrack[trackId]++;
|
|
44
|
+
// If we emit samples with data length 0, Chrome will fail
|
|
45
|
+
if (callback) {
|
|
46
|
+
if (seekSignal.getSeek()) {
|
|
47
|
+
log_1.Log.trace(logLevel, 'Not emitting sample because seek is processing');
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
await callback(audioSample);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
if ((0, need_samples_for_fields_1.needsToIterateOverSamples)({ emittedFields, fields })) {
|
|
55
|
+
slowDurationAndFpsState.addAudioSample(audioSample);
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
getSamplesForTrack: (trackId) => {
|
|
59
|
+
var _a;
|
|
60
|
+
return (_a = samplesForTrack[trackId]) !== null && _a !== void 0 ? _a : 0;
|
|
61
|
+
},
|
|
62
|
+
onVideoSample: async (trackId, videoSample) => {
|
|
63
|
+
if (controller._internals.signal.aborted) {
|
|
64
|
+
throw new Error('Aborted');
|
|
65
|
+
}
|
|
66
|
+
if (typeof samplesForTrack[trackId] === 'undefined') {
|
|
67
|
+
samplesForTrack[trackId] = 0;
|
|
68
|
+
}
|
|
69
|
+
if (videoSample.data.length > 0) {
|
|
70
|
+
samplesForTrack[trackId]++;
|
|
71
|
+
const callback = videoSampleCallbacks[trackId];
|
|
72
|
+
// If we emit samples with data 0, Chrome will fail
|
|
73
|
+
if (callback) {
|
|
74
|
+
if (seekSignal.getSeek()) {
|
|
75
|
+
log_1.Log.trace(logLevel, 'Not emitting sample because seek is processing');
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
await callback(videoSample);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
if ((0, need_samples_for_fields_1.needsToIterateOverSamples)({
|
|
83
|
+
fields,
|
|
84
|
+
emittedFields,
|
|
85
|
+
})) {
|
|
86
|
+
if (fields.slowKeyframes && videoSample.type === 'key') {
|
|
87
|
+
keyframes.addKeyframe({
|
|
88
|
+
trackId,
|
|
89
|
+
decodingTimeInSeconds: videoSample.dts / videoSample.timescale,
|
|
90
|
+
positionInBytes: videoSample.offset,
|
|
91
|
+
presentationTimeInSeconds: videoSample.cts / videoSample.timescale,
|
|
92
|
+
sizeInBytes: videoSample.data.length,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
slowDurationAndFpsState.addVideoSample(videoSample);
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
canSkipTracksState,
|
|
99
|
+
registerAudioSampleCallback: async (id, callback) => {
|
|
100
|
+
var _a;
|
|
101
|
+
if (callback === null) {
|
|
102
|
+
delete audioSampleCallbacks[id];
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
audioSampleCallbacks[id] = callback;
|
|
106
|
+
for (const queued of (_a = queuedAudioSamples[id]) !== null && _a !== void 0 ? _a : []) {
|
|
107
|
+
await callback(queued);
|
|
108
|
+
}
|
|
109
|
+
queuedAudioSamples[id] = [];
|
|
110
|
+
},
|
|
111
|
+
tracks: tracksState,
|
|
112
|
+
audioSampleCallbacks,
|
|
113
|
+
videoSampleCallbacks,
|
|
114
|
+
hasAudioTrackHandlers,
|
|
115
|
+
hasVideoTrackHandlers,
|
|
116
|
+
};
|
|
117
|
+
};
|
|
118
|
+
exports.sampleCallback = sampleCallback;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.seekInfiniteLoopDetectionState = void 0;
|
|
4
|
+
const seekInfiniteLoopDetectionState = () => {
|
|
5
|
+
let lastSeek = null;
|
|
6
|
+
return {
|
|
7
|
+
registerSeek: (byte) => {
|
|
8
|
+
if (!lastSeek || lastSeek.byte !== byte) {
|
|
9
|
+
lastSeek = { byte, numberOfTimes: 1 };
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
lastSeek.numberOfTimes++;
|
|
13
|
+
if (lastSeek.numberOfTimes >= 10) {
|
|
14
|
+
throw new Error(`Seeking infinite loop detected: Seeked to byte 0x${byte.toString(16)} ${lastSeek.numberOfTimes} times in a row with no position change in the file. Check your usage of .seek().`);
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
reset: () => {
|
|
18
|
+
lastSeek = null;
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
exports.seekInfiniteLoopDetectionState = seekInfiniteLoopDetectionState;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { AudioOrVideoSample } from '../webcodec-sample-types';
|
|
2
|
+
export declare const slowDurationAndFpsState: () => {
|
|
3
|
+
addVideoSample: (videoSample: AudioOrVideoSample) => void;
|
|
4
|
+
addAudioSample: (audioSample: AudioOrVideoSample) => void;
|
|
5
|
+
getSlowDurationInSeconds: () => number;
|
|
6
|
+
getFps: () => number;
|
|
7
|
+
getSlowNumberOfFrames: () => number;
|
|
8
|
+
getAudioBitrate: () => number | null;
|
|
9
|
+
getVideoBitrate: () => number | null;
|
|
10
|
+
};
|
|
11
|
+
export type SlowDurationAndFpsState = ReturnType<typeof slowDurationAndFpsState>;
|