Fix studio edition on audio only file
This commit is contained in:
parent
ae3b487c42
commit
a1dd455634
3 changed files with 65 additions and 7 deletions
|
@ -1,5 +1,5 @@
|
||||||
import { expect } from 'chai'
|
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 { VideoStudioTask } from '@peertube/peertube-models'
|
||||||
import { areMockObjectStorageTestsDisabled } from '@peertube/peertube-node-utils'
|
import { areMockObjectStorageTestsDisabled } from '@peertube/peertube-node-utils'
|
||||||
import {
|
import {
|
||||||
|
@ -111,6 +111,41 @@ describe('Test video studio', function () {
|
||||||
await checkVideoDuration(server, videoUUID, 4)
|
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 () {
|
describe('Intro/Outro', function () {
|
||||||
|
@ -261,6 +296,7 @@ describe('Test video studio', function () {
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('Complex tasks', function () {
|
describe('Complex tasks', function () {
|
||||||
|
|
||||||
it('Should run a complex task', async function () {
|
it('Should run a complex task', async function () {
|
||||||
this.timeout(240_000)
|
this.timeout(240_000)
|
||||||
await renewVideo()
|
await renewVideo()
|
||||||
|
|
|
@ -33,10 +33,14 @@ const videoStudioAddEditionValidator = [
|
||||||
}
|
}
|
||||||
|
|
||||||
if (areValidationErrors(req, res)) return cleanUpReqFiles(req)
|
if (areValidationErrors(req, res)) return cleanUpReqFiles(req)
|
||||||
|
if (!await doesVideoExist(req.params.videoId, res)) return cleanUpReqFiles(req)
|
||||||
|
|
||||||
const body: VideoStudioCreateEdition = req.body
|
const body: VideoStudioCreateEdition = req.body
|
||||||
const files = req.files as Express.Multer.File[]
|
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++) {
|
for (let i = 0; i < body.tasks.length; i++) {
|
||||||
const task = body.tasks[i]
|
const task = body.tasks[i]
|
||||||
|
|
||||||
|
@ -49,6 +53,17 @@ const videoStudioAddEditionValidator = [
|
||||||
return cleanUpReqFiles(req)
|
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') {
|
if (task.name === 'add-intro' || task.name === 'add-outro') {
|
||||||
const filePath = getTaskFileFromReq(files, i).path
|
const filePath = getTaskFileFromReq(files, i).path
|
||||||
|
|
||||||
|
@ -56,7 +71,7 @@ const videoStudioAddEditionValidator = [
|
||||||
if (await isAudioFile(filePath)) {
|
if (await isAudioFile(filePath)) {
|
||||||
res.fail({
|
res.fail({
|
||||||
status: HttpStatusCode.BAD_REQUEST_400,
|
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)
|
return cleanUpReqFiles(req)
|
||||||
|
@ -64,9 +79,6 @@ const videoStudioAddEditionValidator = [
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!await doesVideoExist(req.params.videoId, res)) return cleanUpReqFiles(req)
|
|
||||||
|
|
||||||
const video = res.locals.videoAll
|
|
||||||
if (!checkVideoFileCanBeEdited(video, res)) return cleanUpReqFiles(req)
|
if (!checkVideoFileCanBeEdited(video, res)) return cleanUpReqFiles(req)
|
||||||
|
|
||||||
const user = res.locals.oauth.token.User
|
const user = res.locals.oauth.token.User
|
||||||
|
|
|
@ -1738,7 +1738,13 @@ export class VideoModel extends SequelizeModel<VideoModel> {
|
||||||
|
|
||||||
getMaxQualityAudioAndVideoFiles <T extends MVideoWithFile> (this: T) {
|
getMaxQualityAudioAndVideoFiles <T extends MVideoWithFile> (this: T) {
|
||||||
const videoFile = this.getMaxQualityFile(VideoFileStream.VIDEO)
|
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
|
// File also has audio, we can return it
|
||||||
if (videoFile.hasAudio()) return { videoFile }
|
if (videoFile.hasAudio()) return { videoFile }
|
||||||
|
@ -1759,7 +1765,7 @@ export class VideoModel extends SequelizeModel<VideoModel> {
|
||||||
getMaxQualityBytes <T extends MVideoWithFile> (this: T) {
|
getMaxQualityBytes <T extends MVideoWithFile> (this: T) {
|
||||||
const { videoFile, separatedAudioFile } = this.getMaxQualityAudioAndVideoFiles()
|
const { videoFile, separatedAudioFile } = this.getMaxQualityAudioAndVideoFiles()
|
||||||
|
|
||||||
let size = videoFile.size
|
let size = videoFile?.size || 0
|
||||||
if (separatedAudioFile) size += separatedAudioFile.size
|
if (separatedAudioFile) size += separatedAudioFile.size
|
||||||
|
|
||||||
return size
|
return size
|
||||||
|
@ -1801,6 +1807,10 @@ export class VideoModel extends SequelizeModel<VideoModel> {
|
||||||
return !!this.getMaxQualityFile(VideoFileStream.AUDIO)
|
return !!this.getMaxQualityFile(VideoFileStream.AUDIO)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hasVideo () {
|
||||||
|
return !!this.getMaxQualityFile(VideoFileStream.VIDEO)
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
getWebVideoFileMinResolution<T extends MVideoWithFile> (this: T, resolution: number): MVideoFileVideo {
|
getWebVideoFileMinResolution<T extends MVideoWithFile> (this: T, resolution: number): MVideoFileVideo {
|
||||||
|
|
Loading…
Add table
Reference in a new issue