2021-08-06 07:35:25 -04:00
|
|
|
import { expect } from 'chai'
|
2021-08-27 08:32:44 -04:00
|
|
|
import ffmpeg from 'fluent-ffmpeg'
|
2021-07-13 03:43:59 -04:00
|
|
|
import { ensureDir, pathExists } from 'fs-extra'
|
|
|
|
import { dirname } from 'path'
|
2021-08-06 07:35:25 -04:00
|
|
|
import { getVideoFileBitrate, getVideoFileFPS, getVideoFileResolution } from '@server/helpers/ffprobe-utils'
|
|
|
|
import { getMaxBitrate } from '@shared/core-utils'
|
2021-07-13 03:43:59 -04:00
|
|
|
import { buildAbsoluteFixturePath } from './tests'
|
|
|
|
|
2021-08-06 07:35:25 -04:00
|
|
|
async function ensureHasTooBigBitrate (fixturePath: string) {
|
|
|
|
const bitrate = await getVideoFileBitrate(fixturePath)
|
|
|
|
const dataResolution = await getVideoFileResolution(fixturePath)
|
|
|
|
const fps = await getVideoFileFPS(fixturePath)
|
|
|
|
|
|
|
|
const maxBitrate = getMaxBitrate({ ...dataResolution, fps })
|
|
|
|
expect(bitrate).to.be.above(maxBitrate)
|
|
|
|
}
|
|
|
|
|
2021-07-13 03:43:59 -04:00
|
|
|
async function generateHighBitrateVideo () {
|
|
|
|
const tempFixturePath = buildAbsoluteFixturePath('video_high_bitrate_1080p.mp4', true)
|
|
|
|
|
|
|
|
await ensureDir(dirname(tempFixturePath))
|
|
|
|
|
|
|
|
const exists = await pathExists(tempFixturePath)
|
|
|
|
if (!exists) {
|
|
|
|
console.log('Generating high bitrate video.')
|
|
|
|
|
|
|
|
// Generate a random, high bitrate video on the fly, so we don't have to include
|
|
|
|
// a large file in the repo. The video needs to have a certain minimum length so
|
|
|
|
// that FFmpeg properly applies bitrate limits.
|
|
|
|
// https://stackoverflow.com/a/15795112
|
|
|
|
return new Promise<string>((res, rej) => {
|
|
|
|
ffmpeg()
|
|
|
|
.outputOptions([ '-f rawvideo', '-video_size 1920x1080', '-i /dev/urandom' ])
|
|
|
|
.outputOptions([ '-ac 2', '-f s16le', '-i /dev/urandom', '-t 10' ])
|
|
|
|
.outputOptions([ '-maxrate 10M', '-bufsize 10M' ])
|
|
|
|
.output(tempFixturePath)
|
|
|
|
.on('error', rej)
|
|
|
|
.on('end', () => res(tempFixturePath))
|
|
|
|
.run()
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2021-08-06 07:35:25 -04:00
|
|
|
await ensureHasTooBigBitrate(tempFixturePath)
|
|
|
|
|
2021-07-13 03:43:59 -04:00
|
|
|
return tempFixturePath
|
|
|
|
}
|
|
|
|
|
|
|
|
async function generateVideoWithFramerate (fps = 60) {
|
|
|
|
const tempFixturePath = buildAbsoluteFixturePath(`video_${fps}fps.mp4`, true)
|
|
|
|
|
|
|
|
await ensureDir(dirname(tempFixturePath))
|
|
|
|
|
|
|
|
const exists = await pathExists(tempFixturePath)
|
|
|
|
if (!exists) {
|
|
|
|
console.log('Generating video with framerate %d.', fps)
|
|
|
|
|
|
|
|
return new Promise<string>((res, rej) => {
|
|
|
|
ffmpeg()
|
|
|
|
.outputOptions([ '-f rawvideo', '-video_size 1280x720', '-i /dev/urandom' ])
|
|
|
|
.outputOptions([ '-ac 2', '-f s16le', '-i /dev/urandom', '-t 10' ])
|
|
|
|
.outputOptions([ `-r ${fps}` ])
|
|
|
|
.output(tempFixturePath)
|
|
|
|
.on('error', rej)
|
|
|
|
.on('end', () => res(tempFixturePath))
|
|
|
|
.run()
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
return tempFixturePath
|
|
|
|
}
|
|
|
|
|
|
|
|
export {
|
|
|
|
generateHighBitrateVideo,
|
|
|
|
generateVideoWithFramerate
|
|
|
|
}
|