diff options
-rw-r--r-- | .travis.yml | 5 | ||||
-rw-r--r-- | server/tests/api/videos/video-transcoder.ts | 79 | ||||
-rw-r--r-- | server/tests/utils/miscs/miscs.ts | 4 | ||||
-rw-r--r-- | shared/models/videos/video-resolution.enum.ts | 16 |
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 | ||
17 | cache: yarn | 17 | cache: |
18 | directories: | ||
19 | - $HOME/.cache/yarn | ||
20 | - $HOME/fixtures | ||
18 | 21 | ||
19 | sudo: false | 22 | sudo: 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' | |||
4 | import 'mocha' | 4 | import 'mocha' |
5 | import { omit } from 'lodash' | 5 | import { omit } from 'lodash' |
6 | import * as ffmpeg from 'fluent-ffmpeg' | 6 | import * as ffmpeg from 'fluent-ffmpeg' |
7 | import { VideoDetails, VideoState, getMaxBitrate, VideoResolution } from '../../../../shared/models/videos' | 7 | import { getMaxBitrate, VideoDetails, VideoResolution, VideoState } from '../../../../shared/models/videos' |
8 | import { getVideoFileFPS, audio, getVideoFileBitrate, getVideoFileResolution } from '../../../helpers/ffmpeg-utils' | 8 | import { audio, getVideoFileBitrate, getVideoFileFPS, getVideoFileResolution } from '../../../helpers/ffmpeg-utils' |
9 | import { | 9 | import { |
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' |
23 | import { join, basename } from 'path' | 23 | import { join } from 'path' |
24 | import { waitJobs } from '../../utils/server/jobs' | 24 | import { waitJobs } from '../../utils/server/jobs' |
25 | import { remove } from 'fs-extra' | 25 | import { pathExists } from 'fs-extra' |
26 | import { VIDEO_TRANSCODING_FPS } from '../../../../server/initializers/constants' | 26 | import { VIDEO_TRANSCODING_FPS } from '../../../../server/initializers/constants' |
27 | 27 | ||
28 | const expect = chai.expect | 28 | const 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 | ||
54 | function buildAbsoluteFixturePath (path: string) { | 54 | function 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 | ||