"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.hasAudioStream = exports.getVideoStreamBitrate = exports.ffprobePromise = exports.isAudioFile = exports.getVideoStreamFPS = exports.getAudioStream = exports.getVideoStreamDuration = exports.getVideoStream = exports.getMaxAudioBitrate = exports.buildFileMetadata = exports.getVideoStreamDimensionsInfo = void 0;
const tslib_1 = require("tslib");
const fluent_ffmpeg_1 = require("fluent-ffmpeg");
const core_utils_1 = require("../core-utils");
const videos_1 = require("../models/videos");
function ffprobePromise(path) {
    return new Promise((res, rej) => {
        (0, fluent_ffmpeg_1.ffprobe)(path, (err, data) => {
            if (err)
                return rej(err);
            return res(data);
        });
    });
}
exports.ffprobePromise = ffprobePromise;
const imageCodecs = new Set([
    'ansi', 'apng', 'bintext', 'bmp', 'brender_pix', 'dpx', 'exr', 'fits', 'gem', 'gif', 'jpeg2000', 'jpgls', 'mjpeg', 'mjpegb', 'msp2',
    'pam', 'pbm', 'pcx', 'pfm', 'pgm', 'pgmyuv', 'pgx', 'photocd', 'pictor', 'png', 'ppm', 'psd', 'sgi', 'sunrast', 'svg', 'targa', 'tiff',
    'txd', 'webp', 'xbin', 'xbm', 'xface', 'xpm', 'xwd'
]);
function isAudioFile(path, existingProbe) {
    return tslib_1.__awaiter(this, void 0, void 0, function* () {
        const videoStream = yield getVideoStream(path, existingProbe);
        if (!videoStream)
            return true;
        if (imageCodecs.has(videoStream.codec_name))
            return true;
        return false;
    });
}
exports.isAudioFile = isAudioFile;
function hasAudioStream(path, existingProbe) {
    return tslib_1.__awaiter(this, void 0, void 0, function* () {
        const { audioStream } = yield getAudioStream(path, existingProbe);
        return !!audioStream;
    });
}
exports.hasAudioStream = hasAudioStream;
function getAudioStream(videoPath, existingProbe) {
    return tslib_1.__awaiter(this, void 0, void 0, function* () {
        const data = existingProbe || (yield ffprobePromise(videoPath));
        if (Array.isArray(data.streams)) {
            const audioStream = data.streams.find(stream => stream['codec_type'] === 'audio');
            if (audioStream) {
                return {
                    absolutePath: data.format.filename,
                    audioStream,
                    bitrate: (0, core_utils_1.forceNumber)(audioStream['bit_rate'])
                };
            }
        }
        return { absolutePath: data.format.filename };
    });
}
exports.getAudioStream = getAudioStream;
function getMaxAudioBitrate(type, bitrate) {
    const maxKBitrate = 384;
    const kToBits = (kbits) => kbits * 1000;
    if (!bitrate)
        return 256;
    if (type === 'aac') {
        switch (true) {
            case bitrate > kToBits(maxKBitrate):
                return maxKBitrate;
            default:
                return -1;
        }
    }
    switch (true) {
        case bitrate <= kToBits(192):
            return 128;
        case bitrate <= kToBits(384):
            return 256;
        default:
            return maxKBitrate;
    }
}
exports.getMaxAudioBitrate = getMaxAudioBitrate;
function getVideoStreamDimensionsInfo(path, existingProbe) {
    return tslib_1.__awaiter(this, void 0, void 0, function* () {
        const videoStream = yield getVideoStream(path, existingProbe);
        if (!videoStream) {
            return {
                width: 0,
                height: 0,
                ratio: 0,
                resolution: 0,
                isPortraitMode: false
            };
        }
        return {
            width: videoStream.width,
            height: videoStream.height,
            ratio: Math.max(videoStream.height, videoStream.width) / Math.min(videoStream.height, videoStream.width),
            resolution: Math.min(videoStream.height, videoStream.width),
            isPortraitMode: videoStream.height > videoStream.width
        };
    });
}
exports.getVideoStreamDimensionsInfo = getVideoStreamDimensionsInfo;
function getVideoStreamFPS(path, existingProbe) {
    return tslib_1.__awaiter(this, void 0, void 0, function* () {
        const videoStream = yield getVideoStream(path, existingProbe);
        if (!videoStream)
            return 0;
        for (const key of ['avg_frame_rate', 'r_frame_rate']) {
            const valuesText = videoStream[key];
            if (!valuesText)
                continue;
            const [frames, seconds] = valuesText.split('/');
            if (!frames || !seconds)
                continue;
            const result = parseInt(frames, 10) / parseInt(seconds, 10);
            if (result > 0)
                return Math.round(result);
        }
        return 0;
    });
}
exports.getVideoStreamFPS = getVideoStreamFPS;
function buildFileMetadata(path, existingProbe) {
    return tslib_1.__awaiter(this, void 0, void 0, function* () {
        const metadata = existingProbe || (yield ffprobePromise(path));
        return new videos_1.VideoFileMetadata(metadata);
    });
}
exports.buildFileMetadata = buildFileMetadata;
function getVideoStreamBitrate(path, existingProbe) {
    return tslib_1.__awaiter(this, void 0, void 0, function* () {
        const metadata = yield buildFileMetadata(path, existingProbe);
        let bitrate = metadata.format.bit_rate;
        if (bitrate && !isNaN(bitrate))
            return bitrate;
        const videoStream = yield getVideoStream(path, existingProbe);
        if (!videoStream)
            return undefined;
        bitrate = videoStream === null || videoStream === void 0 ? void 0 : videoStream.bit_rate;
        if (bitrate && !isNaN(bitrate))
            return bitrate;
        return undefined;
    });
}
exports.getVideoStreamBitrate = getVideoStreamBitrate;
function getVideoStreamDuration(path, existingProbe) {
    return tslib_1.__awaiter(this, void 0, void 0, function* () {
        const metadata = yield buildFileMetadata(path, existingProbe);
        return Math.round(metadata.format.duration);
    });
}
exports.getVideoStreamDuration = getVideoStreamDuration;
function getVideoStream(path, existingProbe) {
    return tslib_1.__awaiter(this, void 0, void 0, function* () {
        const metadata = yield buildFileMetadata(path, existingProbe);
        return metadata.streams.find(s => s.codec_type === 'video');
    });
}
exports.getVideoStream = getVideoStream;
//# sourceMappingURL=ffprobe.js.map