1
0
Fork 0
mirror of https://github.com/Chocobozzz/PeerTube.git synced 2025-10-04 02:09:37 +02:00

Fix splitting audio/video of existing videos

This commit is contained in:
Chocobozzz 2024-09-25 13:49:21 +02:00
parent 7e9fba3ae5
commit 093a9bf749
No known key found for this signature in database
GPG key ID: 583A612D890159BE
5 changed files with 313 additions and 163 deletions

View file

@ -127,8 +127,7 @@ export abstract class AbstractJobBuilder <P> {
}
await this.createJobs({
parent: mergeOrOptimizePayload,
children,
payloads: [ [ mergeOrOptimizePayload ], ...children ],
user,
video
})
@ -151,19 +150,24 @@ export abstract class AbstractJobBuilder <P> {
const inputFPS = video.getMaxFPS()
const children = childrenResolutions.map(resolution => {
const fps = computeOutputFPS({ inputFPS, resolution, isOriginResolution: maxResolution === resolution, type: 'vod' })
const children = childrenResolutions
.map(resolution => {
const fps = computeOutputFPS({ inputFPS, resolution, isOriginResolution: maxResolution === resolution, type: 'vod' })
if (transcodingType === 'hls') {
return this.buildHLSJobPayload({ video, resolution, fps, isNewVideo, separatedAudio })
}
if (transcodingType === 'hls') {
// We'll generate audio resolution in a parent job
if (resolution === VideoResolution.H_NOVIDEO && separatedAudio) return undefined
if (transcodingType === 'webtorrent' || transcodingType === 'web-video') {
return this.buildWebVideoJobPayload({ video, resolution, fps, isNewVideo })
}
return this.buildHLSJobPayload({ video, resolution, fps, isNewVideo, separatedAudio })
}
throw new Error('Unknown transcoding type')
})
if (transcodingType === 'webtorrent' || transcodingType === 'web-video') {
return this.buildWebVideoJobPayload({ video, resolution, fps, isNewVideo })
}
throw new Error('Unknown transcoding type')
})
.filter(r => !!r)
const fps = computeOutputFPS({ inputFPS, resolution: maxResolution, isOriginResolution: true, type: 'vod' })
@ -171,9 +175,17 @@ export abstract class AbstractJobBuilder <P> {
? this.buildHLSJobPayload({ video, resolution: maxResolution, fps, isNewVideo, separatedAudio })
: this.buildWebVideoJobPayload({ video, resolution: maxResolution, fps, isNewVideo })
// Process the last resolution after the other ones to prevent concurrency issue
// Because low resolutions use the biggest one as ffmpeg input
await this.createJobs({ video, parent, children: [ children ], user: null })
// Low resolutions use the biggest one as ffmpeg input so we need to process max resolution (with audio) independently
const payloads: [ [ P ], ...(P[][]) ] = [ [ parent ] ]
// Process audio first to not override the max resolution where the audio stream will be removed
if (transcodingType === 'hls' && separatedAudio) {
payloads.unshift([ this.buildHLSJobPayload({ video, resolution: VideoResolution.H_NOVIDEO, fps, isNewVideo, separatedAudio }) ])
}
if (children && children.length !== 0) payloads.push(children)
await this.createJobs({ video, payloads, user: null })
}
private async buildLowerResolutionJobPayloads (options: {
@ -247,8 +259,7 @@ export abstract class AbstractJobBuilder <P> {
protected abstract createJobs (options: {
video: MVideoFullLight
parent: P
children: P[][]
payloads: [ [ P ], ...(P[][]) ] // Array of sequential jobs to create that depend on parent job
user: MUserId | null
}): Promise<void>

View file

@ -22,14 +22,16 @@ export class TranscodingJobQueueBuilder extends AbstractJobBuilder <Payload> {
protected async createJobs (options: {
video: MVideo
parent: Payload
children: Payload[][]
payloads: [ [ Payload ], ...(Payload[][]) ] // Array of sequential jobs to create that depend on parent job
user: MUserId | null
}): Promise<void> {
const { video, parent, children, user } = options
const { video, payloads, user } = options
const nextTranscodingSequentialJobs = await Bluebird.mapSeries(children, payloads => {
return Bluebird.mapSeries(payloads, payload => {
const parent = payloads[0][0]
payloads.shift()
const nextTranscodingSequentialJobs = await Bluebird.mapSeries(payloads, p => {
return Bluebird.mapSeries(p, payload => {
return this.buildTranscodingJob({ payload, user })
})
})
@ -42,9 +44,9 @@ export class TranscodingJobQueueBuilder extends AbstractJobBuilder <Payload> {
}
}
const mergeOrOptimizeJob = await this.buildTranscodingJob({ payload: parent, user, hasChildren: !!children.length })
const parentJob = await this.buildTranscodingJob({ payload: parent, user, hasChildren: payloads.length !== 0 })
await JobQueue.Instance.createSequentialJobFlow(mergeOrOptimizeJob, transcodingJobBuilderJob)
await JobQueue.Instance.createSequentialJobFlow(parentJob, transcodingJobBuilderJob)
// transcoding-job-builder job will increase pendingTranscode
await VideoJobInfoModel.increaseOrCreate(video.uuid, 'pendingTranscode')

View file

@ -31,15 +31,17 @@ export class TranscodingRunnerJobBuilder extends AbstractJobBuilder <Payload> {
protected async createJobs (options: {
video: MVideo
parent: Payload
children: Payload[][] // Array of sequential jobs to create that depend on parent job
payloads: [ [ Payload ], ...(Payload[][]) ] // Array of sequential jobs to create that depend on parent job
user: MUserId | null
}): Promise<void> {
const { parent, children, user } = options
const { payloads, user } = options
const parent = payloads[0][0]
payloads.shift()
const parentJob = await this.createJob({ payload: parent, user })
for (const parallelPayloads of children) {
for (const parallelPayloads of payloads) {
let lastJob = parentJob
for (const parallelPayload of parallelPayloads) {