Add video files migration

pull/3756/head
Chocobozzz 2021-02-17 09:36:09 +01:00 committed by Chocobozzz
parent 90a8bd305d
commit 2451916e45
5 changed files with 74 additions and 23 deletions

View File

@ -24,7 +24,7 @@ import { CONFIG, registerConfigChangedHandler } from './config'
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
const LAST_MIGRATION_VERSION = 580 const LAST_MIGRATION_VERSION = 585
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------

View File

@ -0,0 +1,55 @@
import * as Sequelize from 'sequelize'
async function up (utils: {
transaction: Sequelize.Transaction
queryInterface: Sequelize.QueryInterface
sequelize: Sequelize.Sequelize
db: any
}): Promise<void> {
for (const column of [ 'filename', 'fileUrl', 'torrentFilename', 'torrentUrl' ]) {
const data = {
type: Sequelize.STRING,
allowNull: true,
defaultValue: null
}
await utils.queryInterface.addColumn('videoFile', column, data)
}
// Generate filenames for webtorrent files
{
const webtorrentQuery = `SELECT "videoFile".id, "video".uuid, "videoFile".resolution, "videoFile".extname ` +
`FROM video INNER JOIN "videoFile" ON "videoFile"."videoId" = video.id`
const query = `UPDATE "videoFile" ` +
`SET filename = t.uuid || '-' || t.resolution || t.extname, ` +
`"torrentFilename" = t.uuid || '-' || t.resolution || '.torrent' ` +
`FROM (${webtorrentQuery}) AS t WHERE t.id = "videoFile"."id"`
await utils.sequelize.query(query)
}
// Generate filenames for HLS files
{
const hlsQuery = `SELECT "videoFile".id, "video".uuid, "videoFile".resolution, "videoFile".extname ` +
`FROM video ` +
`INNER JOIN "videoStreamingPlaylist" ON "videoStreamingPlaylist"."videoId" = video.id ` +
`INNER JOIN "videoFile" ON "videoFile"."videoStreamingPlaylistId" = "videoStreamingPlaylist".id`
const query = `UPDATE "videoFile" ` +
`SET filename = t.uuid || '-' || t.resolution || '-fragmented' || t.extname, ` +
`"torrentFilename" = t.uuid || '-' || t.resolution || '-hls.torrent' ` +
`FROM (${hlsQuery}) AS t WHERE t.id = "videoFile"."id"`
await utils.sequelize.query(query)
}
}
function down (options) {
throw new Error('Not implemented.')
}
export {
up,
down
}

View File

@ -4,7 +4,7 @@ import { extname } from 'path'
import { createTorrentAndSetInfoHash } from '@server/helpers/webtorrent' import { createTorrentAndSetInfoHash } from '@server/helpers/webtorrent'
import { generateVideoFilename, getVideoFilePath } from '@server/lib/video-paths' import { generateVideoFilename, getVideoFilePath } from '@server/lib/video-paths'
import { UserModel } from '@server/models/account/user' import { UserModel } from '@server/models/account/user'
import { MVideoFile, MVideoFullLight } from '@server/types/models' import { MVideoFullLight } from '@server/types/models'
import { VideoFileImportPayload } from '@shared/models' import { VideoFileImportPayload } from '@shared/models'
import { getVideoFileFPS, getVideoFileResolution } from '../../../helpers/ffprobe-utils' import { getVideoFileFPS, getVideoFileResolution } from '../../../helpers/ffprobe-utils'
import { logger } from '../../../helpers/logger' import { logger } from '../../../helpers/logger'
@ -56,16 +56,8 @@ async function updateVideoFile (video: MVideoFullLight, inputFilePath: string) {
const fps = await getVideoFileFPS(inputFilePath) const fps = await getVideoFileFPS(inputFilePath)
const fileExt = extname(inputFilePath) const fileExt = extname(inputFilePath)
let updatedVideoFile = new VideoFileModel({
resolution: videoFileResolution,
extname: fileExt,
filename: generateVideoFilename(video, false, videoFileResolution, fileExt),
size,
fps,
videoId: video.id
}) as MVideoFile
const currentVideoFile = video.VideoFiles.find(videoFile => videoFile.resolution === updatedVideoFile.resolution) const currentVideoFile = video.VideoFiles.find(videoFile => videoFile.resolution === videoFileResolution)
if (currentVideoFile) { if (currentVideoFile) {
// Remove old file and old torrent // Remove old file and old torrent
@ -74,20 +66,23 @@ async function updateVideoFile (video: MVideoFullLight, inputFilePath: string) {
// Remove the old video file from the array // Remove the old video file from the array
video.VideoFiles = video.VideoFiles.filter(f => f !== currentVideoFile) video.VideoFiles = video.VideoFiles.filter(f => f !== currentVideoFile)
// Update the database await currentVideoFile.destroy()
currentVideoFile.extname = updatedVideoFile.extname
currentVideoFile.size = updatedVideoFile.size
currentVideoFile.fps = updatedVideoFile.fps
updatedVideoFile = currentVideoFile
} }
const outputPath = getVideoFilePath(video, updatedVideoFile) const newVideoFile = new VideoFileModel({
resolution: videoFileResolution,
extname: fileExt,
filename: generateVideoFilename(video, false, videoFileResolution, fileExt),
size,
fps,
videoId: video.id
})
const outputPath = getVideoFilePath(video, newVideoFile)
await copy(inputFilePath, outputPath) await copy(inputFilePath, outputPath)
await createTorrentAndSetInfoHash(video, video, updatedVideoFile) video.VideoFiles.push(newVideoFile)
await createTorrentAndSetInfoHash(video, video, newVideoFile)
await updatedVideoFile.save() await newVideoFile.save()
video.VideoFiles.push(updatedVideoFile)
} }

View File

@ -166,6 +166,7 @@ async function mergeAudioVideofile (video: MVideoFullLight, resolution: VideoRes
// Important to do this before getVideoFilename() to take in account the new file extension // Important to do this before getVideoFilename() to take in account the new file extension
inputVideoFile.extname = newExtname inputVideoFile.extname = newExtname
inputVideoFile.filename = generateVideoFilename(video, false, inputVideoFile.resolution, newExtname)
const videoOutputPath = getVideoFilePath(video, inputVideoFile) const videoOutputPath = getVideoFilePath(video, inputVideoFile)
// ffmpeg generated a new video file, so update the video duration // ffmpeg generated a new video file, so update the video duration

View File

@ -22,9 +22,9 @@ const expect = chai.expect
function assertVideoProperties (video: VideoFile, resolution: number, extname: string, size?: number) { function assertVideoProperties (video: VideoFile, resolution: number, extname: string, size?: number) {
expect(video).to.have.nested.property('resolution.id', resolution) expect(video).to.have.nested.property('resolution.id', resolution)
expect(video).to.have.property('magnetUri').that.includes(`.${extname}`)
expect(video).to.have.property('torrentUrl').that.includes(`-${resolution}.torrent`) expect(video).to.have.property('torrentUrl').that.includes(`-${resolution}.torrent`)
expect(video).to.have.property('fileUrl').that.includes(`.${extname}`) expect(video).to.have.property('fileUrl').that.includes(`.${extname}`)
expect(video).to.have.property('magnetUri').that.includes(`.${extname}`)
expect(video).to.have.property('size').that.is.above(0) expect(video).to.have.property('size').that.is.above(0)
if (size) expect(video.size).to.equal(size) if (size) expect(video.size).to.equal(size)