aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2021-06-08 11:28:51 +0200
committerChocobozzz <me@florianbigard.com>2021-06-08 11:28:51 +0200
commit318b0bd0c2ff575f35d51d97327f77abfecd6b86 (patch)
tree095a464dc053c06bc7a9c1e6a50a18ac9a7e4dce
parent5982ffc4b5c926ea51f5bb3ca48f0f2f8f5bd621 (diff)
downloadPeerTube-318b0bd0c2ff575f35d51d97327f77abfecd6b86.tar.gz
PeerTube-318b0bd0c2ff575f35d51d97327f77abfecd6b86.tar.zst
PeerTube-318b0bd0c2ff575f35d51d97327f77abfecd6b86.zip
Fix "height not divisible by 2" ffmpeg error
-rw-r--r--server/helpers/core-utils.ts17
-rw-r--r--server/helpers/ffmpeg-utils.ts15
-rw-r--r--server/lib/transcoding/video-transcoding.ts7
3 files changed, 31 insertions, 8 deletions
diff --git a/server/helpers/core-utils.ts b/server/helpers/core-utils.ts
index b5bf2c92c..f7e6fdddc 100644
--- a/server/helpers/core-utils.ts
+++ b/server/helpers/core-utils.ts
@@ -243,6 +243,18 @@ function execShell (command: string, options?: ExecOptions) {
243 243
244// --------------------------------------------------------------------------- 244// ---------------------------------------------------------------------------
245 245
246function isOdd (num: number) {
247 return (num % 2) !== 0
248}
249
250function toEven (num: number) {
251 if (isOdd) return num + 1
252
253 return num
254}
255
256// ---------------------------------------------------------------------------
257
246function promisify0<A> (func: (cb: (err: any, result: A) => void) => void): () => Promise<A> { 258function promisify0<A> (func: (cb: (err: any, result: A) => void) => void): () => Promise<A> {
247 return function promisified (): Promise<A> { 259 return function promisified (): Promise<A> {
248 return new Promise<A>((resolve: (arg: A) => void, reject: (err: any) => void) => { 260 return new Promise<A>((resolve: (arg: A) => void, reject: (err: any) => void) => {
@@ -310,5 +322,8 @@ export {
310 execPromise, 322 execPromise,
311 pipelinePromise, 323 pipelinePromise,
312 324
313 parseSemVersion 325 parseSemVersion,
326
327 isOdd,
328 toEven
314} 329}
diff --git a/server/helpers/ffmpeg-utils.ts b/server/helpers/ffmpeg-utils.ts
index e328c49ac..d20ca5d56 100644
--- a/server/helpers/ffmpeg-utils.ts
+++ b/server/helpers/ffmpeg-utils.ts
@@ -5,11 +5,12 @@ import { dirname, join } from 'path'
5import { FFMPEG_NICE, VIDEO_LIVE } from '@server/initializers/constants' 5import { FFMPEG_NICE, VIDEO_LIVE } from '@server/initializers/constants'
6import { AvailableEncoders, EncoderOptionsBuilder, EncoderOptions, EncoderProfile, VideoResolution } from '../../shared/models/videos' 6import { AvailableEncoders, EncoderOptionsBuilder, EncoderOptions, EncoderProfile, VideoResolution } from '../../shared/models/videos'
7import { CONFIG } from '../initializers/config' 7import { CONFIG } from '../initializers/config'
8import { execPromise, promisify0 } from './core-utils' 8import { execPromise, isOdd, promisify0 } from './core-utils'
9import { computeFPS, getAudioStream, getVideoFileFPS } from './ffprobe-utils' 9import { computeFPS, getAudioStream, getVideoFileFPS } from './ffprobe-utils'
10import { processImage } from './image-utils' 10import { processImage } from './image-utils'
11import { logger } from './logger' 11import { logger } from './logger'
12import { FilterSpecification } from 'fluent-ffmpeg' 12import { FilterSpecification } from 'fluent-ffmpeg'
13import { findCommentId } from '@shared/extra-utils'
13 14
14/** 15/**
15 * 16 *
@@ -133,7 +134,7 @@ interface BaseTranscodeOptions {
133 availableEncoders: AvailableEncoders 134 availableEncoders: AvailableEncoders
134 profile: string 135 profile: string
135 136
136 resolution: VideoResolution 137 resolution: number
137 138
138 isPortraitMode?: boolean 139 isPortraitMode?: boolean
139 140
@@ -407,8 +408,7 @@ async function buildx264VODCommand (command: ffmpeg.FfmpegCommand, options: Tran
407async function buildAudioMergeCommand (command: ffmpeg.FfmpegCommand, options: MergeAudioTranscodeOptions) { 408async function buildAudioMergeCommand (command: ffmpeg.FfmpegCommand, options: MergeAudioTranscodeOptions) {
408 command = command.loop(undefined) 409 command = command.loop(undefined)
409 410
410 // Avoid "height not divisible by 2" error 411 const scaleFilterValue = getScaleCleanerValue()
411 const scaleFilterValue = 'trunc(iw/2)*2:trunc(ih/2)*2'
412 command = await presetVideo({ command, input: options.audioPath, transcodeOptions: options, scaleFilterValue }) 412 command = await presetVideo({ command, input: options.audioPath, transcodeOptions: options, scaleFilterValue })
413 413
414 command.outputOption('-preset:v veryfast') 414 command.outputOption('-preset:v veryfast')
@@ -542,7 +542,7 @@ async function getEncoderBuilderResult (options: {
542 } 542 }
543 } 543 }
544 544
545 const result = await builder({ input, resolution: resolution, fps, streamNum }) 545 const result = await builder({ input, resolution, fps, streamNum })
546 546
547 return { 547 return {
548 result, 548 result,
@@ -727,6 +727,11 @@ async function runCommand (options: {
727 }) 727 })
728} 728}
729 729
730// Avoid "height not divisible by 2" error
731function getScaleCleanerValue () {
732 return 'trunc(iw/2)*2:trunc(ih/2)*2'
733}
734
730// --------------------------------------------------------------------------- 735// ---------------------------------------------------------------------------
731 736
732export { 737export {
diff --git a/server/lib/transcoding/video-transcoding.ts b/server/lib/transcoding/video-transcoding.ts
index 5df192575..1ad63baf3 100644
--- a/server/lib/transcoding/video-transcoding.ts
+++ b/server/lib/transcoding/video-transcoding.ts
@@ -1,6 +1,7 @@
1import { Job } from 'bull' 1import { Job } from 'bull'
2import { copyFile, ensureDir, move, remove, stat } from 'fs-extra' 2import { copyFile, ensureDir, move, remove, stat } from 'fs-extra'
3import { basename, extname as extnameUtil, join } from 'path' 3import { basename, extname as extnameUtil, join } from 'path'
4import { toEven } from '@server/helpers/core-utils'
4import { createTorrentAndSetInfoHash } from '@server/helpers/webtorrent' 5import { createTorrentAndSetInfoHash } from '@server/helpers/webtorrent'
5import { MStreamingPlaylistFilesVideo, MVideoFile, MVideoFullLight } from '@server/types/models' 6import { MStreamingPlaylistFilesVideo, MVideoFile, MVideoFullLight } from '@server/types/models'
6import { VideoResolution } from '../../../shared/models/videos' 7import { VideoResolution } from '../../../shared/models/videos'
@@ -35,6 +36,8 @@ async function optimizeOriginalVideofile (video: MVideoFullLight, inputVideoFile
35 ? 'quick-transcode' 36 ? 'quick-transcode'
36 : 'video' 37 : 'video'
37 38
39 const resolution = toEven(inputVideoFile.resolution)
40
38 const transcodeOptions: TranscodeOptions = { 41 const transcodeOptions: TranscodeOptions = {
39 type: transcodeType, 42 type: transcodeType,
40 43
@@ -44,7 +47,7 @@ async function optimizeOriginalVideofile (video: MVideoFullLight, inputVideoFile
44 availableEncoders: VideoTranscodingProfilesManager.Instance.getAvailableEncoders(), 47 availableEncoders: VideoTranscodingProfilesManager.Instance.getAvailableEncoders(),
45 profile: CONFIG.TRANSCODING.PROFILE, 48 profile: CONFIG.TRANSCODING.PROFILE,
46 49
47 resolution: inputVideoFile.resolution, 50 resolution,
48 51
49 job 52 job
50 } 53 }
@@ -57,7 +60,7 @@ async function optimizeOriginalVideofile (video: MVideoFullLight, inputVideoFile
57 60
58 // Important to do this before getVideoFilename() to take in account the new filename 61 // Important to do this before getVideoFilename() to take in account the new filename
59 inputVideoFile.extname = newExtname 62 inputVideoFile.extname = newExtname
60 inputVideoFile.filename = generateVideoFilename(video, false, inputVideoFile.resolution, newExtname) 63 inputVideoFile.filename = generateVideoFilename(video, false, resolution, newExtname)
61 64
62 const videoOutputPath = getVideoFilePath(video, inputVideoFile) 65 const videoOutputPath = getVideoFilePath(video, inputVideoFile)
63 66