Files
smartffmpeg/test/test.ts

192 lines
6.0 KiB
TypeScript
Raw Normal View History

2025-12-11 23:03:14 +00:00
import { expect, tap } from '@git.zone/tstest/tapbundle';
import * as smartffmpeg from '../ts/index.js';
let ffmpegInstance: smartffmpeg.SmartFfmpeg;
tap.test('should create SmartFfmpeg instance', async () => {
ffmpegInstance = new smartffmpeg.SmartFfmpeg();
expect(ffmpegInstance).toBeInstanceOf(smartffmpeg.SmartFfmpeg);
});
// ==================== BUILDER API TESTS ====================
tap.test('should create FfmpegCommand via create()', async () => {
const command = ffmpegInstance.create();
expect(command).toBeInstanceOf(smartffmpeg.FfmpegCommand);
});
tap.test('should create FfmpegCommand via input() shorthand', async () => {
const command = ffmpegInstance.input('/path/to/input.mp4');
expect(command).toBeInstanceOf(smartffmpeg.FfmpegCommand);
});
tap.test('should build correct args with builder API', async () => {
const args = ffmpegInstance.create()
.input('/input.mp4')
.videoCodec('libx264')
.audioCodec('aac')
.videoBitrate('1M')
.audioBitrate('128k')
.size(1920, 1080)
.fps(30)
.crf(23)
.preset('fast')
.output('/output.mp4')
.getArgs('/output.mp4');
expect(args).toContain('-i');
expect(args).toContain('/input.mp4');
expect(args).toContain('-c:v');
expect(args).toContain('libx264');
expect(args).toContain('-c:a');
expect(args).toContain('aac');
expect(args).toContain('-b:v');
expect(args).toContain('1M');
expect(args).toContain('-b:a');
expect(args).toContain('128k');
expect(args).toContain('-crf');
expect(args).toContain('23');
expect(args).toContain('-preset');
expect(args).toContain('fast');
expect(args).toContain('-r');
expect(args).toContain('30');
console.log('Builder API generates correct ffmpeg arguments');
});
tap.test('should support video filters', async () => {
const args = ffmpegInstance.create()
.input('/input.mp4')
.scale(1280, 720)
.flipHorizontal()
.output('/output.mp4')
.getArgs('/output.mp4');
expect(args).toContain('-vf');
const vfIndex = args.indexOf('-vf');
const filterString = args[vfIndex + 1];
expect(filterString).toInclude('scale=1280:720');
expect(filterString).toInclude('hflip');
console.log('Video filters work correctly');
});
tap.test('should support audio options', async () => {
const args = ffmpegInstance.create()
.input('/input.mp4')
.noVideo()
.audioCodec('libmp3lame')
.audioBitrate('320k')
.sampleRate(44100)
.audioChannels(2)
.volume(1.5)
.format('mp3')
.getArgs('/output.mp3');
expect(args).toContain('-vn');
expect(args).toContain('-c:a');
expect(args).toContain('libmp3lame');
expect(args).toContain('-ar');
expect(args).toContain('44100');
expect(args).toContain('-ac');
expect(args).toContain('2');
expect(args).toContain('-af');
expect(args).toContain('-f');
expect(args).toContain('mp3');
console.log('Audio extraction with builder works correctly');
});
tap.test('should support seek and duration', async () => {
const args = ffmpegInstance.create()
.input('/input.mp4')
.seek(10)
.duration(30)
.output('/output.mp4')
.getArgs('/output.mp4');
expect(args).toContain('-ss');
expect(args).toContain('-t');
console.log('Seek and duration work correctly');
});
// ==================== WEB STREAMS API TESTS ====================
tap.test('should return Web ReadableStream from toStream()', async () => {
// Just verify the method signature and types - don't execute
const command = ffmpegInstance.input('/input.mp4')
.videoCodec('libx264')
.format('mp4');
// Verify getArgs works (doesn't execute ffmpeg)
const args = command.getArgs('pipe:1');
expect(args).toContain('-f');
expect(args).toContain('mp4');
console.log('toStream() method returns correct type signature');
});
tap.test('should accept Uint8Array input', async () => {
const uint8Input = new Uint8Array([0, 1, 2, 3, 4]); // Dummy data
const command = ffmpegInstance.input(uint8Input, { format: 'mp4' })
.videoCodec('libx264')
.format('webm');
// Just verify args are built correctly for memory input
const args = command.getArgs('pipe:1');
expect(args).toContain('-i');
expect(args).toContain('pipe:0'); // Memory input uses stdin
console.log('Uint8Array input accepted correctly');
});
tap.test('should build correct args for memory output', async () => {
const args = ffmpegInstance.input('/input.mp4')
.videoCodec('libx264')
.format('webm')
.getArgs('pipe:1');
expect(args).toContain('-f');
expect(args).toContain('webm');
expect(args).toContain('pipe:1');
console.log('Memory output args built correctly');
});
// ==================== LEGACY API TESTS ====================
tap.test('should get available encoders', async () => {
const encoders = await ffmpegInstance.getEncoders();
expect(encoders).toBeArray();
expect(encoders.length).toBeGreaterThan(0);
// Common encoders should be available
expect(encoders).toContain('libx264');
console.log(`Found ${encoders.length} encoders`);
});
tap.test('should get available decoders', async () => {
const decoders = await ffmpegInstance.getDecoders();
expect(decoders).toBeArray();
expect(decoders.length).toBeGreaterThan(0);
console.log(`Found ${decoders.length} decoders`);
});
tap.test('should get available formats', async () => {
const formats = await ffmpegInstance.getFormats();
expect(formats).toBeArray();
expect(formats.length).toBeGreaterThan(0);
// Common formats should be available
expect(formats).toContain('mp4');
expect(formats).toContain('mp3');
console.log(`Found ${formats.length} formats`);
});
tap.test('should run raw ffmpeg command', async () => {
const result = await ffmpegInstance.runRaw(['-version']);
expect(result.stdout).toInclude('ffmpeg');
console.log('FFmpeg version info retrieved successfully');
});
tap.test('should run raw ffprobe command', async () => {
const result = await ffmpegInstance.runProbeRaw(['-version']);
expect(result.stdout).toInclude('ffprobe');
console.log('FFprobe version info retrieved successfully');
});
// IMPORTANT: Always end with tap.start()
export default tap.start();