@remotion/webcodecs 4.0.311 → 4.0.313
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-audio-decoder.d.ts +4 -0
- package/dist/create-audio-decoder.js +31 -6
- package/dist/create-video-decoder.d.ts +4 -0
- package/dist/create-video-decoder.js +38 -6
- package/dist/esm/index.mjs +94 -12
- package/dist/flush-pending.d.ts +10 -0
- package/dist/flush-pending.js +13 -0
- package/dist/get-wave-audio-decoder.js +10 -1
- package/dist/io-manager/io-synchronizer.d.ts +1 -0
- package/dist/io-manager/io-synchronizer.js +15 -0
- package/dist/processing-queue.d.ts +1 -0
- package/package.json +5 -5
|
@@ -6,6 +6,10 @@ export type WebCodecsAudioDecoder = {
|
|
|
6
6
|
flush: () => Promise<void>;
|
|
7
7
|
waitForQueueToBeLessThan: (items: number) => Promise<void>;
|
|
8
8
|
reset: () => void;
|
|
9
|
+
checkReset: () => {
|
|
10
|
+
wasReset: () => boolean;
|
|
11
|
+
};
|
|
12
|
+
getMostRecentSampleInput: () => number | null;
|
|
9
13
|
};
|
|
10
14
|
export type CreateAudioDecoderInit = {
|
|
11
15
|
onFrame: (frame: AudioData) => Promise<void> | void;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createAudioDecoder = exports.internalCreateAudioDecoder = void 0;
|
|
4
|
+
const flush_pending_1 = require("./flush-pending");
|
|
4
5
|
const get_wave_audio_decoder_1 = require("./get-wave-audio-decoder");
|
|
5
6
|
const io_synchronizer_1 = require("./io-manager/io-synchronizer");
|
|
6
7
|
const internalCreateAudioDecoder = ({ onFrame, onError, controller, config, logLevel, }) => {
|
|
@@ -13,6 +14,7 @@ const internalCreateAudioDecoder = ({ onFrame, onError, controller, config, logL
|
|
|
13
14
|
label: 'Audio decoder',
|
|
14
15
|
controller,
|
|
15
16
|
});
|
|
17
|
+
let mostRecentSampleReceived = null;
|
|
16
18
|
if (config.codec === 'pcm-s16') {
|
|
17
19
|
return (0, get_wave_audio_decoder_1.getWaveAudioDecoder)({
|
|
18
20
|
onFrame,
|
|
@@ -67,6 +69,7 @@ const internalCreateAudioDecoder = ({ onFrame, onError, controller, config, logL
|
|
|
67
69
|
onError(err);
|
|
68
70
|
return;
|
|
69
71
|
}
|
|
72
|
+
mostRecentSampleReceived = audioSample.timestamp;
|
|
70
73
|
// Don't flush, it messes up the audio
|
|
71
74
|
const chunk = audioSample instanceof EncodedAudioChunk
|
|
72
75
|
? audioSample
|
|
@@ -81,22 +84,44 @@ const internalCreateAudioDecoder = ({ onFrame, onError, controller, config, logL
|
|
|
81
84
|
ioSynchronizer.inputItem(chunk.timestamp);
|
|
82
85
|
}
|
|
83
86
|
};
|
|
87
|
+
let flushPending = null;
|
|
88
|
+
const lastReset = null;
|
|
84
89
|
return {
|
|
85
90
|
decode,
|
|
86
91
|
close,
|
|
87
|
-
flush:
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
await audioDecoder.flush();
|
|
92
|
+
flush: () => {
|
|
93
|
+
if (flushPending) {
|
|
94
|
+
throw new Error('Flush already pending');
|
|
91
95
|
}
|
|
92
|
-
|
|
93
|
-
|
|
96
|
+
const pendingFlush = (0, flush_pending_1.makeFlushPending)();
|
|
97
|
+
flushPending = pendingFlush;
|
|
98
|
+
Promise.resolve()
|
|
99
|
+
.then(() => {
|
|
100
|
+
return audioDecoder.flush();
|
|
101
|
+
})
|
|
102
|
+
.catch(() => {
|
|
103
|
+
// Firefox might throw "Needs to be configured first"
|
|
104
|
+
})
|
|
105
|
+
.finally(() => {
|
|
106
|
+
pendingFlush.resolve();
|
|
107
|
+
flushPending = null;
|
|
108
|
+
});
|
|
109
|
+
return pendingFlush.promise;
|
|
94
110
|
},
|
|
95
111
|
waitForQueueToBeLessThan: ioSynchronizer.waitForQueueSize,
|
|
96
112
|
reset: () => {
|
|
97
113
|
audioDecoder.reset();
|
|
98
114
|
audioDecoder.configure(config);
|
|
99
115
|
},
|
|
116
|
+
checkReset: () => {
|
|
117
|
+
const initTime = Date.now();
|
|
118
|
+
return {
|
|
119
|
+
wasReset: () => lastReset !== null && lastReset > initTime,
|
|
120
|
+
};
|
|
121
|
+
},
|
|
122
|
+
getMostRecentSampleInput() {
|
|
123
|
+
return mostRecentSampleReceived;
|
|
124
|
+
},
|
|
100
125
|
};
|
|
101
126
|
};
|
|
102
127
|
exports.internalCreateAudioDecoder = internalCreateAudioDecoder;
|
|
@@ -6,6 +6,10 @@ export type WebCodecsVideoDecoder = {
|
|
|
6
6
|
flush: () => Promise<void>;
|
|
7
7
|
waitForQueueToBeLessThan: (items: number) => Promise<void>;
|
|
8
8
|
reset: () => void;
|
|
9
|
+
checkReset: () => {
|
|
10
|
+
wasReset: () => boolean;
|
|
11
|
+
};
|
|
12
|
+
getMostRecentSampleInput: () => number | null;
|
|
9
13
|
};
|
|
10
14
|
export declare const internalCreateVideoDecoder: ({ onFrame, onError, controller, config, logLevel, }: {
|
|
11
15
|
onFrame: (frame: VideoFrame) => Promise<void> | void;
|
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createVideoDecoder = exports.internalCreateVideoDecoder = void 0;
|
|
4
|
+
const flush_pending_1 = require("./flush-pending");
|
|
4
5
|
const io_synchronizer_1 = require("./io-manager/io-synchronizer");
|
|
5
6
|
const internalCreateVideoDecoder = ({ onFrame, onError, controller, config, logLevel, }) => {
|
|
7
|
+
if (controller &&
|
|
8
|
+
controller._internals._mediaParserController._internals.signal.aborted) {
|
|
9
|
+
throw new Error('Not creating audio decoder, already aborted');
|
|
10
|
+
}
|
|
6
11
|
const ioSynchronizer = (0, io_synchronizer_1.makeIoSynchronizer)({
|
|
7
12
|
logLevel,
|
|
8
13
|
label: 'Video decoder',
|
|
9
14
|
controller,
|
|
10
15
|
});
|
|
16
|
+
let mostRecentSampleReceived = null;
|
|
11
17
|
const videoDecoder = new VideoDecoder({
|
|
12
18
|
async output(frame) {
|
|
13
19
|
try {
|
|
@@ -52,28 +58,54 @@ const internalCreateVideoDecoder = ({ onFrame, onError, controller, config, logL
|
|
|
52
58
|
onError(err);
|
|
53
59
|
return;
|
|
54
60
|
}
|
|
61
|
+
mostRecentSampleReceived = sample.timestamp;
|
|
55
62
|
const encodedChunk = sample instanceof EncodedVideoChunk
|
|
56
63
|
? sample
|
|
57
64
|
: new EncodedVideoChunk(sample);
|
|
58
65
|
videoDecoder.decode(encodedChunk);
|
|
59
66
|
ioSynchronizer.inputItem(sample.timestamp);
|
|
60
67
|
};
|
|
68
|
+
let flushPending = null;
|
|
69
|
+
let lastReset = null;
|
|
61
70
|
return {
|
|
62
71
|
decode,
|
|
63
72
|
close,
|
|
64
|
-
flush:
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
await videoDecoder.flush();
|
|
73
|
+
flush: () => {
|
|
74
|
+
if (flushPending) {
|
|
75
|
+
throw new Error('Flush already pending');
|
|
68
76
|
}
|
|
69
|
-
|
|
70
|
-
|
|
77
|
+
const pendingFlush = (0, flush_pending_1.makeFlushPending)();
|
|
78
|
+
flushPending = pendingFlush;
|
|
79
|
+
Promise.resolve()
|
|
80
|
+
.then(() => {
|
|
81
|
+
return videoDecoder.flush();
|
|
82
|
+
})
|
|
83
|
+
.catch(() => {
|
|
84
|
+
// Firefox might throw "Needs to be configured first"
|
|
85
|
+
})
|
|
86
|
+
.finally(() => {
|
|
87
|
+
pendingFlush.resolve();
|
|
88
|
+
flushPending = null;
|
|
89
|
+
});
|
|
90
|
+
return pendingFlush.promise;
|
|
71
91
|
},
|
|
72
92
|
waitForQueueToBeLessThan: ioSynchronizer.waitForQueueSize,
|
|
73
93
|
reset: () => {
|
|
94
|
+
lastReset = Date.now();
|
|
95
|
+
flushPending?.resolve();
|
|
96
|
+
ioSynchronizer.clearQueue();
|
|
74
97
|
videoDecoder.reset();
|
|
75
98
|
videoDecoder.configure(config);
|
|
76
99
|
},
|
|
100
|
+
checkReset: () => {
|
|
101
|
+
const initTime = Date.now();
|
|
102
|
+
return {
|
|
103
|
+
wasReset: () => lastReset !== null && lastReset > initTime,
|
|
104
|
+
};
|
|
105
|
+
},
|
|
106
|
+
getMostRecentSampleInput() {
|
|
107
|
+
return mostRecentSampleReceived;
|
|
108
|
+
},
|
|
77
109
|
};
|
|
78
110
|
};
|
|
79
111
|
exports.internalCreateVideoDecoder = internalCreateVideoDecoder;
|
package/dist/esm/index.mjs
CHANGED
|
@@ -538,6 +538,7 @@ var makeIoSynchronizer = ({
|
|
|
538
538
|
let lastOutput = 0;
|
|
539
539
|
let inputsSinceLastOutput = 0;
|
|
540
540
|
let inputs = [];
|
|
541
|
+
let resolvers = [];
|
|
541
542
|
const getQueuedItems = () => {
|
|
542
543
|
inputs = inputs.filter((input) => Math.floor(input) > Math.floor(lastOutput) + 1);
|
|
543
544
|
return inputs.length;
|
|
@@ -567,8 +568,10 @@ var makeIoSynchronizer = ({
|
|
|
567
568
|
const on = () => {
|
|
568
569
|
eventEmitter.removeEventListener("output", on);
|
|
569
570
|
resolve();
|
|
571
|
+
resolvers = resolvers.filter((resolver) => resolver !== resolve);
|
|
570
572
|
};
|
|
571
573
|
eventEmitter.addEventListener("output", on);
|
|
574
|
+
resolvers.push(resolve);
|
|
572
575
|
return promise;
|
|
573
576
|
};
|
|
574
577
|
const makeErrorBanner = () => {
|
|
@@ -608,10 +611,22 @@ var makeIoSynchronizer = ({
|
|
|
608
611
|
controller._internals._mediaParserController._internals.signal.removeEventListener("abort", clear);
|
|
609
612
|
}
|
|
610
613
|
};
|
|
614
|
+
const clearQueue = () => {
|
|
615
|
+
inputs.length = 0;
|
|
616
|
+
lastInput = 0;
|
|
617
|
+
lastOutput = 0;
|
|
618
|
+
inputsSinceLastOutput = 0;
|
|
619
|
+
resolvers.forEach((resolver) => {
|
|
620
|
+
return resolver();
|
|
621
|
+
});
|
|
622
|
+
resolvers.length = 0;
|
|
623
|
+
inputs.length = 0;
|
|
624
|
+
};
|
|
611
625
|
return {
|
|
612
626
|
inputItem,
|
|
613
627
|
onOutput,
|
|
614
|
-
waitForQueueSize
|
|
628
|
+
waitForQueueSize,
|
|
629
|
+
clearQueue
|
|
615
630
|
};
|
|
616
631
|
};
|
|
617
632
|
|
|
@@ -4135,6 +4150,16 @@ var convertEncodedChunk = (chunk) => {
|
|
|
4135
4150
|
};
|
|
4136
4151
|
};
|
|
4137
4152
|
|
|
4153
|
+
// src/flush-pending.ts
|
|
4154
|
+
var makeFlushPending = () => {
|
|
4155
|
+
const { promise, resolve, reject } = withResolvers();
|
|
4156
|
+
return {
|
|
4157
|
+
promise,
|
|
4158
|
+
resolve,
|
|
4159
|
+
reject
|
|
4160
|
+
};
|
|
4161
|
+
};
|
|
4162
|
+
|
|
4138
4163
|
// src/get-wave-audio-decoder.ts
|
|
4139
4164
|
var getBytesPerSample = (sampleFormat) => {
|
|
4140
4165
|
if (sampleFormat === "s16") {
|
|
@@ -4196,16 +4221,25 @@ var getWaveAudioDecoder = ({
|
|
|
4196
4221
|
onError(err);
|
|
4197
4222
|
}
|
|
4198
4223
|
};
|
|
4224
|
+
let lastReset = null;
|
|
4225
|
+
let mostRecentSampleInput = null;
|
|
4199
4226
|
return {
|
|
4200
4227
|
close() {
|
|
4201
4228
|
return Promise.resolve();
|
|
4202
4229
|
},
|
|
4203
4230
|
decode(audioSample) {
|
|
4231
|
+
mostRecentSampleInput = audioSample.timestamp;
|
|
4204
4232
|
return processSample(audioSample);
|
|
4205
4233
|
},
|
|
4206
4234
|
flush: () => Promise.resolve(),
|
|
4207
4235
|
waitForQueueToBeLessThan: ioSynchronizer.waitForQueueSize,
|
|
4208
|
-
reset: () => {
|
|
4236
|
+
reset: () => {
|
|
4237
|
+
lastReset = Date.now();
|
|
4238
|
+
},
|
|
4239
|
+
checkReset: () => ({
|
|
4240
|
+
wasReset: () => lastReset !== null && lastReset > Date.now()
|
|
4241
|
+
}),
|
|
4242
|
+
getMostRecentSampleInput: () => mostRecentSampleInput
|
|
4209
4243
|
};
|
|
4210
4244
|
};
|
|
4211
4245
|
|
|
@@ -4225,6 +4259,7 @@ var internalCreateAudioDecoder = ({
|
|
|
4225
4259
|
label: "Audio decoder",
|
|
4226
4260
|
controller
|
|
4227
4261
|
});
|
|
4262
|
+
let mostRecentSampleReceived = null;
|
|
4228
4263
|
if (config.codec === "pcm-s16") {
|
|
4229
4264
|
return getWaveAudioDecoder({
|
|
4230
4265
|
onFrame,
|
|
@@ -4275,25 +4310,45 @@ var internalCreateAudioDecoder = ({
|
|
|
4275
4310
|
onError(err);
|
|
4276
4311
|
return;
|
|
4277
4312
|
}
|
|
4313
|
+
mostRecentSampleReceived = audioSample.timestamp;
|
|
4278
4314
|
const chunk = audioSample instanceof EncodedAudioChunk ? audioSample : new EncodedAudioChunk(audioSample);
|
|
4279
4315
|
audioDecoder.decode(chunk);
|
|
4280
4316
|
if (chunk.byteLength > 16) {
|
|
4281
4317
|
ioSynchronizer.inputItem(chunk.timestamp);
|
|
4282
4318
|
}
|
|
4283
4319
|
};
|
|
4320
|
+
let flushPending = null;
|
|
4321
|
+
const lastReset = null;
|
|
4284
4322
|
return {
|
|
4285
4323
|
decode,
|
|
4286
4324
|
close,
|
|
4287
|
-
flush:
|
|
4288
|
-
|
|
4289
|
-
|
|
4290
|
-
}
|
|
4291
|
-
|
|
4325
|
+
flush: () => {
|
|
4326
|
+
if (flushPending) {
|
|
4327
|
+
throw new Error("Flush already pending");
|
|
4328
|
+
}
|
|
4329
|
+
const pendingFlush = makeFlushPending();
|
|
4330
|
+
flushPending = pendingFlush;
|
|
4331
|
+
Promise.resolve().then(() => {
|
|
4332
|
+
return audioDecoder.flush();
|
|
4333
|
+
}).catch(() => {}).finally(() => {
|
|
4334
|
+
pendingFlush.resolve();
|
|
4335
|
+
flushPending = null;
|
|
4336
|
+
});
|
|
4337
|
+
return pendingFlush.promise;
|
|
4292
4338
|
},
|
|
4293
4339
|
waitForQueueToBeLessThan: ioSynchronizer.waitForQueueSize,
|
|
4294
4340
|
reset: () => {
|
|
4295
4341
|
audioDecoder.reset();
|
|
4296
4342
|
audioDecoder.configure(config);
|
|
4343
|
+
},
|
|
4344
|
+
checkReset: () => {
|
|
4345
|
+
const initTime = Date.now();
|
|
4346
|
+
return {
|
|
4347
|
+
wasReset: () => lastReset !== null && lastReset > initTime
|
|
4348
|
+
};
|
|
4349
|
+
},
|
|
4350
|
+
getMostRecentSampleInput() {
|
|
4351
|
+
return mostRecentSampleReceived;
|
|
4297
4352
|
}
|
|
4298
4353
|
};
|
|
4299
4354
|
};
|
|
@@ -4672,11 +4727,15 @@ var internalCreateVideoDecoder = ({
|
|
|
4672
4727
|
config,
|
|
4673
4728
|
logLevel
|
|
4674
4729
|
}) => {
|
|
4730
|
+
if (controller && controller._internals._mediaParserController._internals.signal.aborted) {
|
|
4731
|
+
throw new Error("Not creating audio decoder, already aborted");
|
|
4732
|
+
}
|
|
4675
4733
|
const ioSynchronizer = makeIoSynchronizer({
|
|
4676
4734
|
logLevel,
|
|
4677
4735
|
label: "Video decoder",
|
|
4678
4736
|
controller
|
|
4679
4737
|
});
|
|
4738
|
+
let mostRecentSampleReceived = null;
|
|
4680
4739
|
const videoDecoder = new VideoDecoder({
|
|
4681
4740
|
async output(frame) {
|
|
4682
4741
|
try {
|
|
@@ -4717,23 +4776,46 @@ var internalCreateVideoDecoder = ({
|
|
|
4717
4776
|
onError(err);
|
|
4718
4777
|
return;
|
|
4719
4778
|
}
|
|
4779
|
+
mostRecentSampleReceived = sample.timestamp;
|
|
4720
4780
|
const encodedChunk = sample instanceof EncodedVideoChunk ? sample : new EncodedVideoChunk(sample);
|
|
4721
4781
|
videoDecoder.decode(encodedChunk);
|
|
4722
4782
|
ioSynchronizer.inputItem(sample.timestamp);
|
|
4723
4783
|
};
|
|
4784
|
+
let flushPending = null;
|
|
4785
|
+
let lastReset = null;
|
|
4724
4786
|
return {
|
|
4725
4787
|
decode,
|
|
4726
4788
|
close,
|
|
4727
|
-
flush:
|
|
4728
|
-
|
|
4729
|
-
|
|
4730
|
-
}
|
|
4731
|
-
|
|
4789
|
+
flush: () => {
|
|
4790
|
+
if (flushPending) {
|
|
4791
|
+
throw new Error("Flush already pending");
|
|
4792
|
+
}
|
|
4793
|
+
const pendingFlush = makeFlushPending();
|
|
4794
|
+
flushPending = pendingFlush;
|
|
4795
|
+
Promise.resolve().then(() => {
|
|
4796
|
+
return videoDecoder.flush();
|
|
4797
|
+
}).catch(() => {}).finally(() => {
|
|
4798
|
+
pendingFlush.resolve();
|
|
4799
|
+
flushPending = null;
|
|
4800
|
+
});
|
|
4801
|
+
return pendingFlush.promise;
|
|
4732
4802
|
},
|
|
4733
4803
|
waitForQueueToBeLessThan: ioSynchronizer.waitForQueueSize,
|
|
4734
4804
|
reset: () => {
|
|
4805
|
+
lastReset = Date.now();
|
|
4806
|
+
flushPending?.resolve();
|
|
4807
|
+
ioSynchronizer.clearQueue();
|
|
4735
4808
|
videoDecoder.reset();
|
|
4736
4809
|
videoDecoder.configure(config);
|
|
4810
|
+
},
|
|
4811
|
+
checkReset: () => {
|
|
4812
|
+
const initTime = Date.now();
|
|
4813
|
+
return {
|
|
4814
|
+
wasReset: () => lastReset !== null && lastReset > initTime
|
|
4815
|
+
};
|
|
4816
|
+
},
|
|
4817
|
+
getMostRecentSampleInput() {
|
|
4818
|
+
return mostRecentSampleReceived;
|
|
4737
4819
|
}
|
|
4738
4820
|
};
|
|
4739
4821
|
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type FlushPending = {
|
|
2
|
+
resolve: (value: void | PromiseLike<void>) => void;
|
|
3
|
+
reject: (reason?: any) => void;
|
|
4
|
+
promise: Promise<void>;
|
|
5
|
+
};
|
|
6
|
+
export declare const makeFlushPending: () => {
|
|
7
|
+
promise: Promise<void>;
|
|
8
|
+
resolve: (value: void | PromiseLike<void>) => void;
|
|
9
|
+
reject: (reason?: any) => void;
|
|
10
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.makeFlushPending = void 0;
|
|
4
|
+
const with_resolvers_1 = require("./create/with-resolvers");
|
|
5
|
+
const makeFlushPending = () => {
|
|
6
|
+
const { promise, resolve, reject } = (0, with_resolvers_1.withResolvers)();
|
|
7
|
+
return {
|
|
8
|
+
promise,
|
|
9
|
+
resolve,
|
|
10
|
+
reject,
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
exports.makeFlushPending = makeFlushPending;
|
|
@@ -56,16 +56,25 @@ const getWaveAudioDecoder = ({ onFrame, config, sampleFormat, ioSynchronizer, on
|
|
|
56
56
|
onError(err);
|
|
57
57
|
}
|
|
58
58
|
};
|
|
59
|
+
let lastReset = null;
|
|
60
|
+
let mostRecentSampleInput = null;
|
|
59
61
|
return {
|
|
60
62
|
close() {
|
|
61
63
|
return Promise.resolve();
|
|
62
64
|
},
|
|
63
65
|
decode(audioSample) {
|
|
66
|
+
mostRecentSampleInput = audioSample.timestamp;
|
|
64
67
|
return processSample(audioSample);
|
|
65
68
|
},
|
|
66
69
|
flush: () => Promise.resolve(),
|
|
67
70
|
waitForQueueToBeLessThan: ioSynchronizer.waitForQueueSize,
|
|
68
|
-
reset: () => {
|
|
71
|
+
reset: () => {
|
|
72
|
+
lastReset = Date.now();
|
|
73
|
+
},
|
|
74
|
+
checkReset: () => ({
|
|
75
|
+
wasReset: () => lastReset !== null && lastReset > Date.now(),
|
|
76
|
+
}),
|
|
77
|
+
getMostRecentSampleInput: () => mostRecentSampleInput,
|
|
69
78
|
};
|
|
70
79
|
};
|
|
71
80
|
exports.getWaveAudioDecoder = getWaveAudioDecoder;
|
|
@@ -8,5 +8,6 @@ export declare const makeIoSynchronizer: ({ logLevel, label, controller, }: {
|
|
|
8
8
|
inputItem: (timestamp: number) => void;
|
|
9
9
|
onOutput: (timestamp: number) => void;
|
|
10
10
|
waitForQueueSize: (queueSize: number) => Promise<void>;
|
|
11
|
+
clearQueue: () => void;
|
|
11
12
|
};
|
|
12
13
|
export type IoSynchronizer = ReturnType<typeof makeIoSynchronizer>;
|
|
@@ -11,6 +11,7 @@ const makeIoSynchronizer = ({ logLevel, label, controller, }) => {
|
|
|
11
11
|
let lastOutput = 0;
|
|
12
12
|
let inputsSinceLastOutput = 0;
|
|
13
13
|
let inputs = [];
|
|
14
|
+
let resolvers = [];
|
|
14
15
|
const getQueuedItems = () => {
|
|
15
16
|
inputs = inputs.filter(
|
|
16
17
|
// In chrome, the last output sometimes shifts the timestamp by 1 macrosecond - allowing this to happen
|
|
@@ -42,8 +43,10 @@ const makeIoSynchronizer = ({ logLevel, label, controller, }) => {
|
|
|
42
43
|
const on = () => {
|
|
43
44
|
eventEmitter.removeEventListener('output', on);
|
|
44
45
|
resolve();
|
|
46
|
+
resolvers = resolvers.filter((resolver) => resolver !== resolve);
|
|
45
47
|
};
|
|
46
48
|
eventEmitter.addEventListener('output', on);
|
|
49
|
+
resolvers.push(resolve);
|
|
47
50
|
return promise;
|
|
48
51
|
};
|
|
49
52
|
const makeErrorBanner = () => {
|
|
@@ -82,10 +85,22 @@ const makeIoSynchronizer = ({ logLevel, label, controller, }) => {
|
|
|
82
85
|
controller._internals._mediaParserController._internals.signal.removeEventListener('abort', clear);
|
|
83
86
|
}
|
|
84
87
|
};
|
|
88
|
+
const clearQueue = () => {
|
|
89
|
+
inputs.length = 0;
|
|
90
|
+
lastInput = 0;
|
|
91
|
+
lastOutput = 0;
|
|
92
|
+
inputsSinceLastOutput = 0;
|
|
93
|
+
resolvers.forEach((resolver) => {
|
|
94
|
+
return resolver();
|
|
95
|
+
});
|
|
96
|
+
resolvers.length = 0;
|
|
97
|
+
inputs.length = 0;
|
|
98
|
+
};
|
|
85
99
|
return {
|
|
86
100
|
inputItem,
|
|
87
101
|
onOutput,
|
|
88
102
|
waitForQueueSize,
|
|
103
|
+
clearQueue,
|
|
89
104
|
};
|
|
90
105
|
};
|
|
91
106
|
exports.makeIoSynchronizer = makeIoSynchronizer;
|
|
@@ -13,6 +13,7 @@ export declare function processingQueue<T extends Processable>({ onOutput, logLe
|
|
|
13
13
|
inputItem: (timestamp: number) => void;
|
|
14
14
|
onOutput: (timestamp: number) => void;
|
|
15
15
|
waitForQueueSize: (queueSize: number) => Promise<void>;
|
|
16
|
+
clearQueue: () => void;
|
|
16
17
|
};
|
|
17
18
|
};
|
|
18
19
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remotion/webcodecs",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.313",
|
|
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.313",
|
|
23
|
+
"@remotion/media-parser": "4.0.313"
|
|
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.313",
|
|
33
|
+
"@remotion/example-videos": "4.0.313"
|
|
34
34
|
},
|
|
35
35
|
"keywords": [],
|
|
36
36
|
"publishConfig": {
|