mirror of https://github.com/Chocobozzz/PeerTube
Fix duplicated resolutions when capping fps
parent
8e644dedb2
commit
baefe61cff
|
@ -64,6 +64,16 @@ describe('Test video transcoding limits', function () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateMaxFPS (value: number) {
|
||||||
|
return servers[1].config.updateExistingConfig({
|
||||||
|
newConfig: {
|
||||||
|
transcoding: {
|
||||||
|
fps: { max: value }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
it('Should transcode a 60 FPS video', async function () {
|
it('Should transcode a 60 FPS video', async function () {
|
||||||
this.timeout(60_000)
|
this.timeout(60_000)
|
||||||
|
|
||||||
|
@ -117,25 +127,37 @@ describe('Test video transcoding limits', function () {
|
||||||
it('Should configure max FPS', async function () {
|
it('Should configure max FPS', async function () {
|
||||||
this.timeout(120_000)
|
this.timeout(120_000)
|
||||||
|
|
||||||
const update = (value: number) => {
|
await updateMaxFPS(15)
|
||||||
return servers[1].config.updateExistingConfig({
|
|
||||||
newConfig: {
|
|
||||||
transcoding: {
|
|
||||||
fps: { max: value }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
await update(15)
|
|
||||||
|
|
||||||
const attributes = { name: 'capped 15fps', fixture: '60fps_720p_small.mp4' }
|
const attributes = { name: 'capped 15fps', fixture: '60fps_720p_small.mp4' }
|
||||||
const { uuid } = await servers[1].videos.upload({ attributes })
|
const { uuid } = await servers[1].videos.upload({ attributes })
|
||||||
|
|
||||||
await waitJobs(servers)
|
await waitJobs(servers)
|
||||||
await testFPS(uuid, 15, 15)
|
await testFPS(uuid, 15, 15)
|
||||||
|
})
|
||||||
|
|
||||||
await update(60)
|
it('Should not duplicate resolution on re-transcoding', async function () {
|
||||||
|
this.timeout(120_000)
|
||||||
|
|
||||||
|
await updateMaxFPS(50)
|
||||||
|
|
||||||
|
const attributes = { name: 'capped 50fps', fixture: '60fps_720p_small.mp4' }
|
||||||
|
const { uuid } = await servers[1].videos.upload({ attributes })
|
||||||
|
|
||||||
|
await waitJobs(servers)
|
||||||
|
await testFPS(uuid, 50, 25)
|
||||||
|
|
||||||
|
await servers[1].videos.runTranscoding({ transcodingType: 'web-video', videoId: uuid })
|
||||||
|
await waitJobs(servers)
|
||||||
|
|
||||||
|
const video = await servers[1].videos.get({ id: uuid })
|
||||||
|
expect(video.files.map(f => f.resolution.id)).to.deep.equal([ 720, 480, 360, 240, 144 ])
|
||||||
|
|
||||||
|
await testFPS(uuid, 50, 25)
|
||||||
|
})
|
||||||
|
|
||||||
|
after(async function () {
|
||||||
|
await updateMaxFPS(60)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { FileStorage, LiveVideoLatencyMode, LiveVideoLatencyModeType, VideoState
|
||||||
import { logger } from '@server/helpers/logger.js'
|
import { logger } from '@server/helpers/logger.js'
|
||||||
import { VIDEO_LIVE } from '@server/initializers/constants.js'
|
import { VIDEO_LIVE } from '@server/initializers/constants.js'
|
||||||
import { MStreamingPlaylist, MStreamingPlaylistVideo, MVideo } from '@server/types/models/index.js'
|
import { MStreamingPlaylist, MStreamingPlaylistVideo, MVideo } from '@server/types/models/index.js'
|
||||||
import { pathExists, remove, } from 'fs-extra/esm'
|
import { pathExists, remove } from 'fs-extra/esm'
|
||||||
import { readdir, rmdir } from 'fs/promises'
|
import { readdir, rmdir } from 'fs/promises'
|
||||||
import { basename, join } from 'path'
|
import { basename, join } from 'path'
|
||||||
import { listHLSFileKeysOf, removeHLSFileObjectStorageByFullKey, removeHLSObjectStorage } from '../object-storage/index.js'
|
import { listHLSFileKeysOf, removeHLSFileObjectStorageByFullKey, removeHLSObjectStorage } from '../object-storage/index.js'
|
||||||
|
|
|
@ -38,8 +38,6 @@ export abstract class AbstractJobBuilder <P> {
|
||||||
const probe = await ffprobePromise(videoFilePath)
|
const probe = await ffprobePromise(videoFilePath)
|
||||||
const quickTranscode = await canDoQuickTranscode(videoFilePath, CONFIG.TRANSCODING.FPS.MAX, probe)
|
const quickTranscode = await canDoQuickTranscode(videoFilePath, CONFIG.TRANSCODING.FPS.MAX, probe)
|
||||||
|
|
||||||
let inputFPS: number
|
|
||||||
|
|
||||||
let maxFPS: number
|
let maxFPS: number
|
||||||
let maxResolution: number
|
let maxResolution: number
|
||||||
|
|
||||||
|
@ -47,7 +45,7 @@ export abstract class AbstractJobBuilder <P> {
|
||||||
|
|
||||||
if (videoFile.isAudio()) {
|
if (videoFile.isAudio()) {
|
||||||
// The first transcoding job will transcode to this FPS value
|
// The first transcoding job will transcode to this FPS value
|
||||||
inputFPS = maxFPS = Math.min(DEFAULT_AUDIO_MERGE_RESOLUTION, CONFIG.TRANSCODING.FPS.MAX)
|
maxFPS = Math.min(DEFAULT_AUDIO_MERGE_RESOLUTION, CONFIG.TRANSCODING.FPS.MAX)
|
||||||
maxResolution = DEFAULT_AUDIO_RESOLUTION
|
maxResolution = DEFAULT_AUDIO_RESOLUTION
|
||||||
|
|
||||||
mergeOrOptimizePayload = this.buildMergeAudioPayload({
|
mergeOrOptimizePayload = this.buildMergeAudioPayload({
|
||||||
|
@ -58,7 +56,7 @@ export abstract class AbstractJobBuilder <P> {
|
||||||
fps: maxFPS
|
fps: maxFPS
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
inputFPS = videoFile.fps
|
const inputFPS = videoFile.fps
|
||||||
maxResolution = buildOriginalFileResolution(videoFile.resolution)
|
maxResolution = buildOriginalFileResolution(videoFile.resolution)
|
||||||
maxFPS = computeOutputFPS({ inputFPS, resolution: maxResolution, isOriginResolution: true, type: 'vod' })
|
maxFPS = computeOutputFPS({ inputFPS, resolution: maxResolution, isOriginResolution: true, type: 'vod' })
|
||||||
|
|
||||||
|
@ -116,7 +114,7 @@ export abstract class AbstractJobBuilder <P> {
|
||||||
const lowerResolutionJobPayloads = await this.buildLowerResolutionJobPayloads({
|
const lowerResolutionJobPayloads = await this.buildLowerResolutionJobPayloads({
|
||||||
video,
|
video,
|
||||||
inputVideoResolution: maxResolution,
|
inputVideoResolution: maxResolution,
|
||||||
inputVideoFPS: inputFPS,
|
inputVideoFPS: maxFPS,
|
||||||
hasAudio: videoFile.hasAudio(),
|
hasAudio: videoFile.hasAudio(),
|
||||||
isNewVideo,
|
isNewVideo,
|
||||||
hlsAudioAlreadyGenerated
|
hlsAudioAlreadyGenerated
|
||||||
|
|
Loading…
Reference in New Issue