1
0
Fork 0

Fix transcoding of audio only videos

This commit is contained in:
Chocobozzz 2025-01-17 09:52:45 +01:00
parent 82246a0c8d
commit 6ef092f0da
No known key found for this signature in database
GPG key ID: 583A612D890159BE
7 changed files with 113 additions and 4 deletions

View file

@ -66,7 +66,6 @@
</div>
<my-user-notifications
#userNotifications
[ignoreLoadingBar]="true" [infiniteScroll]="false" [itemsPerPage]="10"
[markAllAsReadSubject]="markAllAsReadSubject" (notificationsLoaded)="onNotificationLoaded()"
></my-user-notifications>

View file

@ -5,6 +5,8 @@ import { AbstractCommand, OverrideCommandOptions } from '../shared/abstract-comm
export class ConfigCommand extends AbstractCommand {
private savedConfig: CustomConfig
static getConfigResolutions (enabled: boolean, with0p = false) {
return {
'0p': enabled && with0p,
@ -579,4 +581,14 @@ export class ConfigCommand extends AbstractCommand {
return this.updateCustomConfig({ ...options, newCustomConfig: merge({}, existing, options.newConfig) })
}
// ---------------------------------------------------------------------------
async save () {
this.savedConfig = await this.getCustomConfig()
}
rollback () {
return this.updateCustomConfig({ newCustomConfig: this.savedConfig })
}
}

View file

@ -1,6 +1,6 @@
/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
import { HttpStatusCode, VideoDetails } from '@peertube/peertube-models'
import { HttpStatusCode, VideoDetails, VideoResolution } from '@peertube/peertube-models'
import { areMockObjectStorageTestsDisabled } from '@peertube/peertube-node-utils'
import {
cleanupTests,
@ -253,6 +253,56 @@ function runTests (options: {
expect(video.publishedAt).to.equal(publishedAt)
})
it('Should transcode with an audio-only video', async function () {
this.timeout(60000)
await servers[0].config.enableTranscoding({
webVideo: true,
hls: false,
keepOriginal: false,
splitAudioAndVideo: false,
alwaysTranscodeOriginalResolution: false,
resolutions: [ VideoResolution.H_NOVIDEO ]
})
const { uuid } = await servers[0].videos.quickUpload({ name: 'quick' })
await waitJobs(servers)
// Only keep audio resolution
{
const video = await servers[0].videos.get({ id: uuid })
expect(video.streamingPlaylists).to.have.lengthOf(0)
for (const file of video.files) {
if (file.resolution.id !== VideoResolution.H_NOVIDEO) {
await servers[0].videos.removeWebVideoFile({ videoId: uuid, fileId: file.id })
}
}
}
await servers[0].videos.runTranscoding({ videoId: uuid, transcodingType: 'hls' })
await waitJobs(servers)
await servers[0].videos.runTranscoding({ videoId: uuid, transcodingType: 'web-video' })
await waitJobs(servers)
await expectNoFailedTranscodingJob(servers[0])
for (const server of servers) {
const videoDetails = await server.videos.get({ id: uuid })
expect(videoDetails.files).to.have.lengthOf(1)
expect(videoDetails.streamingPlaylists).to.have.lengthOf(1)
expect(videoDetails.streamingPlaylists[0].files).to.have.lengthOf(1)
for (const files of videoDetails.files) {
expect(files.resolution.id).to.equal(VideoResolution.H_NOVIDEO)
}
if (enableObjectStorage) await checkFilesInObjectStorage(objectStorage, videoDetails)
}
})
})
describe('With split audio and video', function () {

View file

@ -409,6 +409,32 @@ describe('Test video source management', function () {
await makeGetRequest({ url: server.url, path: video.thumbnailPath, expectedStatus: HttpStatusCode.OK_200 })
}
})
it('Should replace the video with an audio only file', async function () {
await servers[0].config.save()
await servers[0].config.enableTranscoding({ webVideo: true, hls: true, resolutions: [ 480, 360, 240, 144 ] })
const { uuid } = await servers[0].videos.quickUpload({ name: 'future audio', fixture: 'video_short_360p.mp4' })
await waitJobs(servers)
{
const video = await servers[0].videos.get({ id: uuid })
expect(getAllFiles(video)).to.have.lengthOf(6)
}
const fixture = 'sample.ogg'
await servers[0].videos.replaceSourceFile({ videoId: uuid, fixture })
await waitJobs(servers)
for (const server of servers) {
const video = await server.videos.get({ id: uuid })
const files = getAllFiles(video)
expect(files).to.have.lengthOf(8)
}
await servers[0].config.rollback()
})
})
describe('Autoblacklist', function () {

View file

@ -75,6 +75,25 @@ describe('Test replace file using peertube-runner program', function () {
await checkSourceFile({ server, fsCount: 2, fixture, uuid })
})
it('Should replace the video by an audio file', async function () {
{
await server.videos.removeAllWebVideoFiles({ videoId: uuid })
const video = await server.videos.get({ id: uuid })
expect(getAllFiles(video)).to.have.lengthOf(2)
}
const fixture = 'sample.ogg'
await server.videos.replaceSourceFile({ videoId: uuid, fixture })
await waitJobs(server, { runnerJobs: true })
const video = await server.videos.get({ id: uuid })
const files = getAllFiles(video)
expect(files).to.have.lengthOf(4)
await checkSourceFile({ server, fsCount: 2, fixture, uuid })
})
after(async function () {
if (peertubeRunner) {
await peertubeRunner.unregisterPeerTubeInstance({ runnerName: 'runner' })

View file

@ -1,3 +1,4 @@
import { VideoResolution } from '@peertube/peertube-models'
import { CONFIG } from '@server/initializers/config.js'
import { logger } from '../logger.js'
@ -9,6 +10,8 @@ export function computeOutputFPS (options: {
}) {
const { resolution, isOriginResolution, type } = options
if (resolution === VideoResolution.H_NOVIDEO) return 0
const settings = type === 'vod'
? buildTranscodingFPSOptions(CONFIG.TRANSCODING.FPS.MAX)
: buildTranscodingFPSOptions(CONFIG.LIVE.TRANSCODING.FPS.MAX)

View file

@ -1796,11 +1796,11 @@ export class VideoModel extends SequelizeModel<VideoModel> {
// ---------------------------------------------------------------------------
getMaxFPS () {
return this.getMaxQualityFile(VideoFileStream.VIDEO).fps
return this.getMaxQualityFile(VideoFileStream.VIDEO)?.fps || 0
}
getMaxResolution () {
return this.getMaxQualityFile(VideoFileStream.VIDEO).resolution
return this.getMaxQualityFile(VideoFileStream.VIDEO)?.resolution || this.getMaxQualityFile(VideoFileStream.AUDIO)?.resolution
}
hasAudio () {