From edb4ffc7e0b13659d7c73b120f2c87b27e4c26a1 Mon Sep 17 00:00:00 2001 From: Felix Ableitner Date: Mon, 8 Oct 2018 09:26:04 -0500 Subject: Set bitrate limits for transcoding (fixes #638) (#1135) * Set bitrate limits for transcoding (fixes #638) * added optimization script and test, changed stuff * fix test, improve docs * re-add optimize-old-videos script * added documentation * Don't optimize videos without valid UUID, or redundancy videos * move getUUIDFromFilename * fix tests? * update torrent and file size, some more fixes/improvements * use higher bitrate for high fps video, adjust bitrates * add test video * don't throw error if resolution is undefined * generate test fixture on the fly * use random noise video for bitrate test, add promise * shorten test video to avoid timeout * use existing function to optimize video * various fixes * increase test timeout * limit test fixture size, add link * test fixes * add await * more test fixes, add -b:v parameter * replace ffmpeg wiki link * fix ffmpeg params * fix unit test * add test fixture to .gitgnore * add video transcoding fps model * add missing file --- server/tests/api/videos/video-transcoder.ts | 62 +++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 4 deletions(-) (limited to 'server/tests/api/videos') diff --git a/server/tests/api/videos/video-transcoder.ts b/server/tests/api/videos/video-transcoder.ts index 0f83d4d57..ec554ed19 100644 --- a/server/tests/api/videos/video-transcoder.ts +++ b/server/tests/api/videos/video-transcoder.ts @@ -4,8 +4,8 @@ import * as chai from 'chai' import 'mocha' import { omit } from 'lodash' import * as ffmpeg from 'fluent-ffmpeg' -import { VideoDetails, VideoState } from '../../../../shared/models/videos' -import { getVideoFileFPS, audio } from '../../../helpers/ffmpeg-utils' +import { VideoDetails, VideoState, getMaxBitrate, VideoResolution } from '../../../../shared/models/videos' +import { getVideoFileFPS, audio, getVideoFileBitrate, getVideoFileResolution } from '../../../helpers/ffmpeg-utils' import { buildAbsoluteFixturePath, doubleFollow, @@ -20,8 +20,10 @@ import { uploadVideo, webtorrentAdd } from '../../utils' -import { join } from 'path' +import { join, basename } from 'path' import { waitJobs } from '../../utils/server/jobs' +import { remove } from 'fs-extra' +import { VIDEO_TRANSCODING_FPS } from '../../../../server/initializers/constants' const expect = chai.expect @@ -228,7 +230,7 @@ describe('Test video transcoding', function () { } }) - it('Should wait transcoding before publishing the video', async function () { + it('Should wait for transcoding before publishing the video', async function () { this.timeout(80000) { @@ -281,7 +283,59 @@ describe('Test video transcoding', function () { } }) + const tempFixturePath = buildAbsoluteFixturePath('video_high_bitrate_1080p.mp4') + it('Should respect maximum bitrate values', async function () { + this.timeout(160000) + + { + // 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 + await new Promise(async (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) + .run() + }) + + const bitrate = await getVideoFileBitrate(tempFixturePath) + expect(bitrate).to.be.above(getMaxBitrate(VideoResolution.H_1080P, 60, VIDEO_TRANSCODING_FPS)) + + const videoAttributes = { + name: 'high bitrate video', + description: 'high bitrate video', + fixture: basename(tempFixturePath) + } + + await uploadVideo(servers[1].url, servers[1].accessToken, videoAttributes) + + await waitJobs(servers) + + for (const server of servers) { + const res = await getVideosList(server.url) + + const video = res.body.data.find(v => v.name === videoAttributes.name) + + for (const resolution of ['240', '360', '480', '720', '1080']) { + const path = join(root(), 'test2', 'videos', video.uuid + '-' + resolution + '.mp4') + const bitrate = await getVideoFileBitrate(path) + const fps = await getVideoFileFPS(path) + const resolution2 = await getVideoFileResolution(path) + + expect(resolution2.videoFileResolution.toString()).to.equal(resolution) + expect(bitrate).to.be.below(getMaxBitrate(resolution2.videoFileResolution, fps, VIDEO_TRANSCODING_FPS)) + } + } + } + }) + after(async function () { + remove(tempFixturePath) killallServers(servers) }) }) -- cgit v1.2.3