mediabunny 1.22.0 → 1.24.0
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/bundles/mediabunny.cjs +182 -42
- package/dist/bundles/mediabunny.min.cjs +7 -7
- package/dist/bundles/mediabunny.min.mjs +7 -7
- package/dist/bundles/mediabunny.mjs +182 -42
- package/dist/mediabunny.d.ts +64 -0
- package/dist/modules/src/conversion.d.ts +45 -1
- package/dist/modules/src/conversion.d.ts.map +1 -1
- package/dist/modules/src/conversion.js +145 -39
- package/dist/modules/src/index.d.ts +1 -1
- package/dist/modules/src/index.d.ts.map +1 -1
- package/dist/modules/src/index.js +1 -1
- package/dist/modules/src/misc.d.ts +2 -2
- package/dist/modules/src/misc.js +1 -1
- package/dist/modules/src/source.js +6 -0
- package/dist/modules/src/target.d.ts +18 -0
- package/dist/modules/src/target.d.ts.map +1 -1
- package/dist/modules/src/target.js +52 -0
- package/dist/modules/src/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/conversion.ts +237 -43
- package/src/index.ts +2 -0
- package/src/misc.ts +1 -1
- package/src/source.ts +7 -0
- package/src/target.ts +69 -0
|
@@ -77,6 +77,7 @@ var Mediabunny = (() => {
|
|
|
77
77
|
EncodedVideoPacketSource: () => EncodedVideoPacketSource,
|
|
78
78
|
FLAC: () => FLAC,
|
|
79
79
|
FilePathSource: () => FilePathSource,
|
|
80
|
+
FilePathTarget: () => FilePathTarget,
|
|
80
81
|
FlacInputFormat: () => FlacInputFormat,
|
|
81
82
|
FlacOutputFormat: () => FlacOutputFormat,
|
|
82
83
|
Input: () => Input,
|
|
@@ -312,7 +313,7 @@ var Mediabunny = (() => {
|
|
|
312
313
|
// Linear transfer characteristics
|
|
313
314
|
"iec61966-2-1": 13,
|
|
314
315
|
// IEC 61966-2-1
|
|
315
|
-
"
|
|
316
|
+
"pq": 16,
|
|
316
317
|
// Rec. ITU-R BT.2100-2 perceptual quantization (PQ) system
|
|
317
318
|
"hlg": 18
|
|
318
319
|
// Rec. ITU-R BT.2100-2 hybrid loggamma (HLG) system
|
|
@@ -15655,6 +15656,7 @@ var Mediabunny = (() => {
|
|
|
15655
15656
|
this.workers = [];
|
|
15656
15657
|
this.cache = [];
|
|
15657
15658
|
this.currentCacheSize = 0;
|
|
15659
|
+
this.disposed = false;
|
|
15658
15660
|
}
|
|
15659
15661
|
read(innerStart, innerEnd) {
|
|
15660
15662
|
assert(this.fileSize !== null);
|
|
@@ -15831,6 +15833,9 @@ var Mediabunny = (() => {
|
|
|
15831
15833
|
}
|
|
15832
15834
|
/** Called by a worker when it has read some data. */
|
|
15833
15835
|
supplyWorkerData(worker, bytes2) {
|
|
15836
|
+
if (this.disposed) {
|
|
15837
|
+
return;
|
|
15838
|
+
}
|
|
15834
15839
|
const start = worker.currentPos;
|
|
15835
15840
|
const end = start + bytes2.length;
|
|
15836
15841
|
this.insertIntoCache({
|
|
@@ -15962,6 +15967,7 @@ var Mediabunny = (() => {
|
|
|
15962
15967
|
}
|
|
15963
15968
|
this.workers.length = 0;
|
|
15964
15969
|
this.cache.length = 0;
|
|
15970
|
+
this.disposed = true;
|
|
15965
15971
|
}
|
|
15966
15972
|
};
|
|
15967
15973
|
|
|
@@ -18494,6 +18500,8 @@ var Mediabunny = (() => {
|
|
|
18494
18500
|
};
|
|
18495
18501
|
|
|
18496
18502
|
// src/target.ts
|
|
18503
|
+
var nodeAlias2 = __toESM(require_node(), 1);
|
|
18504
|
+
var node2 = typeof nodeAlias2 !== "undefined" ? nodeAlias2 : void 0;
|
|
18497
18505
|
var Target = class {
|
|
18498
18506
|
constructor() {
|
|
18499
18507
|
/** @internal */
|
|
@@ -18542,6 +18550,44 @@ var Mediabunny = (() => {
|
|
|
18542
18550
|
return new StreamTargetWriter(this);
|
|
18543
18551
|
}
|
|
18544
18552
|
};
|
|
18553
|
+
var FilePathTarget = class extends Target {
|
|
18554
|
+
/** Creates a new {@link FilePathTarget} that writes to the file at the specified file path. */
|
|
18555
|
+
constructor(filePath, options = {}) {
|
|
18556
|
+
if (typeof filePath !== "string") {
|
|
18557
|
+
throw new TypeError("filePath must be a string.");
|
|
18558
|
+
}
|
|
18559
|
+
if (!options || typeof options !== "object") {
|
|
18560
|
+
throw new TypeError("options must be an object.");
|
|
18561
|
+
}
|
|
18562
|
+
super();
|
|
18563
|
+
/** @internal */
|
|
18564
|
+
this._fileHandle = null;
|
|
18565
|
+
const writable = new WritableStream({
|
|
18566
|
+
start: async () => {
|
|
18567
|
+
this._fileHandle = await node2.fs.open(filePath, "w");
|
|
18568
|
+
},
|
|
18569
|
+
write: async (chunk) => {
|
|
18570
|
+
assert(this._fileHandle);
|
|
18571
|
+
await this._fileHandle.write(chunk.data, 0, chunk.data.byteLength, chunk.position);
|
|
18572
|
+
},
|
|
18573
|
+
close: async () => {
|
|
18574
|
+
if (this._fileHandle) {
|
|
18575
|
+
await this._fileHandle.close();
|
|
18576
|
+
this._fileHandle = null;
|
|
18577
|
+
}
|
|
18578
|
+
}
|
|
18579
|
+
});
|
|
18580
|
+
this._streamTarget = new StreamTarget(writable, {
|
|
18581
|
+
chunked: true,
|
|
18582
|
+
...options
|
|
18583
|
+
});
|
|
18584
|
+
this._streamTarget._output = this._output;
|
|
18585
|
+
}
|
|
18586
|
+
/** @internal */
|
|
18587
|
+
_createWriter() {
|
|
18588
|
+
return this._streamTarget._createWriter();
|
|
18589
|
+
}
|
|
18590
|
+
};
|
|
18545
18591
|
var NullTarget = class extends Target {
|
|
18546
18592
|
/** @internal */
|
|
18547
18593
|
_createWriter() {
|
|
@@ -23864,7 +23910,16 @@ ${cue.notes ?? ""}`;
|
|
|
23864
23910
|
throw new TypeError("options.video.alpha, when provided, must be either 'discard' or 'keep'.");
|
|
23865
23911
|
}
|
|
23866
23912
|
if (videoOptions?.keyFrameInterval !== void 0 && (!Number.isFinite(videoOptions.keyFrameInterval) || videoOptions.keyFrameInterval < 0)) {
|
|
23867
|
-
throw new TypeError("
|
|
23913
|
+
throw new TypeError("options.video.keyFrameInterval, when provided, must be a non-negative number.");
|
|
23914
|
+
}
|
|
23915
|
+
if (videoOptions?.process !== void 0 && typeof videoOptions.process !== "function") {
|
|
23916
|
+
throw new TypeError("options.video.process, when provided, must be a function.");
|
|
23917
|
+
}
|
|
23918
|
+
if (videoOptions?.processedWidth !== void 0 && (!Number.isInteger(videoOptions.processedWidth) || videoOptions.processedWidth <= 0)) {
|
|
23919
|
+
throw new TypeError("options.video.processedWidth, when provided, must be a positive integer.");
|
|
23920
|
+
}
|
|
23921
|
+
if (videoOptions?.processedHeight !== void 0 && (!Number.isInteger(videoOptions.processedHeight) || videoOptions.processedHeight <= 0)) {
|
|
23922
|
+
throw new TypeError("options.video.processedHeight, when provided, must be a positive integer.");
|
|
23868
23923
|
}
|
|
23869
23924
|
};
|
|
23870
23925
|
var validateAudioOptions = (audioOptions) => {
|
|
@@ -23891,6 +23946,15 @@ ${cue.notes ?? ""}`;
|
|
|
23891
23946
|
if (audioOptions?.sampleRate !== void 0 && (!Number.isInteger(audioOptions.sampleRate) || audioOptions.sampleRate <= 0)) {
|
|
23892
23947
|
throw new TypeError("options.audio.sampleRate, when provided, must be a positive integer.");
|
|
23893
23948
|
}
|
|
23949
|
+
if (audioOptions?.process !== void 0 && typeof audioOptions.process !== "function") {
|
|
23950
|
+
throw new TypeError("options.audio.process, when provided, must be a function.");
|
|
23951
|
+
}
|
|
23952
|
+
if (audioOptions?.processedNumberOfChannels !== void 0 && (!Number.isInteger(audioOptions.processedNumberOfChannels) || audioOptions.processedNumberOfChannels <= 0)) {
|
|
23953
|
+
throw new TypeError("options.audio.processedNumberOfChannels, when provided, must be a positive integer.");
|
|
23954
|
+
}
|
|
23955
|
+
if (audioOptions?.processedSampleRate !== void 0 && (!Number.isInteger(audioOptions.processedSampleRate) || audioOptions.processedSampleRate <= 0)) {
|
|
23956
|
+
throw new TypeError("options.audio.processedSampleRate, when provided, must be a positive integer.");
|
|
23957
|
+
}
|
|
23894
23958
|
};
|
|
23895
23959
|
var FALLBACK_NUMBER_OF_CHANNELS = 2;
|
|
23896
23960
|
var FALLBACK_SAMPLE_RATE = 48e3;
|
|
@@ -24225,7 +24289,7 @@ The @mediabunny/mp3-encoder extension package provides support for encoding MP3.
|
|
|
24225
24289
|
height = ceilToMultipleOfTwo(trackOptions.height);
|
|
24226
24290
|
}
|
|
24227
24291
|
const firstTimestamp = await track.getFirstTimestamp();
|
|
24228
|
-
const needsTranscode = !!trackOptions.forceTranscode || this._startTimestamp > 0 || firstTimestamp < 0 || !!trackOptions.frameRate || trackOptions.keyFrameInterval !== void 0;
|
|
24292
|
+
const needsTranscode = !!trackOptions.forceTranscode || this._startTimestamp > 0 || firstTimestamp < 0 || !!trackOptions.frameRate || trackOptions.keyFrameInterval !== void 0 || trackOptions.process !== void 0;
|
|
24229
24293
|
let needsRerender = width !== originalWidth || height !== originalHeight || totalRotation !== 0 && !outputSupportsRotation || !!crop;
|
|
24230
24294
|
const alpha = trackOptions.alpha ?? "discard";
|
|
24231
24295
|
let videoCodecs = this.output.format.getSupportedVideoCodecs();
|
|
@@ -24239,9 +24303,6 @@ The @mediabunny/mp3-encoder extension package provides support for encoding MP3.
|
|
|
24239
24303
|
const meta = { decoderConfig: decoderConfig ?? void 0 };
|
|
24240
24304
|
const endPacket = Number.isFinite(this._endTimestamp) ? await sink.getPacket(this._endTimestamp, { metadataOnly: true }) ?? void 0 : void 0;
|
|
24241
24305
|
for await (const packet of sink.packets(void 0, endPacket, { verifyKeyPackets: true })) {
|
|
24242
|
-
if (this._synchronizer.shouldWait(track.id, packet.timestamp)) {
|
|
24243
|
-
await this._synchronizer.wait(packet.timestamp);
|
|
24244
|
-
}
|
|
24245
24306
|
if (this._canceled) {
|
|
24246
24307
|
return;
|
|
24247
24308
|
}
|
|
@@ -24249,8 +24310,11 @@ The @mediabunny/mp3-encoder extension package provides support for encoding MP3.
|
|
|
24249
24310
|
delete packet.sideData.alpha;
|
|
24250
24311
|
delete packet.sideData.alphaByteLength;
|
|
24251
24312
|
}
|
|
24313
|
+
this._reportProgress(track.id, packet.timestamp);
|
|
24252
24314
|
await source.add(packet, meta);
|
|
24253
|
-
this.
|
|
24315
|
+
if (this._synchronizer.shouldWait(track.id, packet.timestamp)) {
|
|
24316
|
+
await this._synchronizer.wait(packet.timestamp);
|
|
24317
|
+
}
|
|
24254
24318
|
}
|
|
24255
24319
|
source.close();
|
|
24256
24320
|
this._synchronizer.closeTrack(track.id);
|
|
@@ -24268,7 +24332,11 @@ The @mediabunny/mp3-encoder extension package provides support for encoding MP3.
|
|
|
24268
24332
|
videoCodecs = videoCodecs.filter((codec) => codec === trackOptions.codec);
|
|
24269
24333
|
}
|
|
24270
24334
|
const bitrate = trackOptions.bitrate ?? QUALITY_HIGH;
|
|
24271
|
-
const encodableCodec = await getFirstEncodableVideoCodec(videoCodecs, {
|
|
24335
|
+
const encodableCodec = await getFirstEncodableVideoCodec(videoCodecs, {
|
|
24336
|
+
width: trackOptions.process && trackOptions.processedWidth ? trackOptions.processedWidth : width,
|
|
24337
|
+
height: trackOptions.process && trackOptions.processedHeight ? trackOptions.processedHeight : height,
|
|
24338
|
+
bitrate
|
|
24339
|
+
});
|
|
24272
24340
|
if (!encodableCodec) {
|
|
24273
24341
|
this.discardedTracks.push({
|
|
24274
24342
|
track,
|
|
@@ -24281,8 +24349,7 @@ The @mediabunny/mp3-encoder extension package provides support for encoding MP3.
|
|
|
24281
24349
|
bitrate,
|
|
24282
24350
|
keyFrameInterval: trackOptions.keyFrameInterval,
|
|
24283
24351
|
sizeChangeBehavior: trackOptions.fit ?? "passThrough",
|
|
24284
|
-
alpha
|
|
24285
|
-
onEncodedPacket: (sample) => this._reportProgress(track.id, sample.timestamp + sample.duration)
|
|
24352
|
+
alpha
|
|
24286
24353
|
};
|
|
24287
24354
|
const source = new VideoSampleSource(encodingConfig);
|
|
24288
24355
|
videoSource = source;
|
|
@@ -24338,13 +24405,10 @@ The @mediabunny/mp3-encoder extension package provides support for encoding MP3.
|
|
|
24338
24405
|
timestamp: lastCanvasTimestamp + i / frameRate,
|
|
24339
24406
|
duration: 1 / frameRate
|
|
24340
24407
|
});
|
|
24341
|
-
await
|
|
24408
|
+
await this._registerVideoSample(track, trackOptions, source, sample);
|
|
24342
24409
|
}
|
|
24343
24410
|
};
|
|
24344
24411
|
for await (const { canvas, timestamp, duration } of iterator) {
|
|
24345
|
-
if (this._synchronizer.shouldWait(track.id, timestamp)) {
|
|
24346
|
-
await this._synchronizer.wait(timestamp);
|
|
24347
|
-
}
|
|
24348
24412
|
if (this._canceled) {
|
|
24349
24413
|
return;
|
|
24350
24414
|
}
|
|
@@ -24367,7 +24431,7 @@ The @mediabunny/mp3-encoder extension package provides support for encoding MP3.
|
|
|
24367
24431
|
timestamp: adjustedSampleTimestamp,
|
|
24368
24432
|
duration: frameRate !== void 0 ? 1 / frameRate : duration
|
|
24369
24433
|
});
|
|
24370
|
-
await
|
|
24434
|
+
await this._registerVideoSample(track, trackOptions, source, sample);
|
|
24371
24435
|
if (frameRate !== void 0) {
|
|
24372
24436
|
lastCanvas = canvas;
|
|
24373
24437
|
lastCanvasTimestamp = adjustedSampleTimestamp;
|
|
@@ -24398,14 +24462,11 @@ The @mediabunny/mp3-encoder extension package provides support for encoding MP3.
|
|
|
24398
24462
|
for (let i = 1; i < frameDifference; i++) {
|
|
24399
24463
|
lastSample.setTimestamp(lastSampleTimestamp + i / frameRate);
|
|
24400
24464
|
lastSample.setDuration(1 / frameRate);
|
|
24401
|
-
await
|
|
24465
|
+
await this._registerVideoSample(track, trackOptions, source, lastSample);
|
|
24402
24466
|
}
|
|
24403
24467
|
lastSample.close();
|
|
24404
24468
|
};
|
|
24405
24469
|
for await (const sample of sink.samples(this._startTimestamp, this._endTimestamp)) {
|
|
24406
|
-
if (this._synchronizer.shouldWait(track.id, sample.timestamp)) {
|
|
24407
|
-
await this._synchronizer.wait(sample.timestamp);
|
|
24408
|
-
}
|
|
24409
24470
|
if (this._canceled) {
|
|
24410
24471
|
lastSample?.close();
|
|
24411
24472
|
return;
|
|
@@ -24428,7 +24489,7 @@ The @mediabunny/mp3-encoder extension package provides support for encoding MP3.
|
|
|
24428
24489
|
sample.setDuration(1 / frameRate);
|
|
24429
24490
|
}
|
|
24430
24491
|
sample.setTimestamp(adjustedSampleTimestamp);
|
|
24431
|
-
await
|
|
24492
|
+
await this._registerVideoSample(track, trackOptions, source, sample);
|
|
24432
24493
|
if (frameRate !== void 0) {
|
|
24433
24494
|
lastSample = sample;
|
|
24434
24495
|
lastSampleTimestamp = adjustedSampleTimestamp;
|
|
@@ -24459,6 +24520,49 @@ The @mediabunny/mp3-encoder extension package provides support for encoding MP3.
|
|
|
24459
24520
|
this.utilizedTracks.push(track);
|
|
24460
24521
|
}
|
|
24461
24522
|
/** @internal */
|
|
24523
|
+
async _registerVideoSample(track, trackOptions, source, sample) {
|
|
24524
|
+
if (this._canceled) {
|
|
24525
|
+
return;
|
|
24526
|
+
}
|
|
24527
|
+
this._reportProgress(track.id, sample.timestamp);
|
|
24528
|
+
let finalSamples;
|
|
24529
|
+
if (!trackOptions.process) {
|
|
24530
|
+
finalSamples = [sample];
|
|
24531
|
+
} else {
|
|
24532
|
+
let processed = trackOptions.process(sample);
|
|
24533
|
+
if (processed instanceof Promise) processed = await processed;
|
|
24534
|
+
if (!Array.isArray(processed)) {
|
|
24535
|
+
processed = processed === null ? [] : [processed];
|
|
24536
|
+
}
|
|
24537
|
+
finalSamples = processed.map((x) => {
|
|
24538
|
+
if (x instanceof VideoSample) {
|
|
24539
|
+
return x;
|
|
24540
|
+
}
|
|
24541
|
+
if (typeof VideoFrame !== "undefined" && x instanceof VideoFrame) {
|
|
24542
|
+
return new VideoSample(x);
|
|
24543
|
+
}
|
|
24544
|
+
return new VideoSample(x, {
|
|
24545
|
+
timestamp: sample.timestamp,
|
|
24546
|
+
duration: sample.duration
|
|
24547
|
+
});
|
|
24548
|
+
});
|
|
24549
|
+
}
|
|
24550
|
+
for (const finalSample of finalSamples) {
|
|
24551
|
+
if (this._canceled) {
|
|
24552
|
+
break;
|
|
24553
|
+
}
|
|
24554
|
+
await source.add(finalSample);
|
|
24555
|
+
if (this._synchronizer.shouldWait(track.id, finalSample.timestamp)) {
|
|
24556
|
+
await this._synchronizer.wait(finalSample.timestamp);
|
|
24557
|
+
}
|
|
24558
|
+
}
|
|
24559
|
+
for (const finalSample of finalSamples) {
|
|
24560
|
+
if (finalSample !== sample) {
|
|
24561
|
+
finalSample.close();
|
|
24562
|
+
}
|
|
24563
|
+
}
|
|
24564
|
+
}
|
|
24565
|
+
/** @internal */
|
|
24462
24566
|
async _processAudioTrack(track, trackOptions) {
|
|
24463
24567
|
const sourceCodec = track.codec;
|
|
24464
24568
|
if (!sourceCodec) {
|
|
@@ -24476,7 +24580,7 @@ The @mediabunny/mp3-encoder extension package provides support for encoding MP3.
|
|
|
24476
24580
|
let sampleRate = trackOptions.sampleRate ?? originalSampleRate;
|
|
24477
24581
|
let needsResample = numberOfChannels !== originalNumberOfChannels || sampleRate !== originalSampleRate || this._startTimestamp > 0 || firstTimestamp < 0;
|
|
24478
24582
|
let audioCodecs = this.output.format.getSupportedAudioCodecs();
|
|
24479
|
-
if (!trackOptions.forceTranscode && !trackOptions.bitrate && !needsResample && audioCodecs.includes(sourceCodec) && (!trackOptions.codec || trackOptions.codec === sourceCodec)) {
|
|
24583
|
+
if (!trackOptions.forceTranscode && !trackOptions.bitrate && !needsResample && audioCodecs.includes(sourceCodec) && (!trackOptions.codec || trackOptions.codec === sourceCodec) && !trackOptions.process) {
|
|
24480
24584
|
const source = new EncodedAudioPacketSource(sourceCodec);
|
|
24481
24585
|
audioSource = source;
|
|
24482
24586
|
this._trackPromises.push((async () => {
|
|
@@ -24486,14 +24590,14 @@ The @mediabunny/mp3-encoder extension package provides support for encoding MP3.
|
|
|
24486
24590
|
const meta = { decoderConfig: decoderConfig ?? void 0 };
|
|
24487
24591
|
const endPacket = Number.isFinite(this._endTimestamp) ? await sink.getPacket(this._endTimestamp, { metadataOnly: true }) ?? void 0 : void 0;
|
|
24488
24592
|
for await (const packet of sink.packets(void 0, endPacket)) {
|
|
24489
|
-
if (this._synchronizer.shouldWait(track.id, packet.timestamp)) {
|
|
24490
|
-
await this._synchronizer.wait(packet.timestamp);
|
|
24491
|
-
}
|
|
24492
24593
|
if (this._canceled) {
|
|
24493
24594
|
return;
|
|
24494
24595
|
}
|
|
24596
|
+
this._reportProgress(track.id, packet.timestamp);
|
|
24495
24597
|
await source.add(packet, meta);
|
|
24496
|
-
this.
|
|
24598
|
+
if (this._synchronizer.shouldWait(track.id, packet.timestamp)) {
|
|
24599
|
+
await this._synchronizer.wait(packet.timestamp);
|
|
24600
|
+
}
|
|
24497
24601
|
}
|
|
24498
24602
|
source.close();
|
|
24499
24603
|
this._synchronizer.closeTrack(track.id);
|
|
@@ -24513,11 +24617,11 @@ The @mediabunny/mp3-encoder extension package provides support for encoding MP3.
|
|
|
24513
24617
|
}
|
|
24514
24618
|
const bitrate = trackOptions.bitrate ?? QUALITY_HIGH;
|
|
24515
24619
|
const encodableCodecs = await getEncodableAudioCodecs(audioCodecs, {
|
|
24516
|
-
numberOfChannels,
|
|
24517
|
-
sampleRate,
|
|
24620
|
+
numberOfChannels: trackOptions.process && trackOptions.processedNumberOfChannels ? trackOptions.processedNumberOfChannels : numberOfChannels,
|
|
24621
|
+
sampleRate: trackOptions.process && trackOptions.processedSampleRate ? trackOptions.processedSampleRate : sampleRate,
|
|
24518
24622
|
bitrate
|
|
24519
24623
|
});
|
|
24520
|
-
if (!encodableCodecs.some((codec) => NON_PCM_AUDIO_CODECS.includes(codec)) && audioCodecs.some((codec) => NON_PCM_AUDIO_CODECS.includes(codec)) && (numberOfChannels !== FALLBACK_NUMBER_OF_CHANNELS || sampleRate !== FALLBACK_SAMPLE_RATE)) {
|
|
24624
|
+
if (!encodableCodecs.some((codec) => NON_PCM_AUDIO_CODECS.includes(codec)) && audioCodecs.some((codec) => NON_PCM_AUDIO_CODECS.includes(codec)) && (numberOfChannels !== FALLBACK_NUMBER_OF_CHANNELS || sampleRate !== FALLBACK_SAMPLE_RATE) && !trackOptions.process) {
|
|
24521
24625
|
const encodableCodecsWithDefaultParams = await getEncodableAudioCodecs(audioCodecs, {
|
|
24522
24626
|
numberOfChannels: FALLBACK_NUMBER_OF_CHANNELS,
|
|
24523
24627
|
sampleRate: FALLBACK_SAMPLE_RATE,
|
|
@@ -24541,25 +24645,28 @@ The @mediabunny/mp3-encoder extension package provides support for encoding MP3.
|
|
|
24541
24645
|
return;
|
|
24542
24646
|
}
|
|
24543
24647
|
if (needsResample) {
|
|
24544
|
-
audioSource = this._resampleAudio(
|
|
24648
|
+
audioSource = this._resampleAudio(
|
|
24649
|
+
track,
|
|
24650
|
+
trackOptions,
|
|
24651
|
+
codecOfChoice,
|
|
24652
|
+
numberOfChannels,
|
|
24653
|
+
sampleRate,
|
|
24654
|
+
bitrate
|
|
24655
|
+
);
|
|
24545
24656
|
} else {
|
|
24546
24657
|
const source = new AudioSampleSource({
|
|
24547
24658
|
codec: codecOfChoice,
|
|
24548
|
-
bitrate
|
|
24549
|
-
onEncodedPacket: (packet) => this._reportProgress(track.id, packet.timestamp + packet.duration)
|
|
24659
|
+
bitrate
|
|
24550
24660
|
});
|
|
24551
24661
|
audioSource = source;
|
|
24552
24662
|
this._trackPromises.push((async () => {
|
|
24553
24663
|
await this._started;
|
|
24554
24664
|
const sink = new AudioSampleSink(track);
|
|
24555
24665
|
for await (const sample of sink.samples(void 0, this._endTimestamp)) {
|
|
24556
|
-
if (this._synchronizer.shouldWait(track.id, sample.timestamp)) {
|
|
24557
|
-
await this._synchronizer.wait(sample.timestamp);
|
|
24558
|
-
}
|
|
24559
24666
|
if (this._canceled) {
|
|
24560
24667
|
return;
|
|
24561
24668
|
}
|
|
24562
|
-
await
|
|
24669
|
+
await this._registerAudioSample(track, trackOptions, source, sample);
|
|
24563
24670
|
sample.close();
|
|
24564
24671
|
}
|
|
24565
24672
|
source.close();
|
|
@@ -24577,11 +24684,47 @@ The @mediabunny/mp3-encoder extension package provides support for encoding MP3.
|
|
|
24577
24684
|
this.utilizedTracks.push(track);
|
|
24578
24685
|
}
|
|
24579
24686
|
/** @internal */
|
|
24580
|
-
|
|
24687
|
+
async _registerAudioSample(track, trackOptions, source, sample) {
|
|
24688
|
+
if (this._canceled) {
|
|
24689
|
+
return;
|
|
24690
|
+
}
|
|
24691
|
+
this._reportProgress(track.id, sample.timestamp);
|
|
24692
|
+
let finalSamples;
|
|
24693
|
+
if (!trackOptions.process) {
|
|
24694
|
+
finalSamples = [sample];
|
|
24695
|
+
} else {
|
|
24696
|
+
let processed = trackOptions.process(sample);
|
|
24697
|
+
if (processed instanceof Promise) processed = await processed;
|
|
24698
|
+
if (!Array.isArray(processed)) {
|
|
24699
|
+
processed = processed === null ? [] : [processed];
|
|
24700
|
+
}
|
|
24701
|
+
if (!processed.every((x) => x instanceof AudioSample)) {
|
|
24702
|
+
throw new TypeError(
|
|
24703
|
+
"The audio process function must return an AudioSample, null, or an array of AudioSamples."
|
|
24704
|
+
);
|
|
24705
|
+
}
|
|
24706
|
+
finalSamples = processed;
|
|
24707
|
+
}
|
|
24708
|
+
for (const finalSample of finalSamples) {
|
|
24709
|
+
if (this._canceled) {
|
|
24710
|
+
break;
|
|
24711
|
+
}
|
|
24712
|
+
await source.add(finalSample);
|
|
24713
|
+
if (this._synchronizer.shouldWait(track.id, finalSample.timestamp)) {
|
|
24714
|
+
await this._synchronizer.wait(finalSample.timestamp);
|
|
24715
|
+
}
|
|
24716
|
+
}
|
|
24717
|
+
for (const finalSample of finalSamples) {
|
|
24718
|
+
if (finalSample !== sample) {
|
|
24719
|
+
finalSample.close();
|
|
24720
|
+
}
|
|
24721
|
+
}
|
|
24722
|
+
}
|
|
24723
|
+
/** @internal */
|
|
24724
|
+
_resampleAudio(track, trackOptions, codec, targetNumberOfChannels, targetSampleRate, bitrate) {
|
|
24581
24725
|
const source = new AudioSampleSource({
|
|
24582
24726
|
codec,
|
|
24583
|
-
bitrate
|
|
24584
|
-
onEncodedPacket: (packet) => this._reportProgress(track.id, packet.timestamp + packet.duration)
|
|
24727
|
+
bitrate
|
|
24585
24728
|
});
|
|
24586
24729
|
this._trackPromises.push((async () => {
|
|
24587
24730
|
await this._started;
|
|
@@ -24590,14 +24733,11 @@ The @mediabunny/mp3-encoder extension package provides support for encoding MP3.
|
|
|
24590
24733
|
targetSampleRate,
|
|
24591
24734
|
startTime: this._startTimestamp,
|
|
24592
24735
|
endTime: this._endTimestamp,
|
|
24593
|
-
onSample: (sample) =>
|
|
24736
|
+
onSample: (sample) => this._registerAudioSample(track, trackOptions, source, sample)
|
|
24594
24737
|
});
|
|
24595
24738
|
const sink = new AudioSampleSink(track);
|
|
24596
24739
|
const iterator = sink.samples(this._startTimestamp, this._endTimestamp);
|
|
24597
24740
|
for await (const sample of iterator) {
|
|
24598
|
-
if (this._synchronizer.shouldWait(track.id, sample.timestamp)) {
|
|
24599
|
-
await this._synchronizer.wait(sample.timestamp);
|
|
24600
|
-
}
|
|
24601
24741
|
if (this._canceled) {
|
|
24602
24742
|
return;
|
|
24603
24743
|
}
|