1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
import { pick } from '@peertube/peertube-core-utils'
import { FFmpegCommandWrapper } from '../ffmpeg-command-wrapper.js'
import { getScaleFilter, StreamType } from '../ffmpeg-utils.js'
import { ffprobePromise, getVideoStreamBitrate, getVideoStreamDimensionsInfo, hasAudioStream } from '../ffprobe.js'
import { addDefaultEncoderGlobalParams, addDefaultEncoderParams, applyEncoderOptions } from './encoder-options.js'
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()
}
|