1
0
Fork 0
mirror of https://github.com/Chocobozzz/PeerTube.git synced 2025-10-03 17:59:37 +02:00

Add config option to keep original video file (basic first version) (#6157)

* testing not removing old file and adding columb to db

* implement feature

* remove unnecessary config changes

* use only keptOriginalFileName, change keptOriginalFileName to keptOriginalFilename for consistency with with videoFile table, slight refactor with basename()

* save original video files to dedicated directory original-video-files

* begin implementing object storage (bucket) support

---------

Co-authored-by: chagai.friedlander <chagai.friedlander@fairkom.eu>
Co-authored-by: Ian <ian.kraft@hotmail.com>
Co-authored-by: Chocobozzz <me@florianbigard.com>
This commit is contained in:
chagai95 2024-03-15 15:47:18 +01:00 committed by GitHub
parent ae31e90c30
commit e57c3024f4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
75 changed files with 1653 additions and 801 deletions

View file

@ -1,5 +1,4 @@
import { buildAspectRatio } from '@peertube/peertube-core-utils'
import { ffprobePromise } from '@peertube/peertube-ffmpeg'
import {
LiveVideoCreate,
LiveVideoLatencyMode,
@ -18,11 +17,10 @@ import { ScheduleVideoUpdateModel } from '@server/models/video/schedule-video-up
import { VideoLiveReplaySettingModel } from '@server/models/video/video-live-replay-setting.js'
import { VideoLiveModel } from '@server/models/video/video-live.js'
import { VideoPasswordModel } from '@server/models/video/video-password.js'
import { VideoSourceModel } from '@server/models/video/video-source.js'
import { VideoModel } from '@server/models/video/video.js'
import { MChannel, MChannelAccountLight, MThumbnail, MUser, MVideoFile, MVideoFullLight } from '@server/types/models/index.js'
import { FilteredModelAttributes } from '@server/types/sequelize.js'
import Ffmpeg from 'fluent-ffmpeg'
import { FfprobeData } from 'fluent-ffmpeg'
import { move } from 'fs-extra/esm'
import { getLocalVideoActivityPubUrl } from './activitypub/url.js'
import { federateVideoIfNeeded } from './activitypub/videos/federate.js'
@ -30,7 +28,7 @@ import { Hooks } from './plugins/hooks.js'
import { generateLocalVideoMiniature, updateLocalVideoMiniatureFromExisting } from './thumbnail.js'
import { autoBlacklistVideoIfNeeded } from './video-blacklist.js'
import { replaceChapters, replaceChaptersFromDescriptionIfNeeded } from './video-chapters.js'
import { buildNewFile } from './video-file.js'
import { buildNewFile, createVideoSource } from './video-file.js'
import { addVideoJobsAfterCreation } from './video-jobs.js'
import { VideoPathManager } from './video-path-manager.js'
import { setVideoTags } from './video.js'
@ -39,7 +37,7 @@ type VideoAttributes = Omit<VideoCreate, 'channelId'> & {
duration: number
isLive: boolean
state: VideoStateType
filename: string
inputFilename: string
}
type LiveAttributes = Pick<LiveVideoCreate, 'permanentLive' | 'latencyMode' | 'saveReplay' | 'replaySettings'> & {
@ -64,6 +62,8 @@ export class LocalVideoCreator {
private readonly lTags: LoggerTagsFn
private readonly videoFilePath: string | undefined
private readonly videoFileProbe: FfprobeData
private readonly videoAttributes: VideoAttributes
private readonly liveAttributes: LiveAttributes | undefined
@ -72,12 +72,15 @@ export class LocalVideoCreator {
private video: MVideoFullLight
private videoFile: MVideoFile
private ffprobe: Ffmpeg.FfprobeData
private videoPath: string
constructor (private readonly options: {
lTags: LoggerTagsFn
videoFilePath: string
videoFile: {
path: string
probe: FfprobeData
}
videoAttributes: VideoAttributes
liveAttributes: LiveAttributes
@ -93,7 +96,8 @@ export class LocalVideoCreator {
finalFallback: ChaptersOption | undefined
}
}) {
this.videoFilePath = options.videoFilePath
this.videoFilePath = options.videoFile?.path
this.videoFileProbe = options.videoFile?.probe
this.videoAttributes = options.videoAttributes
this.liveAttributes = options.liveAttributes
@ -112,11 +116,10 @@ export class LocalVideoCreator {
this.video.url = getLocalVideoActivityPubUrl(this.video)
if (this.videoFilePath) {
this.ffprobe = await ffprobePromise(this.videoFilePath)
this.videoFile = await buildNewFile({ path: this.videoFilePath, mode: 'web-video', ffprobe: this.ffprobe })
this.videoFile = await buildNewFile({ path: this.videoFilePath, mode: 'web-video', ffprobe: this.videoFileProbe })
const destination = VideoPathManager.Instance.getFSVideoFileOutputPath(this.video, this.videoFile)
await move(this.videoFilePath, destination)
this.videoPath = VideoPathManager.Instance.getFSVideoFileOutputPath(this.video, this.videoFile)
await move(this.videoFilePath, this.videoPath)
this.video.aspectRatio = buildAspectRatio({ width: this.videoFile.width, height: this.videoFile.height })
}
@ -166,13 +169,6 @@ export class LocalVideoCreator {
transaction
})
if (this.videoAttributes.filename) {
await VideoSourceModel.create({
filename: this.videoAttributes.filename,
videoId: this.video.id
}, { transaction })
}
if (this.videoAttributes.privacy === VideoPrivacy.PASSWORD_PROTECTED) {
await VideoPasswordModel.addPasswords(this.videoAttributes.videoPasswords, this.video.id, transaction)
}
@ -197,10 +193,11 @@ export class LocalVideoCreator {
videoLive.videoId = this.video.id
this.video.VideoLive = await videoLive.save({ transaction })
}
if (this.videoFile) {
transaction.afterCommit(() => {
addVideoJobsAfterCreation({ video: this.video, videoFile: this.videoFile })
.catch(err => logger.error('Cannot build new video jobs of %s.', this.video.uuid, { err, ...this.lTags(this.video.uuid) }))
.catch(err => logger.error('Cannot build new video jobs of %s.', this.video.uuid, { err, ...this.lTags(this.video.uuid) }))
})
} else {
await federateVideoIfNeeded(this.video, true, transaction)
@ -218,6 +215,15 @@ export class LocalVideoCreator {
})
})
if (this.videoAttributes.inputFilename) {
await createVideoSource({
inputFilename: this.videoAttributes.inputFilename,
inputPath: this.videoPath,
inputProbe: this.videoFileProbe,
video: this.video
})
}
// Channel has a new content, set as updated
await this.channel.setAsUpdated()
@ -248,7 +254,12 @@ export class LocalVideoCreator {
return [
...await Promise.all(promises),
...await generateLocalVideoMiniature({ video: this.video, videoFile: this.videoFile, types: toGenerate, ffprobe: this.ffprobe })
...await generateLocalVideoMiniature({
video: this.video,
videoFile: this.videoFile,
types: toGenerate,
ffprobe: this.videoFileProbe
})
]
}