"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.canDoQuickAudioTranscode = exports.getVideoFileBitrate = exports.ffprobePromise = exports.isAudioFile = exports.getVideoFileFPS = exports.getAudioStream = exports.getDurationFromVideoFile = exports.getVideoStreamFromFile = exports.getMaxAudioBitrate = exports.getMetadataFromFile = exports.getVideoFileResolution = exports.getVideoStreamSize = void 0;
const tslib_1 = require("tslib");
const fluent_ffmpeg_1 = require("fluent-ffmpeg");
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;
function isAudioFile(path, existingProbe) {
    return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
        const videoStream = yield getVideoStreamFromFile(path, existingProbe);
        return !videoStream;
    });
}
exports.isAudioFile = isAudioFile;
function getAudioStream(videoPath, existingProbe) {
    return (0, 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: parseInt(audioStream['bit_rate'] + '', 10)
                };
            }
        }
        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 getVideoStreamSize(path, existingProbe) {
    return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
        const videoStream = yield getVideoStreamFromFile(path, existingProbe);
        return videoStream === null
            ? { width: 0, height: 0 }
            : { width: videoStream.width, height: videoStream.height };
    });
}
exports.getVideoStreamSize = getVideoStreamSize;
function getVideoFileResolution(path, existingProbe) {
    return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
        const size = yield getVideoStreamSize(path, existingProbe);
        return {
            width: size.width,
            height: size.height,
            ratio: Math.max(size.height, size.width) / Math.min(size.height, size.width),
            resolution: Math.min(size.height, size.width),
            isPortraitMode: size.height > size.width
        };
    });
}
exports.getVideoFileResolution = getVideoFileResolution;
function getVideoFileFPS(path, existingProbe) {
    return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
        const videoStream = yield getVideoStreamFromFile(path, existingProbe);
        if (videoStream === null)
            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.getVideoFileFPS = getVideoFileFPS;
function getMetadataFromFile(path, existingProbe) {
    return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
        const metadata = existingProbe || (yield ffprobePromise(path));
        return new videos_1.VideoFileMetadata(metadata);
    });
}
exports.getMetadataFromFile = getMetadataFromFile;
function getVideoFileBitrate(path, existingProbe) {
    return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
        const metadata = yield getMetadataFromFile(path, existingProbe);
        let bitrate = metadata.format.bit_rate;
        if (bitrate && !isNaN(bitrate))
            return bitrate;
        const videoStream = yield getVideoStreamFromFile(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.getVideoFileBitrate = getVideoFileBitrate;
function getDurationFromVideoFile(path, existingProbe) {
    return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
        const metadata = yield getMetadataFromFile(path, existingProbe);
        return Math.round(metadata.format.duration);
    });
}
exports.getDurationFromVideoFile = getDurationFromVideoFile;
function getVideoStreamFromFile(path, existingProbe) {
    return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
        const metadata = yield getMetadataFromFile(path, existingProbe);
        return metadata.streams.find(s => s.codec_type === 'video') || null;
    });
}
exports.getVideoStreamFromFile = getVideoStreamFromFile;
function canDoQuickAudioTranscode(path, probe) {
    return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
        const parsedAudio = yield getAudioStream(path, probe);
        if (!parsedAudio.audioStream)
            return true;
        if (parsedAudio.audioStream['codec_name'] !== 'aac')
            return false;
        const audioBitrate = parsedAudio.bitrate;
        if (!audioBitrate)
            return false;
        const maxAudioBitrate = getMaxAudioBitrate('aac', audioBitrate);
        if (maxAudioBitrate !== -1 && audioBitrate > maxAudioBitrate)
            return false;
        const channelLayout = parsedAudio.audioStream['channel_layout'];
        if (!channelLayout || channelLayout === 'unknown')
            return false;
        return true;
    });
}
exports.canDoQuickAudioTranscode = canDoQuickAudioTranscode;
//# sourceMappingURL=ffprobe.js.map