From 9b293cd6a2ce9ed1e1ccd41adbf7f2dbe2da8231 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Wed, 8 Dec 2021 11:07:19 +0100 Subject: Update torrent metadata on video update --- scripts/update-host.ts | 6 +++--- server/controllers/api/videos/update.ts | 12 +++++++++--- server/helpers/webtorrent.ts | 15 +++++++++++---- server/lib/job-queue/handlers/move-to-object-storage.ts | 4 ++-- server/models/video/video-playlist-element.ts | 2 +- server/models/video/video.ts | 15 +++++++++++++++ shared/extra-utils/videos/videos.ts | 1 + 7 files changed, 42 insertions(+), 13 deletions(-) diff --git a/scripts/update-host.ts b/scripts/update-host.ts index c6eb9d533..f752082fd 100755 --- a/scripts/update-host.ts +++ b/scripts/update-host.ts @@ -17,7 +17,7 @@ import { VideoCommentModel } from '../server/models/video/video-comment' import { AccountModel } from '../server/models/account/account' import { VideoChannelModel } from '../server/models/video/video-channel' import { initDatabaseModels } from '../server/initializers/database' -import { updateTorrentUrls } from '@server/helpers/webtorrent' +import { updateTorrentMetadata } from '@server/helpers/webtorrent' import { getServerActor } from '@server/models/application/application' run() @@ -126,7 +126,7 @@ async function run () { for (const file of video.VideoFiles) { console.log('Updating torrent file %s of video %s.', file.resolution, video.uuid) - await updateTorrentUrls(video, file) + await updateTorrentMetadata(video, file) await file.save() } @@ -135,7 +135,7 @@ async function run () { for (const file of (playlist?.VideoFiles || [])) { console.log('Updating fragmented torrent file %s of video %s.', file.resolution, video.uuid) - await updateTorrentUrls(video, file) + await updateTorrentMetadata(video, file) await file.save() } diff --git a/server/controllers/api/videos/update.ts b/server/controllers/api/videos/update.ts index 3fcff3e86..6f14a6788 100644 --- a/server/controllers/api/videos/update.ts +++ b/server/controllers/api/videos/update.ts @@ -1,5 +1,6 @@ import express from 'express' import { Transaction } from 'sequelize/types' +import { updateTorrentMetadata } from '@server/helpers/webtorrent' import { changeVideoChannelShare } from '@server/lib/activitypub/share' import { buildVideoThumbnailsFromReq, setVideoTags } from '@server/lib/video' import { openapiOperationDoc } from '@server/middlewares/doc' @@ -149,9 +150,8 @@ async function updateVideo (req: express.Request, res: express.Response) { return videoInstanceUpdated }) - if (wasConfidentialVideo) { - Notifier.Instance.notifyOnNewVideoIfNeeded(videoInstanceUpdated) - } + if (videoInfoToUpdate.name) await updateTorrentsMetadata(videoInstanceUpdated) + if (wasConfidentialVideo) Notifier.Instance.notifyOnNewVideoIfNeeded(videoInstanceUpdated) Hooks.runAction('action:api.video.updated', { video: videoInstanceUpdated, body: req.body, req, res }) } catch (err) { @@ -199,3 +199,9 @@ function updateSchedule (videoInstance: MVideoFullLight, videoInfoToUpdate: Vide return ScheduleVideoUpdateModel.deleteByVideoId(videoInstance.id, transaction) } } + +async function updateTorrentsMetadata (video: MVideoFullLight) { + for (const file of video.getAllFiles()) { + await updateTorrentMetadata(video, file) + } +} diff --git a/server/helpers/webtorrent.ts b/server/helpers/webtorrent.ts index c75c058e4..b350c9718 100644 --- a/server/helpers/webtorrent.ts +++ b/server/helpers/webtorrent.ts @@ -94,7 +94,7 @@ function createTorrentAndSetInfoHash (videoOrPlaylist: MVideo | MStreamingPlayli const options = { // Keep the extname, it's used by the client to stream the file inside a web browser - name: `${video.name} ${videoFile.resolution}p${videoFile.extname}`, + name: buildInfoName(video, videoFile), createdBy: 'PeerTube', announceList: buildAnnounceList(), urlList: buildUrlList(video, videoFile) @@ -120,7 +120,7 @@ function createTorrentAndSetInfoHash (videoOrPlaylist: MVideo | MStreamingPlayli }) } -async function updateTorrentUrls (videoOrPlaylist: MVideo | MStreamingPlaylistVideo, videoFile: MVideoFile) { +async function updateTorrentMetadata (videoOrPlaylist: MVideo | MStreamingPlaylistVideo, videoFile: MVideoFile) { const video = extractVideo(videoOrPlaylist) const oldTorrentPath = join(CONFIG.STORAGE.TORRENTS_DIR, videoFile.torrentFilename) @@ -133,10 +133,13 @@ async function updateTorrentUrls (videoOrPlaylist: MVideo | MStreamingPlaylistVi decoded['url-list'] = buildUrlList(video, videoFile) + decoded.info.name = buildInfoName(video, videoFile) + decoded['creation date'] = Math.ceil(Date.now() / 1000) + const newTorrentFilename = generateTorrentFileName(videoOrPlaylist, videoFile.resolution) const newTorrentPath = join(CONFIG.STORAGE.TORRENTS_DIR, newTorrentFilename) - logger.info('Updating torrent URLs %s -> %s.', oldTorrentPath, newTorrentPath) + logger.info('Updating torrent metadata %s -> %s.', oldTorrentPath, newTorrentPath) await writeFile(newTorrentPath, encode(decoded)) await remove(join(CONFIG.STORAGE.TORRENTS_DIR, videoFile.torrentFilename)) @@ -171,7 +174,7 @@ function generateMagnetUri ( export { createTorrentPromise, - updateTorrentUrls, + updateTorrentMetadata, createTorrentAndSetInfoHash, generateMagnetUri, downloadWebTorrentVideo @@ -226,3 +229,7 @@ function buildAnnounceList () { function buildUrlList (video: MVideo, videoFile: MVideoFile) { return [ videoFile.getFileUrl(video) ] } + +function buildInfoName (video: MVideo, videoFile: MVideoFile) { + return `${video.name} ${videoFile.resolution}p${videoFile.extname}` +} diff --git a/server/lib/job-queue/handlers/move-to-object-storage.ts b/server/lib/job-queue/handlers/move-to-object-storage.ts index 54a7c566b..b5eea0184 100644 --- a/server/lib/job-queue/handlers/move-to-object-storage.ts +++ b/server/lib/job-queue/handlers/move-to-object-storage.ts @@ -2,7 +2,7 @@ import { Job } from 'bull' import { remove } from 'fs-extra' import { join } from 'path' import { logger } from '@server/helpers/logger' -import { updateTorrentUrls } from '@server/helpers/webtorrent' +import { updateTorrentMetadata } from '@server/helpers/webtorrent' import { CONFIG } from '@server/initializers/config' import { P2P_MEDIA_LOADER_PEER_VERSION } from '@server/initializers/constants' import { storeHLSFile, storeWebTorrentFile } from '@server/lib/object-storage' @@ -113,7 +113,7 @@ async function onFileMoved (options: { file.fileUrl = fileUrl file.storage = VideoStorage.OBJECT_STORAGE - await updateTorrentUrls(videoOrPlaylist, file) + await updateTorrentMetadata(videoOrPlaylist, file) await file.save() logger.debug('Removing %s because it\'s now on object storage', oldPath) diff --git a/server/models/video/video-playlist-element.ts b/server/models/video/video-playlist-element.ts index 82c832188..a87b2bcae 100644 --- a/server/models/video/video-playlist-element.ts +++ b/server/models/video/video-playlist-element.ts @@ -276,7 +276,7 @@ export class VideoPlaylistElementModel extends Model>> { return this.VideoChannel.Account.Actor.Server?.isBlocked() || this.VideoChannel.Account.isBlocked() } + getAllFiles () { + let files: MVideoFile[] = [] + + if (Array.isArray(this.VideoFiles)) { + files = files.concat(this.VideoFiles) + } + + const hls = this.getHLSPlaylist() + if (hls) { + files = files.concat(hls.VideoFiles) + } + + return files + } + getQualityFileBy (this: T, fun: (files: MVideoFile[], it: (file: MVideoFile) => number) => MVideoFile) { // We first transcode to WebTorrent format, so try this array first if (Array.isArray(this.VideoFiles) && this.VideoFiles.length !== 0) { diff --git a/shared/extra-utils/videos/videos.ts b/shared/extra-utils/videos/videos.ts index 4d2784dde..c05c2be6c 100644 --- a/shared/extra-utils/videos/videos.ts +++ b/shared/extra-utils/videos/videos.ts @@ -217,6 +217,7 @@ async function completeVideoCheck ( expect(torrent.files).to.be.an('array') expect(torrent.files.length).to.equal(1) expect(torrent.files[0].path).to.exist.and.to.not.equal('') + expect(torrent.files[0].name).to.equal(`${videoDetails.name} ${file.resolution.id}p${extension}`) } expect(videoDetails.thumbnailPath).to.exist -- cgit v1.2.3