@remotion/webcodecs 4.0.331 → 4.0.333
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/create/matroska/create-matroska-media.js +15 -4
- package/dist/create-audio-decoder.d.ts +2 -2
- package/dist/create-audio-decoder.js +9 -1
- package/dist/create-video-decoder.d.ts +2 -2
- package/dist/create-video-decoder.js +9 -1
- package/dist/default-on-video-track-handler.js +2 -1
- package/dist/esm/index.mjs +72 -17
- package/dist/esm/worker.mjs +41 -6
- package/dist/get-partial-audio-data.js +2 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.js +4 -1
- package/dist/internal-extract-frames.js +4 -5
- package/dist/reencode-audio-track.js +1 -1
- package/dist/reencode-video-track.js +1 -1
- package/dist/undecodable-error.d.ts +14 -0
- package/dist/undecodable-error.js +25 -0
- package/package.json +5 -5
|
@@ -95,7 +95,11 @@ const createMatroskaMedia = async ({ writer, onBytesProgress, onMillisecondsProg
|
|
|
95
95
|
isVideo,
|
|
96
96
|
chunk,
|
|
97
97
|
})) {
|
|
98
|
-
return {
|
|
98
|
+
return {
|
|
99
|
+
cluster: currentCluster,
|
|
100
|
+
isNew: false,
|
|
101
|
+
smallestProgress,
|
|
102
|
+
};
|
|
99
103
|
}
|
|
100
104
|
currentCluster = await (0, cluster_1.makeCluster)({
|
|
101
105
|
writer: w,
|
|
@@ -103,7 +107,11 @@ const createMatroskaMedia = async ({ writer, onBytesProgress, onMillisecondsProg
|
|
|
103
107
|
timescale,
|
|
104
108
|
logLevel,
|
|
105
109
|
});
|
|
106
|
-
return {
|
|
110
|
+
return {
|
|
111
|
+
cluster: currentCluster,
|
|
112
|
+
isNew: true,
|
|
113
|
+
smallestProgress,
|
|
114
|
+
};
|
|
107
115
|
};
|
|
108
116
|
const updateDuration = async (newDuration) => {
|
|
109
117
|
const blocks = (0, make_duration_with_padding_1.makeDurationWithPadding)(newDuration);
|
|
@@ -111,6 +119,7 @@ const createMatroskaMedia = async ({ writer, onBytesProgress, onMillisecondsProg
|
|
|
111
119
|
onBytesProgress(w.getWrittenByteCount());
|
|
112
120
|
};
|
|
113
121
|
const addSample = async ({ chunk, trackNumber, isVideo, }) => {
|
|
122
|
+
const offset = w.getWrittenByteCount();
|
|
114
123
|
const { cluster, isNew, smallestProgress } = await getClusterOrMakeNew({
|
|
115
124
|
chunk,
|
|
116
125
|
isVideo,
|
|
@@ -119,11 +128,13 @@ const createMatroskaMedia = async ({ writer, onBytesProgress, onMillisecondsProg
|
|
|
119
128
|
await updateDuration(newDuration);
|
|
120
129
|
const { timecodeRelativeToCluster } = await cluster.addSample(chunk, trackNumber);
|
|
121
130
|
if (isNew) {
|
|
122
|
-
|
|
131
|
+
if (offset === null) {
|
|
132
|
+
throw new Error('offset is null');
|
|
133
|
+
}
|
|
123
134
|
cues.push({
|
|
124
135
|
time: (0, cluster_1.timestampToClusterTimestamp)(smallestProgress, timescale) +
|
|
125
136
|
timecodeRelativeToCluster,
|
|
126
|
-
clusterPosition:
|
|
137
|
+
clusterPosition: offset - seekHeadOffset,
|
|
127
138
|
trackNumber,
|
|
128
139
|
});
|
|
129
140
|
}
|
|
@@ -18,11 +18,11 @@ export type CreateAudioDecoderInit = {
|
|
|
18
18
|
config: AudioDecoderConfig;
|
|
19
19
|
logLevel: MediaParserLogLevel;
|
|
20
20
|
};
|
|
21
|
-
export declare const internalCreateAudioDecoder: ({ onFrame, onError, controller, config, logLevel, }: CreateAudioDecoderInit) => WebCodecsAudioDecoder
|
|
21
|
+
export declare const internalCreateAudioDecoder: ({ onFrame, onError, controller, config, logLevel, }: CreateAudioDecoderInit) => Promise<WebCodecsAudioDecoder>;
|
|
22
22
|
export declare const createAudioDecoder: ({ track, onFrame, onError, controller, logLevel, }: {
|
|
23
23
|
track: AudioDecoderConfig;
|
|
24
24
|
onFrame: (frame: AudioData) => Promise<void> | void;
|
|
25
25
|
onError: (error: Error) => void;
|
|
26
26
|
controller?: WebCodecsController | null;
|
|
27
27
|
logLevel?: MediaParserLogLevel;
|
|
28
|
-
}) => WebCodecsAudioDecoder
|
|
28
|
+
}) => Promise<WebCodecsAudioDecoder>;
|
|
@@ -4,7 +4,8 @@ exports.createAudioDecoder = exports.internalCreateAudioDecoder = void 0;
|
|
|
4
4
|
const flush_pending_1 = require("./flush-pending");
|
|
5
5
|
const get_wave_audio_decoder_1 = require("./get-wave-audio-decoder");
|
|
6
6
|
const io_synchronizer_1 = require("./io-manager/io-synchronizer");
|
|
7
|
-
const
|
|
7
|
+
const undecodable_error_1 = require("./undecodable-error");
|
|
8
|
+
const internalCreateAudioDecoder = async ({ onFrame, onError, controller, config, logLevel, }) => {
|
|
8
9
|
if (controller &&
|
|
9
10
|
controller._internals._mediaParserController._internals.signal.aborted) {
|
|
10
11
|
throw new Error('Not creating audio decoder, already aborted');
|
|
@@ -57,6 +58,13 @@ const internalCreateAudioDecoder = ({ onFrame, onError, controller, config, logL
|
|
|
57
58
|
if (controller) {
|
|
58
59
|
controller._internals._mediaParserController._internals.signal.addEventListener('abort', onAbort);
|
|
59
60
|
}
|
|
61
|
+
const isConfigSupported = await AudioDecoder.isConfigSupported(config);
|
|
62
|
+
if (!isConfigSupported) {
|
|
63
|
+
throw new undecodable_error_1.AudioUndecodableError({
|
|
64
|
+
message: 'Audio cannot be decoded by this browser',
|
|
65
|
+
config,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
60
68
|
audioDecoder.configure(config);
|
|
61
69
|
const decode = async (audioSample) => {
|
|
62
70
|
if (audioDecoder.state === 'closed') {
|
|
@@ -17,11 +17,11 @@ export declare const internalCreateVideoDecoder: ({ onFrame, onError, controller
|
|
|
17
17
|
controller: WebCodecsController | null;
|
|
18
18
|
config: VideoDecoderConfig;
|
|
19
19
|
logLevel: MediaParserLogLevel;
|
|
20
|
-
}) => WebCodecsVideoDecoder
|
|
20
|
+
}) => Promise<WebCodecsVideoDecoder>;
|
|
21
21
|
export declare const createVideoDecoder: ({ onFrame, onError, controller, track, logLevel, }: {
|
|
22
22
|
track: VideoDecoderConfig;
|
|
23
23
|
onFrame: (frame: VideoFrame) => Promise<void> | void;
|
|
24
24
|
onError: (error: Error) => void;
|
|
25
25
|
controller?: WebCodecsController;
|
|
26
26
|
logLevel?: MediaParserLogLevel;
|
|
27
|
-
}) => WebCodecsVideoDecoder
|
|
27
|
+
}) => Promise<WebCodecsVideoDecoder>;
|
|
@@ -3,7 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.createVideoDecoder = exports.internalCreateVideoDecoder = void 0;
|
|
4
4
|
const flush_pending_1 = require("./flush-pending");
|
|
5
5
|
const io_synchronizer_1 = require("./io-manager/io-synchronizer");
|
|
6
|
-
const
|
|
6
|
+
const undecodable_error_1 = require("./undecodable-error");
|
|
7
|
+
const internalCreateVideoDecoder = async ({ onFrame, onError, controller, config, logLevel, }) => {
|
|
7
8
|
if (controller &&
|
|
8
9
|
controller._internals._mediaParserController._internals.signal.aborted) {
|
|
9
10
|
throw new Error('Not creating audio decoder, already aborted');
|
|
@@ -46,6 +47,13 @@ const internalCreateVideoDecoder = ({ onFrame, onError, controller, config, logL
|
|
|
46
47
|
if (controller) {
|
|
47
48
|
controller._internals._mediaParserController._internals.signal.addEventListener('abort', onAbort);
|
|
48
49
|
}
|
|
50
|
+
const isConfigSupported = await VideoDecoder.isConfigSupported(config);
|
|
51
|
+
if (!isConfigSupported) {
|
|
52
|
+
throw new undecodable_error_1.VideoUndecodableError({
|
|
53
|
+
message: 'Video cannot be decoded by this browser',
|
|
54
|
+
config,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
49
57
|
videoDecoder.configure(config);
|
|
50
58
|
const decode = async (sample) => {
|
|
51
59
|
if (videoDecoder.state === 'closed') {
|
|
@@ -23,7 +23,8 @@ const defaultOnVideoTrackHandler = async ({ track, defaultVideoCodec, logLevel,
|
|
|
23
23
|
return Promise.resolve({
|
|
24
24
|
type: 'reencode',
|
|
25
25
|
videoCodec: defaultVideoCodec,
|
|
26
|
-
|
|
26
|
+
// By default, will remove rotation when re-encoding
|
|
27
|
+
rotate: undefined,
|
|
27
28
|
resize: resizeOperation,
|
|
28
29
|
});
|
|
29
30
|
}
|
package/dist/esm/index.mjs
CHANGED
|
@@ -3751,7 +3751,11 @@ var createMatroskaMedia = async ({
|
|
|
3751
3751
|
isVideo,
|
|
3752
3752
|
chunk
|
|
3753
3753
|
})) {
|
|
3754
|
-
return {
|
|
3754
|
+
return {
|
|
3755
|
+
cluster: currentCluster,
|
|
3756
|
+
isNew: false,
|
|
3757
|
+
smallestProgress
|
|
3758
|
+
};
|
|
3755
3759
|
}
|
|
3756
3760
|
currentCluster = await makeCluster({
|
|
3757
3761
|
writer: w,
|
|
@@ -3759,7 +3763,11 @@ var createMatroskaMedia = async ({
|
|
|
3759
3763
|
timescale,
|
|
3760
3764
|
logLevel
|
|
3761
3765
|
});
|
|
3762
|
-
return {
|
|
3766
|
+
return {
|
|
3767
|
+
cluster: currentCluster,
|
|
3768
|
+
isNew: true,
|
|
3769
|
+
smallestProgress
|
|
3770
|
+
};
|
|
3763
3771
|
};
|
|
3764
3772
|
const updateDuration = async (newDuration) => {
|
|
3765
3773
|
const blocks = makeDurationWithPadding(newDuration);
|
|
@@ -3771,6 +3779,7 @@ var createMatroskaMedia = async ({
|
|
|
3771
3779
|
trackNumber,
|
|
3772
3780
|
isVideo
|
|
3773
3781
|
}) => {
|
|
3782
|
+
const offset = w.getWrittenByteCount();
|
|
3774
3783
|
const { cluster, isNew, smallestProgress } = await getClusterOrMakeNew({
|
|
3775
3784
|
chunk,
|
|
3776
3785
|
isVideo
|
|
@@ -3779,10 +3788,12 @@ var createMatroskaMedia = async ({
|
|
|
3779
3788
|
await updateDuration(newDuration);
|
|
3780
3789
|
const { timecodeRelativeToCluster } = await cluster.addSample(chunk, trackNumber);
|
|
3781
3790
|
if (isNew) {
|
|
3782
|
-
|
|
3791
|
+
if (offset === null) {
|
|
3792
|
+
throw new Error("offset is null");
|
|
3793
|
+
}
|
|
3783
3794
|
cues.push({
|
|
3784
3795
|
time: timestampToClusterTimestamp(smallestProgress, timescale) + timecodeRelativeToCluster,
|
|
3785
|
-
clusterPosition:
|
|
3796
|
+
clusterPosition: offset - seekHeadOffset,
|
|
3786
3797
|
trackNumber
|
|
3787
3798
|
});
|
|
3788
3799
|
}
|
|
@@ -4253,8 +4264,39 @@ var getWaveAudioDecoder = ({
|
|
|
4253
4264
|
};
|
|
4254
4265
|
};
|
|
4255
4266
|
|
|
4267
|
+
// src/undecodable-error.ts
|
|
4268
|
+
class VideoUndecodableError extends Error {
|
|
4269
|
+
config;
|
|
4270
|
+
constructor({
|
|
4271
|
+
message,
|
|
4272
|
+
config
|
|
4273
|
+
}) {
|
|
4274
|
+
super(message);
|
|
4275
|
+
this.name = "VideoUndecodableError";
|
|
4276
|
+
this.config = config;
|
|
4277
|
+
if (Error.captureStackTrace) {
|
|
4278
|
+
Error.captureStackTrace(this, VideoUndecodableError);
|
|
4279
|
+
}
|
|
4280
|
+
}
|
|
4281
|
+
}
|
|
4282
|
+
|
|
4283
|
+
class AudioUndecodableError extends Error {
|
|
4284
|
+
config;
|
|
4285
|
+
constructor({
|
|
4286
|
+
message,
|
|
4287
|
+
config
|
|
4288
|
+
}) {
|
|
4289
|
+
super(message);
|
|
4290
|
+
this.name = "AudioUndecodableError";
|
|
4291
|
+
this.config = config;
|
|
4292
|
+
if (Error.captureStackTrace) {
|
|
4293
|
+
Error.captureStackTrace(this, AudioUndecodableError);
|
|
4294
|
+
}
|
|
4295
|
+
}
|
|
4296
|
+
}
|
|
4297
|
+
|
|
4256
4298
|
// src/create-audio-decoder.ts
|
|
4257
|
-
var internalCreateAudioDecoder = ({
|
|
4299
|
+
var internalCreateAudioDecoder = async ({
|
|
4258
4300
|
onFrame,
|
|
4259
4301
|
onError,
|
|
4260
4302
|
controller,
|
|
@@ -4309,6 +4351,13 @@ var internalCreateAudioDecoder = ({
|
|
|
4309
4351
|
if (controller) {
|
|
4310
4352
|
controller._internals._mediaParserController._internals.signal.addEventListener("abort", onAbort);
|
|
4311
4353
|
}
|
|
4354
|
+
const isConfigSupported = await AudioDecoder.isConfigSupported(config);
|
|
4355
|
+
if (!isConfigSupported) {
|
|
4356
|
+
throw new AudioUndecodableError({
|
|
4357
|
+
message: "Audio cannot be decoded by this browser",
|
|
4358
|
+
config
|
|
4359
|
+
});
|
|
4360
|
+
}
|
|
4312
4361
|
audioDecoder.configure(config);
|
|
4313
4362
|
const decode = async (audioSample) => {
|
|
4314
4363
|
if (audioDecoder.state === "closed") {
|
|
@@ -4547,7 +4596,7 @@ var reencodeAudioTrack = async ({
|
|
|
4547
4596
|
newAudioData.close();
|
|
4548
4597
|
}
|
|
4549
4598
|
});
|
|
4550
|
-
const audioDecoder = internalCreateAudioDecoder({
|
|
4599
|
+
const audioDecoder = await internalCreateAudioDecoder({
|
|
4551
4600
|
onFrame: async (audioData) => {
|
|
4552
4601
|
await controller._internals._mediaParserController._internals.checkForAbortAndPause();
|
|
4553
4602
|
await audioProcessingQueue.ioSynchronizer.waitForQueueSize(10);
|
|
@@ -4700,7 +4749,7 @@ var defaultOnVideoTrackHandler = async ({
|
|
|
4700
4749
|
return Promise.resolve({
|
|
4701
4750
|
type: "reencode",
|
|
4702
4751
|
videoCodec: defaultVideoCodec,
|
|
4703
|
-
rotate:
|
|
4752
|
+
rotate: undefined,
|
|
4704
4753
|
resize: resizeOperation
|
|
4705
4754
|
});
|
|
4706
4755
|
}
|
|
@@ -4730,7 +4779,7 @@ var arrayBufferToUint8Array = (buffer) => {
|
|
|
4730
4779
|
};
|
|
4731
4780
|
|
|
4732
4781
|
// src/create-video-decoder.ts
|
|
4733
|
-
var internalCreateVideoDecoder = ({
|
|
4782
|
+
var internalCreateVideoDecoder = async ({
|
|
4734
4783
|
onFrame,
|
|
4735
4784
|
onError,
|
|
4736
4785
|
controller,
|
|
@@ -4775,6 +4824,13 @@ var internalCreateVideoDecoder = ({
|
|
|
4775
4824
|
if (controller) {
|
|
4776
4825
|
controller._internals._mediaParserController._internals.signal.addEventListener("abort", onAbort);
|
|
4777
4826
|
}
|
|
4827
|
+
const isConfigSupported = await VideoDecoder.isConfigSupported(config);
|
|
4828
|
+
if (!isConfigSupported) {
|
|
4829
|
+
throw new VideoUndecodableError({
|
|
4830
|
+
message: "Video cannot be decoded by this browser",
|
|
4831
|
+
config
|
|
4832
|
+
});
|
|
4833
|
+
}
|
|
4778
4834
|
videoDecoder.configure(config);
|
|
4779
4835
|
const decode = async (sample) => {
|
|
4780
4836
|
if (videoDecoder.state === "closed") {
|
|
@@ -5172,7 +5228,7 @@ var reencodeVideoTrack = async ({
|
|
|
5172
5228
|
videoProcessingQueue.input(frame);
|
|
5173
5229
|
}
|
|
5174
5230
|
});
|
|
5175
|
-
const videoDecoder = createVideoDecoder({
|
|
5231
|
+
const videoDecoder = await createVideoDecoder({
|
|
5176
5232
|
track: videoDecoderConfig,
|
|
5177
5233
|
onFrame: async (frame) => {
|
|
5178
5234
|
await frameSorter.waitUntilProcessed();
|
|
@@ -5641,7 +5697,7 @@ var internalExtractFrames = ({
|
|
|
5641
5697
|
throw new Error("expected at least one timestamp to extract but found zero");
|
|
5642
5698
|
}
|
|
5643
5699
|
controller.seek(timestampTargets[0]);
|
|
5644
|
-
const decoder = createVideoDecoder({
|
|
5700
|
+
const decoder = await createVideoDecoder({
|
|
5645
5701
|
onFrame: (frame) => {
|
|
5646
5702
|
Log.trace(logLevel, "Received frame with timestamp", frame.timestamp);
|
|
5647
5703
|
if (expectedFrames.length === 0) {
|
|
@@ -5655,13 +5711,10 @@ var internalExtractFrames = ({
|
|
|
5655
5711
|
lastFrame = frame;
|
|
5656
5712
|
return;
|
|
5657
5713
|
}
|
|
5658
|
-
if (expectedFrames[0] + 6667 < frame.timestamp && lastFrame) {
|
|
5714
|
+
if (expectedFrames[0] + 6667 < frame.timestamp && lastFrame && lastFrame !== lastFrameEmitted) {
|
|
5659
5715
|
onFrame(lastFrame);
|
|
5660
5716
|
lastFrameEmitted = lastFrame;
|
|
5661
5717
|
expectedFrames.shift();
|
|
5662
|
-
if (lastFrame) {
|
|
5663
|
-
lastFrame.close();
|
|
5664
|
-
}
|
|
5665
5718
|
lastFrame = frame;
|
|
5666
5719
|
return;
|
|
5667
5720
|
}
|
|
@@ -5836,11 +5889,11 @@ var getPartialAudioData = async ({
|
|
|
5836
5889
|
acknowledgeRemotionLicense: true,
|
|
5837
5890
|
src,
|
|
5838
5891
|
controller,
|
|
5839
|
-
onAudioTrack: ({ track }) => {
|
|
5892
|
+
onAudioTrack: async ({ track }) => {
|
|
5840
5893
|
if (signal.aborted) {
|
|
5841
5894
|
return null;
|
|
5842
5895
|
}
|
|
5843
|
-
const audioDecoder = createAudioDecoder({
|
|
5896
|
+
const audioDecoder = await createAudioDecoder({
|
|
5844
5897
|
track,
|
|
5845
5898
|
onFrame: (sample) => {
|
|
5846
5899
|
if (signal.aborted) {
|
|
@@ -5940,5 +5993,7 @@ export {
|
|
|
5940
5993
|
canReencodeAudioTrack,
|
|
5941
5994
|
canCopyVideoTrack,
|
|
5942
5995
|
canCopyAudioTrack,
|
|
5943
|
-
WebCodecsInternals
|
|
5996
|
+
WebCodecsInternals,
|
|
5997
|
+
VideoUndecodableError,
|
|
5998
|
+
AudioUndecodableError
|
|
5944
5999
|
};
|
package/dist/esm/worker.mjs
CHANGED
|
@@ -231,8 +231,39 @@ var makeIoSynchronizer = ({
|
|
|
231
231
|
};
|
|
232
232
|
};
|
|
233
233
|
|
|
234
|
+
// src/undecodable-error.ts
|
|
235
|
+
class VideoUndecodableError extends Error {
|
|
236
|
+
config;
|
|
237
|
+
constructor({
|
|
238
|
+
message,
|
|
239
|
+
config
|
|
240
|
+
}) {
|
|
241
|
+
super(message);
|
|
242
|
+
this.name = "VideoUndecodableError";
|
|
243
|
+
this.config = config;
|
|
244
|
+
if (Error.captureStackTrace) {
|
|
245
|
+
Error.captureStackTrace(this, VideoUndecodableError);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
class AudioUndecodableError extends Error {
|
|
251
|
+
config;
|
|
252
|
+
constructor({
|
|
253
|
+
message,
|
|
254
|
+
config
|
|
255
|
+
}) {
|
|
256
|
+
super(message);
|
|
257
|
+
this.name = "AudioUndecodableError";
|
|
258
|
+
this.config = config;
|
|
259
|
+
if (Error.captureStackTrace) {
|
|
260
|
+
Error.captureStackTrace(this, AudioUndecodableError);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
234
265
|
// src/create-video-decoder.ts
|
|
235
|
-
var internalCreateVideoDecoder = ({
|
|
266
|
+
var internalCreateVideoDecoder = async ({
|
|
236
267
|
onFrame,
|
|
237
268
|
onError,
|
|
238
269
|
controller,
|
|
@@ -277,6 +308,13 @@ var internalCreateVideoDecoder = ({
|
|
|
277
308
|
if (controller) {
|
|
278
309
|
controller._internals._mediaParserController._internals.signal.addEventListener("abort", onAbort);
|
|
279
310
|
}
|
|
311
|
+
const isConfigSupported = await VideoDecoder.isConfigSupported(config);
|
|
312
|
+
if (!isConfigSupported) {
|
|
313
|
+
throw new VideoUndecodableError({
|
|
314
|
+
message: "Video cannot be decoded by this browser",
|
|
315
|
+
config
|
|
316
|
+
});
|
|
317
|
+
}
|
|
280
318
|
videoDecoder.configure(config);
|
|
281
319
|
const decode = async (sample) => {
|
|
282
320
|
if (videoDecoder.state === "closed") {
|
|
@@ -387,7 +425,7 @@ var internalExtractFrames = ({
|
|
|
387
425
|
throw new Error("expected at least one timestamp to extract but found zero");
|
|
388
426
|
}
|
|
389
427
|
controller.seek(timestampTargets[0]);
|
|
390
|
-
const decoder = createVideoDecoder({
|
|
428
|
+
const decoder = await createVideoDecoder({
|
|
391
429
|
onFrame: (frame) => {
|
|
392
430
|
Log.trace(logLevel, "Received frame with timestamp", frame.timestamp);
|
|
393
431
|
if (expectedFrames.length === 0) {
|
|
@@ -401,13 +439,10 @@ var internalExtractFrames = ({
|
|
|
401
439
|
lastFrame = frame;
|
|
402
440
|
return;
|
|
403
441
|
}
|
|
404
|
-
if (expectedFrames[0] + 6667 < frame.timestamp && lastFrame) {
|
|
442
|
+
if (expectedFrames[0] + 6667 < frame.timestamp && lastFrame && lastFrame !== lastFrameEmitted) {
|
|
405
443
|
onFrame(lastFrame);
|
|
406
444
|
lastFrameEmitted = lastFrame;
|
|
407
445
|
expectedFrames.shift();
|
|
408
|
-
if (lastFrame) {
|
|
409
|
-
lastFrame.close();
|
|
410
|
-
}
|
|
411
446
|
lastFrame = frame;
|
|
412
447
|
return;
|
|
413
448
|
}
|
|
@@ -69,11 +69,11 @@ const getPartialAudioData = async ({ src, fromSeconds, toSeconds, channelIndex,
|
|
|
69
69
|
acknowledgeRemotionLicense: true,
|
|
70
70
|
src,
|
|
71
71
|
controller,
|
|
72
|
-
onAudioTrack: ({ track }) => {
|
|
72
|
+
onAudioTrack: async ({ track }) => {
|
|
73
73
|
if (signal.aborted) {
|
|
74
74
|
return null;
|
|
75
75
|
}
|
|
76
|
-
const audioDecoder = (0, create_audio_decoder_1.createAudioDecoder)({
|
|
76
|
+
const audioDecoder = await (0, create_audio_decoder_1.createAudioDecoder)({
|
|
77
77
|
track,
|
|
78
78
|
onFrame: (sample) => {
|
|
79
79
|
if (signal.aborted) {
|
package/dist/index.d.ts
CHANGED
|
@@ -28,6 +28,7 @@ export type { AudioOperation, ConvertMediaOnAudioTrackHandler, } from './on-audi
|
|
|
28
28
|
export type { ConvertMediaOnVideoTrackHandler, VideoOperation, } from './on-video-track-handler';
|
|
29
29
|
export type { ResizeOperation } from './resizing/mode';
|
|
30
30
|
export { rotateAndResizeVideoFrame } from './rotate-and-resize-video-frame';
|
|
31
|
+
export { AudioUndecodableError, VideoUndecodableError, } from './undecodable-error';
|
|
31
32
|
export { createVideoEncoder } from './video-encoder';
|
|
32
33
|
export type { WebCodecsVideoEncoder } from './video-encoder';
|
|
33
34
|
export { webcodecsController } from './webcodecs-controller';
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.WebCodecsInternals = exports.webcodecsController = exports.createVideoEncoder = exports.rotateAndResizeVideoFrame = exports.getPartialAudioData = exports.getDefaultVideoCodec = exports.getDefaultAudioCodec = exports.getAvailableVideoCodecs = exports.getAvailableContainers = exports.getAvailableAudioCodecs = exports.extractFrames = exports.defaultOnVideoTrackHandler = exports.defaultOnAudioTrackHandler = exports.createVideoDecoder = exports.createAudioDecoder = exports.convertMedia = exports.convertAudioData = exports.canReencodeVideoTrack = exports.canReencodeAudioTrack = exports.canCopyVideoTrack = exports.canCopyAudioTrack = exports.createAudioEncoder = void 0;
|
|
3
|
+
exports.WebCodecsInternals = exports.webcodecsController = exports.createVideoEncoder = exports.VideoUndecodableError = exports.AudioUndecodableError = exports.rotateAndResizeVideoFrame = exports.getPartialAudioData = exports.getDefaultVideoCodec = exports.getDefaultAudioCodec = exports.getAvailableVideoCodecs = exports.getAvailableContainers = exports.getAvailableAudioCodecs = exports.extractFrames = exports.defaultOnVideoTrackHandler = exports.defaultOnAudioTrackHandler = exports.createVideoDecoder = exports.createAudioDecoder = exports.convertMedia = exports.convertAudioData = exports.canReencodeVideoTrack = exports.canReencodeAudioTrack = exports.canCopyVideoTrack = exports.canCopyAudioTrack = exports.createAudioEncoder = void 0;
|
|
4
4
|
const rotate_and_resize_video_frame_1 = require("./rotate-and-resize-video-frame");
|
|
5
5
|
const rotation_1 = require("./rotation");
|
|
6
6
|
const set_remotion_imported_1 = require("./set-remotion-imported");
|
|
@@ -42,6 +42,9 @@ var get_partial_audio_data_1 = require("./get-partial-audio-data");
|
|
|
42
42
|
Object.defineProperty(exports, "getPartialAudioData", { enumerable: true, get: function () { return get_partial_audio_data_1.getPartialAudioData; } });
|
|
43
43
|
var rotate_and_resize_video_frame_2 = require("./rotate-and-resize-video-frame");
|
|
44
44
|
Object.defineProperty(exports, "rotateAndResizeVideoFrame", { enumerable: true, get: function () { return rotate_and_resize_video_frame_2.rotateAndResizeVideoFrame; } });
|
|
45
|
+
var undecodable_error_1 = require("./undecodable-error");
|
|
46
|
+
Object.defineProperty(exports, "AudioUndecodableError", { enumerable: true, get: function () { return undecodable_error_1.AudioUndecodableError; } });
|
|
47
|
+
Object.defineProperty(exports, "VideoUndecodableError", { enumerable: true, get: function () { return undecodable_error_1.VideoUndecodableError; } });
|
|
45
48
|
var video_encoder_1 = require("./video-encoder");
|
|
46
49
|
Object.defineProperty(exports, "createVideoEncoder", { enumerable: true, get: function () { return video_encoder_1.createVideoEncoder; } });
|
|
47
50
|
var webcodecs_controller_1 = require("./webcodecs-controller");
|
|
@@ -38,7 +38,7 @@ const internalExtractFrames = ({ src, onFrame, signal, timestampsInSeconds, ackn
|
|
|
38
38
|
throw new Error('expected at least one timestamp to extract but found zero');
|
|
39
39
|
}
|
|
40
40
|
controller.seek(timestampTargets[0]);
|
|
41
|
-
const decoder = (0, create_video_decoder_1.createVideoDecoder)({
|
|
41
|
+
const decoder = await (0, create_video_decoder_1.createVideoDecoder)({
|
|
42
42
|
onFrame: (frame) => {
|
|
43
43
|
log_1.Log.trace(logLevel, 'Received frame with timestamp', frame.timestamp);
|
|
44
44
|
if (expectedFrames.length === 0) {
|
|
@@ -55,13 +55,12 @@ const internalExtractFrames = ({ src, onFrame, signal, timestampsInSeconds, ackn
|
|
|
55
55
|
// A WebM might have a timestamp of 67000 but we request 66666
|
|
56
56
|
// See a test with this problem in it-tests/rendering/frame-accuracy.test.ts
|
|
57
57
|
// Solution: We allow a 10.000ms - 3.333ms = 6.667ms difference between the requested timestamp and the actual timestamp
|
|
58
|
-
if (expectedFrames[0] + 6667 < frame.timestamp &&
|
|
58
|
+
if (expectedFrames[0] + 6667 < frame.timestamp &&
|
|
59
|
+
lastFrame &&
|
|
60
|
+
lastFrame !== lastFrameEmitted) {
|
|
59
61
|
onFrame(lastFrame);
|
|
60
62
|
lastFrameEmitted = lastFrame;
|
|
61
63
|
expectedFrames.shift();
|
|
62
|
-
if (lastFrame) {
|
|
63
|
-
lastFrame.close();
|
|
64
|
-
}
|
|
65
64
|
lastFrame = frame;
|
|
66
65
|
return;
|
|
67
66
|
}
|
|
@@ -129,7 +129,7 @@ const reencodeAudioTrack = async ({ audioOperation, track, logLevel, abortConver
|
|
|
129
129
|
newAudioData.close();
|
|
130
130
|
},
|
|
131
131
|
});
|
|
132
|
-
const audioDecoder = (0, create_audio_decoder_1.internalCreateAudioDecoder)({
|
|
132
|
+
const audioDecoder = await (0, create_audio_decoder_1.internalCreateAudioDecoder)({
|
|
133
133
|
onFrame: async (audioData) => {
|
|
134
134
|
await controller._internals._mediaParserController._internals.checkForAbortAndPause();
|
|
135
135
|
await audioProcessingQueue.ioSynchronizer.waitForQueueSize(10);
|
|
@@ -111,7 +111,7 @@ const reencodeVideoTrack = async ({ videoOperation, rotate, track, logLevel, abo
|
|
|
111
111
|
videoProcessingQueue.input(frame);
|
|
112
112
|
},
|
|
113
113
|
});
|
|
114
|
-
const videoDecoder = (0, create_video_decoder_1.createVideoDecoder)({
|
|
114
|
+
const videoDecoder = await (0, create_video_decoder_1.createVideoDecoder)({
|
|
115
115
|
track: videoDecoderConfig,
|
|
116
116
|
onFrame: async (frame) => {
|
|
117
117
|
await frameSorter.waitUntilProcessed();
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare class VideoUndecodableError extends Error {
|
|
2
|
+
config: VideoDecoderConfig;
|
|
3
|
+
constructor({ message, config, }: {
|
|
4
|
+
message: string;
|
|
5
|
+
config: VideoDecoderConfig;
|
|
6
|
+
});
|
|
7
|
+
}
|
|
8
|
+
export declare class AudioUndecodableError extends Error {
|
|
9
|
+
config: AudioDecoderConfig;
|
|
10
|
+
constructor({ message, config, }: {
|
|
11
|
+
message: string;
|
|
12
|
+
config: AudioDecoderConfig;
|
|
13
|
+
});
|
|
14
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AudioUndecodableError = exports.VideoUndecodableError = void 0;
|
|
4
|
+
class VideoUndecodableError extends Error {
|
|
5
|
+
constructor({ message, config, }) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.name = 'VideoUndecodableError';
|
|
8
|
+
this.config = config;
|
|
9
|
+
if (Error.captureStackTrace) {
|
|
10
|
+
Error.captureStackTrace(this, VideoUndecodableError);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
exports.VideoUndecodableError = VideoUndecodableError;
|
|
15
|
+
class AudioUndecodableError extends Error {
|
|
16
|
+
constructor({ message, config, }) {
|
|
17
|
+
super(message);
|
|
18
|
+
this.name = 'AudioUndecodableError';
|
|
19
|
+
this.config = config;
|
|
20
|
+
if (Error.captureStackTrace) {
|
|
21
|
+
Error.captureStackTrace(this, AudioUndecodableError);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
exports.AudioUndecodableError = AudioUndecodableError;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remotion/webcodecs",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.333",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"module": "dist/esm/index.mjs",
|
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
"author": "Jonny Burger <jonny@remotion.dev>",
|
|
20
20
|
"license": "Remotion License (See https://remotion.dev/docs/webcodecs#license)",
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@remotion/
|
|
23
|
-
"@remotion/
|
|
22
|
+
"@remotion/licensing": "4.0.333",
|
|
23
|
+
"@remotion/media-parser": "4.0.333"
|
|
24
24
|
},
|
|
25
25
|
"peerDependencies": {},
|
|
26
26
|
"devDependencies": {
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
"vite": "5.4.19",
|
|
30
30
|
"@playwright/test": "1.51.1",
|
|
31
31
|
"eslint": "9.19.0",
|
|
32
|
-
"@remotion/
|
|
33
|
-
"@remotion/
|
|
32
|
+
"@remotion/eslint-config-internal": "4.0.333",
|
|
33
|
+
"@remotion/example-videos": "4.0.333"
|
|
34
34
|
},
|
|
35
35
|
"keywords": [],
|
|
36
36
|
"publishConfig": {
|