import { remove } from 'fs-extra' import { throttle } from 'lodash' import { ConfigManager, downloadFile, logger } from 'packages/peertube-runner/shared' import { join } from 'path' import { buildUUID } from '@shared/extra-utils' import { FFmpegEdition, FFmpegLive, FFmpegVOD, getDefaultAvailableEncoders, getDefaultEncodersToTry } from '@shared/ffmpeg' import { RunnerJob, RunnerJobPayload } from '@shared/models' import { PeerTubeServer } from '@shared/server-commands' import { getTranscodingLogger } from './transcoding-logger' export type JobWithToken = RunnerJob & { jobToken: string } export type ProcessOptions = { server: PeerTubeServer job: JobWithToken runnerToken: string } export async function downloadInputFile (options: { url: string job: JobWithToken runnerToken: string }) { const { url, job, runnerToken } = options const destination = join(ConfigManager.Instance.getTranscodingDirectory(), buildUUID()) try { await downloadFile({ url, jobToken: job.jobToken, runnerToken, destination }) } catch (err) { remove(destination) .catch(err => logger.error({ err }, `Cannot remove ${destination}`)) throw err } return destination } export async function updateTranscodingProgress (options: { server: PeerTubeServer runnerToken: string job: JobWithToken progress: number }) { const { server, job, runnerToken, progress } = options return server.runnerJobs.update({ jobToken: job.jobToken, jobUUID: job.uuid, runnerToken, progress }) } // --------------------------------------------------------------------------- export function buildFFmpegVOD (options: { server: PeerTubeServer runnerToken: string job: JobWithToken }) { const { server, job, runnerToken } = options const updateInterval = ConfigManager.Instance.isTestInstance() ? 500 : 60000 const updateJobProgress = throttle((progress: number) => { if (progress < 0 || progress > 100) progress = undefined updateTranscodingProgress({ server, job, runnerToken, progress }) .catch(err => logger.error({ err }, 'Cannot send job progress')) }, updateInterval, { trailing: false }) return new FFmpegVOD({ ...getCommonFFmpegOptions(), updateJobProgress }) } export function buildFFmpegLive () { return new FFmpegLive(getCommonFFmpegOptions()) } export function buildFFmpegEdition () { return new FFmpegEdition(getCommonFFmpegOptions()) } function getCommonFFmpegOptions () { const config = ConfigManager.Instance.getConfig() return { niceness: config.ffmpeg.nice, threads: config.ffmpeg.threads, tmpDirectory: ConfigManager.Instance.getTranscodingDirectory(), profile: 'default', availableEncoders: { available: getDefaultAvailableEncoders(), encodersToTry: getDefaultEncodersToTry() }, logger: getTranscodingLogger() } }