feat(video): add MIME types for mp4/webm/mov/avi/mkv

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-01 21:59:06 +02:00
co-authored by Claude Sonnet 5
parent 913dbac691
commit 9c1f857398
2 changed files with 92 additions and 0 deletions
+5
View File
@@ -43,6 +43,11 @@ const OUTPUT_MIME_TYPES = {
flac: 'audio/flac',
aac: 'audio/aac',
m4a: 'audio/x-m4a',
mp4: 'video/mp4',
webm: 'video/webm',
mov: 'video/quicktime',
avi: 'video/x-msvideo',
mkv: 'video/x-matroska',
};
export async function detectInputMime(filePath) {
+87
View File
@@ -361,3 +361,90 @@ describe('resolveInputFormat — audio formats', () => {
await fs.unlink(fixturePath);
});
});
describe('outputMimeType — video', () => {
it('returns the correct MIME type for each video target format', () => {
expect(outputMimeType('mp4')).toBe('video/mp4');
expect(outputMimeType('webm')).toBe('video/webm');
expect(outputMimeType('mov')).toBe('video/quicktime');
expect(outputMimeType('avi')).toBe('video/x-msvideo');
expect(outputMimeType('mkv')).toBe('video/x-matroska');
});
});
describe('resolveInputFormat — video magic bytes', () => {
it('accepts a minimal mp4 (ftyp box) declared as mp4', async () => {
const fixturePath = path.join(import.meta.dirname, 'fixtures', 'sample-video.mp4');
await fs.writeFile(
fixturePath,
Buffer.concat([Buffer.from([0, 0, 0, 0x18]), Buffer.from('ftyp'), Buffer.from('isom')])
);
const result = await resolveInputFormat(fixturePath, 'mp4');
expect(result).toEqual({ mime: 'video/mp4', valid: true });
await fs.unlink(fixturePath);
});
it('accepts a minimal mov (moov atom) declared as mov', async () => {
const fixturePath = path.join(import.meta.dirname, 'fixtures', 'sample-video.mov');
await fs.writeFile(fixturePath, Buffer.concat([Buffer.from([0, 0, 0, 0x08]), Buffer.from('moov')]));
const result = await resolveInputFormat(fixturePath, 'mov');
expect(result).toEqual({ mime: 'video/quicktime', valid: true });
await fs.unlink(fixturePath);
});
it('accepts a minimal avi (RIFF/AVI) declared as avi', async () => {
const fixturePath = path.join(import.meta.dirname, 'fixtures', 'sample-video.avi');
await fs.writeFile(
fixturePath,
Buffer.concat([Buffer.from('RIFF'), Buffer.from([0, 0, 0, 0]), Buffer.from('AVI ')])
);
const result = await resolveInputFormat(fixturePath, 'avi');
expect(result).toEqual({ mime: 'video/vnd.avi', valid: true });
await fs.unlink(fixturePath);
});
it('accepts a minimal webm (EBML DocType webm) declared as webm', async () => {
const fixturePath = path.join(import.meta.dirname, 'fixtures', 'sample-video.webm');
await fs.writeFile(
fixturePath,
Buffer.concat([Buffer.from([0x1a, 0x45, 0xdf, 0xa3, 0x81, 0x42, 0x82, 0x84]), Buffer.from('webm')])
);
const result = await resolveInputFormat(fixturePath, 'webm');
expect(result).toEqual({ mime: 'video/webm', valid: true });
await fs.unlink(fixturePath);
});
it('accepts a minimal mkv (EBML DocType matroska) declared as mkv', async () => {
const fixturePath = path.join(import.meta.dirname, 'fixtures', 'sample-video.mkv');
await fs.writeFile(
fixturePath,
Buffer.concat([Buffer.from([0x1a, 0x45, 0xdf, 0xa3, 0x81, 0x42, 0x82, 0x88]), Buffer.from('matroska')])
);
const result = await resolveInputFormat(fixturePath, 'mkv');
expect(result).toEqual({ mime: 'video/matroska', valid: true });
await fs.unlink(fixturePath);
});
it('rejects a webm file declared as mkv', async () => {
const fixturePath = path.join(import.meta.dirname, 'fixtures', 'sample-video-mismatch.webm');
await fs.writeFile(
fixturePath,
Buffer.concat([Buffer.from([0x1a, 0x45, 0xdf, 0xa3, 0x81, 0x42, 0x82, 0x84]), Buffer.from('webm')])
);
const result = await resolveInputFormat(fixturePath, 'mkv');
expect(result.valid).toBe(false);
await fs.unlink(fixturePath);
});
});