@remotion/media-parser 4.0.234 → 4.0.236
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/aac-codecprivate.d.ts +19 -0
- package/dist/aac-codecprivate.js +122 -0
- package/dist/add-avc-profile-to-track.d.ts +1 -1
- package/dist/boxes/iso-base-media/get-actual-number-of-channels.d.ts +13 -0
- package/dist/boxes/iso-base-media/get-actual-number-of-channels.js +22 -0
- package/dist/boxes/iso-base-media/make-track.js +16 -7
- package/dist/boxes/iso-base-media/meta/hdlr.d.ts +12 -0
- package/dist/boxes/iso-base-media/meta/hdlr.js +33 -0
- package/dist/boxes/iso-base-media/meta/ilst.d.ts +28 -0
- package/dist/boxes/iso-base-media/meta/ilst.js +86 -0
- package/dist/boxes/iso-base-media/meta/keys.d.ts +10 -0
- package/dist/boxes/iso-base-media/meta/keys.js +17 -0
- package/dist/boxes/iso-base-media/meta/list.d.ts +12 -0
- package/dist/boxes/iso-base-media/meta/list.js +33 -0
- package/dist/boxes/iso-base-media/moov/moov.d.ts +3 -1
- package/dist/boxes/iso-base-media/moov/moov.js +2 -1
- package/dist/boxes/iso-base-media/process-box.d.ts +5 -2
- package/dist/boxes/iso-base-media/process-box.js +66 -8
- package/dist/boxes/iso-base-media/stsd/keys.d.ts +15 -1
- package/dist/boxes/iso-base-media/stsd/keys.js +25 -12
- package/dist/boxes/iso-base-media/stsd/mebx.d.ts +3 -1
- package/dist/boxes/iso-base-media/stsd/mebx.js +2 -1
- package/dist/boxes/iso-base-media/stsd/samples.d.ts +5 -2
- package/dist/boxes/iso-base-media/stsd/samples.js +7 -2
- package/dist/boxes/iso-base-media/stsd/stsd.d.ts +3 -1
- package/dist/boxes/iso-base-media/stsd/stsd.js +2 -1
- package/dist/boxes/iso-base-media/trak/trak.d.ts +3 -1
- package/dist/boxes/iso-base-media/trak/trak.js +2 -1
- package/dist/boxes/riff/expect-riff-box.d.ts +1 -0
- package/dist/boxes/riff/expect-riff-box.js +1 -1
- package/dist/boxes/riff/get-tracks-from-avi.d.ts +2 -1
- package/dist/boxes/riff/get-tracks-from-avi.js +14 -8
- package/dist/boxes/riff/parse-box.d.ts +3 -1
- package/dist/boxes/riff/parse-box.js +38 -5
- package/dist/boxes/riff/parse-isft.d.ts +6 -0
- package/dist/boxes/riff/parse-isft.js +17 -0
- package/dist/boxes/riff/parse-movi.js +31 -20
- package/dist/boxes/riff/parse-riff-box.js +4 -0
- package/dist/boxes/riff/riff-box.d.ts +5 -1
- package/dist/boxes/webm/parse-ebml.js +2 -1
- package/dist/boxes/webm/parse-webm-header.d.ts +6 -1
- package/dist/boxes/webm/parse-webm-header.js +3 -1
- package/dist/boxes/webm/segments/all-segments.d.ts +42 -2
- package/dist/boxes/webm/segments/all-segments.js +28 -3
- package/dist/boxes/webm/segments/parse-children.d.ts +8 -3
- package/dist/boxes/webm/segments/parse-children.js +39 -4
- package/dist/boxes/webm/segments.d.ts +5 -2
- package/dist/boxes/webm/segments.js +23 -3
- package/dist/boxes/webm/traversal.d.ts +1 -0
- package/dist/boxes/webm/traversal.js +18 -2
- package/dist/buffer-iterator.d.ts +3 -0
- package/dist/buffer-iterator.js +23 -0
- package/dist/create/iso-base-media/codec-specific/mp4a.js +1 -17
- package/dist/create/iso-base-media/mp4-header.js +2 -1
- package/dist/emit-available-info.d.ts +1 -1
- package/dist/emit-available-info.js +17 -6
- package/dist/esm/index.mjs +992 -162
- package/dist/get-audio-codec.d.ts +1 -1
- package/dist/get-dimensions.d.ts +1 -1
- package/dist/get-duration.d.ts +1 -1
- package/dist/get-is-hdr.d.ts +1 -1
- package/dist/get-metadata.d.ts +7 -0
- package/dist/get-metadata.js +63 -0
- package/dist/get-tracks.d.ts +1 -1
- package/dist/get-tracks.js +1 -1
- package/dist/get-video-codec.d.ts +1 -1
- package/dist/has-all-info.d.ts +8 -3
- package/dist/has-all-info.js +21 -12
- package/dist/index.d.ts +6 -0
- package/dist/index.js +2 -0
- package/dist/metadata/get-metadata.d.ts +7 -0
- package/dist/metadata/get-metadata.js +16 -0
- package/dist/metadata/metadata-from-iso.d.ts +4 -0
- package/dist/metadata/metadata-from-iso.js +148 -0
- package/dist/metadata/metadata-from-matroska.d.ts +3 -0
- package/dist/metadata/metadata-from-matroska.js +53 -0
- package/dist/metadata/metadata-from-riff.d.ts +3 -0
- package/dist/metadata/metadata-from-riff.js +24 -0
- package/dist/options.d.ts +9 -3
- package/dist/parse-media.js +32 -29
- package/dist/parse-result.d.ts +3 -1
- package/dist/parse-video.d.ts +3 -1
- package/dist/parse-video.js +5 -3
- package/dist/parser-context.d.ts +1 -2
- package/dist/register-track.d.ts +1 -1
- package/dist/state/can-skip-tracks.d.ts +9 -0
- package/dist/state/can-skip-tracks.js +33 -0
- package/dist/state/has-tracks-section.d.ts +6 -0
- package/dist/state/has-tracks-section.js +21 -0
- package/dist/state/parser-state.d.ts +51 -0
- package/dist/state/parser-state.js +170 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +9 -9
package/dist/parse-media.js
CHANGED
|
@@ -6,13 +6,17 @@ const emit_available_info_1 = require("./emit-available-info");
|
|
|
6
6
|
const has_all_info_1 = require("./has-all-info");
|
|
7
7
|
const log_1 = require("./log");
|
|
8
8
|
const parse_video_1 = require("./parse-video");
|
|
9
|
-
const parser_state_1 = require("./parser-state");
|
|
10
9
|
const from_fetch_1 = require("./readers/from-fetch");
|
|
10
|
+
const parser_state_1 = require("./state/parser-state");
|
|
11
11
|
const parseMedia = async ({ src, fields, reader: readerInterface = from_fetch_1.fetchReader, onAudioTrack, onVideoTrack, signal, logLevel = 'info', onParseProgress, ...more }) => {
|
|
12
|
+
let iterator = null;
|
|
13
|
+
let parseResult = null;
|
|
12
14
|
const state = (0, parser_state_1.makeParserState)({
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
hasAudioTrackHandlers: Boolean(onAudioTrack),
|
|
16
|
+
hasVideoTrackHandlers: Boolean(onVideoTrack),
|
|
15
17
|
signal,
|
|
18
|
+
getIterator: () => iterator,
|
|
19
|
+
fields: fields !== null && fields !== void 0 ? fields : {},
|
|
16
20
|
});
|
|
17
21
|
const { reader, contentLength, name, supportsContentRange: readerSupportsContentRange, } = await readerInterface.read(src, null, signal);
|
|
18
22
|
let currentReader = reader;
|
|
@@ -22,18 +26,7 @@ const parseMedia = async ({ src, fields, reader: readerInterface = from_fetch_1.
|
|
|
22
26
|
process.env.DISABLE_CONTENT_RANGE === 'true');
|
|
23
27
|
const returnValue = {};
|
|
24
28
|
const moreFields = more;
|
|
25
|
-
let iterator = null;
|
|
26
|
-
let parseResult = null;
|
|
27
|
-
// TODO: Should be possible to skip if `null` is returned
|
|
28
|
-
const canSkipVideoData = !onVideoTrack && !onAudioTrack;
|
|
29
|
-
if (canSkipVideoData) {
|
|
30
|
-
log_1.Log.verbose(logLevel, 'Only parsing metadata, because no onVideoTrack and onAudioTrack callbacks were passed.');
|
|
31
|
-
}
|
|
32
|
-
else {
|
|
33
|
-
log_1.Log.verbose(logLevel, 'Parsing video data, because onVideoTrack/onAudioTrack callbacks were passed.');
|
|
34
|
-
}
|
|
35
29
|
const options = {
|
|
36
|
-
canSkipVideoData,
|
|
37
30
|
onAudioTrack: onAudioTrack !== null && onAudioTrack !== void 0 ? onAudioTrack : null,
|
|
38
31
|
onVideoTrack: onVideoTrack !== null && onVideoTrack !== void 0 ? onVideoTrack : null,
|
|
39
32
|
parserState: state,
|
|
@@ -43,15 +36,9 @@ const parseMedia = async ({ src, fields, reader: readerInterface = from_fetch_1.
|
|
|
43
36
|
supportsContentRange,
|
|
44
37
|
nextTrackIndex: 0,
|
|
45
38
|
};
|
|
46
|
-
const hasAllInfo = () => {
|
|
47
|
-
if (parseResult === null) {
|
|
48
|
-
return false;
|
|
49
|
-
}
|
|
50
|
-
const availableInfo = (0, has_all_info_1.getAvailableInfo)(fields !== null && fields !== void 0 ? fields : {}, parseResult, state);
|
|
51
|
-
return Object.values(availableInfo).every(Boolean);
|
|
52
|
-
};
|
|
53
39
|
const triggerInfoEmit = () => {
|
|
54
|
-
|
|
40
|
+
var _a;
|
|
41
|
+
const availableInfo = (0, has_all_info_1.getAvailableInfo)(fields !== null && fields !== void 0 ? fields : {}, (_a = parseResult === null || parseResult === void 0 ? void 0 : parseResult.segments) !== null && _a !== void 0 ? _a : null, state);
|
|
55
42
|
(0, emit_available_info_1.emitAvailableInfo)({
|
|
56
43
|
hasInfo: availableInfo,
|
|
57
44
|
moreFields,
|
|
@@ -108,19 +95,32 @@ const parseMedia = async ({ src, fields, reader: readerInterface = from_fetch_1.
|
|
|
108
95
|
options,
|
|
109
96
|
signal: signal !== null && signal !== void 0 ? signal : null,
|
|
110
97
|
logLevel,
|
|
98
|
+
fields: fields !== null && fields !== void 0 ? fields : {},
|
|
111
99
|
});
|
|
112
100
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
101
|
+
if (parseResult.status === 'incomplete' && parseResult.skipTo !== null) {
|
|
102
|
+
state.increaseSkippedBytes(parseResult.skipTo - iterator.counter.getOffset());
|
|
103
|
+
}
|
|
104
|
+
if ((0, has_all_info_1.hasAllInfo)({
|
|
105
|
+
fields: fields !== null && fields !== void 0 ? fields : {},
|
|
106
|
+
structure: parseResult.segments,
|
|
107
|
+
state,
|
|
108
|
+
})) {
|
|
109
|
+
log_1.Log.verbose(logLevel, 'Got all info, skipping to the end.');
|
|
110
|
+
if (contentLength !== null) {
|
|
111
|
+
state.increaseSkippedBytes(contentLength - iterator.counter.getOffset());
|
|
112
|
+
}
|
|
116
113
|
break;
|
|
117
114
|
}
|
|
118
|
-
if (parseResult &&
|
|
119
|
-
parseResult.status === 'incomplete' &&
|
|
120
|
-
parseResult.skipTo !== null) {
|
|
115
|
+
if (parseResult.status === 'incomplete' && parseResult.skipTo !== null) {
|
|
121
116
|
if (!supportsContentRange) {
|
|
122
117
|
throw new Error('Content-Range header is not supported by the reader, but was asked to seek');
|
|
123
118
|
}
|
|
119
|
+
if (parseResult.skipTo === contentLength) {
|
|
120
|
+
log_1.Log.verbose(logLevel, 'Skipped to end of file, not fetching.');
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
log_1.Log.verbose(logLevel, `Skipping over video data from position ${iterator.counter.getOffset()} -> ${parseResult.skipTo}`);
|
|
124
124
|
currentReader.abort();
|
|
125
125
|
const { reader: newReader } = await readerInterface.read(src, parseResult.skipTo, signal);
|
|
126
126
|
currentReader = newReader;
|
|
@@ -131,7 +131,9 @@ const parseMedia = async ({ src, fields, reader: readerInterface = from_fetch_1.
|
|
|
131
131
|
// Force assign
|
|
132
132
|
(0, emit_available_info_1.emitAvailableInfo)({
|
|
133
133
|
hasInfo: Object.keys(fields !== null && fields !== void 0 ? fields : {}).reduce((acc, key) => {
|
|
134
|
-
|
|
134
|
+
if (fields === null || fields === void 0 ? void 0 : fields[key]) {
|
|
135
|
+
acc[key] = true;
|
|
136
|
+
}
|
|
135
137
|
return acc;
|
|
136
138
|
}, {}),
|
|
137
139
|
moreFields,
|
|
@@ -143,6 +145,7 @@ const parseMedia = async ({ src, fields, reader: readerInterface = from_fetch_1.
|
|
|
143
145
|
});
|
|
144
146
|
currentReader.abort();
|
|
145
147
|
iterator === null || iterator === void 0 ? void 0 : iterator.destroy();
|
|
148
|
+
state.tracks.ensureHasTracksAtEnd();
|
|
146
149
|
return returnValue;
|
|
147
150
|
};
|
|
148
151
|
exports.parseMedia = parseMedia;
|
package/dist/parse-result.d.ts
CHANGED
|
@@ -3,6 +3,8 @@ import type { EsdsBox } from './boxes/iso-base-media/esds/esds';
|
|
|
3
3
|
import type { FtypBox } from './boxes/iso-base-media/ftyp';
|
|
4
4
|
import type { MdatBox } from './boxes/iso-base-media/mdat/mdat';
|
|
5
5
|
import type { MdhdBox } from './boxes/iso-base-media/mdhd';
|
|
6
|
+
import type { HdlrBox } from './boxes/iso-base-media/meta/hdlr';
|
|
7
|
+
import type { IlstBox } from './boxes/iso-base-media/meta/ilst';
|
|
6
8
|
import type { MoovBox } from './boxes/iso-base-media/moov/moov';
|
|
7
9
|
import type { MvhdBox } from './boxes/iso-base-media/mvhd';
|
|
8
10
|
import type { Av1CBox } from './boxes/iso-base-media/stsd/av1c';
|
|
@@ -34,7 +36,7 @@ export interface RegularBox extends BaseBox {
|
|
|
34
36
|
offset: number;
|
|
35
37
|
type: 'regular-box';
|
|
36
38
|
}
|
|
37
|
-
export type IsoBaseMediaBox = RegularBox | FtypBox | MvhdBox | TkhdBox | StsdBox | MebxBox | KeysBox | MoovBox | TrakBox | SttsBox | MdhdBox | EsdsBox | MdatBox | StszBox | StcoBox | StscBox | AvccBox | HvccBox | VoidBox | StssBox | PaspBox | CttsBox | Av1CBox | TrunBox | ColorParameterBox | TfdtBox | TfhdBox;
|
|
39
|
+
export type IsoBaseMediaBox = RegularBox | FtypBox | MvhdBox | TkhdBox | StsdBox | MebxBox | KeysBox | MoovBox | TrakBox | SttsBox | MdhdBox | IlstBox | EsdsBox | MdatBox | StszBox | StcoBox | StscBox | AvccBox | HvccBox | VoidBox | StssBox | PaspBox | CttsBox | Av1CBox | TrunBox | HdlrBox | ColorParameterBox | TfdtBox | TfhdBox;
|
|
38
40
|
export type AnySegment = MatroskaSegment | IsoBaseMediaBox | RiffBox;
|
|
39
41
|
export type IsoBaseMediaStructure = {
|
|
40
42
|
type: 'iso-base-media';
|
package/dist/parse-video.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { BufferIterator } from './buffer-iterator';
|
|
2
2
|
import { type LogLevel } from './log';
|
|
3
|
+
import type { Options, ParseMediaFields } from './options';
|
|
3
4
|
import type { IsoBaseMediaBox, ParseResult, Structure } from './parse-result';
|
|
4
5
|
import type { ParserContext } from './parser-context';
|
|
5
6
|
export type PartialMdatBox = {
|
|
@@ -15,9 +16,10 @@ export type BoxAndNext = {
|
|
|
15
16
|
} | {
|
|
16
17
|
type: 'incomplete';
|
|
17
18
|
} | PartialMdatBox;
|
|
18
|
-
export declare const parseVideo: ({ iterator, options, signal, logLevel, }: {
|
|
19
|
+
export declare const parseVideo: ({ iterator, options, signal, logLevel, fields, }: {
|
|
19
20
|
iterator: BufferIterator;
|
|
20
21
|
options: ParserContext;
|
|
21
22
|
signal: AbortSignal | null;
|
|
22
23
|
logLevel: LogLevel;
|
|
24
|
+
fields: Options<ParseMediaFields>;
|
|
23
25
|
}) => Promise<ParseResult<Structure>>;
|
package/dist/parse-video.js
CHANGED
|
@@ -5,12 +5,13 @@ const process_box_1 = require("./boxes/iso-base-media/process-box");
|
|
|
5
5
|
const parse_box_1 = require("./boxes/riff/parse-box");
|
|
6
6
|
const parse_webm_header_1 = require("./boxes/webm/parse-webm-header");
|
|
7
7
|
const log_1 = require("./log");
|
|
8
|
-
const parseVideo = ({ iterator, options, signal, logLevel, }) => {
|
|
8
|
+
const parseVideo = ({ iterator, options, signal, logLevel, fields, }) => {
|
|
9
9
|
if (iterator.bytesRemaining() === 0) {
|
|
10
10
|
return Promise.reject(new Error('no bytes'));
|
|
11
11
|
}
|
|
12
12
|
if (iterator.isRiff()) {
|
|
13
|
-
|
|
13
|
+
log_1.Log.verbose(logLevel, 'Detected RIFF container');
|
|
14
|
+
return Promise.resolve((0, parse_box_1.parseRiff)({ iterator, options, fields }));
|
|
14
15
|
}
|
|
15
16
|
if (iterator.isIsoBaseMedia()) {
|
|
16
17
|
log_1.Log.verbose(logLevel, 'Detected ISO Base Media container');
|
|
@@ -23,11 +24,12 @@ const parseVideo = ({ iterator, options, signal, logLevel, }) => {
|
|
|
23
24
|
continueMdat: false,
|
|
24
25
|
signal,
|
|
25
26
|
logLevel,
|
|
27
|
+
fields,
|
|
26
28
|
});
|
|
27
29
|
}
|
|
28
30
|
if (iterator.isWebm()) {
|
|
29
31
|
log_1.Log.verbose(logLevel, 'Detected Matroska container');
|
|
30
|
-
return (0, parse_webm_header_1.parseWebm)(iterator, options);
|
|
32
|
+
return (0, parse_webm_header_1.parseWebm)({ counter: iterator, parserContext: options, fields });
|
|
31
33
|
}
|
|
32
34
|
if (iterator.isMp3()) {
|
|
33
35
|
return Promise.reject(new Error('MP3 files are not yet supported'));
|
package/dist/parser-context.d.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import type { ParserState } from './parser-state';
|
|
1
|
+
import type { ParserState } from './state/parser-state';
|
|
2
2
|
import type { OnAudioTrack, OnVideoTrack } from './webcodec-sample-types';
|
|
3
3
|
export type ParserContext = {
|
|
4
4
|
onAudioTrack: OnAudioTrack | null;
|
|
5
5
|
onVideoTrack: OnVideoTrack | null;
|
|
6
|
-
canSkipVideoData: boolean;
|
|
7
6
|
parserState: ParserState;
|
|
8
7
|
nullifySamples: boolean;
|
|
9
8
|
supportsContentRange: boolean;
|
package/dist/register-track.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Track, VideoTrack } from './get-tracks';
|
|
2
2
|
import type { ParserContext } from './parser-context';
|
|
3
|
-
import type { ParserState } from './parser-state';
|
|
3
|
+
import type { ParserState } from './state/parser-state';
|
|
4
4
|
export declare const registerTrack: ({ state, options, track, }: {
|
|
5
5
|
state: ParserState;
|
|
6
6
|
options: ParserContext;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Options, ParseMediaFields } from '../options';
|
|
2
|
+
export declare const makeCanSkipTracksState: ({ hasAudioTrackHandlers, fields, hasVideoTrackHandlers, }: {
|
|
3
|
+
hasAudioTrackHandlers: boolean;
|
|
4
|
+
hasVideoTrackHandlers: boolean;
|
|
5
|
+
fields: Options<ParseMediaFields>;
|
|
6
|
+
}) => {
|
|
7
|
+
canSkipTracks: () => boolean;
|
|
8
|
+
};
|
|
9
|
+
export type CanSkipTracksState = ReturnType<typeof makeCanSkipTracksState>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.makeCanSkipTracksState = void 0;
|
|
4
|
+
const needsTracksField = {
|
|
5
|
+
audioCodec: true,
|
|
6
|
+
container: false,
|
|
7
|
+
dimensions: true,
|
|
8
|
+
durationInSeconds: true,
|
|
9
|
+
fps: true,
|
|
10
|
+
internalStats: false,
|
|
11
|
+
isHdr: true,
|
|
12
|
+
name: false,
|
|
13
|
+
rotation: true,
|
|
14
|
+
size: false,
|
|
15
|
+
structure: true,
|
|
16
|
+
tracks: true,
|
|
17
|
+
unrotatedDimensions: true,
|
|
18
|
+
videoCodec: true,
|
|
19
|
+
metadata: true,
|
|
20
|
+
};
|
|
21
|
+
const makeCanSkipTracksState = ({ hasAudioTrackHandlers, fields, hasVideoTrackHandlers, }) => {
|
|
22
|
+
return {
|
|
23
|
+
canSkipTracks: () => {
|
|
24
|
+
if (hasAudioTrackHandlers || hasVideoTrackHandlers) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
const keys = Object.keys(fields !== null && fields !== void 0 ? fields : {});
|
|
28
|
+
const selectedKeys = keys.filter((k) => fields[k]);
|
|
29
|
+
return !selectedKeys.some((k) => needsTracksField[k]);
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
exports.makeCanSkipTracksState = makeCanSkipTracksState;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.makeTracksSectionState = void 0;
|
|
4
|
+
const makeTracksSectionState = (canSkipTracksState) => {
|
|
5
|
+
let doneWithTracks = false;
|
|
6
|
+
return {
|
|
7
|
+
hasAllTracks: () => doneWithTracks,
|
|
8
|
+
setIsDone: () => {
|
|
9
|
+
doneWithTracks = true;
|
|
10
|
+
},
|
|
11
|
+
ensureHasTracksAtEnd: () => {
|
|
12
|
+
if (canSkipTracksState.canSkipTracks()) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
if (!doneWithTracks) {
|
|
16
|
+
throw new Error('Error in Media Parser: End of parsing has been reached, but no tracks have been found');
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
exports.makeTracksSectionState = makeTracksSectionState;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { AvcPPs, AvcProfileInfo } from '../boxes/avc/parse-avc';
|
|
2
|
+
import type { OnTrackEntrySegment } from '../boxes/webm/segments';
|
|
3
|
+
import type { TrackInfo } from '../boxes/webm/segments/track-entry';
|
|
4
|
+
import type { BufferIterator } from '../buffer-iterator';
|
|
5
|
+
import type { Options, ParseMediaFields } from '../options';
|
|
6
|
+
import type { AudioOrVideoSample, OnAudioSample, OnVideoSample } from '../webcodec-sample-types';
|
|
7
|
+
export type InternalStats = {
|
|
8
|
+
skippedBytes: number;
|
|
9
|
+
finalCursorOffset: number;
|
|
10
|
+
};
|
|
11
|
+
export type SpsAndPps = {
|
|
12
|
+
sps: AvcProfileInfo;
|
|
13
|
+
pps: AvcPPs;
|
|
14
|
+
};
|
|
15
|
+
type AvcProfileInfoCallback = (profile: SpsAndPps) => Promise<void>;
|
|
16
|
+
export declare const makeParserState: ({ hasAudioTrackHandlers, hasVideoTrackHandlers, signal, getIterator, fields, }: {
|
|
17
|
+
hasAudioTrackHandlers: boolean;
|
|
18
|
+
hasVideoTrackHandlers: boolean;
|
|
19
|
+
signal: AbortSignal | undefined;
|
|
20
|
+
getIterator: () => BufferIterator | null;
|
|
21
|
+
fields: Options<ParseMediaFields>;
|
|
22
|
+
}) => {
|
|
23
|
+
onTrackEntrySegment: OnTrackEntrySegment;
|
|
24
|
+
onProfile: (profile: SpsAndPps) => Promise<void>;
|
|
25
|
+
registerOnAvcProfileCallback: (callback: AvcProfileInfoCallback) => void;
|
|
26
|
+
getTrackInfoByNumber: (id: number) => TrackInfo;
|
|
27
|
+
registerVideoSampleCallback: (id: number, callback: OnVideoSample | null) => Promise<void>;
|
|
28
|
+
setTimestampOffset: (byteOffset: number, timestamp: number) => void;
|
|
29
|
+
getTimestampOffsetForByteOffset: (byteOffset: number) => number | undefined;
|
|
30
|
+
registerAudioSampleCallback: (id: number, callback: OnAudioSample | null) => Promise<void>;
|
|
31
|
+
onAudioSample: (trackId: number, audioSample: AudioOrVideoSample) => Promise<void>;
|
|
32
|
+
onVideoSample: (trackId: number, videoSample: AudioOrVideoSample) => Promise<void>;
|
|
33
|
+
getTimescale: () => number;
|
|
34
|
+
setTimescale: (newTimescale: number) => void;
|
|
35
|
+
getSamplesForTrack: (trackId: number) => number;
|
|
36
|
+
getAvcProfile: () => SpsAndPps | null;
|
|
37
|
+
getInternalStats: () => InternalStats;
|
|
38
|
+
getSkipBytes: () => number;
|
|
39
|
+
increaseSkippedBytes: (bytes: number) => void;
|
|
40
|
+
maySkipVideoData: () => boolean;
|
|
41
|
+
tracks: {
|
|
42
|
+
hasAllTracks: () => boolean;
|
|
43
|
+
setIsDone: () => void;
|
|
44
|
+
ensureHasTracksAtEnd: () => void;
|
|
45
|
+
};
|
|
46
|
+
canSkipTracksState: {
|
|
47
|
+
canSkipTracks: () => boolean;
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
export type ParserState = ReturnType<typeof makeParserState>;
|
|
51
|
+
export {};
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.makeParserState = void 0;
|
|
4
|
+
const traversal_1 = require("../boxes/webm/traversal");
|
|
5
|
+
const can_skip_tracks_1 = require("./can-skip-tracks");
|
|
6
|
+
const has_tracks_section_1 = require("./has-tracks-section");
|
|
7
|
+
const makeParserState = ({ hasAudioTrackHandlers, hasVideoTrackHandlers, signal, getIterator, fields, }) => {
|
|
8
|
+
const trackEntries = {};
|
|
9
|
+
const onTrackEntrySegment = (trackEntry) => {
|
|
10
|
+
var _a;
|
|
11
|
+
const trackId = (0, traversal_1.getTrackId)(trackEntry);
|
|
12
|
+
if (!trackId) {
|
|
13
|
+
throw new Error('Expected track id');
|
|
14
|
+
}
|
|
15
|
+
if (trackEntries[trackId]) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const codec = (0, traversal_1.getTrackCodec)(trackEntry);
|
|
19
|
+
if (!codec) {
|
|
20
|
+
throw new Error('Expected codec');
|
|
21
|
+
}
|
|
22
|
+
const trackTimescale = (0, traversal_1.getTrackTimestampScale)(trackEntry);
|
|
23
|
+
trackEntries[trackId] = {
|
|
24
|
+
codec: codec.value,
|
|
25
|
+
trackTimescale: (_a = trackTimescale === null || trackTimescale === void 0 ? void 0 : trackTimescale.value) !== null && _a !== void 0 ? _a : null,
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
const videoSampleCallbacks = {};
|
|
29
|
+
const audioSampleCallbacks = {};
|
|
30
|
+
const queuedAudioSamples = {};
|
|
31
|
+
const queuedVideoSamples = {};
|
|
32
|
+
let timescale = null;
|
|
33
|
+
let skippedBytes = 0;
|
|
34
|
+
const getTimescale = () => {
|
|
35
|
+
// https://www.matroska.org/technical/notes.html
|
|
36
|
+
// When using the default value of TimestampScale of “1,000,000”, one Segment Tick represents one millisecond.
|
|
37
|
+
if (timescale === null) {
|
|
38
|
+
return 1000000;
|
|
39
|
+
}
|
|
40
|
+
return timescale;
|
|
41
|
+
};
|
|
42
|
+
const increaseSkippedBytes = (bytes) => {
|
|
43
|
+
skippedBytes += bytes;
|
|
44
|
+
};
|
|
45
|
+
const setTimescale = (newTimescale) => {
|
|
46
|
+
timescale = newTimescale;
|
|
47
|
+
};
|
|
48
|
+
const timestampMap = new Map();
|
|
49
|
+
const setTimestampOffset = (byteOffset, timestamp) => {
|
|
50
|
+
timestampMap.set(byteOffset, timestamp);
|
|
51
|
+
};
|
|
52
|
+
const getTimestampOffsetForByteOffset = (byteOffset) => {
|
|
53
|
+
const entries = Array.from(timestampMap.entries());
|
|
54
|
+
const sortedByByteOffset = entries
|
|
55
|
+
.sort((a, b) => {
|
|
56
|
+
return a[0] - b[0];
|
|
57
|
+
})
|
|
58
|
+
.reverse();
|
|
59
|
+
for (const [offset, timestamp] of sortedByByteOffset) {
|
|
60
|
+
if (offset >= byteOffset) {
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
return timestamp;
|
|
64
|
+
}
|
|
65
|
+
return timestampMap.get(byteOffset);
|
|
66
|
+
};
|
|
67
|
+
const samplesForTrack = {};
|
|
68
|
+
const profileCallbacks = [];
|
|
69
|
+
const registerOnAvcProfileCallback = (callback) => {
|
|
70
|
+
profileCallbacks.push(callback);
|
|
71
|
+
};
|
|
72
|
+
let avcProfile = null;
|
|
73
|
+
const onProfile = async (profile) => {
|
|
74
|
+
avcProfile = profile;
|
|
75
|
+
for (const callback of profileCallbacks) {
|
|
76
|
+
await callback(profile);
|
|
77
|
+
}
|
|
78
|
+
profileCallbacks.length = 0;
|
|
79
|
+
};
|
|
80
|
+
const canSkipTracksState = (0, can_skip_tracks_1.makeCanSkipTracksState)({
|
|
81
|
+
hasAudioTrackHandlers,
|
|
82
|
+
fields,
|
|
83
|
+
hasVideoTrackHandlers,
|
|
84
|
+
});
|
|
85
|
+
const tracksState = (0, has_tracks_section_1.makeTracksSectionState)(canSkipTracksState);
|
|
86
|
+
return {
|
|
87
|
+
onTrackEntrySegment,
|
|
88
|
+
onProfile,
|
|
89
|
+
registerOnAvcProfileCallback,
|
|
90
|
+
getTrackInfoByNumber: (id) => trackEntries[id],
|
|
91
|
+
registerVideoSampleCallback: async (id, callback) => {
|
|
92
|
+
var _a;
|
|
93
|
+
if (callback === null) {
|
|
94
|
+
delete videoSampleCallbacks[id];
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
videoSampleCallbacks[id] = callback;
|
|
98
|
+
for (const queued of (_a = queuedVideoSamples[id]) !== null && _a !== void 0 ? _a : []) {
|
|
99
|
+
await callback(queued);
|
|
100
|
+
}
|
|
101
|
+
queuedVideoSamples[id] = [];
|
|
102
|
+
},
|
|
103
|
+
setTimestampOffset,
|
|
104
|
+
getTimestampOffsetForByteOffset,
|
|
105
|
+
registerAudioSampleCallback: async (id, callback) => {
|
|
106
|
+
var _a;
|
|
107
|
+
if (callback === null) {
|
|
108
|
+
delete audioSampleCallbacks[id];
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
audioSampleCallbacks[id] = callback;
|
|
112
|
+
for (const queued of (_a = queuedAudioSamples[id]) !== null && _a !== void 0 ? _a : []) {
|
|
113
|
+
await callback(queued);
|
|
114
|
+
}
|
|
115
|
+
queuedAudioSamples[id] = [];
|
|
116
|
+
},
|
|
117
|
+
onAudioSample: async (trackId, audioSample) => {
|
|
118
|
+
if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
|
|
119
|
+
throw new Error('Aborted');
|
|
120
|
+
}
|
|
121
|
+
if (typeof samplesForTrack[trackId] === 'undefined') {
|
|
122
|
+
samplesForTrack[trackId] = 0;
|
|
123
|
+
}
|
|
124
|
+
samplesForTrack[trackId]++;
|
|
125
|
+
const callback = audioSampleCallbacks[trackId];
|
|
126
|
+
if (callback) {
|
|
127
|
+
await callback(audioSample);
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
onVideoSample: async (trackId, videoSample) => {
|
|
131
|
+
if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
|
|
132
|
+
throw new Error('Aborted');
|
|
133
|
+
}
|
|
134
|
+
if (typeof samplesForTrack[trackId] === 'undefined') {
|
|
135
|
+
samplesForTrack[trackId] = 0;
|
|
136
|
+
}
|
|
137
|
+
samplesForTrack[trackId]++;
|
|
138
|
+
const callback = videoSampleCallbacks[trackId];
|
|
139
|
+
if (callback) {
|
|
140
|
+
await callback(videoSample);
|
|
141
|
+
}
|
|
142
|
+
},
|
|
143
|
+
getTimescale,
|
|
144
|
+
setTimescale,
|
|
145
|
+
getSamplesForTrack: (trackId) => {
|
|
146
|
+
var _a;
|
|
147
|
+
return (_a = samplesForTrack[trackId]) !== null && _a !== void 0 ? _a : 0;
|
|
148
|
+
},
|
|
149
|
+
getAvcProfile: () => {
|
|
150
|
+
return avcProfile;
|
|
151
|
+
},
|
|
152
|
+
getInternalStats: () => {
|
|
153
|
+
var _a, _b;
|
|
154
|
+
return ({
|
|
155
|
+
skippedBytes,
|
|
156
|
+
finalCursorOffset: (_b = (_a = getIterator()) === null || _a === void 0 ? void 0 : _a.counter.getOffset()) !== null && _b !== void 0 ? _b : 0,
|
|
157
|
+
});
|
|
158
|
+
},
|
|
159
|
+
getSkipBytes: () => skippedBytes,
|
|
160
|
+
increaseSkippedBytes,
|
|
161
|
+
maySkipVideoData: () => {
|
|
162
|
+
return (tracksState.hasAllTracks() &&
|
|
163
|
+
Object.values(videoSampleCallbacks).length === 0 &&
|
|
164
|
+
Object.values(audioSampleCallbacks).length === 0);
|
|
165
|
+
},
|
|
166
|
+
tracks: tracksState,
|
|
167
|
+
canSkipTracksState,
|
|
168
|
+
};
|
|
169
|
+
};
|
|
170
|
+
exports.makeParserState = makeParserState;
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VERSION = "4.0.
|
|
1
|
+
export declare const VERSION = "4.0.236";
|
package/dist/version.js
CHANGED
package/package.json
CHANGED
|
@@ -3,14 +3,14 @@
|
|
|
3
3
|
"url": "https://github.com/remotion-dev/remotion/tree/main/packages/media-parser"
|
|
4
4
|
},
|
|
5
5
|
"name": "@remotion/media-parser",
|
|
6
|
-
"version": "4.0.
|
|
6
|
+
"version": "4.0.236",
|
|
7
7
|
"main": "dist/index.js",
|
|
8
8
|
"sideEffects": false,
|
|
9
9
|
"devDependencies": {
|
|
10
10
|
"@types/wicg-file-system-access": "2023.10.5",
|
|
11
11
|
"eslint": "9.14.0",
|
|
12
|
-
"@remotion/example-videos": "4.0.
|
|
13
|
-
"@remotion/eslint-config-internal": "4.0.
|
|
12
|
+
"@remotion/example-videos": "4.0.236",
|
|
13
|
+
"@remotion/eslint-config-internal": "4.0.236"
|
|
14
14
|
},
|
|
15
15
|
"publishConfig": {
|
|
16
16
|
"access": "public"
|
|
@@ -20,39 +20,39 @@
|
|
|
20
20
|
},
|
|
21
21
|
"exports": {
|
|
22
22
|
".": {
|
|
23
|
+
"types": "./dist/index.d.ts",
|
|
23
24
|
"require": "./dist/index.js",
|
|
24
25
|
"module": "./dist/esm/index.mjs",
|
|
25
|
-
"types": "./dist/index.d.ts",
|
|
26
26
|
"import": "./dist/esm/index.mjs"
|
|
27
27
|
},
|
|
28
28
|
"./node": {
|
|
29
|
+
"types": "./dist/readers/from-node.d.ts",
|
|
29
30
|
"require": "./dist/readers/from-node.js",
|
|
30
31
|
"module": "./dist/esm/from-node.mjs",
|
|
31
|
-
"types": "./dist/readers/from-node.d.ts",
|
|
32
32
|
"import": "./dist/esm/from-node.mjs"
|
|
33
33
|
},
|
|
34
34
|
"./fetch": {
|
|
35
|
+
"types": "./dist/readers/from-fetch.d.ts",
|
|
35
36
|
"require": "./dist/readers/from-fetch.js",
|
|
36
37
|
"module": "./dist/esm/from-fetch.mjs",
|
|
37
|
-
"types": "./dist/readers/from-fetch.d.ts",
|
|
38
38
|
"import": "./dist/esm/from-fetch.mjs"
|
|
39
39
|
},
|
|
40
40
|
"./web-file": {
|
|
41
|
+
"types": "./dist/readers/from-web-file.d.ts",
|
|
41
42
|
"require": "./dist/readers/from-web-file.js",
|
|
42
43
|
"module": "./dist/esm/from-web-file.mjs",
|
|
43
|
-
"types": "./dist/readers/from-web-file.d.ts",
|
|
44
44
|
"import": "./dist/esm/from-web-file.mjs"
|
|
45
45
|
},
|
|
46
46
|
"./web-fs": {
|
|
47
|
+
"types": "./dist/writers/web-fs.d.ts",
|
|
47
48
|
"require": "./dist/writers/web-fs.js",
|
|
48
49
|
"module": "./dist/esm/web-fs.mjs",
|
|
49
|
-
"types": "./dist/writers/web-fs.d.ts",
|
|
50
50
|
"import": "./dist/esm/web-fs.mjs"
|
|
51
51
|
},
|
|
52
52
|
"./buffer": {
|
|
53
|
+
"types": "./dist/writers/buffer.d.ts",
|
|
53
54
|
"require": "./dist/writers/buffer.js",
|
|
54
55
|
"module": "./dist/esm/buffer.mjs",
|
|
55
|
-
"types": "./dist/writers/buffer.d.ts",
|
|
56
56
|
"import": "./dist/esm/buffer.mjs"
|
|
57
57
|
},
|
|
58
58
|
"./package.json": "./package.json"
|