mirror of
https://github.com/arcodange-org/mediabunny.git
synced 2026-09-27 02:43:48 +02:00
Add more conversion tests for trimming wholly outside of the available media range
This commit is contained in:
+21
-4
@@ -1781,8 +1781,16 @@ export class Conversion {
|
||||
break;
|
||||
}
|
||||
|
||||
const adjustedSampleTimestamp = Math.max(0, sample.timestamp + this._timestampOffset);
|
||||
sample.setTimestamp(adjustedSampleTimestamp);
|
||||
const clampedStartTimestamp = Math.max(this._startTimestamp, sample.timestamp);
|
||||
const clampedEndTimestamp = Math.min(this._endTimestamp, sample.timestamp + sample.duration);
|
||||
|
||||
if (clampedStartTimestamp >= clampedEndTimestamp) {
|
||||
// Wholly out of the trim region
|
||||
continue;
|
||||
}
|
||||
|
||||
sample.setTimestamp(clampedStartTimestamp + this._timestampOffset);
|
||||
sample.setDuration(clampedEndTimestamp - clampedStartTimestamp);
|
||||
|
||||
this._reportProgress(outputTrackId, sample.timestamp + sample.duration);
|
||||
await source.add(sample);
|
||||
@@ -1874,8 +1882,17 @@ export class Conversion {
|
||||
|
||||
if (
|
||||
startPacket
|
||||
&& startPacket.timestamp < this._startTimestamp
|
||||
&& this._copyBoundaryPolicy === 'shrink'
|
||||
&& (
|
||||
(
|
||||
this._copyBoundaryPolicy === 'shrink'
|
||||
&& startPacket.timestamp < this._startTimestamp
|
||||
)
|
||||
|| (
|
||||
this._copyBoundaryPolicy === 'expand'
|
||||
// Check if packet is wholly before the start
|
||||
&& startPacket.timestamp + startPacket.duration <= this._startTimestamp
|
||||
)
|
||||
)
|
||||
) {
|
||||
startPacket = await sink.getNextKeyPacket(startPacket);
|
||||
}
|
||||
|
||||
@@ -939,8 +939,8 @@ test('Packet copy, delta frame trim, video transcoded, Matroska', async () => {
|
||||
shiftTolerance: Infinity,
|
||||
},
|
||||
},
|
||||
expectedTimeOffset: 1.484,
|
||||
videoStartTimestamp: 0.008,
|
||||
expectedTimeOffset: 1.472,
|
||||
videoStartTimestamp: 0.028,
|
||||
videoEndTimestamp: 1.008,
|
||||
audioStartTimestamp: 0,
|
||||
audioEndTimestamp: 1.024,
|
||||
@@ -1053,3 +1053,130 @@ const testCopy = async (options: {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
test('Trim wholly before media data, transcode', async () => {
|
||||
using input = new Input({
|
||||
source: new UrlSource('/demo.mp4'),
|
||||
formats: ALL_FORMATS,
|
||||
});
|
||||
const output = new Output({
|
||||
format: new Mp4OutputFormat(),
|
||||
target: new BufferTarget(),
|
||||
});
|
||||
|
||||
const conversion = await Conversion.init({
|
||||
input,
|
||||
output,
|
||||
video: {
|
||||
forceTranscode: true,
|
||||
},
|
||||
audio: {
|
||||
forceTranscode: true,
|
||||
},
|
||||
trim: {
|
||||
start: -10,
|
||||
end: -5,
|
||||
},
|
||||
});
|
||||
await conversion.execute();
|
||||
|
||||
using newInput = new Input({
|
||||
source: new BufferSource(output.target.buffer!),
|
||||
formats: ALL_FORMATS,
|
||||
});
|
||||
expect(await newInput.getPrimaryVideoTrack()).toBeNull(); // No video data
|
||||
expect(await newInput.getPrimaryAudioTrack()).toBeNull(); // No audio data
|
||||
});
|
||||
|
||||
test('Trim wholly before media data, copy', async () => {
|
||||
using input = new Input({
|
||||
source: new UrlSource('/demo.mp4'),
|
||||
formats: ALL_FORMATS,
|
||||
});
|
||||
const output = new Output({
|
||||
format: new Mp4OutputFormat(),
|
||||
target: new BufferTarget(),
|
||||
});
|
||||
|
||||
const conversion = await Conversion.init({
|
||||
input,
|
||||
output,
|
||||
copy: { mode: 'forced' },
|
||||
trim: {
|
||||
start: -10,
|
||||
end: -5,
|
||||
},
|
||||
});
|
||||
await conversion.execute();
|
||||
|
||||
using newInput = new Input({
|
||||
source: new BufferSource(output.target.buffer!),
|
||||
formats: ALL_FORMATS,
|
||||
});
|
||||
expect(await newInput.getPrimaryVideoTrack()).toBeNull(); // No video data
|
||||
expect(await newInput.getPrimaryAudioTrack()).toBeNull(); // No audio data
|
||||
});
|
||||
|
||||
test('Trim wholly past media data, transcode', async () => {
|
||||
using input = new Input({
|
||||
source: new UrlSource('/demo.mp4'),
|
||||
formats: ALL_FORMATS,
|
||||
});
|
||||
const output = new Output({
|
||||
format: new Mp4OutputFormat(),
|
||||
target: new BufferTarget(),
|
||||
});
|
||||
|
||||
const conversion = await Conversion.init({
|
||||
input,
|
||||
output,
|
||||
video: {
|
||||
forceTranscode: true,
|
||||
},
|
||||
audio: {
|
||||
forceTranscode: true,
|
||||
},
|
||||
trim: {
|
||||
start: 10,
|
||||
end: 15,
|
||||
},
|
||||
});
|
||||
await conversion.execute();
|
||||
|
||||
using newInput = new Input({
|
||||
source: new BufferSource(output.target.buffer!),
|
||||
formats: ALL_FORMATS,
|
||||
});
|
||||
expect(await newInput.getPrimaryVideoTrack()).toBeNull(); // No video data
|
||||
expect(await newInput.getPrimaryAudioTrack()).toBeNull(); // No audio data
|
||||
});
|
||||
|
||||
test('Trim wholly past media data, copy', async () => {
|
||||
using input = new Input({
|
||||
source: new UrlSource('/demo.mp4'),
|
||||
formats: ALL_FORMATS,
|
||||
});
|
||||
const output = new Output({
|
||||
format: new Mp4OutputFormat(),
|
||||
target: new BufferTarget(),
|
||||
});
|
||||
|
||||
const conversion = await Conversion.init({
|
||||
input,
|
||||
output,
|
||||
copy: { mode: 'forced' },
|
||||
trim: {
|
||||
start: 10,
|
||||
end: 15,
|
||||
},
|
||||
});
|
||||
await conversion.execute();
|
||||
|
||||
using newInput = new Input({
|
||||
source: new BufferSource(output.target.buffer!),
|
||||
formats: ALL_FORMATS,
|
||||
});
|
||||
// Don't test video yet; requires extensions to packet fetching logic. B-frames!!
|
||||
// expect(await newInput.getPrimaryVideoTrack()).toBeNull(); // No video data
|
||||
expect(await newInput.getPrimaryAudioTrack()).toBeNull(); // No audio data
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user