Do not transcode to an higher bitrate
Thanks bkil https://github.com/bkil
This commit is contained in:
parent
da2516fde1
commit
d218e7de94
|
@ -674,7 +674,12 @@ async function presetH264 (command: ffmpeg.FfmpegCommand, input: string, resolut
|
||||||
// Constrained Encoding (VBV)
|
// Constrained Encoding (VBV)
|
||||||
// https://slhck.info/video/2017/03/01/rate-control.html
|
// https://slhck.info/video/2017/03/01/rate-control.html
|
||||||
// https://trac.ffmpeg.org/wiki/Limiting%20the%20output%20bitrate
|
// 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}` ])
|
localCommand = localCommand.outputOptions([ `-maxrate ${targetBitrate}`, `-bufsize ${targetBitrate * 2}` ])
|
||||||
|
|
||||||
// Keyframe interval of 2 seconds for faster seeking and resolution switching.
|
// Keyframe interval of 2 seconds for faster seeking and resolution switching.
|
||||||
|
|
|
@ -20,6 +20,7 @@ import {
|
||||||
generateHighBitrateVideo,
|
generateHighBitrateVideo,
|
||||||
generateVideoWithFramerate,
|
generateVideoWithFramerate,
|
||||||
getMyVideos,
|
getMyVideos,
|
||||||
|
getServerFileSize,
|
||||||
getVideo,
|
getVideo,
|
||||||
getVideoFileMetadataUrl,
|
getVideoFileMetadataUrl,
|
||||||
getVideosList,
|
getVideosList,
|
||||||
|
@ -27,6 +28,7 @@ import {
|
||||||
root,
|
root,
|
||||||
ServerInfo,
|
ServerInfo,
|
||||||
setAccessTokensToServers,
|
setAccessTokensToServers,
|
||||||
|
updateCustomSubConfig,
|
||||||
uploadVideo, uploadVideoAndGetId,
|
uploadVideo, uploadVideoAndGetId,
|
||||||
waitJobs,
|
waitJobs,
|
||||||
webtorrentAdd
|
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 () {
|
it('Should provide valid ffprobe data', async function () {
|
||||||
this.timeout(160000)
|
this.timeout(160000)
|
||||||
|
|
||||||
|
|
BIN
server/tests/fixtures/low-bitrate.mp4
vendored
Normal file
BIN
server/tests/fixtures/low-bitrate.mp4
vendored
Normal file
Binary file not shown.
|
@ -4,7 +4,7 @@ import * as chai from 'chai'
|
||||||
import { basename, dirname, isAbsolute, join, resolve } from 'path'
|
import { basename, dirname, isAbsolute, join, resolve } from 'path'
|
||||||
import * as request from 'supertest'
|
import * as request from 'supertest'
|
||||||
import * as WebTorrent from 'webtorrent'
|
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'
|
import * as ffmpeg from 'fluent-ffmpeg'
|
||||||
|
|
||||||
const expect = chai.expect
|
const expect = chai.expect
|
||||||
|
@ -130,6 +130,12 @@ async function generateVideoWithFramerate (fps = 60) {
|
||||||
return tempFixturePath
|
return tempFixturePath
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getFileSize (path: string) {
|
||||||
|
const stats = await stat(path)
|
||||||
|
|
||||||
|
return stats.size
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
@ -138,6 +144,7 @@ export {
|
||||||
areHttpImportTestsDisabled,
|
areHttpImportTestsDisabled,
|
||||||
buildServerDirectory,
|
buildServerDirectory,
|
||||||
webtorrentAdd,
|
webtorrentAdd,
|
||||||
|
getFileSize,
|
||||||
immutableAssign,
|
immutableAssign,
|
||||||
testImage,
|
testImage,
|
||||||
buildAbsoluteFixturePath,
|
buildAbsoluteFixturePath,
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { copy, pathExists, readdir, readFile, remove } from 'fs-extra'
|
||||||
import { join } from 'path'
|
import { join } from 'path'
|
||||||
import { randomInt } from '../../core-utils/miscs/miscs'
|
import { randomInt } from '../../core-utils/miscs/miscs'
|
||||||
import { VideoChannel } from '../../models/videos'
|
import { VideoChannel } from '../../models/videos'
|
||||||
import { root, wait } from '../miscs/miscs'
|
import { getFileSize, root, wait } from '../miscs/miscs'
|
||||||
|
|
||||||
interface ServerInfo {
|
interface ServerInfo {
|
||||||
app: ChildProcess
|
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 {
|
export {
|
||||||
checkDirectoryIsEmpty,
|
checkDirectoryIsEmpty,
|
||||||
checkTmpIsEmpty,
|
checkTmpIsEmpty,
|
||||||
|
getServerFileSize,
|
||||||
ServerInfo,
|
ServerInfo,
|
||||||
parallelTests,
|
parallelTests,
|
||||||
cleanupTests,
|
cleanupTests,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user