"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getEncoderBuilderResult = exports.resetSupportedEncoders = exports.checkFFmpegEncoders = void 0;
const tslib_1 = require("tslib");
const fluent_ffmpeg_1 = require("fluent-ffmpeg");
const core_utils_1 = require("../../../shared/core-utils");
const core_utils_2 = require("../core-utils");
const logger_1 = require("../logger");
const lTags = (0, logger_1.loggerTagsFactory)('ffmpeg');
let supportedEncoders;
function checkFFmpegEncoders(peertubeAvailableEncoders) {
    return tslib_1.__awaiter(this, void 0, void 0, function* () {
        if (supportedEncoders !== undefined) {
            return supportedEncoders;
        }
        const getAvailableEncodersPromise = (0, core_utils_2.promisify0)(fluent_ffmpeg_1.getAvailableEncoders);
        const availableFFmpegEncoders = yield getAvailableEncodersPromise();
        const searchEncoders = new Set();
        for (const type of ['live', 'vod']) {
            for (const streamType of ['audio', 'video']) {
                for (const encoder of peertubeAvailableEncoders.encodersToTry[type][streamType]) {
                    searchEncoders.add(encoder);
                }
            }
        }
        supportedEncoders = new Map();
        for (const searchEncoder of searchEncoders) {
            supportedEncoders.set(searchEncoder, availableFFmpegEncoders[searchEncoder] !== undefined);
        }
        logger_1.logger.info('Built supported ffmpeg encoders.', Object.assign({ supportedEncoders, searchEncoders }, lTags()));
        return supportedEncoders;
    });
}
exports.checkFFmpegEncoders = checkFFmpegEncoders;
function resetSupportedEncoders() {
    supportedEncoders = undefined;
}
exports.resetSupportedEncoders = resetSupportedEncoders;
function getEncoderBuilderResult(options) {
    return tslib_1.__awaiter(this, void 0, void 0, function* () {
        const { availableEncoders, profile, streamType, videoType } = options;
        const encodersToTry = availableEncoders.encodersToTry[videoType][streamType];
        const encoders = availableEncoders.available[videoType];
        for (const encoder of encodersToTry) {
            if (!(yield checkFFmpegEncoders(availableEncoders)).get(encoder)) {
                logger_1.logger.debug('Encoder %s not available in ffmpeg, skipping.', encoder, lTags());
                continue;
            }
            if (!encoders[encoder]) {
                logger_1.logger.debug('Encoder %s not available in peertube encoders, skipping.', encoder, lTags());
                continue;
            }
            const builderProfiles = encoders[encoder];
            let builder = builderProfiles[profile];
            if (!builder) {
                logger_1.logger.debug('Profile %s for encoder %s not available. Fallback to default.', profile, encoder, lTags());
                builder = builderProfiles.default;
                if (!builder) {
                    logger_1.logger.debug('Default profile for encoder %s not available. Try next available encoder.', encoder, lTags());
                    continue;
                }
            }
            const result = yield builder((0, core_utils_1.pick)(options, [
                'input',
                'canCopyAudio',
                'canCopyVideo',
                'resolution',
                'inputBitrate',
                'fps',
                'inputRatio',
                'streamNum'
            ]));
            return {
                result,
                encoder: result.copy === true
                    ? 'copy'
                    : encoder
            };
        }
        return null;
    });
}
exports.getEncoderBuilderResult = getEncoderBuilderResult;
//# sourceMappingURL=ffmpeg-encoders.js.map