Fix "height not divisible by 2" ffmpeg error

This commit is contained in:
Chocobozzz 2021-06-08 11:28:51 +02:00
parent 5982ffc4b5
commit 318b0bd0c2
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
3 changed files with 31 additions and 8 deletions

View File

@ -243,6 +243,18 @@ function execShell (command: string, options?: ExecOptions) {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
function isOdd (num: number) {
return (num % 2) !== 0
}
function toEven (num: number) {
if (isOdd) return num + 1
return num
}
// ---------------------------------------------------------------------------
function promisify0<A> (func: (cb: (err: any, result: A) => void) => void): () => Promise<A> { function promisify0<A> (func: (cb: (err: any, result: A) => void) => void): () => Promise<A> {
return function promisified (): Promise<A> { return function promisified (): Promise<A> {
return new Promise<A>((resolve: (arg: A) => void, reject: (err: any) => void) => { return new Promise<A>((resolve: (arg: A) => void, reject: (err: any) => void) => {
@ -310,5 +322,8 @@ export {
execPromise, execPromise,
pipelinePromise, pipelinePromise,
parseSemVersion parseSemVersion,
isOdd,
toEven
} }

View File

@ -5,11 +5,12 @@ import { dirname, join } from 'path'
import { FFMPEG_NICE, VIDEO_LIVE } from '@server/initializers/constants' import { FFMPEG_NICE, VIDEO_LIVE } from '@server/initializers/constants'
import { AvailableEncoders, EncoderOptionsBuilder, EncoderOptions, EncoderProfile, VideoResolution } from '../../shared/models/videos' import { AvailableEncoders, EncoderOptionsBuilder, EncoderOptions, EncoderProfile, VideoResolution } from '../../shared/models/videos'
import { CONFIG } from '../initializers/config' import { CONFIG } from '../initializers/config'
import { execPromise, promisify0 } from './core-utils' import { execPromise, isOdd, promisify0 } from './core-utils'
import { computeFPS, getAudioStream, getVideoFileFPS } from './ffprobe-utils' import { computeFPS, getAudioStream, getVideoFileFPS } from './ffprobe-utils'
import { processImage } from './image-utils' import { processImage } from './image-utils'
import { logger } from './logger' import { logger } from './logger'
import { FilterSpecification } from 'fluent-ffmpeg' import { FilterSpecification } from 'fluent-ffmpeg'
import { findCommentId } from '@shared/extra-utils'
/** /**
* *
@ -133,7 +134,7 @@ interface BaseTranscodeOptions {
availableEncoders: AvailableEncoders availableEncoders: AvailableEncoders
profile: string profile: string
resolution: VideoResolution resolution: number
isPortraitMode?: boolean isPortraitMode?: boolean
@ -407,8 +408,7 @@ async function buildx264VODCommand (command: ffmpeg.FfmpegCommand, options: Tran
async function buildAudioMergeCommand (command: ffmpeg.FfmpegCommand, options: MergeAudioTranscodeOptions) { async function buildAudioMergeCommand (command: ffmpeg.FfmpegCommand, options: MergeAudioTranscodeOptions) {
command = command.loop(undefined) command = command.loop(undefined)
// Avoid "height not divisible by 2" error const scaleFilterValue = getScaleCleanerValue()
const scaleFilterValue = 'trunc(iw/2)*2:trunc(ih/2)*2'
command = await presetVideo({ command, input: options.audioPath, transcodeOptions: options, scaleFilterValue }) command = await presetVideo({ command, input: options.audioPath, transcodeOptions: options, scaleFilterValue })
command.outputOption('-preset:v veryfast') command.outputOption('-preset:v veryfast')
@ -542,7 +542,7 @@ async function getEncoderBuilderResult (options: {
} }
} }
const result = await builder({ input, resolution: resolution, fps, streamNum }) const result = await builder({ input, resolution, fps, streamNum })
return { return {
result, result,
@ -727,6 +727,11 @@ async function runCommand (options: {
}) })
} }
// Avoid "height not divisible by 2" error
function getScaleCleanerValue () {
return 'trunc(iw/2)*2:trunc(ih/2)*2'
}
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
export { export {

View File

@ -1,6 +1,7 @@
import { Job } from 'bull' import { Job } from 'bull'
import { copyFile, ensureDir, move, remove, stat } from 'fs-extra' import { copyFile, ensureDir, move, remove, stat } from 'fs-extra'
import { basename, extname as extnameUtil, join } from 'path' import { basename, extname as extnameUtil, join } from 'path'
import { toEven } from '@server/helpers/core-utils'
import { createTorrentAndSetInfoHash } from '@server/helpers/webtorrent' import { createTorrentAndSetInfoHash } from '@server/helpers/webtorrent'
import { MStreamingPlaylistFilesVideo, MVideoFile, MVideoFullLight } from '@server/types/models' import { MStreamingPlaylistFilesVideo, MVideoFile, MVideoFullLight } from '@server/types/models'
import { VideoResolution } from '../../../shared/models/videos' import { VideoResolution } from '../../../shared/models/videos'
@ -35,6 +36,8 @@ async function optimizeOriginalVideofile (video: MVideoFullLight, inputVideoFile
? 'quick-transcode' ? 'quick-transcode'
: 'video' : 'video'
const resolution = toEven(inputVideoFile.resolution)
const transcodeOptions: TranscodeOptions = { const transcodeOptions: TranscodeOptions = {
type: transcodeType, type: transcodeType,
@ -44,7 +47,7 @@ async function optimizeOriginalVideofile (video: MVideoFullLight, inputVideoFile
availableEncoders: VideoTranscodingProfilesManager.Instance.getAvailableEncoders(), availableEncoders: VideoTranscodingProfilesManager.Instance.getAvailableEncoders(),
profile: CONFIG.TRANSCODING.PROFILE, profile: CONFIG.TRANSCODING.PROFILE,
resolution: inputVideoFile.resolution, resolution,
job job
} }
@ -57,7 +60,7 @@ async function optimizeOriginalVideofile (video: MVideoFullLight, inputVideoFile
// Important to do this before getVideoFilename() to take in account the new filename // Important to do this before getVideoFilename() to take in account the new filename
inputVideoFile.extname = newExtname inputVideoFile.extname = newExtname
inputVideoFile.filename = generateVideoFilename(video, false, inputVideoFile.resolution, newExtname) inputVideoFile.filename = generateVideoFilename(video, false, resolution, newExtname)
const videoOutputPath = getVideoFilePath(video, inputVideoFile) const videoOutputPath = getVideoFilePath(video, inputVideoFile)