@remotion/media-parser 4.0.267 → 4.0.268
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/containers/mp3/get-duration.js +4 -3
- package/dist/containers/mp3/parse-mpeg-header.js +57 -40
- package/dist/containers/webm/get-ready-tracks.d.ts +9 -2
- package/dist/containers/webm/get-ready-tracks.js +43 -8
- package/dist/containers/webm/get-sample-from-block.js +19 -0
- package/dist/containers/webm/make-track.d.ts +1 -0
- package/dist/containers/webm/make-track.js +9 -8
- package/dist/esm/fetch.mjs +31 -11
- package/dist/esm/index.mjs +533 -430
- package/dist/get-tracks.js +7 -14
- package/dist/has-all-info.js +7 -3
- package/dist/index.d.ts +4 -0
- package/dist/internal-parse-media.js +1 -1
- package/dist/readers/fetch/get-body-and-reader.d.ts +6 -1
- package/dist/readers/fetch/get-body-and-reader.js +7 -6
- package/dist/readers/from-fetch.js +16 -5
- package/dist/state/mp3.d.ts +5 -1
- package/dist/state/mp3.js +6 -0
- package/dist/state/parser-state.d.ts +4 -0
- package/dist/state/webm.d.ts +4 -0
- package/dist/state/webm.js +10 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +3 -3
package/dist/get-tracks.js
CHANGED
|
@@ -6,7 +6,6 @@ const traversal_1 = require("./containers/iso-base-media/traversal");
|
|
|
6
6
|
const get_tracks_from_avi_1 = require("./containers/riff/get-tracks-from-avi");
|
|
7
7
|
const get_tracks_1 = require("./containers/transport-stream/get-tracks");
|
|
8
8
|
const get_ready_tracks_1 = require("./containers/webm/get-ready-tracks");
|
|
9
|
-
const traversal_2 = require("./containers/webm/traversal");
|
|
10
9
|
const getNumberOfTracks = (moovBox) => {
|
|
11
10
|
const mvHdBox = (0, traversal_1.getMvhdBox)(moovBox);
|
|
12
11
|
if (!mvHdBox) {
|
|
@@ -22,11 +21,7 @@ exports.isoBaseMediaHasTracks = isoBaseMediaHasTracks;
|
|
|
22
21
|
const getHasTracks = (state) => {
|
|
23
22
|
const structure = state.getStructure();
|
|
24
23
|
if (structure.type === 'matroska') {
|
|
25
|
-
|
|
26
|
-
if (!mainSegment) {
|
|
27
|
-
return false;
|
|
28
|
-
}
|
|
29
|
-
return (0, traversal_2.getTracksSegment)(mainSegment) !== null;
|
|
24
|
+
return (0, get_ready_tracks_1.matroskaHasTracks)(state);
|
|
30
25
|
}
|
|
31
26
|
if (structure.type === 'iso-base-media') {
|
|
32
27
|
return (0, exports.isoBaseMediaHasTracks)(state);
|
|
@@ -55,16 +50,14 @@ const getHasTracks = (state) => {
|
|
|
55
50
|
throw new Error('Unknown container ' + structure);
|
|
56
51
|
};
|
|
57
52
|
exports.getHasTracks = getHasTracks;
|
|
58
|
-
const
|
|
53
|
+
const getCategorizedTracksFromMatroska = (state) => {
|
|
59
54
|
const videoTracks = [];
|
|
60
55
|
const audioTracks = [];
|
|
61
56
|
const otherTracks = [];
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
const matroskaTracks = (0, get_ready_tracks_1.getTracksFromMatroska)(mainSegment, state.webm.getTimescale());
|
|
67
|
-
for (const track of matroskaTracks) {
|
|
57
|
+
const { resolved } = (0, get_ready_tracks_1.getTracksFromMatroska)({
|
|
58
|
+
state,
|
|
59
|
+
});
|
|
60
|
+
for (const track of resolved) {
|
|
68
61
|
if (track.type === 'video') {
|
|
69
62
|
videoTracks.push(track);
|
|
70
63
|
}
|
|
@@ -141,7 +134,7 @@ exports.defaultHasallTracks = defaultHasallTracks;
|
|
|
141
134
|
const getTracks = (state) => {
|
|
142
135
|
const structure = state.getStructure();
|
|
143
136
|
if (structure.type === 'matroska') {
|
|
144
|
-
return
|
|
137
|
+
return getCategorizedTracksFromMatroska(state);
|
|
145
138
|
}
|
|
146
139
|
if (structure.type === 'iso-base-media') {
|
|
147
140
|
return (0, exports.getTracksFromIsoBaseMedia)(state);
|
package/dist/has-all-info.js
CHANGED
|
@@ -107,8 +107,12 @@ const hasAllInfo = ({ fields, state, }) => {
|
|
|
107
107
|
if (!Object.values(availableInfo).every(Boolean)) {
|
|
108
108
|
return false;
|
|
109
109
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
110
|
+
if ((0, may_skip_video_data_1.maySkipVideoData)({ state })) {
|
|
111
|
+
return true;
|
|
112
|
+
}
|
|
113
|
+
if (state.callbacks.canSkipTracksState.canSkipTracks()) {
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
return false;
|
|
113
117
|
};
|
|
114
118
|
exports.hasAllInfo = hasAllInfo;
|
package/dist/index.d.ts
CHANGED
|
@@ -881,6 +881,8 @@ export declare const MediaParserInternals: {
|
|
|
881
881
|
addCluster: (cluster: import("./state/webm").ClusterSection) => void;
|
|
882
882
|
isInsideSegment: (iterator: import("./buffer-iterator").BufferIterator) => import("./state/webm").SegmentSection | null;
|
|
883
883
|
isInsideCluster: (iterator: import("./buffer-iterator").BufferIterator) => import("./state/webm").ClusterSection | null;
|
|
884
|
+
setAvcProfileForTrackNumber: (trackNumber: number, avcProfile: import("./containers/avc/parse-avc").AvcProfileInfo) => void;
|
|
885
|
+
getAvcProfileForTrackNumber: (trackNumber: number) => import("./containers/avc/parse-avc").AvcProfileInfo | null;
|
|
884
886
|
};
|
|
885
887
|
iso: {
|
|
886
888
|
flatSamples: {
|
|
@@ -895,6 +897,8 @@ export declare const MediaParserInternals: {
|
|
|
895
897
|
mp3Info: {
|
|
896
898
|
getMp3Info: () => import("./state/mp3").Mp3Info | null;
|
|
897
899
|
setMp3Info: (info: import("./state/mp3").Mp3Info) => void;
|
|
900
|
+
getCbrMp3Info: () => import("./state/mp3").Mp3CbrInfo | null;
|
|
901
|
+
setCbrMp3Info: (info: import("./state/mp3").Mp3CbrInfo) => void;
|
|
898
902
|
};
|
|
899
903
|
aac: {
|
|
900
904
|
addSample: ({ offset, size }: {
|
|
@@ -26,7 +26,7 @@ const internalParseMedia = async function ({ src, fields: _fieldsInReturnValue,
|
|
|
26
26
|
log_1.Log.verbose(logLevel, `Reading ${typeof src === 'string' ? src : src.name}`);
|
|
27
27
|
const { reader: readerInstance, contentLength, name, contentType, supportsContentRange, needsContentRange, } = await readerInterface.read({ src, range: null, controller });
|
|
28
28
|
if (contentLength === null) {
|
|
29
|
-
throw new Error(
|
|
29
|
+
throw new Error(`Cannot read media ${src} without a content length. This is currently not supported. Ensure the media has a "Content-Length" HTTP header.`);
|
|
30
30
|
}
|
|
31
31
|
if (!supportsContentRange && needsContentRange) {
|
|
32
32
|
throw new Error('Cannot read media without it supporting the "Content-Range" header. This is currently not supported. Ensure the media supports the "Content-Range" HTTP header.');
|
|
@@ -4,5 +4,10 @@ type ReturnType = {
|
|
|
4
4
|
contentLength: number | null;
|
|
5
5
|
needsContentRange: boolean;
|
|
6
6
|
};
|
|
7
|
-
export declare const getLengthAndReader: (
|
|
7
|
+
export declare const getLengthAndReader: ({ canLiveWithoutContentLength, res, ownController, requestedWithoutRange, }: {
|
|
8
|
+
canLiveWithoutContentLength: boolean;
|
|
9
|
+
res: Response;
|
|
10
|
+
ownController: AbortController;
|
|
11
|
+
requestedWithoutRange: boolean;
|
|
12
|
+
}) => Promise<ReturnType>;
|
|
8
13
|
export {};
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getLengthAndReader = void 0;
|
|
4
|
-
const getLengthAndReader = async (
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
const getLengthAndReader = async ({ canLiveWithoutContentLength, res, ownController, requestedWithoutRange, }) => {
|
|
5
|
+
const length = res.headers.get('content-length');
|
|
6
|
+
const contentLength = length === null ? null : parseInt(length, 10);
|
|
7
|
+
if (requestedWithoutRange ||
|
|
8
|
+
(canLiveWithoutContentLength && contentLength === null)) {
|
|
9
|
+
const buffer = await res.arrayBuffer();
|
|
10
|
+
const encoded = new Uint8Array(buffer);
|
|
8
11
|
const stream = new ReadableStream({
|
|
9
12
|
start(controller) {
|
|
10
13
|
controller.enqueue(encoded);
|
|
@@ -22,8 +25,6 @@ const getLengthAndReader = async (endsWithM3u8, res, ownController) => {
|
|
|
22
25
|
needsContentRange: false,
|
|
23
26
|
};
|
|
24
27
|
}
|
|
25
|
-
const length = res.headers.get('content-length');
|
|
26
|
-
const contentLength = length === null ? null : parseInt(length, 10);
|
|
27
28
|
if (!res.body) {
|
|
28
29
|
throw new Error('No body');
|
|
29
30
|
}
|
|
@@ -27,7 +27,7 @@ function parseContentRange(input) {
|
|
|
27
27
|
}
|
|
28
28
|
return range;
|
|
29
29
|
}
|
|
30
|
-
const validateContentRangeAndDetectIfSupported = (actualRange, parsedContentRange, statusCode) => {
|
|
30
|
+
const validateContentRangeAndDetectIfSupported = ({ actualRange, parsedContentRange, statusCode, }) => {
|
|
31
31
|
if (statusCode === 206) {
|
|
32
32
|
return { supportsContentRange: true };
|
|
33
33
|
}
|
|
@@ -66,8 +66,10 @@ exports.fetchReader = {
|
|
|
66
66
|
: // Disable Next.js caching
|
|
67
67
|
'no-store';
|
|
68
68
|
const actualRange = range === null ? 0 : range;
|
|
69
|
-
const
|
|
70
|
-
const
|
|
69
|
+
const asString = typeof resolvedUrl === 'string' ? resolvedUrl : resolvedUrl.pathname;
|
|
70
|
+
const requestWithoutRange = asString.endsWith('.m3u8');
|
|
71
|
+
const canLiveWithoutContentLength = asString.endsWith('.m3u8') || asString.endsWith('.ts');
|
|
72
|
+
const headers = actualRange === 0 && requestWithoutRange
|
|
71
73
|
? {}
|
|
72
74
|
: typeof actualRange === 'number'
|
|
73
75
|
? {
|
|
@@ -85,7 +87,11 @@ exports.fetchReader = {
|
|
|
85
87
|
const parsedContentRange = contentRange
|
|
86
88
|
? parseContentRange(contentRange)
|
|
87
89
|
: null;
|
|
88
|
-
const { supportsContentRange } = validateContentRangeAndDetectIfSupported(
|
|
90
|
+
const { supportsContentRange } = validateContentRangeAndDetectIfSupported({
|
|
91
|
+
actualRange,
|
|
92
|
+
parsedContentRange,
|
|
93
|
+
statusCode: res.status,
|
|
94
|
+
});
|
|
89
95
|
controller._internals.signal.addEventListener('abort', () => {
|
|
90
96
|
ownController.abort(new errors_1.MediaParserAbortError('Aborted by user'));
|
|
91
97
|
}, { once: true });
|
|
@@ -96,7 +102,12 @@ exports.fetchReader = {
|
|
|
96
102
|
const contentDisposition = res.headers.get('content-disposition');
|
|
97
103
|
const name = (_a = contentDisposition === null || contentDisposition === void 0 ? void 0 : contentDisposition.match(/filename="([^"]+)"/)) === null || _a === void 0 ? void 0 : _a[1];
|
|
98
104
|
const fallbackName = src.split('/').pop();
|
|
99
|
-
const { contentLength, needsContentRange, reader } = await (0, get_body_and_reader_1.getLengthAndReader)(
|
|
105
|
+
const { contentLength, needsContentRange, reader } = await (0, get_body_and_reader_1.getLengthAndReader)({
|
|
106
|
+
canLiveWithoutContentLength,
|
|
107
|
+
res,
|
|
108
|
+
ownController,
|
|
109
|
+
requestedWithoutRange: requestWithoutRange,
|
|
110
|
+
});
|
|
100
111
|
if (controller) {
|
|
101
112
|
controller._internals.signal.addEventListener('abort', () => {
|
|
102
113
|
reader.reader.cancel().catch(() => {
|
package/dist/state/mp3.d.ts
CHANGED
|
@@ -2,10 +2,14 @@ export type Mp3Info = {
|
|
|
2
2
|
sampleRate: number;
|
|
3
3
|
mpegVersion: 1 | 2;
|
|
4
4
|
layer: number;
|
|
5
|
-
bitrateKbit: number;
|
|
6
5
|
startOfMpegStream: number;
|
|
7
6
|
};
|
|
7
|
+
export type Mp3CbrInfo = {
|
|
8
|
+
bitrateKbit: number;
|
|
9
|
+
};
|
|
8
10
|
export declare const makeMp3State: () => {
|
|
9
11
|
getMp3Info: () => Mp3Info | null;
|
|
10
12
|
setMp3Info: (info: Mp3Info) => void;
|
|
13
|
+
getCbrMp3Info: () => Mp3CbrInfo | null;
|
|
14
|
+
setCbrMp3Info: (info: Mp3CbrInfo) => void;
|
|
11
15
|
};
|
package/dist/state/mp3.js
CHANGED
|
@@ -3,11 +3,17 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.makeMp3State = void 0;
|
|
4
4
|
const makeMp3State = () => {
|
|
5
5
|
let mp3Info = null;
|
|
6
|
+
// cbr = constant bit rate
|
|
7
|
+
let cbrMp3Info = null;
|
|
6
8
|
return {
|
|
7
9
|
getMp3Info: () => mp3Info,
|
|
8
10
|
setMp3Info: (info) => {
|
|
9
11
|
mp3Info = info;
|
|
10
12
|
},
|
|
13
|
+
getCbrMp3Info: () => cbrMp3Info,
|
|
14
|
+
setCbrMp3Info: (info) => {
|
|
15
|
+
cbrMp3Info = info;
|
|
16
|
+
},
|
|
11
17
|
};
|
|
12
18
|
};
|
|
13
19
|
exports.makeMp3State = makeMp3State;
|
|
@@ -168,6 +168,8 @@ export declare const makeParserState: ({ hasAudioTrackHandlers, hasVideoTrackHan
|
|
|
168
168
|
addCluster: (cluster: import("./webm").ClusterSection) => void;
|
|
169
169
|
isInsideSegment: (iterator: BufferIterator) => import("./webm").SegmentSection | null;
|
|
170
170
|
isInsideCluster: (iterator: BufferIterator) => import("./webm").ClusterSection | null;
|
|
171
|
+
setAvcProfileForTrackNumber: (trackNumber: number, avcProfile: AvcProfileInfo) => void;
|
|
172
|
+
getAvcProfileForTrackNumber: (trackNumber: number) => AvcProfileInfo | null;
|
|
171
173
|
};
|
|
172
174
|
iso: {
|
|
173
175
|
flatSamples: {
|
|
@@ -182,6 +184,8 @@ export declare const makeParserState: ({ hasAudioTrackHandlers, hasVideoTrackHan
|
|
|
182
184
|
mp3Info: {
|
|
183
185
|
getMp3Info: () => import("./mp3").Mp3Info | null;
|
|
184
186
|
setMp3Info: (info: import("./mp3").Mp3Info) => void;
|
|
187
|
+
getCbrMp3Info: () => import("./mp3").Mp3CbrInfo | null;
|
|
188
|
+
setCbrMp3Info: (info: import("./mp3").Mp3CbrInfo) => void;
|
|
185
189
|
};
|
|
186
190
|
aac: {
|
|
187
191
|
addSample: ({ offset, size }: {
|
package/dist/state/webm.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { BufferIterator } from '../buffer-iterator';
|
|
2
|
+
import type { AvcProfileInfo } from '../containers/avc/parse-avc';
|
|
2
3
|
import type { OnTrackEntrySegment } from '../containers/webm/segments';
|
|
3
4
|
import type { TrackInfo } from '../containers/webm/segments/track-entry';
|
|
4
5
|
export type SegmentSection = {
|
|
@@ -23,4 +24,7 @@ export declare const webmState: () => {
|
|
|
23
24
|
addCluster: (cluster: ClusterSection) => void;
|
|
24
25
|
isInsideSegment: (iterator: BufferIterator) => SegmentSection | null;
|
|
25
26
|
isInsideCluster: (iterator: BufferIterator) => ClusterSection | null;
|
|
27
|
+
setAvcProfileForTrackNumber: (trackNumber: number, avcProfile: AvcProfileInfo) => void;
|
|
28
|
+
getAvcProfileForTrackNumber: (trackNumber: number) => AvcProfileInfo | null;
|
|
26
29
|
};
|
|
30
|
+
export type WebmState = ReturnType<typeof webmState>;
|
package/dist/state/webm.js
CHANGED
|
@@ -56,6 +56,14 @@ const webmState = () => {
|
|
|
56
56
|
};
|
|
57
57
|
const segments = [];
|
|
58
58
|
const clusters = [];
|
|
59
|
+
const avcProfilesMap = {};
|
|
60
|
+
const setAvcProfileForTrackNumber = (trackNumber, avcProfile) => {
|
|
61
|
+
avcProfilesMap[trackNumber] = avcProfile;
|
|
62
|
+
};
|
|
63
|
+
const getAvcProfileForTrackNumber = (trackNumber) => {
|
|
64
|
+
var _a;
|
|
65
|
+
return (_a = avcProfilesMap[trackNumber]) !== null && _a !== void 0 ? _a : null;
|
|
66
|
+
};
|
|
59
67
|
return {
|
|
60
68
|
onTrackEntrySegment,
|
|
61
69
|
getTrackInfoByNumber: (id) => trackEntries[id],
|
|
@@ -94,6 +102,8 @@ const webmState = () => {
|
|
|
94
102
|
}
|
|
95
103
|
return null;
|
|
96
104
|
},
|
|
105
|
+
setAvcProfileForTrackNumber,
|
|
106
|
+
getAvcProfileForTrackNumber,
|
|
97
107
|
};
|
|
98
108
|
};
|
|
99
109
|
exports.webmState = webmState;
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VERSION = "4.0.
|
|
1
|
+
export declare const VERSION = "4.0.268";
|
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.268",
|
|
7
7
|
"main": "dist/index.js",
|
|
8
8
|
"sideEffects": false,
|
|
9
9
|
"devDependencies": {
|
|
10
10
|
"@types/wicg-file-system-access": "2023.10.5",
|
|
11
11
|
"eslint": "9.19.0",
|
|
12
|
-
"@remotion/
|
|
13
|
-
"@remotion/
|
|
12
|
+
"@remotion/eslint-config-internal": "4.0.268",
|
|
13
|
+
"@remotion/example-videos": "4.0.268"
|
|
14
14
|
},
|
|
15
15
|
"publishConfig": {
|
|
16
16
|
"access": "public"
|