feat: publish av-tools 0.1.0

This commit is contained in:
2026-07-24 14:58:03 +02:00
commit fcc537b024
254 changed files with 63270 additions and 0 deletions

View File

@@ -0,0 +1,201 @@
import type { BuiltInExportPreset } from './preset.types';
function immutable<T extends BuiltInExportPreset>(preset: T): Readonly<T> {
return Object.freeze({
...preset,
requirements: Object.freeze({
...preset.requirements,
...(preset.requirements.muxers
? { muxers: Object.freeze([...preset.requirements.muxers]) }
: {}),
...(preset.requirements.encoders
? { encoders: Object.freeze([...preset.requirements.encoders]) }
: {}),
...(preset.requirements.filters
? { filters: Object.freeze([...preset.requirements.filters]) }
: {}),
}),
...(preset.video ? { video: Object.freeze({ ...preset.video }) } : {}),
...(preset.audio ? { audio: Object.freeze({ ...preset.audio }) } : {}),
settingsSummary: Object.freeze([...preset.settingsSummary]),
});
}
export const VIDEO_PRESETS: readonly BuiltInExportPreset[] = Object.freeze([
immutable({
id: 'mp4-h264-balanced',
name: 'MP4 · H.264 + AAC',
description: 'Balanced browser-friendly video.',
kind: 'video',
container: 'mp4',
fileExtension: 'mp4',
video: {
codec: 'libx264',
qualityMode: 'balanced',
crf: 23,
pixelFormat: 'yuv420p',
encoderPreset: 'medium',
},
audio: { codec: 'aac', bitrateKbps: 160, sampleRate: 48_000, channels: 2 },
fastStart: true,
metadataPolicy: 'copy',
chapterPolicy: 'keep',
subtitlePolicy: 'convert',
requirements: {
muxers: ['mp4'],
encoders: ['libx264', 'aac'],
},
settingsSummary: [
'libx264 CRF 23, medium preset',
'yuv420p pixel format',
'AAC 160 kbit/s stereo at 48 kHz',
'fast-start metadata',
],
builtIn: true,
}),
immutable({
id: 'mp4-h264-compatibility',
name: 'MP4 · H.264 compatibility',
description: 'Conservative settings for broad playback support.',
kind: 'video',
container: 'mp4',
fileExtension: 'mp4',
video: {
codec: 'libx264',
qualityMode: 'compatibility',
crf: 24,
pixelFormat: 'yuv420p',
encoderPreset: 'fast',
},
audio: { codec: 'aac', bitrateKbps: 128, sampleRate: 44_100, channels: 2 },
fastStart: true,
metadataPolicy: 'copy',
chapterPolicy: 'keep',
subtitlePolicy: 'convert',
requirements: { muxers: ['mp4'], encoders: ['libx264', 'aac'] },
settingsSummary: [
'libx264 CRF 24, fast preset',
'yuv420p pixel format',
'AAC 128 kbit/s stereo at 44.1 kHz',
],
builtIn: true,
}),
immutable({
id: 'webm-vp9-opus',
name: 'WebM · VP9 + Opus',
description: 'Efficient open web video when both encoders are available.',
kind: 'video',
container: 'webm',
fileExtension: 'webm',
video: {
codec: 'libvpx-vp9',
qualityMode: 'smaller-file',
crf: 32,
bitrateKbps: 0,
pixelFormat: 'yuv420p',
},
audio: {
codec: 'libopus',
bitrateKbps: 128,
sampleRate: 48_000,
channels: 2,
},
metadataPolicy: 'copy',
chapterPolicy: 'keep',
subtitlePolicy: 'convert',
requirements: {
muxers: ['webm'],
encoders: ['libvpx-vp9', 'libopus'],
},
settingsSummary: ['libvpx-vp9 CRF 32', 'Opus 128 kbit/s stereo at 48 kHz'],
builtIn: true,
}),
immutable({
id: 'webm-vp8-vorbis',
name: 'WebM · VP8 + Vorbis',
description: 'Compatibility-oriented open web video.',
kind: 'video',
container: 'webm',
fileExtension: 'webm',
video: {
codec: 'libvpx',
qualityMode: 'compatibility',
crf: 18,
bitrateKbps: 1_500,
pixelFormat: 'yuv420p',
},
audio: {
codec: 'libvorbis',
bitrateKbps: 128,
sampleRate: 48_000,
channels: 2,
},
metadataPolicy: 'copy',
chapterPolicy: 'keep',
subtitlePolicy: 'convert',
requirements: { muxers: ['webm'], encoders: ['libvpx', 'libvorbis'] },
settingsSummary: ['libvpx CRF 18, 1.5 Mbit/s target', 'Vorbis 128 kbit/s'],
builtIn: true,
}),
immutable({
id: 'animated-webp',
name: 'Animated WebP',
description: 'Animated image derivative without audio.',
kind: 'derivative',
container: 'webp',
fileExtension: 'webp',
video: {
codec: 'libwebp_anim',
qualityMode: 'balanced',
crf: 60,
pixelFormat: 'rgba',
},
metadataPolicy: 'remove',
chapterPolicy: 'remove',
subtitlePolicy: 'none',
requirements: { muxers: ['webp'], encoders: ['libwebp_anim'] },
settingsSummary: ['libwebp_anim quality 60', 'audio omitted'],
builtIn: true,
}),
immutable({
id: 'animated-gif',
name: 'Animated GIF',
description: 'Advanced compatibility derivative with limited colours.',
kind: 'derivative',
container: 'gif',
fileExtension: 'gif',
video: { codec: 'gif', qualityMode: 'compatibility' },
metadataPolicy: 'remove',
chapterPolicy: 'remove',
subtitlePolicy: 'none',
requirements: {
muxers: ['gif'],
encoders: ['gif'],
filters: ['palettegen', 'paletteuse'],
},
settingsSummary: ['palettegen/paletteuse filter workflow', 'audio omitted'],
builtIn: true,
}),
immutable({
id: 'matroska-h264-aac',
name: 'Matroska · H.264 + AAC',
description: 'Flexible Matroska output with selected compatible streams.',
kind: 'video',
container: 'matroska',
fileExtension: 'mkv',
video: {
codec: 'libx264',
qualityMode: 'higher-quality',
crf: 20,
pixelFormat: 'yuv420p',
encoderPreset: 'medium',
},
audio: { codec: 'aac', bitrateKbps: 192, sampleRate: 48_000, channels: 2 },
metadataPolicy: 'copy',
chapterPolicy: 'keep',
subtitlePolicy: 'copy-compatible',
requirements: { muxers: ['matroska'], encoders: ['libx264', 'aac'] },
settingsSummary: ['libx264 CRF 20', 'AAC 192 kbit/s', 'Matroska container'],
builtIn: true,
}),
]);