Files
mediabunny/test/node/prores.test.ts
T
2026-02-12 12:47:52 +01:00

120 lines
3.6 KiB
TypeScript

import { expect, test } from 'vitest';
import { Input } from '../../src/input.js';
import { BufferSource, UrlSource } from '../../src/source.js';
import { ALL_FORMATS } from '../../src/input-format.js';
import { Output } from '../../src/output.js';
import { MkvOutputFormat, MovOutputFormat } from '../../src/output-format.js';
import { BufferTarget } from '../../src/target.js';
import { Conversion } from '../../src/conversion.js';
import { VideoSampleSink } from '../../src/media-sink.js';
import { CustomVideoDecoder, registerDecoder } from '../../src/custom-coder.js';
import { ProResDecoder } from '../../packages/prores-decoder/src/index.js';
test.concurrent('ProRes MOV file reading', async () => {
using input = new Input({
source: new UrlSource('https://pub-cf9fcfcb5c0a44e9b1bb5ff890e041ae.r2.dev/IMG_0158-prores-log.MOV'),
formats: ALL_FORMATS,
});
const videoTrack = (await input.getPrimaryVideoTrack())!;
expect(videoTrack.codec).toBe('prores');
expect(videoTrack.codedWidth).toBe(1920);
expect(videoTrack.codedHeight).toBe(1080);
const decoderConfig = (await videoTrack.getDecoderConfig())!;
expect(decoderConfig.codec).toBe('apch');
expect(decoderConfig.description).toBeUndefined();
});
test.concurrent('ProRes transmuxing into MOV', { timeout: 60_000 }, async () => {
using input = new Input({
source: new UrlSource('https://pub-cf9fcfcb5c0a44e9b1bb5ff890e041ae.r2.dev/IMG_0158-prores-log.MOV'),
formats: ALL_FORMATS,
});
const output = new Output({
format: new MovOutputFormat(),
target: new BufferTarget(),
});
const conversion = await Conversion.init({
input,
output,
audio: {
discard: true,
},
trim: {
end: 0.5,
},
});
await conversion.execute();
using newInput = new Input({
source: new BufferSource(output.target.buffer!),
formats: ALL_FORMATS,
});
const videoTrack = (await newInput.getPrimaryVideoTrack())!;
expect(videoTrack.codec).toBe('prores');
expect((await videoTrack.computePacketStats()).packetCount).toBe(15);
const decoderConfig = (await videoTrack.getDecoderConfig())!;
expect(decoderConfig.codec).toBe('apch');
expect(decoderConfig.description).toBeUndefined();
});
test.concurrent('ProRes transmuxing into MKV', { timeout: 60_000 }, async () => {
using input = new Input({
source: new UrlSource('https://pub-cf9fcfcb5c0a44e9b1bb5ff890e041ae.r2.dev/IMG_0158-prores-log.MOV'),
formats: ALL_FORMATS,
});
const output = new Output({
format: new MkvOutputFormat(),
target: new BufferTarget(),
});
const conversion = await Conversion.init({
input,
output,
video: {
rotate: 270, // To undo the source rotation metadata so the copy path is taken
},
audio: {
discard: true,
},
trim: {
end: 0.5,
},
});
await conversion.execute();
using newInput = new Input({
source: new BufferSource(output.target.buffer!),
formats: ALL_FORMATS,
});
const videoTrack = (await newInput.getPrimaryVideoTrack())!;
expect(videoTrack.codec).toBe('prores');
expect((await videoTrack.computePacketStats()).packetCount).toBe(15);
const decoderConfig = (await videoTrack.getDecoderConfig())!;
expect(decoderConfig.codec).toBe('apch');
expect(decoderConfig.description).toBeUndefined();
});
test.concurrent.only('ProRes sample ahh', async () => {
registerDecoder(ProResDecoder);
using input = new Input({
source: new UrlSource('https://pub-cf9fcfcb5c0a44e9b1bb5ff890e041ae.r2.dev/IMG_0158-prores-log.MOV'),
formats: ALL_FORMATS,
});
const videoTrack = (await input.getPrimaryVideoTrack())!;
const sink = new VideoSampleSink(videoTrack);
const sample = await sink.getSample(0);
console.log(sample);
});