Don't publish video before audio stream

This commit is contained in:
Chocobozzz 2025-01-31 07:04:34 +01:00
parent f099067e9d
commit 23cd92430f
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
6 changed files with 47 additions and 8 deletions

View File

@ -32,7 +32,6 @@ async function waitJobs (
if (process.env.DEBUG) console.log(`${new Date().toISOString()} - Checking ${server.url}`) if (process.env.DEBUG) console.log(`${new Date().toISOString()} - Checking ${server.url}`)
for (const state of states) { for (const state of states) {
const jobPromise = server.jobs.list({ const jobPromise = server.jobs.list({
state, state,
start: 0, start: 0,

View File

@ -187,6 +187,9 @@ describe('Test resumable upload', function () {
}) })
it('Should not accept more chunks than expected with an invalid content length/content range', async function () { it('Should not accept more chunks than expected with an invalid content length/content range', async function () {
// Sometimes the server answers 409, and sometimes 400 :shrug:
this.retries(3)
const uploadId = await prepareUpload({ size: 1500 }) const uploadId = await prepareUpload({ size: 1500 })
try { try {

View File

@ -5,6 +5,7 @@ import {
OptimizeTranscodingPayload, OptimizeTranscodingPayload,
VideoTranscodingPayload VideoTranscodingPayload
} from '@peertube/peertube-models' } from '@peertube/peertube-models'
import { isVideoMissHLSAudio } from '@server/lib/runners/job-handlers/shared/utils.js'
import { onTranscodingEnded } from '@server/lib/transcoding/ended-transcoding.js' import { onTranscodingEnded } from '@server/lib/transcoding/ended-transcoding.js'
import { generateHlsPlaylistResolution } from '@server/lib/transcoding/hls-transcoding.js' import { generateHlsPlaylistResolution } from '@server/lib/transcoding/hls-transcoding.js'
import { mergeAudioVideofile, optimizeOriginalVideofile, transcodeNewWebVideoResolution } from '@server/lib/transcoding/web-transcoding.js' import { mergeAudioVideofile, optimizeOriginalVideofile, transcodeNewWebVideoResolution } from '@server/lib/transcoding/web-transcoding.js'
@ -150,5 +151,12 @@ async function handleHLSJob (job: Job, payload: HLSTranscodingPayload, videoArg:
await removeAllWebVideoFiles(video) await removeAllWebVideoFiles(video)
} }
await onTranscodingEnded({ isNewVideo: payload.isNewVideo, moveVideoToNextState: !payload.hasChildren, video }) let moveVideoToNextState = !payload.hasChildren
// Splitted audio, wait audio generation before moving the video in its next state
if (await isVideoMissHLSAudio({ resolution: payload.resolution, separatedAudio: payload.separatedAudio, videoId: videoArg.uuid })) {
moveVideoToNextState = false
}
await onTranscodingEnded({ isNewVideo: payload.isNewVideo, moveVideoToNextState, video })
} }

View File

@ -1,10 +1,14 @@
import {
RunnerJobVODAudioMergeTranscodingPrivatePayload,
RunnerJobVODWebVideoTranscodingPrivatePayload,
VideoResolution
} from '@peertube/peertube-models'
import { logger, LoggerTagsFn } from '@server/helpers/logger.js' import { logger, LoggerTagsFn } from '@server/helpers/logger.js'
import { onTranscodingEnded } from '@server/lib/transcoding/ended-transcoding.js' import { onTranscodingEnded } from '@server/lib/transcoding/ended-transcoding.js'
import { onWebVideoFileTranscoding } from '@server/lib/transcoding/web-transcoding.js' import { onWebVideoFileTranscoding } from '@server/lib/transcoding/web-transcoding.js'
import { VideoModel } from '@server/models/video/video.js' import { VideoModel } from '@server/models/video/video.js'
import { MVideoFullLight } from '@server/types/models/index.js' import { MVideoFullLight } from '@server/types/models/index.js'
import { MRunnerJob } from '@server/types/models/runners/index.js' import { MRunnerJob } from '@server/types/models/runners/index.js'
import { RunnerJobVODAudioMergeTranscodingPrivatePayload, RunnerJobVODWebVideoTranscodingPrivatePayload } from '@peertube/peertube-models'
export async function onVODWebVideoOrAudioMergeTranscodingJob (options: { export async function onVODWebVideoOrAudioMergeTranscodingJob (options: {
video: MVideoFullLight video: MVideoFullLight
@ -34,3 +38,20 @@ export async function loadRunnerVideo (runnerJob: MRunnerJob, lTags: LoggerTagsF
return video return video
} }
export async function isVideoMissHLSAudio (options: {
resolution: number
separatedAudio: boolean
videoId: string | number
}) {
if (!options.separatedAudio) return false
if (options.resolution !== VideoResolution.H_NOVIDEO) {
const video = await VideoModel.loadFull(options.videoId)
// Video doesn't have audio file yet
if (video.hasAudio() !== true) return true
}
return false
}

View File

@ -15,7 +15,7 @@ import { MVideoWithFile } from '@server/types/models/index.js'
import { MRunnerJob } from '@server/types/models/runners/index.js' import { MRunnerJob } from '@server/types/models/runners/index.js'
import { generateRunnerTranscodingAudioInputFileUrl, generateRunnerTranscodingVideoInputFileUrl } from '../runner-urls.js' import { generateRunnerTranscodingAudioInputFileUrl, generateRunnerTranscodingVideoInputFileUrl } from '../runner-urls.js'
import { AbstractVODTranscodingJobHandler } from './abstract-vod-transcoding-job-handler.js' import { AbstractVODTranscodingJobHandler } from './abstract-vod-transcoding-job-handler.js'
import { loadRunnerVideo } from './shared/utils.js' import { isVideoMissHLSAudio, loadRunnerVideo } from './shared/utils.js'
type CreateOptions = { type CreateOptions = {
video: MVideoWithFile video: MVideoWithFile
@ -80,6 +80,7 @@ export class VODHLSTranscodingJobHandler extends AbstractVODTranscodingJobHandle
resultPayload: VODHLSTranscodingSuccess resultPayload: VODHLSTranscodingSuccess
}) { }) {
const { runnerJob, resultPayload } = options const { runnerJob, resultPayload } = options
const payload = runnerJob.payload as RunnerJobVODHLSTranscodingPayload
const privatePayload = runnerJob.privatePayload as RunnerJobVODHLSTranscodingPrivatePayload const privatePayload = runnerJob.privatePayload as RunnerJobVODHLSTranscodingPrivatePayload
const video = await loadRunnerVideo(runnerJob, this.lTags) const video = await loadRunnerVideo(runnerJob, this.lTags)
@ -94,7 +95,14 @@ export class VODHLSTranscodingJobHandler extends AbstractVODTranscodingJobHandle
videoOutputPath: videoFilePath videoOutputPath: videoFilePath
}) })
await onTranscodingEnded({ isNewVideo: privatePayload.isNewVideo, moveVideoToNextState: true, video }) // Splitted audio? Wait audio generation before moving the video in its next state
const moveVideoToNextState = !await isVideoMissHLSAudio({
resolution: payload.output.resolution,
separatedAudio: payload.output.separatedAudio,
videoId: video.uuid
})
await onTranscodingEnded({ isNewVideo: privatePayload.isNewVideo, moveVideoToNextState, video })
if (privatePayload.deleteWebVideoFiles === true) { if (privatePayload.deleteWebVideoFiles === true) {
logger.info('Removing web video files of %s now we have a HLS version of it.', video.uuid, this.lTags(video.uuid)) logger.info('Removing web video files of %s now we have a HLS version of it.', video.uuid, this.lTags(video.uuid))

View File

@ -83,7 +83,7 @@ export abstract class AbstractJobBuilder <P> {
this.buildHLSJobPayload({ this.buildHLSJobPayload({
deleteWebVideoFiles: !CONFIG.TRANSCODING.WEB_VIDEOS.ENABLED && !hasSplitAudioTranscoding, deleteWebVideoFiles: !CONFIG.TRANSCODING.WEB_VIDEOS.ENABLED && !hasSplitAudioTranscoding,
separatedAudio: CONFIG.TRANSCODING.HLS.SPLIT_AUDIO_AND_VIDEO, separatedAudio: hasSplitAudioTranscoding,
copyCodecs, copyCodecs,
@ -103,7 +103,7 @@ export abstract class AbstractJobBuilder <P> {
...this.buildHLSJobPayload({ ...this.buildHLSJobPayload({
deleteWebVideoFiles: !CONFIG.TRANSCODING.WEB_VIDEOS.ENABLED, deleteWebVideoFiles: !CONFIG.TRANSCODING.WEB_VIDEOS.ENABLED,
separatedAudio: CONFIG.TRANSCODING.HLS.SPLIT_AUDIO_AND_VIDEO, separatedAudio: hasSplitAudioTranscoding,
copyCodecs, copyCodecs,
resolution: 0, resolution: 0,
@ -248,7 +248,7 @@ export abstract class AbstractJobBuilder <P> {
resolution, resolution,
fps, fps,
isNewVideo, isNewVideo,
separatedAudio: CONFIG.TRANSCODING.HLS.SPLIT_AUDIO_AND_VIDEO, separatedAudio: hasAudio && CONFIG.TRANSCODING.HLS.SPLIT_AUDIO_AND_VIDEO,
copyCodecs: CONFIG.TRANSCODING.WEB_VIDEOS.ENABLED copyCodecs: CONFIG.TRANSCODING.WEB_VIDEOS.ENABLED
}) })
) )