Skip to content

Commit

Permalink
fix: handle git installation of ffmpeg
Browse files Browse the repository at this point in the history
  • Loading branch information
SethFalco authored and Chocobozzz committed Aug 18, 2023
1 parent 8e4fba9 commit 2055962
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 11 deletions.
13 changes: 6 additions & 7 deletions packages/ffmpeg/src/ffmpeg-version.ts
Original file line number Diff line number Diff line change
@@ -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) => {
Expand All @@ -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])
})
})
})
Expand Down
53 changes: 52 additions & 1 deletion packages/tests/src/server-helpers/core-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 () {

Expand Down Expand Up @@ -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)
})
})
14 changes: 12 additions & 2 deletions server/server/helpers/core-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down
9 changes: 8 additions & 1 deletion server/server/initializers/checker-after-init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit 2055962

Please sign in to comment.