"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getLiveMuxingCommand = exports.getLiveTranscodingCommand = exports.getLiveSegmentTime = void 0;
const tslib_1 = require("tslib");
const path_1 = require("path");
const constants_1 = require("../../initializers/constants");
const logger_1 = require("../logger");
const ffmpeg_commons_1 = require("./ffmpeg-commons");
const ffmpeg_encoders_1 = require("./ffmpeg-encoders");
const ffmpeg_presets_1 = require("./ffmpeg-presets");
const ffprobe_utils_1 = require("./ffprobe-utils");
const lTags = (0, logger_1.loggerTagsFactory)('ffmpeg');
function getLiveTranscodingCommand(options) {
    return tslib_1.__awaiter(this, void 0, void 0, function* () {
        const { inputUrl, outPath, resolutions, fps, bitrate, availableEncoders, profile, masterPlaylistName, ratio, latencyMode, hasAudio } = options;
        const command = (0, ffmpeg_commons_1.getFFmpeg)(inputUrl, 'live');
        const varStreamMap = [];
        const complexFilter = [
            {
                inputs: '[v:0]',
                filter: 'split',
                options: resolutions.length,
                outputs: resolutions.map(r => `vtemp${r}`)
            }
        ];
        command.outputOption('-sc_threshold 0');
        (0, ffmpeg_presets_1.addDefaultEncoderGlobalParams)(command);
        for (let i = 0; i < resolutions.length; i++) {
            const streamMap = [];
            const resolution = resolutions[i];
            const resolutionFPS = (0, ffprobe_utils_1.computeFPS)(fps, resolution);
            const baseEncoderBuilderParams = {
                input: inputUrl,
                availableEncoders,
                profile,
                canCopyAudio: true,
                canCopyVideo: true,
                inputBitrate: bitrate,
                inputRatio: ratio,
                resolution,
                fps: resolutionFPS,
                streamNum: i,
                videoType: 'live'
            };
            {
                const streamType = 'video';
                const builderResult = yield (0, ffmpeg_encoders_1.getEncoderBuilderResult)(Object.assign(Object.assign({}, baseEncoderBuilderParams), { streamType }));
                if (!builderResult) {
                    throw new Error('No available live video encoder found');
                }
                command.outputOption(`-map [vout${resolution}]`);
                (0, ffmpeg_presets_1.addDefaultEncoderParams)({ command, encoder: builderResult.encoder, fps: resolutionFPS, streamNum: i });
                logger_1.logger.debug('Apply ffmpeg live video params from %s using %s profile.', builderResult.encoder, profile, Object.assign({ builderResult, fps: resolutionFPS, resolution }, lTags()));
                command.outputOption(`${(0, ffmpeg_commons_1.buildStreamSuffix)('-c:v', i)} ${builderResult.encoder}`);
                (0, ffmpeg_presets_1.applyEncoderOptions)(command, builderResult.result);
                complexFilter.push({
                    inputs: `vtemp${resolution}`,
                    filter: (0, ffmpeg_commons_1.getScaleFilter)(builderResult.result),
                    options: `w=-2:h=${resolution}`,
                    outputs: `vout${resolution}`
                });
                streamMap.push(`v:${i}`);
            }
            if (hasAudio) {
                const streamType = 'audio';
                const builderResult = yield (0, ffmpeg_encoders_1.getEncoderBuilderResult)(Object.assign(Object.assign({}, baseEncoderBuilderParams), { streamType }));
                if (!builderResult) {
                    throw new Error('No available live audio encoder found');
                }
                command.outputOption('-map a:0');
                (0, ffmpeg_presets_1.addDefaultEncoderParams)({ command, encoder: builderResult.encoder, fps: resolutionFPS, streamNum: i });
                logger_1.logger.debug('Apply ffmpeg live audio params from %s using %s profile.', builderResult.encoder, profile, Object.assign({ builderResult, fps: resolutionFPS, resolution }, lTags()));
                command.outputOption(`${(0, ffmpeg_commons_1.buildStreamSuffix)('-c:a', i)} ${builderResult.encoder}`);
                (0, ffmpeg_presets_1.applyEncoderOptions)(command, builderResult.result);
                streamMap.push(`a:${i}`);
            }
            varStreamMap.push(streamMap.join(','));
        }
        command.complexFilter(complexFilter);
        addDefaultLiveHLSParams({ command, outPath, masterPlaylistName, latencyMode });
        command.outputOption('-var_stream_map', varStreamMap.join(' '));
        return command;
    });
}
exports.getLiveTranscodingCommand = getLiveTranscodingCommand;
function getLiveMuxingCommand(options) {
    const { inputUrl, outPath, masterPlaylistName, latencyMode } = options;
    const command = (0, ffmpeg_commons_1.getFFmpeg)(inputUrl, 'live');
    command.outputOption('-c:v copy');
    command.outputOption('-c:a copy');
    command.outputOption('-map 0:a?');
    command.outputOption('-map 0:v?');
    addDefaultLiveHLSParams({ command, outPath, masterPlaylistName, latencyMode });
    return command;
}
exports.getLiveMuxingCommand = getLiveMuxingCommand;
function getLiveSegmentTime(latencyMode) {
    if (latencyMode === 3) {
        return constants_1.VIDEO_LIVE.SEGMENT_TIME_SECONDS.SMALL_LATENCY;
    }
    return constants_1.VIDEO_LIVE.SEGMENT_TIME_SECONDS.DEFAULT_LATENCY;
}
exports.getLiveSegmentTime = getLiveSegmentTime;
function addDefaultLiveHLSParams(options) {
    const { command, outPath, masterPlaylistName, latencyMode } = options;
    command.outputOption('-hls_time ' + getLiveSegmentTime(latencyMode));
    command.outputOption('-hls_list_size ' + constants_1.VIDEO_LIVE.SEGMENTS_LIST_SIZE);
    command.outputOption('-hls_flags delete_segments+independent_segments+program_date_time');
    command.outputOption(`-hls_segment_filename ${(0, path_1.join)(outPath, '%v-%06d.ts')}`);
    command.outputOption('-master_pl_name ' + masterPlaylistName);
    command.outputOption(`-f hls`);
    command.output((0, path_1.join)(outPath, '%v.m3u8'));
}
//# sourceMappingURL=ffmpeg-live.js.map