fix: handle git installation of ffmpeg
This commit is contained in:
parent
8e4fba97b2
commit
2055962c84
|
@ -1,6 +1,9 @@
|
||||||
import { exec } from 'child_process'
|
import { exec } from 'child_process'
|
||||||
import ffmpeg from 'fluent-ffmpeg'
|
import ffmpeg from 'fluent-ffmpeg'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns FFmpeg version string. Usually a semver string, but may vary when depending on installation method.
|
||||||
|
*/
|
||||||
export function getFFmpegVersion () {
|
export function getFFmpegVersion () {
|
||||||
return new Promise<string>((res, rej) => {
|
return new Promise<string>((res, rej) => {
|
||||||
(ffmpeg() as any)._getFfmpegPath((err, ffmpegPath) => {
|
(ffmpeg() as any)._getFfmpegPath((err, ffmpegPath) => {
|
||||||
|
@ -10,14 +13,10 @@ export function getFFmpegVersion () {
|
||||||
return exec(`${ffmpegPath} -version`, (err, stdout) => {
|
return exec(`${ffmpegPath} -version`, (err, stdout) => {
|
||||||
if (err) return rej(err)
|
if (err) return rej(err)
|
||||||
|
|
||||||
const parsed = stdout.match(/ffmpeg version .?(\d+\.\d+(\.\d+)?)/)
|
const parsed = stdout.match(/(?<=ffmpeg version )[a-zA-Z\d.-]+/)
|
||||||
if (!parsed?.[1]) return rej(new Error(`Could not find ffmpeg version in ${stdout}`))
|
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)
|
res(parsed[0])
|
||||||
let version = parsed[1]
|
|
||||||
if (version.match(/^\d+\.\d+$/)) {
|
|
||||||
version += '.0'
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -5,7 +5,7 @@ import snakeCase from 'lodash-es/snakeCase.js'
|
||||||
import validator from 'validator'
|
import validator from 'validator'
|
||||||
import { getAverageTheoreticalBitrate, getMaxTheoreticalBitrate } from '@peertube/peertube-core-utils'
|
import { getAverageTheoreticalBitrate, getMaxTheoreticalBitrate } from '@peertube/peertube-core-utils'
|
||||||
import { VideoResolution } from '@peertube/peertube-models'
|
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 () {
|
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)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
|
@ -183,13 +183,23 @@ function pageToStartAndCount (page: number, itemsPerPage: number) {
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
type SemVersion = { major: number, minor: number, patch: 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) {
|
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 {
|
return {
|
||||||
major: parseInt(parsed[1]),
|
major: parseInt(parsed[1]),
|
||||||
minor: parseInt(parsed[2]),
|
minor: parseInt(parsed[2]),
|
||||||
patch: parseInt(parsed[3])
|
patch: parsed[3] ? parseInt(parsed[3]) : 0
|
||||||
} as SemVersion
|
} as SemVersion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,14 @@ async function applicationExist () {
|
||||||
|
|
||||||
async function checkFFmpegVersion () {
|
async function checkFFmpegVersion () {
|
||||||
const version = await getFFmpegVersion()
|
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)) {
|
if (major < 4 || (major === 4 && minor < 1)) {
|
||||||
logger.warn('Your ffmpeg version (%s) is outdated. PeerTube supports ffmpeg >= 4.1. Please upgrade ffmpeg.', version)
|
logger.warn('Your ffmpeg version (%s) is outdated. PeerTube supports ffmpeg >= 4.1. Please upgrade ffmpeg.', version)
|
||||||
|
|
Loading…
Reference in New Issue