Files
netfelix-audio-fix/server/services/__tests__/probe.test.ts
T

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");
});
});