"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.applyEncoderOptions = exports.addDefaultEncoderParams = exports.addDefaultEncoderGlobalParams = exports.presetOnlyAudio = exports.presetCopy = exports.presetVOD = void 0;
const tslib_1 = require("tslib");
const logger_1 = require("../logger");
const core_utils_1 = require("../../../shared/core-utils");
const ffmpeg_commons_1 = require("./ffmpeg-commons");
const ffmpeg_encoders_1 = require("./ffmpeg-encoders");
const ffprobe_utils_1 = require("./ffprobe-utils");
const lTags = (0, logger_1.loggerTagsFactory)('ffmpeg');
function addDefaultEncoderGlobalParams(command) {
    command.outputOption('-max_muxing_queue_size 1024')
        .outputOption('-map_metadata -1')
        .outputOption('-pix_fmt yuv420p');
}
exports.addDefaultEncoderGlobalParams = addDefaultEncoderGlobalParams;
function addDefaultEncoderParams(options) {
    const { command, encoder, fps, streamNum } = options;
    if (encoder === 'libx264') {
        command.outputOption((0, ffmpeg_commons_1.buildStreamSuffix)('-level:v', streamNum) + ' 3.1');
        if (fps) {
            command.outputOption((0, ffmpeg_commons_1.buildStreamSuffix)('-g:v', streamNum) + ' ' + (fps * 2));
        }
    }
}
exports.addDefaultEncoderParams = addDefaultEncoderParams;
function presetVOD(options) {
    return tslib_1.__awaiter(this, void 0, void 0, function* () {
        const { command, input, profile, resolution, fps, scaleFilterValue } = options;
        let localCommand = command
            .format('mp4')
            .outputOption('-movflags faststart');
        addDefaultEncoderGlobalParams(command);
        const probe = yield (0, ffprobe_utils_1.ffprobePromise)(input);
        const bitrate = yield (0, ffprobe_utils_1.getVideoStreamBitrate)(input, probe);
        const videoStreamDimensions = yield (0, ffprobe_utils_1.getVideoStreamDimensionsInfo)(input, probe);
        let streamsToProcess = ['audio', 'video'];
        if (!(yield (0, ffprobe_utils_1.hasAudioStream)(input, probe))) {
            localCommand = localCommand.noAudio();
            streamsToProcess = ['video'];
        }
        for (const streamType of streamsToProcess) {
            const builderResult = yield (0, ffmpeg_encoders_1.getEncoderBuilderResult)(Object.assign(Object.assign({}, (0, core_utils_1.pick)(options, ['availableEncoders', 'canCopyAudio', 'canCopyVideo'])), { input, inputBitrate: bitrate, inputRatio: (videoStreamDimensions === null || videoStreamDimensions === void 0 ? void 0 : videoStreamDimensions.ratio) || 0, profile,
                resolution,
                fps,
                streamType, videoType: 'vod' }));
            if (!builderResult) {
                throw new Error('No available encoder found for stream ' + streamType);
            }
            logger_1.logger.debug('Apply ffmpeg params from %s for %s stream of input %s using %s profile.', builderResult.encoder, streamType, input, profile, Object.assign({ builderResult, resolution, fps }, lTags()));
            if (streamType === 'video') {
                localCommand.videoCodec(builderResult.encoder);
                if (scaleFilterValue) {
                    localCommand.outputOption(`-vf ${(0, ffmpeg_commons_1.getScaleFilter)(builderResult.result)}=${scaleFilterValue}`);
                }
            }
            else if (streamType === 'audio') {
                localCommand.audioCodec(builderResult.encoder);
            }
            applyEncoderOptions(localCommand, builderResult.result);
            addDefaultEncoderParams({ command: localCommand, encoder: builderResult.encoder, fps });
        }
        return localCommand;
    });
}
exports.presetVOD = presetVOD;
function presetCopy(command) {
    return command
        .format('mp4')
        .videoCodec('copy')
        .audioCodec('copy');
}
exports.presetCopy = presetCopy;
function presetOnlyAudio(command) {
    return command
        .format('mp4')
        .audioCodec('copy')
        .noVideo();
}
exports.presetOnlyAudio = presetOnlyAudio;
function applyEncoderOptions(command, options) {
    var _a, _b;
    return command
        .inputOptions((_a = options.inputOptions) !== null && _a !== void 0 ? _a : [])
        .outputOptions((_b = options.outputOptions) !== null && _b !== void 0 ? _b : []);
}
exports.applyEncoderOptions = applyEncoderOptions;
//# sourceMappingURL=ffmpeg-presets.js.map