7d12241ccb
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
226 lines
6.1 KiB
TypeScript
226 lines
6.1 KiB
TypeScript
import { describe, expect, test } from "bun:test";
|
|
import { parseProbeOutput } from "../probe";
|
|
|
|
describe("parseProbeOutput — format metadata", () => {
|
|
test("parses size, duration, and container from format", () => {
|
|
const json = JSON.stringify({
|
|
format: {
|
|
size: "1500000000",
|
|
duration: "7200.000000",
|
|
format_name: "matroska,webm",
|
|
},
|
|
streams: [],
|
|
});
|
|
const result = parseProbeOutput(json);
|
|
expect(result.fileSize).toBe(1500000000);
|
|
expect(result.durationSeconds).toBe(7200.0);
|
|
expect(result.container).toBe("matroska");
|
|
});
|
|
|
|
test("returns null for missing format fields", () => {
|
|
const json = JSON.stringify({ format: {}, streams: [] });
|
|
const result = parseProbeOutput(json);
|
|
expect(result.fileSize).toBeNull();
|
|
expect(result.durationSeconds).toBeNull();
|
|
expect(result.container).toBeNull();
|
|
});
|
|
|
|
test("takes first part of comma-separated format_name", () => {
|
|
const json = JSON.stringify({
|
|
format: { format_name: "mov,mp4,m4a,3gp,3g2,mj2" },
|
|
streams: [],
|
|
});
|
|
const result = parseProbeOutput(json);
|
|
expect(result.container).toBe("mov");
|
|
});
|
|
});
|
|
|
|
describe("parseProbeOutput — video stream", () => {
|
|
test("parses a video stream correctly", () => {
|
|
const json = JSON.stringify({
|
|
format: {},
|
|
streams: [
|
|
{
|
|
index: 0,
|
|
codec_type: "video",
|
|
codec_name: "h264",
|
|
profile: "High",
|
|
disposition: { default: 1, forced: 0, hearing_impaired: 0 },
|
|
tags: { language: "eng", title: "Main Video" },
|
|
},
|
|
],
|
|
});
|
|
const result = parseProbeOutput(json);
|
|
expect(result.streams).toHaveLength(1);
|
|
const s = result.streams[0];
|
|
expect(s.streamIndex).toBe(0);
|
|
expect(s.type).toBe("Video");
|
|
expect(s.codec).toBe("h264");
|
|
expect(s.profile).toBe("High");
|
|
expect(s.language).toBe("eng");
|
|
expect(s.title).toBe("Main Video");
|
|
expect(s.isDefault).toBe(1);
|
|
expect(s.isForced).toBe(0);
|
|
expect(s.isHearingImpaired).toBe(0);
|
|
expect(s.channels).toBeNull();
|
|
expect(s.channelLayout).toBeNull();
|
|
expect(s.bitRate).toBeNull();
|
|
expect(s.sampleRate).toBeNull();
|
|
expect(s.bitDepth).toBeNull();
|
|
});
|
|
});
|
|
|
|
describe("parseProbeOutput — audio stream", () => {
|
|
test("parses audio stream with full metadata", () => {
|
|
const json = JSON.stringify({
|
|
format: {},
|
|
streams: [
|
|
{
|
|
index: 1,
|
|
codec_type: "audio",
|
|
codec_name: "eac3",
|
|
profile: "DDP",
|
|
channels: 6,
|
|
channel_layout: "5.1(side)",
|
|
bit_rate: "640000",
|
|
sample_rate: "48000",
|
|
bits_per_raw_sample: "24",
|
|
disposition: { default: 1, forced: 0, hearing_impaired: 0 },
|
|
tags: { language: "eng", title: "English Surround" },
|
|
},
|
|
],
|
|
});
|
|
const result = parseProbeOutput(json);
|
|
expect(result.streams).toHaveLength(1);
|
|
const s = result.streams[0];
|
|
expect(s.streamIndex).toBe(1);
|
|
expect(s.type).toBe("Audio");
|
|
expect(s.codec).toBe("eac3");
|
|
expect(s.profile).toBe("DDP");
|
|
expect(s.language).toBe("eng");
|
|
expect(s.title).toBe("English Surround");
|
|
expect(s.channels).toBe(6);
|
|
expect(s.channelLayout).toBe("5.1(side)");
|
|
expect(s.bitRate).toBe(640000);
|
|
expect(s.sampleRate).toBe(48000);
|
|
expect(s.bitDepth).toBe(24);
|
|
expect(s.isDefault).toBe(1);
|
|
expect(s.isForced).toBe(0);
|
|
expect(s.isHearingImpaired).toBe(0);
|
|
});
|
|
|
|
test("accepts uppercase LANGUAGE and TITLE tags", () => {
|
|
const json = JSON.stringify({
|
|
format: {},
|
|
streams: [
|
|
{
|
|
index: 2,
|
|
codec_type: "audio",
|
|
codec_name: "aac",
|
|
disposition: { default: 0, forced: 0, hearing_impaired: 0 },
|
|
tags: { LANGUAGE: "deu", TITLE: "Deutsch" },
|
|
},
|
|
],
|
|
});
|
|
const result = parseProbeOutput(json);
|
|
const s = result.streams[0];
|
|
expect(s.language).toBe("deu");
|
|
expect(s.title).toBe("Deutsch");
|
|
});
|
|
|
|
test("handles null/missing optional audio fields", () => {
|
|
const json = JSON.stringify({
|
|
format: {},
|
|
streams: [
|
|
{
|
|
index: 0,
|
|
codec_type: "audio",
|
|
codec_name: "aac",
|
|
disposition: { default: 0, forced: 0, hearing_impaired: 0 },
|
|
},
|
|
],
|
|
});
|
|
const result = parseProbeOutput(json);
|
|
const s = result.streams[0];
|
|
expect(s.channels).toBeNull();
|
|
expect(s.channelLayout).toBeNull();
|
|
expect(s.bitRate).toBeNull();
|
|
expect(s.sampleRate).toBeNull();
|
|
expect(s.bitDepth).toBeNull();
|
|
expect(s.language).toBeNull();
|
|
expect(s.title).toBeNull();
|
|
});
|
|
});
|
|
|
|
describe("parseProbeOutput — subtitle stream", () => {
|
|
test("parses subtitle stream with hearing_impaired flag", () => {
|
|
const json = JSON.stringify({
|
|
format: {},
|
|
streams: [
|
|
{
|
|
index: 3,
|
|
codec_type: "subtitle",
|
|
codec_name: "subrip",
|
|
disposition: { default: 0, forced: 0, hearing_impaired: 1 },
|
|
tags: { language: "eng", title: "SDH" },
|
|
},
|
|
],
|
|
});
|
|
const result = parseProbeOutput(json);
|
|
expect(result.streams).toHaveLength(1);
|
|
const s = result.streams[0];
|
|
expect(s.streamIndex).toBe(3);
|
|
expect(s.type).toBe("Subtitle");
|
|
expect(s.codec).toBe("subrip");
|
|
expect(s.language).toBe("eng");
|
|
expect(s.title).toBe("SDH");
|
|
expect(s.isDefault).toBe(0);
|
|
expect(s.isForced).toBe(0);
|
|
expect(s.isHearingImpaired).toBe(1);
|
|
});
|
|
|
|
test("parses forced subtitle stream", () => {
|
|
const json = JSON.stringify({
|
|
format: {},
|
|
streams: [
|
|
{
|
|
index: 4,
|
|
codec_type: "subtitle",
|
|
codec_name: "hdmv_pgs_subtitle",
|
|
disposition: { default: 0, forced: 1, hearing_impaired: 0 },
|
|
tags: { language: "deu" },
|
|
},
|
|
],
|
|
});
|
|
const result = parseProbeOutput(json);
|
|
const s = result.streams[0];
|
|
expect(s.type).toBe("Subtitle");
|
|
expect(s.isForced).toBe(1);
|
|
expect(s.language).toBe("deu");
|
|
expect(s.title).toBeNull();
|
|
});
|
|
});
|
|
|
|
describe("parseProbeOutput — codec_type mapping", () => {
|
|
test("maps data → Data and attachment → EmbeddedImage", () => {
|
|
const json = JSON.stringify({
|
|
format: {},
|
|
streams: [
|
|
{
|
|
index: 0,
|
|
codec_type: "data",
|
|
disposition: { default: 0, forced: 0, hearing_impaired: 0 },
|
|
},
|
|
{
|
|
index: 1,
|
|
codec_type: "attachment",
|
|
disposition: { default: 0, forced: 0, hearing_impaired: 0 },
|
|
},
|
|
],
|
|
});
|
|
const result = parseProbeOutput(json);
|
|
expect(result.streams[0].type).toBe("Data");
|
|
expect(result.streams[1].type).toBe("EmbeddedImage");
|
|
});
|
|
});
|