@remotion/media-parser 4.0.237 → 4.0.239
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/aac-codecprivate.d.ts +2 -9
- package/dist/aac-codecprivate.js +69 -34
- package/dist/add-avc-profile-to-track.js +4 -23
- package/dist/boxes/avc/codec-private.d.ts +2 -0
- package/dist/boxes/avc/codec-private.js +28 -0
- package/dist/boxes/avc/codec-string.d.ts +2 -0
- package/dist/boxes/avc/codec-string.js +7 -0
- package/dist/boxes/avc/color.d.ts +6 -0
- package/dist/boxes/avc/color.js +39 -0
- package/dist/boxes/avc/interpret-sps.d.ts +11 -0
- package/dist/boxes/avc/interpret-sps.js +44 -0
- package/dist/boxes/avc/key.d.ts +2 -0
- package/dist/boxes/avc/key.js +11 -0
- package/dist/boxes/avc/parse-avc.d.ts +36 -3
- package/dist/boxes/avc/parse-avc.js +161 -4
- package/dist/boxes/avc/sps-and-pps.d.ts +3 -0
- package/dist/boxes/avc/sps-and-pps.js +12 -0
- package/dist/boxes/iso-base-media/get-video-codec-from-iso-track.d.ts +2 -0
- package/dist/boxes/iso-base-media/get-video-codec-from-iso-track.js +55 -0
- package/dist/boxes/iso-base-media/make-track.js +2 -1
- package/dist/boxes/iso-base-media/mdat/mdat.js +8 -14
- package/dist/boxes/iso-base-media/process-box.js +1 -1
- package/dist/boxes/riff/parse-box.js +2 -2
- package/dist/boxes/riff/parse-movi.js +12 -14
- package/dist/boxes/transport-stream/adts-header.d.ts +7 -0
- package/dist/boxes/transport-stream/adts-header.js +56 -0
- package/dist/boxes/transport-stream/boxes.d.ts +41 -0
- package/dist/boxes/transport-stream/boxes.js +2 -0
- package/dist/boxes/transport-stream/discard-rest-of-packet.d.ts +3 -0
- package/dist/boxes/transport-stream/discard-rest-of-packet.js +13 -0
- package/dist/boxes/transport-stream/find-separator.d.ts +2 -0
- package/dist/boxes/transport-stream/find-separator.js +30 -0
- package/dist/boxes/transport-stream/get-tracks.d.ts +5 -0
- package/dist/boxes/transport-stream/get-tracks.js +33 -0
- package/dist/boxes/transport-stream/handle-aac-packet.d.ts +7 -0
- package/dist/boxes/transport-stream/handle-aac-packet.js +50 -0
- package/dist/boxes/transport-stream/handle-avc-packet.d.ts +8 -0
- package/dist/boxes/transport-stream/handle-avc-packet.js +60 -0
- package/dist/boxes/transport-stream/next-pes-header-store.d.ts +6 -0
- package/dist/boxes/transport-stream/next-pes-header-store.js +18 -0
- package/dist/boxes/transport-stream/parse-packet.d.ts +13 -0
- package/dist/boxes/transport-stream/parse-packet.js +80 -0
- package/dist/boxes/transport-stream/parse-pat.d.ts +8 -0
- package/dist/boxes/transport-stream/parse-pat.js +49 -0
- package/dist/boxes/transport-stream/parse-pes.d.ts +8 -0
- package/dist/boxes/transport-stream/parse-pes.js +76 -0
- package/dist/boxes/transport-stream/parse-pmt.d.ts +11 -0
- package/dist/boxes/transport-stream/parse-pmt.js +64 -0
- package/dist/boxes/transport-stream/parse-stream-packet.d.ts +15 -0
- package/dist/boxes/transport-stream/parse-stream-packet.js +107 -0
- package/dist/boxes/transport-stream/parse-transport-stream.d.ts +14 -0
- package/dist/boxes/transport-stream/parse-transport-stream.js +72 -0
- package/dist/boxes/transport-stream/process-stream-buffers.d.ts +19 -0
- package/dist/boxes/transport-stream/process-stream-buffers.js +42 -0
- package/dist/boxes/transport-stream/traversal.d.ts +6 -0
- package/dist/boxes/transport-stream/traversal.js +30 -0
- package/dist/boxes/webm/parse-ebml.js +1 -1
- package/dist/buffer-iterator.d.ts +2 -0
- package/dist/buffer-iterator.js +25 -0
- package/dist/convert-audio-or-video-sample.d.ts +2 -0
- package/dist/convert-audio-or-video-sample.js +17 -0
- package/dist/create/iso-base-media/create-iso-base-media.js +38 -19
- package/dist/create/iso-base-media/trak/mdia/minf/create-stbl.js +7 -1
- package/dist/create/iso-base-media/trak/mdia/minf/stbl/create-stts.js +3 -0
- package/dist/create/media-fn.d.ts +0 -1
- package/dist/create/progress-tracker.d.ts +2 -0
- package/dist/create/progress-tracker.js +32 -8
- package/dist/emit-available-info.js +1 -1
- package/dist/esm/index.mjs +1288 -252
- package/dist/get-container.d.ts +1 -1
- package/dist/get-container.js +3 -0
- package/dist/get-duration.js +4 -1
- package/dist/get-fps.js +8 -2
- package/dist/get-tracks.d.ts +4 -3
- package/dist/get-tracks.js +9 -2
- package/dist/get-video-codec.d.ts +1 -2
- package/dist/get-video-codec.js +9 -148
- package/dist/index.d.ts +2 -0
- package/dist/metadata/get-metadata.js +3 -0
- package/dist/options.d.ts +3 -3
- package/dist/parse-media.js +3 -3
- package/dist/parse-result.d.ts +7 -2
- package/dist/parse-video.js +15 -0
- package/dist/register-track.d.ts +5 -5
- package/dist/register-track.js +16 -10
- package/dist/state/has-tracks-section.d.ts +3 -0
- package/dist/state/has-tracks-section.js +5 -0
- package/dist/state/parser-state.d.ts +2 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/webcodec-sample-types.d.ts +9 -2
- package/package.json +3 -3
- package/dist/add-new-matroska-tracks.d.ts +0 -13
- package/dist/add-new-matroska-tracks.js +0 -29
- package/dist/boxes/iso-base-media/meta/keys.d.ts +0 -10
- package/dist/boxes/iso-base-media/meta/keys.js +0 -17
- package/dist/boxes/iso-base-media/meta/list.d.ts +0 -12
- package/dist/boxes/iso-base-media/meta/list.js +0 -33
- package/dist/boxes/riff/strf.d.ts +0 -7
- package/dist/boxes/riff/strf.js +0 -67
- package/dist/create/mp3/create-mp3.d.ts +0 -2
- package/dist/create/mp3/create-mp3.js +0 -49
- package/dist/get-metadata.d.ts +0 -7
- package/dist/get-metadata.js +0 -63
- package/dist/parser-state.d.ts +0 -33
- package/dist/parser-state.js +0 -162
package/dist/esm/index.mjs
CHANGED
|
@@ -106,6 +106,38 @@ var fetchReader = {
|
|
|
106
106
|
};
|
|
107
107
|
|
|
108
108
|
// src/aac-codecprivate.ts
|
|
109
|
+
var getSampleRateFromSampleFrequencyIndex = (samplingFrequencyIndex) => {
|
|
110
|
+
switch (samplingFrequencyIndex) {
|
|
111
|
+
case 0:
|
|
112
|
+
return 96000;
|
|
113
|
+
case 1:
|
|
114
|
+
return 88200;
|
|
115
|
+
case 2:
|
|
116
|
+
return 64000;
|
|
117
|
+
case 3:
|
|
118
|
+
return 48000;
|
|
119
|
+
case 4:
|
|
120
|
+
return 44100;
|
|
121
|
+
case 5:
|
|
122
|
+
return 32000;
|
|
123
|
+
case 6:
|
|
124
|
+
return 24000;
|
|
125
|
+
case 7:
|
|
126
|
+
return 22050;
|
|
127
|
+
case 8:
|
|
128
|
+
return 16000;
|
|
129
|
+
case 9:
|
|
130
|
+
return 12000;
|
|
131
|
+
case 10:
|
|
132
|
+
return 11025;
|
|
133
|
+
case 11:
|
|
134
|
+
return 8000;
|
|
135
|
+
case 12:
|
|
136
|
+
return 7350;
|
|
137
|
+
default:
|
|
138
|
+
throw new Error(`Unexpected sampling frequency index ${samplingFrequencyIndex}`);
|
|
139
|
+
}
|
|
140
|
+
};
|
|
109
141
|
var getConfigForSampleRate = (sampleRate) => {
|
|
110
142
|
if (sampleRate === 96000) {
|
|
111
143
|
return 0;
|
|
@@ -175,44 +207,35 @@ var parseAacCodecPrivate = (bytes) => {
|
|
|
175
207
|
const audioObjectType = parseInt(bits.slice(0, 5), 2);
|
|
176
208
|
const samplingFrequencyIndex = parseInt(bits.slice(5, 9), 2);
|
|
177
209
|
const channelConfiguration = parseInt(bits.slice(9, 13), 2);
|
|
178
|
-
const sampleRate = (
|
|
179
|
-
switch (samplingFrequencyIndex) {
|
|
180
|
-
case 0:
|
|
181
|
-
return 96000;
|
|
182
|
-
case 1:
|
|
183
|
-
return 88200;
|
|
184
|
-
case 2:
|
|
185
|
-
return 64000;
|
|
186
|
-
case 3:
|
|
187
|
-
return 48000;
|
|
188
|
-
case 4:
|
|
189
|
-
return 44100;
|
|
190
|
-
case 5:
|
|
191
|
-
return 32000;
|
|
192
|
-
case 6:
|
|
193
|
-
return 24000;
|
|
194
|
-
case 7:
|
|
195
|
-
return 22050;
|
|
196
|
-
case 8:
|
|
197
|
-
return 16000;
|
|
198
|
-
case 9:
|
|
199
|
-
return 12000;
|
|
200
|
-
case 10:
|
|
201
|
-
return 11025;
|
|
202
|
-
case 11:
|
|
203
|
-
return 8000;
|
|
204
|
-
case 12:
|
|
205
|
-
return 7350;
|
|
206
|
-
default:
|
|
207
|
-
throw new Error(`Unexpected sampling frequency index ${samplingFrequencyIndex}`);
|
|
208
|
-
}
|
|
209
|
-
})();
|
|
210
|
+
const sampleRate = getSampleRateFromSampleFrequencyIndex(samplingFrequencyIndex);
|
|
210
211
|
return {
|
|
211
212
|
audioObjectType,
|
|
212
213
|
sampleRate,
|
|
213
214
|
channelConfiguration
|
|
214
215
|
};
|
|
215
216
|
};
|
|
217
|
+
var mapAudioObjectTypeToCodecString = (audioObjectType) => {
|
|
218
|
+
switch (audioObjectType) {
|
|
219
|
+
case 1:
|
|
220
|
+
return "mp4a.40.2";
|
|
221
|
+
case 2:
|
|
222
|
+
return "mp4a.40.5";
|
|
223
|
+
case 3:
|
|
224
|
+
return "mp4a.40.29";
|
|
225
|
+
case 4:
|
|
226
|
+
return "mp4a.40.1";
|
|
227
|
+
case 5:
|
|
228
|
+
return "mp4a.40.3";
|
|
229
|
+
case 6:
|
|
230
|
+
return "mp4a.40.4";
|
|
231
|
+
case 17:
|
|
232
|
+
return "mp4a.40.17";
|
|
233
|
+
case 23:
|
|
234
|
+
return "mp4a.40.23";
|
|
235
|
+
default:
|
|
236
|
+
throw new Error(`Unexpected audio object type ${audioObjectType}`);
|
|
237
|
+
}
|
|
238
|
+
};
|
|
216
239
|
|
|
217
240
|
// src/create/event-emitter.ts
|
|
218
241
|
class IoEventEmitter {
|
|
@@ -1343,7 +1366,7 @@ var createIsoBaseMediaFtyp = ({
|
|
|
1343
1366
|
};
|
|
1344
1367
|
|
|
1345
1368
|
// src/version.ts
|
|
1346
|
-
var VERSION = "4.0.
|
|
1369
|
+
var VERSION = "4.0.239";
|
|
1347
1370
|
|
|
1348
1371
|
// src/create/iso-base-media/create-ilst.ts
|
|
1349
1372
|
var createIlst = (items) => {
|
|
@@ -1872,6 +1895,9 @@ var createStsz = (samplePositions) => {
|
|
|
1872
1895
|
|
|
1873
1896
|
// src/create/iso-base-media/trak/mdia/minf/stbl/create-stts.ts
|
|
1874
1897
|
var makeEntry2 = (entry) => {
|
|
1898
|
+
if (entry.sampleOffset < 0) {
|
|
1899
|
+
throw new Error("negative sample offset in stts " + entry.sampleOffset);
|
|
1900
|
+
}
|
|
1875
1901
|
return combineUint8Arrays([
|
|
1876
1902
|
numberTo32BitUIntOrInt(entry.sampleCount),
|
|
1877
1903
|
numberTo32BitUIntOrInt(entry.sampleOffset)
|
|
@@ -1923,10 +1949,11 @@ var createStbl = ({
|
|
|
1923
1949
|
codecSpecificData,
|
|
1924
1950
|
isVideo
|
|
1925
1951
|
}) => {
|
|
1952
|
+
const sorted = samplePositions.slice().sort((a, b) => a.dts - b.dts);
|
|
1926
1953
|
return addSize(combineUint8Arrays([
|
|
1927
1954
|
stringsToUint8Array("stbl"),
|
|
1928
1955
|
createStsdData(codecSpecificData),
|
|
1929
|
-
createSttsAtom(
|
|
1956
|
+
createSttsAtom(sorted),
|
|
1930
1957
|
isVideo ? createStss(samplePositions) : null,
|
|
1931
1958
|
createCttsBox(samplePositions),
|
|
1932
1959
|
createStsc(samplePositions),
|
|
@@ -2119,6 +2146,7 @@ var createPaddedMoovAtom = ({
|
|
|
2119
2146
|
};
|
|
2120
2147
|
|
|
2121
2148
|
// src/create/iso-base-media/create-iso-base-media.ts
|
|
2149
|
+
var CONTAINER_TIMESCALE = 1000;
|
|
2122
2150
|
var createIsoBaseMedia = async ({
|
|
2123
2151
|
writer,
|
|
2124
2152
|
onBytesProgress,
|
|
@@ -2134,23 +2162,25 @@ var createIsoBaseMedia = async ({
|
|
|
2134
2162
|
});
|
|
2135
2163
|
const w = await writer.createContent({ filename, mimeType: "video/mp4" });
|
|
2136
2164
|
await w.write(header);
|
|
2137
|
-
let
|
|
2165
|
+
let globalDurationInUnits = 0;
|
|
2166
|
+
const lowestTrackTimestamps = {};
|
|
2167
|
+
const trackDurations = {};
|
|
2138
2168
|
const currentTracks = [];
|
|
2139
2169
|
const samplePositions = [];
|
|
2140
2170
|
const sampleChunkIndices = [];
|
|
2141
2171
|
const moovOffset = w.getWrittenByteCount();
|
|
2142
2172
|
const getPaddedMoovAtom = () => {
|
|
2143
2173
|
return createPaddedMoovAtom({
|
|
2144
|
-
durationInUnits,
|
|
2174
|
+
durationInUnits: globalDurationInUnits,
|
|
2145
2175
|
trackInfo: currentTracks.map((track) => {
|
|
2146
2176
|
return {
|
|
2147
2177
|
track,
|
|
2148
|
-
durationInUnits,
|
|
2178
|
+
durationInUnits: trackDurations[track.trackNumber] ?? 0,
|
|
2149
2179
|
samplePositions: samplePositions[track.trackNumber] ?? [],
|
|
2150
2180
|
timescale: track.timescale
|
|
2151
2181
|
};
|
|
2152
2182
|
}),
|
|
2153
|
-
timescale:
|
|
2183
|
+
timescale: CONTAINER_TIMESCALE
|
|
2154
2184
|
});
|
|
2155
2185
|
};
|
|
2156
2186
|
await w.write(getPaddedMoovAtom());
|
|
@@ -2169,10 +2199,6 @@ var createIsoBaseMedia = async ({
|
|
|
2169
2199
|
await w.updateDataAt(moovOffset, getPaddedMoovAtom());
|
|
2170
2200
|
onBytesProgress(w.getWrittenByteCount());
|
|
2171
2201
|
};
|
|
2172
|
-
const updateDuration = (newDuration) => {
|
|
2173
|
-
durationInUnits = newDuration;
|
|
2174
|
-
onMillisecondsProgress(newDuration);
|
|
2175
|
-
};
|
|
2176
2202
|
const addCodecPrivateToTrack = ({
|
|
2177
2203
|
trackNumber: trackNumber2,
|
|
2178
2204
|
codecPrivate: codecPrivate2
|
|
@@ -2188,19 +2214,35 @@ var createIsoBaseMedia = async ({
|
|
|
2188
2214
|
chunk,
|
|
2189
2215
|
trackNumber: trackNumber2,
|
|
2190
2216
|
isVideo,
|
|
2191
|
-
timescale,
|
|
2192
2217
|
codecPrivate: codecPrivate2
|
|
2193
2218
|
}) => {
|
|
2194
2219
|
const position = w.getWrittenByteCount();
|
|
2195
2220
|
await w.write(chunk.data);
|
|
2196
2221
|
mdatSize += chunk.data.length;
|
|
2197
2222
|
onBytesProgress(w.getWrittenByteCount());
|
|
2223
|
+
progressTracker.setPossibleLowestTimestamp(Math.min(chunk.timestamp, chunk.cts ?? Infinity, chunk.dts ?? Infinity));
|
|
2198
2224
|
progressTracker.updateTrackProgress(trackNumber2, chunk.timestamp);
|
|
2199
2225
|
if (codecPrivate2) {
|
|
2200
2226
|
addCodecPrivateToTrack({ trackNumber: trackNumber2, codecPrivate: codecPrivate2 });
|
|
2201
2227
|
}
|
|
2202
|
-
const
|
|
2203
|
-
|
|
2228
|
+
const currentTrack = currentTracks.find((t) => t.trackNumber === trackNumber2);
|
|
2229
|
+
if (!currentTrack) {
|
|
2230
|
+
throw new Error(`Tried to add sample to track ${trackNumber2}, but it doesn't exist`);
|
|
2231
|
+
}
|
|
2232
|
+
if (!lowestTrackTimestamps[trackNumber2] || chunk.timestamp < lowestTrackTimestamps[trackNumber2]) {
|
|
2233
|
+
lowestTrackTimestamps[trackNumber2] = chunk.timestamp;
|
|
2234
|
+
}
|
|
2235
|
+
if (typeof lowestTrackTimestamps[trackNumber2] !== "number") {
|
|
2236
|
+
throw new Error(`Tried to add sample to track ${trackNumber2}, but it has no timestamp`);
|
|
2237
|
+
}
|
|
2238
|
+
const newDurationInMicroSeconds = chunk.timestamp + (chunk.duration ?? 0) - lowestTrackTimestamps[trackNumber2];
|
|
2239
|
+
const newDurationInTrackTimeUnits = Math.round(newDurationInMicroSeconds / (1e6 / currentTrack.timescale));
|
|
2240
|
+
trackDurations[trackNumber2] = newDurationInTrackTimeUnits;
|
|
2241
|
+
const newDurationInMilliseconds = Math.round(newDurationInMicroSeconds / 1e6 * CONTAINER_TIMESCALE);
|
|
2242
|
+
if (newDurationInMilliseconds > globalDurationInUnits) {
|
|
2243
|
+
globalDurationInUnits = newDurationInMilliseconds;
|
|
2244
|
+
onMillisecondsProgress(newDurationInMilliseconds);
|
|
2245
|
+
}
|
|
2204
2246
|
if (!samplePositions[trackNumber2]) {
|
|
2205
2247
|
samplePositions[trackNumber2] = [];
|
|
2206
2248
|
}
|
|
@@ -2218,9 +2260,9 @@ var createIsoBaseMedia = async ({
|
|
|
2218
2260
|
isKeyframe: chunk.type === "key",
|
|
2219
2261
|
offset: position,
|
|
2220
2262
|
chunk: sampleChunkIndices[trackNumber2],
|
|
2221
|
-
cts: Math.round(chunk.cts /
|
|
2222
|
-
dts: Math.round(chunk.dts /
|
|
2223
|
-
duration: Math.round((chunk.duration ?? 0) /
|
|
2263
|
+
cts: Math.round(chunk.cts / 1e6 * currentTrack.timescale),
|
|
2264
|
+
dts: Math.round(chunk.dts / 1e6 * currentTrack.timescale),
|
|
2265
|
+
duration: Math.round((chunk.duration ?? 0) / 1e6 * currentTrack.timescale),
|
|
2224
2266
|
size: chunk.data.length
|
|
2225
2267
|
};
|
|
2226
2268
|
lastChunkWasVideo = isVideo;
|
|
@@ -2240,13 +2282,12 @@ var createIsoBaseMedia = async ({
|
|
|
2240
2282
|
remove: async () => {
|
|
2241
2283
|
await w.remove();
|
|
2242
2284
|
},
|
|
2243
|
-
addSample: ({ chunk, trackNumber: trackNumber2, isVideo,
|
|
2285
|
+
addSample: ({ chunk, trackNumber: trackNumber2, isVideo, codecPrivate: codecPrivate2 }) => {
|
|
2244
2286
|
operationProm.current = operationProm.current.then(() => {
|
|
2245
2287
|
return addSample({
|
|
2246
2288
|
chunk,
|
|
2247
2289
|
trackNumber: trackNumber2,
|
|
2248
2290
|
isVideo,
|
|
2249
|
-
timescale,
|
|
2250
2291
|
codecPrivate: codecPrivate2
|
|
2251
2292
|
});
|
|
2252
2293
|
});
|
|
@@ -3318,20 +3359,37 @@ var withResolversAndWaitForReturn = () => {
|
|
|
3318
3359
|
var makeProgressTracker = () => {
|
|
3319
3360
|
const trackNumberProgresses = {};
|
|
3320
3361
|
const eventEmitter = new IoEventEmitter;
|
|
3321
|
-
|
|
3322
|
-
|
|
3323
|
-
if (
|
|
3324
|
-
|
|
3362
|
+
let startingTimestamp = null;
|
|
3363
|
+
const setPossibleLowestTimestamp = (timestamp) => {
|
|
3364
|
+
if (startingTimestamp === null) {
|
|
3365
|
+
startingTimestamp = timestamp;
|
|
3366
|
+
} else {
|
|
3367
|
+
startingTimestamp = Math.min(startingTimestamp, timestamp);
|
|
3325
3368
|
}
|
|
3369
|
+
};
|
|
3370
|
+
const getStartingTimestamp = () => {
|
|
3371
|
+
if (startingTimestamp === null) {
|
|
3372
|
+
throw new Error("No starting timestamp");
|
|
3373
|
+
}
|
|
3374
|
+
return startingTimestamp;
|
|
3375
|
+
};
|
|
3376
|
+
const calculateSmallestProgress = () => {
|
|
3377
|
+
const progressValues = Object.values(trackNumberProgresses).map((p) => {
|
|
3378
|
+
if (p !== null) {
|
|
3379
|
+
return p;
|
|
3380
|
+
}
|
|
3381
|
+
if (startingTimestamp === null) {
|
|
3382
|
+
throw new Error("No progress values to calculate smallest progress from");
|
|
3383
|
+
}
|
|
3384
|
+
return startingTimestamp;
|
|
3385
|
+
});
|
|
3326
3386
|
return Math.min(...progressValues);
|
|
3327
3387
|
};
|
|
3328
3388
|
return {
|
|
3329
3389
|
registerTrack: (trackNumber2) => {
|
|
3330
|
-
trackNumberProgresses[trackNumber2] =
|
|
3331
|
-
},
|
|
3332
|
-
getSmallestProgress: () => {
|
|
3333
|
-
return calculateSmallestProgress();
|
|
3390
|
+
trackNumberProgresses[trackNumber2] = null;
|
|
3334
3391
|
},
|
|
3392
|
+
getSmallestProgress: calculateSmallestProgress,
|
|
3335
3393
|
updateTrackProgress: (trackNumber2, progress) => {
|
|
3336
3394
|
if (trackNumberProgresses[trackNumber2] === undefined) {
|
|
3337
3395
|
throw new Error(`Tried to update progress for a track that was not registered: ${trackNumber2}`);
|
|
@@ -3349,7 +3407,9 @@ var makeProgressTracker = () => {
|
|
|
3349
3407
|
};
|
|
3350
3408
|
eventEmitter.addEventListener("processed", on);
|
|
3351
3409
|
return promise;
|
|
3352
|
-
}
|
|
3410
|
+
},
|
|
3411
|
+
getStartingTimestamp,
|
|
3412
|
+
setPossibleLowestTimestamp
|
|
3353
3413
|
};
|
|
3354
3414
|
};
|
|
3355
3415
|
|
|
@@ -3819,6 +3879,9 @@ var getMetadata = (structure) => {
|
|
|
3819
3879
|
if (structure.type === "riff") {
|
|
3820
3880
|
return getMetadataFromRiff(structure);
|
|
3821
3881
|
}
|
|
3882
|
+
if (structure.type === "transport-stream") {
|
|
3883
|
+
return [];
|
|
3884
|
+
}
|
|
3822
3885
|
return getMetadataFromIsoBase(structure);
|
|
3823
3886
|
};
|
|
3824
3887
|
|
|
@@ -3944,6 +4007,9 @@ var getFps = (segments) => {
|
|
|
3944
4007
|
if (segments.type === "matroska") {
|
|
3945
4008
|
return null;
|
|
3946
4009
|
}
|
|
4010
|
+
if (segments.type === "transport-stream") {
|
|
4011
|
+
return null;
|
|
4012
|
+
}
|
|
3947
4013
|
throw new Error("Cannot get fps, not implemented");
|
|
3948
4014
|
};
|
|
3949
4015
|
var hasFps = (boxes) => {
|
|
@@ -3951,6 +4017,9 @@ var hasFps = (boxes) => {
|
|
|
3951
4017
|
if (boxes.type === "matroska") {
|
|
3952
4018
|
return true;
|
|
3953
4019
|
}
|
|
4020
|
+
if (boxes.type === "transport-stream") {
|
|
4021
|
+
return true;
|
|
4022
|
+
}
|
|
3954
4023
|
return getFps(boxes) !== null;
|
|
3955
4024
|
} catch {
|
|
3956
4025
|
return false;
|
|
@@ -4278,6 +4347,17 @@ var getDisplayAspectRatio = ({
|
|
|
4278
4347
|
return reduceFraction(num, den);
|
|
4279
4348
|
};
|
|
4280
4349
|
|
|
4350
|
+
// src/boxes/avc/color.ts
|
|
4351
|
+
var getMatrixCoefficientsFromIndex = (index) => {
|
|
4352
|
+
return index === 1 ? "bt709" : index === 5 ? "bt470bg" : index === 6 ? "smpte170m" : index === 9 ? "bt2020" : null;
|
|
4353
|
+
};
|
|
4354
|
+
var getTransferCharacteristicsFromIndex = (index) => {
|
|
4355
|
+
return index === 1 ? "bt709" : index === 6 ? "smpte170m" : index === 13 ? "iec61966-2-1" : index === 18 ? "arib-std-b67" : null;
|
|
4356
|
+
};
|
|
4357
|
+
var getPrimariesFromIndex = (index) => {
|
|
4358
|
+
return index === 1 ? "bt709" : index === 5 ? "bt470bg" : index === 6 ? "smpte170m" : index === 9 ? "bt2020" : null;
|
|
4359
|
+
};
|
|
4360
|
+
|
|
4281
4361
|
// src/buffer-iterator.ts
|
|
4282
4362
|
class OffsetCounter {
|
|
4283
4363
|
#offset;
|
|
@@ -4474,6 +4554,9 @@ var getArrayBufferIterator = (initialData, maxBytes) => {
|
|
|
4474
4554
|
const isMp3 = () => {
|
|
4475
4555
|
return matchesPattern(mpegPattern)(data.subarray(0, 4));
|
|
4476
4556
|
};
|
|
4557
|
+
const isTransportStream = () => {
|
|
4558
|
+
return data[0] === 71;
|
|
4559
|
+
};
|
|
4477
4560
|
const removeBytesRead = () => {
|
|
4478
4561
|
if (!discardAllowed) {
|
|
4479
4562
|
return;
|
|
@@ -4510,6 +4593,20 @@ var getArrayBufferIterator = (initialData, maxBytes) => {
|
|
|
4510
4593
|
removeBytesRead();
|
|
4511
4594
|
}
|
|
4512
4595
|
};
|
|
4596
|
+
const readExpGolomb = () => {
|
|
4597
|
+
if (!bitReadingMode) {
|
|
4598
|
+
throw new Error("Not in bit reading mode");
|
|
4599
|
+
}
|
|
4600
|
+
let zerosCount = 0;
|
|
4601
|
+
while (getBits(1) === 0) {
|
|
4602
|
+
zerosCount++;
|
|
4603
|
+
}
|
|
4604
|
+
let suffix = 0;
|
|
4605
|
+
for (let i = 0;i < zerosCount; i++) {
|
|
4606
|
+
suffix = suffix << 1 | getBits(1);
|
|
4607
|
+
}
|
|
4608
|
+
return (1 << zerosCount) - 1 + suffix;
|
|
4609
|
+
};
|
|
4513
4610
|
const peekB = (length) => {
|
|
4514
4611
|
console.log([...getSlice(length)].map((b) => b.toString(16).padStart(2, "0")));
|
|
4515
4612
|
counter.decrement(length);
|
|
@@ -4532,9 +4629,12 @@ var getArrayBufferIterator = (initialData, maxBytes) => {
|
|
|
4532
4629
|
let bitIndex = 0;
|
|
4533
4630
|
const stopReadingBits = () => {
|
|
4534
4631
|
bitIndex = 0;
|
|
4632
|
+
bitReadingMode = false;
|
|
4535
4633
|
};
|
|
4536
4634
|
let byteToShift = 0;
|
|
4635
|
+
let bitReadingMode = false;
|
|
4537
4636
|
const startReadingBits = () => {
|
|
4637
|
+
bitReadingMode = true;
|
|
4538
4638
|
byteToShift = getUint8();
|
|
4539
4639
|
};
|
|
4540
4640
|
const getBits = (bits) => {
|
|
@@ -4739,7 +4839,9 @@ var getArrayBufferIterator = (initialData, maxBytes) => {
|
|
|
4739
4839
|
isMp3,
|
|
4740
4840
|
disallowDiscard,
|
|
4741
4841
|
allowDiscard,
|
|
4742
|
-
startBox
|
|
4842
|
+
startBox,
|
|
4843
|
+
isTransportStream,
|
|
4844
|
+
readExpGolomb
|
|
4743
4845
|
};
|
|
4744
4846
|
};
|
|
4745
4847
|
|
|
@@ -4806,114 +4908,9 @@ var parseAv1PrivateData = (data, colrAtom) => {
|
|
|
4806
4908
|
};
|
|
4807
4909
|
|
|
4808
4910
|
// src/get-video-codec.ts
|
|
4809
|
-
var
|
|
4810
|
-
const
|
|
4811
|
-
|
|
4812
|
-
const videoSample = stsdBox.samples.find((s) => s.type === "video");
|
|
4813
|
-
if (videoSample && videoSample.type === "video") {
|
|
4814
|
-
if (videoSample.format === "hvc1") {
|
|
4815
|
-
return "h265";
|
|
4816
|
-
}
|
|
4817
|
-
if (videoSample.format === "avc1") {
|
|
4818
|
-
return "h264";
|
|
4819
|
-
}
|
|
4820
|
-
if (videoSample.format === "av01") {
|
|
4821
|
-
return "av1";
|
|
4822
|
-
}
|
|
4823
|
-
if (videoSample.format === "ap4h") {
|
|
4824
|
-
return "prores";
|
|
4825
|
-
}
|
|
4826
|
-
if (videoSample.format === "ap4x") {
|
|
4827
|
-
return "prores";
|
|
4828
|
-
}
|
|
4829
|
-
if (videoSample.format === "apch") {
|
|
4830
|
-
return "prores";
|
|
4831
|
-
}
|
|
4832
|
-
if (videoSample.format === "apcn") {
|
|
4833
|
-
return "prores";
|
|
4834
|
-
}
|
|
4835
|
-
if (videoSample.format === "apcs") {
|
|
4836
|
-
return "prores";
|
|
4837
|
-
}
|
|
4838
|
-
if (videoSample.format === "apco") {
|
|
4839
|
-
return "prores";
|
|
4840
|
-
}
|
|
4841
|
-
if (videoSample.format === "aprh") {
|
|
4842
|
-
return "prores";
|
|
4843
|
-
}
|
|
4844
|
-
if (videoSample.format === "aprn") {
|
|
4845
|
-
return "prores";
|
|
4846
|
-
}
|
|
4847
|
-
}
|
|
4848
|
-
}
|
|
4849
|
-
throw new Error("Could not find video codec");
|
|
4850
|
-
};
|
|
4851
|
-
var getVideoCodecFromMatroska = (boxes) => {
|
|
4852
|
-
const mainSegment = boxes.find((b) => b.type === "Segment");
|
|
4853
|
-
if (!mainSegment || mainSegment.type !== "Segment") {
|
|
4854
|
-
return null;
|
|
4855
|
-
}
|
|
4856
|
-
const tracksSegment = mainSegment.value.find((b) => b.type === "Tracks");
|
|
4857
|
-
if (!tracksSegment || tracksSegment.type !== "Tracks") {
|
|
4858
|
-
return null;
|
|
4859
|
-
}
|
|
4860
|
-
for (const track of tracksSegment.value) {
|
|
4861
|
-
if (track.type === "TrackEntry") {
|
|
4862
|
-
const trackType2 = track.value.find((b) => b.type === "CodecID");
|
|
4863
|
-
if (trackType2 && trackType2.type === "CodecID") {
|
|
4864
|
-
if (trackType2.value === "V_VP8") {
|
|
4865
|
-
return "vp8";
|
|
4866
|
-
}
|
|
4867
|
-
if (trackType2.value === "V_VP9") {
|
|
4868
|
-
return "vp9";
|
|
4869
|
-
}
|
|
4870
|
-
if (trackType2.value === "V_AV1") {
|
|
4871
|
-
return "av1";
|
|
4872
|
-
}
|
|
4873
|
-
if (trackType2.value === "V_MPEG4/ISO/AVC") {
|
|
4874
|
-
return "h264";
|
|
4875
|
-
}
|
|
4876
|
-
if (trackType2.value === "V_MPEGH/ISO/HEVC") {
|
|
4877
|
-
return "h265";
|
|
4878
|
-
}
|
|
4879
|
-
}
|
|
4880
|
-
}
|
|
4881
|
-
}
|
|
4882
|
-
throw new Error("Could not find video codec");
|
|
4883
|
-
};
|
|
4884
|
-
var getVideoCodecFromAvi = (structure) => {
|
|
4885
|
-
const strl = getStrlBoxes(structure);
|
|
4886
|
-
for (const s of strl) {
|
|
4887
|
-
const strh = getStrhBox(s.children);
|
|
4888
|
-
if (!strh) {
|
|
4889
|
-
throw new Error("No strh box");
|
|
4890
|
-
}
|
|
4891
|
-
if (strh.fccType === "auds") {
|
|
4892
|
-
continue;
|
|
4893
|
-
}
|
|
4894
|
-
if (strh.handler === "H264") {
|
|
4895
|
-
return "h264";
|
|
4896
|
-
}
|
|
4897
|
-
}
|
|
4898
|
-
throw new Error("Unsupported codec");
|
|
4899
|
-
};
|
|
4900
|
-
var getVideoCodec = (boxes) => {
|
|
4901
|
-
if (boxes.type === "iso-base-media") {
|
|
4902
|
-
const moovBox = getMoovBox(boxes.boxes);
|
|
4903
|
-
if (moovBox) {
|
|
4904
|
-
const trakBox = getTraks(moovBox).filter((t) => trakBoxContainsVideo(t))[0];
|
|
4905
|
-
if (trakBox) {
|
|
4906
|
-
return getVideoCodecFromIsoTrak(trakBox);
|
|
4907
|
-
}
|
|
4908
|
-
}
|
|
4909
|
-
}
|
|
4910
|
-
if (boxes.type === "riff") {
|
|
4911
|
-
return getVideoCodecFromAvi(boxes);
|
|
4912
|
-
}
|
|
4913
|
-
if (boxes.type === "matroska") {
|
|
4914
|
-
return getVideoCodecFromMatroska(boxes.boxes);
|
|
4915
|
-
}
|
|
4916
|
-
return null;
|
|
4911
|
+
var getVideoCodec = (boxes, state) => {
|
|
4912
|
+
const track = getTracks(boxes, state);
|
|
4913
|
+
return track.videoTracks[0]?.codecWithoutConfig ?? null;
|
|
4917
4914
|
};
|
|
4918
4915
|
var hasVideoCodec = (boxes, state) => {
|
|
4919
4916
|
return hasTracks(boxes, state);
|
|
@@ -4951,9 +4948,9 @@ var getIsoBmColrConfig = (trakBox) => {
|
|
|
4951
4948
|
}
|
|
4952
4949
|
return {
|
|
4953
4950
|
fullRange: colrAtom.fullRangeFlag,
|
|
4954
|
-
matrixCoefficients: colrAtom.matrixIndex
|
|
4955
|
-
primaries: colrAtom.primaries
|
|
4956
|
-
transferCharacteristics: colrAtom.transfer
|
|
4951
|
+
matrixCoefficients: getMatrixCoefficientsFromIndex(colrAtom.matrixIndex),
|
|
4952
|
+
primaries: getPrimariesFromIndex(colrAtom.primaries),
|
|
4953
|
+
transferCharacteristics: getTransferCharacteristicsFromIndex(colrAtom.transfer)
|
|
4957
4954
|
};
|
|
4958
4955
|
};
|
|
4959
4956
|
var getVideoCodecString = (trakBox) => {
|
|
@@ -4998,6 +4995,50 @@ var getActualDecoderParameters = ({
|
|
|
4998
4995
|
};
|
|
4999
4996
|
};
|
|
5000
4997
|
|
|
4998
|
+
// src/boxes/iso-base-media/get-video-codec-from-iso-track.ts
|
|
4999
|
+
var getVideoCodecFromIsoTrak = (trakBox) => {
|
|
5000
|
+
const stsdBox = getStsdBox(trakBox);
|
|
5001
|
+
if (stsdBox && stsdBox.type === "stsd-box") {
|
|
5002
|
+
const videoSample = stsdBox.samples.find((s) => s.type === "video");
|
|
5003
|
+
if (videoSample && videoSample.type === "video") {
|
|
5004
|
+
if (videoSample.format === "hvc1") {
|
|
5005
|
+
return "h265";
|
|
5006
|
+
}
|
|
5007
|
+
if (videoSample.format === "avc1") {
|
|
5008
|
+
return "h264";
|
|
5009
|
+
}
|
|
5010
|
+
if (videoSample.format === "av01") {
|
|
5011
|
+
return "av1";
|
|
5012
|
+
}
|
|
5013
|
+
if (videoSample.format === "ap4h") {
|
|
5014
|
+
return "prores";
|
|
5015
|
+
}
|
|
5016
|
+
if (videoSample.format === "ap4x") {
|
|
5017
|
+
return "prores";
|
|
5018
|
+
}
|
|
5019
|
+
if (videoSample.format === "apch") {
|
|
5020
|
+
return "prores";
|
|
5021
|
+
}
|
|
5022
|
+
if (videoSample.format === "apcn") {
|
|
5023
|
+
return "prores";
|
|
5024
|
+
}
|
|
5025
|
+
if (videoSample.format === "apcs") {
|
|
5026
|
+
return "prores";
|
|
5027
|
+
}
|
|
5028
|
+
if (videoSample.format === "apco") {
|
|
5029
|
+
return "prores";
|
|
5030
|
+
}
|
|
5031
|
+
if (videoSample.format === "aprh") {
|
|
5032
|
+
return "prores";
|
|
5033
|
+
}
|
|
5034
|
+
if (videoSample.format === "aprn") {
|
|
5035
|
+
return "prores";
|
|
5036
|
+
}
|
|
5037
|
+
}
|
|
5038
|
+
}
|
|
5039
|
+
throw new Error("Could not find video codec");
|
|
5040
|
+
};
|
|
5041
|
+
|
|
5001
5042
|
// src/boxes/iso-base-media/make-track.ts
|
|
5002
5043
|
var makeBaseMediaTrack = (trakBox) => {
|
|
5003
5044
|
const tkhdBox = getTkhdBox(trakBox);
|
|
@@ -5095,6 +5136,30 @@ var makeBaseMediaTrack = (trakBox) => {
|
|
|
5095
5136
|
return track;
|
|
5096
5137
|
};
|
|
5097
5138
|
|
|
5139
|
+
// src/boxes/avc/codec-private.ts
|
|
5140
|
+
var getAvccBoxContent = (avc1Profile) => {
|
|
5141
|
+
return combineUint8Arrays([
|
|
5142
|
+
new Uint8Array([
|
|
5143
|
+
1,
|
|
5144
|
+
avc1Profile.sps.spsData.level,
|
|
5145
|
+
avc1Profile.sps.spsData.compatibility,
|
|
5146
|
+
avc1Profile.sps.spsData.profile,
|
|
5147
|
+
255,
|
|
5148
|
+
225
|
|
5149
|
+
]),
|
|
5150
|
+
serializeUint16(avc1Profile.sps.sps.length),
|
|
5151
|
+
avc1Profile.sps.sps,
|
|
5152
|
+
new Uint8Array([1]),
|
|
5153
|
+
serializeUint16(avc1Profile.pps.pps.length),
|
|
5154
|
+
avc1Profile.pps.pps
|
|
5155
|
+
]);
|
|
5156
|
+
};
|
|
5157
|
+
|
|
5158
|
+
// src/boxes/avc/codec-string.ts
|
|
5159
|
+
var getCodecStringFromSpsAndPps = (sps) => {
|
|
5160
|
+
return `avc1.${sps.spsData.profile.toString(16).padStart(2, "0")}${sps.spsData.compatibility.toString(16).padStart(2, "0")}${sps.spsData.level.toString(16).padStart(2, "0")}`;
|
|
5161
|
+
};
|
|
5162
|
+
|
|
5098
5163
|
// src/add-avc-profile-to-track.ts
|
|
5099
5164
|
var addAvcProfileToTrack = (track, avc1Profile) => {
|
|
5100
5165
|
if (avc1Profile === null) {
|
|
@@ -5102,22 +5167,8 @@ var addAvcProfileToTrack = (track, avc1Profile) => {
|
|
|
5102
5167
|
}
|
|
5103
5168
|
return {
|
|
5104
5169
|
...track,
|
|
5105
|
-
codec:
|
|
5106
|
-
codecPrivate:
|
|
5107
|
-
new Uint8Array([
|
|
5108
|
-
1,
|
|
5109
|
-
avc1Profile.sps.level,
|
|
5110
|
-
avc1Profile.sps.compatibility,
|
|
5111
|
-
avc1Profile.sps.profile,
|
|
5112
|
-
255,
|
|
5113
|
-
225
|
|
5114
|
-
]),
|
|
5115
|
-
serializeUint16(avc1Profile.sps.sps.length),
|
|
5116
|
-
avc1Profile.sps.sps,
|
|
5117
|
-
new Uint8Array([1]),
|
|
5118
|
-
serializeUint16(avc1Profile.pps.pps.length),
|
|
5119
|
-
avc1Profile.pps.pps
|
|
5120
|
-
])
|
|
5170
|
+
codec: getCodecStringFromSpsAndPps(avc1Profile.sps),
|
|
5171
|
+
codecPrivate: getAvccBoxContent(avc1Profile)
|
|
5121
5172
|
};
|
|
5122
5173
|
};
|
|
5123
5174
|
|
|
@@ -5229,6 +5280,57 @@ var hasAllTracksFromAvi = (structure, state) => {
|
|
|
5229
5280
|
}
|
|
5230
5281
|
};
|
|
5231
5282
|
|
|
5283
|
+
// src/boxes/transport-stream/traversal.ts
|
|
5284
|
+
var findProgramAssociationTableOrThrow = (structure) => {
|
|
5285
|
+
const box = structure.boxes.find((b) => b.type === "transport-stream-pat-box");
|
|
5286
|
+
if (!box) {
|
|
5287
|
+
throw new Error("No PAT box found");
|
|
5288
|
+
}
|
|
5289
|
+
return box;
|
|
5290
|
+
};
|
|
5291
|
+
var findProgramMapTableOrThrow = (structure) => {
|
|
5292
|
+
const box = structure.boxes.find((b) => b.type === "transport-stream-pmt-box");
|
|
5293
|
+
if (!box) {
|
|
5294
|
+
throw new Error("No PMT box found");
|
|
5295
|
+
}
|
|
5296
|
+
return box;
|
|
5297
|
+
};
|
|
5298
|
+
var getProgramForId = (structure, packetIdentifier) => {
|
|
5299
|
+
const box = findProgramAssociationTableOrThrow(structure);
|
|
5300
|
+
const entry = box.pat.find((e) => e.programMapIdentifier === packetIdentifier);
|
|
5301
|
+
return entry ?? null;
|
|
5302
|
+
};
|
|
5303
|
+
var getStreamForId = (structure, packetIdentifier) => {
|
|
5304
|
+
const box = findProgramMapTableOrThrow(structure);
|
|
5305
|
+
const entry = box.streams.find((e) => e.pid === packetIdentifier);
|
|
5306
|
+
return entry ?? null;
|
|
5307
|
+
};
|
|
5308
|
+
|
|
5309
|
+
// src/boxes/transport-stream/get-tracks.ts
|
|
5310
|
+
var getTracksFromTransportStream = (structure, parserState) => {
|
|
5311
|
+
const programMapTable = findProgramMapTableOrThrow(structure);
|
|
5312
|
+
const parserTracks = parserState.tracks.getTracks();
|
|
5313
|
+
const mapped = programMapTable.streams.map((stream) => {
|
|
5314
|
+
return parserTracks.find((track) => track.trackId === stream.pid);
|
|
5315
|
+
}).filter(truthy);
|
|
5316
|
+
if (mapped.length !== programMapTable.streams.length) {
|
|
5317
|
+
throw new Error("Not all tracks found");
|
|
5318
|
+
}
|
|
5319
|
+
return {
|
|
5320
|
+
videoTracks: mapped.filter((track) => track.type === "video"),
|
|
5321
|
+
audioTracks: mapped.filter((track) => track.type === "audio"),
|
|
5322
|
+
otherTracks: []
|
|
5323
|
+
};
|
|
5324
|
+
};
|
|
5325
|
+
var hasAllTracksFromTransportStream = (structure, parserState) => {
|
|
5326
|
+
try {
|
|
5327
|
+
getTracksFromTransportStream(structure, parserState);
|
|
5328
|
+
return true;
|
|
5329
|
+
} catch {
|
|
5330
|
+
return false;
|
|
5331
|
+
}
|
|
5332
|
+
};
|
|
5333
|
+
|
|
5232
5334
|
// src/make-hvc1-codec-strings.ts
|
|
5233
5335
|
var getHvc1CodecString = (data) => {
|
|
5234
5336
|
const configurationVersion = data.getUint8();
|
|
@@ -5629,7 +5731,10 @@ var hasTracks = (structure, state) => {
|
|
|
5629
5731
|
if (structure.type === "riff") {
|
|
5630
5732
|
return hasAllTracksFromAvi(structure, state);
|
|
5631
5733
|
}
|
|
5632
|
-
|
|
5734
|
+
if (structure.type === "transport-stream") {
|
|
5735
|
+
return hasAllTracksFromTransportStream(structure, state);
|
|
5736
|
+
}
|
|
5737
|
+
throw new Error("Unknown container " + structure);
|
|
5633
5738
|
};
|
|
5634
5739
|
var getTracksFromMa = (segments, state) => {
|
|
5635
5740
|
const videoTracks = [];
|
|
@@ -5697,7 +5802,10 @@ var getTracks = (segments, state) => {
|
|
|
5697
5802
|
if (segments.type === "riff") {
|
|
5698
5803
|
return getTracksFromAvi(segments, state);
|
|
5699
5804
|
}
|
|
5700
|
-
|
|
5805
|
+
if (segments.type === "transport-stream") {
|
|
5806
|
+
return getTracksFromTransportStream(segments, state);
|
|
5807
|
+
}
|
|
5808
|
+
throw new Error(`Unknown container${segments}`);
|
|
5701
5809
|
};
|
|
5702
5810
|
|
|
5703
5811
|
// src/get-container.ts
|
|
@@ -5708,6 +5816,9 @@ var getContainer = (segments) => {
|
|
|
5708
5816
|
if (segments.type === "matroska") {
|
|
5709
5817
|
return "webm";
|
|
5710
5818
|
}
|
|
5819
|
+
if (segments.type === "transport-stream") {
|
|
5820
|
+
return "transport-stream";
|
|
5821
|
+
}
|
|
5711
5822
|
if (segments.type === "riff") {
|
|
5712
5823
|
if (isRiffAvi(segments)) {
|
|
5713
5824
|
return "avi";
|
|
@@ -6036,7 +6147,10 @@ var getDuration = (structure, parserState) => {
|
|
|
6036
6147
|
if (structure.type === "riff") {
|
|
6037
6148
|
return getDurationFromAvi(structure);
|
|
6038
6149
|
}
|
|
6039
|
-
|
|
6150
|
+
if (structure.type === "transport-stream") {
|
|
6151
|
+
return null;
|
|
6152
|
+
}
|
|
6153
|
+
throw new Error("Has no duration " + structure);
|
|
6040
6154
|
};
|
|
6041
6155
|
var hasDuration = (structure, parserState) => {
|
|
6042
6156
|
return hasTracks(structure, parserState);
|
|
@@ -6124,7 +6238,7 @@ var emitAvailableInfo = ({
|
|
|
6124
6238
|
}
|
|
6125
6239
|
if (key === "videoCodec") {
|
|
6126
6240
|
if (returnValue.videoCodec === undefined && hasInfo.videoCodec && parseResult) {
|
|
6127
|
-
const videoCodec = getVideoCodec(parseResult.segments);
|
|
6241
|
+
const videoCodec = getVideoCodec(parseResult.segments, state);
|
|
6128
6242
|
moreFields.onVideoCodec?.(videoCodec);
|
|
6129
6243
|
returnValue.videoCodec = videoCodec;
|
|
6130
6244
|
}
|
|
@@ -6260,29 +6374,35 @@ var hasAllInfo = ({
|
|
|
6260
6374
|
|
|
6261
6375
|
// src/register-track.ts
|
|
6262
6376
|
var registerTrack = async ({
|
|
6263
|
-
state,
|
|
6264
6377
|
options,
|
|
6265
|
-
track
|
|
6378
|
+
track,
|
|
6379
|
+
container
|
|
6266
6380
|
}) => {
|
|
6267
|
-
if (track.type === "video"
|
|
6268
|
-
|
|
6269
|
-
|
|
6381
|
+
if (track.type === "video") {
|
|
6382
|
+
options.parserState.tracks.addTrack(track);
|
|
6383
|
+
if (options.onVideoTrack) {
|
|
6384
|
+
const callback = await options.onVideoTrack({ track, container });
|
|
6385
|
+
await options.parserState.registerVideoSampleCallback(track.trackId, callback ?? null);
|
|
6386
|
+
}
|
|
6270
6387
|
}
|
|
6271
|
-
if (track.type === "audio"
|
|
6272
|
-
|
|
6273
|
-
|
|
6388
|
+
if (track.type === "audio") {
|
|
6389
|
+
options.parserState.tracks.addTrack(track);
|
|
6390
|
+
if (options.onAudioTrack) {
|
|
6391
|
+
const callback = await options.onAudioTrack({ track, container });
|
|
6392
|
+
await options.parserState.registerAudioSampleCallback(track.trackId, callback ?? null);
|
|
6393
|
+
}
|
|
6274
6394
|
}
|
|
6275
6395
|
};
|
|
6276
6396
|
var registerVideoTrackWhenProfileIsAvailable = ({
|
|
6277
6397
|
options,
|
|
6278
|
-
|
|
6279
|
-
|
|
6398
|
+
track,
|
|
6399
|
+
container
|
|
6280
6400
|
}) => {
|
|
6281
|
-
|
|
6401
|
+
options.parserState.registerOnAvcProfileCallback(async (profile) => {
|
|
6282
6402
|
await registerTrack({
|
|
6283
6403
|
options,
|
|
6284
|
-
|
|
6285
|
-
|
|
6404
|
+
track: addAvcProfileToTrack(track, profile),
|
|
6405
|
+
container
|
|
6286
6406
|
});
|
|
6287
6407
|
});
|
|
6288
6408
|
};
|
|
@@ -6445,6 +6565,20 @@ var parseFtyp = ({
|
|
|
6445
6565
|
};
|
|
6446
6566
|
};
|
|
6447
6567
|
|
|
6568
|
+
// src/convert-audio-or-video-sample.ts
|
|
6569
|
+
var convertAudioOrVideoSampleToWebCodecsTimestamps = (sample, timescale2) => {
|
|
6570
|
+
const { cts, dts, timestamp } = sample;
|
|
6571
|
+
return {
|
|
6572
|
+
cts: cts * 1e6 / timescale2,
|
|
6573
|
+
dts: dts * 1e6 / timescale2,
|
|
6574
|
+
timestamp: timestamp * 1e6 / timescale2,
|
|
6575
|
+
duration: (sample.duration ?? 0) * 1e6 / timescale2,
|
|
6576
|
+
data: sample.data,
|
|
6577
|
+
trackId: sample.trackId,
|
|
6578
|
+
type: sample.type
|
|
6579
|
+
};
|
|
6580
|
+
};
|
|
6581
|
+
|
|
6448
6582
|
// src/boxes/iso-base-media/mdat/mdat.ts
|
|
6449
6583
|
var parseMdat = async ({
|
|
6450
6584
|
data,
|
|
@@ -6518,31 +6652,28 @@ var parseMdat = async ({
|
|
|
6518
6652
|
break;
|
|
6519
6653
|
}
|
|
6520
6654
|
const bytes = data.getSlice(samplesWithIndex.samplePosition.size);
|
|
6521
|
-
const
|
|
6522
|
-
const duration2 = samplesWithIndex.samplePosition.duration * 1e6 / samplesWithIndex.track.timescale;
|
|
6523
|
-
const cts = samplesWithIndex.samplePosition.cts * 1e6 / samplesWithIndex.track.timescale;
|
|
6524
|
-
const dts = samplesWithIndex.samplePosition.dts * 1e6 / samplesWithIndex.track.timescale;
|
|
6655
|
+
const { cts, dts, duration: duration2 } = samplesWithIndex.samplePosition;
|
|
6525
6656
|
if (samplesWithIndex.track.type === "audio") {
|
|
6526
|
-
await options.parserState.onAudioSample(samplesWithIndex.track.trackId, {
|
|
6657
|
+
await options.parserState.onAudioSample(samplesWithIndex.track.trackId, convertAudioOrVideoSampleToWebCodecsTimestamps({
|
|
6527
6658
|
data: bytes,
|
|
6528
|
-
timestamp,
|
|
6659
|
+
timestamp: cts,
|
|
6529
6660
|
duration: duration2,
|
|
6530
6661
|
cts,
|
|
6531
6662
|
dts,
|
|
6532
6663
|
trackId: samplesWithIndex.track.trackId,
|
|
6533
6664
|
type: samplesWithIndex.samplePosition.isKeyframe ? "key" : "delta"
|
|
6534
|
-
});
|
|
6665
|
+
}, samplesWithIndex.track.timescale));
|
|
6535
6666
|
}
|
|
6536
6667
|
if (samplesWithIndex.track.type === "video") {
|
|
6537
|
-
await options.parserState.onVideoSample(samplesWithIndex.track.trackId, {
|
|
6668
|
+
await options.parserState.onVideoSample(samplesWithIndex.track.trackId, convertAudioOrVideoSampleToWebCodecsTimestamps({
|
|
6538
6669
|
data: bytes,
|
|
6539
|
-
timestamp,
|
|
6670
|
+
timestamp: cts,
|
|
6540
6671
|
duration: duration2,
|
|
6541
6672
|
cts,
|
|
6542
6673
|
dts,
|
|
6543
6674
|
trackId: samplesWithIndex.track.trackId,
|
|
6544
6675
|
type: samplesWithIndex.samplePosition.isKeyframe ? "key" : "delta"
|
|
6545
|
-
});
|
|
6676
|
+
}, samplesWithIndex.track.timescale));
|
|
6546
6677
|
}
|
|
6547
6678
|
const remaining = size - (data.counter.getOffset() - fileOffset);
|
|
6548
6679
|
data.removeBytesRead();
|
|
@@ -8230,8 +8361,8 @@ var processBox = async ({
|
|
|
8230
8361
|
if (transformedTrack) {
|
|
8231
8362
|
await registerTrack({
|
|
8232
8363
|
options,
|
|
8233
|
-
|
|
8234
|
-
|
|
8364
|
+
track: transformedTrack,
|
|
8365
|
+
container: "mp4"
|
|
8235
8366
|
});
|
|
8236
8367
|
}
|
|
8237
8368
|
return {
|
|
@@ -8554,15 +8685,164 @@ var isMoviAtom = (iterator, ckId) => {
|
|
|
8554
8685
|
return listType === "movi";
|
|
8555
8686
|
};
|
|
8556
8687
|
|
|
8688
|
+
// src/boxes/avc/key.ts
|
|
8689
|
+
var getKeyFrameOrDeltaFromAvcInfo = (infos) => {
|
|
8690
|
+
const keyOrDelta = infos.find((i) => i.type === "keyframe" || i.type === "delta-frame");
|
|
8691
|
+
if (!keyOrDelta) {
|
|
8692
|
+
throw new Error("expected avc to contain info about key or delta");
|
|
8693
|
+
}
|
|
8694
|
+
return keyOrDelta.type === "keyframe" ? "key" : "delta";
|
|
8695
|
+
};
|
|
8696
|
+
|
|
8557
8697
|
// src/boxes/avc/parse-avc.ts
|
|
8698
|
+
var Extended_SAR = 255;
|
|
8699
|
+
var readVuiParameters = (iterator) => {
|
|
8700
|
+
let sar_width = null;
|
|
8701
|
+
let sar_height = null;
|
|
8702
|
+
let overscan_appropriate_flag = null;
|
|
8703
|
+
let video_format = null;
|
|
8704
|
+
let video_full_range_flag = null;
|
|
8705
|
+
let colour_primaries = null;
|
|
8706
|
+
let transfer_characteristics = null;
|
|
8707
|
+
let matrix_coefficients = null;
|
|
8708
|
+
let chroma_sample_loc_type_top_field = null;
|
|
8709
|
+
let chroma_sample_loc_type_bottom_field = null;
|
|
8710
|
+
const aspect_ratio_info_present_flag = iterator.getBits(1);
|
|
8711
|
+
if (aspect_ratio_info_present_flag) {
|
|
8712
|
+
const aspect_ratio_idc = iterator.getBits(8);
|
|
8713
|
+
if (aspect_ratio_idc === Extended_SAR) {
|
|
8714
|
+
sar_width = iterator.getBits(16);
|
|
8715
|
+
sar_height = iterator.getBits(16);
|
|
8716
|
+
}
|
|
8717
|
+
}
|
|
8718
|
+
const overscan_info_present_flag = iterator.getBits(1);
|
|
8719
|
+
if (overscan_info_present_flag) {
|
|
8720
|
+
overscan_appropriate_flag = iterator.getBits(1);
|
|
8721
|
+
}
|
|
8722
|
+
const video_signal_type_present_flag = iterator.getBits(1);
|
|
8723
|
+
if (video_signal_type_present_flag) {
|
|
8724
|
+
video_format = iterator.getBits(3);
|
|
8725
|
+
video_full_range_flag = Boolean(iterator.getBits(1));
|
|
8726
|
+
const colour_description_present_flag = iterator.getBits(1);
|
|
8727
|
+
if (colour_description_present_flag) {
|
|
8728
|
+
colour_primaries = iterator.getBits(8);
|
|
8729
|
+
transfer_characteristics = iterator.getBits(8);
|
|
8730
|
+
matrix_coefficients = iterator.getBits(8);
|
|
8731
|
+
}
|
|
8732
|
+
}
|
|
8733
|
+
const chroma_loc_info_present_flag = iterator.getBits(1);
|
|
8734
|
+
if (chroma_loc_info_present_flag) {
|
|
8735
|
+
chroma_sample_loc_type_top_field = iterator.readExpGolomb();
|
|
8736
|
+
chroma_sample_loc_type_bottom_field = iterator.readExpGolomb();
|
|
8737
|
+
}
|
|
8738
|
+
return {
|
|
8739
|
+
sar_width,
|
|
8740
|
+
sar_height,
|
|
8741
|
+
overscan_appropriate_flag,
|
|
8742
|
+
chroma_sample_loc_type_bottom_field,
|
|
8743
|
+
chroma_sample_loc_type_top_field,
|
|
8744
|
+
colour_primaries,
|
|
8745
|
+
matrix_coefficients,
|
|
8746
|
+
transfer_characteristics,
|
|
8747
|
+
video_format,
|
|
8748
|
+
video_full_range_flag
|
|
8749
|
+
};
|
|
8750
|
+
};
|
|
8558
8751
|
var readSps = (iterator) => {
|
|
8559
8752
|
const profile = iterator.getUint8();
|
|
8560
8753
|
const compatibility = iterator.getUint8();
|
|
8561
8754
|
const level = iterator.getUint8();
|
|
8755
|
+
iterator.startReadingBits();
|
|
8756
|
+
const seq_parameter_set_id = iterator.readExpGolomb();
|
|
8757
|
+
let separate_colour_plane_flag = null;
|
|
8758
|
+
let bit_depth_luma_minus8 = null;
|
|
8759
|
+
let bit_depth_chroma_minus8 = null;
|
|
8760
|
+
let qpprime_y_zero_transform_bypass_flag = null;
|
|
8761
|
+
let log2_max_frame_num_minus4 = null;
|
|
8762
|
+
let log2_max_pic_order_cnt_lsb_minus4 = null;
|
|
8763
|
+
let max_num_ref_frames = null;
|
|
8764
|
+
let gaps_in_frame_num_value_allowed_flag = null;
|
|
8765
|
+
let mb_adaptive_frame_field_flag = null;
|
|
8766
|
+
let direct_8x8_inference_flag = null;
|
|
8767
|
+
let frame_crop_left_offset = null;
|
|
8768
|
+
let frame_crop_right_offset = null;
|
|
8769
|
+
let frame_crop_top_offset = null;
|
|
8770
|
+
let frame_crop_bottom_offset = null;
|
|
8771
|
+
let vui_parameters = null;
|
|
8772
|
+
if (!(profile === 100 || profile === 110 || profile === 122 || profile === 244 || profile === 44 || profile === 83 || profile === 86 || profile === 118 || profile === 128 || profile === 138 || profile === 139 || profile === 134 || profile === 135)) {
|
|
8773
|
+
throw new Error("Invalid profile");
|
|
8774
|
+
}
|
|
8775
|
+
const chromaFormat = iterator.readExpGolomb();
|
|
8776
|
+
if (chromaFormat === 3) {
|
|
8777
|
+
separate_colour_plane_flag = iterator.getBits(1);
|
|
8778
|
+
}
|
|
8779
|
+
bit_depth_luma_minus8 = iterator.readExpGolomb();
|
|
8780
|
+
bit_depth_chroma_minus8 = iterator.readExpGolomb();
|
|
8781
|
+
qpprime_y_zero_transform_bypass_flag = iterator.getBits(1);
|
|
8782
|
+
const seq_scaling_matrix_present_flag = iterator.getBits(1);
|
|
8783
|
+
const seq_scaling_list_present_flag = [];
|
|
8784
|
+
if (seq_scaling_matrix_present_flag) {
|
|
8785
|
+
for (let i = 0;i < (chromaFormat !== 3 ? 8 : 12); i++) {
|
|
8786
|
+
seq_scaling_list_present_flag[i] = iterator.getBits(1);
|
|
8787
|
+
if (seq_scaling_list_present_flag[i]) {
|
|
8788
|
+
if (i < 6) {
|
|
8789
|
+
throw new Error("Not implemented");
|
|
8790
|
+
} else {
|
|
8791
|
+
throw new Error("Not implemented");
|
|
8792
|
+
}
|
|
8793
|
+
}
|
|
8794
|
+
}
|
|
8795
|
+
}
|
|
8796
|
+
log2_max_frame_num_minus4 = iterator.readExpGolomb();
|
|
8797
|
+
const pic_order_cnt_type = iterator.readExpGolomb();
|
|
8798
|
+
if (pic_order_cnt_type === 0) {
|
|
8799
|
+
log2_max_pic_order_cnt_lsb_minus4 = iterator.readExpGolomb();
|
|
8800
|
+
} else if (pic_order_cnt_type === 1) {
|
|
8801
|
+
throw new Error("pic_order_cnt_type = 1 not implemented");
|
|
8802
|
+
}
|
|
8803
|
+
max_num_ref_frames = iterator.readExpGolomb();
|
|
8804
|
+
gaps_in_frame_num_value_allowed_flag = iterator.getBits(1);
|
|
8805
|
+
const pic_width_in_mbs_minus1 = iterator.readExpGolomb();
|
|
8806
|
+
const pic_height_in_map_units_minus1 = iterator.readExpGolomb();
|
|
8807
|
+
const frame_mbs_only_flag = iterator.getBits(1);
|
|
8808
|
+
if (!frame_mbs_only_flag) {
|
|
8809
|
+
mb_adaptive_frame_field_flag = iterator.getBits(1);
|
|
8810
|
+
}
|
|
8811
|
+
direct_8x8_inference_flag = iterator.getBits(1);
|
|
8812
|
+
const frame_cropping_flag = iterator.getBits(1);
|
|
8813
|
+
if (frame_cropping_flag) {
|
|
8814
|
+
frame_crop_left_offset = iterator.readExpGolomb();
|
|
8815
|
+
frame_crop_right_offset = iterator.readExpGolomb();
|
|
8816
|
+
frame_crop_top_offset = iterator.readExpGolomb();
|
|
8817
|
+
frame_crop_bottom_offset = iterator.readExpGolomb();
|
|
8818
|
+
}
|
|
8819
|
+
const vui_parameters_present_flag = iterator.getBits(1);
|
|
8820
|
+
if (vui_parameters_present_flag) {
|
|
8821
|
+
vui_parameters = readVuiParameters(iterator);
|
|
8822
|
+
}
|
|
8823
|
+
iterator.stopReadingBits();
|
|
8562
8824
|
return {
|
|
8563
8825
|
profile,
|
|
8564
8826
|
compatibility,
|
|
8565
|
-
level
|
|
8827
|
+
level,
|
|
8828
|
+
bit_depth_chroma_minus8,
|
|
8829
|
+
bit_depth_luma_minus8,
|
|
8830
|
+
gaps_in_frame_num_value_allowed_flag,
|
|
8831
|
+
log2_max_frame_num_minus4,
|
|
8832
|
+
log2_max_pic_order_cnt_lsb_minus4,
|
|
8833
|
+
max_num_ref_frames,
|
|
8834
|
+
pic_height_in_map_units_minus1,
|
|
8835
|
+
pic_width_in_mbs_minus1,
|
|
8836
|
+
qpprime_y_zero_transform_bypass_flag,
|
|
8837
|
+
separate_colour_plane_flag,
|
|
8838
|
+
seq_parameter_set_id,
|
|
8839
|
+
direct_8x8_inference_flag,
|
|
8840
|
+
frame_crop_bottom_offset,
|
|
8841
|
+
frame_crop_left_offset,
|
|
8842
|
+
frame_crop_right_offset,
|
|
8843
|
+
frame_crop_top_offset,
|
|
8844
|
+
mb_adaptive_frame_field_flag,
|
|
8845
|
+
vui_parameters
|
|
8566
8846
|
};
|
|
8567
8847
|
};
|
|
8568
8848
|
var findEnd = (buffer) => {
|
|
@@ -8590,11 +8870,9 @@ var inspect = (buffer) => {
|
|
|
8590
8870
|
if (type === 7) {
|
|
8591
8871
|
const end = findEnd(buffer);
|
|
8592
8872
|
const data = readSps(iterator);
|
|
8593
|
-
const sps = buffer.slice(
|
|
8873
|
+
const sps = buffer.slice(0, end === null ? Infinity : end);
|
|
8594
8874
|
return {
|
|
8595
|
-
|
|
8596
|
-
profile: data.profile,
|
|
8597
|
-
compatibility: data.compatibility,
|
|
8875
|
+
spsData: data,
|
|
8598
8876
|
sps,
|
|
8599
8877
|
type: "avc-profile"
|
|
8600
8878
|
};
|
|
@@ -8673,29 +8951,26 @@ var handleChunk = async ({
|
|
|
8673
8951
|
const samplesPerSecond = strh.rate / strh.scale;
|
|
8674
8952
|
const nthSample = options.parserState.getSamplesForTrack(trackId);
|
|
8675
8953
|
const timeInSec = nthSample / samplesPerSecond;
|
|
8676
|
-
const timestamp = Math.floor(timeInSec
|
|
8677
|
-
const duration2 = Math.floor(1 / samplesPerSecond
|
|
8954
|
+
const timestamp = Math.floor(timeInSec);
|
|
8955
|
+
const duration2 = Math.floor(1 / samplesPerSecond);
|
|
8678
8956
|
const data = iterator.getSlice(ckSize);
|
|
8679
8957
|
const infos = parseAvc(data);
|
|
8680
|
-
const keyOrDelta = infos
|
|
8681
|
-
if (!keyOrDelta) {
|
|
8682
|
-
throw new Error("expected avc to contain info about key or delta");
|
|
8683
|
-
}
|
|
8958
|
+
const keyOrDelta = getKeyFrameOrDeltaFromAvcInfo(infos);
|
|
8684
8959
|
const avcProfile = infos.find((i) => i.type === "avc-profile");
|
|
8685
8960
|
const ppsProfile = infos.find((i) => i.type === "avc-pps");
|
|
8686
8961
|
if (avcProfile && ppsProfile) {
|
|
8687
8962
|
await options.parserState.onProfile({ pps: ppsProfile, sps: avcProfile });
|
|
8688
8963
|
options.parserState.tracks.setIsDone();
|
|
8689
8964
|
}
|
|
8690
|
-
await options.parserState.onVideoSample(trackId, {
|
|
8965
|
+
await options.parserState.onVideoSample(trackId, convertAudioOrVideoSampleToWebCodecsTimestamps({
|
|
8691
8966
|
cts: timestamp,
|
|
8692
8967
|
dts: timestamp,
|
|
8693
8968
|
data,
|
|
8694
8969
|
duration: duration2,
|
|
8695
8970
|
timestamp,
|
|
8696
8971
|
trackId,
|
|
8697
|
-
type: keyOrDelta
|
|
8698
|
-
});
|
|
8972
|
+
type: keyOrDelta
|
|
8973
|
+
}, 1));
|
|
8699
8974
|
return;
|
|
8700
8975
|
}
|
|
8701
8976
|
const audioChunk = ckId.match(/^([0-9]{2})wb$/);
|
|
@@ -8705,9 +8980,9 @@ var handleChunk = async ({
|
|
|
8705
8980
|
const samplesPerSecond = strh.rate / strh.scale;
|
|
8706
8981
|
const nthSample = options.parserState.getSamplesForTrack(trackId);
|
|
8707
8982
|
const timeInSec = nthSample / samplesPerSecond;
|
|
8708
|
-
const timestamp = timeInSec
|
|
8709
|
-
const duration2 = 1 / samplesPerSecond
|
|
8710
|
-
await options.parserState.onAudioSample(trackId, {
|
|
8983
|
+
const timestamp = timeInSec;
|
|
8984
|
+
const duration2 = 1 / samplesPerSecond;
|
|
8985
|
+
await options.parserState.onAudioSample(trackId, convertAudioOrVideoSampleToWebCodecsTimestamps({
|
|
8711
8986
|
cts: timestamp,
|
|
8712
8987
|
dts: timestamp,
|
|
8713
8988
|
data: iterator.getSlice(ckSize),
|
|
@@ -8715,7 +8990,7 @@ var handleChunk = async ({
|
|
|
8715
8990
|
timestamp,
|
|
8716
8991
|
trackId,
|
|
8717
8992
|
type: "key"
|
|
8718
|
-
});
|
|
8993
|
+
}, 1));
|
|
8719
8994
|
}
|
|
8720
8995
|
};
|
|
8721
8996
|
var parseMovi = async ({
|
|
@@ -9201,8 +9476,8 @@ var parseRiffBody = async ({
|
|
|
9201
9476
|
});
|
|
9202
9477
|
await registerTrack({
|
|
9203
9478
|
options,
|
|
9204
|
-
|
|
9205
|
-
|
|
9479
|
+
track: audioTrack,
|
|
9480
|
+
container: "avi"
|
|
9206
9481
|
});
|
|
9207
9482
|
}
|
|
9208
9483
|
if (options.onVideoTrack && strf.type === "strf-box-video") {
|
|
@@ -9213,8 +9488,8 @@ var parseRiffBody = async ({
|
|
|
9213
9488
|
});
|
|
9214
9489
|
registerVideoTrackWhenProfileIsAvailable({
|
|
9215
9490
|
options,
|
|
9216
|
-
|
|
9217
|
-
|
|
9491
|
+
track: videoTrack,
|
|
9492
|
+
container: "avi"
|
|
9218
9493
|
});
|
|
9219
9494
|
}
|
|
9220
9495
|
options.nextTrackIndex++;
|
|
@@ -9250,15 +9525,758 @@ var parseRiff = ({
|
|
|
9250
9525
|
return parseRiffBody({ iterator, structure, maxOffset: Infinity, options });
|
|
9251
9526
|
};
|
|
9252
9527
|
|
|
9253
|
-
// src/boxes/
|
|
9254
|
-
var
|
|
9255
|
-
|
|
9256
|
-
|
|
9257
|
-
|
|
9258
|
-
|
|
9259
|
-
|
|
9260
|
-
|
|
9261
|
-
|
|
9528
|
+
// src/boxes/transport-stream/next-pes-header-store.ts
|
|
9529
|
+
var makeNextPesHeaderStore = () => {
|
|
9530
|
+
let nextPesHeader = null;
|
|
9531
|
+
return {
|
|
9532
|
+
setNextPesHeader: (pesHeader) => {
|
|
9533
|
+
nextPesHeader = pesHeader;
|
|
9534
|
+
},
|
|
9535
|
+
getNextPesHeader: () => {
|
|
9536
|
+
if (!nextPesHeader) {
|
|
9537
|
+
throw new Error("No next PES header found");
|
|
9538
|
+
}
|
|
9539
|
+
return nextPesHeader;
|
|
9540
|
+
}
|
|
9541
|
+
};
|
|
9542
|
+
};
|
|
9543
|
+
|
|
9544
|
+
// src/boxes/transport-stream/discard-rest-of-packet.ts
|
|
9545
|
+
var discardRestOfPacket = (iterator) => {
|
|
9546
|
+
const next188 = 188 - iterator.counter.getOffset() % 188;
|
|
9547
|
+
iterator.discard(next188);
|
|
9548
|
+
};
|
|
9549
|
+
var getRestOfPacket = (iterator) => {
|
|
9550
|
+
const next188 = 188 - iterator.counter.getOffset() % 188;
|
|
9551
|
+
return iterator.getSlice(next188);
|
|
9552
|
+
};
|
|
9553
|
+
|
|
9554
|
+
// src/boxes/transport-stream/parse-pat.ts
|
|
9555
|
+
var parsePatTable = (iterator, tableId) => {
|
|
9556
|
+
iterator.getUint16();
|
|
9557
|
+
iterator.startReadingBits();
|
|
9558
|
+
iterator.getBits(7);
|
|
9559
|
+
iterator.getBits(1);
|
|
9560
|
+
const sectionNumber = iterator.getBits(8);
|
|
9561
|
+
const lastSectionNumber = iterator.getBits(8);
|
|
9562
|
+
if (tableId !== 0) {
|
|
9563
|
+
throw new Error("Invalid table ID: " + tableId);
|
|
9564
|
+
}
|
|
9565
|
+
const tables = [];
|
|
9566
|
+
for (let i = sectionNumber;i <= lastSectionNumber; i++) {
|
|
9567
|
+
const programNumber = iterator.getBits(16);
|
|
9568
|
+
iterator.getBits(3);
|
|
9569
|
+
const programMapIdentifier = iterator.getBits(13);
|
|
9570
|
+
tables.push({
|
|
9571
|
+
type: "transport-stream-program-association-table",
|
|
9572
|
+
programNumber,
|
|
9573
|
+
programMapIdentifier
|
|
9574
|
+
});
|
|
9575
|
+
}
|
|
9576
|
+
iterator.stopReadingBits();
|
|
9577
|
+
return {
|
|
9578
|
+
type: "transport-stream-pat-box",
|
|
9579
|
+
tableId: tableId.toString(16),
|
|
9580
|
+
pat: tables
|
|
9581
|
+
};
|
|
9582
|
+
};
|
|
9583
|
+
var parsePat = (iterator) => {
|
|
9584
|
+
iterator.startReadingBits();
|
|
9585
|
+
const tableId = iterator.getBits(8);
|
|
9586
|
+
iterator.getBits(1);
|
|
9587
|
+
iterator.getBits(1);
|
|
9588
|
+
iterator.getBits(4);
|
|
9589
|
+
const sectionLength = iterator.getBits(10);
|
|
9590
|
+
if (sectionLength > 1021) {
|
|
9591
|
+
throw new Error("Invalid section length");
|
|
9592
|
+
}
|
|
9593
|
+
iterator.stopReadingBits();
|
|
9594
|
+
const tables = parsePatTable(iterator, tableId);
|
|
9595
|
+
discardRestOfPacket(iterator);
|
|
9596
|
+
return tables;
|
|
9597
|
+
};
|
|
9598
|
+
|
|
9599
|
+
// src/boxes/transport-stream/parse-pes.ts
|
|
9600
|
+
var parsePes = (iterator) => {
|
|
9601
|
+
const ident = iterator.getUint24();
|
|
9602
|
+
if (ident !== 1) {
|
|
9603
|
+
throw new Error(`Unexpected PES packet start code: ${ident.toString(16)}`);
|
|
9604
|
+
}
|
|
9605
|
+
const streamId = iterator.getUint8();
|
|
9606
|
+
iterator.getUint16();
|
|
9607
|
+
iterator.startReadingBits();
|
|
9608
|
+
const markerBits = iterator.getBits(2);
|
|
9609
|
+
if (markerBits !== 2) {
|
|
9610
|
+
throw new Error(`Invalid marker bits: ${markerBits}`);
|
|
9611
|
+
}
|
|
9612
|
+
const scrambled = iterator.getBits(2);
|
|
9613
|
+
if (scrambled !== 0) {
|
|
9614
|
+
throw new Error(`Only supporting non-scrambled streams`);
|
|
9615
|
+
}
|
|
9616
|
+
const priority = iterator.getBits(1);
|
|
9617
|
+
iterator.getBits(1);
|
|
9618
|
+
iterator.getBits(1);
|
|
9619
|
+
iterator.getBits(1);
|
|
9620
|
+
const ptsPresent = iterator.getBits(1);
|
|
9621
|
+
const dtsPresent = iterator.getBits(1);
|
|
9622
|
+
if (!ptsPresent && dtsPresent) {
|
|
9623
|
+
throw new Error(`DTS is present but not PTS, this is not allowed in the spec`);
|
|
9624
|
+
}
|
|
9625
|
+
iterator.getBits(1);
|
|
9626
|
+
iterator.getBits(1);
|
|
9627
|
+
iterator.getBits(1);
|
|
9628
|
+
iterator.getBits(1);
|
|
9629
|
+
iterator.getBits(1);
|
|
9630
|
+
iterator.getBits(1);
|
|
9631
|
+
const pesHeaderLength = iterator.getBits(8);
|
|
9632
|
+
const offset = iterator.counter.getOffset();
|
|
9633
|
+
let pts = null;
|
|
9634
|
+
if (!ptsPresent) {
|
|
9635
|
+
throw new Error(`PTS is required`);
|
|
9636
|
+
}
|
|
9637
|
+
const fourBits = iterator.getBits(4);
|
|
9638
|
+
if (fourBits !== 3 && fourBits !== 2) {
|
|
9639
|
+
throw new Error(`Invalid PTS marker bits: ${fourBits}`);
|
|
9640
|
+
}
|
|
9641
|
+
const pts1 = iterator.getBits(3);
|
|
9642
|
+
iterator.getBits(1);
|
|
9643
|
+
const pts2 = iterator.getBits(15);
|
|
9644
|
+
iterator.getBits(1);
|
|
9645
|
+
const pts3 = iterator.getBits(15);
|
|
9646
|
+
iterator.getBits(1);
|
|
9647
|
+
pts = pts1 << 30 | pts2 << 15 | pts3;
|
|
9648
|
+
let dts = null;
|
|
9649
|
+
if (dtsPresent) {
|
|
9650
|
+
const _fourBits = iterator.getBits(4);
|
|
9651
|
+
if (_fourBits !== 1) {
|
|
9652
|
+
throw new Error(`Invalid DTS marker bits: ${_fourBits}`);
|
|
9653
|
+
}
|
|
9654
|
+
const dts1 = iterator.getBits(3);
|
|
9655
|
+
iterator.getBits(1);
|
|
9656
|
+
const dts2 = iterator.getBits(15);
|
|
9657
|
+
iterator.getBits(1);
|
|
9658
|
+
const dts3 = iterator.getBits(15);
|
|
9659
|
+
iterator.getBits(1);
|
|
9660
|
+
dts = dts1 << 30 | dts2 << 15 | dts3;
|
|
9661
|
+
}
|
|
9662
|
+
iterator.stopReadingBits();
|
|
9663
|
+
iterator.discard(pesHeaderLength - (iterator.counter.getOffset() - offset));
|
|
9664
|
+
const packet = {
|
|
9665
|
+
dts,
|
|
9666
|
+
pts,
|
|
9667
|
+
streamId,
|
|
9668
|
+
priority
|
|
9669
|
+
};
|
|
9670
|
+
return packet;
|
|
9671
|
+
};
|
|
9672
|
+
|
|
9673
|
+
// src/boxes/transport-stream/parse-pmt.ts
|
|
9674
|
+
var parsePmtTable = ({
|
|
9675
|
+
iterator,
|
|
9676
|
+
tableId,
|
|
9677
|
+
sectionLength
|
|
9678
|
+
}) => {
|
|
9679
|
+
const start = iterator.counter.getOffset();
|
|
9680
|
+
iterator.getUint16();
|
|
9681
|
+
iterator.startReadingBits();
|
|
9682
|
+
iterator.getBits(7);
|
|
9683
|
+
iterator.getBits(1);
|
|
9684
|
+
const sectionNumber = iterator.getBits(8);
|
|
9685
|
+
const lastSectionNumber = iterator.getBits(8);
|
|
9686
|
+
const tables = [];
|
|
9687
|
+
for (let i = sectionNumber;i <= lastSectionNumber; i++) {
|
|
9688
|
+
iterator.getBits(3);
|
|
9689
|
+
iterator.getBits(13);
|
|
9690
|
+
iterator.getBits(4);
|
|
9691
|
+
const programInfoLength = iterator.getBits(12);
|
|
9692
|
+
const streams = [];
|
|
9693
|
+
while (true) {
|
|
9694
|
+
const streamType = iterator.getBits(8);
|
|
9695
|
+
iterator.getBits(3);
|
|
9696
|
+
const elementaryPid = iterator.getBits(13);
|
|
9697
|
+
iterator.getBits(4);
|
|
9698
|
+
const esInfoLength = iterator.getBits(12);
|
|
9699
|
+
iterator.getBits(esInfoLength * 8);
|
|
9700
|
+
streams.push({ streamType, pid: elementaryPid });
|
|
9701
|
+
iterator.getBits(programInfoLength * 8);
|
|
9702
|
+
const remaining = sectionLength - (iterator.counter.getOffset() - start);
|
|
9703
|
+
if (remaining <= 4) {
|
|
9704
|
+
break;
|
|
9705
|
+
}
|
|
9706
|
+
}
|
|
9707
|
+
tables.push({
|
|
9708
|
+
type: "transport-stream-program-map-table",
|
|
9709
|
+
streams
|
|
9710
|
+
});
|
|
9711
|
+
}
|
|
9712
|
+
if (tables.length !== 1) {
|
|
9713
|
+
throw new Error("Does not PMT table with more than 1 entry, uncommon");
|
|
9714
|
+
}
|
|
9715
|
+
iterator.stopReadingBits();
|
|
9716
|
+
return {
|
|
9717
|
+
type: "transport-stream-pmt-box",
|
|
9718
|
+
tableId,
|
|
9719
|
+
streams: tables[0].streams
|
|
9720
|
+
};
|
|
9721
|
+
};
|
|
9722
|
+
var parsePmt = (iterator) => {
|
|
9723
|
+
iterator.startReadingBits();
|
|
9724
|
+
const tableId = iterator.getBits(8);
|
|
9725
|
+
iterator.getBits(1);
|
|
9726
|
+
iterator.getBits(1);
|
|
9727
|
+
iterator.getBits(4);
|
|
9728
|
+
const sectionLength = iterator.getBits(10);
|
|
9729
|
+
if (sectionLength > 1021) {
|
|
9730
|
+
throw new Error("Invalid section length");
|
|
9731
|
+
}
|
|
9732
|
+
iterator.stopReadingBits();
|
|
9733
|
+
const tables = parsePmtTable({ iterator, tableId, sectionLength });
|
|
9734
|
+
discardRestOfPacket(iterator);
|
|
9735
|
+
return tables;
|
|
9736
|
+
};
|
|
9737
|
+
|
|
9738
|
+
// src/boxes/transport-stream/adts-header.ts
|
|
9739
|
+
var readAdtsHeader = (buffer) => {
|
|
9740
|
+
if (buffer.byteLength < 9) {
|
|
9741
|
+
return null;
|
|
9742
|
+
}
|
|
9743
|
+
const iterator = getArrayBufferIterator(buffer, buffer.byteLength);
|
|
9744
|
+
iterator.startReadingBits();
|
|
9745
|
+
const bits = iterator.getBits(12);
|
|
9746
|
+
if (bits !== 4095) {
|
|
9747
|
+
throw new Error("Invalid ADTS header ");
|
|
9748
|
+
}
|
|
9749
|
+
const id = iterator.getBits(1);
|
|
9750
|
+
if (id !== 0) {
|
|
9751
|
+
throw new Error("Only supporting MPEG-4 for .ts");
|
|
9752
|
+
}
|
|
9753
|
+
const layer = iterator.getBits(2);
|
|
9754
|
+
if (layer !== 0) {
|
|
9755
|
+
throw new Error("Only supporting layer 0 for .ts");
|
|
9756
|
+
}
|
|
9757
|
+
const protectionAbsent = iterator.getBits(1);
|
|
9758
|
+
const audioObjectType = iterator.getBits(2);
|
|
9759
|
+
const samplingFrequencyIndex = iterator.getBits(4);
|
|
9760
|
+
const sampleRate = getSampleRateFromSampleFrequencyIndex(samplingFrequencyIndex);
|
|
9761
|
+
iterator.getBits(1);
|
|
9762
|
+
const channelConfiguration = iterator.getBits(3);
|
|
9763
|
+
const codecPrivate2 = createAacCodecPrivate({
|
|
9764
|
+
audioObjectType,
|
|
9765
|
+
sampleRate,
|
|
9766
|
+
channelConfiguration
|
|
9767
|
+
});
|
|
9768
|
+
iterator.getBits(1);
|
|
9769
|
+
iterator.getBits(1);
|
|
9770
|
+
iterator.getBits(1);
|
|
9771
|
+
iterator.getBits(1);
|
|
9772
|
+
const frameLength = iterator.getBits(13);
|
|
9773
|
+
iterator.getBits(11);
|
|
9774
|
+
iterator.getBits(2);
|
|
9775
|
+
if (!protectionAbsent) {
|
|
9776
|
+
iterator.getBits(16);
|
|
9777
|
+
}
|
|
9778
|
+
iterator.stopReadingBits();
|
|
9779
|
+
iterator.destroy();
|
|
9780
|
+
return {
|
|
9781
|
+
frameLength,
|
|
9782
|
+
codecPrivate: codecPrivate2,
|
|
9783
|
+
channelConfiguration,
|
|
9784
|
+
sampleRate,
|
|
9785
|
+
audioObjectType
|
|
9786
|
+
};
|
|
9787
|
+
};
|
|
9788
|
+
|
|
9789
|
+
// src/boxes/transport-stream/find-separator.ts
|
|
9790
|
+
function findSubarrayIndex(array, subarray) {
|
|
9791
|
+
const subarrayLength = subarray.length;
|
|
9792
|
+
const arrayLength = array.length;
|
|
9793
|
+
for (let i = 0;i <= arrayLength - subarrayLength; i++) {
|
|
9794
|
+
let match = true;
|
|
9795
|
+
for (let j = 0;j < subarrayLength; j++) {
|
|
9796
|
+
if (array[i + j] !== subarray[j]) {
|
|
9797
|
+
match = false;
|
|
9798
|
+
break;
|
|
9799
|
+
}
|
|
9800
|
+
}
|
|
9801
|
+
if (match) {
|
|
9802
|
+
if (subarray[i - 1] === 0) {
|
|
9803
|
+
i--;
|
|
9804
|
+
}
|
|
9805
|
+
return i;
|
|
9806
|
+
}
|
|
9807
|
+
}
|
|
9808
|
+
return -1;
|
|
9809
|
+
}
|
|
9810
|
+
var findNextSeparator = (restOfPacket, transportStreamEntry) => {
|
|
9811
|
+
if (transportStreamEntry.streamType === 27) {
|
|
9812
|
+
return findSubarrayIndex(restOfPacket, new Uint8Array([0, 0, 1, 9]));
|
|
9813
|
+
}
|
|
9814
|
+
throw new Error(`Unsupported stream ID ${transportStreamEntry.streamType}`);
|
|
9815
|
+
};
|
|
9816
|
+
|
|
9817
|
+
// src/boxes/avc/interpret-sps.ts
|
|
9818
|
+
var getDimensionsFromSps = (sps) => {
|
|
9819
|
+
const height = sps.pic_height_in_map_units_minus1;
|
|
9820
|
+
const width = sps.pic_width_in_mbs_minus1;
|
|
9821
|
+
return {
|
|
9822
|
+
height: (height + 1) * 16,
|
|
9823
|
+
width: (width + 1) * 16
|
|
9824
|
+
};
|
|
9825
|
+
};
|
|
9826
|
+
var getSampleAspectRatioFromSps = (sps) => {
|
|
9827
|
+
if (sps.vui_parameters?.sar_height && sps.vui_parameters.sar_width) {
|
|
9828
|
+
return {
|
|
9829
|
+
width: sps.vui_parameters.sar_width,
|
|
9830
|
+
height: sps.vui_parameters.sar_height
|
|
9831
|
+
};
|
|
9832
|
+
}
|
|
9833
|
+
return {
|
|
9834
|
+
width: 1,
|
|
9835
|
+
height: 1
|
|
9836
|
+
};
|
|
9837
|
+
};
|
|
9838
|
+
var getVideoColorFromSps = (sps) => {
|
|
9839
|
+
const matrixCoefficients2 = sps.vui_parameters?.matrix_coefficients;
|
|
9840
|
+
const transferCharacteristics2 = sps.vui_parameters?.transfer_characteristics;
|
|
9841
|
+
const colorPrimaries = sps.vui_parameters?.colour_primaries;
|
|
9842
|
+
return {
|
|
9843
|
+
matrixCoefficients: matrixCoefficients2 ? getMatrixCoefficientsFromIndex(matrixCoefficients2) : null,
|
|
9844
|
+
transferCharacteristics: transferCharacteristics2 ? getTransferCharacteristicsFromIndex(transferCharacteristics2) : null,
|
|
9845
|
+
primaries: colorPrimaries ? getPrimariesFromIndex(colorPrimaries) : null,
|
|
9846
|
+
fullRange: sps.vui_parameters?.video_full_range_flag ?? null
|
|
9847
|
+
};
|
|
9848
|
+
};
|
|
9849
|
+
|
|
9850
|
+
// src/boxes/avc/sps-and-pps.ts
|
|
9851
|
+
var getSpsAndPps = (infos) => {
|
|
9852
|
+
const avcProfile = infos.find((i) => i.type === "avc-profile");
|
|
9853
|
+
const ppsProfile = infos.find((i) => i.type === "avc-pps");
|
|
9854
|
+
if (!avcProfile || !ppsProfile) {
|
|
9855
|
+
throw new Error("Expected avcProfile and ppsProfile");
|
|
9856
|
+
}
|
|
9857
|
+
return { pps: ppsProfile, sps: avcProfile };
|
|
9858
|
+
};
|
|
9859
|
+
|
|
9860
|
+
// src/boxes/transport-stream/handle-avc-packet.ts
|
|
9861
|
+
var MPEG_TIMESCALE = 90000;
|
|
9862
|
+
var handleAvcPacket = async ({
|
|
9863
|
+
streamBuffer,
|
|
9864
|
+
programId,
|
|
9865
|
+
options
|
|
9866
|
+
}) => {
|
|
9867
|
+
const avc = parseAvc(streamBuffer.buffer);
|
|
9868
|
+
const isTrackRegistered = options.parserState.tracks.getTracks().find((t) => {
|
|
9869
|
+
return t.trackId === programId;
|
|
9870
|
+
});
|
|
9871
|
+
if (!isTrackRegistered) {
|
|
9872
|
+
const spsAndPps = getSpsAndPps(avc);
|
|
9873
|
+
const dimensions = getDimensionsFromSps(spsAndPps.sps.spsData);
|
|
9874
|
+
const sampleAspectRatio = getSampleAspectRatioFromSps(spsAndPps.sps.spsData);
|
|
9875
|
+
const track = {
|
|
9876
|
+
rotation: 0,
|
|
9877
|
+
trackId: programId,
|
|
9878
|
+
type: "video",
|
|
9879
|
+
timescale: MPEG_TIMESCALE,
|
|
9880
|
+
codec: getCodecStringFromSpsAndPps(spsAndPps.sps),
|
|
9881
|
+
codecPrivate: getAvccBoxContent(spsAndPps),
|
|
9882
|
+
fps: null,
|
|
9883
|
+
codedWidth: dimensions.width,
|
|
9884
|
+
codedHeight: dimensions.height,
|
|
9885
|
+
height: dimensions.height,
|
|
9886
|
+
width: dimensions.width,
|
|
9887
|
+
displayAspectWidth: dimensions.width,
|
|
9888
|
+
displayAspectHeight: dimensions.height,
|
|
9889
|
+
trakBox: null,
|
|
9890
|
+
codecWithoutConfig: "h264",
|
|
9891
|
+
description: undefined,
|
|
9892
|
+
sampleAspectRatio: {
|
|
9893
|
+
denominator: sampleAspectRatio.height,
|
|
9894
|
+
numerator: sampleAspectRatio.width
|
|
9895
|
+
},
|
|
9896
|
+
color: getVideoColorFromSps(spsAndPps.sps.spsData)
|
|
9897
|
+
};
|
|
9898
|
+
await registerTrack({ track, options, container: "transport-stream" });
|
|
9899
|
+
}
|
|
9900
|
+
const sample = {
|
|
9901
|
+
cts: streamBuffer.pesHeader.pts,
|
|
9902
|
+
dts: streamBuffer.pesHeader.dts ?? streamBuffer.pesHeader.pts,
|
|
9903
|
+
timestamp: streamBuffer.pesHeader.pts,
|
|
9904
|
+
duration: undefined,
|
|
9905
|
+
data: new Uint8Array(streamBuffer.buffer),
|
|
9906
|
+
trackId: programId,
|
|
9907
|
+
type: getKeyFrameOrDeltaFromAvcInfo(avc)
|
|
9908
|
+
};
|
|
9909
|
+
await options.parserState.onVideoSample(programId, convertAudioOrVideoSampleToWebCodecsTimestamps(sample, MPEG_TIMESCALE));
|
|
9910
|
+
};
|
|
9911
|
+
|
|
9912
|
+
// src/boxes/transport-stream/handle-aac-packet.ts
|
|
9913
|
+
var handleAacPacket = async ({
|
|
9914
|
+
streamBuffer,
|
|
9915
|
+
options,
|
|
9916
|
+
programId
|
|
9917
|
+
}) => {
|
|
9918
|
+
const adtsHeader = readAdtsHeader(streamBuffer.buffer);
|
|
9919
|
+
if (!adtsHeader) {
|
|
9920
|
+
throw new Error("Invalid ADTS header - too short");
|
|
9921
|
+
}
|
|
9922
|
+
const { channelConfiguration, codecPrivate: codecPrivate2, sampleRate, audioObjectType } = adtsHeader;
|
|
9923
|
+
const isTrackRegistered = options.parserState.tracks.getTracks().find((t) => {
|
|
9924
|
+
return t.trackId === programId;
|
|
9925
|
+
});
|
|
9926
|
+
if (!isTrackRegistered) {
|
|
9927
|
+
const track = {
|
|
9928
|
+
type: "audio",
|
|
9929
|
+
codecPrivate: codecPrivate2,
|
|
9930
|
+
trackId: programId,
|
|
9931
|
+
trakBox: null,
|
|
9932
|
+
timescale: MPEG_TIMESCALE,
|
|
9933
|
+
codecWithoutConfig: "aac",
|
|
9934
|
+
codec: mapAudioObjectTypeToCodecString(audioObjectType),
|
|
9935
|
+
description: undefined,
|
|
9936
|
+
numberOfChannels: channelConfiguration,
|
|
9937
|
+
sampleRate
|
|
9938
|
+
};
|
|
9939
|
+
await registerTrack({
|
|
9940
|
+
track,
|
|
9941
|
+
options,
|
|
9942
|
+
container: "transport-stream"
|
|
9943
|
+
});
|
|
9944
|
+
}
|
|
9945
|
+
const sample = {
|
|
9946
|
+
cts: streamBuffer.pesHeader.pts,
|
|
9947
|
+
dts: streamBuffer.pesHeader.dts ?? streamBuffer.pesHeader.pts,
|
|
9948
|
+
timestamp: streamBuffer.pesHeader.pts,
|
|
9949
|
+
duration: undefined,
|
|
9950
|
+
data: new Uint8Array(streamBuffer.buffer),
|
|
9951
|
+
trackId: programId,
|
|
9952
|
+
type: "key"
|
|
9953
|
+
};
|
|
9954
|
+
await options.parserState.onAudioSample(programId, convertAudioOrVideoSampleToWebCodecsTimestamps(sample, MPEG_TIMESCALE));
|
|
9955
|
+
};
|
|
9956
|
+
|
|
9957
|
+
// src/boxes/transport-stream/process-stream-buffers.ts
|
|
9958
|
+
var processStreamBuffer = async ({
|
|
9959
|
+
streamBuffer,
|
|
9960
|
+
options,
|
|
9961
|
+
programId,
|
|
9962
|
+
structure
|
|
9963
|
+
}) => {
|
|
9964
|
+
const stream = getStreamForId(structure, programId);
|
|
9965
|
+
if (!stream) {
|
|
9966
|
+
throw new Error("No stream found");
|
|
9967
|
+
}
|
|
9968
|
+
if (stream.streamType === 27) {
|
|
9969
|
+
await handleAvcPacket({ programId, streamBuffer, options });
|
|
9970
|
+
} else if (stream.streamType === 15) {
|
|
9971
|
+
await handleAacPacket({ streamBuffer, options, programId });
|
|
9972
|
+
}
|
|
9973
|
+
if (!options.parserState.tracks.hasAllTracks()) {
|
|
9974
|
+
const tracksRegistered = options.parserState.tracks.getTracks().length;
|
|
9975
|
+
const { streams } = findProgramMapTableOrThrow(structure);
|
|
9976
|
+
if (streams.length === tracksRegistered) {
|
|
9977
|
+
options.parserState.tracks.setIsDone();
|
|
9978
|
+
}
|
|
9979
|
+
}
|
|
9980
|
+
};
|
|
9981
|
+
var processFinalStreamBuffers = async ({
|
|
9982
|
+
streamBufferMap,
|
|
9983
|
+
parserContext,
|
|
9984
|
+
structure
|
|
9985
|
+
}) => {
|
|
9986
|
+
for (const [programId, buffer] of streamBufferMap) {
|
|
9987
|
+
if (buffer.buffer.byteLength > 0) {
|
|
9988
|
+
await processStreamBuffer({
|
|
9989
|
+
streamBuffer: buffer,
|
|
9990
|
+
options: parserContext,
|
|
9991
|
+
programId,
|
|
9992
|
+
structure
|
|
9993
|
+
});
|
|
9994
|
+
streamBufferMap.delete(programId);
|
|
9995
|
+
}
|
|
9996
|
+
}
|
|
9997
|
+
};
|
|
9998
|
+
|
|
9999
|
+
// src/boxes/transport-stream/parse-stream-packet.ts
|
|
10000
|
+
var parseAdtsStream = async ({
|
|
10001
|
+
restOfPacket,
|
|
10002
|
+
transportStreamEntry,
|
|
10003
|
+
streamBuffers,
|
|
10004
|
+
nextPesHeader,
|
|
10005
|
+
options,
|
|
10006
|
+
structure
|
|
10007
|
+
}) => {
|
|
10008
|
+
const streamBuffer = streamBuffers.get(transportStreamEntry.pid);
|
|
10009
|
+
if (!streamBuffer) {
|
|
10010
|
+
streamBuffers.set(transportStreamEntry.pid, {
|
|
10011
|
+
buffer: restOfPacket,
|
|
10012
|
+
pesHeader: nextPesHeader
|
|
10013
|
+
});
|
|
10014
|
+
return;
|
|
10015
|
+
}
|
|
10016
|
+
const expectedLength = readAdtsHeader(streamBuffer.buffer)?.frameLength ?? null;
|
|
10017
|
+
const bytesToTake = expectedLength ? Math.min(restOfPacket.length, expectedLength - streamBuffer.buffer.byteLength) : restOfPacket.length;
|
|
10018
|
+
streamBuffer.buffer = combineUint8Arrays([
|
|
10019
|
+
streamBuffer.buffer,
|
|
10020
|
+
restOfPacket.slice(0, bytesToTake)
|
|
10021
|
+
]);
|
|
10022
|
+
if (expectedLength === streamBuffer.buffer.byteLength) {
|
|
10023
|
+
await processStreamBuffer({
|
|
10024
|
+
streamBuffer,
|
|
10025
|
+
programId: transportStreamEntry.pid,
|
|
10026
|
+
options,
|
|
10027
|
+
structure
|
|
10028
|
+
});
|
|
10029
|
+
const rest = restOfPacket.slice(bytesToTake);
|
|
10030
|
+
streamBuffers.set(transportStreamEntry.pid, {
|
|
10031
|
+
buffer: rest,
|
|
10032
|
+
pesHeader: nextPesHeader
|
|
10033
|
+
});
|
|
10034
|
+
}
|
|
10035
|
+
};
|
|
10036
|
+
var parseAvcStream = async ({
|
|
10037
|
+
restOfPacket,
|
|
10038
|
+
transportStreamEntry,
|
|
10039
|
+
streamBuffers,
|
|
10040
|
+
nextPesHeader,
|
|
10041
|
+
programId,
|
|
10042
|
+
parserContext,
|
|
10043
|
+
structure
|
|
10044
|
+
}) => {
|
|
10045
|
+
const indexOfSeparator = findNextSeparator(restOfPacket, transportStreamEntry);
|
|
10046
|
+
const streamBuffer = streamBuffers.get(transportStreamEntry.pid);
|
|
10047
|
+
if (indexOfSeparator === -1) {
|
|
10048
|
+
if (streamBuffer) {
|
|
10049
|
+
streamBuffer.buffer = combineUint8Arrays([
|
|
10050
|
+
streamBuffer.buffer,
|
|
10051
|
+
restOfPacket
|
|
10052
|
+
]);
|
|
10053
|
+
return;
|
|
10054
|
+
}
|
|
10055
|
+
streamBuffers.set(programId, {
|
|
10056
|
+
pesHeader: nextPesHeader,
|
|
10057
|
+
buffer: restOfPacket
|
|
10058
|
+
});
|
|
10059
|
+
return;
|
|
10060
|
+
}
|
|
10061
|
+
if (streamBuffer) {
|
|
10062
|
+
const packet = restOfPacket.slice(0, indexOfSeparator);
|
|
10063
|
+
streamBuffer.buffer = combineUint8Arrays([streamBuffer.buffer, packet]);
|
|
10064
|
+
await processStreamBuffer({
|
|
10065
|
+
options: parserContext,
|
|
10066
|
+
streamBuffer,
|
|
10067
|
+
programId,
|
|
10068
|
+
structure
|
|
10069
|
+
});
|
|
10070
|
+
const rest = restOfPacket.slice(indexOfSeparator);
|
|
10071
|
+
streamBuffers.set(programId, {
|
|
10072
|
+
pesHeader: nextPesHeader,
|
|
10073
|
+
buffer: rest
|
|
10074
|
+
});
|
|
10075
|
+
return;
|
|
10076
|
+
}
|
|
10077
|
+
if (indexOfSeparator !== 0) {
|
|
10078
|
+
throw new Error("No stream buffer found but new separator is not at the beginning");
|
|
10079
|
+
}
|
|
10080
|
+
streamBuffers.set(programId, {
|
|
10081
|
+
pesHeader: nextPesHeader,
|
|
10082
|
+
buffer: restOfPacket.slice(indexOfSeparator)
|
|
10083
|
+
});
|
|
10084
|
+
};
|
|
10085
|
+
var parseStream = ({
|
|
10086
|
+
iterator,
|
|
10087
|
+
transportStreamEntry,
|
|
10088
|
+
streamBuffers,
|
|
10089
|
+
parserContext,
|
|
10090
|
+
programId,
|
|
10091
|
+
structure,
|
|
10092
|
+
nextPesHeader
|
|
10093
|
+
}) => {
|
|
10094
|
+
const restOfPacket = getRestOfPacket(iterator);
|
|
10095
|
+
if (transportStreamEntry.streamType === 27) {
|
|
10096
|
+
return parseAvcStream({
|
|
10097
|
+
restOfPacket,
|
|
10098
|
+
transportStreamEntry,
|
|
10099
|
+
streamBuffers,
|
|
10100
|
+
nextPesHeader,
|
|
10101
|
+
parserContext,
|
|
10102
|
+
programId,
|
|
10103
|
+
structure
|
|
10104
|
+
});
|
|
10105
|
+
}
|
|
10106
|
+
if (transportStreamEntry.streamType === 15) {
|
|
10107
|
+
return parseAdtsStream({
|
|
10108
|
+
restOfPacket,
|
|
10109
|
+
transportStreamEntry,
|
|
10110
|
+
streamBuffers,
|
|
10111
|
+
nextPesHeader,
|
|
10112
|
+
options: parserContext,
|
|
10113
|
+
structure
|
|
10114
|
+
});
|
|
10115
|
+
}
|
|
10116
|
+
throw new Error(`Unsupported stream type ${transportStreamEntry.streamType}`);
|
|
10117
|
+
};
|
|
10118
|
+
|
|
10119
|
+
// src/boxes/transport-stream/parse-packet.ts
|
|
10120
|
+
var parsePacket = async ({
|
|
10121
|
+
iterator,
|
|
10122
|
+
structure,
|
|
10123
|
+
streamBuffers,
|
|
10124
|
+
parserContext,
|
|
10125
|
+
nextPesHeaderStore
|
|
10126
|
+
}) => {
|
|
10127
|
+
const offset = iterator.counter.getOffset();
|
|
10128
|
+
const syncByte = iterator.getUint8();
|
|
10129
|
+
if (syncByte !== 71) {
|
|
10130
|
+
throw new Error("Invalid sync byte");
|
|
10131
|
+
}
|
|
10132
|
+
iterator.startReadingBits();
|
|
10133
|
+
iterator.getBits(1);
|
|
10134
|
+
const payloadUnitStartIndicator = iterator.getBits(1);
|
|
10135
|
+
iterator.getBits(1);
|
|
10136
|
+
const programId = iterator.getBits(13);
|
|
10137
|
+
iterator.getBits(2);
|
|
10138
|
+
const adaptationFieldControl1 = iterator.getBits(1);
|
|
10139
|
+
iterator.getBits(1);
|
|
10140
|
+
iterator.getBits(4);
|
|
10141
|
+
iterator.stopReadingBits();
|
|
10142
|
+
if (adaptationFieldControl1 === 1) {
|
|
10143
|
+
iterator.startReadingBits();
|
|
10144
|
+
const adaptationFieldLength = iterator.getBits(8);
|
|
10145
|
+
const headerOffset = iterator.counter.getOffset();
|
|
10146
|
+
if (adaptationFieldLength > 0) {
|
|
10147
|
+
iterator.getBits(1);
|
|
10148
|
+
iterator.getBits(1);
|
|
10149
|
+
iterator.getBits(1);
|
|
10150
|
+
iterator.getBits(1);
|
|
10151
|
+
iterator.getBits(1);
|
|
10152
|
+
iterator.getBits(1);
|
|
10153
|
+
iterator.getBits(1);
|
|
10154
|
+
iterator.getBits(1);
|
|
10155
|
+
}
|
|
10156
|
+
const remaining = adaptationFieldLength - (iterator.counter.getOffset() - headerOffset);
|
|
10157
|
+
iterator.stopReadingBits();
|
|
10158
|
+
const toDiscard = Math.max(0, remaining);
|
|
10159
|
+
iterator.discard(toDiscard);
|
|
10160
|
+
}
|
|
10161
|
+
const read = iterator.counter.getOffset() - offset;
|
|
10162
|
+
if (read === 188) {
|
|
10163
|
+
return Promise.resolve(null);
|
|
10164
|
+
}
|
|
10165
|
+
const pat = structure.boxes.find((b) => b.type === "transport-stream-pmt-box");
|
|
10166
|
+
const isPes = payloadUnitStartIndicator && pat?.streams.find((e) => e.pid === programId);
|
|
10167
|
+
if (isPes) {
|
|
10168
|
+
const packetPes = parsePes(iterator);
|
|
10169
|
+
nextPesHeaderStore.setNextPesHeader(packetPes);
|
|
10170
|
+
} else if (payloadUnitStartIndicator === 1) {
|
|
10171
|
+
iterator.getUint8();
|
|
10172
|
+
}
|
|
10173
|
+
if (programId === 0) {
|
|
10174
|
+
return Promise.resolve(parsePat(iterator));
|
|
10175
|
+
}
|
|
10176
|
+
const program = getProgramForId(structure, programId);
|
|
10177
|
+
if (program) {
|
|
10178
|
+
const pmt = parsePmt(iterator);
|
|
10179
|
+
return Promise.resolve(pmt);
|
|
10180
|
+
}
|
|
10181
|
+
const stream = getStreamForId(structure, programId);
|
|
10182
|
+
if (stream) {
|
|
10183
|
+
await parseStream({
|
|
10184
|
+
iterator,
|
|
10185
|
+
transportStreamEntry: stream,
|
|
10186
|
+
streamBuffers,
|
|
10187
|
+
nextPesHeader: nextPesHeaderStore.getNextPesHeader(),
|
|
10188
|
+
parserContext,
|
|
10189
|
+
programId,
|
|
10190
|
+
structure
|
|
10191
|
+
});
|
|
10192
|
+
return Promise.resolve(null);
|
|
10193
|
+
}
|
|
10194
|
+
throw new Error("Unknown packet identifier");
|
|
10195
|
+
};
|
|
10196
|
+
|
|
10197
|
+
// src/boxes/transport-stream/parse-transport-stream.ts
|
|
10198
|
+
var parseTransportStream = async ({
|
|
10199
|
+
iterator,
|
|
10200
|
+
parserContext,
|
|
10201
|
+
structure,
|
|
10202
|
+
streamBuffers,
|
|
10203
|
+
fields,
|
|
10204
|
+
nextPesHeaderStore
|
|
10205
|
+
}) => {
|
|
10206
|
+
if (iterator.bytesRemaining() === 0) {
|
|
10207
|
+
await processFinalStreamBuffers({
|
|
10208
|
+
streamBufferMap: streamBuffers,
|
|
10209
|
+
parserContext,
|
|
10210
|
+
structure
|
|
10211
|
+
});
|
|
10212
|
+
return Promise.resolve({
|
|
10213
|
+
status: "done",
|
|
10214
|
+
segments: structure
|
|
10215
|
+
});
|
|
10216
|
+
}
|
|
10217
|
+
while (true) {
|
|
10218
|
+
if (hasAllInfo({
|
|
10219
|
+
fields,
|
|
10220
|
+
state: parserContext.parserState,
|
|
10221
|
+
structure
|
|
10222
|
+
})) {
|
|
10223
|
+
break;
|
|
10224
|
+
}
|
|
10225
|
+
if (iterator.bytesRemaining() < 188) {
|
|
10226
|
+
return Promise.resolve({
|
|
10227
|
+
status: "incomplete",
|
|
10228
|
+
segments: structure,
|
|
10229
|
+
skipTo: null,
|
|
10230
|
+
continueParsing: () => {
|
|
10231
|
+
return parseTransportStream({
|
|
10232
|
+
iterator,
|
|
10233
|
+
parserContext,
|
|
10234
|
+
structure,
|
|
10235
|
+
streamBuffers,
|
|
10236
|
+
fields,
|
|
10237
|
+
nextPesHeaderStore
|
|
10238
|
+
});
|
|
10239
|
+
}
|
|
10240
|
+
});
|
|
10241
|
+
}
|
|
10242
|
+
const packet = await parsePacket({
|
|
10243
|
+
iterator,
|
|
10244
|
+
structure,
|
|
10245
|
+
streamBuffers,
|
|
10246
|
+
parserContext,
|
|
10247
|
+
nextPesHeaderStore
|
|
10248
|
+
});
|
|
10249
|
+
if (packet) {
|
|
10250
|
+
structure.boxes.push(packet);
|
|
10251
|
+
break;
|
|
10252
|
+
}
|
|
10253
|
+
}
|
|
10254
|
+
return Promise.resolve({
|
|
10255
|
+
segments: structure,
|
|
10256
|
+
status: "incomplete",
|
|
10257
|
+
continueParsing() {
|
|
10258
|
+
return parseTransportStream({
|
|
10259
|
+
iterator,
|
|
10260
|
+
parserContext,
|
|
10261
|
+
structure,
|
|
10262
|
+
streamBuffers,
|
|
10263
|
+
fields,
|
|
10264
|
+
nextPesHeaderStore
|
|
10265
|
+
});
|
|
10266
|
+
},
|
|
10267
|
+
skipTo: null
|
|
10268
|
+
});
|
|
10269
|
+
};
|
|
10270
|
+
|
|
10271
|
+
// src/boxes/webm/segments/block-simple-block-flags.ts
|
|
10272
|
+
var parseBlockFlags = (iterator, type) => {
|
|
10273
|
+
if (type === matroskaElements.Block) {
|
|
10274
|
+
iterator.startReadingBits();
|
|
10275
|
+
iterator.getBits(4);
|
|
10276
|
+
const invisible = Boolean(iterator.getBits(1));
|
|
10277
|
+
const lacing = iterator.getBits(2);
|
|
10278
|
+
iterator.getBits(1);
|
|
10279
|
+
iterator.stopReadingBits();
|
|
9262
10280
|
return {
|
|
9263
10281
|
invisible,
|
|
9264
10282
|
lacing,
|
|
@@ -9456,9 +10474,9 @@ var postprocessEbml = async ({
|
|
|
9456
10474
|
});
|
|
9457
10475
|
if (track) {
|
|
9458
10476
|
await registerTrack({
|
|
9459
|
-
state: parserContext.parserState,
|
|
9460
10477
|
options: parserContext,
|
|
9461
|
-
track
|
|
10478
|
+
track,
|
|
10479
|
+
container: "webm"
|
|
9462
10480
|
});
|
|
9463
10481
|
}
|
|
9464
10482
|
}
|
|
@@ -9928,6 +10946,19 @@ var parseVideo = ({
|
|
|
9928
10946
|
Log.verbose(logLevel, "Detected Matroska container");
|
|
9929
10947
|
return parseWebm({ counter: iterator, parserContext: options, fields });
|
|
9930
10948
|
}
|
|
10949
|
+
if (iterator.isTransportStream()) {
|
|
10950
|
+
return parseTransportStream({
|
|
10951
|
+
iterator,
|
|
10952
|
+
parserContext: options,
|
|
10953
|
+
structure: {
|
|
10954
|
+
type: "transport-stream",
|
|
10955
|
+
boxes: []
|
|
10956
|
+
},
|
|
10957
|
+
streamBuffers: new Map,
|
|
10958
|
+
fields,
|
|
10959
|
+
nextPesHeaderStore: makeNextPesHeaderStore()
|
|
10960
|
+
});
|
|
10961
|
+
}
|
|
9931
10962
|
if (iterator.isMp3()) {
|
|
9932
10963
|
return Promise.reject(new Error("MP3 files are not yet supported"));
|
|
9933
10964
|
}
|
|
@@ -9971,12 +11002,17 @@ var makeCanSkipTracksState = ({
|
|
|
9971
11002
|
|
|
9972
11003
|
// src/state/has-tracks-section.ts
|
|
9973
11004
|
var makeTracksSectionState = (canSkipTracksState) => {
|
|
11005
|
+
const tracks2 = [];
|
|
9974
11006
|
let doneWithTracks = false;
|
|
9975
11007
|
return {
|
|
9976
11008
|
hasAllTracks: () => doneWithTracks,
|
|
9977
11009
|
setIsDone: () => {
|
|
9978
11010
|
doneWithTracks = true;
|
|
9979
11011
|
},
|
|
11012
|
+
addTrack: (track) => {
|
|
11013
|
+
tracks2.push(track);
|
|
11014
|
+
},
|
|
11015
|
+
getTracks: () => tracks2,
|
|
9980
11016
|
ensureHasTracksAtEnd: () => {
|
|
9981
11017
|
if (canSkipTracksState.canSkipTracks()) {
|
|
9982
11018
|
return;
|
|
@@ -10199,10 +11235,10 @@ var parseMedia = async ({
|
|
|
10199
11235
|
};
|
|
10200
11236
|
triggerInfoEmit();
|
|
10201
11237
|
while (parseResult === null || parseResult.status === "incomplete") {
|
|
10202
|
-
if (signal?.aborted) {
|
|
10203
|
-
throw new Error("Aborted");
|
|
10204
|
-
}
|
|
10205
11238
|
while (true) {
|
|
11239
|
+
if (signal?.aborted) {
|
|
11240
|
+
throw new Error("Aborted");
|
|
11241
|
+
}
|
|
10206
11242
|
const result = await currentReader.reader.read();
|
|
10207
11243
|
if (iterator) {
|
|
10208
11244
|
if (!result.done) {
|