]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/commitdiff
Do not transcode to an higher bitrate
authorChocobozzz <me@florianbigard.com>
Fri, 20 Nov 2020 14:06:56 +0000 (15:06 +0100)
committerChocobozzz <me@florianbigard.com>
Fri, 20 Nov 2020 14:11:31 +0000 (15:11 +0100)
Thanks bkil https://github.com/bkil

server/helpers/ffmpeg-utils.ts
server/tests/api/videos/video-transcoder.ts
server/tests/fixtures/low-bitrate.mp4 [new file with mode: 0644]
shared/extra-utils/miscs/miscs.ts
shared/extra-utils/server/servers.ts

index 1d610eff245234cb0a13f9e2223ee0ff4f0bbfce..c8d6969ffbd3bc478afcbb7a35acd85b84819a66 100644 (file)
@@ -674,7 +674,12 @@ async function presetH264 (command: ffmpeg.FfmpegCommand, input: string, resolut
     // Constrained Encoding (VBV)
     // https://slhck.info/video/2017/03/01/rate-control.html
     // https://trac.ffmpeg.org/wiki/Limiting%20the%20output%20bitrate
-    const targetBitrate = getTargetBitrate(resolution, fps, VIDEO_TRANSCODING_FPS)
+    let targetBitrate = getTargetBitrate(resolution, fps, VIDEO_TRANSCODING_FPS)
+
+    // Don't transcode to an higher bitrate than the original file
+    const fileBitrate = await getVideoFileBitrate(input)
+    targetBitrate = Math.min(targetBitrate, fileBitrate)
+
     localCommand = localCommand.outputOptions([ `-maxrate ${targetBitrate}`, `-bufsize ${targetBitrate * 2}` ])
 
     // Keyframe interval of 2 seconds for faster seeking and resolution switching.
index a1959e1a9dc8cdb70e91b2ad487df6d90552bad3..a3d7b870766090893a1c5d88415368f18780c2fe 100644 (file)
@@ -20,6 +20,7 @@ import {
   generateHighBitrateVideo,
   generateVideoWithFramerate,
   getMyVideos,
+  getServerFileSize,
   getVideo,
   getVideoFileMetadataUrl,
   getVideosList,
@@ -27,6 +28,7 @@ import {
   root,
   ServerInfo,
   setAccessTokensToServers,
+  updateCustomSubConfig,
   uploadVideo, uploadVideoAndGetId,
   waitJobs,
   webtorrentAdd
@@ -468,6 +470,41 @@ describe('Test video transcoding', function () {
     }
   })
 
+  it('Should not transcode to an higher bitrate than the original file', async function () {
+    this.timeout(160000)
+
+    const config = {
+      transcoding: {
+        enabled: true,
+        resolutions: {
+          '240p': true,
+          '360p': true,
+          '480p': true,
+          '720p': true,
+          '1080p': true
+        },
+        webtorrent: { enabled: true },
+        hls: { enabled: true }
+      }
+    }
+    await updateCustomSubConfig(servers[1].url, servers[1].accessToken, config)
+
+    const videoAttributes = {
+      name: 'low bitrate',
+      fixture: 'low-bitrate.mp4'
+    }
+
+    const resUpload = await uploadVideo(servers[1].url, servers[1].accessToken, videoAttributes)
+    const videoUUID = resUpload.body.video.uuid
+
+    await waitJobs(servers)
+
+    const resolutions = [ 240, 360, 480, 720, 1080 ]
+    for (const r of resolutions) {
+      expect(await getServerFileSize(servers[1], `videos/${videoUUID}-${r}.mp4`)).to.be.below(43)
+    }
+  })
+
   it('Should provide valid ffprobe data', async function () {
     this.timeout(160000)
 
diff --git a/server/tests/fixtures/low-bitrate.mp4 b/server/tests/fixtures/low-bitrate.mp4
new file mode 100644 (file)
index 0000000..69004ec
Binary files /dev/null and b/server/tests/fixtures/low-bitrate.mp4 differ
index dfd6e28cbeb6809ecb6cdc8b0d4218838b5b15bc..3c8191ae886a04fddb28ccb964ec2259693357af 100644 (file)
@@ -4,7 +4,7 @@ import * as chai from 'chai'
 import { basename, dirname, isAbsolute, join, resolve } from 'path'
 import * as request from 'supertest'
 import * as WebTorrent from 'webtorrent'
-import { ensureDir, pathExists, readFile } from 'fs-extra'
+import { ensureDir, pathExists, readFile, stat } from 'fs-extra'
 import * as ffmpeg from 'fluent-ffmpeg'
 
 const expect = chai.expect
@@ -130,6 +130,12 @@ async function generateVideoWithFramerate (fps = 60) {
   return tempFixturePath
 }
 
+async function getFileSize (path: string) {
+  const stats = await stat(path)
+
+  return stats.size
+}
+
 // ---------------------------------------------------------------------------
 
 export {
@@ -138,6 +144,7 @@ export {
   areHttpImportTestsDisabled,
   buildServerDirectory,
   webtorrentAdd,
+  getFileSize,
   immutableAssign,
   testImage,
   buildAbsoluteFixturePath,
index 6140cebb5d067f417eb0ba68043c8d5ba22973f3..a647b0eb4e21129b2f7e7cc39d7f2c987ee68d68 100644 (file)
@@ -6,7 +6,7 @@ import { copy, pathExists, readdir, readFile, remove } from 'fs-extra'
 import { join } from 'path'
 import { randomInt } from '../../core-utils/miscs/miscs'
 import { VideoChannel } from '../../models/videos'
-import { root, wait } from '../miscs/miscs'
+import { getFileSize, root, wait } from '../miscs/miscs'
 
 interface ServerInfo {
   app: ChildProcess
@@ -318,11 +318,18 @@ async function waitUntilLog (server: ServerInfo, str: string, count = 1, strictC
   }
 }
 
+async function getServerFileSize (server: ServerInfo, subPath: string) {
+  const path = join(root(), 'test' + server.internalServerNumber, subPath)
+
+  return getFileSize(path)
+}
+
 // ---------------------------------------------------------------------------
 
 export {
   checkDirectoryIsEmpty,
   checkTmpIsEmpty,
+  getServerFileSize,
   ServerInfo,
   parallelTests,
   cleanupTests,