diff options
-rw-r--r-- | server.ts | 5 | ||||
-rw-r--r-- | server/helpers/core-utils.ts | 14 | ||||
-rw-r--r-- | server/helpers/ffmpeg-utils.ts | 21 | ||||
-rw-r--r-- | server/initializers/checker-after-init.ts | 27 | ||||
-rw-r--r-- | server/initializers/checker-before-init.ts | 5 |
5 files changed, 58 insertions, 14 deletions
@@ -44,7 +44,7 @@ checkFFmpeg(CONFIG) | |||
44 | 44 | ||
45 | checkNodeVersion() | 45 | checkNodeVersion() |
46 | 46 | ||
47 | import { checkConfig, checkActivityPubUrls } from './server/initializers/checker-after-init' | 47 | import { checkConfig, checkActivityPubUrls, checkFFmpegVersion } from './server/initializers/checker-after-init' |
48 | 48 | ||
49 | const errorMessage = checkConfig() | 49 | const errorMessage = checkConfig() |
50 | if (errorMessage !== null) { | 50 | if (errorMessage !== null) { |
@@ -252,6 +252,9 @@ async function startApplication () { | |||
252 | process.exit(-1) | 252 | process.exit(-1) |
253 | }) | 253 | }) |
254 | 254 | ||
255 | checkFFmpegVersion() | ||
256 | .catch(err => logger.error('Cannot check ffmpeg version', { err })) | ||
257 | |||
255 | // Email initialization | 258 | // Email initialization |
256 | Emailer.Instance.init() | 259 | Emailer.Instance.init() |
257 | 260 | ||
diff --git a/server/helpers/core-utils.ts b/server/helpers/core-utils.ts index 7ba7d865a..ceb6a341d 100644 --- a/server/helpers/core-utils.ts +++ b/server/helpers/core-utils.ts | |||
@@ -251,6 +251,16 @@ function promisify2<T, U, A> (func: (arg1: T, arg2: U, cb: (err: any, result: A) | |||
251 | } | 251 | } |
252 | } | 252 | } |
253 | 253 | ||
254 | function parseSemVersion (s: string) { | ||
255 | const parsed = s.match(/^v?(\d+)\.(\d+)\.(\d+)$/i) | ||
256 | |||
257 | return { | ||
258 | major: parseInt(parsed[1]), | ||
259 | minor: parseInt(parsed[2]), | ||
260 | patch: parseInt(parsed[3]) | ||
261 | } | ||
262 | } | ||
263 | |||
254 | const randomBytesPromise = promisify1<number, Buffer>(randomBytes) | 264 | const randomBytesPromise = promisify1<number, Buffer>(randomBytes) |
255 | const createPrivateKey = promisify1<number, { key: string }>(pem.createPrivateKey) | 265 | const createPrivateKey = promisify1<number, { key: string }>(pem.createPrivateKey) |
256 | const getPublicKey = promisify1<string, { publicKey: string }>(pem.getPublicKey) | 266 | const getPublicKey = promisify1<string, { publicKey: string }>(pem.getPublicKey) |
@@ -288,5 +298,7 @@ export { | |||
288 | getPublicKey, | 298 | getPublicKey, |
289 | execPromise2, | 299 | execPromise2, |
290 | execPromise, | 300 | execPromise, |
291 | pipelinePromise | 301 | pipelinePromise, |
302 | |||
303 | parseSemVersion | ||
292 | } | 304 | } |
diff --git a/server/helpers/ffmpeg-utils.ts b/server/helpers/ffmpeg-utils.ts index 620025966..69cd397b9 100644 --- a/server/helpers/ffmpeg-utils.ts +++ b/server/helpers/ffmpeg-utils.ts | |||
@@ -5,7 +5,7 @@ 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' |
6 | import { AvailableEncoders, EncoderOptionsBuilder, EncoderProfile, VideoResolution } from '../../shared/models/videos' | 6 | import { AvailableEncoders, EncoderOptionsBuilder, EncoderProfile, VideoResolution } from '../../shared/models/videos' |
7 | import { CONFIG } from '../initializers/config' | 7 | import { CONFIG } from '../initializers/config' |
8 | import { promisify0 } from './core-utils' | 8 | import { execPromise, promisify0 } from './core-utils' |
9 | import { computeFPS, getAudioStream, getVideoFileFPS } from './ffprobe-utils' | 9 | import { computeFPS, getAudioStream, getVideoFileFPS } from './ffprobe-utils' |
10 | import { processImage } from './image-utils' | 10 | import { processImage } from './image-utils' |
11 | import { logger } from './logger' | 11 | import { logger } from './logger' |
@@ -649,6 +649,24 @@ function getFFmpeg (input: string, type: 'live' | 'vod') { | |||
649 | return command | 649 | return command |
650 | } | 650 | } |
651 | 651 | ||
652 | function getFFmpegVersion () { | ||
653 | return new Promise<string>((res, rej) => { | ||
654 | (ffmpeg() as any)._getFfmpegPath((err, ffmpegPath) => { | ||
655 | if (err) return rej(err) | ||
656 | if (!ffmpegPath) return rej(new Error('Could not find ffmpeg path')) | ||
657 | |||
658 | return execPromise(`${ffmpegPath} -version`) | ||
659 | .then(stdout => { | ||
660 | const parsed = stdout.match(/ffmpeg version .(\d+\.\d+\.\d+)/) | ||
661 | if (!parsed || !parsed[1]) return rej(new Error(`Could not find ffmpeg version in ${stdout}`)) | ||
662 | |||
663 | return res(parsed[1]) | ||
664 | }) | ||
665 | .catch(err => rej(err)) | ||
666 | }) | ||
667 | }) | ||
668 | } | ||
669 | |||
652 | async function runCommand (options: { | 670 | async function runCommand (options: { |
653 | command: ffmpeg.FfmpegCommand | 671 | command: ffmpeg.FfmpegCommand |
654 | silent?: boolean // false | 672 | silent?: boolean // false |
@@ -695,6 +713,7 @@ export { | |||
695 | TranscodeOptionsType, | 713 | TranscodeOptionsType, |
696 | transcode, | 714 | transcode, |
697 | runCommand, | 715 | runCommand, |
716 | getFFmpegVersion, | ||
698 | 717 | ||
699 | resetSupportedEncoders, | 718 | resetSupportedEncoders, |
700 | 719 | ||
diff --git a/server/initializers/checker-after-init.ts b/server/initializers/checker-after-init.ts index 2b00e2047..a93c8b7fd 100644 --- a/server/initializers/checker-after-init.ts +++ b/server/initializers/checker-after-init.ts | |||
@@ -1,16 +1,17 @@ | |||
1 | import * as config from 'config' | 1 | import * as config from 'config' |
2 | import { isProdInstance, isTestInstance } from '../helpers/core-utils' | 2 | import { uniq } from 'lodash' |
3 | import { UserModel } from '../models/account/user' | ||
4 | import { getServerActor, ApplicationModel } from '../models/application/application' | ||
5 | import { OAuthClientModel } from '../models/oauth/oauth-client' | ||
6 | import { URL } from 'url' | 3 | import { URL } from 'url' |
7 | import { CONFIG, isEmailEnabled } from './config' | 4 | import { getFFmpegVersion } from '@server/helpers/ffmpeg-utils' |
8 | import { logger } from '../helpers/logger' | 5 | import { VideoRedundancyConfigFilter } from '@shared/models/redundancy/video-redundancy-config-filter.type' |
9 | import { RecentlyAddedStrategy } from '../../shared/models/redundancy' | 6 | import { RecentlyAddedStrategy } from '../../shared/models/redundancy' |
7 | import { isProdInstance, isTestInstance, parseSemVersion } from '../helpers/core-utils' | ||
10 | import { isArray } from '../helpers/custom-validators/misc' | 8 | import { isArray } from '../helpers/custom-validators/misc' |
11 | import { uniq } from 'lodash' | 9 | import { logger } from '../helpers/logger' |
10 | import { UserModel } from '../models/account/user' | ||
11 | import { ApplicationModel, getServerActor } from '../models/application/application' | ||
12 | import { OAuthClientModel } from '../models/oauth/oauth-client' | ||
13 | import { CONFIG, isEmailEnabled } from './config' | ||
12 | import { WEBSERVER } from './constants' | 14 | import { WEBSERVER } from './constants' |
13 | import { VideoRedundancyConfigFilter } from '@shared/models/redundancy/video-redundancy-config-filter.type' | ||
14 | 15 | ||
15 | async function checkActivityPubUrls () { | 16 | async function checkActivityPubUrls () { |
16 | const actor = await getServerActor() | 17 | const actor = await getServerActor() |
@@ -176,11 +177,21 @@ async function applicationExist () { | |||
176 | return totalApplication !== 0 | 177 | return totalApplication !== 0 |
177 | } | 178 | } |
178 | 179 | ||
180 | async function checkFFmpegVersion () { | ||
181 | const version = await getFFmpegVersion() | ||
182 | const { major, minor } = parseSemVersion(version) | ||
183 | |||
184 | if (major < 4 || (major === 4 && minor < 1)) { | ||
185 | logger.warn('Your ffmpeg version (%s) is outdated. PeerTube supports ffmpeg >= 4.1. Please upgrade.', version) | ||
186 | } | ||
187 | } | ||
188 | |||
179 | // --------------------------------------------------------------------------- | 189 | // --------------------------------------------------------------------------- |
180 | 190 | ||
181 | export { | 191 | export { |
182 | checkConfig, | 192 | checkConfig, |
183 | clientsExist, | 193 | clientsExist, |
194 | checkFFmpegVersion, | ||
184 | usersExist, | 195 | usersExist, |
185 | applicationExist, | 196 | applicationExist, |
186 | checkActivityPubUrls | 197 | checkActivityPubUrls |
diff --git a/server/initializers/checker-before-init.ts b/server/initializers/checker-before-init.ts index 565e0d1fa..65a019ca6 100644 --- a/server/initializers/checker-before-init.ts +++ b/server/initializers/checker-before-init.ts | |||
@@ -1,5 +1,5 @@ | |||
1 | import * as config from 'config' | 1 | import * as config from 'config' |
2 | import { promisify0 } from '../helpers/core-utils' | 2 | import { parseSemVersion, promisify0 } from '../helpers/core-utils' |
3 | import { logger } from '../helpers/logger' | 3 | import { logger } from '../helpers/logger' |
4 | 4 | ||
5 | // ONLY USE CORE MODULES IN THIS FILE! | 5 | // ONLY USE CORE MODULES IN THIS FILE! |
@@ -102,8 +102,7 @@ async function checkFFmpeg (CONFIG: { TRANSCODING: { ENABLED: boolean } }) { | |||
102 | 102 | ||
103 | function checkNodeVersion () { | 103 | function checkNodeVersion () { |
104 | const v = process.version | 104 | const v = process.version |
105 | const majorString = v.split('.')[0].replace('v', '') | 105 | const { major } = parseSemVersion(v) |
106 | const major = parseInt(majorString, 10) | ||
107 | 106 | ||
108 | logger.debug('Checking NodeJS version %s.', v) | 107 | logger.debug('Checking NodeJS version %s.', v) |
109 | 108 | ||