fix: handle git installation of ffmpeg

pull/5949/head
Seth Falco 2023-08-02 23:22:36 +01:00 committed by Chocobozzz
parent 8e4fba97b2
commit 2055962c84
4 changed files with 78 additions and 11 deletions

View File

@ -1,6 +1,9 @@
import { exec } from 'child_process'
import ffmpeg from 'fluent-ffmpeg'
/**
* @returns FFmpeg version string. Usually a semver string, but may vary when depending on installation method.
*/
export function getFFmpegVersion () {
return new Promise<string>((res, rej) => {
(ffmpeg() as any)._getFfmpegPath((err, ffmpegPath) => {
@ -10,14 +13,10 @@ export function getFFmpegVersion () {
return exec(`${ffmpegPath} -version`, (err, stdout) => {
if (err) return rej(err)
const parsed = stdout.match(/ffmpeg version .?(\d+\.\d+(\.\d+)?)/)
if (!parsed?.[1]) return rej(new Error(`Could not find ffmpeg version in ${stdout}`))
const parsed = stdout.match(/(?<=ffmpeg version )[a-zA-Z\d.-]+/)
if (!parsed) return rej(new Error(`Could not find ffmpeg version in ${stdout}`))
// Fix ffmpeg version that does not include patch version (4.4 for example)
let version = parsed[1]
if (version.match(/^\d+\.\d+$/)) {
version += '.0'
}
res(parsed[0])
})
})
})

View File

@ -5,7 +5,7 @@ import snakeCase from 'lodash-es/snakeCase.js'
import validator from 'validator'
import { getAverageTheoreticalBitrate, getMaxTheoreticalBitrate } from '@peertube/peertube-core-utils'
import { VideoResolution } from '@peertube/peertube-models'
import { objectConverter, parseBytes, parseDurationToMs } from '@peertube/peertube-server/server/helpers/core-utils.js'
import { objectConverter, parseBytes, parseDurationToMs, parseSemVersion } from '@peertube/peertube-server/server/helpers/core-utils.js'
describe('Parse Bytes', function () {
@ -148,3 +148,54 @@ describe('Bitrate', function () {
}
})
})
describe('Parse semantic version string', function () {
it('Should parse Node.js version string', function () {
const actual = parseSemVersion('v18.16.0')
expect(actual.major).to.equal(18)
expect(actual.minor).to.equal(16)
expect(actual.patch).to.equal(0)
})
it('Should parse FFmpeg version string from Debian 12 repo', function () {
const actual = parseSemVersion('5.1.3-1')
expect(actual.major).to.equal(5)
expect(actual.minor).to.equal(1)
expect(actual.patch).to.equal(3)
})
it('Should parse FFmpeg version string from Arch repo', function () {
const actual = parseSemVersion('n6.0')
expect(actual.major).to.equal(6)
expect(actual.minor).to.equal(0)
expect(actual.patch).to.equal(0)
})
it('Should parse FFmpeg version from GitHub release', function () {
const actual = parseSemVersion('5.1.3')
expect(actual.major).to.equal(5)
expect(actual.minor).to.equal(1)
expect(actual.patch).to.equal(3)
})
it('Should parse FFmpeg version from GitHub dev release', function () {
const actual = parseSemVersion('5.1.git')
expect(actual.major).to.equal(5)
expect(actual.minor).to.equal(1)
expect(actual.patch).to.equal(0)
})
it('Should parse FFmpeg version string with missing patch segment', function () {
const actual = parseSemVersion('4.4')
expect(actual.major).to.equal(4)
expect(actual.minor).to.equal(4)
expect(actual.patch).to.equal(0)
})
})

View File

@ -183,13 +183,23 @@ function pageToStartAndCount (page: number, itemsPerPage: number) {
// ---------------------------------------------------------------------------
type SemVersion = { major: number, minor: number, patch: number }
/**
* Parses a semantic version string into its separate components.
* Fairly lax, and allows for missing or additional segments in the string.
*
* @param s String to parse semantic version from.
* @returns Major, minor, and patch version, or null if string does not follow semantic version conventions.
*/
function parseSemVersion (s: string) {
const parsed = s.match(/^v?(\d+)\.(\d+)\.(\d+)$/i)
const parsed = s.match(/v?(\d+)\.(\d+)(?:\.(\d+))?/i)
if (!parsed) return null
return {
major: parseInt(parsed[1]),
minor: parseInt(parsed[2]),
patch: parseInt(parsed[3])
patch: parsed[3] ? parseInt(parsed[3]) : 0
} as SemVersion
}

View File

@ -78,7 +78,14 @@ async function applicationExist () {
async function checkFFmpegVersion () {
const version = await getFFmpegVersion()
const { major, minor, patch } = parseSemVersion(version)
const semvar = parseSemVersion(version)
if (!semvar) {
logger.warn('Your ffmpeg version (%s) does not use semvar. Unable to determine version compatibility.', version)
return
}
const { major, minor, patch } = semvar
if (major < 4 || (major === 4 && minor < 1)) {
logger.warn('Your ffmpeg version (%s) is outdated. PeerTube supports ffmpeg >= 4.1. Please upgrade ffmpeg.', version)