← Files Cecil-IA Labs FFmpegARCHIVED FILE

dist/media/ffprobe-normalizer.js

6.05 KB · Sep 30, 2026 · 23:17 UTC

↓ Download file

import { ToolkitRuntimeError } from "../core/errors.js";
function record(value) {
    return typeof value === "object" && value !== null && !Array.isArray(value)
        ? value
        : undefined;
}
function stringValue(value) {
    return typeof value === "string" && value.length > 0 && value !== "N/A" ? value : undefined;
}
function numberValue(value) {
    if (typeof value === "number" && Number.isFinite(value))
        return value;
    if (typeof value !== "string" || value.length === 0 || value === "N/A")
        return undefined;
    const parsed = Number(value);
    return Number.isFinite(parsed) ? parsed : undefined;
}
function integerValue(value) {
    const parsed = numberValue(value);
    return parsed !== undefined ? Math.trunc(parsed) : undefined;
}
function tagsValue(value) {
    const input = record(value);
    if (!input)
        return undefined;
    const tags = {};
    for (const [key, item] of Object.entries(input)) {
        if (typeof item === "string")
            tags[key] = item;
    }
    return Object.keys(tags).length > 0 ? tags : undefined;
}
function codecType(value) {
    switch (value) {
        case "video":
        case "audio":
        case "subtitle":
        case "data":
        case "attachment":
            return value;
        default:
            return "unknown";
    }
}
function normalizeBaseStream(raw, fallbackIndex) {
    const result = {
        index: integerValue(raw["index"]) ?? fallbackIndex,
        codecType: codecType(raw["codec_type"]),
    };
    const codecName = stringValue(raw["codec_name"]);
    const codecLongName = stringValue(raw["codec_long_name"]);
    const duration = numberValue(raw["duration"]);
    const timeBase = stringValue(raw["time_base"]);
    const startTime = numberValue(raw["start_time"]);
    const bitrate = numberValue(raw["bit_rate"]);
    const tags = tagsValue(raw["tags"]);
    if (codecName !== undefined)
        result.codecName = codecName;
    if (codecLongName !== undefined)
        result.codecLongName = codecLongName;
    if (duration !== undefined)
        result.durationSeconds = duration;
    if (timeBase !== undefined)
        result.timeBase = timeBase;
    if (startTime !== undefined)
        result.startTimeSeconds = startTime;
    if (bitrate !== undefined)
        result.bitrate = bitrate;
    if (tags !== undefined)
        result.tags = tags;
    return result;
}
function normalizeStream(raw, fallbackIndex) {
    const base = normalizeBaseStream(raw, fallbackIndex);
    if (base.codecType === "video") {
        const stream = { ...base, codecType: "video" };
        const width = integerValue(raw["width"]);
        const height = integerValue(raw["height"]);
        const pixelFormat = stringValue(raw["pix_fmt"]);
        const sampleAspectRatio = stringValue(raw["sample_aspect_ratio"]);
        const displayAspectRatio = stringValue(raw["display_aspect_ratio"]);
        const averageFrameRate = stringValue(raw["avg_frame_rate"]);
        const realFrameRate = stringValue(raw["r_frame_rate"]);
        const fieldOrder = stringValue(raw["field_order"]);
        if (width !== undefined)
            stream.width = width;
        if (height !== undefined)
            stream.height = height;
        if (pixelFormat !== undefined)
            stream.pixelFormat = pixelFormat;
        if (sampleAspectRatio !== undefined)
            stream.sampleAspectRatio = sampleAspectRatio;
        if (displayAspectRatio !== undefined)
            stream.displayAspectRatio = displayAspectRatio;
        if (averageFrameRate !== undefined)
            stream.averageFrameRate = averageFrameRate;
        if (realFrameRate !== undefined)
            stream.realFrameRate = realFrameRate;
        if (fieldOrder !== undefined)
            stream.fieldOrder = fieldOrder;
        return stream;
    }
    if (base.codecType === "audio") {
        const stream = { ...base, codecType: "audio" };
        const sampleRate = integerValue(raw["sample_rate"]);
        const channels = integerValue(raw["channels"]);
        const channelLayout = stringValue(raw["channel_layout"]);
        const sampleFormat = stringValue(raw["sample_fmt"]);
        if (sampleRate !== undefined)
            stream.sampleRate = sampleRate;
        if (channels !== undefined)
            stream.channels = channels;
        if (channelLayout !== undefined)
            stream.channelLayout = channelLayout;
        if (sampleFormat !== undefined)
            stream.sampleFormat = sampleFormat;
        return stream;
    }
    return base;
}
function normalizeFormat(raw) {
    const result = {};
    if (!raw)
        return result;
    const formatName = stringValue(raw["format_name"]);
    const formatLongName = stringValue(raw["format_long_name"]);
    const duration = numberValue(raw["duration"]);
    const size = numberValue(raw["size"]);
    const bitrate = numberValue(raw["bit_rate"]);
    const tags = tagsValue(raw["tags"]);
    if (formatName !== undefined)
        result.formatName = formatName;
    if (formatLongName !== undefined)
        result.formatLongName = formatLongName;
    if (duration !== undefined)
        result.durationSeconds = duration;
    if (size !== undefined)
        result.sizeBytes = size;
    if (bitrate !== undefined)
        result.bitrate = bitrate;
    if (tags !== undefined)
        result.tags = tags;
    return result;
}
export function normalizeFFprobeJson(source, raw) {
    const root = record(raw);
    if (!root) {
        throw new ToolkitRuntimeError("E_PROBE_FAILED", "FFprobe returned a non-object JSON document.");
    }
    const rawStreams = Array.isArray(root["streams"]) ? root["streams"] : [];
    const streams = rawStreams.flatMap((value, index) => {
        const item = record(value);
        return item ? [normalizeStream(item, index)] : [];
    });
    const video = streams.filter((stream) => stream.codecType === "video");
    const audio = streams.filter((stream) => stream.codecType === "audio");
    return {
        source,
        format: normalizeFormat(record(root["format"])),
        streams,
        video,
        audio,
    };
}
//# sourceMappingURL=ffprobe-normalizer.js.map

SHA-256: a35db48542077d0360745dab4411709e348db790b2cd64afbad6fa187e835146