Fix empty audio trim range crashing conversion (fixes #486)

This commit is contained in:
Vanilagy
2026-09-08 16:19:56 +02:00
parent 8a25743ee8
commit b560977b50
3 changed files with 25 additions and 17 deletions
+3 -1
View File
@@ -99,7 +99,7 @@
input, input,
output, output,
audio: { audio: {
discard: true, forceTranscode: true,
//discard: true, //discard: true,
//codec: 'aac', //codec: 'aac',
//forceTranscode: true, //forceTranscode: true,
@@ -162,6 +162,8 @@
} }
}, },
trim: { trim: {
start: 30,
end: 35,
//start: -60, //start: -60,
//end: 60, //end: 60,
//start: -2, //start: -2,
+6
View File
@@ -2113,6 +2113,12 @@ export class Conversion {
endFrame = Math.round((this._endTimestamp - sample.timestamp) * sample.sampleRate); endFrame = Math.round((this._endTimestamp - sample.timestamp) * sample.sampleRate);
} }
if (startFrame >= endFrame) {
// Sample lies wholly out of trim region
sample.close();
continue; // No break since we may be before the start
}
// Can't assign to "using" identifiers so we gotta do this // Can't assign to "using" identifiers so we gotta do this
let finalSampleLet: AudioSample; let finalSampleLet: AudioSample;
if (startFrame > 0 || endFrame < sample.numberOfFrames) { if (startFrame > 0 || endFrame < sample.numberOfFrames) {
+16 -16
View File
@@ -2866,32 +2866,32 @@ export class AudioSample implements Disposable {
} }
/** /**
* Returns a new {@link AudioSample} containing only the frames in the range [startSample, endSample). Both bounds * Returns a new {@link AudioSample} containing only the frames in the range [startFrame, endFrame). Both bounds
* must lie within this sample's range of frames. The returned sample's timestamp is shifted to match the start of * must lie within this sample's range of frames. The returned sample's timestamp is shifted to match the start of
* the trimmed section. * the trimmed section.
*/ */
trim(startSample: number, endSample = this.numberOfFrames) { trim(startFrame: number, endFrame = this.numberOfFrames) {
if (!Number.isInteger(startSample) || startSample < 0) { if (!Number.isInteger(startFrame) || startFrame < 0) {
throw new TypeError('startSample must be a non-negative integer.'); throw new TypeError('startFrame must be a non-negative integer.');
} }
if (!Number.isInteger(endSample) || endSample < 0) { if (!Number.isInteger(endFrame) || endFrame < 0) {
throw new TypeError('endSample must be a non-negative integer.'); throw new TypeError('endFrame must be a non-negative integer.');
} }
if (startSample > this.numberOfFrames) { if (startFrame > this.numberOfFrames) {
throw new RangeError('startSample out of range.'); throw new RangeError('startFrame out of range.');
} }
if (endSample > this.numberOfFrames) { if (endFrame > this.numberOfFrames) {
throw new RangeError('endSample out of range.'); throw new RangeError('endFrame out of range.');
} }
if (endSample < startSample) { if (endFrame < startFrame) {
throw new RangeError('endSample must not be less than startSample.'); throw new RangeError('endFrame must not be less than startFrame.');
} }
if (this._closed) { if (this._closed) {
throw new Error('AudioSample is closed.'); throw new Error('AudioSample is closed.');
} }
const frameCount = endSample - startSample; const frameCount = endFrame - startFrame;
const bytesPerSample = getBytesPerSample(this.format); const bytesPerSample = getBytesPerSample(this.format);
let data: Uint8Array; let data: Uint8Array;
@@ -2905,7 +2905,7 @@ export class AudioSample implements Disposable {
this.copyTo(data.subarray(i * planeSize, (i + 1) * planeSize), { this.copyTo(data.subarray(i * planeSize, (i + 1) * planeSize), {
planeIndex: i, planeIndex: i,
format: this.format, format: this.format,
frameOffset: startSample, frameOffset: startFrame,
frameCount, frameCount,
}); });
} }
@@ -2918,7 +2918,7 @@ export class AudioSample implements Disposable {
this.copyTo(data, { this.copyTo(data, {
planeIndex: 0, planeIndex: 0,
format: this.format, format: this.format,
frameOffset: startSample, frameOffset: startFrame,
frameCount, frameCount,
}); });
} }
@@ -2929,7 +2929,7 @@ export class AudioSample implements Disposable {
format: this.format, format: this.format,
sampleRate: this.sampleRate, sampleRate: this.sampleRate,
numberOfChannels: this.numberOfChannels, numberOfChannels: this.numberOfChannels,
timestamp: this.timestamp + startSample / this.sampleRate, timestamp: this.timestamp + startFrame / this.sampleRate,
}); });
} }