mirror of https://github.com/Chocobozzz/PeerTube
Add video files migration
parent
90a8bd305d
commit
2451916e45
|
@ -24,7 +24,7 @@ import { CONFIG, registerConfigChangedHandler } from './config'
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
const LAST_MIGRATION_VERSION = 580
|
const LAST_MIGRATION_VERSION = 585
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
|
@ -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)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue