Skip to content

Commit

Permalink
Fix studio edition on audio only file
Browse files Browse the repository at this point in the history
  • Loading branch information
Chocobozzz committed Dec 16, 2024
1 parent ae3b487 commit a1dd455
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 7 deletions.
38 changes: 37 additions & 1 deletion packages/tests/src/api/transcoding/video-studio.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { expect } from 'chai'
import { getAllFiles } from '@peertube/peertube-core-utils'
import { getAllFiles, getHLS } from '@peertube/peertube-core-utils'
import { VideoStudioTask } from '@peertube/peertube-models'
import { areMockObjectStorageTestsDisabled } from '@peertube/peertube-node-utils'
import {
Expand Down Expand Up @@ -111,6 +111,41 @@ describe('Test video studio', function () {
await checkVideoDuration(server, videoUUID, 4)
}
})

it('Should cut start/end of the audio', async function () {
this.timeout(120_000)

await servers[0].config.enableMinimumTranscoding({ splitAudioAndVideo: true })
await renewVideo('video_short1.webm')
await servers[0].config.enableMinimumTranscoding()

const video = await servers[0].videos.get({ id: videoUUID })
for (const file of video.files) {
if (file.resolution.id === 0) continue

await servers[0].videos.removeWebVideoFile({ fileId: file.id, videoId: videoUUID })
}

for (const file of getHLS(video).files) {
if (file.resolution.id === 0) continue

await servers[0].videos.removeHLSFile({ fileId: file.id, videoId: videoUUID })
}

await createTasks([
{
name: 'cut',
options: {
start: 2,
end: 6
}
}
])

for (const server of servers) {
await checkVideoDuration(server, videoUUID, 4)
}
})
})

describe('Intro/Outro', function () {
Expand Down Expand Up @@ -261,6 +296,7 @@ describe('Test video studio', function () {
})

describe('Complex tasks', function () {

it('Should run a complex task', async function () {
this.timeout(240_000)
await renewVideo()
Expand Down
20 changes: 16 additions & 4 deletions server/core/middlewares/validators/videos/video-studio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,14 @@ const videoStudioAddEditionValidator = [
}

if (areValidationErrors(req, res)) return cleanUpReqFiles(req)
if (!await doesVideoExist(req.params.videoId, res)) return cleanUpReqFiles(req)

const body: VideoStudioCreateEdition = req.body
const files = req.files as Express.Multer.File[]

const video = res.locals.videoAll
const videoIsAudio = video.hasAudio() && !video.hasVideo()

for (let i = 0; i < body.tasks.length; i++) {
const task = body.tasks[i]

Expand All @@ -49,24 +53,32 @@ const videoStudioAddEditionValidator = [
return cleanUpReqFiles(req)
}

if (videoIsAudio) {
if (task.name === 'add-intro' || task.name === 'add-outro' || task.name === 'add-watermark') {
res.fail({
status: HttpStatusCode.BAD_REQUEST_400,
message: `Task ${task.name} is invalid: video does not contain a video stream`
})

return cleanUpReqFiles(req)
}
}

if (task.name === 'add-intro' || task.name === 'add-outro') {
const filePath = getTaskFileFromReq(files, i).path

// Our concat filter needs a video stream
if (await isAudioFile(filePath)) {
res.fail({
status: HttpStatusCode.BAD_REQUEST_400,
message: `Task ${task.name} is invalid: file does not contain a video stream`
message: `Task ${task.name} is invalid: input file does not contain a video stream`
})

return cleanUpReqFiles(req)
}
}
}

if (!await doesVideoExist(req.params.videoId, res)) return cleanUpReqFiles(req)

const video = res.locals.videoAll
if (!checkVideoFileCanBeEdited(video, res)) return cleanUpReqFiles(req)

const user = res.locals.oauth.token.User
Expand Down
14 changes: 12 additions & 2 deletions server/core/models/video/video.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1738,7 +1738,13 @@ export class VideoModel extends SequelizeModel<VideoModel> {

getMaxQualityAudioAndVideoFiles <T extends MVideoWithFile> (this: T) {
const videoFile = this.getMaxQualityFile(VideoFileStream.VIDEO)
if (!videoFile) return { videoFile: undefined }

if (!videoFile) {
const audioOnly = this.getMaxQualityFile(VideoFileStream.AUDIO)
if (audioOnly) return { videoFile: audioOnly }

return { videoFile: undefined }
}

// File also has audio, we can return it
if (videoFile.hasAudio()) return { videoFile }
Expand All @@ -1759,7 +1765,7 @@ export class VideoModel extends SequelizeModel<VideoModel> {
getMaxQualityBytes <T extends MVideoWithFile> (this: T) {
const { videoFile, separatedAudioFile } = this.getMaxQualityAudioAndVideoFiles()

let size = videoFile.size
let size = videoFile?.size || 0
if (separatedAudioFile) size += separatedAudioFile.size

return size
Expand Down Expand Up @@ -1801,6 +1807,10 @@ export class VideoModel extends SequelizeModel<VideoModel> {
return !!this.getMaxQualityFile(VideoFileStream.AUDIO)
}

hasVideo () {
return !!this.getMaxQualityFile(VideoFileStream.VIDEO)
}

// ---------------------------------------------------------------------------

getWebVideoFileMinResolution<T extends MVideoWithFile> (this: T, resolution: number): MVideoFileVideo {
Expand Down

0 comments on commit a1dd455

Please sign in to comment.