mirror of
https://github.com/arcodange-org/mediabunny.git
synced 2026-10-01 04:43:51 +02:00
Remove input track descriptors, add async getters on tracks for everything, deprecate old sync getters
This commit is contained in:
@@ -16,9 +16,9 @@ test('ADTS demuxing', async () => {
|
||||
const audioTrack = await input.getPrimaryAudioTrack();
|
||||
assert(audioTrack);
|
||||
|
||||
expect(audioTrack.codec).toBe('aac');
|
||||
expect(audioTrack.sampleRate).toBe(44100);
|
||||
expect(audioTrack.numberOfChannels).toBe(2);
|
||||
expect(await audioTrack.getCodec()).toBe('aac');
|
||||
expect(await audioTrack.getSampleRate()).toBe(44100);
|
||||
expect(await audioTrack.getNumberOfChannels()).toBe(2);
|
||||
|
||||
const decoderConfig = await audioTrack.getDecoderConfig();
|
||||
assert(decoderConfig);
|
||||
|
||||
@@ -79,7 +79,7 @@ test('ADTS with metadata over StreamTarget', async () => {
|
||||
|
||||
const outputAudioTrack = await outputAsInput.getPrimaryAudioTrack();
|
||||
assert(outputAudioTrack);
|
||||
expect(outputAudioTrack.codec).toBe('aac');
|
||||
expect(await outputAudioTrack.getCodec()).toBe('aac');
|
||||
});
|
||||
|
||||
// Previously, write handler rejections were silently swallowed and surfaced as
|
||||
|
||||
@@ -17,11 +17,11 @@ test('Rotation is baked-in when rerendering', async () => {
|
||||
const ogTrack = await input.getPrimaryVideoTrack();
|
||||
assert(ogTrack);
|
||||
|
||||
expect(ogTrack.rotation).toBe(90);
|
||||
expect(ogTrack.codedWidth).toBe(1920);
|
||||
expect(ogTrack.codedHeight).toBe(1080);
|
||||
expect(ogTrack.displayWidth).toBe(1080);
|
||||
expect(ogTrack.displayHeight).toBe(1920);
|
||||
expect(await ogTrack.getRotation()).toBe(90);
|
||||
expect(await ogTrack.getCodedWidth()).toBe(1920);
|
||||
expect(await ogTrack.getCodedHeight()).toBe(1080);
|
||||
expect(await ogTrack.getDisplayWidth()).toBe(1080);
|
||||
expect(await ogTrack.getDisplayHeight()).toBe(1920);
|
||||
|
||||
const output = new Output({
|
||||
format: new Mp4OutputFormat(),
|
||||
@@ -41,9 +41,9 @@ test('Rotation is baked-in when rerendering', async () => {
|
||||
const track = await newInput.getPrimaryVideoTrack();
|
||||
assert(track);
|
||||
|
||||
expect(track.codedWidth).toBe(320);
|
||||
expect(track.codedHeight).toBe(570);
|
||||
expect(track.displayWidth).toBe(320);
|
||||
expect(track.displayHeight).toBe(570);
|
||||
expect(track.rotation).toBe(0);
|
||||
expect(await track.getCodedWidth()).toBe(320);
|
||||
expect(await track.getCodedHeight()).toBe(570);
|
||||
expect(await track.getDisplayWidth()).toBe(320);
|
||||
expect(await track.getDisplayHeight()).toBe(570);
|
||||
expect(await track.getRotation()).toBe(0);
|
||||
});
|
||||
|
||||
@@ -62,7 +62,7 @@ test('can convert a .flac to .wav', async () => {
|
||||
IPRD: 'Samples files',
|
||||
ITRK: '4',
|
||||
});
|
||||
expect(inputTrack.sampleRate).toBe(outputTrack.sampleRate);
|
||||
expect(inputTrack.numberOfChannels).toBe(outputTrack.numberOfChannels);
|
||||
expect(inputTrack.timeResolution).toBe(outputTrack.timeResolution);
|
||||
expect(await inputTrack.getSampleRate()).toBe(await outputTrack.getSampleRate());
|
||||
expect(await inputTrack.getNumberOfChannels()).toBe(await outputTrack.getNumberOfChannels());
|
||||
expect(await inputTrack.getTimeResolution()).toBe(await outputTrack.getTimeResolution());
|
||||
});
|
||||
|
||||
@@ -106,8 +106,8 @@ test(
|
||||
);
|
||||
|
||||
const { input, track } = await readBackTrack(buffer);
|
||||
expect(track.codedWidth).toBe(100);
|
||||
expect(track.codedHeight).toBe(100);
|
||||
expect(await track.getCodedWidth()).toBe(100);
|
||||
expect(await track.getCodedHeight()).toBe(100);
|
||||
input.dispose();
|
||||
}
|
||||
},
|
||||
@@ -120,8 +120,8 @@ test('VideoSampleSource, same-sized frames with width and height set', async ()
|
||||
);
|
||||
|
||||
const { input, track } = await readBackTrack(buffer);
|
||||
expect(track.codedWidth).toBe(50);
|
||||
expect(track.codedHeight).toBe(80);
|
||||
expect(await track.getCodedWidth()).toBe(50);
|
||||
expect(await track.getCodedHeight()).toBe(80);
|
||||
input.dispose();
|
||||
});
|
||||
|
||||
@@ -132,8 +132,8 @@ test('VideoSampleSource, same-sized frames with rotation set to 90', async () =>
|
||||
);
|
||||
|
||||
const { input, track } = await readBackTrack(buffer);
|
||||
expect(track.codedWidth).toBe(100);
|
||||
expect(track.codedHeight).toBe(200);
|
||||
expect(await track.getCodedWidth()).toBe(100);
|
||||
expect(await track.getCodedHeight()).toBe(200);
|
||||
input.dispose();
|
||||
});
|
||||
|
||||
@@ -144,8 +144,8 @@ test('VideoSampleSource, same-sized frames with rotation, width and height', asy
|
||||
);
|
||||
|
||||
const { input, track } = await readBackTrack(buffer);
|
||||
expect(track.codedWidth).toBe(50);
|
||||
expect(track.codedHeight).toBe(80);
|
||||
expect(await track.getCodedWidth()).toBe(50);
|
||||
expect(await track.getCodedHeight()).toBe(80);
|
||||
input.dispose();
|
||||
});
|
||||
|
||||
@@ -254,8 +254,8 @@ test('VideoSampleSource, transform.process manual resize', async () => {
|
||||
);
|
||||
|
||||
const { input, track } = await readBackTrack(buffer);
|
||||
expect(track.codedWidth).toBe(60);
|
||||
expect(track.codedHeight).toBe(40);
|
||||
expect(await track.getCodedWidth()).toBe(60);
|
||||
expect(await track.getCodedHeight()).toBe(40);
|
||||
input.dispose();
|
||||
});
|
||||
|
||||
@@ -289,8 +289,8 @@ test('VideoSampleSource, transform.process receives pre-transformed frames', asy
|
||||
}
|
||||
|
||||
const { input, track } = await readBackTrack(buffer);
|
||||
expect(track.codedWidth).toBe(50);
|
||||
expect(track.codedHeight).toBe(80);
|
||||
expect(await track.getCodedWidth()).toBe(50);
|
||||
expect(await track.getCodedHeight()).toBe(80);
|
||||
input.dispose();
|
||||
});
|
||||
|
||||
@@ -492,8 +492,8 @@ test('VideoSampleSource, transform.frameRate works with process', async () => {
|
||||
}
|
||||
|
||||
const { input, track } = await readBackTrack(buffer);
|
||||
expect(track.codedWidth).toBe(60);
|
||||
expect(track.codedHeight).toBe(40);
|
||||
expect(await track.getCodedWidth()).toBe(60);
|
||||
expect(await track.getCodedHeight()).toBe(40);
|
||||
|
||||
input.dispose();
|
||||
});
|
||||
@@ -576,8 +576,8 @@ test('AudioSampleSource, normal usage', async () => {
|
||||
const buffer = await encodeAudio({ codec: 'pcm-s16' }, sample);
|
||||
|
||||
const { input, track } = await readBackAudioTrack(buffer);
|
||||
expect(track.numberOfChannels).toBe(2);
|
||||
expect(track.sampleRate).toBe(48000);
|
||||
expect(await track.getNumberOfChannels()).toBe(2);
|
||||
expect(await track.getSampleRate()).toBe(48000);
|
||||
expect(await track.computeDuration()).toBe(1);
|
||||
input.dispose();
|
||||
});
|
||||
@@ -590,8 +590,8 @@ test('AudioSampleSource, remixed to mono', async () => {
|
||||
);
|
||||
|
||||
const { input, track } = await readBackAudioTrack(buffer);
|
||||
expect(track.numberOfChannels).toBe(1);
|
||||
expect(track.sampleRate).toBe(48000);
|
||||
expect(await track.getNumberOfChannels()).toBe(1);
|
||||
expect(await track.getSampleRate()).toBe(48000);
|
||||
expect(await track.computeDuration()).toBe(1);
|
||||
input.dispose();
|
||||
});
|
||||
@@ -604,8 +604,8 @@ test('AudioSampleSource, resampled to 44100 Hz', async () => {
|
||||
);
|
||||
|
||||
const { input, track } = await readBackAudioTrack(buffer);
|
||||
expect(track.numberOfChannels).toBe(2);
|
||||
expect(track.sampleRate).toBe(44100);
|
||||
expect(await track.getNumberOfChannels()).toBe(2);
|
||||
expect(await track.getSampleRate()).toBe(44100);
|
||||
expect(await track.computeDuration()).toBe(1);
|
||||
input.dispose();
|
||||
});
|
||||
@@ -618,8 +618,8 @@ test('AudioSampleSource, resampled stereo with non-zero start timestamp', async
|
||||
);
|
||||
|
||||
const { input, track } = await readBackAudioTrack(buffer);
|
||||
expect(track.numberOfChannels).toBe(2);
|
||||
expect(track.sampleRate).toBe(48000);
|
||||
expect(await track.getNumberOfChannels()).toBe(2);
|
||||
expect(await track.getSampleRate()).toBe(48000);
|
||||
|
||||
expect(await track.getFirstTimestamp()).toBe(1);
|
||||
expect(await track.computeDuration()).toBe(2);
|
||||
|
||||
@@ -119,9 +119,9 @@ test('MPEG-TS muxing with AVC and AAC', async () => {
|
||||
assert(videoTrack);
|
||||
|
||||
expect(videoTrack.id).toBe(0x100);
|
||||
expect(videoTrack.codec).toBe('avc');
|
||||
expect(videoTrack.displayWidth).toBe(640);
|
||||
expect(videoTrack.displayHeight).toBe(480);
|
||||
expect(await videoTrack.getCodec()).toBe('avc');
|
||||
expect(await videoTrack.getDisplayWidth()).toBe(640);
|
||||
expect(await videoTrack.getDisplayHeight()).toBe(480);
|
||||
|
||||
const videoDecoderConfig = await videoTrack.getDecoderConfig();
|
||||
assert(videoDecoderConfig);
|
||||
@@ -135,9 +135,9 @@ test('MPEG-TS muxing with AVC and AAC', async () => {
|
||||
assert(audioTrack);
|
||||
|
||||
expect(audioTrack.id).toBe(0x101);
|
||||
expect(audioTrack.codec).toBe('aac');
|
||||
expect(audioTrack.numberOfChannels).toBe(2);
|
||||
expect(audioTrack.sampleRate).toBe(48000);
|
||||
expect(await audioTrack.getCodec()).toBe('aac');
|
||||
expect(await audioTrack.getNumberOfChannels()).toBe(2);
|
||||
expect(await audioTrack.getSampleRate()).toBe(48000);
|
||||
|
||||
const audioDecoderConfig = await audioTrack.getDecoderConfig();
|
||||
assert(audioDecoderConfig);
|
||||
@@ -289,7 +289,7 @@ test('MPEG-TS muxing with HEVC and MP3', async () => {
|
||||
assert(videoTrack);
|
||||
|
||||
expect(videoTrack.id).toBe(0x100);
|
||||
expect(videoTrack.codec).toBe('hevc');
|
||||
expect(await videoTrack.getCodec()).toBe('hevc');
|
||||
|
||||
const videoDecoderConfig = await videoTrack.getDecoderConfig();
|
||||
assert(videoDecoderConfig);
|
||||
@@ -301,9 +301,9 @@ test('MPEG-TS muxing with HEVC and MP3', async () => {
|
||||
assert(audioTrack);
|
||||
|
||||
expect(audioTrack.id).toBe(0x101);
|
||||
expect(audioTrack.codec).toBe('mp3');
|
||||
expect(audioTrack.numberOfChannels).toBe(2);
|
||||
expect(audioTrack.sampleRate).toBe(24000);
|
||||
expect(await audioTrack.getCodec()).toBe('mp3');
|
||||
expect(await audioTrack.getNumberOfChannels()).toBe(2);
|
||||
expect(await audioTrack.getSampleRate()).toBe(24000);
|
||||
|
||||
const audioDecoderConfig = await audioTrack.getDecoderConfig();
|
||||
assert(audioDecoderConfig);
|
||||
@@ -407,7 +407,7 @@ test('MPEG-TS muxing with video only', async () => {
|
||||
|
||||
const videoTrack = await input.getPrimaryVideoTrack();
|
||||
assert(videoTrack);
|
||||
expect(videoTrack.codec).toBe('avc');
|
||||
expect(await videoTrack.getCodec()).toBe('avc');
|
||||
|
||||
const audioTrack = await input.getPrimaryAudioTrack();
|
||||
expect(audioTrack).toBeNull();
|
||||
@@ -470,7 +470,7 @@ test('MPEG-TS muxing with audio only', async () => {
|
||||
|
||||
const audioTrack = await input.getPrimaryAudioTrack();
|
||||
assert(audioTrack);
|
||||
expect(audioTrack.codec).toBe('aac');
|
||||
expect(await audioTrack.getCodec()).toBe('aac');
|
||||
|
||||
const audioSink = new EncodedPacketSink(audioTrack);
|
||||
let audioPacketCount = 0;
|
||||
@@ -531,8 +531,8 @@ test('MPEG-TS muxing with two video tracks', async () => {
|
||||
const videoTracks = tracks.filter(t => t.type === 'video');
|
||||
expect(videoTracks.length).toBe(2);
|
||||
|
||||
expect(videoTracks[0]!.codec).toBe('hevc');
|
||||
expect(videoTracks[1]!.codec).toBe('hevc');
|
||||
expect(await videoTracks[0]!.getCodec()).toBe('hevc');
|
||||
expect(await videoTracks[1]!.getCodec()).toBe('hevc');
|
||||
expect(videoTracks[0]!.id).toBe(0x100);
|
||||
expect(videoTracks[1]!.id).toBe(0x101);
|
||||
});
|
||||
@@ -599,8 +599,8 @@ test('MPEG-TS muxing with two audio tracks', async () => {
|
||||
const audioTracks = tracks.filter(t => t.type === 'audio');
|
||||
expect(audioTracks.length).toBe(2);
|
||||
|
||||
expect(audioTracks[0]!.codec).toBe('aac');
|
||||
expect(audioTracks[1]!.codec).toBe('aac');
|
||||
expect(await audioTracks[0]!.getCodec()).toBe('aac');
|
||||
expect(await audioTracks[1]!.getCodec()).toBe('aac');
|
||||
expect(audioTracks[0]!.id).toBe(0x100);
|
||||
expect(audioTracks[1]!.id).toBe(0x101);
|
||||
});
|
||||
@@ -646,8 +646,8 @@ test('MPEG-TS transmux (Annex B and ADTS passthrough)', async () => {
|
||||
assert(outputAudioTrack);
|
||||
|
||||
// Codecs should match
|
||||
expect(outputVideoTrack.codec).toBe(inputVideoTrack.codec);
|
||||
expect(outputAudioTrack.codec).toBe(inputAudioTrack.codec);
|
||||
expect(await outputVideoTrack.getCodec()).toBe(await inputVideoTrack.getCodec());
|
||||
expect(await outputAudioTrack.getCodec()).toBe(await inputAudioTrack.getCodec());
|
||||
|
||||
// Verify video packets are Annex B
|
||||
const videoSink = new EncodedPacketSink(outputVideoTrack);
|
||||
@@ -728,7 +728,7 @@ test('MPEG-TS muxing with StreamTarget', async () => {
|
||||
|
||||
const videoTrack = await input.getPrimaryVideoTrack();
|
||||
assert(videoTrack);
|
||||
expect(videoTrack.codec).toBe('avc');
|
||||
expect(await videoTrack.getCodec()).toBe('avc');
|
||||
|
||||
const videoSink = new EncodedPacketSink(videoTrack);
|
||||
let videoPacketCount = 0;
|
||||
|
||||
+47
-27
@@ -3,7 +3,7 @@ import { Conversion } from '../../src/conversion.js';
|
||||
import { ALL_FORMATS, MATROSKA, MP4, MPEG_TS } from '../../src/input-format.js';
|
||||
import { Input } from '../../src/input.js';
|
||||
import { VideoSampleSink } from '../../src/media-sink.js';
|
||||
import { assert } from '../../src/misc.js';
|
||||
import { assert, Rational } from '../../src/misc.js';
|
||||
import { Output } from '../../src/output.js';
|
||||
import { MkvOutputFormat, Mp4OutputFormat, MpegTsOutputFormat } from '../../src/output-format.js';
|
||||
import { BufferSource, UrlSource } from '../../src/source.js';
|
||||
@@ -22,13 +22,13 @@ test('Pixel aspect ratio reading', async () => {
|
||||
const videoTrack = await input.getPrimaryVideoTrack();
|
||||
assert(videoTrack);
|
||||
|
||||
expect(videoTrack.rotation).toBe(0);
|
||||
expectPar2x1Geometry(videoTrack);
|
||||
expect(await videoTrack.getRotation()).toBe(0);
|
||||
expectPar2x1Geometry(await snapshotTrack(videoTrack));
|
||||
|
||||
const decoderConfig = await videoTrack.getDecoderConfig();
|
||||
assert(decoderConfig);
|
||||
expect(decoderConfig.displayAspectWidth).toBe(videoTrack.squarePixelWidth);
|
||||
expect(decoderConfig.displayAspectHeight).toBe(videoTrack.squarePixelHeight);
|
||||
expect(decoderConfig.displayAspectWidth).toBe(await videoTrack.getSquarePixelWidth());
|
||||
expect(decoderConfig.displayAspectHeight).toBe(await videoTrack.getSquarePixelHeight());
|
||||
|
||||
const sink = new VideoSampleSink(videoTrack);
|
||||
using sample = (await sink.getSample(await videoTrack.getFirstTimestamp()))!;
|
||||
@@ -36,11 +36,11 @@ test('Pixel aspect ratio reading', async () => {
|
||||
expect(sample.rotation).toBe(0);
|
||||
expect(sample.visibleRect.width).toBe(sample.codedWidth);
|
||||
expect(sample.visibleRect.height).toBe(sample.codedHeight);
|
||||
expect(sample.codedWidth).toBe(videoTrack.codedWidth);
|
||||
expect(sample.codedHeight).toBe(videoTrack.codedHeight);
|
||||
expect(sample.codedWidth).toBe(await videoTrack.getCodedWidth());
|
||||
expect(sample.codedHeight).toBe(await videoTrack.getCodedHeight());
|
||||
expectPar2x1Geometry(sample);
|
||||
expect(sample.squarePixelWidth).toBe(videoTrack.squarePixelWidth);
|
||||
expect(sample.squarePixelHeight).toBe(videoTrack.squarePixelHeight);
|
||||
expect(sample.squarePixelWidth).toBe(await videoTrack.getSquarePixelWidth());
|
||||
expect(sample.squarePixelHeight).toBe(await videoTrack.getSquarePixelHeight());
|
||||
});
|
||||
|
||||
test('Pixel aspect ratio copy conversion', async () => {
|
||||
@@ -103,7 +103,7 @@ const expectPar2x1Geometry = (value: {
|
||||
squarePixelHeight: number;
|
||||
displayWidth: number;
|
||||
displayHeight: number;
|
||||
pixelAspectRatio: { num: number; den: number };
|
||||
pixelAspectRatio: Rational;
|
||||
}) => {
|
||||
expect(value.pixelAspectRatio).toEqual({ num: 2, den: 1 });
|
||||
expect(value.squarePixelWidth).toBe(value.codedWidth * 2);
|
||||
@@ -113,28 +113,48 @@ const expectPar2x1Geometry = (value: {
|
||||
};
|
||||
|
||||
const snapshotTrack = async (track: {
|
||||
codedWidth: number;
|
||||
codedHeight: number;
|
||||
squarePixelWidth: number;
|
||||
squarePixelHeight: number;
|
||||
displayWidth: number;
|
||||
displayHeight: number;
|
||||
rotation: number;
|
||||
pixelAspectRatio: { num: number; den: number };
|
||||
getCodedWidth(): Promise<number>;
|
||||
getCodedHeight(): Promise<number>;
|
||||
getSquarePixelWidth(): Promise<number>;
|
||||
getSquarePixelHeight(): Promise<number>;
|
||||
getDisplayWidth(): Promise<number>;
|
||||
getDisplayHeight(): Promise<number>;
|
||||
getRotation(): Promise<number>;
|
||||
getPixelAspectRatio(): Promise<Rational>;
|
||||
getDecoderConfig(): Promise<VideoDecoderConfig | null>;
|
||||
}) => {
|
||||
const decoderConfig = await track.getDecoderConfig();
|
||||
const [
|
||||
decoderConfig,
|
||||
pixelAspectRatio,
|
||||
codedWidth,
|
||||
codedHeight,
|
||||
squarePixelWidth,
|
||||
squarePixelHeight,
|
||||
displayWidth,
|
||||
displayHeight,
|
||||
rotation,
|
||||
] = await Promise.all([
|
||||
track.getDecoderConfig(),
|
||||
track.getPixelAspectRatio(),
|
||||
track.getCodedWidth(),
|
||||
track.getCodedHeight(),
|
||||
track.getSquarePixelWidth(),
|
||||
track.getSquarePixelHeight(),
|
||||
track.getDisplayWidth(),
|
||||
track.getDisplayHeight(),
|
||||
track.getRotation(),
|
||||
]);
|
||||
assert(decoderConfig);
|
||||
|
||||
return {
|
||||
codedWidth: track.codedWidth,
|
||||
codedHeight: track.codedHeight,
|
||||
squarePixelWidth: track.squarePixelWidth,
|
||||
squarePixelHeight: track.squarePixelHeight,
|
||||
displayWidth: track.displayWidth,
|
||||
displayHeight: track.displayHeight,
|
||||
rotation: track.rotation,
|
||||
pixelAspectRatio: track.pixelAspectRatio,
|
||||
codedWidth,
|
||||
codedHeight,
|
||||
squarePixelWidth,
|
||||
squarePixelHeight,
|
||||
displayWidth,
|
||||
displayHeight,
|
||||
rotation,
|
||||
pixelAspectRatio,
|
||||
decoderDisplayAspectWidth: decoderConfig.displayAspectWidth,
|
||||
decoderDisplayAspectHeight: decoderConfig.displayAspectHeight,
|
||||
};
|
||||
|
||||
@@ -367,7 +367,7 @@ test.skip('Can reencode transparent video, keeping alpha', async () => {
|
||||
|
||||
const videoTrack = (await outputInput.getPrimaryVideoTrack())!;
|
||||
expect(await videoTrack.canBeTransparent()).toBe(true);
|
||||
expect(videoTrack.displayWidth).toBe(320);
|
||||
expect(await videoTrack.getDisplayWidth()).toBe(320);
|
||||
|
||||
const sink = new VideoSampleSink(videoTrack);
|
||||
using sample = (await sink.getSample(await videoTrack.getFirstTimestamp()))!;
|
||||
|
||||
Reference in New Issue
Block a user