diff options
Diffstat (limited to 'server/helpers/ffmpeg-utils.ts')
-rw-r--r-- | server/helpers/ffmpeg-utils.ts | 38 |
1 files changed, 19 insertions, 19 deletions
diff --git a/server/helpers/ffmpeg-utils.ts b/server/helpers/ffmpeg-utils.ts index a99c9ee7c..54fd031b7 100644 --- a/server/helpers/ffmpeg-utils.ts +++ b/server/helpers/ffmpeg-utils.ts | |||
@@ -1,5 +1,5 @@ | |||
1 | import { Job } from 'bull' | 1 | import { Job } from 'bull' |
2 | import * as ffmpeg from 'fluent-ffmpeg' | 2 | import ffmpeg, { FfmpegCommand, FilterSpecification, getAvailableEncoders } from 'fluent-ffmpeg' |
3 | import { readFile, remove, writeFile } from 'fs-extra' | 3 | import { readFile, remove, writeFile } from 'fs-extra' |
4 | import { dirname, join } from 'path' | 4 | import { dirname, join } from 'path' |
5 | import { FFMPEG_NICE, VIDEO_LIVE } from '@server/initializers/constants' | 5 | import { FFMPEG_NICE, VIDEO_LIVE } from '@server/initializers/constants' |
@@ -42,7 +42,7 @@ async function checkFFmpegEncoders (peertubeAvailableEncoders: AvailableEncoders | |||
42 | return supportedEncoders | 42 | return supportedEncoders |
43 | } | 43 | } |
44 | 44 | ||
45 | const getAvailableEncodersPromise = promisify0(ffmpeg.getAvailableEncoders) | 45 | const getAvailableEncodersPromise = promisify0(getAvailableEncoders) |
46 | const availableFFmpegEncoders = await getAvailableEncodersPromise() | 46 | const availableFFmpegEncoders = await getAvailableEncodersPromise() |
47 | 47 | ||
48 | const searchEncoders = new Set<string>() | 48 | const searchEncoders = new Set<string>() |
@@ -191,7 +191,7 @@ type TranscodeOptions = | |||
191 | | QuickTranscodeOptions | 191 | | QuickTranscodeOptions |
192 | 192 | ||
193 | const builders: { | 193 | const builders: { |
194 | [ type in TranscodeOptionsType ]: (c: ffmpeg.FfmpegCommand, o?: TranscodeOptions) => Promise<ffmpeg.FfmpegCommand> | ffmpeg.FfmpegCommand | 194 | [ type in TranscodeOptionsType ]: (c: FfmpegCommand, o?: TranscodeOptions) => Promise<FfmpegCommand> | FfmpegCommand |
195 | } = { | 195 | } = { |
196 | 'quick-transcode': buildQuickTranscodeCommand, | 196 | 'quick-transcode': buildQuickTranscodeCommand, |
197 | 'hls': buildHLSVODCommand, | 197 | 'hls': buildHLSVODCommand, |
@@ -241,7 +241,7 @@ async function getLiveTranscodingCommand (options: { | |||
241 | 241 | ||
242 | const varStreamMap: string[] = [] | 242 | const varStreamMap: string[] = [] |
243 | 243 | ||
244 | const complexFilter: ffmpeg.FilterSpecification[] = [ | 244 | const complexFilter: FilterSpecification[] = [ |
245 | { | 245 | { |
246 | inputs: '[v:0]', | 246 | inputs: '[v:0]', |
247 | filter: 'split', | 247 | filter: 'split', |
@@ -353,7 +353,7 @@ function buildStreamSuffix (base: string, streamNum?: number) { | |||
353 | // --------------------------------------------------------------------------- | 353 | // --------------------------------------------------------------------------- |
354 | 354 | ||
355 | function addDefaultEncoderGlobalParams (options: { | 355 | function addDefaultEncoderGlobalParams (options: { |
356 | command: ffmpeg.FfmpegCommand | 356 | command: FfmpegCommand |
357 | }) { | 357 | }) { |
358 | const { command } = options | 358 | const { command } = options |
359 | 359 | ||
@@ -370,7 +370,7 @@ function addDefaultEncoderGlobalParams (options: { | |||
370 | } | 370 | } |
371 | 371 | ||
372 | function addDefaultEncoderParams (options: { | 372 | function addDefaultEncoderParams (options: { |
373 | command: ffmpeg.FfmpegCommand | 373 | command: FfmpegCommand |
374 | encoder: 'libx264' | string | 374 | encoder: 'libx264' | string |
375 | streamNum?: number | 375 | streamNum?: number |
376 | fps?: number | 376 | fps?: number |
@@ -390,7 +390,7 @@ function addDefaultEncoderParams (options: { | |||
390 | } | 390 | } |
391 | } | 391 | } |
392 | 392 | ||
393 | function addDefaultLiveHLSParams (command: ffmpeg.FfmpegCommand, outPath: string, masterPlaylistName: string) { | 393 | function addDefaultLiveHLSParams (command: FfmpegCommand, outPath: string, masterPlaylistName: string) { |
394 | command.outputOption('-hls_time ' + VIDEO_LIVE.SEGMENT_TIME_SECONDS) | 394 | command.outputOption('-hls_time ' + VIDEO_LIVE.SEGMENT_TIME_SECONDS) |
395 | command.outputOption('-hls_list_size ' + VIDEO_LIVE.SEGMENTS_LIST_SIZE) | 395 | command.outputOption('-hls_list_size ' + VIDEO_LIVE.SEGMENTS_LIST_SIZE) |
396 | command.outputOption('-hls_flags delete_segments+independent_segments') | 396 | command.outputOption('-hls_flags delete_segments+independent_segments') |
@@ -405,7 +405,7 @@ function addDefaultLiveHLSParams (command: ffmpeg.FfmpegCommand, outPath: string | |||
405 | // Transcode VOD command builders | 405 | // Transcode VOD command builders |
406 | // --------------------------------------------------------------------------- | 406 | // --------------------------------------------------------------------------- |
407 | 407 | ||
408 | async function buildx264VODCommand (command: ffmpeg.FfmpegCommand, options: TranscodeOptions) { | 408 | async function buildx264VODCommand (command: FfmpegCommand, options: TranscodeOptions) { |
409 | let fps = await getVideoFileFPS(options.inputPath) | 409 | let fps = await getVideoFileFPS(options.inputPath) |
410 | fps = computeFPS(fps, options.resolution) | 410 | fps = computeFPS(fps, options.resolution) |
411 | 411 | ||
@@ -422,7 +422,7 @@ async function buildx264VODCommand (command: ffmpeg.FfmpegCommand, options: Tran | |||
422 | return command | 422 | return command |
423 | } | 423 | } |
424 | 424 | ||
425 | async function buildAudioMergeCommand (command: ffmpeg.FfmpegCommand, options: MergeAudioTranscodeOptions) { | 425 | async function buildAudioMergeCommand (command: FfmpegCommand, options: MergeAudioTranscodeOptions) { |
426 | command = command.loop(undefined) | 426 | command = command.loop(undefined) |
427 | 427 | ||
428 | const scaleFilterValue = getScaleCleanerValue() | 428 | const scaleFilterValue = getScaleCleanerValue() |
@@ -437,13 +437,13 @@ async function buildAudioMergeCommand (command: ffmpeg.FfmpegCommand, options: M | |||
437 | return command | 437 | return command |
438 | } | 438 | } |
439 | 439 | ||
440 | function buildOnlyAudioCommand (command: ffmpeg.FfmpegCommand, _options: OnlyAudioTranscodeOptions) { | 440 | function buildOnlyAudioCommand (command: FfmpegCommand, _options: OnlyAudioTranscodeOptions) { |
441 | command = presetOnlyAudio(command) | 441 | command = presetOnlyAudio(command) |
442 | 442 | ||
443 | return command | 443 | return command |
444 | } | 444 | } |
445 | 445 | ||
446 | function buildQuickTranscodeCommand (command: ffmpeg.FfmpegCommand) { | 446 | function buildQuickTranscodeCommand (command: FfmpegCommand) { |
447 | command = presetCopy(command) | 447 | command = presetCopy(command) |
448 | 448 | ||
449 | command = command.outputOption('-map_metadata -1') // strip all metadata | 449 | command = command.outputOption('-map_metadata -1') // strip all metadata |
@@ -452,7 +452,7 @@ function buildQuickTranscodeCommand (command: ffmpeg.FfmpegCommand) { | |||
452 | return command | 452 | return command |
453 | } | 453 | } |
454 | 454 | ||
455 | function addCommonHLSVODCommandOptions (command: ffmpeg.FfmpegCommand, outputPath: string) { | 455 | function addCommonHLSVODCommandOptions (command: FfmpegCommand, outputPath: string) { |
456 | return command.outputOption('-hls_time 4') | 456 | return command.outputOption('-hls_time 4') |
457 | .outputOption('-hls_list_size 0') | 457 | .outputOption('-hls_list_size 0') |
458 | .outputOption('-hls_playlist_type vod') | 458 | .outputOption('-hls_playlist_type vod') |
@@ -462,7 +462,7 @@ function addCommonHLSVODCommandOptions (command: ffmpeg.FfmpegCommand, outputPat | |||
462 | .outputOption('-hls_flags single_file') | 462 | .outputOption('-hls_flags single_file') |
463 | } | 463 | } |
464 | 464 | ||
465 | async function buildHLSVODCommand (command: ffmpeg.FfmpegCommand, options: HLSTranscodeOptions) { | 465 | async function buildHLSVODCommand (command: FfmpegCommand, options: HLSTranscodeOptions) { |
466 | const videoPath = getHLSVideoPath(options) | 466 | const videoPath = getHLSVideoPath(options) |
467 | 467 | ||
468 | if (options.copyCodecs) command = presetCopy(command) | 468 | if (options.copyCodecs) command = presetCopy(command) |
@@ -474,7 +474,7 @@ async function buildHLSVODCommand (command: ffmpeg.FfmpegCommand, options: HLSTr | |||
474 | return command | 474 | return command |
475 | } | 475 | } |
476 | 476 | ||
477 | function buildHLSVODFromTSCommand (command: ffmpeg.FfmpegCommand, options: HLSFromTSTranscodeOptions) { | 477 | function buildHLSVODFromTSCommand (command: FfmpegCommand, options: HLSFromTSTranscodeOptions) { |
478 | const videoPath = getHLSVideoPath(options) | 478 | const videoPath = getHLSVideoPath(options) |
479 | 479 | ||
480 | command.outputOption('-c copy') | 480 | command.outputOption('-c copy') |
@@ -571,7 +571,7 @@ async function getEncoderBuilderResult (options: EncoderOptionsBuilderParams & { | |||
571 | } | 571 | } |
572 | 572 | ||
573 | async function presetVideo (options: { | 573 | async function presetVideo (options: { |
574 | command: ffmpeg.FfmpegCommand | 574 | command: FfmpegCommand |
575 | input: string | 575 | input: string |
576 | transcodeOptions: TranscodeOptions | 576 | transcodeOptions: TranscodeOptions |
577 | fps?: number | 577 | fps?: number |
@@ -640,21 +640,21 @@ async function presetVideo (options: { | |||
640 | return localCommand | 640 | return localCommand |
641 | } | 641 | } |
642 | 642 | ||
643 | function presetCopy (command: ffmpeg.FfmpegCommand): ffmpeg.FfmpegCommand { | 643 | function presetCopy (command: FfmpegCommand): FfmpegCommand { |
644 | return command | 644 | return command |
645 | .format('mp4') | 645 | .format('mp4') |
646 | .videoCodec('copy') | 646 | .videoCodec('copy') |
647 | .audioCodec('copy') | 647 | .audioCodec('copy') |
648 | } | 648 | } |
649 | 649 | ||
650 | function presetOnlyAudio (command: ffmpeg.FfmpegCommand): ffmpeg.FfmpegCommand { | 650 | function presetOnlyAudio (command: FfmpegCommand): FfmpegCommand { |
651 | return command | 651 | return command |
652 | .format('mp4') | 652 | .format('mp4') |
653 | .audioCodec('copy') | 653 | .audioCodec('copy') |
654 | .noVideo() | 654 | .noVideo() |
655 | } | 655 | } |
656 | 656 | ||
657 | function applyEncoderOptions (command: ffmpeg.FfmpegCommand, options: EncoderOptions): ffmpeg.FfmpegCommand { | 657 | function applyEncoderOptions (command: FfmpegCommand, options: EncoderOptions): FfmpegCommand { |
658 | return command | 658 | return command |
659 | .inputOptions(options.inputOptions ?? []) | 659 | .inputOptions(options.inputOptions ?? []) |
660 | .outputOptions(options.outputOptions ?? []) | 660 | .outputOptions(options.outputOptions ?? []) |
@@ -714,7 +714,7 @@ function getFFmpegVersion () { | |||
714 | } | 714 | } |
715 | 715 | ||
716 | async function runCommand (options: { | 716 | async function runCommand (options: { |
717 | command: ffmpeg.FfmpegCommand | 717 | command: FfmpegCommand |
718 | silent?: boolean // false | 718 | silent?: boolean // false |
719 | job?: Job | 719 | job?: Job |
720 | }) { | 720 | }) { |