aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--server/helpers/ffmpeg-utils.ts7
-rw-r--r--server/tests/api/videos/video-transcoder.ts37
-rw-r--r--server/tests/fixtures/low-bitrate.mp4bin0 -> 43850 bytes
-rw-r--r--shared/extra-utils/miscs/miscs.ts9
-rw-r--r--shared/extra-utils/server/servers.ts9
5 files changed, 59 insertions, 3 deletions
diff --git a/server/helpers/ffmpeg-utils.ts b/server/helpers/ffmpeg-utils.ts
index 1d610eff2..c8d6969ff 100644
--- a/server/helpers/ffmpeg-utils.ts
+++ b/server/helpers/ffmpeg-utils.ts
@@ -674,7 +674,12 @@ async function presetH264 (command: ffmpeg.FfmpegCommand, input: string, resolut
674 // Constrained Encoding (VBV) 674 // Constrained Encoding (VBV)
675 // https://slhck.info/video/2017/03/01/rate-control.html 675 // https://slhck.info/video/2017/03/01/rate-control.html
676 // https://trac.ffmpeg.org/wiki/Limiting%20the%20output%20bitrate 676 // https://trac.ffmpeg.org/wiki/Limiting%20the%20output%20bitrate
677 const targetBitrate = getTargetBitrate(resolution, fps, VIDEO_TRANSCODING_FPS) 677 let targetBitrate = getTargetBitrate(resolution, fps, VIDEO_TRANSCODING_FPS)
678
679 // Don't transcode to an higher bitrate than the original file
680 const fileBitrate = await getVideoFileBitrate(input)
681 targetBitrate = Math.min(targetBitrate, fileBitrate)
682
678 localCommand = localCommand.outputOptions([ `-maxrate ${targetBitrate}`, `-bufsize ${targetBitrate * 2}` ]) 683 localCommand = localCommand.outputOptions([ `-maxrate ${targetBitrate}`, `-bufsize ${targetBitrate * 2}` ])
679 684
680 // Keyframe interval of 2 seconds for faster seeking and resolution switching. 685 // Keyframe interval of 2 seconds for faster seeking and resolution switching.
diff --git a/server/tests/api/videos/video-transcoder.ts b/server/tests/api/videos/video-transcoder.ts
index a1959e1a9..a3d7b8707 100644
--- a/server/tests/api/videos/video-transcoder.ts
+++ b/server/tests/api/videos/video-transcoder.ts
@@ -20,6 +20,7 @@ import {
20 generateHighBitrateVideo, 20 generateHighBitrateVideo,
21 generateVideoWithFramerate, 21 generateVideoWithFramerate,
22 getMyVideos, 22 getMyVideos,
23 getServerFileSize,
23 getVideo, 24 getVideo,
24 getVideoFileMetadataUrl, 25 getVideoFileMetadataUrl,
25 getVideosList, 26 getVideosList,
@@ -27,6 +28,7 @@ import {
27 root, 28 root,
28 ServerInfo, 29 ServerInfo,
29 setAccessTokensToServers, 30 setAccessTokensToServers,
31 updateCustomSubConfig,
30 uploadVideo, uploadVideoAndGetId, 32 uploadVideo, uploadVideoAndGetId,
31 waitJobs, 33 waitJobs,
32 webtorrentAdd 34 webtorrentAdd
@@ -468,6 +470,41 @@ describe('Test video transcoding', function () {
468 } 470 }
469 }) 471 })
470 472
473 it('Should not transcode to an higher bitrate than the original file', async function () {
474 this.timeout(160000)
475
476 const config = {
477 transcoding: {
478 enabled: true,
479 resolutions: {
480 '240p': true,
481 '360p': true,
482 '480p': true,
483 '720p': true,
484 '1080p': true
485 },
486 webtorrent: { enabled: true },
487 hls: { enabled: true }
488 }
489 }
490 await updateCustomSubConfig(servers[1].url, servers[1].accessToken, config)
491
492 const videoAttributes = {
493 name: 'low bitrate',
494 fixture: 'low-bitrate.mp4'
495 }
496
497 const resUpload = await uploadVideo(servers[1].url, servers[1].accessToken, videoAttributes)
498 const videoUUID = resUpload.body.video.uuid
499
500 await waitJobs(servers)
501
502 const resolutions = [ 240, 360, 480, 720, 1080 ]
503 for (const r of resolutions) {
504 expect(await getServerFileSize(servers[1], `videos/${videoUUID}-${r}.mp4`)).to.be.below(43)
505 }
506 })
507
471 it('Should provide valid ffprobe data', async function () { 508 it('Should provide valid ffprobe data', async function () {
472 this.timeout(160000) 509 this.timeout(160000)
473 510
diff --git a/server/tests/fixtures/low-bitrate.mp4 b/server/tests/fixtures/low-bitrate.mp4
new file mode 100644
index 000000000..69004eccc
--- /dev/null
+++ b/server/tests/fixtures/low-bitrate.mp4
Binary files differ
diff --git a/shared/extra-utils/miscs/miscs.ts b/shared/extra-utils/miscs/miscs.ts
index dfd6e28cb..3c8191ae8 100644
--- a/shared/extra-utils/miscs/miscs.ts
+++ b/shared/extra-utils/miscs/miscs.ts
@@ -4,7 +4,7 @@ import * as chai from 'chai'
4import { basename, dirname, isAbsolute, join, resolve } from 'path' 4import { basename, dirname, isAbsolute, join, resolve } from 'path'
5import * as request from 'supertest' 5import * as request from 'supertest'
6import * as WebTorrent from 'webtorrent' 6import * as WebTorrent from 'webtorrent'
7import { ensureDir, pathExists, readFile } from 'fs-extra' 7import { ensureDir, pathExists, readFile, stat } from 'fs-extra'
8import * as ffmpeg from 'fluent-ffmpeg' 8import * as ffmpeg from 'fluent-ffmpeg'
9 9
10const expect = chai.expect 10const expect = chai.expect
@@ -130,6 +130,12 @@ async function generateVideoWithFramerate (fps = 60) {
130 return tempFixturePath 130 return tempFixturePath
131} 131}
132 132
133async function getFileSize (path: string) {
134 const stats = await stat(path)
135
136 return stats.size
137}
138
133// --------------------------------------------------------------------------- 139// ---------------------------------------------------------------------------
134 140
135export { 141export {
@@ -138,6 +144,7 @@ export {
138 areHttpImportTestsDisabled, 144 areHttpImportTestsDisabled,
139 buildServerDirectory, 145 buildServerDirectory,
140 webtorrentAdd, 146 webtorrentAdd,
147 getFileSize,
141 immutableAssign, 148 immutableAssign,
142 testImage, 149 testImage,
143 buildAbsoluteFixturePath, 150 buildAbsoluteFixturePath,
diff --git a/shared/extra-utils/server/servers.ts b/shared/extra-utils/server/servers.ts
index 6140cebb5..a647b0eb4 100644
--- a/shared/extra-utils/server/servers.ts
+++ b/shared/extra-utils/server/servers.ts
@@ -6,7 +6,7 @@ import { copy, pathExists, readdir, readFile, remove } from 'fs-extra'
6import { join } from 'path' 6import { join } from 'path'
7import { randomInt } from '../../core-utils/miscs/miscs' 7import { randomInt } from '../../core-utils/miscs/miscs'
8import { VideoChannel } from '../../models/videos' 8import { VideoChannel } from '../../models/videos'
9import { root, wait } from '../miscs/miscs' 9import { getFileSize, root, wait } from '../miscs/miscs'
10 10
11interface ServerInfo { 11interface ServerInfo {
12 app: ChildProcess 12 app: ChildProcess
@@ -318,11 +318,18 @@ async function waitUntilLog (server: ServerInfo, str: string, count = 1, strictC
318 } 318 }
319} 319}
320 320
321async function getServerFileSize (server: ServerInfo, subPath: string) {
322 const path = join(root(), 'test' + server.internalServerNumber, subPath)
323
324 return getFileSize(path)
325}
326
321// --------------------------------------------------------------------------- 327// ---------------------------------------------------------------------------
322 328
323export { 329export {
324 checkDirectoryIsEmpty, 330 checkDirectoryIsEmpty,
325 checkTmpIsEmpty, 331 checkTmpIsEmpty,
332 getServerFileSize,
326 ServerInfo, 333 ServerInfo,
327 parallelTests, 334 parallelTests,
328 cleanupTests, 335 cleanupTests,