@remotion/media-parser 4.0.230 → 4.0.232
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/add-avc-profile-to-track.d.ts +3 -0
- package/dist/add-avc-profile-to-track.js +35 -0
- package/dist/add-new-matroska-tracks.d.ts +6 -1
- package/dist/add-new-matroska-tracks.js +16 -1
- package/dist/boxes/avc/parse-avc.d.ts +18 -0
- package/dist/boxes/avc/parse-avc.js +96 -0
- package/dist/boxes/iso-base-media/make-track.js +3 -3
- package/dist/boxes/iso-base-media/mdat/mdat.d.ts +2 -2
- package/dist/boxes/iso-base-media/mdat/mdat.js +5 -2
- package/dist/boxes/iso-base-media/moov/moov.js +2 -2
- package/dist/boxes/iso-base-media/process-box.d.ts +5 -5
- package/dist/boxes/iso-base-media/process-box.js +38 -37
- package/dist/boxes/iso-base-media/stsd/mebx.js +2 -2
- package/dist/boxes/iso-base-media/stsd/samples.d.ts +2 -2
- package/dist/boxes/iso-base-media/stsd/samples.js +9 -9
- package/dist/boxes/iso-base-media/trak/trak.js +2 -2
- package/dist/boxes/iso-base-media/traversal.d.ts +1 -1
- package/dist/boxes/riff/expect-riff-box.d.ts +16 -0
- package/dist/boxes/riff/expect-riff-box.js +49 -0
- package/dist/boxes/riff/get-tracks-from-avi.d.ts +21 -0
- package/dist/boxes/riff/get-tracks-from-avi.js +108 -0
- package/dist/boxes/riff/is-movi.d.ts +2 -0
- package/dist/boxes/riff/is-movi.js +12 -0
- package/dist/boxes/riff/parse-avih.d.ts +6 -0
- package/dist/boxes/riff/parse-avih.js +32 -0
- package/dist/boxes/riff/parse-box.d.ts +13 -0
- package/dist/boxes/riff/parse-box.js +113 -0
- package/dist/boxes/riff/parse-fmt-box.d.ts +7 -0
- package/dist/boxes/riff/parse-fmt-box.js +33 -0
- package/dist/boxes/riff/parse-list-box.d.ts +8 -0
- package/dist/boxes/riff/parse-list-box.js +30 -0
- package/dist/boxes/riff/parse-movi.d.ts +17 -0
- package/dist/boxes/riff/parse-movi.js +122 -0
- package/dist/boxes/riff/parse-riff-box.d.ts +10 -0
- package/dist/boxes/riff/parse-riff-box.js +33 -0
- package/dist/boxes/riff/parse-strf.d.ts +7 -0
- package/dist/boxes/riff/parse-strf.js +67 -0
- package/dist/boxes/riff/parse-strh.d.ts +6 -0
- package/dist/boxes/riff/parse-strh.js +46 -0
- package/dist/boxes/riff/riff-box.d.ts +81 -0
- package/dist/boxes/riff/riff-box.js +2 -0
- package/dist/boxes/riff/strf.d.ts +7 -0
- package/dist/boxes/riff/strf.js +67 -0
- package/dist/boxes/riff/timescale.d.ts +1 -0
- package/dist/boxes/riff/timescale.js +4 -0
- package/dist/boxes/riff/traversal.d.ts +8 -0
- package/dist/boxes/riff/traversal.js +36 -0
- package/dist/boxes/webm/parse-ebml.js +2 -2
- package/dist/boxes/webm/parse-webm-header.d.ts +2 -2
- package/dist/boxes/webm/parse-webm-header.js +23 -4
- package/dist/boxes/webm/segments/parse-children.d.ts +12 -7
- package/dist/boxes/webm/segments/parse-children.js +67 -57
- package/dist/boxes/webm/segments.d.ts +8 -3
- package/dist/boxes/webm/segments.js +70 -39
- package/dist/boxes/webm/traversal.d.ts +2 -2
- package/dist/buffer-iterator.d.ts +6 -1
- package/dist/buffer-iterator.js +24 -5
- package/dist/create/iso-base-media/create-iso-base-media.d.ts +1 -1
- package/dist/create/iso-base-media/create-iso-base-media.js +4 -9
- package/dist/create/matroska/cluster.d.ts +7 -1
- package/dist/create/matroska/cluster.js +8 -5
- package/dist/create/matroska/create-matroska-media.d.ts +1 -1
- package/dist/create/matroska/create-matroska-media.js +27 -14
- package/dist/create/media-fn.d.ts +1 -1
- package/dist/create/mp3/create-mp3.d.ts +2 -0
- package/dist/create/mp3/create-mp3.js +49 -0
- package/dist/create/wav/create-wav.d.ts +2 -0
- package/dist/create/wav/create-wav.js +108 -0
- package/dist/emit-available-info.d.ts +2 -2
- package/dist/emit-available-info.js +28 -13
- package/dist/esm/buffer.mjs +2 -2
- package/dist/esm/from-node.mjs +2 -1
- package/dist/esm/index.mjs +1513 -331
- package/dist/esm/web-fs.mjs +2 -2
- package/dist/get-audio-codec.d.ts +3 -3
- package/dist/get-audio-codec.js +1 -6
- package/dist/get-container.d.ts +3 -3
- package/dist/get-container.js +9 -7
- package/dist/get-dimensions.d.ts +3 -3
- package/dist/get-duration.d.ts +8 -3
- package/dist/get-duration.js +37 -15
- package/dist/get-fps.d.ts +3 -3
- package/dist/get-fps.js +36 -2
- package/dist/get-tracks.d.ts +4 -7
- package/dist/get-tracks.js +55 -27
- package/dist/get-video-codec.d.ts +5 -4
- package/dist/get-video-codec.js +39 -15
- package/dist/has-all-info.d.ts +2 -2
- package/dist/has-all-info.js +9 -9
- package/dist/index.d.ts +5 -3
- package/dist/index.js +5 -1
- package/dist/options.d.ts +17 -10
- package/dist/parse-media.js +43 -14
- package/dist/parse-result.d.ts +35 -6
- package/dist/parse-video.d.ts +3 -3
- package/dist/parse-video.js +8 -16
- package/dist/parser-context.d.ts +1 -0
- package/dist/parser-state.d.ts +11 -0
- package/dist/parser-state.js +30 -0
- package/dist/readers/from-node.js +2 -1
- package/dist/readers/reader.d.ts +2 -2
- package/dist/register-track.d.ts +13 -0
- package/dist/register-track.js +25 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.js +5 -0
- package/dist/writers/buffer-implementation/writer.d.ts +2 -2
- package/dist/writers/buffer-implementation/writer.js +2 -2
- package/dist/writers/web-fs.js +2 -3
- package/dist/writers/writer.d.ts +5 -3
- package/package.json +3 -3
package/dist/esm/index.mjs
CHANGED
|
@@ -1965,14 +1965,15 @@ var createIsoBaseMedia = async ({
|
|
|
1965
1965
|
writer,
|
|
1966
1966
|
onBytesProgress,
|
|
1967
1967
|
onMillisecondsProgress,
|
|
1968
|
-
logLevel
|
|
1968
|
+
logLevel,
|
|
1969
|
+
filename
|
|
1969
1970
|
}) => {
|
|
1970
1971
|
const header = createIsoBaseMediaFtyp({
|
|
1971
1972
|
compatibleBrands: ["isom", "iso2", "avc1", "mp42"],
|
|
1972
1973
|
majorBrand: "isom",
|
|
1973
1974
|
minorBrand: 512
|
|
1974
1975
|
});
|
|
1975
|
-
const w = await writer.createContent();
|
|
1976
|
+
const w = await writer.createContent({ filename, mimeType: "video/mp4" });
|
|
1976
1977
|
await w.write(header);
|
|
1977
1978
|
let durationInUnits = 0;
|
|
1978
1979
|
const currentTracks = [];
|
|
@@ -2072,9 +2073,8 @@ var createIsoBaseMedia = async ({
|
|
|
2072
2073
|
};
|
|
2073
2074
|
const waitForFinishPromises = [];
|
|
2074
2075
|
return {
|
|
2075
|
-
save:
|
|
2076
|
-
|
|
2077
|
-
return file;
|
|
2076
|
+
save: () => {
|
|
2077
|
+
return w.save();
|
|
2078
2078
|
},
|
|
2079
2079
|
remove: async () => {
|
|
2080
2080
|
await w.remove();
|
|
@@ -2117,10 +2117,6 @@ var createIsoBaseMedia = async ({
|
|
|
2117
2117
|
await updateMdatSize();
|
|
2118
2118
|
Log.verbose(logLevel, "All write operations done. Waiting for finish...");
|
|
2119
2119
|
await w.waitForFinish();
|
|
2120
|
-
},
|
|
2121
|
-
updateDuration: (duration2) => {
|
|
2122
|
-
operationProm.current = operationProm.current.then(() => updateDuration(duration2));
|
|
2123
|
-
return operationProm.current;
|
|
2124
2120
|
}
|
|
2125
2121
|
};
|
|
2126
2122
|
};
|
|
@@ -2182,11 +2178,17 @@ var canFitInCluster = ({
|
|
|
2182
2178
|
}
|
|
2183
2179
|
return timecodeRelativeToCluster <= maxClusterTimestamp;
|
|
2184
2180
|
};
|
|
2185
|
-
var makeCluster = async (
|
|
2181
|
+
var makeCluster = async ({
|
|
2182
|
+
writer,
|
|
2183
|
+
clusterStartTimestamp,
|
|
2184
|
+
timescale,
|
|
2185
|
+
logLevel
|
|
2186
|
+
}) => {
|
|
2187
|
+
Log.verbose(logLevel, `Making new Matroska cluster with timestamp ${clusterStartTimestamp}`);
|
|
2186
2188
|
const cluster = createClusterSegment(timestampToClusterTimestamp(clusterStartTimestamp, timescale));
|
|
2187
|
-
const clusterVIntPosition =
|
|
2189
|
+
const clusterVIntPosition = writer.getWrittenByteCount() + cluster.offsets.offset + matroskaToHex(matroskaElements.Cluster).byteLength;
|
|
2188
2190
|
let clusterSize = cluster.bytes.byteLength - matroskaToHex(matroskaElements.Cluster).byteLength - CLUSTER_MIN_VINT_WIDTH;
|
|
2189
|
-
await
|
|
2191
|
+
await writer.write(cluster.bytes);
|
|
2190
2192
|
const addSample = async (chunk, trackNumber2) => {
|
|
2191
2193
|
const timecodeRelativeToCluster = timestampToClusterTimestamp(chunk.timestamp, timescale) - timestampToClusterTimestamp(clusterStartTimestamp, timescale);
|
|
2192
2194
|
if (!canFitInCluster({ clusterStartTimestamp, chunk, timescale })) {
|
|
@@ -2202,8 +2204,8 @@ var makeCluster = async (w, clusterStartTimestamp, timescale) => {
|
|
|
2202
2204
|
timecodeRelativeToCluster
|
|
2203
2205
|
});
|
|
2204
2206
|
clusterSize += simpleBlock2.byteLength;
|
|
2205
|
-
await
|
|
2206
|
-
await
|
|
2207
|
+
await writer.updateDataAt(clusterVIntPosition, getVariableInt(clusterSize, CLUSTER_MIN_VINT_WIDTH));
|
|
2208
|
+
await writer.write(simpleBlock2);
|
|
2207
2209
|
return { timecodeRelativeToCluster };
|
|
2208
2210
|
};
|
|
2209
2211
|
const shouldMakeNewCluster = ({
|
|
@@ -2219,6 +2221,7 @@ var makeCluster = async (w, clusterStartTimestamp, timescale) => {
|
|
|
2219
2221
|
timescale
|
|
2220
2222
|
});
|
|
2221
2223
|
if (!canFit) {
|
|
2224
|
+
Log.verbose(logLevel, `Cannot fit ${chunk.timestamp} in cluster ${clusterStartTimestamp}. Creating new cluster`);
|
|
2222
2225
|
return true;
|
|
2223
2226
|
}
|
|
2224
2227
|
const keyframe = chunk.type === "key";
|
|
@@ -2938,10 +2941,12 @@ var timescale = 1e6;
|
|
|
2938
2941
|
var createMatroskaMedia = async ({
|
|
2939
2942
|
writer,
|
|
2940
2943
|
onBytesProgress,
|
|
2941
|
-
onMillisecondsProgress
|
|
2944
|
+
onMillisecondsProgress,
|
|
2945
|
+
filename,
|
|
2946
|
+
logLevel
|
|
2942
2947
|
}) => {
|
|
2943
2948
|
const header = makeMatroskaHeader();
|
|
2944
|
-
const w = await writer.createContent();
|
|
2949
|
+
const w = await writer.createContent({ filename, mimeType: "video/webm" });
|
|
2945
2950
|
await w.write(header.bytes);
|
|
2946
2951
|
const matroskaInfo = makeMatroskaInfo({
|
|
2947
2952
|
timescale
|
|
@@ -2993,7 +2998,12 @@ var createMatroskaMedia = async ({
|
|
|
2993
2998
|
};
|
|
2994
2999
|
await w.write(matroskaSegment.bytes);
|
|
2995
3000
|
const clusterOffset = w.getWrittenByteCount();
|
|
2996
|
-
let currentCluster = await makeCluster(
|
|
3001
|
+
let currentCluster = await makeCluster({
|
|
3002
|
+
writer: w,
|
|
3003
|
+
clusterStartTimestamp: 0,
|
|
3004
|
+
timescale,
|
|
3005
|
+
logLevel
|
|
3006
|
+
});
|
|
2997
3007
|
seeks.push({
|
|
2998
3008
|
hexString: matroskaElements.Cluster,
|
|
2999
3009
|
byte: clusterOffset - seekHeadOffset
|
|
@@ -3001,9 +3011,14 @@ var createMatroskaMedia = async ({
|
|
|
3001
3011
|
const trackNumberProgresses = {};
|
|
3002
3012
|
const getClusterOrMakeNew = async ({
|
|
3003
3013
|
chunk,
|
|
3004
|
-
isVideo
|
|
3014
|
+
isVideo,
|
|
3015
|
+
trackNumber: trackNumber2
|
|
3005
3016
|
}) => {
|
|
3006
|
-
const
|
|
3017
|
+
const trackProgressValues = Object.values(trackNumberProgresses);
|
|
3018
|
+
const smallestProgress = trackProgressValues.length === 0 ? 0 : Math.min(...trackProgressValues);
|
|
3019
|
+
if (chunk.type === "key") {
|
|
3020
|
+
trackNumberProgresses[trackNumber2] = chunk.timestamp;
|
|
3021
|
+
}
|
|
3007
3022
|
if (!currentCluster.shouldMakeNewCluster({
|
|
3008
3023
|
newT: smallestProgress,
|
|
3009
3024
|
isVideo,
|
|
@@ -3011,7 +3026,12 @@ var createMatroskaMedia = async ({
|
|
|
3011
3026
|
})) {
|
|
3012
3027
|
return { cluster: currentCluster, isNew: false, smallestProgress };
|
|
3013
3028
|
}
|
|
3014
|
-
currentCluster = await makeCluster(
|
|
3029
|
+
currentCluster = await makeCluster({
|
|
3030
|
+
writer: w,
|
|
3031
|
+
clusterStartTimestamp: smallestProgress,
|
|
3032
|
+
timescale,
|
|
3033
|
+
logLevel
|
|
3034
|
+
});
|
|
3015
3035
|
return { cluster: currentCluster, isNew: true, smallestProgress };
|
|
3016
3036
|
};
|
|
3017
3037
|
const updateDuration = async (newDuration) => {
|
|
@@ -3024,10 +3044,10 @@ var createMatroskaMedia = async ({
|
|
|
3024
3044
|
trackNumber: trackNumber2,
|
|
3025
3045
|
isVideo
|
|
3026
3046
|
}) => {
|
|
3027
|
-
trackNumberProgresses[trackNumber2] = chunk.timestamp;
|
|
3028
3047
|
const { cluster, isNew, smallestProgress } = await getClusterOrMakeNew({
|
|
3029
3048
|
chunk,
|
|
3030
|
-
isVideo
|
|
3049
|
+
isVideo,
|
|
3050
|
+
trackNumber: trackNumber2
|
|
3031
3051
|
});
|
|
3032
3052
|
const newDuration = Math.round((chunk.timestamp + (chunk.duration ?? 0)) / 1000);
|
|
3033
3053
|
await updateDuration(newDuration);
|
|
@@ -3061,9 +3081,8 @@ var createMatroskaMedia = async ({
|
|
|
3061
3081
|
}
|
|
3062
3082
|
});
|
|
3063
3083
|
},
|
|
3064
|
-
save:
|
|
3065
|
-
|
|
3066
|
-
return file;
|
|
3084
|
+
save: () => {
|
|
3085
|
+
return w.save();
|
|
3067
3086
|
},
|
|
3068
3087
|
remove: async () => {
|
|
3069
3088
|
await w.remove();
|
|
@@ -3072,10 +3091,6 @@ var createMatroskaMedia = async ({
|
|
|
3072
3091
|
operationProm.current = operationProm.current.then(() => addSample({ chunk, trackNumber: trackNumber2, isVideo }));
|
|
3073
3092
|
return operationProm.current;
|
|
3074
3093
|
},
|
|
3075
|
-
updateDuration: (duration2) => {
|
|
3076
|
-
operationProm.current = operationProm.current.then(() => updateDuration(duration2));
|
|
3077
|
-
return operationProm.current;
|
|
3078
|
-
},
|
|
3079
3094
|
addTrack: (track) => {
|
|
3080
3095
|
const trackNumber2 = currentTracks.length + 1;
|
|
3081
3096
|
operationProm.current = operationProm.current.then(() => addTrack({ ...track, trackNumber: trackNumber2 }));
|
|
@@ -3101,6 +3116,119 @@ var createMatroskaMedia = async ({
|
|
|
3101
3116
|
};
|
|
3102
3117
|
};
|
|
3103
3118
|
|
|
3119
|
+
// src/create/wav/create-wav.ts
|
|
3120
|
+
var numberTo32BiIntLittleEndian = (num) => {
|
|
3121
|
+
return new Uint8Array([
|
|
3122
|
+
num & 255,
|
|
3123
|
+
num >> 8 & 255,
|
|
3124
|
+
num >> 16 & 255,
|
|
3125
|
+
num >> 24 & 255
|
|
3126
|
+
]);
|
|
3127
|
+
};
|
|
3128
|
+
var numberTo16BitLittleEndian = (num) => {
|
|
3129
|
+
return new Uint8Array([num & 255, num >> 8 & 255]);
|
|
3130
|
+
};
|
|
3131
|
+
var BIT_DEPTH = 16;
|
|
3132
|
+
var BYTES_PER_SAMPLE = BIT_DEPTH / 8;
|
|
3133
|
+
var createWav = async ({
|
|
3134
|
+
filename,
|
|
3135
|
+
logLevel,
|
|
3136
|
+
onBytesProgress,
|
|
3137
|
+
onMillisecondsProgress,
|
|
3138
|
+
writer
|
|
3139
|
+
}) => {
|
|
3140
|
+
const w = await writer.createContent({ filename, mimeType: "audio/wav" });
|
|
3141
|
+
await w.write(new Uint8Array([82, 73, 70, 70]));
|
|
3142
|
+
const sizePosition = w.getWrittenByteCount();
|
|
3143
|
+
await w.write(new Uint8Array([0, 0, 0, 0]));
|
|
3144
|
+
await w.write(new Uint8Array([87, 65, 86, 69]));
|
|
3145
|
+
await w.write(new Uint8Array([102, 109, 116, 32]));
|
|
3146
|
+
await w.write(new Uint8Array([16, 0, 0, 0]));
|
|
3147
|
+
await w.write(new Uint8Array([1, 0]));
|
|
3148
|
+
const channelNumPosition = w.getWrittenByteCount();
|
|
3149
|
+
await w.write(new Uint8Array([1, 0]));
|
|
3150
|
+
const sampleRatePosition = w.getWrittenByteCount();
|
|
3151
|
+
await w.write(new Uint8Array([0, 0, 0, 0]));
|
|
3152
|
+
const byteRatePosition = w.getWrittenByteCount();
|
|
3153
|
+
await w.write(new Uint8Array([0, 0, 0, 0]));
|
|
3154
|
+
const blockAlignPosition = w.getWrittenByteCount();
|
|
3155
|
+
await w.write(new Uint8Array([0, 0]));
|
|
3156
|
+
await w.write(numberTo16BitLittleEndian(BIT_DEPTH));
|
|
3157
|
+
await w.write(new Uint8Array([100, 97, 116, 97]));
|
|
3158
|
+
const dataSizePosition = w.getWrittenByteCount();
|
|
3159
|
+
await w.write(new Uint8Array([0, 0, 0, 0]));
|
|
3160
|
+
const operationProm = { current: Promise.resolve() };
|
|
3161
|
+
const updateSize = async () => {
|
|
3162
|
+
const size = w.getWrittenByteCount() - sizePosition - 4;
|
|
3163
|
+
await w.updateDataAt(sizePosition, numberTo32BiIntLittleEndian(size));
|
|
3164
|
+
const dataSize = w.getWrittenByteCount() - dataSizePosition - 4;
|
|
3165
|
+
await w.updateDataAt(dataSizePosition, numberTo32BiIntLittleEndian(dataSize));
|
|
3166
|
+
};
|
|
3167
|
+
const updateChannelNum = async (numberOfChannels) => {
|
|
3168
|
+
await w.updateDataAt(channelNumPosition, new Uint8Array([numberOfChannels, 0]));
|
|
3169
|
+
};
|
|
3170
|
+
const updateSampleRate = async (sampleRate) => {
|
|
3171
|
+
await w.updateDataAt(sampleRatePosition, numberTo32BiIntLittleEndian(sampleRate));
|
|
3172
|
+
};
|
|
3173
|
+
const updateByteRate = async ({
|
|
3174
|
+
sampleRate,
|
|
3175
|
+
numberOfChannels
|
|
3176
|
+
}) => {
|
|
3177
|
+
await w.updateDataAt(byteRatePosition, numberTo32BiIntLittleEndian(sampleRate * numberOfChannels + BYTES_PER_SAMPLE));
|
|
3178
|
+
};
|
|
3179
|
+
const updateBlockAlign = async (numberOfChannels) => {
|
|
3180
|
+
await w.updateDataAt(blockAlignPosition, new Uint8Array(numberTo16BitLittleEndian(numberOfChannels * BYTES_PER_SAMPLE)));
|
|
3181
|
+
};
|
|
3182
|
+
const addSample = async (chunk) => {
|
|
3183
|
+
Log.verbose(logLevel, "Adding sample", chunk);
|
|
3184
|
+
await w.write(chunk.data);
|
|
3185
|
+
onMillisecondsProgress((chunk.timestamp + (chunk.duration ?? 0)) / 1000);
|
|
3186
|
+
onBytesProgress(w.getWrittenByteCount());
|
|
3187
|
+
};
|
|
3188
|
+
const waitForFinishPromises = [];
|
|
3189
|
+
return {
|
|
3190
|
+
save: () => {
|
|
3191
|
+
return w.save();
|
|
3192
|
+
},
|
|
3193
|
+
remove: () => {
|
|
3194
|
+
return w.remove();
|
|
3195
|
+
},
|
|
3196
|
+
addSample: ({ chunk, trackNumber: trackNumber2 }) => {
|
|
3197
|
+
if (trackNumber2 !== 1) {
|
|
3198
|
+
throw new Error("Only one track supported for WAV");
|
|
3199
|
+
}
|
|
3200
|
+
operationProm.current = operationProm.current.then(() => addSample(chunk));
|
|
3201
|
+
return operationProm.current;
|
|
3202
|
+
},
|
|
3203
|
+
updateTrackSampleRate: () => {
|
|
3204
|
+
throw new Error("updateTrackSampleRate() not implemented for WAV encoder");
|
|
3205
|
+
},
|
|
3206
|
+
addWaitForFinishPromise: (promise) => {
|
|
3207
|
+
waitForFinishPromises.push(promise);
|
|
3208
|
+
},
|
|
3209
|
+
async waitForFinish() {
|
|
3210
|
+
Log.verbose(logLevel, "All write operations queued. Waiting for finish...");
|
|
3211
|
+
await Promise.all(waitForFinishPromises.map((p) => p()));
|
|
3212
|
+
await operationProm.current;
|
|
3213
|
+
await updateSize();
|
|
3214
|
+
await w.waitForFinish();
|
|
3215
|
+
},
|
|
3216
|
+
addTrack: async (track) => {
|
|
3217
|
+
if (track.type !== "audio") {
|
|
3218
|
+
throw new Error("Only audio tracks supported for WAV");
|
|
3219
|
+
}
|
|
3220
|
+
await updateChannelNum(track.numberOfChannels);
|
|
3221
|
+
await updateSampleRate(track.sampleRate);
|
|
3222
|
+
await updateByteRate({
|
|
3223
|
+
sampleRate: track.sampleRate,
|
|
3224
|
+
numberOfChannels: track.numberOfChannels
|
|
3225
|
+
});
|
|
3226
|
+
await updateBlockAlign(track.numberOfChannels);
|
|
3227
|
+
return Promise.resolve({ trackNumber: 1 });
|
|
3228
|
+
}
|
|
3229
|
+
};
|
|
3230
|
+
};
|
|
3231
|
+
|
|
3104
3232
|
// src/boxes/iso-base-media/traversal.ts
|
|
3105
3233
|
var getMoovBox = (segments) => {
|
|
3106
3234
|
const moovBox = segments.find((s) => s.type === "moov-box");
|
|
@@ -3266,6 +3394,34 @@ var getMdatBox = (anySegment) => {
|
|
|
3266
3394
|
return mdat;
|
|
3267
3395
|
};
|
|
3268
3396
|
|
|
3397
|
+
// src/boxes/riff/traversal.ts
|
|
3398
|
+
var isRiffAvi = (structure) => {
|
|
3399
|
+
return structure.boxes.some((box) => box.type === "riff-header" && box.fileType === "AVI");
|
|
3400
|
+
};
|
|
3401
|
+
var getHdlrBox = (structure) => {
|
|
3402
|
+
return structure.boxes.find((box) => box.type === "list-box" && box.listType === "hdrl");
|
|
3403
|
+
};
|
|
3404
|
+
var getAvihBox = (structure) => {
|
|
3405
|
+
const hdlrBox = getHdlrBox(structure);
|
|
3406
|
+
if (!hdlrBox) {
|
|
3407
|
+
return null;
|
|
3408
|
+
}
|
|
3409
|
+
return hdlrBox.children.find((box) => box.type === "avih-box");
|
|
3410
|
+
};
|
|
3411
|
+
var getStrlBoxes = (structure) => {
|
|
3412
|
+
const hdlrBox = getHdlrBox(structure);
|
|
3413
|
+
if (!hdlrBox) {
|
|
3414
|
+
return [];
|
|
3415
|
+
}
|
|
3416
|
+
return hdlrBox.children.filter((box) => box.type === "list-box" && box.listType === "strl");
|
|
3417
|
+
};
|
|
3418
|
+
var getStrhBox = (strlBoxChildren) => {
|
|
3419
|
+
return strlBoxChildren.find((box) => box.type === "strh-box");
|
|
3420
|
+
};
|
|
3421
|
+
var getStrfBox = (strlBoxChildren) => {
|
|
3422
|
+
return strlBoxChildren.find((box) => box.type === "strf-box-audio" || box.type === "strf-box-video") ?? null;
|
|
3423
|
+
};
|
|
3424
|
+
|
|
3269
3425
|
// src/get-fps.ts
|
|
3270
3426
|
var calculateFps = ({
|
|
3271
3427
|
sttsBox,
|
|
@@ -3324,8 +3480,8 @@ var getFpsFromMp4TrakBox = (trakBox) => {
|
|
|
3324
3480
|
durationInSamples: timescaleAndDuration.duration
|
|
3325
3481
|
});
|
|
3326
3482
|
};
|
|
3327
|
-
var
|
|
3328
|
-
const moovBox = getMoovBox(
|
|
3483
|
+
var getFpsFromIsoMaseMedia = (structure) => {
|
|
3484
|
+
const moovBox = getMoovBox(structure.boxes);
|
|
3329
3485
|
if (!moovBox) {
|
|
3330
3486
|
return null;
|
|
3331
3487
|
}
|
|
@@ -3336,8 +3492,37 @@ var getFps = (segments) => {
|
|
|
3336
3492
|
}
|
|
3337
3493
|
return getFpsFromMp4TrakBox(trackBox);
|
|
3338
3494
|
};
|
|
3495
|
+
var getFpsFromAvi = (structure) => {
|
|
3496
|
+
const strl = getStrlBoxes(structure);
|
|
3497
|
+
for (const s of strl) {
|
|
3498
|
+
const strh = getStrhBox(s.children);
|
|
3499
|
+
if (!strh) {
|
|
3500
|
+
throw new Error("No strh box");
|
|
3501
|
+
}
|
|
3502
|
+
if (strh.fccType === "auds") {
|
|
3503
|
+
continue;
|
|
3504
|
+
}
|
|
3505
|
+
return strh.rate;
|
|
3506
|
+
}
|
|
3507
|
+
return null;
|
|
3508
|
+
};
|
|
3509
|
+
var getFps = (segments) => {
|
|
3510
|
+
if (segments.type === "iso-base-media") {
|
|
3511
|
+
return getFpsFromIsoMaseMedia(segments);
|
|
3512
|
+
}
|
|
3513
|
+
if (segments.type === "riff") {
|
|
3514
|
+
return getFpsFromAvi(segments);
|
|
3515
|
+
}
|
|
3516
|
+
if (segments.type === "matroska") {
|
|
3517
|
+
return null;
|
|
3518
|
+
}
|
|
3519
|
+
throw new Error("Cannot get fps, not implemented");
|
|
3520
|
+
};
|
|
3339
3521
|
var hasFps = (boxes) => {
|
|
3340
3522
|
try {
|
|
3523
|
+
if (boxes.type === "matroska") {
|
|
3524
|
+
return true;
|
|
3525
|
+
}
|
|
3341
3526
|
return getFps(boxes) !== null;
|
|
3342
3527
|
} catch {
|
|
3343
3528
|
return false;
|
|
@@ -3361,11 +3546,7 @@ var getAudioCodec = (boxes, parserState) => {
|
|
|
3361
3546
|
return null;
|
|
3362
3547
|
};
|
|
3363
3548
|
var hasAudioCodec = (boxes, state) => {
|
|
3364
|
-
|
|
3365
|
-
return getAudioCodec(boxes, state) !== null;
|
|
3366
|
-
} catch {
|
|
3367
|
-
return false;
|
|
3368
|
-
}
|
|
3549
|
+
return hasTracks(boxes, state);
|
|
3369
3550
|
};
|
|
3370
3551
|
var getCodecSpecificatorFromEsdsBox = ({
|
|
3371
3552
|
child
|
|
@@ -3727,6 +3908,9 @@ var getArrayBufferIterator = (initialData, maxBytes) => {
|
|
|
3727
3908
|
const allowDiscard = () => {
|
|
3728
3909
|
discardAllowed = true;
|
|
3729
3910
|
};
|
|
3911
|
+
const discard = (length) => {
|
|
3912
|
+
counter.increment(length);
|
|
3913
|
+
};
|
|
3730
3914
|
const getUint8 = () => {
|
|
3731
3915
|
const val = view.getUint8(counter.getDiscardedOffset());
|
|
3732
3916
|
counter.increment(1);
|
|
@@ -3772,8 +3956,8 @@ var getArrayBufferIterator = (initialData, maxBytes) => {
|
|
|
3772
3956
|
}
|
|
3773
3957
|
return lastInt;
|
|
3774
3958
|
};
|
|
3775
|
-
const getUint32 = (
|
|
3776
|
-
const val = view.getUint32(counter.getDiscardedOffset()
|
|
3959
|
+
const getUint32 = () => {
|
|
3960
|
+
const val = view.getUint32(counter.getDiscardedOffset());
|
|
3777
3961
|
counter.increment(4);
|
|
3778
3962
|
return val;
|
|
3779
3963
|
};
|
|
@@ -3782,6 +3966,18 @@ var getArrayBufferIterator = (initialData, maxBytes) => {
|
|
|
3782
3966
|
counter.increment(8);
|
|
3783
3967
|
return val;
|
|
3784
3968
|
};
|
|
3969
|
+
const startBox = (size) => {
|
|
3970
|
+
const startOffset = counter.getOffset();
|
|
3971
|
+
return {
|
|
3972
|
+
discardRest: () => discard(size - (counter.getOffset() - startOffset)),
|
|
3973
|
+
expectNoMoreBytes: () => {
|
|
3974
|
+
const remaining = size - (counter.getOffset() - startOffset);
|
|
3975
|
+
if (remaining !== 0) {
|
|
3976
|
+
throw new Error("expected 0 bytes, got " + remaining);
|
|
3977
|
+
}
|
|
3978
|
+
}
|
|
3979
|
+
};
|
|
3980
|
+
};
|
|
3785
3981
|
const getUint32Le = () => {
|
|
3786
3982
|
const val = view.getUint32(counter.getDiscardedOffset(), true);
|
|
3787
3983
|
counter.increment(4);
|
|
@@ -3925,9 +4121,7 @@ var getArrayBufferIterator = (initialData, maxBytes) => {
|
|
|
3925
4121
|
leb128,
|
|
3926
4122
|
removeBytesRead,
|
|
3927
4123
|
isWebm,
|
|
3928
|
-
discard
|
|
3929
|
-
counter.increment(length);
|
|
3930
|
-
},
|
|
4124
|
+
discard,
|
|
3931
4125
|
getEightByteNumber,
|
|
3932
4126
|
getFourByteNumber,
|
|
3933
4127
|
getSlice,
|
|
@@ -4021,6 +4215,11 @@ var getArrayBufferIterator = (initialData, maxBytes) => {
|
|
|
4021
4215
|
counter.increment(2);
|
|
4022
4216
|
return val;
|
|
4023
4217
|
},
|
|
4218
|
+
getUint16Le: () => {
|
|
4219
|
+
const val = view.getUint16(counter.getDiscardedOffset(), true);
|
|
4220
|
+
counter.increment(2);
|
|
4221
|
+
return val;
|
|
4222
|
+
},
|
|
4024
4223
|
getUint24: () => {
|
|
4025
4224
|
const val1 = view.getUint8(counter.getDiscardedOffset());
|
|
4026
4225
|
const val2 = view.getUint8(counter.getDiscardedOffset() + 1);
|
|
@@ -4076,7 +4275,8 @@ var getArrayBufferIterator = (initialData, maxBytes) => {
|
|
|
4076
4275
|
destroy,
|
|
4077
4276
|
isMp3,
|
|
4078
4277
|
disallowDiscard,
|
|
4079
|
-
allowDiscard
|
|
4278
|
+
allowDiscard,
|
|
4279
|
+
startBox
|
|
4080
4280
|
};
|
|
4081
4281
|
};
|
|
4082
4282
|
|
|
@@ -4185,14 +4385,7 @@ var getVideoCodecFromIsoTrak = (trakBox) => {
|
|
|
4185
4385
|
}
|
|
4186
4386
|
throw new Error("Could not find video codec");
|
|
4187
4387
|
};
|
|
4188
|
-
var
|
|
4189
|
-
const moovBox = getMoovBox(boxes);
|
|
4190
|
-
if (moovBox) {
|
|
4191
|
-
const trakBox = getTraks(moovBox).filter((t) => trakBoxContainsVideo(t))[0];
|
|
4192
|
-
if (trakBox) {
|
|
4193
|
-
return getVideoCodecFromIsoTrak(trakBox);
|
|
4194
|
-
}
|
|
4195
|
-
}
|
|
4388
|
+
var getVideoCodecFromMatroska = (boxes) => {
|
|
4196
4389
|
const mainSegment = boxes.find((b) => b.type === "Segment");
|
|
4197
4390
|
if (!mainSegment || mainSegment.type !== "Segment") {
|
|
4198
4391
|
return null;
|
|
@@ -4223,14 +4416,44 @@ var getVideoCodec = (boxes) => {
|
|
|
4223
4416
|
}
|
|
4224
4417
|
}
|
|
4225
4418
|
}
|
|
4226
|
-
|
|
4419
|
+
throw new Error("Could not find video codec");
|
|
4227
4420
|
};
|
|
4228
|
-
var
|
|
4229
|
-
|
|
4230
|
-
|
|
4231
|
-
|
|
4232
|
-
|
|
4421
|
+
var getVideoCodecFromAvi = (structure) => {
|
|
4422
|
+
const strl = getStrlBoxes(structure);
|
|
4423
|
+
for (const s of strl) {
|
|
4424
|
+
const strh = getStrhBox(s.children);
|
|
4425
|
+
if (!strh) {
|
|
4426
|
+
throw new Error("No strh box");
|
|
4427
|
+
}
|
|
4428
|
+
if (strh.fccType === "auds") {
|
|
4429
|
+
continue;
|
|
4430
|
+
}
|
|
4431
|
+
if (strh.handler === "H264") {
|
|
4432
|
+
return "h264";
|
|
4433
|
+
}
|
|
4434
|
+
}
|
|
4435
|
+
throw new Error("Unsupported codec");
|
|
4436
|
+
};
|
|
4437
|
+
var getVideoCodec = (boxes) => {
|
|
4438
|
+
if (boxes.type === "iso-base-media") {
|
|
4439
|
+
const moovBox = getMoovBox(boxes.boxes);
|
|
4440
|
+
if (moovBox) {
|
|
4441
|
+
const trakBox = getTraks(moovBox).filter((t) => trakBoxContainsVideo(t))[0];
|
|
4442
|
+
if (trakBox) {
|
|
4443
|
+
return getVideoCodecFromIsoTrak(trakBox);
|
|
4444
|
+
}
|
|
4445
|
+
}
|
|
4446
|
+
}
|
|
4447
|
+
if (boxes.type === "riff") {
|
|
4448
|
+
return getVideoCodecFromAvi(boxes);
|
|
4233
4449
|
}
|
|
4450
|
+
if (boxes.type === "matroska") {
|
|
4451
|
+
return getVideoCodecFromMatroska(boxes.boxes);
|
|
4452
|
+
}
|
|
4453
|
+
return null;
|
|
4454
|
+
};
|
|
4455
|
+
var hasVideoCodec = (boxes, state) => {
|
|
4456
|
+
return hasTracks(boxes, state);
|
|
4234
4457
|
};
|
|
4235
4458
|
var getVideoPrivateData = (trakBox) => {
|
|
4236
4459
|
const videoSample = getStsdVideoConfig(trakBox);
|
|
@@ -4321,7 +4544,7 @@ var makeBaseMediaTrack = (trakBox) => {
|
|
|
4321
4544
|
sampleRate,
|
|
4322
4545
|
description,
|
|
4323
4546
|
trakBox,
|
|
4324
|
-
codecPrivate: getCodecPrivateFromTrak(trakBox),
|
|
4547
|
+
codecPrivate: getCodecPrivateFromTrak(trakBox) ?? description ?? null,
|
|
4325
4548
|
codecWithoutConfig: getAudioCodecFromTrack(trakBox)
|
|
4326
4549
|
};
|
|
4327
4550
|
}
|
|
@@ -4380,6 +4603,135 @@ var makeBaseMediaTrack = (trakBox) => {
|
|
|
4380
4603
|
return track;
|
|
4381
4604
|
};
|
|
4382
4605
|
|
|
4606
|
+
// src/add-avc-profile-to-track.ts
|
|
4607
|
+
var addAvcProfileToTrack = (track, avc1Profile) => {
|
|
4608
|
+
if (avc1Profile === null) {
|
|
4609
|
+
return track;
|
|
4610
|
+
}
|
|
4611
|
+
return {
|
|
4612
|
+
...track,
|
|
4613
|
+
codec: `avc1.${avc1Profile.sps.profile.toString(16).padStart(2, "0")}${avc1Profile.sps.compatibility.toString(16).padStart(2, "0")}${avc1Profile.sps.level.toString(16).padStart(2, "0")}`,
|
|
4614
|
+
codecPrivate: combineUint8Arrays([
|
|
4615
|
+
new Uint8Array([
|
|
4616
|
+
1,
|
|
4617
|
+
avc1Profile.sps.level,
|
|
4618
|
+
avc1Profile.sps.compatibility,
|
|
4619
|
+
avc1Profile.sps.profile,
|
|
4620
|
+
255,
|
|
4621
|
+
225
|
|
4622
|
+
]),
|
|
4623
|
+
serializeUint16(avc1Profile.sps.sps.length),
|
|
4624
|
+
avc1Profile.sps.sps,
|
|
4625
|
+
new Uint8Array([1]),
|
|
4626
|
+
serializeUint16(avc1Profile.pps.pps.length),
|
|
4627
|
+
avc1Profile.pps.pps
|
|
4628
|
+
])
|
|
4629
|
+
};
|
|
4630
|
+
};
|
|
4631
|
+
|
|
4632
|
+
// src/boxes/riff/timescale.ts
|
|
4633
|
+
var MEDIA_PARSER_RIFF_TIMESCALE = 1e6;
|
|
4634
|
+
|
|
4635
|
+
// src/boxes/riff/get-tracks-from-avi.ts
|
|
4636
|
+
var getNumberOfTracks = (structure) => {
|
|
4637
|
+
const avihBox = getAvihBox(structure);
|
|
4638
|
+
if (avihBox) {
|
|
4639
|
+
return avihBox.streams;
|
|
4640
|
+
}
|
|
4641
|
+
throw new Error("No avih box found");
|
|
4642
|
+
};
|
|
4643
|
+
var makeAviAudioTrack = ({
|
|
4644
|
+
strf,
|
|
4645
|
+
index
|
|
4646
|
+
}) => {
|
|
4647
|
+
if (strf.formatTag !== 255) {
|
|
4648
|
+
throw new Error(`Unsupported audio format ${strf.formatTag}`);
|
|
4649
|
+
}
|
|
4650
|
+
return {
|
|
4651
|
+
type: "audio",
|
|
4652
|
+
codec: "mp4a.40.2",
|
|
4653
|
+
codecPrivate: new Uint8Array([18, 16]),
|
|
4654
|
+
codecWithoutConfig: "aac",
|
|
4655
|
+
description: new Uint8Array([18, 16]),
|
|
4656
|
+
numberOfChannels: strf.numberOfChannels,
|
|
4657
|
+
sampleRate: strf.sampleRate,
|
|
4658
|
+
timescale: MEDIA_PARSER_RIFF_TIMESCALE,
|
|
4659
|
+
trackId: index,
|
|
4660
|
+
trakBox: null
|
|
4661
|
+
};
|
|
4662
|
+
};
|
|
4663
|
+
var makeAviVideoTrack = ({
|
|
4664
|
+
strh,
|
|
4665
|
+
strf,
|
|
4666
|
+
index
|
|
4667
|
+
}) => {
|
|
4668
|
+
if (strh.handler !== "H264") {
|
|
4669
|
+
throw new Error(`Unsupported video codec ${strh.handler}`);
|
|
4670
|
+
}
|
|
4671
|
+
return {
|
|
4672
|
+
codecPrivate: null,
|
|
4673
|
+
codec: "to-be-overriden-later",
|
|
4674
|
+
codecWithoutConfig: "h264",
|
|
4675
|
+
codedHeight: strf.height,
|
|
4676
|
+
codedWidth: strf.width,
|
|
4677
|
+
width: strf.width,
|
|
4678
|
+
height: strf.height,
|
|
4679
|
+
type: "video",
|
|
4680
|
+
displayAspectHeight: strf.height,
|
|
4681
|
+
timescale: MEDIA_PARSER_RIFF_TIMESCALE,
|
|
4682
|
+
description: undefined,
|
|
4683
|
+
trackId: index,
|
|
4684
|
+
color: {
|
|
4685
|
+
fullRange: null,
|
|
4686
|
+
matrixCoefficients: null,
|
|
4687
|
+
primaries: null,
|
|
4688
|
+
transferCharacteristics: null
|
|
4689
|
+
},
|
|
4690
|
+
displayAspectWidth: strf.width,
|
|
4691
|
+
trakBox: null,
|
|
4692
|
+
rotation: 0,
|
|
4693
|
+
sampleAspectRatio: {
|
|
4694
|
+
numerator: 1,
|
|
4695
|
+
denominator: 1
|
|
4696
|
+
},
|
|
4697
|
+
fps: strh.rate / strh.scale
|
|
4698
|
+
};
|
|
4699
|
+
};
|
|
4700
|
+
var getTracksFromAvi = (structure, state) => {
|
|
4701
|
+
if (!isRiffAvi(structure)) {
|
|
4702
|
+
throw new Error("Not an AVI file");
|
|
4703
|
+
}
|
|
4704
|
+
const videoTracks = [];
|
|
4705
|
+
const audioTracks = [];
|
|
4706
|
+
const otherTracks = [];
|
|
4707
|
+
const boxes = getStrlBoxes(structure);
|
|
4708
|
+
let i = 0;
|
|
4709
|
+
for (const box of boxes) {
|
|
4710
|
+
const strh = getStrhBox(box.children);
|
|
4711
|
+
const strf = getStrfBox(box.children);
|
|
4712
|
+
if (!strh || !strf) {
|
|
4713
|
+
continue;
|
|
4714
|
+
}
|
|
4715
|
+
if (strf.type === "strf-box-video") {
|
|
4716
|
+
videoTracks.push(addAvcProfileToTrack(makeAviVideoTrack({ strh, strf, index: i }), state.getAvcProfile()));
|
|
4717
|
+
} else if (strh.fccType === "auds") {
|
|
4718
|
+
audioTracks.push(makeAviAudioTrack({ strf, index: i }));
|
|
4719
|
+
} else {
|
|
4720
|
+
throw new Error(`Unsupported track type ${strh.fccType}`);
|
|
4721
|
+
}
|
|
4722
|
+
i++;
|
|
4723
|
+
}
|
|
4724
|
+
return { audioTracks, otherTracks, videoTracks };
|
|
4725
|
+
};
|
|
4726
|
+
var hasAllTracksFromAvi = (structure, state) => {
|
|
4727
|
+
if (!isRiffAvi(structure)) {
|
|
4728
|
+
throw new Error("Not an AVI file");
|
|
4729
|
+
}
|
|
4730
|
+
const numberOfTracks = getNumberOfTracks(structure);
|
|
4731
|
+
const tracks2 = getTracksFromAvi(structure, state);
|
|
4732
|
+
return tracks2.videoTracks.length + tracks2.audioTracks.length + tracks2.otherTracks.length === numberOfTracks;
|
|
4733
|
+
};
|
|
4734
|
+
|
|
4383
4735
|
// src/make-hvc1-codec-strings.ts
|
|
4384
4736
|
var getHvc1CodecString = (data) => {
|
|
4385
4737
|
const configurationVersion = data.getUint8();
|
|
@@ -4753,48 +5105,63 @@ var getTracksFromMatroska = (segment, timescale2) => {
|
|
|
4753
5105
|
};
|
|
4754
5106
|
|
|
4755
5107
|
// src/get-tracks.ts
|
|
4756
|
-
var
|
|
5108
|
+
var getNumberOfTracks2 = (moovBox) => {
|
|
4757
5109
|
const mvHdBox = getMvhdBox(moovBox);
|
|
4758
5110
|
if (!mvHdBox) {
|
|
4759
5111
|
return 0;
|
|
4760
5112
|
}
|
|
4761
5113
|
return mvHdBox.nextTrackId - 1;
|
|
4762
5114
|
};
|
|
4763
|
-
var hasTracks = (
|
|
4764
|
-
|
|
4765
|
-
|
|
5115
|
+
var hasTracks = (structure, state) => {
|
|
5116
|
+
if (structure.type === "matroska") {
|
|
5117
|
+
const mainSegment = getMainSegment(structure.boxes);
|
|
5118
|
+
if (!mainSegment) {
|
|
5119
|
+
throw new Error("No main segment found");
|
|
5120
|
+
}
|
|
4766
5121
|
return getTracksSegment(mainSegment) !== null;
|
|
4767
5122
|
}
|
|
4768
|
-
|
|
4769
|
-
|
|
4770
|
-
|
|
5123
|
+
if (structure.type === "iso-base-media") {
|
|
5124
|
+
const moovBox = getMoovBox(structure.boxes);
|
|
5125
|
+
if (!moovBox) {
|
|
5126
|
+
return false;
|
|
5127
|
+
}
|
|
5128
|
+
const numberOfTracks = getNumberOfTracks2(moovBox);
|
|
5129
|
+
const tracks2 = getTraks(moovBox);
|
|
5130
|
+
return tracks2.length === numberOfTracks;
|
|
4771
5131
|
}
|
|
4772
|
-
|
|
4773
|
-
|
|
4774
|
-
|
|
5132
|
+
if (structure.type === "riff") {
|
|
5133
|
+
return hasAllTracksFromAvi(structure, state);
|
|
5134
|
+
}
|
|
5135
|
+
throw new Error("Unknown container");
|
|
4775
5136
|
};
|
|
4776
|
-
var
|
|
5137
|
+
var getTracksFromMa = (segments, state) => {
|
|
4777
5138
|
const videoTracks = [];
|
|
4778
5139
|
const audioTracks = [];
|
|
4779
5140
|
const otherTracks = [];
|
|
4780
5141
|
const mainSegment = segments.find((s) => s.type === "Segment");
|
|
4781
|
-
if (mainSegment
|
|
4782
|
-
|
|
4783
|
-
|
|
4784
|
-
|
|
4785
|
-
|
|
4786
|
-
|
|
4787
|
-
|
|
4788
|
-
|
|
4789
|
-
|
|
4790
|
-
|
|
5142
|
+
if (!mainSegment) {
|
|
5143
|
+
throw new Error("No main segment found");
|
|
5144
|
+
}
|
|
5145
|
+
const matroskaTracks = getTracksFromMatroska(mainSegment, state.getTimescale());
|
|
5146
|
+
for (const track of matroskaTracks) {
|
|
5147
|
+
if (track.type === "video") {
|
|
5148
|
+
videoTracks.push(track);
|
|
5149
|
+
} else if (track.type === "audio") {
|
|
5150
|
+
audioTracks.push(track);
|
|
5151
|
+
} else if (track.type === "other") {
|
|
5152
|
+
otherTracks.push(track);
|
|
4791
5153
|
}
|
|
4792
|
-
return {
|
|
4793
|
-
videoTracks,
|
|
4794
|
-
audioTracks,
|
|
4795
|
-
otherTracks
|
|
4796
|
-
};
|
|
4797
5154
|
}
|
|
5155
|
+
return {
|
|
5156
|
+
videoTracks,
|
|
5157
|
+
audioTracks,
|
|
5158
|
+
otherTracks
|
|
5159
|
+
};
|
|
5160
|
+
};
|
|
5161
|
+
var getTracksFromIsoBaseMedia = (segments) => {
|
|
5162
|
+
const videoTracks = [];
|
|
5163
|
+
const audioTracks = [];
|
|
5164
|
+
const otherTracks = [];
|
|
4798
5165
|
const moovBox = getMoovBox(segments);
|
|
4799
5166
|
if (!moovBox) {
|
|
4800
5167
|
return {
|
|
@@ -4823,18 +5190,33 @@ var getTracks = (segments, state) => {
|
|
|
4823
5190
|
otherTracks
|
|
4824
5191
|
};
|
|
4825
5192
|
};
|
|
5193
|
+
var getTracks = (segments, state) => {
|
|
5194
|
+
if (segments.type === "matroska") {
|
|
5195
|
+
return getTracksFromMa(segments.boxes, state);
|
|
5196
|
+
}
|
|
5197
|
+
if (segments.type === "iso-base-media") {
|
|
5198
|
+
return getTracksFromIsoBaseMedia(segments.boxes);
|
|
5199
|
+
}
|
|
5200
|
+
if (segments.type === "riff") {
|
|
5201
|
+
return getTracksFromAvi(segments, state);
|
|
5202
|
+
}
|
|
5203
|
+
throw new Error("Unknown container");
|
|
5204
|
+
};
|
|
4826
5205
|
|
|
4827
5206
|
// src/get-container.ts
|
|
4828
5207
|
var getContainer = (segments) => {
|
|
4829
|
-
|
|
4830
|
-
if (moovBox) {
|
|
5208
|
+
if (segments.type === "iso-base-media") {
|
|
4831
5209
|
return "mp4";
|
|
4832
5210
|
}
|
|
4833
|
-
|
|
4834
|
-
if (mainSegment) {
|
|
5211
|
+
if (segments.type === "matroska") {
|
|
4835
5212
|
return "webm";
|
|
4836
5213
|
}
|
|
4837
|
-
|
|
5214
|
+
if (segments.type === "riff") {
|
|
5215
|
+
if (isRiffAvi(segments)) {
|
|
5216
|
+
return "avi";
|
|
5217
|
+
}
|
|
5218
|
+
}
|
|
5219
|
+
throw new Error("Unknown container");
|
|
4838
5220
|
};
|
|
4839
5221
|
var hasContainer = (boxes) => {
|
|
4840
5222
|
try {
|
|
@@ -5058,16 +5440,12 @@ var getDurationFromMatroska = (segments) => {
|
|
|
5058
5440
|
}
|
|
5059
5441
|
return duration2.value.value / timestampScale2.value.value * 1000;
|
|
5060
5442
|
};
|
|
5061
|
-
var
|
|
5062
|
-
const
|
|
5063
|
-
if (matroskaBox) {
|
|
5064
|
-
return getDurationFromMatroska(boxes);
|
|
5065
|
-
}
|
|
5066
|
-
const moovBox = getMoovBox(boxes);
|
|
5443
|
+
var getDurationFromIsoBaseMedia = (structure, parserState) => {
|
|
5444
|
+
const moovBox = getMoovBox(structure.boxes);
|
|
5067
5445
|
if (!moovBox) {
|
|
5068
5446
|
return null;
|
|
5069
5447
|
}
|
|
5070
|
-
const moofBox = getMoofBox(boxes);
|
|
5448
|
+
const moofBox = getMoofBox(structure.boxes);
|
|
5071
5449
|
const mvhdBox = getMvhdBox(moovBox);
|
|
5072
5450
|
if (!mvhdBox) {
|
|
5073
5451
|
return null;
|
|
@@ -5078,7 +5456,7 @@ var getDuration = (boxes, parserState) => {
|
|
|
5078
5456
|
if (mvhdBox.durationInSeconds > 0) {
|
|
5079
5457
|
return mvhdBox.durationInSeconds;
|
|
5080
5458
|
}
|
|
5081
|
-
const tracks2 = getTracks(
|
|
5459
|
+
const tracks2 = getTracks(structure, parserState);
|
|
5082
5460
|
const allTracks = [
|
|
5083
5461
|
...tracks2.videoTracks,
|
|
5084
5462
|
...tracks2.audioTracks,
|
|
@@ -5093,13 +5471,34 @@ var getDuration = (boxes, parserState) => {
|
|
|
5093
5471
|
const highestTimestamp = Math.max(...allSamples);
|
|
5094
5472
|
return highestTimestamp;
|
|
5095
5473
|
};
|
|
5096
|
-
var
|
|
5097
|
-
|
|
5098
|
-
|
|
5099
|
-
|
|
5100
|
-
|
|
5101
|
-
|
|
5474
|
+
var getDurationFromAvi = (structure) => {
|
|
5475
|
+
const strl = getStrlBoxes(structure);
|
|
5476
|
+
const lengths = [];
|
|
5477
|
+
for (const s of strl) {
|
|
5478
|
+
const strh = getStrhBox(s.children);
|
|
5479
|
+
if (!strh) {
|
|
5480
|
+
throw new Error("No strh box");
|
|
5481
|
+
}
|
|
5482
|
+
const samplesPerSecond = strh.rate / strh.scale;
|
|
5483
|
+
const streamLength = strh.length / samplesPerSecond;
|
|
5484
|
+
lengths.push(streamLength);
|
|
5485
|
+
}
|
|
5486
|
+
return Math.max(...lengths);
|
|
5487
|
+
};
|
|
5488
|
+
var getDuration = (structure, parserState) => {
|
|
5489
|
+
if (structure.type === "matroska") {
|
|
5490
|
+
return getDurationFromMatroska(structure.boxes);
|
|
5491
|
+
}
|
|
5492
|
+
if (structure.type === "iso-base-media") {
|
|
5493
|
+
return getDurationFromIsoBaseMedia(structure, parserState);
|
|
5102
5494
|
}
|
|
5495
|
+
if (structure.type === "riff") {
|
|
5496
|
+
return getDurationFromAvi(structure);
|
|
5497
|
+
}
|
|
5498
|
+
throw new Error("Has no duration");
|
|
5499
|
+
};
|
|
5500
|
+
var hasDuration = (structure, parserState) => {
|
|
5501
|
+
return hasTracks(structure, parserState);
|
|
5103
5502
|
};
|
|
5104
5503
|
|
|
5105
5504
|
// src/emit-available-info.ts
|
|
@@ -5114,15 +5513,15 @@ var emitAvailableInfo = ({
|
|
|
5114
5513
|
}) => {
|
|
5115
5514
|
const keys = Object.keys(hasInfo);
|
|
5116
5515
|
for (const key of keys) {
|
|
5117
|
-
if (key === "
|
|
5118
|
-
if (hasInfo.
|
|
5119
|
-
moreFields.
|
|
5120
|
-
returnValue.
|
|
5516
|
+
if (key === "structure") {
|
|
5517
|
+
if (parseResult && hasInfo.structure && returnValue.structure === undefined) {
|
|
5518
|
+
moreFields.onStructure?.(parseResult.segments);
|
|
5519
|
+
returnValue.structure = parseResult.segments;
|
|
5121
5520
|
}
|
|
5122
5521
|
continue;
|
|
5123
5522
|
}
|
|
5124
5523
|
if (key === "durationInSeconds") {
|
|
5125
|
-
if (hasInfo.durationInSeconds && returnValue.durationInSeconds === undefined) {
|
|
5524
|
+
if (hasInfo.durationInSeconds && returnValue.durationInSeconds === undefined && parseResult) {
|
|
5126
5525
|
const durationInSeconds = getDuration(parseResult.segments, state);
|
|
5127
5526
|
moreFields.onDurationInSeconds?.(durationInSeconds);
|
|
5128
5527
|
returnValue.durationInSeconds = durationInSeconds;
|
|
@@ -5130,7 +5529,7 @@ var emitAvailableInfo = ({
|
|
|
5130
5529
|
continue;
|
|
5131
5530
|
}
|
|
5132
5531
|
if (key === "dimensions") {
|
|
5133
|
-
if (hasInfo.dimensions && returnValue.dimensions === undefined) {
|
|
5532
|
+
if (hasInfo.dimensions && returnValue.dimensions === undefined && parseResult) {
|
|
5134
5533
|
const dimensionsQueried = getDimensions(parseResult.segments, state);
|
|
5135
5534
|
const dimensions = {
|
|
5136
5535
|
height: dimensionsQueried.height,
|
|
@@ -5142,7 +5541,7 @@ var emitAvailableInfo = ({
|
|
|
5142
5541
|
continue;
|
|
5143
5542
|
}
|
|
5144
5543
|
if (key === "unrotatedDimensions") {
|
|
5145
|
-
if (returnValue.unrotatedDimensions === undefined && hasInfo.unrotatedDimensions) {
|
|
5544
|
+
if (returnValue.unrotatedDimensions === undefined && hasInfo.unrotatedDimensions && parseResult) {
|
|
5146
5545
|
const dimensionsQueried = getDimensions(parseResult.segments, state);
|
|
5147
5546
|
const unrotatedDimensions = {
|
|
5148
5547
|
height: dimensionsQueried.unrotatedHeight,
|
|
@@ -5154,7 +5553,7 @@ var emitAvailableInfo = ({
|
|
|
5154
5553
|
continue;
|
|
5155
5554
|
}
|
|
5156
5555
|
if (key === "rotation") {
|
|
5157
|
-
if (returnValue.rotation === undefined && hasInfo.rotation) {
|
|
5556
|
+
if (returnValue.rotation === undefined && hasInfo.rotation && parseResult) {
|
|
5158
5557
|
const dimensionsQueried = getDimensions(parseResult.segments, state);
|
|
5159
5558
|
const { rotation } = dimensionsQueried;
|
|
5160
5559
|
moreFields.onRotation?.(rotation);
|
|
@@ -5163,7 +5562,7 @@ var emitAvailableInfo = ({
|
|
|
5163
5562
|
continue;
|
|
5164
5563
|
}
|
|
5165
5564
|
if (key === "fps") {
|
|
5166
|
-
if (returnValue.fps === undefined && hasInfo.fps) {
|
|
5565
|
+
if (returnValue.fps === undefined && hasInfo.fps && parseResult) {
|
|
5167
5566
|
const fps = getFps(parseResult.segments);
|
|
5168
5567
|
moreFields.onFps?.(fps);
|
|
5169
5568
|
returnValue.fps = fps;
|
|
@@ -5171,7 +5570,7 @@ var emitAvailableInfo = ({
|
|
|
5171
5570
|
continue;
|
|
5172
5571
|
}
|
|
5173
5572
|
if (key === "videoCodec") {
|
|
5174
|
-
if (returnValue.videoCodec === undefined && hasInfo.videoCodec) {
|
|
5573
|
+
if (returnValue.videoCodec === undefined && hasInfo.videoCodec && parseResult) {
|
|
5175
5574
|
const videoCodec = getVideoCodec(parseResult.segments);
|
|
5176
5575
|
moreFields.onVideoCodec?.(videoCodec);
|
|
5177
5576
|
returnValue.videoCodec = videoCodec;
|
|
@@ -5179,7 +5578,7 @@ var emitAvailableInfo = ({
|
|
|
5179
5578
|
continue;
|
|
5180
5579
|
}
|
|
5181
5580
|
if (key === "audioCodec") {
|
|
5182
|
-
if (returnValue.audioCodec === undefined && hasInfo.audioCodec) {
|
|
5581
|
+
if (returnValue.audioCodec === undefined && hasInfo.audioCodec && parseResult) {
|
|
5183
5582
|
const audioCodec = getAudioCodec(parseResult.segments, state);
|
|
5184
5583
|
moreFields.onAudioCodec?.(audioCodec);
|
|
5185
5584
|
returnValue.audioCodec = audioCodec;
|
|
@@ -5187,7 +5586,7 @@ var emitAvailableInfo = ({
|
|
|
5187
5586
|
continue;
|
|
5188
5587
|
}
|
|
5189
5588
|
if (key === "tracks") {
|
|
5190
|
-
if (hasInfo.tracks && returnValue.videoTracks === undefined && returnValue.audioTracks === undefined) {
|
|
5589
|
+
if (hasInfo.tracks && returnValue.videoTracks === undefined && returnValue.audioTracks === undefined && parseResult) {
|
|
5191
5590
|
const { videoTracks, audioTracks } = getTracks(parseResult.segments, state);
|
|
5192
5591
|
moreFields.onTracks?.({ videoTracks, audioTracks });
|
|
5193
5592
|
returnValue.videoTracks = videoTracks;
|
|
@@ -5218,7 +5617,7 @@ var emitAvailableInfo = ({
|
|
|
5218
5617
|
continue;
|
|
5219
5618
|
}
|
|
5220
5619
|
if (key === "container") {
|
|
5221
|
-
if (returnValue.container === undefined && hasInfo.container) {
|
|
5620
|
+
if (returnValue.container === undefined && hasInfo.container && parseResult) {
|
|
5222
5621
|
const container = getContainer(parseResult.segments);
|
|
5223
5622
|
moreFields.onContainer?.(container);
|
|
5224
5623
|
returnValue.container = container;
|
|
@@ -5233,26 +5632,26 @@ var emitAvailableInfo = ({
|
|
|
5233
5632
|
var getAvailableInfo = (options, parseResult, state) => {
|
|
5234
5633
|
const keys = Object.entries(options).filter(([, value]) => value);
|
|
5235
5634
|
const infos = keys.map(([key]) => {
|
|
5236
|
-
if (key === "
|
|
5237
|
-
return parseResult.status === "done";
|
|
5635
|
+
if (key === "structure") {
|
|
5636
|
+
return Boolean(parseResult && parseResult.status === "done");
|
|
5238
5637
|
}
|
|
5239
5638
|
if (key === "durationInSeconds") {
|
|
5240
|
-
return hasDuration(parseResult.segments, state);
|
|
5639
|
+
return Boolean(parseResult && hasDuration(parseResult.segments, state));
|
|
5241
5640
|
}
|
|
5242
5641
|
if (key === "dimensions" || key === "rotation" || key === "unrotatedDimensions") {
|
|
5243
|
-
return hasDimensions(parseResult.segments, state);
|
|
5642
|
+
return Boolean(parseResult && hasDimensions(parseResult.segments, state));
|
|
5244
5643
|
}
|
|
5245
5644
|
if (key === "fps") {
|
|
5246
|
-
return hasFps(parseResult.segments);
|
|
5645
|
+
return Boolean(parseResult && hasFps(parseResult.segments));
|
|
5247
5646
|
}
|
|
5248
5647
|
if (key === "videoCodec") {
|
|
5249
|
-
return hasVideoCodec(parseResult.segments);
|
|
5648
|
+
return Boolean(parseResult && hasVideoCodec(parseResult.segments, state));
|
|
5250
5649
|
}
|
|
5251
5650
|
if (key === "audioCodec") {
|
|
5252
|
-
return hasAudioCodec(parseResult.segments, state);
|
|
5651
|
+
return Boolean(parseResult && hasAudioCodec(parseResult.segments, state));
|
|
5253
5652
|
}
|
|
5254
5653
|
if (key === "tracks") {
|
|
5255
|
-
return hasTracks(parseResult.segments);
|
|
5654
|
+
return Boolean(parseResult && hasTracks(parseResult.segments, state));
|
|
5256
5655
|
}
|
|
5257
5656
|
if (key === "internalStats") {
|
|
5258
5657
|
return false;
|
|
@@ -5264,7 +5663,7 @@ var getAvailableInfo = (options, parseResult, state) => {
|
|
|
5264
5663
|
return true;
|
|
5265
5664
|
}
|
|
5266
5665
|
if (key === "container") {
|
|
5267
|
-
return hasContainer(parseResult.segments);
|
|
5666
|
+
return Boolean(parseResult && hasContainer(parseResult.segments));
|
|
5268
5667
|
}
|
|
5269
5668
|
throw new Error(`Unknown key: ${key}`);
|
|
5270
5669
|
});
|
|
@@ -5276,6 +5675,35 @@ var getAvailableInfo = (options, parseResult, state) => {
|
|
|
5276
5675
|
return Object.fromEntries(entries);
|
|
5277
5676
|
};
|
|
5278
5677
|
|
|
5678
|
+
// src/register-track.ts
|
|
5679
|
+
var registerTrack = async ({
|
|
5680
|
+
state,
|
|
5681
|
+
options,
|
|
5682
|
+
track
|
|
5683
|
+
}) => {
|
|
5684
|
+
if (track.type === "video" && options.onVideoTrack) {
|
|
5685
|
+
const callback = await options.onVideoTrack(track);
|
|
5686
|
+
await state.registerVideoSampleCallback(track.trackId, callback ?? null);
|
|
5687
|
+
}
|
|
5688
|
+
if (track.type === "audio" && options.onAudioTrack) {
|
|
5689
|
+
const callback = await options.onAudioTrack(track);
|
|
5690
|
+
await state.registerAudioSampleCallback(track.trackId, callback ?? null);
|
|
5691
|
+
}
|
|
5692
|
+
};
|
|
5693
|
+
var registerVideoTrackWhenProfileIsAvailable = ({
|
|
5694
|
+
options,
|
|
5695
|
+
state,
|
|
5696
|
+
track
|
|
5697
|
+
}) => {
|
|
5698
|
+
state.registerOnAvcProfileCallback(async (profile) => {
|
|
5699
|
+
await registerTrack({
|
|
5700
|
+
options,
|
|
5701
|
+
state,
|
|
5702
|
+
track: addAvcProfileToTrack(track, profile)
|
|
5703
|
+
});
|
|
5704
|
+
});
|
|
5705
|
+
};
|
|
5706
|
+
|
|
5279
5707
|
// src/boxes/iso-base-media/esds/decoder-specific-config.ts
|
|
5280
5708
|
var parseDecoderSpecificConfig = (iterator, logLevel) => {
|
|
5281
5709
|
const layerTag = iterator.getUint8();
|
|
@@ -5450,7 +5878,10 @@ var parseMdat = async ({
|
|
|
5450
5878
|
signal,
|
|
5451
5879
|
maySkipSampleProcessing
|
|
5452
5880
|
}) => {
|
|
5453
|
-
const alreadyHas = hasTracks(
|
|
5881
|
+
const alreadyHas = hasTracks({
|
|
5882
|
+
type: "iso-base-media",
|
|
5883
|
+
boxes: existingBoxes
|
|
5884
|
+
}, options.parserState);
|
|
5454
5885
|
if (!alreadyHas) {
|
|
5455
5886
|
if (maySkipSampleProcessing) {
|
|
5456
5887
|
data.discard(size - (data.counter.getOffset() - fileOffset));
|
|
@@ -5470,7 +5901,7 @@ var parseMdat = async ({
|
|
|
5470
5901
|
fileOffset
|
|
5471
5902
|
});
|
|
5472
5903
|
}
|
|
5473
|
-
const tracks2 = getTracks(existingBoxes, options.parserState);
|
|
5904
|
+
const tracks2 = getTracks({ type: "iso-base-media", boxes: existingBoxes }, options.parserState);
|
|
5474
5905
|
const allTracks = [
|
|
5475
5906
|
...tracks2.videoTracks,
|
|
5476
5907
|
...tracks2.audioTracks,
|
|
@@ -5589,7 +6020,7 @@ var parseMoov = async ({
|
|
|
5589
6020
|
signal,
|
|
5590
6021
|
logLevel
|
|
5591
6022
|
}) => {
|
|
5592
|
-
const children = await
|
|
6023
|
+
const children = await parseIsoBaseMediaBoxes({
|
|
5593
6024
|
iterator,
|
|
5594
6025
|
maxBytes: size - (iterator.counter.getOffset() - offset),
|
|
5595
6026
|
allowIncompleteBoxes: false,
|
|
@@ -5606,7 +6037,7 @@ var parseMoov = async ({
|
|
|
5606
6037
|
offset,
|
|
5607
6038
|
boxSize: size,
|
|
5608
6039
|
type: "moov-box",
|
|
5609
|
-
children: children.segments
|
|
6040
|
+
children: children.segments.boxes
|
|
5610
6041
|
};
|
|
5611
6042
|
};
|
|
5612
6043
|
|
|
@@ -5911,7 +6342,7 @@ var parseMebx = async ({
|
|
|
5911
6342
|
}) => {
|
|
5912
6343
|
iterator.discard(6);
|
|
5913
6344
|
const dataReferenceIndex = iterator.getUint16();
|
|
5914
|
-
const children = await
|
|
6345
|
+
const children = await parseIsoBaseMediaBoxes({
|
|
5915
6346
|
iterator,
|
|
5916
6347
|
maxBytes: iterator.counter.getOffset() - offset,
|
|
5917
6348
|
allowIncompleteBoxes: false,
|
|
@@ -5930,7 +6361,7 @@ var parseMebx = async ({
|
|
|
5930
6361
|
offset,
|
|
5931
6362
|
dataReferenceIndex,
|
|
5932
6363
|
format: "mebx",
|
|
5933
|
-
children: children.segments
|
|
6364
|
+
children: children.segments.boxes
|
|
5934
6365
|
};
|
|
5935
6366
|
};
|
|
5936
6367
|
|
|
@@ -6121,7 +6552,7 @@ var processSample = async ({
|
|
|
6121
6552
|
const packetSize = iterator.getUint16();
|
|
6122
6553
|
const sampleRate = iterator.getFixedPointUnsigned1616Number();
|
|
6123
6554
|
const bytesRemainingInBox = boxSize - (iterator.counter.getOffset() - fileOffset);
|
|
6124
|
-
const children = await
|
|
6555
|
+
const children = await parseIsoBaseMediaBoxes({
|
|
6125
6556
|
iterator,
|
|
6126
6557
|
allowIncompleteBoxes: false,
|
|
6127
6558
|
maxBytes: bytesRemainingInBox,
|
|
@@ -6153,7 +6584,7 @@ var processSample = async ({
|
|
|
6153
6584
|
bytesPerPacket: null,
|
|
6154
6585
|
bytesPerFrame: null,
|
|
6155
6586
|
bitsPerSample: null,
|
|
6156
|
-
children: children.segments
|
|
6587
|
+
children: children.segments.boxes
|
|
6157
6588
|
}
|
|
6158
6589
|
};
|
|
6159
6590
|
}
|
|
@@ -6168,7 +6599,7 @@ var processSample = async ({
|
|
|
6168
6599
|
const bytesPerFrame = iterator.getUint32();
|
|
6169
6600
|
const bytesPerSample = iterator.getUint32();
|
|
6170
6601
|
const bytesRemainingInBox = boxSize - (iterator.counter.getOffset() - fileOffset);
|
|
6171
|
-
const children = await
|
|
6602
|
+
const children = await parseIsoBaseMediaBoxes({
|
|
6172
6603
|
iterator,
|
|
6173
6604
|
allowIncompleteBoxes: false,
|
|
6174
6605
|
maxBytes: bytesRemainingInBox,
|
|
@@ -6200,7 +6631,7 @@ var processSample = async ({
|
|
|
6200
6631
|
bytesPerPacket,
|
|
6201
6632
|
bytesPerFrame,
|
|
6202
6633
|
bitsPerSample: bytesPerSample,
|
|
6203
|
-
children: children.segments
|
|
6634
|
+
children: children.segments.boxes
|
|
6204
6635
|
}
|
|
6205
6636
|
};
|
|
6206
6637
|
}
|
|
@@ -6219,7 +6650,7 @@ var processSample = async ({
|
|
|
6219
6650
|
const bytesPerFrame = iterator.getUint32();
|
|
6220
6651
|
const samplesPerPacket = iterator.getUint32();
|
|
6221
6652
|
const bytesRemainingInBox = boxSize - (iterator.counter.getOffset() - fileOffset);
|
|
6222
|
-
const children = await
|
|
6653
|
+
const children = await parseIsoBaseMediaBoxes({
|
|
6223
6654
|
iterator,
|
|
6224
6655
|
allowIncompleteBoxes: false,
|
|
6225
6656
|
maxBytes: bytesRemainingInBox,
|
|
@@ -6251,7 +6682,7 @@ var processSample = async ({
|
|
|
6251
6682
|
bytesPerPacket: null,
|
|
6252
6683
|
bytesPerFrame,
|
|
6253
6684
|
bitsPerSample: bitsPerCodedSample,
|
|
6254
|
-
children: children.segments
|
|
6685
|
+
children: children.segments.boxes
|
|
6255
6686
|
}
|
|
6256
6687
|
};
|
|
6257
6688
|
}
|
|
@@ -6273,7 +6704,7 @@ var processSample = async ({
|
|
|
6273
6704
|
const depth = iterator.getUint16();
|
|
6274
6705
|
const colorTableId = iterator.getInt16();
|
|
6275
6706
|
const bytesRemainingInBox = boxSize - (iterator.counter.getOffset() - fileOffset);
|
|
6276
|
-
const children = bytesRemainingInBox > 8 ? await
|
|
6707
|
+
const children = bytesRemainingInBox > 8 ? await parseIsoBaseMediaBoxes({
|
|
6277
6708
|
iterator,
|
|
6278
6709
|
allowIncompleteBoxes: false,
|
|
6279
6710
|
maxBytes: bytesRemainingInBox,
|
|
@@ -6282,7 +6713,7 @@ var processSample = async ({
|
|
|
6282
6713
|
continueMdat: false,
|
|
6283
6714
|
signal,
|
|
6284
6715
|
logLevel
|
|
6285
|
-
}) : (iterator.discard(bytesRemainingInBox), { status: "done", segments: [] });
|
|
6716
|
+
}) : (iterator.discard(bytesRemainingInBox), { status: "done", segments: { boxes: [], type: "iso-base-media" } });
|
|
6286
6717
|
if (children.status === "incomplete") {
|
|
6287
6718
|
throw new Error("Incomplete boxes are not allowed");
|
|
6288
6719
|
}
|
|
@@ -6307,7 +6738,7 @@ var processSample = async ({
|
|
|
6307
6738
|
compressorName,
|
|
6308
6739
|
depth,
|
|
6309
6740
|
colorTableId,
|
|
6310
|
-
descriptors: children.segments
|
|
6741
|
+
descriptors: children.segments.boxes
|
|
6311
6742
|
}
|
|
6312
6743
|
};
|
|
6313
6744
|
}
|
|
@@ -6629,7 +7060,7 @@ var parseTrak = async ({
|
|
|
6629
7060
|
signal,
|
|
6630
7061
|
logLevel
|
|
6631
7062
|
}) => {
|
|
6632
|
-
const children = await
|
|
7063
|
+
const children = await parseIsoBaseMediaBoxes({
|
|
6633
7064
|
iterator: data,
|
|
6634
7065
|
maxBytes: size - (data.counter.getOffset() - offsetAtStart),
|
|
6635
7066
|
allowIncompleteBoxes: false,
|
|
@@ -6646,7 +7077,7 @@ var parseTrak = async ({
|
|
|
6646
7077
|
offset: offsetAtStart,
|
|
6647
7078
|
boxSize: size,
|
|
6648
7079
|
type: "trak-box",
|
|
6649
|
-
children: children.segments
|
|
7080
|
+
children: children.segments.boxes
|
|
6650
7081
|
};
|
|
6651
7082
|
};
|
|
6652
7083
|
|
|
@@ -6703,7 +7134,7 @@ var getChildren = async ({
|
|
|
6703
7134
|
}) => {
|
|
6704
7135
|
const parseChildren = boxType === "mdia" || boxType === "minf" || boxType === "stbl" || boxType === "moof" || boxType === "dims" || boxType === "wave" || boxType === "traf" || boxType === "stsb";
|
|
6705
7136
|
if (parseChildren) {
|
|
6706
|
-
const parsed = await
|
|
7137
|
+
const parsed = await parseIsoBaseMediaBoxes({
|
|
6707
7138
|
iterator,
|
|
6708
7139
|
maxBytes: bytesRemainingInBox,
|
|
6709
7140
|
allowIncompleteBoxes: false,
|
|
@@ -6716,7 +7147,7 @@ var getChildren = async ({
|
|
|
6716
7147
|
if (parsed.status === "incomplete") {
|
|
6717
7148
|
throw new Error("Incomplete boxes are not allowed");
|
|
6718
7149
|
}
|
|
6719
|
-
return parsed.segments;
|
|
7150
|
+
return parsed.segments.boxes;
|
|
6720
7151
|
}
|
|
6721
7152
|
if (bytesRemainingInBox < 0) {
|
|
6722
7153
|
throw new Error("Box size is too big " + JSON.stringify({ boxType }));
|
|
@@ -6790,7 +7221,7 @@ var processBox = async ({
|
|
|
6790
7221
|
const boxSize = boxSizeRaw === 1 ? iterator.getEightByteNumber() : boxSizeRaw;
|
|
6791
7222
|
if (bytesRemaining < boxSize) {
|
|
6792
7223
|
if (boxType === "mdat") {
|
|
6793
|
-
const shouldSkip = (options.canSkipVideoData || !hasTracks(parsedBoxes)) && options.supportsContentRange;
|
|
7224
|
+
const shouldSkip = (options.canSkipVideoData || !hasTracks({ type: "iso-base-media", boxes: parsedBoxes }, options.parserState)) && options.supportsContentRange;
|
|
6794
7225
|
if (shouldSkip) {
|
|
6795
7226
|
const skipTo = fileOffset + boxSize;
|
|
6796
7227
|
const bytesToSkip = skipTo - iterator.counter.getOffset();
|
|
@@ -7019,14 +7450,11 @@ var processBox = async ({
|
|
|
7019
7450
|
});
|
|
7020
7451
|
const transformedTrack = makeBaseMediaTrack(box);
|
|
7021
7452
|
if (transformedTrack) {
|
|
7022
|
-
|
|
7023
|
-
|
|
7024
|
-
|
|
7025
|
-
|
|
7026
|
-
|
|
7027
|
-
const callback = await options.onVideoTrack?.(transformedTrack);
|
|
7028
|
-
await options.parserState.registerVideoSampleCallback(transformedTrack.trackId, callback ?? null);
|
|
7029
|
-
}
|
|
7453
|
+
await registerTrack({
|
|
7454
|
+
options,
|
|
7455
|
+
state: options.parserState,
|
|
7456
|
+
track: transformedTrack
|
|
7457
|
+
});
|
|
7030
7458
|
}
|
|
7031
7459
|
return {
|
|
7032
7460
|
type: "complete",
|
|
@@ -7167,7 +7595,7 @@ var processBox = async ({
|
|
|
7167
7595
|
skipTo: null
|
|
7168
7596
|
};
|
|
7169
7597
|
};
|
|
7170
|
-
var
|
|
7598
|
+
var parseIsoBaseMediaBoxes = async ({
|
|
7171
7599
|
iterator,
|
|
7172
7600
|
maxBytes,
|
|
7173
7601
|
allowIncompleteBoxes,
|
|
@@ -7177,9 +7605,12 @@ var parseBoxes = async ({
|
|
|
7177
7605
|
signal,
|
|
7178
7606
|
logLevel
|
|
7179
7607
|
}) => {
|
|
7180
|
-
|
|
7608
|
+
const structure = {
|
|
7609
|
+
type: "iso-base-media",
|
|
7610
|
+
boxes: initialBoxes
|
|
7611
|
+
};
|
|
7181
7612
|
const initialOffset = iterator.counter.getOffset();
|
|
7182
|
-
const alreadyHasMdat = boxes.find((b) => b.type === "mdat-box");
|
|
7613
|
+
const alreadyHasMdat = structure.boxes.find((b) => b.type === "mdat-box");
|
|
7183
7614
|
while (iterator.bytesRemaining() > 0 && iterator.counter.getOffset() - initialOffset < maxBytes) {
|
|
7184
7615
|
const result = continueMdat ? await parseMdatPartially({
|
|
7185
7616
|
iterator,
|
|
@@ -7202,13 +7633,13 @@ var parseBoxes = async ({
|
|
|
7202
7633
|
}
|
|
7203
7634
|
return {
|
|
7204
7635
|
status: "incomplete",
|
|
7205
|
-
segments:
|
|
7636
|
+
segments: structure,
|
|
7206
7637
|
continueParsing: () => {
|
|
7207
|
-
return
|
|
7638
|
+
return parseIsoBaseMediaBoxes({
|
|
7208
7639
|
iterator,
|
|
7209
7640
|
maxBytes,
|
|
7210
7641
|
allowIncompleteBoxes,
|
|
7211
|
-
initialBoxes: boxes,
|
|
7642
|
+
initialBoxes: structure.boxes,
|
|
7212
7643
|
options,
|
|
7213
7644
|
continueMdat: false,
|
|
7214
7645
|
signal,
|
|
@@ -7221,13 +7652,13 @@ var parseBoxes = async ({
|
|
|
7221
7652
|
if (result.type === "partial-mdat-box") {
|
|
7222
7653
|
return {
|
|
7223
7654
|
status: "incomplete",
|
|
7224
|
-
segments:
|
|
7655
|
+
segments: structure,
|
|
7225
7656
|
continueParsing: () => {
|
|
7226
|
-
return Promise.resolve(
|
|
7657
|
+
return Promise.resolve(parseIsoBaseMediaBoxes({
|
|
7227
7658
|
iterator,
|
|
7228
7659
|
maxBytes,
|
|
7229
7660
|
allowIncompleteBoxes,
|
|
7230
|
-
initialBoxes: boxes,
|
|
7661
|
+
initialBoxes: structure.boxes,
|
|
7231
7662
|
options,
|
|
7232
7663
|
continueMdat: result,
|
|
7233
7664
|
signal,
|
|
@@ -7238,15 +7669,15 @@ var parseBoxes = async ({
|
|
|
7238
7669
|
};
|
|
7239
7670
|
}
|
|
7240
7671
|
if (result.box.type === "mdat-box" && alreadyHasMdat) {
|
|
7241
|
-
boxes = boxes.filter((b) => b.type !== "mdat-box");
|
|
7242
|
-
boxes.push(result.box);
|
|
7672
|
+
structure.boxes = structure.boxes.filter((b) => b.type !== "mdat-box");
|
|
7673
|
+
structure.boxes.push(result.box);
|
|
7243
7674
|
iterator.allowDiscard();
|
|
7244
7675
|
if (result.box.status !== "samples-processed") {
|
|
7245
7676
|
throw new Error("unexpected");
|
|
7246
7677
|
}
|
|
7247
7678
|
break;
|
|
7248
7679
|
} else {
|
|
7249
|
-
boxes.push(result.box);
|
|
7680
|
+
structure.boxes.push(result.box);
|
|
7250
7681
|
}
|
|
7251
7682
|
if (result.skipTo !== null) {
|
|
7252
7683
|
if (!options.supportsContentRange) {
|
|
@@ -7254,13 +7685,13 @@ var parseBoxes = async ({
|
|
|
7254
7685
|
}
|
|
7255
7686
|
return {
|
|
7256
7687
|
status: "incomplete",
|
|
7257
|
-
segments:
|
|
7688
|
+
segments: structure,
|
|
7258
7689
|
continueParsing: () => {
|
|
7259
|
-
return
|
|
7690
|
+
return parseIsoBaseMediaBoxes({
|
|
7260
7691
|
iterator,
|
|
7261
7692
|
maxBytes,
|
|
7262
7693
|
allowIncompleteBoxes,
|
|
7263
|
-
initialBoxes: boxes,
|
|
7694
|
+
initialBoxes: structure.boxes,
|
|
7264
7695
|
options,
|
|
7265
7696
|
continueMdat: false,
|
|
7266
7697
|
signal,
|
|
@@ -7273,13 +7704,13 @@ var parseBoxes = async ({
|
|
|
7273
7704
|
if (iterator.bytesRemaining() < 0) {
|
|
7274
7705
|
return {
|
|
7275
7706
|
status: "incomplete",
|
|
7276
|
-
segments:
|
|
7707
|
+
segments: structure,
|
|
7277
7708
|
continueParsing: () => {
|
|
7278
|
-
return
|
|
7709
|
+
return parseIsoBaseMediaBoxes({
|
|
7279
7710
|
iterator,
|
|
7280
7711
|
maxBytes,
|
|
7281
7712
|
allowIncompleteBoxes,
|
|
7282
|
-
initialBoxes: boxes,
|
|
7713
|
+
initialBoxes: structure.boxes,
|
|
7283
7714
|
options,
|
|
7284
7715
|
continueMdat: false,
|
|
7285
7716
|
signal,
|
|
@@ -7291,22 +7722,22 @@ var parseBoxes = async ({
|
|
|
7291
7722
|
}
|
|
7292
7723
|
iterator.removeBytesRead();
|
|
7293
7724
|
}
|
|
7294
|
-
const mdatState = getMdatBox(boxes);
|
|
7725
|
+
const mdatState = getMdatBox(structure.boxes);
|
|
7295
7726
|
const skipped = mdatState?.status === "samples-skipped" && !options.canSkipVideoData && options.supportsContentRange;
|
|
7296
7727
|
const buffered = mdatState?.status === "samples-buffered" && !options.canSkipVideoData;
|
|
7297
7728
|
if (skipped || buffered) {
|
|
7298
7729
|
return {
|
|
7299
7730
|
status: "incomplete",
|
|
7300
|
-
segments:
|
|
7731
|
+
segments: structure,
|
|
7301
7732
|
continueParsing: () => {
|
|
7302
7733
|
if (buffered) {
|
|
7303
7734
|
iterator.skipTo(mdatState.fileOffset, false);
|
|
7304
7735
|
}
|
|
7305
|
-
return
|
|
7736
|
+
return parseIsoBaseMediaBoxes({
|
|
7306
7737
|
iterator,
|
|
7307
7738
|
maxBytes,
|
|
7308
7739
|
allowIncompleteBoxes: false,
|
|
7309
|
-
initialBoxes: boxes,
|
|
7740
|
+
initialBoxes: structure.boxes,
|
|
7310
7741
|
options,
|
|
7311
7742
|
continueMdat: false,
|
|
7312
7743
|
signal,
|
|
@@ -7318,24 +7749,651 @@ var parseBoxes = async ({
|
|
|
7318
7749
|
}
|
|
7319
7750
|
return {
|
|
7320
7751
|
status: "done",
|
|
7321
|
-
segments:
|
|
7752
|
+
segments: structure
|
|
7322
7753
|
};
|
|
7323
7754
|
};
|
|
7324
7755
|
|
|
7325
|
-
// src/
|
|
7326
|
-
var
|
|
7327
|
-
|
|
7328
|
-
|
|
7329
|
-
track
|
|
7330
|
-
}) => {
|
|
7331
|
-
if (track.type === "video" && options.onVideoTrack) {
|
|
7332
|
-
const callback = await options.onVideoTrack(track);
|
|
7333
|
-
await state.registerVideoSampleCallback(track.trackId, callback ?? null);
|
|
7756
|
+
// src/boxes/riff/is-movi.ts
|
|
7757
|
+
var isMoviAtom = (iterator, ckId) => {
|
|
7758
|
+
if (ckId !== "LIST") {
|
|
7759
|
+
return false;
|
|
7334
7760
|
}
|
|
7335
|
-
|
|
7336
|
-
|
|
7337
|
-
|
|
7761
|
+
const listType = iterator.getByteString(4);
|
|
7762
|
+
iterator.counter.decrement(4);
|
|
7763
|
+
return listType === "movi";
|
|
7764
|
+
};
|
|
7765
|
+
|
|
7766
|
+
// src/boxes/avc/parse-avc.ts
|
|
7767
|
+
var readSps = (iterator) => {
|
|
7768
|
+
const profile = iterator.getUint8();
|
|
7769
|
+
const compatibility = iterator.getUint8();
|
|
7770
|
+
const level = iterator.getUint8();
|
|
7771
|
+
return {
|
|
7772
|
+
profile,
|
|
7773
|
+
compatibility,
|
|
7774
|
+
level
|
|
7775
|
+
};
|
|
7776
|
+
};
|
|
7777
|
+
var findEnd = (buffer) => {
|
|
7778
|
+
let zeroesInARow = 0;
|
|
7779
|
+
for (let i = 0;i < buffer.length; i++) {
|
|
7780
|
+
const val = buffer[i];
|
|
7781
|
+
if (val === 0) {
|
|
7782
|
+
zeroesInARow++;
|
|
7783
|
+
continue;
|
|
7784
|
+
}
|
|
7785
|
+
if (zeroesInARow >= 2 && val === 1) {
|
|
7786
|
+
return i - zeroesInARow;
|
|
7787
|
+
}
|
|
7788
|
+
zeroesInARow = 0;
|
|
7789
|
+
}
|
|
7790
|
+
return null;
|
|
7791
|
+
};
|
|
7792
|
+
var inspect = (buffer) => {
|
|
7793
|
+
const iterator = getArrayBufferIterator(buffer, buffer.byteLength);
|
|
7794
|
+
iterator.startReadingBits();
|
|
7795
|
+
iterator.getBits(1);
|
|
7796
|
+
iterator.getBits(2);
|
|
7797
|
+
const type = iterator.getBits(5);
|
|
7798
|
+
iterator.stopReadingBits();
|
|
7799
|
+
if (type === 7) {
|
|
7800
|
+
const end = findEnd(buffer);
|
|
7801
|
+
const data = readSps(iterator);
|
|
7802
|
+
const sps = buffer.slice(1, end === null ? Infinity : end);
|
|
7803
|
+
return {
|
|
7804
|
+
level: data.level,
|
|
7805
|
+
profile: data.profile,
|
|
7806
|
+
compatibility: data.compatibility,
|
|
7807
|
+
sps,
|
|
7808
|
+
type: "avc-profile"
|
|
7809
|
+
};
|
|
7810
|
+
}
|
|
7811
|
+
if (type === 5) {
|
|
7812
|
+
return {
|
|
7813
|
+
type: "keyframe"
|
|
7814
|
+
};
|
|
7815
|
+
}
|
|
7816
|
+
if (type === 8) {
|
|
7817
|
+
const end = findEnd(buffer);
|
|
7818
|
+
const pps = buffer.slice(0, end === null ? Infinity : end);
|
|
7819
|
+
return {
|
|
7820
|
+
type: "avc-pps",
|
|
7821
|
+
pps
|
|
7822
|
+
};
|
|
7823
|
+
}
|
|
7824
|
+
if (type === 1) {
|
|
7825
|
+
return {
|
|
7826
|
+
type: "delta-frame"
|
|
7827
|
+
};
|
|
7828
|
+
}
|
|
7829
|
+
iterator.destroy();
|
|
7830
|
+
return null;
|
|
7831
|
+
};
|
|
7832
|
+
var parseAvc = (buffer) => {
|
|
7833
|
+
let zeroesInARow = 0;
|
|
7834
|
+
const infos = [];
|
|
7835
|
+
for (let i = 0;i < buffer.length; i++) {
|
|
7836
|
+
const val = buffer[i];
|
|
7837
|
+
if (val === 0) {
|
|
7838
|
+
zeroesInARow++;
|
|
7839
|
+
continue;
|
|
7840
|
+
}
|
|
7841
|
+
if (zeroesInARow >= 2 && val === 1) {
|
|
7842
|
+
zeroesInARow = 0;
|
|
7843
|
+
const info = inspect(buffer.slice(i + 1, i + 100));
|
|
7844
|
+
if (info) {
|
|
7845
|
+
infos.push(info);
|
|
7846
|
+
if (info.type === "keyframe" || info.type === "delta-frame") {
|
|
7847
|
+
break;
|
|
7848
|
+
}
|
|
7849
|
+
}
|
|
7850
|
+
}
|
|
7851
|
+
if (val !== 1) {
|
|
7852
|
+
zeroesInARow = 0;
|
|
7853
|
+
}
|
|
7854
|
+
}
|
|
7855
|
+
return infos;
|
|
7856
|
+
};
|
|
7857
|
+
|
|
7858
|
+
// src/boxes/riff/parse-movi.ts
|
|
7859
|
+
var getStrhForIndex = (structure, trackId) => {
|
|
7860
|
+
const boxes = getStrlBoxes(structure);
|
|
7861
|
+
const box = boxes[trackId];
|
|
7862
|
+
if (!box) {
|
|
7863
|
+
throw new Error("Expected box");
|
|
7864
|
+
}
|
|
7865
|
+
const strh = getStrhBox(box.children);
|
|
7866
|
+
if (!strh) {
|
|
7867
|
+
throw new Error("strh");
|
|
7868
|
+
}
|
|
7869
|
+
return strh;
|
|
7870
|
+
};
|
|
7871
|
+
var handleChunk = async ({
|
|
7872
|
+
iterator,
|
|
7873
|
+
options,
|
|
7874
|
+
structure,
|
|
7875
|
+
ckId,
|
|
7876
|
+
ckSize
|
|
7877
|
+
}) => {
|
|
7878
|
+
const videoChunk = ckId.match(/^([0-9]{2})dc$/);
|
|
7879
|
+
if (videoChunk) {
|
|
7880
|
+
const trackId = parseInt(videoChunk[1], 10);
|
|
7881
|
+
const strh = getStrhForIndex(structure, trackId);
|
|
7882
|
+
const samplesPerSecond = strh.rate / strh.scale;
|
|
7883
|
+
const nthSample = options.parserState.getSamplesForTrack(trackId);
|
|
7884
|
+
const timeInSec = nthSample / samplesPerSecond;
|
|
7885
|
+
const timestamp = Math.floor(timeInSec * MEDIA_PARSER_RIFF_TIMESCALE);
|
|
7886
|
+
const duration2 = Math.floor(1 / samplesPerSecond * MEDIA_PARSER_RIFF_TIMESCALE);
|
|
7887
|
+
const data = iterator.getSlice(ckSize);
|
|
7888
|
+
const infos = parseAvc(data);
|
|
7889
|
+
const keyOrDelta = infos.find((i) => i.type === "keyframe" || i.type === "delta-frame");
|
|
7890
|
+
if (!keyOrDelta) {
|
|
7891
|
+
throw new Error("expected avc to contain info about key or delta");
|
|
7892
|
+
}
|
|
7893
|
+
const avcProfile = infos.find((i) => i.type === "avc-profile");
|
|
7894
|
+
const ppsProfile = infos.find((i) => i.type === "avc-pps");
|
|
7895
|
+
if (avcProfile && ppsProfile) {
|
|
7896
|
+
await options.parserState.onProfile({ pps: ppsProfile, sps: avcProfile });
|
|
7897
|
+
}
|
|
7898
|
+
await options.parserState.onVideoSample(trackId, {
|
|
7899
|
+
cts: timestamp,
|
|
7900
|
+
dts: timestamp,
|
|
7901
|
+
data,
|
|
7902
|
+
duration: duration2,
|
|
7903
|
+
timestamp,
|
|
7904
|
+
trackId,
|
|
7905
|
+
type: keyOrDelta.type === "keyframe" ? "key" : "delta"
|
|
7906
|
+
});
|
|
7907
|
+
} else {
|
|
7908
|
+
const audioChunk = ckId.match(/^([0-9]{2})wb$/);
|
|
7909
|
+
if (audioChunk) {
|
|
7910
|
+
const trackId = parseInt(audioChunk[1], 10);
|
|
7911
|
+
const strh = getStrhForIndex(structure, trackId);
|
|
7912
|
+
const samplesPerSecond = strh.rate / strh.scale;
|
|
7913
|
+
const nthSample = options.parserState.getSamplesForTrack(trackId);
|
|
7914
|
+
const timeInSec = nthSample / samplesPerSecond;
|
|
7915
|
+
const timestamp = timeInSec * MEDIA_PARSER_RIFF_TIMESCALE;
|
|
7916
|
+
const duration2 = 1 / samplesPerSecond * MEDIA_PARSER_RIFF_TIMESCALE;
|
|
7917
|
+
await options.parserState.onAudioSample(trackId, {
|
|
7918
|
+
cts: timestamp,
|
|
7919
|
+
dts: timestamp,
|
|
7920
|
+
data: iterator.getSlice(ckSize),
|
|
7921
|
+
duration: duration2,
|
|
7922
|
+
timestamp,
|
|
7923
|
+
trackId,
|
|
7924
|
+
type: "key"
|
|
7925
|
+
});
|
|
7926
|
+
}
|
|
7927
|
+
}
|
|
7928
|
+
};
|
|
7929
|
+
var parseMovi = async ({
|
|
7930
|
+
iterator,
|
|
7931
|
+
maxOffset,
|
|
7932
|
+
options,
|
|
7933
|
+
structure
|
|
7934
|
+
}) => {
|
|
7935
|
+
while (iterator.counter.getOffset() < maxOffset) {
|
|
7936
|
+
if (iterator.bytesRemaining() < 8) {
|
|
7937
|
+
return {
|
|
7938
|
+
type: "incomplete",
|
|
7939
|
+
continueParsing: () => {
|
|
7940
|
+
return Promise.resolve(parseMovi({ iterator, maxOffset, options, structure }));
|
|
7941
|
+
}
|
|
7942
|
+
};
|
|
7943
|
+
}
|
|
7944
|
+
const ckId = iterator.getByteString(4);
|
|
7945
|
+
const ckSize = iterator.getUint32Le();
|
|
7946
|
+
if (iterator.bytesRemaining() < ckSize) {
|
|
7947
|
+
iterator.counter.decrement(8);
|
|
7948
|
+
return {
|
|
7949
|
+
type: "incomplete",
|
|
7950
|
+
continueParsing: () => {
|
|
7951
|
+
return Promise.resolve(parseMovi({ iterator, maxOffset, options, structure }));
|
|
7952
|
+
}
|
|
7953
|
+
};
|
|
7954
|
+
}
|
|
7955
|
+
await handleChunk({ iterator, options, structure, ckId, ckSize });
|
|
7956
|
+
while (iterator.counter.getOffset() < maxOffset && iterator.bytesRemaining() > 0) {
|
|
7957
|
+
if (iterator.getUint8() !== 0) {
|
|
7958
|
+
iterator.counter.decrement(1);
|
|
7959
|
+
break;
|
|
7960
|
+
}
|
|
7961
|
+
}
|
|
7962
|
+
}
|
|
7963
|
+
if (iterator.counter.getOffset() === maxOffset) {
|
|
7964
|
+
return {
|
|
7965
|
+
type: "complete",
|
|
7966
|
+
box: {
|
|
7967
|
+
type: "movi-box"
|
|
7968
|
+
}
|
|
7969
|
+
};
|
|
7970
|
+
}
|
|
7971
|
+
if (iterator.counter.getOffset() > maxOffset) {
|
|
7972
|
+
throw new Error("Oops, this should not happen!");
|
|
7973
|
+
}
|
|
7974
|
+
return {
|
|
7975
|
+
type: "incomplete",
|
|
7976
|
+
continueParsing: () => {
|
|
7977
|
+
return Promise.resolve(parseMovi({ iterator, maxOffset, options, structure }));
|
|
7978
|
+
}
|
|
7979
|
+
};
|
|
7980
|
+
};
|
|
7981
|
+
|
|
7982
|
+
// src/boxes/riff/parse-avih.ts
|
|
7983
|
+
var parseAvih = ({
|
|
7984
|
+
iterator,
|
|
7985
|
+
size
|
|
7986
|
+
}) => {
|
|
7987
|
+
const { expectNoMoreBytes } = iterator.startBox(size);
|
|
7988
|
+
const dwMicroSecPerFrame = iterator.getUint32Le();
|
|
7989
|
+
const dwMaxBytesPerSec = iterator.getUint32Le();
|
|
7990
|
+
const paddingGranularity = iterator.getUint32Le();
|
|
7991
|
+
const flags = iterator.getUint32Le();
|
|
7992
|
+
const totalFrames = iterator.getUint32Le();
|
|
7993
|
+
const initialFrames = iterator.getUint32Le();
|
|
7994
|
+
const streams = iterator.getUint32Le();
|
|
7995
|
+
const suggestedBufferSize = iterator.getUint32Le();
|
|
7996
|
+
const width = iterator.getUint32Le();
|
|
7997
|
+
const height = iterator.getUint32Le();
|
|
7998
|
+
iterator.discard(16);
|
|
7999
|
+
expectNoMoreBytes();
|
|
8000
|
+
return {
|
|
8001
|
+
type: "avih-box",
|
|
8002
|
+
microSecPerFrame: dwMicroSecPerFrame,
|
|
8003
|
+
maxBytesPerSecond: dwMaxBytesPerSec,
|
|
8004
|
+
paddingGranularity,
|
|
8005
|
+
flags,
|
|
8006
|
+
totalFrames,
|
|
8007
|
+
initialFrames,
|
|
8008
|
+
streams,
|
|
8009
|
+
suggestedBufferSize,
|
|
8010
|
+
height,
|
|
8011
|
+
width
|
|
8012
|
+
};
|
|
8013
|
+
};
|
|
8014
|
+
|
|
8015
|
+
// src/boxes/riff/parse-fmt-box.ts
|
|
8016
|
+
var parseFmtBox = ({
|
|
8017
|
+
iterator,
|
|
8018
|
+
boxes,
|
|
8019
|
+
size
|
|
8020
|
+
}) => {
|
|
8021
|
+
const box = iterator.startBox(size);
|
|
8022
|
+
const header = boxes.find((b) => b.type === "riff-header");
|
|
8023
|
+
if (!header) {
|
|
8024
|
+
throw new Error("Expected RIFF header");
|
|
8025
|
+
}
|
|
8026
|
+
if (header.fileType !== "WAVE") {
|
|
8027
|
+
throw new Error("Only supporting WAVE type");
|
|
8028
|
+
}
|
|
8029
|
+
const wFormatTag = iterator.getUint16Le();
|
|
8030
|
+
if (wFormatTag !== 1) {
|
|
8031
|
+
throw new Error("Expected wFormatTag to be 1, only supporting this");
|
|
8032
|
+
}
|
|
8033
|
+
const numberOfChannels = iterator.getUint16Le();
|
|
8034
|
+
const sampleRate = iterator.getUint32Le();
|
|
8035
|
+
const byteRate = iterator.getUint32Le();
|
|
8036
|
+
const blockAlign = iterator.getUint16Le();
|
|
8037
|
+
const bitsPerSample = iterator.getUint16Le();
|
|
8038
|
+
box.expectNoMoreBytes();
|
|
8039
|
+
return {
|
|
8040
|
+
type: "wave-format-box",
|
|
8041
|
+
formatTag: wFormatTag,
|
|
8042
|
+
numberOfChannels,
|
|
8043
|
+
sampleRate,
|
|
8044
|
+
blockAlign,
|
|
8045
|
+
byteRate,
|
|
8046
|
+
bitsPerSample
|
|
8047
|
+
};
|
|
8048
|
+
};
|
|
8049
|
+
|
|
8050
|
+
// src/boxes/riff/parse-list-box.ts
|
|
8051
|
+
var parseListBox = async ({
|
|
8052
|
+
iterator,
|
|
8053
|
+
size,
|
|
8054
|
+
options
|
|
8055
|
+
}) => {
|
|
8056
|
+
const counter = iterator.counter.getOffset();
|
|
8057
|
+
const listType = iterator.getByteString(4);
|
|
8058
|
+
if (listType === "movi") {
|
|
8059
|
+
throw new Error("should not be handled here");
|
|
8060
|
+
}
|
|
8061
|
+
const structure = {
|
|
8062
|
+
type: "riff",
|
|
8063
|
+
boxes: []
|
|
8064
|
+
};
|
|
8065
|
+
const result = await parseRiffBody({
|
|
8066
|
+
structure,
|
|
8067
|
+
iterator,
|
|
8068
|
+
maxOffset: counter + size,
|
|
8069
|
+
options
|
|
8070
|
+
});
|
|
8071
|
+
if (result.status === "incomplete") {
|
|
8072
|
+
throw new Error(`Should only parse complete boxes (${listType})`);
|
|
8073
|
+
}
|
|
8074
|
+
return {
|
|
8075
|
+
type: "list-box",
|
|
8076
|
+
listType,
|
|
8077
|
+
children: structure.boxes
|
|
8078
|
+
};
|
|
8079
|
+
};
|
|
8080
|
+
|
|
8081
|
+
// src/boxes/riff/parse-strf.ts
|
|
8082
|
+
var parseStrfAudio = ({
|
|
8083
|
+
iterator,
|
|
8084
|
+
size
|
|
8085
|
+
}) => {
|
|
8086
|
+
const box = iterator.startBox(size);
|
|
8087
|
+
const formatTag = iterator.getUint16Le();
|
|
8088
|
+
const numberOfChannels = iterator.getUint16Le();
|
|
8089
|
+
const samplesPerSec = iterator.getUint32Le();
|
|
8090
|
+
const avgBytesPerSec = iterator.getUint32Le();
|
|
8091
|
+
const blockAlign = iterator.getUint16Le();
|
|
8092
|
+
const bitsPerSample = iterator.getUint16Le();
|
|
8093
|
+
const cbSize = iterator.getUint16Le();
|
|
8094
|
+
box.expectNoMoreBytes();
|
|
8095
|
+
return {
|
|
8096
|
+
type: "strf-box-audio",
|
|
8097
|
+
avgBytesPerSecond: avgBytesPerSec,
|
|
8098
|
+
bitsPerSample,
|
|
8099
|
+
blockAlign,
|
|
8100
|
+
cbSize,
|
|
8101
|
+
formatTag,
|
|
8102
|
+
numberOfChannels,
|
|
8103
|
+
sampleRate: samplesPerSec
|
|
8104
|
+
};
|
|
8105
|
+
};
|
|
8106
|
+
var parseStrfVideo = ({
|
|
8107
|
+
iterator,
|
|
8108
|
+
size
|
|
8109
|
+
}) => {
|
|
8110
|
+
const box = iterator.startBox(size);
|
|
8111
|
+
const biSize = iterator.getUint32Le();
|
|
8112
|
+
const width = iterator.getInt32Le();
|
|
8113
|
+
const height = iterator.getInt32Le();
|
|
8114
|
+
const planes = iterator.getUint16Le();
|
|
8115
|
+
const bitCount = iterator.getUint16Le();
|
|
8116
|
+
const compression = iterator.getByteString(4);
|
|
8117
|
+
const sizeImage = iterator.getUint32Le();
|
|
8118
|
+
const xPelsPerMeter = iterator.getInt32Le();
|
|
8119
|
+
const yPelsPerMeter = iterator.getInt32Le();
|
|
8120
|
+
const clrUsed = iterator.getUint32Le();
|
|
8121
|
+
const clrImportant = iterator.getUint32Le();
|
|
8122
|
+
box.expectNoMoreBytes();
|
|
8123
|
+
return {
|
|
8124
|
+
type: "strf-box-video",
|
|
8125
|
+
biSize,
|
|
8126
|
+
bitCount,
|
|
8127
|
+
clrImportant,
|
|
8128
|
+
clrUsed,
|
|
8129
|
+
compression,
|
|
8130
|
+
height,
|
|
8131
|
+
planes,
|
|
8132
|
+
sizeImage,
|
|
8133
|
+
width,
|
|
8134
|
+
xPelsPerMeter,
|
|
8135
|
+
yPelsPerMeter
|
|
8136
|
+
};
|
|
8137
|
+
};
|
|
8138
|
+
var parseStrf = ({
|
|
8139
|
+
iterator,
|
|
8140
|
+
size,
|
|
8141
|
+
boxes
|
|
8142
|
+
}) => {
|
|
8143
|
+
const strh = boxes.find((b) => b.type === "strh-box");
|
|
8144
|
+
if (!strh) {
|
|
8145
|
+
throw new Error("strh box not found");
|
|
8146
|
+
}
|
|
8147
|
+
if (strh.fccType === "vids") {
|
|
8148
|
+
return parseStrfVideo({ iterator, size });
|
|
8149
|
+
}
|
|
8150
|
+
if (strh.fccType === "auds") {
|
|
8151
|
+
return parseStrfAudio({ iterator, size });
|
|
8152
|
+
}
|
|
8153
|
+
throw new Error(`Unsupported fccType: ${strh.fccType}`);
|
|
8154
|
+
};
|
|
8155
|
+
|
|
8156
|
+
// src/boxes/riff/parse-strh.ts
|
|
8157
|
+
var parseStrh = ({
|
|
8158
|
+
iterator,
|
|
8159
|
+
size
|
|
8160
|
+
}) => {
|
|
8161
|
+
const box = iterator.startBox(size);
|
|
8162
|
+
const fccType = iterator.getByteString(4);
|
|
8163
|
+
if (fccType !== "vids" && fccType !== "auds") {
|
|
8164
|
+
throw new Error("Expected AVI handler to be vids / auds");
|
|
8165
|
+
}
|
|
8166
|
+
const handler = fccType === "vids" ? iterator.getByteString(4) : iterator.getUint32Le();
|
|
8167
|
+
if (typeof handler === "string" && handler !== "H264") {
|
|
8168
|
+
throw new Error(`Only H264 is supported as a stream type in .avi, got ${handler}`);
|
|
8169
|
+
}
|
|
8170
|
+
if (fccType === "auds" && handler !== 1) {
|
|
8171
|
+
throw new Error(`Only "1" is supported as a stream type in .avi, got ${handler}`);
|
|
8172
|
+
}
|
|
8173
|
+
const flags = iterator.getUint32Le();
|
|
8174
|
+
const priority = iterator.getUint16Le();
|
|
8175
|
+
const language2 = iterator.getUint16Le();
|
|
8176
|
+
const initialFrames = iterator.getUint32Le();
|
|
8177
|
+
const scale = iterator.getUint32Le();
|
|
8178
|
+
const rate = iterator.getUint32Le();
|
|
8179
|
+
const start = iterator.getUint32Le();
|
|
8180
|
+
const length = iterator.getUint32Le();
|
|
8181
|
+
const suggestedBufferSize = iterator.getUint32Le();
|
|
8182
|
+
const quality = iterator.getUint32Le();
|
|
8183
|
+
const sampleSize = iterator.getUint32Le();
|
|
8184
|
+
box.discardRest();
|
|
8185
|
+
return {
|
|
8186
|
+
type: "strh-box",
|
|
8187
|
+
fccType,
|
|
8188
|
+
handler,
|
|
8189
|
+
flags,
|
|
8190
|
+
priority,
|
|
8191
|
+
initialFrames,
|
|
8192
|
+
length,
|
|
8193
|
+
quality,
|
|
8194
|
+
rate,
|
|
8195
|
+
sampleSize,
|
|
8196
|
+
scale,
|
|
8197
|
+
start,
|
|
8198
|
+
suggestedBufferSize,
|
|
8199
|
+
language: language2
|
|
8200
|
+
};
|
|
8201
|
+
};
|
|
8202
|
+
|
|
8203
|
+
// src/boxes/riff/parse-riff-box.ts
|
|
8204
|
+
var parseRiffBox = ({
|
|
8205
|
+
iterator,
|
|
8206
|
+
size,
|
|
8207
|
+
id,
|
|
8208
|
+
boxes,
|
|
8209
|
+
options
|
|
8210
|
+
}) => {
|
|
8211
|
+
if (id === "fmt") {
|
|
8212
|
+
return Promise.resolve(parseFmtBox({ iterator, boxes, size }));
|
|
8213
|
+
}
|
|
8214
|
+
if (id === "LIST") {
|
|
8215
|
+
return parseListBox({ iterator, size, options });
|
|
8216
|
+
}
|
|
8217
|
+
if (id === "avih") {
|
|
8218
|
+
return Promise.resolve(parseAvih({ iterator, size }));
|
|
8219
|
+
}
|
|
8220
|
+
if (id === "strh") {
|
|
8221
|
+
return Promise.resolve(parseStrh({ iterator, size }));
|
|
8222
|
+
}
|
|
8223
|
+
if (id === "strf") {
|
|
8224
|
+
return Promise.resolve(parseStrf({ iterator, size, boxes }));
|
|
8225
|
+
}
|
|
8226
|
+
iterator.discard(size);
|
|
8227
|
+
const box = {
|
|
8228
|
+
type: "riff-box",
|
|
8229
|
+
size,
|
|
8230
|
+
id
|
|
8231
|
+
};
|
|
8232
|
+
return Promise.resolve(box);
|
|
8233
|
+
};
|
|
8234
|
+
|
|
8235
|
+
// src/boxes/riff/expect-riff-box.ts
|
|
8236
|
+
var expectRiffBox = async ({
|
|
8237
|
+
iterator,
|
|
8238
|
+
options,
|
|
8239
|
+
structure
|
|
8240
|
+
}) => {
|
|
8241
|
+
if (iterator.bytesRemaining() < 16) {
|
|
8242
|
+
return {
|
|
8243
|
+
type: "incomplete",
|
|
8244
|
+
continueParsing() {
|
|
8245
|
+
return expectRiffBox({ structure, iterator, options });
|
|
8246
|
+
}
|
|
8247
|
+
};
|
|
8248
|
+
}
|
|
8249
|
+
const ckId = iterator.getByteString(4);
|
|
8250
|
+
const ckSize = iterator.getUint32Le();
|
|
8251
|
+
if (isMoviAtom(iterator, ckId)) {
|
|
8252
|
+
iterator.discard(4);
|
|
8253
|
+
return parseMovi({
|
|
8254
|
+
iterator,
|
|
8255
|
+
maxOffset: ckSize + iterator.counter.getOffset() - 4,
|
|
8256
|
+
options,
|
|
8257
|
+
structure
|
|
8258
|
+
});
|
|
8259
|
+
}
|
|
8260
|
+
if (iterator.bytesRemaining() < ckSize) {
|
|
8261
|
+
iterator.counter.decrement(8);
|
|
8262
|
+
return {
|
|
8263
|
+
type: "incomplete",
|
|
8264
|
+
continueParsing: () => {
|
|
8265
|
+
return expectRiffBox({ structure, iterator, options });
|
|
8266
|
+
}
|
|
8267
|
+
};
|
|
8268
|
+
}
|
|
8269
|
+
return {
|
|
8270
|
+
type: "complete",
|
|
8271
|
+
box: await parseRiffBox({
|
|
8272
|
+
id: ckId,
|
|
8273
|
+
iterator,
|
|
8274
|
+
size: ckSize,
|
|
8275
|
+
boxes: structure.boxes,
|
|
8276
|
+
options
|
|
8277
|
+
})
|
|
8278
|
+
};
|
|
8279
|
+
};
|
|
8280
|
+
|
|
8281
|
+
// src/boxes/riff/parse-box.ts
|
|
8282
|
+
var continueAfterRiffBoxResult = ({
|
|
8283
|
+
result,
|
|
8284
|
+
structure,
|
|
8285
|
+
iterator,
|
|
8286
|
+
maxOffset,
|
|
8287
|
+
options
|
|
8288
|
+
}) => {
|
|
8289
|
+
if (result.type === "incomplete") {
|
|
8290
|
+
return Promise.resolve({
|
|
8291
|
+
status: "incomplete",
|
|
8292
|
+
async continueParsing() {
|
|
8293
|
+
return Promise.resolve(continueAfterRiffBoxResult({
|
|
8294
|
+
result: await result.continueParsing(),
|
|
8295
|
+
structure,
|
|
8296
|
+
iterator,
|
|
8297
|
+
maxOffset,
|
|
8298
|
+
options
|
|
8299
|
+
}));
|
|
8300
|
+
},
|
|
8301
|
+
segments: structure,
|
|
8302
|
+
skipTo: null
|
|
8303
|
+
});
|
|
8304
|
+
}
|
|
8305
|
+
if (result.type === "complete") {
|
|
8306
|
+
if (result.box) {
|
|
8307
|
+
structure.boxes.push(result.box);
|
|
8308
|
+
}
|
|
8309
|
+
}
|
|
8310
|
+
return parseRiffBody({ iterator, maxOffset, options, structure });
|
|
8311
|
+
};
|
|
8312
|
+
var parseRiffBody = async ({
|
|
8313
|
+
iterator,
|
|
8314
|
+
structure,
|
|
8315
|
+
maxOffset,
|
|
8316
|
+
options
|
|
8317
|
+
}) => {
|
|
8318
|
+
while (iterator.bytesRemaining() > 0 && iterator.counter.getOffset() < maxOffset) {
|
|
8319
|
+
const result = await expectRiffBox({
|
|
8320
|
+
iterator,
|
|
8321
|
+
options,
|
|
8322
|
+
structure
|
|
8323
|
+
});
|
|
8324
|
+
if (result.type === "incomplete") {
|
|
8325
|
+
return {
|
|
8326
|
+
status: "incomplete",
|
|
8327
|
+
async continueParsing() {
|
|
8328
|
+
return Promise.resolve(continueAfterRiffBoxResult({
|
|
8329
|
+
iterator,
|
|
8330
|
+
maxOffset,
|
|
8331
|
+
options,
|
|
8332
|
+
result: await result.continueParsing(),
|
|
8333
|
+
structure
|
|
8334
|
+
}));
|
|
8335
|
+
},
|
|
8336
|
+
segments: structure,
|
|
8337
|
+
skipTo: null
|
|
8338
|
+
};
|
|
8339
|
+
}
|
|
8340
|
+
if (result.box === null) {
|
|
8341
|
+
continue;
|
|
8342
|
+
}
|
|
8343
|
+
structure.boxes.push(result.box);
|
|
8344
|
+
if (result.box.type === "strf-box-video" || result.box.type === "strf-box-audio") {
|
|
8345
|
+
const strh = getStrhBox(structure.boxes);
|
|
8346
|
+
const strf = getStrfBox(structure.boxes);
|
|
8347
|
+
if (!strh || !strf) {
|
|
8348
|
+
throw new Error("strh or strf box missing");
|
|
8349
|
+
}
|
|
8350
|
+
if (strf.type === "strf-box-audio" && options.onAudioTrack) {
|
|
8351
|
+
const audioTrack = makeAviAudioTrack({
|
|
8352
|
+
index: options.nextTrackIndex,
|
|
8353
|
+
strf
|
|
8354
|
+
});
|
|
8355
|
+
await registerTrack({
|
|
8356
|
+
options,
|
|
8357
|
+
state: options.parserState,
|
|
8358
|
+
track: audioTrack
|
|
8359
|
+
});
|
|
8360
|
+
}
|
|
8361
|
+
if (options.onVideoTrack && strf.type === "strf-box-video") {
|
|
8362
|
+
const videoTrack = makeAviVideoTrack({
|
|
8363
|
+
strh,
|
|
8364
|
+
index: options.nextTrackIndex,
|
|
8365
|
+
strf
|
|
8366
|
+
});
|
|
8367
|
+
registerVideoTrackWhenProfileIsAvailable({
|
|
8368
|
+
options,
|
|
8369
|
+
state: options.parserState,
|
|
8370
|
+
track: videoTrack
|
|
8371
|
+
});
|
|
8372
|
+
}
|
|
8373
|
+
options.nextTrackIndex++;
|
|
8374
|
+
}
|
|
7338
8375
|
}
|
|
8376
|
+
return {
|
|
8377
|
+
status: "done",
|
|
8378
|
+
segments: structure
|
|
8379
|
+
};
|
|
8380
|
+
};
|
|
8381
|
+
var parseRiff = ({
|
|
8382
|
+
iterator,
|
|
8383
|
+
options
|
|
8384
|
+
}) => {
|
|
8385
|
+
const structure = { type: "riff", boxes: [] };
|
|
8386
|
+
const riff = iterator.getByteString(4);
|
|
8387
|
+
if (riff !== "RIFF") {
|
|
8388
|
+
throw new Error("Not a RIFF file");
|
|
8389
|
+
}
|
|
8390
|
+
const size = iterator.getUint32Le();
|
|
8391
|
+
const fileType = iterator.getByteString(4);
|
|
8392
|
+
if (fileType !== "WAVE" && fileType !== "AVI") {
|
|
8393
|
+
throw new Error(`File type ${fileType} not supported`);
|
|
8394
|
+
}
|
|
8395
|
+
structure.boxes.push({ type: "riff-header", fileSize: size, fileType });
|
|
8396
|
+
return parseRiffBody({ iterator, structure, maxOffset: Infinity, options });
|
|
7339
8397
|
};
|
|
7340
8398
|
|
|
7341
8399
|
// src/boxes/webm/segments/block-simple-block-flags.ts
|
|
@@ -7605,32 +8663,54 @@ var postprocessEbml = async ({
|
|
|
7605
8663
|
};
|
|
7606
8664
|
|
|
7607
8665
|
// src/boxes/webm/segments.ts
|
|
7608
|
-
var
|
|
7609
|
-
|
|
8666
|
+
var continueAfterMatroskaParseResult = async ({
|
|
8667
|
+
result,
|
|
7610
8668
|
iterator,
|
|
7611
|
-
length,
|
|
7612
8669
|
parserContext,
|
|
7613
|
-
|
|
8670
|
+
segment
|
|
7614
8671
|
}) => {
|
|
7615
|
-
if (
|
|
7616
|
-
throw new Error(
|
|
8672
|
+
if (result.status === "done") {
|
|
8673
|
+
throw new Error("Should not continue after done");
|
|
7617
8674
|
}
|
|
7618
|
-
|
|
7619
|
-
|
|
7620
|
-
|
|
7621
|
-
|
|
7622
|
-
|
|
8675
|
+
const proceeded = await result.continueParsing();
|
|
8676
|
+
if (proceeded.status === "done") {
|
|
8677
|
+
return {
|
|
8678
|
+
status: "done",
|
|
8679
|
+
segment
|
|
8680
|
+
};
|
|
8681
|
+
}
|
|
8682
|
+
return {
|
|
8683
|
+
continueParsing() {
|
|
8684
|
+
return continueAfterMatroskaParseResult({
|
|
8685
|
+
result: proceeded,
|
|
8686
|
+
iterator,
|
|
8687
|
+
parserContext,
|
|
8688
|
+
segment
|
|
8689
|
+
});
|
|
8690
|
+
},
|
|
8691
|
+
segment: null,
|
|
8692
|
+
status: "incomplete"
|
|
8693
|
+
};
|
|
7623
8694
|
};
|
|
7624
|
-
var expectSegment = async (
|
|
7625
|
-
|
|
8695
|
+
var expectSegment = async ({
|
|
8696
|
+
iterator,
|
|
8697
|
+
parserContext,
|
|
8698
|
+
offset,
|
|
8699
|
+
children
|
|
8700
|
+
}) => {
|
|
8701
|
+
iterator.counter.decrement(iterator.counter.getOffset() - offset);
|
|
7626
8702
|
if (iterator.bytesRemaining() === 0) {
|
|
7627
8703
|
return {
|
|
7628
8704
|
status: "incomplete",
|
|
7629
|
-
segments: [],
|
|
7630
8705
|
continueParsing: () => {
|
|
7631
|
-
return
|
|
8706
|
+
return expectAndProcessSegment({
|
|
8707
|
+
iterator,
|
|
8708
|
+
parserContext,
|
|
8709
|
+
offset,
|
|
8710
|
+
children
|
|
8711
|
+
});
|
|
7632
8712
|
},
|
|
7633
|
-
|
|
8713
|
+
segment: null
|
|
7634
8714
|
};
|
|
7635
8715
|
}
|
|
7636
8716
|
const segmentId = iterator.getMatroskaSegmentId();
|
|
@@ -7638,11 +8718,15 @@ var expectSegment = async (iterator, parserContext) => {
|
|
|
7638
8718
|
iterator.counter.decrement(iterator.counter.getOffset() - offset);
|
|
7639
8719
|
return {
|
|
7640
8720
|
status: "incomplete",
|
|
7641
|
-
segments: [],
|
|
7642
8721
|
continueParsing: () => {
|
|
7643
|
-
return
|
|
8722
|
+
return expectAndProcessSegment({
|
|
8723
|
+
iterator,
|
|
8724
|
+
parserContext,
|
|
8725
|
+
offset,
|
|
8726
|
+
children
|
|
8727
|
+
});
|
|
7644
8728
|
},
|
|
7645
|
-
|
|
8729
|
+
segment: null
|
|
7646
8730
|
};
|
|
7647
8731
|
}
|
|
7648
8732
|
const offsetBeforeVInt = iterator.counter.getOffset();
|
|
@@ -7652,41 +8736,43 @@ var expectSegment = async (iterator, parserContext) => {
|
|
|
7652
8736
|
iterator.counter.decrement(iterator.counter.getOffset() - offset);
|
|
7653
8737
|
return {
|
|
7654
8738
|
status: "incomplete",
|
|
7655
|
-
segments: [],
|
|
7656
8739
|
continueParsing: () => {
|
|
7657
|
-
return
|
|
8740
|
+
return expectSegment({ iterator, parserContext, offset, children });
|
|
7658
8741
|
},
|
|
7659
|
-
|
|
8742
|
+
segment: null
|
|
7660
8743
|
};
|
|
7661
8744
|
}
|
|
7662
8745
|
const bytesRemainingNow = iterator.byteLength() - iterator.counter.getOffset();
|
|
7663
8746
|
if (segmentId === "0x18538067" || segmentId === "0x1f43b675") {
|
|
8747
|
+
const newSegment = {
|
|
8748
|
+
type: segmentId === "0x18538067" ? "Segment" : "Cluster",
|
|
8749
|
+
minVintWidth: offsetAfterVInt - offsetBeforeVInt,
|
|
8750
|
+
value: []
|
|
8751
|
+
};
|
|
7664
8752
|
const main = await expectChildren({
|
|
7665
8753
|
iterator,
|
|
7666
8754
|
length,
|
|
7667
|
-
|
|
7668
|
-
|
|
7669
|
-
|
|
7670
|
-
value: s,
|
|
7671
|
-
minVintWidth: offsetAfterVInt - offsetBeforeVInt
|
|
7672
|
-
}) : (s) => ({
|
|
7673
|
-
type: "Cluster",
|
|
7674
|
-
value: s,
|
|
7675
|
-
minVintWidth: offsetAfterVInt - offsetBeforeVInt
|
|
7676
|
-
}),
|
|
7677
|
-
parserContext
|
|
8755
|
+
children: newSegment.value,
|
|
8756
|
+
parserContext,
|
|
8757
|
+
startOffset: iterator.counter.getOffset()
|
|
7678
8758
|
});
|
|
7679
8759
|
if (main.status === "incomplete") {
|
|
7680
8760
|
return {
|
|
7681
8761
|
status: "incomplete",
|
|
7682
|
-
|
|
7683
|
-
|
|
7684
|
-
|
|
8762
|
+
continueParsing: () => {
|
|
8763
|
+
return continueAfterMatroskaParseResult({
|
|
8764
|
+
iterator,
|
|
8765
|
+
parserContext,
|
|
8766
|
+
result: main,
|
|
8767
|
+
segment: newSegment
|
|
8768
|
+
});
|
|
8769
|
+
},
|
|
8770
|
+
segment: newSegment
|
|
7685
8771
|
};
|
|
7686
8772
|
}
|
|
7687
8773
|
return {
|
|
7688
8774
|
status: "done",
|
|
7689
|
-
|
|
8775
|
+
segment: newSegment
|
|
7690
8776
|
};
|
|
7691
8777
|
}
|
|
7692
8778
|
if (bytesRemainingNow < length) {
|
|
@@ -7694,11 +8780,10 @@ var expectSegment = async (iterator, parserContext) => {
|
|
|
7694
8780
|
iterator.counter.decrement(bytesRead);
|
|
7695
8781
|
return {
|
|
7696
8782
|
status: "incomplete",
|
|
7697
|
-
|
|
8783
|
+
segment: null,
|
|
7698
8784
|
continueParsing: () => {
|
|
7699
|
-
return
|
|
7700
|
-
}
|
|
7701
|
-
skipTo: null
|
|
8785
|
+
return expectSegment({ iterator, parserContext, offset, children });
|
|
8786
|
+
}
|
|
7702
8787
|
};
|
|
7703
8788
|
}
|
|
7704
8789
|
const segment = await parseSegment({
|
|
@@ -7710,131 +8795,179 @@ var expectSegment = async (iterator, parserContext) => {
|
|
|
7710
8795
|
});
|
|
7711
8796
|
return {
|
|
7712
8797
|
status: "done",
|
|
7713
|
-
|
|
8798
|
+
segment
|
|
7714
8799
|
};
|
|
7715
8800
|
};
|
|
8801
|
+
var parseSegment = async ({
|
|
8802
|
+
segmentId,
|
|
8803
|
+
iterator,
|
|
8804
|
+
length,
|
|
8805
|
+
parserContext,
|
|
8806
|
+
headerReadSoFar
|
|
8807
|
+
}) => {
|
|
8808
|
+
if (length < 0) {
|
|
8809
|
+
throw new Error(`Expected length of ${segmentId} to be greater or equal 0`);
|
|
8810
|
+
}
|
|
8811
|
+
iterator.counter.decrement(headerReadSoFar);
|
|
8812
|
+
const offset = iterator.counter.getOffset();
|
|
8813
|
+
const ebml = await parseEbml(iterator, parserContext);
|
|
8814
|
+
const remapped = await postprocessEbml({ offset, ebml, parserContext });
|
|
8815
|
+
return remapped;
|
|
8816
|
+
};
|
|
7716
8817
|
|
|
7717
8818
|
// src/boxes/webm/segments/parse-children.ts
|
|
7718
8819
|
var processParseResult = ({
|
|
7719
8820
|
parseResult,
|
|
7720
|
-
children
|
|
7721
|
-
wrap
|
|
8821
|
+
children
|
|
7722
8822
|
}) => {
|
|
8823
|
+
if (parseResult.segment && !children.includes(parseResult.segment)) {
|
|
8824
|
+
children.push(parseResult.segment);
|
|
8825
|
+
}
|
|
7723
8826
|
if (parseResult.status === "incomplete") {
|
|
7724
8827
|
return {
|
|
7725
8828
|
status: "incomplete",
|
|
7726
|
-
|
|
8829
|
+
segment: parseResult.segment,
|
|
7727
8830
|
continueParsing: async () => {
|
|
7728
8831
|
const newParseResult = await parseResult.continueParsing();
|
|
7729
8832
|
return processParseResult({
|
|
7730
8833
|
children,
|
|
7731
|
-
parseResult: newParseResult
|
|
7732
|
-
wrap
|
|
8834
|
+
parseResult: newParseResult
|
|
7733
8835
|
});
|
|
7734
|
-
}
|
|
7735
|
-
skipTo: null
|
|
8836
|
+
}
|
|
7736
8837
|
};
|
|
7737
8838
|
}
|
|
7738
|
-
for (const segment of parseResult.segments) {
|
|
7739
|
-
children.push(segment);
|
|
7740
|
-
}
|
|
7741
8839
|
return {
|
|
7742
8840
|
status: "done",
|
|
7743
|
-
|
|
8841
|
+
segment: parseResult.segment
|
|
7744
8842
|
};
|
|
7745
8843
|
};
|
|
7746
|
-
var
|
|
7747
|
-
result,
|
|
8844
|
+
var expectAndProcessSegment = async ({
|
|
7748
8845
|
iterator,
|
|
8846
|
+
parserContext,
|
|
8847
|
+
offset,
|
|
8848
|
+
children
|
|
8849
|
+
}) => {
|
|
8850
|
+
const segment = await expectSegment({
|
|
8851
|
+
iterator,
|
|
8852
|
+
parserContext,
|
|
8853
|
+
offset,
|
|
8854
|
+
children
|
|
8855
|
+
});
|
|
8856
|
+
return processParseResult({
|
|
8857
|
+
children,
|
|
8858
|
+
parseResult: segment
|
|
8859
|
+
});
|
|
8860
|
+
};
|
|
8861
|
+
var continueAfterSegmentResult = async ({
|
|
8862
|
+
result,
|
|
8863
|
+
length,
|
|
7749
8864
|
children,
|
|
7750
|
-
wrap,
|
|
7751
8865
|
parserContext,
|
|
7752
|
-
|
|
7753
|
-
|
|
7754
|
-
|
|
7755
|
-
|
|
8866
|
+
iterator,
|
|
8867
|
+
startOffset
|
|
8868
|
+
}) => {
|
|
8869
|
+
if (result.status === "done") {
|
|
8870
|
+
throw new Error("Should not continue after done");
|
|
7756
8871
|
}
|
|
7757
|
-
const
|
|
7758
|
-
|
|
7759
|
-
if (continued.status === "incomplete") {
|
|
7760
|
-
if (!parserContext.supportsContentRange) {
|
|
7761
|
-
throw new Error("Content-Range header is not supported by the reader, but was asked to seek");
|
|
7762
|
-
}
|
|
8872
|
+
const segmentResult = await result.continueParsing();
|
|
8873
|
+
if (segmentResult.status === "done") {
|
|
7763
8874
|
return {
|
|
7764
8875
|
status: "incomplete",
|
|
7765
|
-
continueParsing:
|
|
7766
|
-
|
|
7767
|
-
|
|
7768
|
-
|
|
7769
|
-
|
|
7770
|
-
|
|
7771
|
-
|
|
7772
|
-
|
|
7773
|
-
|
|
7774
|
-
|
|
8876
|
+
continueParsing: () => {
|
|
8877
|
+
return expectChildren({
|
|
8878
|
+
children,
|
|
8879
|
+
iterator,
|
|
8880
|
+
length,
|
|
8881
|
+
parserContext,
|
|
8882
|
+
startOffset
|
|
8883
|
+
});
|
|
8884
|
+
},
|
|
8885
|
+
skipTo: null
|
|
7775
8886
|
};
|
|
7776
8887
|
}
|
|
7777
|
-
return
|
|
7778
|
-
|
|
7779
|
-
|
|
7780
|
-
|
|
7781
|
-
|
|
7782
|
-
|
|
7783
|
-
|
|
8888
|
+
return {
|
|
8889
|
+
status: "incomplete",
|
|
8890
|
+
continueParsing: () => {
|
|
8891
|
+
return continueAfterSegmentResult({
|
|
8892
|
+
result: segmentResult,
|
|
8893
|
+
children,
|
|
8894
|
+
iterator,
|
|
8895
|
+
length,
|
|
8896
|
+
parserContext,
|
|
8897
|
+
startOffset
|
|
8898
|
+
});
|
|
8899
|
+
},
|
|
8900
|
+
skipTo: null
|
|
8901
|
+
};
|
|
7784
8902
|
};
|
|
7785
8903
|
var expectChildren = async ({
|
|
7786
8904
|
iterator,
|
|
7787
8905
|
length,
|
|
7788
|
-
|
|
7789
|
-
|
|
7790
|
-
|
|
8906
|
+
children,
|
|
8907
|
+
parserContext,
|
|
8908
|
+
startOffset
|
|
7791
8909
|
}) => {
|
|
7792
|
-
const children = [...initialChildren];
|
|
7793
|
-
const startOffset = iterator.counter.getOffset();
|
|
7794
8910
|
while (iterator.counter.getOffset() < startOffset + length) {
|
|
7795
8911
|
if (iterator.bytesRemaining() === 0) {
|
|
7796
8912
|
break;
|
|
7797
8913
|
}
|
|
7798
|
-
const
|
|
7799
|
-
const child =
|
|
7800
|
-
|
|
7801
|
-
|
|
7802
|
-
|
|
8914
|
+
const currentOffset = iterator.counter.getOffset();
|
|
8915
|
+
const child = await expectAndProcessSegment({
|
|
8916
|
+
iterator,
|
|
8917
|
+
parserContext,
|
|
8918
|
+
offset: currentOffset,
|
|
8919
|
+
children
|
|
7803
8920
|
});
|
|
7804
8921
|
if (child.status === "incomplete") {
|
|
7805
|
-
if (!parserContext.supportsContentRange) {
|
|
7806
|
-
throw new Error("Content-Range header is not supported by the reader, but was asked to seek");
|
|
7807
|
-
}
|
|
7808
8922
|
return {
|
|
7809
8923
|
status: "incomplete",
|
|
7810
|
-
continueParsing:
|
|
7811
|
-
|
|
7812
|
-
|
|
7813
|
-
|
|
7814
|
-
|
|
7815
|
-
|
|
7816
|
-
|
|
7817
|
-
|
|
7818
|
-
|
|
7819
|
-
|
|
8924
|
+
continueParsing: () => {
|
|
8925
|
+
return continueAfterSegmentResult({
|
|
8926
|
+
result: child,
|
|
8927
|
+
children,
|
|
8928
|
+
iterator,
|
|
8929
|
+
length: length - (currentOffset - startOffset),
|
|
8930
|
+
parserContext,
|
|
8931
|
+
startOffset: currentOffset
|
|
8932
|
+
});
|
|
8933
|
+
},
|
|
8934
|
+
skipTo: null
|
|
7820
8935
|
};
|
|
7821
8936
|
}
|
|
7822
8937
|
}
|
|
7823
8938
|
return {
|
|
7824
|
-
status: "done"
|
|
7825
|
-
segments: wrap ? [wrap(children)] : children
|
|
8939
|
+
status: "done"
|
|
7826
8940
|
};
|
|
7827
8941
|
};
|
|
7828
8942
|
|
|
7829
8943
|
// src/boxes/webm/parse-webm-header.ts
|
|
7830
|
-
var
|
|
7831
|
-
|
|
8944
|
+
var continueAfterMatroskaResult = (result, structure) => {
|
|
8945
|
+
if (result.status === "done") {
|
|
8946
|
+
return {
|
|
8947
|
+
status: "done",
|
|
8948
|
+
segments: structure
|
|
8949
|
+
};
|
|
8950
|
+
}
|
|
8951
|
+
return {
|
|
8952
|
+
status: "incomplete",
|
|
8953
|
+
segments: structure,
|
|
8954
|
+
continueParsing: async () => {
|
|
8955
|
+
const newResult = await result.continueParsing();
|
|
8956
|
+
return continueAfterMatroskaResult(newResult, structure);
|
|
8957
|
+
},
|
|
8958
|
+
skipTo: null
|
|
8959
|
+
};
|
|
8960
|
+
};
|
|
8961
|
+
var parseWebm = async (counter, parserContext) => {
|
|
8962
|
+
const structure = { type: "matroska", boxes: [] };
|
|
8963
|
+
const results = await expectChildren({
|
|
7832
8964
|
iterator: counter,
|
|
7833
8965
|
length: Infinity,
|
|
7834
|
-
|
|
7835
|
-
|
|
7836
|
-
|
|
8966
|
+
children: structure.boxes,
|
|
8967
|
+
parserContext,
|
|
8968
|
+
startOffset: counter.counter.getOffset()
|
|
7837
8969
|
});
|
|
8970
|
+
return continueAfterMatroskaResult(results, structure);
|
|
7838
8971
|
};
|
|
7839
8972
|
|
|
7840
8973
|
// src/parse-video.ts
|
|
@@ -7845,25 +8978,14 @@ var parseVideo = ({
|
|
|
7845
8978
|
logLevel
|
|
7846
8979
|
}) => {
|
|
7847
8980
|
if (iterator.bytesRemaining() === 0) {
|
|
7848
|
-
return Promise.
|
|
7849
|
-
status: "incomplete",
|
|
7850
|
-
segments: [],
|
|
7851
|
-
continueParsing: () => {
|
|
7852
|
-
return parseVideo({
|
|
7853
|
-
iterator,
|
|
7854
|
-
options,
|
|
7855
|
-
signal,
|
|
7856
|
-
logLevel
|
|
7857
|
-
});
|
|
7858
|
-
},
|
|
7859
|
-
skipTo: null
|
|
7860
|
-
});
|
|
8981
|
+
return Promise.reject(new Error("no bytes"));
|
|
7861
8982
|
}
|
|
7862
8983
|
if (iterator.isRiff()) {
|
|
7863
|
-
|
|
8984
|
+
return Promise.resolve(parseRiff({ iterator, options }));
|
|
7864
8985
|
}
|
|
7865
8986
|
if (iterator.isIsoBaseMedia()) {
|
|
7866
|
-
|
|
8987
|
+
Log.verbose(logLevel, "Detected ISO Base Media container");
|
|
8988
|
+
return parseIsoBaseMediaBoxes({
|
|
7867
8989
|
iterator,
|
|
7868
8990
|
maxBytes: Infinity,
|
|
7869
8991
|
allowIncompleteBoxes: true,
|
|
@@ -7875,7 +8997,8 @@ var parseVideo = ({
|
|
|
7875
8997
|
});
|
|
7876
8998
|
}
|
|
7877
8999
|
if (iterator.isWebm()) {
|
|
7878
|
-
|
|
9000
|
+
Log.verbose(logLevel, "Detected Matroska container");
|
|
9001
|
+
return parseWebm(iterator, options);
|
|
7879
9002
|
}
|
|
7880
9003
|
if (iterator.isMp3()) {
|
|
7881
9004
|
return Promise.reject(new Error("MP3 files are not yet supported"));
|
|
@@ -7940,8 +9063,23 @@ var makeParserState = ({
|
|
|
7940
9063
|
}
|
|
7941
9064
|
return timestampMap.get(byteOffset);
|
|
7942
9065
|
};
|
|
9066
|
+
const samplesForTrack = {};
|
|
9067
|
+
const profileCallbacks = [];
|
|
9068
|
+
const registerOnAvcProfileCallback = (callback) => {
|
|
9069
|
+
profileCallbacks.push(callback);
|
|
9070
|
+
};
|
|
9071
|
+
let avcProfile = null;
|
|
9072
|
+
const onProfile = async (profile) => {
|
|
9073
|
+
avcProfile = profile;
|
|
9074
|
+
for (const callback of profileCallbacks) {
|
|
9075
|
+
await callback(profile);
|
|
9076
|
+
}
|
|
9077
|
+
profileCallbacks.length = 0;
|
|
9078
|
+
};
|
|
7943
9079
|
return {
|
|
7944
9080
|
onTrackEntrySegment,
|
|
9081
|
+
onProfile,
|
|
9082
|
+
registerOnAvcProfileCallback,
|
|
7945
9083
|
getTrackInfoByNumber: (id) => trackEntries[id],
|
|
7946
9084
|
registerVideoSampleCallback: async (id, callback) => {
|
|
7947
9085
|
if (callback === null) {
|
|
@@ -7973,6 +9111,10 @@ var makeParserState = ({
|
|
|
7973
9111
|
if (signal?.aborted) {
|
|
7974
9112
|
throw new Error("Aborted");
|
|
7975
9113
|
}
|
|
9114
|
+
if (typeof samplesForTrack[trackId] === "undefined") {
|
|
9115
|
+
samplesForTrack[trackId] = 0;
|
|
9116
|
+
}
|
|
9117
|
+
samplesForTrack[trackId]++;
|
|
7976
9118
|
const callback = audioSampleCallbacks[trackId];
|
|
7977
9119
|
if (callback) {
|
|
7978
9120
|
await callback(audioSample);
|
|
@@ -7989,6 +9131,10 @@ var makeParserState = ({
|
|
|
7989
9131
|
if (signal?.aborted) {
|
|
7990
9132
|
throw new Error("Aborted");
|
|
7991
9133
|
}
|
|
9134
|
+
if (typeof samplesForTrack[trackId] === "undefined") {
|
|
9135
|
+
samplesForTrack[trackId] = 0;
|
|
9136
|
+
}
|
|
9137
|
+
samplesForTrack[trackId]++;
|
|
7992
9138
|
const callback = videoSampleCallbacks[trackId];
|
|
7993
9139
|
if (callback) {
|
|
7994
9140
|
await callback(videoSample);
|
|
@@ -8003,7 +9149,13 @@ var makeParserState = ({
|
|
|
8003
9149
|
},
|
|
8004
9150
|
getInternalStats: () => ({}),
|
|
8005
9151
|
getTimescale,
|
|
8006
|
-
setTimescale
|
|
9152
|
+
setTimescale,
|
|
9153
|
+
getSamplesForTrack: (trackId) => {
|
|
9154
|
+
return samplesForTrack[trackId] ?? 0;
|
|
9155
|
+
},
|
|
9156
|
+
getAvcProfile: () => {
|
|
9157
|
+
return avcProfile;
|
|
9158
|
+
}
|
|
8007
9159
|
};
|
|
8008
9160
|
};
|
|
8009
9161
|
|
|
@@ -8016,6 +9168,7 @@ var parseMedia = async ({
|
|
|
8016
9168
|
onVideoTrack,
|
|
8017
9169
|
signal,
|
|
8018
9170
|
logLevel = "info",
|
|
9171
|
+
onParseProgress,
|
|
8019
9172
|
...more
|
|
8020
9173
|
}) => {
|
|
8021
9174
|
const state = makeParserState({
|
|
@@ -8035,14 +9188,41 @@ var parseMedia = async ({
|
|
|
8035
9188
|
const moreFields = more;
|
|
8036
9189
|
let iterator = null;
|
|
8037
9190
|
let parseResult = null;
|
|
9191
|
+
const canSkipVideoData = !onVideoTrack && !onAudioTrack;
|
|
9192
|
+
if (canSkipVideoData) {
|
|
9193
|
+
Log.verbose(logLevel, "Only parsing metadata, because no onVideoTrack and onAudioTrack callbacks were passed.");
|
|
9194
|
+
} else {
|
|
9195
|
+
Log.verbose(logLevel, "Parsing video data, because onVideoTrack/onAudioTrack callbacks were passed.");
|
|
9196
|
+
}
|
|
8038
9197
|
const options = {
|
|
8039
|
-
canSkipVideoData
|
|
9198
|
+
canSkipVideoData,
|
|
8040
9199
|
onAudioTrack: onAudioTrack ?? null,
|
|
8041
9200
|
onVideoTrack: onVideoTrack ?? null,
|
|
8042
9201
|
parserState: state,
|
|
8043
9202
|
nullifySamples: !(typeof process !== "undefined" && typeof process.env !== "undefined" && process.env.KEEP_SAMPLES === "true"),
|
|
8044
|
-
supportsContentRange
|
|
9203
|
+
supportsContentRange,
|
|
9204
|
+
nextTrackIndex: 0
|
|
9205
|
+
};
|
|
9206
|
+
const hasAllInfo = () => {
|
|
9207
|
+
if (parseResult === null) {
|
|
9208
|
+
return false;
|
|
9209
|
+
}
|
|
9210
|
+
const availableInfo = getAvailableInfo(fields ?? {}, parseResult, state);
|
|
9211
|
+
return Object.values(availableInfo).every(Boolean);
|
|
9212
|
+
};
|
|
9213
|
+
const triggerInfoEmit = () => {
|
|
9214
|
+
const availableInfo = getAvailableInfo(fields ?? {}, parseResult, state);
|
|
9215
|
+
emitAvailableInfo({
|
|
9216
|
+
hasInfo: availableInfo,
|
|
9217
|
+
moreFields,
|
|
9218
|
+
parseResult,
|
|
9219
|
+
state,
|
|
9220
|
+
returnValue,
|
|
9221
|
+
contentLength,
|
|
9222
|
+
name
|
|
9223
|
+
});
|
|
8045
9224
|
};
|
|
9225
|
+
triggerInfoEmit();
|
|
8046
9226
|
while (parseResult === null || parseResult.status === "incomplete") {
|
|
8047
9227
|
if (signal?.aborted) {
|
|
8048
9228
|
throw new Error("Aborted");
|
|
@@ -8069,7 +9249,14 @@ var parseMedia = async ({
|
|
|
8069
9249
|
if (!iterator) {
|
|
8070
9250
|
throw new Error("Unexpected null");
|
|
8071
9251
|
}
|
|
9252
|
+
await onParseProgress?.({
|
|
9253
|
+
bytes: iterator.counter.getOffset(),
|
|
9254
|
+
percentage: contentLength ? iterator.counter.getOffset() / contentLength : null,
|
|
9255
|
+
totalBytes: contentLength
|
|
9256
|
+
});
|
|
9257
|
+
triggerInfoEmit();
|
|
8072
9258
|
if (parseResult && parseResult.status === "incomplete") {
|
|
9259
|
+
Log.verbose(logLevel, "Continuing parsing of file, currently at position", iterator.counter.getOffset(), getAvailableInfo(fields ?? {}, parseResult, state));
|
|
8073
9260
|
parseResult = await parseResult.continueParsing();
|
|
8074
9261
|
} else {
|
|
8075
9262
|
parseResult = await parseVideo({
|
|
@@ -8079,18 +9266,7 @@ var parseMedia = async ({
|
|
|
8079
9266
|
logLevel
|
|
8080
9267
|
});
|
|
8081
9268
|
}
|
|
8082
|
-
|
|
8083
|
-
const hasAllInfo = Object.values(availableInfo).every(Boolean);
|
|
8084
|
-
emitAvailableInfo({
|
|
8085
|
-
hasInfo: availableInfo,
|
|
8086
|
-
moreFields,
|
|
8087
|
-
parseResult,
|
|
8088
|
-
state,
|
|
8089
|
-
returnValue,
|
|
8090
|
-
contentLength,
|
|
8091
|
-
name
|
|
8092
|
-
});
|
|
8093
|
-
if (hasAllInfo && !onVideoTrack && !onAudioTrack) {
|
|
9269
|
+
if (hasAllInfo() && !onVideoTrack && !onAudioTrack) {
|
|
8094
9270
|
break;
|
|
8095
9271
|
}
|
|
8096
9272
|
if (parseResult && parseResult.status === "incomplete" && parseResult.skipTo !== null) {
|
|
@@ -8103,6 +9279,7 @@ var parseMedia = async ({
|
|
|
8103
9279
|
iterator.skipTo(parseResult.skipTo, true);
|
|
8104
9280
|
}
|
|
8105
9281
|
}
|
|
9282
|
+
Log.verbose(logLevel, "Finished parsing file");
|
|
8106
9283
|
emitAvailableInfo({
|
|
8107
9284
|
hasInfo: Object.keys(fields ?? {}).reduce((acc, key) => {
|
|
8108
9285
|
acc[key] = true;
|
|
@@ -8119,13 +9296,18 @@ var parseMedia = async ({
|
|
|
8119
9296
|
iterator?.destroy();
|
|
8120
9297
|
return returnValue;
|
|
8121
9298
|
};
|
|
9299
|
+
// src/version.ts
|
|
9300
|
+
var VERSION = "4.0.232";
|
|
9301
|
+
|
|
8122
9302
|
// src/index.ts
|
|
8123
9303
|
var MediaParserInternals = {
|
|
8124
9304
|
createMatroskaMedia,
|
|
8125
9305
|
createIsoBaseMedia,
|
|
9306
|
+
createWav,
|
|
8126
9307
|
Log
|
|
8127
9308
|
};
|
|
8128
9309
|
export {
|
|
8129
9310
|
parseMedia,
|
|
9311
|
+
VERSION,
|
|
8130
9312
|
MediaParserInternals
|
|
8131
9313
|
};
|