94 lines
2.7 KiB
TypeScript
94 lines
2.7 KiB
TypeScript
import { pick } from '@shared/core-utils'
|
|
import { FFmpegCommandWrapper } from '../ffmpeg-command-wrapper'
|
|
import { ffprobePromise, getVideoStreamBitrate, getVideoStreamDimensionsInfo, hasAudioStream } from '../ffprobe'
|
|
import { addDefaultEncoderGlobalParams, addDefaultEncoderParams, applyEncoderOptions } from './encoder-options'
|
|
import { getScaleFilter, StreamType } from '../ffmpeg-utils'
|
|
|
|
export async function presetVOD (options: {
|
|
commandWrapper: FFmpegCommandWrapper
|
|
|
|
input: string
|
|
|
|
canCopyAudio: boolean
|
|
canCopyVideo: boolean
|
|
|
|
resolution: number
|
|
fps: number
|
|
|
|
scaleFilterValue?: string
|
|
}) {
|
|
const { commandWrapper, input, resolution, fps, scaleFilterValue } = options
|
|
const command = commandWrapper.getCommand()
|
|
|
|
command.format('mp4')
|
|
.outputOption('-movflags faststart')
|
|
|
|
addDefaultEncoderGlobalParams(command)
|
|
|
|
const probe = await ffprobePromise(input)
|
|
|
|
// Audio encoder
|
|
const bitrate = await getVideoStreamBitrate(input, probe)
|
|
const videoStreamDimensions = await getVideoStreamDimensionsInfo(input, probe)
|
|
|
|
let streamsToProcess: StreamType[] = [ 'audio', 'video' ]
|
|
|
|
if (!await hasAudioStream(input, probe)) {
|
|
command.noAudio()
|
|
streamsToProcess = [ 'video' ]
|
|
}
|
|
|
|
for (const streamType of streamsToProcess) {
|
|
const builderResult = await commandWrapper.getEncoderBuilderResult({
|
|
...pick(options, [ 'canCopyAudio', 'canCopyVideo' ]),
|
|
|
|
input,
|
|
inputBitrate: bitrate,
|
|
inputRatio: videoStreamDimensions?.ratio || 0,
|
|
|
|
resolution,
|
|
fps,
|
|
streamType,
|
|
|
|
videoType: 'vod' as 'vod'
|
|
})
|
|
|
|
if (!builderResult) {
|
|
throw new Error('No available encoder found for stream ' + streamType)
|
|
}
|
|
|
|
commandWrapper.debugLog(
|
|
`Apply ffmpeg params from ${builderResult.encoder} for ${streamType} ` +
|
|
`stream of input ${input} using ${commandWrapper.getProfile()} profile.`,
|
|
{ builderResult, resolution, fps }
|
|
)
|
|
|
|
if (streamType === 'video') {
|
|
command.videoCodec(builderResult.encoder)
|
|
|
|
if (scaleFilterValue) {
|
|
command.outputOption(`-vf ${getScaleFilter(builderResult.result)}=${scaleFilterValue}`)
|
|
}
|
|
} else if (streamType === 'audio') {
|
|
command.audioCodec(builderResult.encoder)
|
|
}
|
|
|
|
applyEncoderOptions(command, builderResult.result)
|
|
addDefaultEncoderParams({ command, encoder: builderResult.encoder, fps })
|
|
}
|
|
}
|
|
|
|
export function presetCopy (commandWrapper: FFmpegCommandWrapper) {
|
|
commandWrapper.getCommand()
|
|
.format('mp4')
|
|
.videoCodec('copy')
|
|
.audioCodec('copy')
|
|
}
|
|
|
|
export function presetOnlyAudio (commandWrapper: FFmpegCommandWrapper) {
|
|
commandWrapper.getCommand()
|
|
.format('mp4')
|
|
.audioCodec('copy')
|
|
.noVideo()
|
|
}
|