aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--.travis.yml5
-rw-r--r--server/tests/api/videos/video-transcoder.ts79
-rw-r--r--server/tests/utils/miscs/miscs.ts4
-rw-r--r--shared/models/videos/video-resolution.enum.ts16
4 files changed, 56 insertions, 48 deletions
diff --git a/.travis.yml b/.travis.yml
index 9fd54447c..7670cb7c0 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -14,7 +14,10 @@ addons:
14 - g++-4.9 14 - g++-4.9
15 postgresql: "9.4" 15 postgresql: "9.4"
16 16
17cache: yarn 17cache:
18 directories:
19 - $HOME/.cache/yarn
20 - $HOME/fixtures
18 21
19sudo: false 22sudo: false
20 23
diff --git a/server/tests/api/videos/video-transcoder.ts b/server/tests/api/videos/video-transcoder.ts
index ec554ed19..0ce5197ea 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'
4import 'mocha' 4import 'mocha'
5import { omit } from 'lodash' 5import { omit } from 'lodash'
6import * as ffmpeg from 'fluent-ffmpeg' 6import * as ffmpeg from 'fluent-ffmpeg'
7import { VideoDetails, VideoState, getMaxBitrate, VideoResolution } from '../../../../shared/models/videos' 7import { getMaxBitrate, VideoDetails, VideoResolution, VideoState } from '../../../../shared/models/videos'
8import { getVideoFileFPS, audio, getVideoFileBitrate, getVideoFileResolution } from '../../../helpers/ffmpeg-utils' 8import { audio, getVideoFileBitrate, getVideoFileFPS, getVideoFileResolution } from '../../../helpers/ffmpeg-utils'
9import { 9import {
10 buildAbsoluteFixturePath, 10 buildAbsoluteFixturePath,
11 doubleFollow, 11 doubleFollow,
@@ -20,9 +20,9 @@ import {
20 uploadVideo, 20 uploadVideo,
21 webtorrentAdd 21 webtorrentAdd
22} from '../../utils' 22} from '../../utils'
23import { join, basename } from 'path' 23import { join } from 'path'
24import { waitJobs } from '../../utils/server/jobs' 24import { waitJobs } from '../../utils/server/jobs'
25import { remove } from 'fs-extra' 25import { pathExists } from 'fs-extra'
26import { VIDEO_TRANSCODING_FPS } from '../../../../server/initializers/constants' 26import { VIDEO_TRANSCODING_FPS } from '../../../../server/initializers/constants'
27 27
28const expect = chai.expect 28const expect = chai.expect
@@ -283,59 +283,62 @@ describe('Test video transcoding', function () {
283 } 283 }
284 }) 284 })
285 285
286 const tempFixturePath = buildAbsoluteFixturePath('video_high_bitrate_1080p.mp4') 286 const tempFixturePath = buildAbsoluteFixturePath('video_high_bitrate_1080p.mp4', true)
287 it('Should respect maximum bitrate values', async function () { 287 it('Should respect maximum bitrate values', async function () {
288 this.timeout(160000) 288 this.timeout(160000)
289 289
290 { 290 {
291 // Generate a random, high bitrate video on the fly, so we don't have to include 291 const exists = await pathExists(tempFixturePath)
292 // a large file in the repo. The video needs to have a certain minimum length so 292 if (!exists) {
293 // that FFmpeg properly applies bitrate limits. 293
294 // https://stackoverflow.com/a/15795112 294 // Generate a random, high bitrate video on the fly, so we don't have to include
295 await new Promise<void>(async (res, rej) => { 295 // a large file in the repo. The video needs to have a certain minimum length so
296 ffmpeg() 296 // that FFmpeg properly applies bitrate limits.
297 .outputOptions(['-f rawvideo', '-video_size 1920x1080', '-i /dev/urandom']) 297 // https://stackoverflow.com/a/15795112
298 .outputOptions(['-ac 2', '-f s16le', '-i /dev/urandom', '-t 10']) 298 await new Promise<void>(async (res, rej) => {
299 .outputOptions(['-maxrate 10M', '-bufsize 10M']) 299 ffmpeg()
300 .output(tempFixturePath) 300 .outputOptions([ '-f rawvideo', '-video_size 1920x1080', '-i /dev/urandom' ])
301 .on('error', rej) 301 .outputOptions([ '-ac 2', '-f s16le', '-i /dev/urandom', '-t 10' ])
302 .on('end', res) 302 .outputOptions([ '-maxrate 10M', '-bufsize 10M' ])
303 .run() 303 .output(tempFixturePath)
304 }) 304 .on('error', rej)
305 .on('end', res)
306 .run()
307 })
308 }
305 309
306 const bitrate = await getVideoFileBitrate(tempFixturePath) 310 const bitrate = await getVideoFileBitrate(tempFixturePath)
307 expect(bitrate).to.be.above(getMaxBitrate(VideoResolution.H_1080P, 60, VIDEO_TRANSCODING_FPS)) 311 expect(bitrate).to.be.above(getMaxBitrate(VideoResolution.H_1080P, 60, VIDEO_TRANSCODING_FPS))
312 }
308 313
309 const videoAttributes = { 314 const videoAttributes = {
310 name: 'high bitrate video', 315 name: 'high bitrate video',
311 description: 'high bitrate video', 316 description: 'high bitrate video',
312 fixture: basename(tempFixturePath) 317 fixture: tempFixturePath
313 } 318 }
314 319
315 await uploadVideo(servers[1].url, servers[1].accessToken, videoAttributes) 320 await uploadVideo(servers[1].url, servers[1].accessToken, videoAttributes)
316 321
317 await waitJobs(servers) 322 await waitJobs(servers)
318 323
319 for (const server of servers) { 324 for (const server of servers) {
320 const res = await getVideosList(server.url) 325 const res = await getVideosList(server.url)
321 326
322 const video = res.body.data.find(v => v.name === videoAttributes.name) 327 const video = res.body.data.find(v => v.name === videoAttributes.name)
323 328
324 for (const resolution of ['240', '360', '480', '720', '1080']) { 329 for (const resolution of ['240', '360', '480', '720', '1080']) {
325 const path = join(root(), 'test2', 'videos', video.uuid + '-' + resolution + '.mp4') 330 const path = join(root(), 'test2', 'videos', video.uuid + '-' + resolution + '.mp4')
326 const bitrate = await getVideoFileBitrate(path) 331 const bitrate = await getVideoFileBitrate(path)
327 const fps = await getVideoFileFPS(path) 332 const fps = await getVideoFileFPS(path)
328 const resolution2 = await getVideoFileResolution(path) 333 const resolution2 = await getVideoFileResolution(path)
329 334
330 expect(resolution2.videoFileResolution.toString()).to.equal(resolution) 335 expect(resolution2.videoFileResolution.toString()).to.equal(resolution)
331 expect(bitrate).to.be.below(getMaxBitrate(resolution2.videoFileResolution, fps, VIDEO_TRANSCODING_FPS)) 336 expect(bitrate).to.be.below(getMaxBitrate(resolution2.videoFileResolution, fps, VIDEO_TRANSCODING_FPS))
332 }
333 } 337 }
334 } 338 }
335 }) 339 })
336 340
337 after(async function () { 341 after(async function () {
338 remove(tempFixturePath)
339 killallServers(servers) 342 killallServers(servers)
340 }) 343 })
341}) 344})
diff --git a/server/tests/utils/miscs/miscs.ts b/server/tests/utils/miscs/miscs.ts
index b2f80e9b1..d20fa96b8 100644
--- a/server/tests/utils/miscs/miscs.ts
+++ b/server/tests/utils/miscs/miscs.ts
@@ -51,11 +51,13 @@ async function testImage (url: string, imageName: string, imagePath: string, ext
51 expect(data.length).to.be.below(maxLength) 51 expect(data.length).to.be.below(maxLength)
52} 52}
53 53
54function buildAbsoluteFixturePath (path: string) { 54function buildAbsoluteFixturePath (path: string, customTravisPath = false) {
55 if (isAbsolute(path)) { 55 if (isAbsolute(path)) {
56 return path 56 return path
57 } 57 }
58 58
59 if (customTravisPath && process.env.TRAVIS) return join(process.env.HOME, 'fixtures', path)
60
59 return join(__dirname, '..', '..', 'fixtures', path) 61 return join(__dirname, '..', '..', 'fixtures', path)
60} 62}
61 63
diff --git a/shared/models/videos/video-resolution.enum.ts b/shared/models/videos/video-resolution.enum.ts
index 3c52bbf98..e40e5b58b 100644
--- a/shared/models/videos/video-resolution.enum.ts
+++ b/shared/models/videos/video-resolution.enum.ts
@@ -34,22 +34,22 @@ export function getTargetBitrate (resolution: VideoResolution, fps: number,
34 // quality according to Google Live Encoder: 2,250 - 6,000 Kbps 34 // quality according to Google Live Encoder: 2,250 - 6,000 Kbps
35 // Quality according to YouTube Video Info: 2634 Kbps 35 // Quality according to YouTube Video Info: 2634 Kbps
36 return 2600 * 1000 36 return 2600 * 1000
37 } else {
38 // quality according to Google Live Encoder: 1,500 - 4,000 Kbps
39 // Quality according to YouTube Video Info: 1752 Kbps
40 return 1750 * 1000
41 } 37 }
38
39 // quality according to Google Live Encoder: 1,500 - 4,000 Kbps
40 // Quality according to YouTube Video Info: 1752 Kbps
41 return 1750 * 1000
42 case VideoResolution.H_1080P: // fallthrough 42 case VideoResolution.H_1080P: // fallthrough
43 default: 43 default:
44 if (fps === fpsTranscodingConstants.MAX) { 44 if (fps === fpsTranscodingConstants.MAX) {
45 // quality according to Google Live Encoder: 3000 - 6000 Kbps 45 // quality according to Google Live Encoder: 3000 - 6000 Kbps
46 // Quality according to YouTube Video Info: 4387 Kbps 46 // Quality according to YouTube Video Info: 4387 Kbps
47 return 4400 * 1000 47 return 4400 * 1000
48 } else {
49 // quality according to Google Live Encoder: 3000 - 6000 Kbps
50 // Quality according to YouTube Video Info: 3277 Kbps
51 return 3300 * 1000
52 } 48 }
49
50 // quality according to Google Live Encoder: 3000 - 6000 Kbps
51 // Quality according to YouTube Video Info: 3277 Kbps
52 return 3300 * 1000
53 } 53 }
54} 54}
55 55