Fix adding an intro/outro with splitted HLS

This commit is contained in:
Chocobozzz 2025-01-31 11:28:30 +01:00
parent 05f105d03f
commit 319932c1de
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
2 changed files with 255 additions and 240 deletions

View File

@ -127,7 +127,8 @@ export class FFmpegEdition {
const mainProbe = await ffprobePromise(videoInputPath) const mainProbe = await ffprobePromise(videoInputPath)
const fps = await getVideoStreamFPS(videoInputPath, mainProbe) const fps = await getVideoStreamFPS(videoInputPath, mainProbe)
const { resolution } = await getVideoStreamDimensionsInfo(videoInputPath, mainProbe) const { resolution } = await getVideoStreamDimensionsInfo(videoInputPath, mainProbe)
const mainHasAudio = await hasAudioStream(separatedAudioInputPath || videoInputPath, mainProbe)
const mainHasAudio = await hasAudioStream(separatedAudioInputPath || videoInputPath)
const introOutroProbe = await ffprobePromise(introOutroPath) const introOutroProbe = await ffprobePromise(introOutroPath)
const introOutroHasAudio = await hasAudioStream(introOutroPath, introOutroProbe) const introOutroHasAudio = await hasAudioStream(introOutroPath, introOutroProbe)
@ -135,12 +136,23 @@ export class FFmpegEdition {
const command = this.commandWrapper.buildCommand([ ...this.buildInputs(options), introOutroPath ], inputFileMutexReleaser) const command = this.commandWrapper.buildCommand([ ...this.buildInputs(options), introOutroPath ], inputFileMutexReleaser)
.output(outputPath) .output(outputPath)
const videoInput = 0
const audioInput = separatedAudioInputPath
? videoInput + 1
: videoInput
const introInput = audioInput + 1
let introAudio = introInput
if (!introOutroHasAudio && mainHasAudio) { if (!introOutroHasAudio && mainHasAudio) {
const duration = await getVideoStreamDuration(introOutroPath, introOutroProbe) const duration = await getVideoStreamDuration(introOutroPath, introOutroProbe)
command.input('anullsrc') command.input('anullsrc')
command.withInputFormat('lavfi') command.withInputFormat('lavfi')
command.withInputOption('-t ' + duration) command.withInputOption('-t ' + duration)
introAudio++
} }
await presetVOD({ await presetVOD({
@ -159,7 +171,7 @@ export class FFmpegEdition {
// Add black background to correctly scale intro/outro with padding // Add black background to correctly scale intro/outro with padding
const complexFilter: FilterSpecification[] = [ const complexFilter: FilterSpecification[] = [
{ {
inputs: [ '1', '0' ], inputs: [ `${introInput}`, `${videoInput}` ],
filter: 'scale2ref', filter: 'scale2ref',
options: { options: {
w: 'iw', w: 'iw',
@ -185,7 +197,7 @@ export class FFmpegEdition {
outputs: [ 'to-scale-bg' ] outputs: [ 'to-scale-bg' ]
}, },
{ {
inputs: [ '1', 'to-scale-bg' ], inputs: [ `${introInput}`, 'to-scale-bg' ],
filter: 'scale2ref', filter: 'scale2ref',
options: { options: {
w: 'iw', w: 'iw',
@ -221,14 +233,9 @@ export class FFmpegEdition {
const mainFilterInputs = [ 'main' ] const mainFilterInputs = [ 'main' ]
if (mainHasAudio) { if (mainHasAudio) {
mainFilterInputs.push('0:a') mainFilterInputs.push(`${audioInput}:a`)
if (introOutroHasAudio) { introOutroFilterInputs.push(`${introAudio}:a`)
introOutroFilterInputs.push('1:a')
} else {
// Silent input
introOutroFilterInputs.push('2:a')
}
} }
if (type === 'intro') { if (type === 'intro') {

View File

@ -1,4 +1,3 @@
import { expect } from 'chai'
import { getAllFiles, getHLS } from '@peertube/peertube-core-utils' import { getAllFiles, getHLS } from '@peertube/peertube-core-utils'
import { VideoStudioTask } from '@peertube/peertube-models' import { VideoStudioTask } from '@peertube/peertube-models'
import { areMockObjectStorageTestsDisabled } from '@peertube/peertube-node-utils' import { areMockObjectStorageTestsDisabled } from '@peertube/peertube-node-utils'
@ -16,6 +15,7 @@ import {
import { checkVideoDuration, expectStartWith } from '@tests/shared/checks.js' import { checkVideoDuration, expectStartWith } from '@tests/shared/checks.js'
import { checkPersistentTmpIsEmpty } from '@tests/shared/directories.js' import { checkPersistentTmpIsEmpty } from '@tests/shared/directories.js'
import { completeCheckHlsPlaylist } from '@tests/shared/streaming-playlists.js' import { completeCheckHlsPlaylist } from '@tests/shared/streaming-playlists.js'
import { expect } from 'chai'
describe('Test video studio', function () { describe('Test video studio', function () {
let servers: PeerTubeServer[] = [] let servers: PeerTubeServer[] = []
@ -48,6 +48,7 @@ describe('Test video studio', function () {
await servers[0].config.enableStudio() await servers[0].config.enableStudio()
}) })
function runCommonTests () {
describe('Cutting', function () { describe('Cutting', function () {
it('Should cut the beginning of the video', async function () { it('Should cut the beginning of the video', async function () {
@ -247,7 +248,7 @@ describe('Test video studio', function () {
} }
}) })
it('Should add an outro without audio to a video with audio', async function () { it('Should add an outro without audio to a video without audio', async function () {
this.timeout(120_000) this.timeout(120_000)
await renewVideo('video_short_no_audio.mp4') await renewVideo('video_short_no_audio.mp4')
@ -294,8 +295,11 @@ describe('Test video studio', function () {
} }
}) })
}) })
}
describe('Complex tasks', function () { describe('Web videos enabled', function () {
runCommonTests()
it('Should run a complex task', async function () { it('Should run a complex task', async function () {
this.timeout(240_000) this.timeout(240_000)
@ -315,7 +319,9 @@ describe('Test video studio', function () {
await servers[0].config.enableMinimumTranscoding({ webVideo: false, hls: true }) await servers[0].config.enableMinimumTranscoding({ webVideo: false, hls: true })
}) })
it('Should run a complex task on HLS only video', async function () { runCommonTests()
it('Should run a complex task', async function () {
this.timeout(240_000) this.timeout(240_000)
await renewVideo() await renewVideo()
@ -338,7 +344,9 @@ describe('Test video studio', function () {
await servers[0].config.enableMinimumTranscoding({ webVideo: false, hls: true, splitAudioAndVideo: true }) await servers[0].config.enableMinimumTranscoding({ webVideo: false, hls: true, splitAudioAndVideo: true })
}) })
it('Should run a complex task on HLS only video', async function () { runCommonTests()
it('Should run a complex task', async function () {
this.timeout(240_000) this.timeout(240_000)
await renewVideo() await renewVideo()