aboutsummaryrefslogtreecommitdiffhomepage
path: root/server
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2023-06-19 09:56:12 +0200
committerChocobozzz <me@florianbigard.com>2023-06-29 10:19:54 +0200
commit53d4db2a8a11407165da6525cad3198439686d36 (patch)
treebcdacea812eb741eb25916a137d6f9d1bcc7704c /server
parent109d4a7f017e5ba18045f308158a71399a1b08cd (diff)
downloadPeerTube-53d4db2a8a11407165da6525cad3198439686d36.tar.gz
PeerTube-53d4db2a8a11407165da6525cad3198439686d36.tar.zst
PeerTube-53d4db2a8a11407165da6525cad3198439686d36.zip
Fix playlist thumbnail generation
Diffstat (limited to 'server')
-rw-r--r--server/controllers/api/video-playlist.ts8
-rw-r--r--server/lib/activitypub/playlists/create-update.ts4
-rw-r--r--server/lib/activitypub/videos/shared/abstract-builder.ts8
-rw-r--r--server/lib/files-cache/shared/abstract-permanent-file-cache.ts6
-rw-r--r--server/lib/thumbnail.ts12
-rw-r--r--server/lib/video-pre-import.ts4
-rw-r--r--server/lib/worker/workers/image-downloader.ts2
7 files changed, 25 insertions, 19 deletions
diff --git a/server/controllers/api/video-playlist.ts b/server/controllers/api/video-playlist.ts
index 1568ee597..304f1ddfb 100644
--- a/server/controllers/api/video-playlist.ts
+++ b/server/controllers/api/video-playlist.ts
@@ -1,6 +1,6 @@
1import express from 'express' 1import express from 'express'
2import { join } from 'path'
3import { scheduleRefreshIfNeeded } from '@server/lib/activitypub/playlists' 2import { scheduleRefreshIfNeeded } from '@server/lib/activitypub/playlists'
3import { VideoMiniaturePermanentFileCache } from '@server/lib/files-cache'
4import { Hooks } from '@server/lib/plugins/hooks' 4import { Hooks } from '@server/lib/plugins/hooks'
5import { getServerActor } from '@server/models/application/application' 5import { getServerActor } from '@server/models/application/application'
6import { MVideoPlaylistFull, MVideoPlaylistThumbnail, MVideoThumbnail } from '@server/types/models' 6import { MVideoPlaylistFull, MVideoPlaylistThumbnail, MVideoThumbnail } from '@server/types/models'
@@ -18,7 +18,6 @@ import { resetSequelizeInstance } from '../../helpers/database-utils'
18import { createReqFiles } from '../../helpers/express-utils' 18import { createReqFiles } from '../../helpers/express-utils'
19import { logger } from '../../helpers/logger' 19import { logger } from '../../helpers/logger'
20import { getFormattedObjects } from '../../helpers/utils' 20import { getFormattedObjects } from '../../helpers/utils'
21import { CONFIG } from '../../initializers/config'
22import { MIMETYPES, VIDEO_PLAYLIST_PRIVACIES } from '../../initializers/constants' 21import { MIMETYPES, VIDEO_PLAYLIST_PRIVACIES } from '../../initializers/constants'
23import { sequelizeTypescript } from '../../initializers/database' 22import { sequelizeTypescript } from '../../initializers/database'
24import { sendCreateVideoPlaylist, sendDeleteVideoPlaylist, sendUpdateVideoPlaylist } from '../../lib/activitypub/send' 23import { sendCreateVideoPlaylist, sendDeleteVideoPlaylist, sendUpdateVideoPlaylist } from '../../lib/activitypub/send'
@@ -496,7 +495,10 @@ async function generateThumbnailForPlaylist (videoPlaylist: MVideoPlaylistThumbn
496 return 495 return
497 } 496 }
498 497
499 const inputPath = join(CONFIG.STORAGE.THUMBNAILS_DIR, videoMiniature.filename) 498 // Ensure the file is on disk
499 const videoMiniaturePermanentFileCache = new VideoMiniaturePermanentFileCache()
500 const inputPath = await videoMiniaturePermanentFileCache.downloadRemoteFile(videoMiniature)
501
500 const thumbnailModel = await updateLocalPlaylistMiniatureFromExisting({ 502 const thumbnailModel = await updateLocalPlaylistMiniatureFromExisting({
501 inputPath, 503 inputPath,
502 playlist: videoPlaylist, 504 playlist: videoPlaylist,
diff --git a/server/lib/activitypub/playlists/create-update.ts b/server/lib/activitypub/playlists/create-update.ts
index 920d3943a..b24299f29 100644
--- a/server/lib/activitypub/playlists/create-update.ts
+++ b/server/lib/activitypub/playlists/create-update.ts
@@ -4,7 +4,7 @@ import { retryTransactionWrapper } from '@server/helpers/database-utils'
4import { logger, loggerTagsFactory } from '@server/helpers/logger' 4import { logger, loggerTagsFactory } from '@server/helpers/logger'
5import { CRAWL_REQUEST_CONCURRENCY } from '@server/initializers/constants' 5import { CRAWL_REQUEST_CONCURRENCY } from '@server/initializers/constants'
6import { sequelizeTypescript } from '@server/initializers/database' 6import { sequelizeTypescript } from '@server/initializers/database'
7import { updatePlaylistMiniatureFromUrl } from '@server/lib/thumbnail' 7import { updateRemotePlaylistMiniatureFromUrl } from '@server/lib/thumbnail'
8import { VideoPlaylistModel } from '@server/models/video/video-playlist' 8import { VideoPlaylistModel } from '@server/models/video/video-playlist'
9import { VideoPlaylistElementModel } from '@server/models/video/video-playlist-element' 9import { VideoPlaylistElementModel } from '@server/models/video/video-playlist-element'
10import { FilteredModelAttributes } from '@server/types' 10import { FilteredModelAttributes } from '@server/types'
@@ -104,7 +104,7 @@ async function updatePlaylistThumbnail (playlistObject: PlaylistObject, playlist
104 let thumbnailModel: MThumbnail 104 let thumbnailModel: MThumbnail
105 105
106 try { 106 try {
107 thumbnailModel = await updatePlaylistMiniatureFromUrl({ downloadUrl: playlistObject.icon.url, playlist }) 107 thumbnailModel = await updateRemotePlaylistMiniatureFromUrl({ downloadUrl: playlistObject.icon.url, playlist })
108 await playlist.setAndSaveThumbnail(thumbnailModel, undefined) 108 await playlist.setAndSaveThumbnail(thumbnailModel, undefined)
109 } catch (err) { 109 } catch (err) {
110 logger.warn('Cannot set thumbnail of %s.', playlistObject.id, { err, ...lTags(playlistObject.id, playlist.uuid, playlist.url) }) 110 logger.warn('Cannot set thumbnail of %s.', playlistObject.id, { err, ...lTags(playlistObject.id, playlist.uuid, playlist.url) })
diff --git a/server/lib/activitypub/videos/shared/abstract-builder.ts b/server/lib/activitypub/videos/shared/abstract-builder.ts
index 4f74316d3..8b6a7fd75 100644
--- a/server/lib/activitypub/videos/shared/abstract-builder.ts
+++ b/server/lib/activitypub/videos/shared/abstract-builder.ts
@@ -1,7 +1,7 @@
1import { CreationAttributes, Transaction } from 'sequelize/types' 1import { CreationAttributes, Transaction } from 'sequelize/types'
2import { deleteAllModels, filterNonExistingModels } from '@server/helpers/database-utils' 2import { deleteAllModels, filterNonExistingModels } from '@server/helpers/database-utils'
3import { logger, LoggerTagsFn } from '@server/helpers/logger' 3import { logger, LoggerTagsFn } from '@server/helpers/logger'
4import { updateRemoteThumbnail } from '@server/lib/thumbnail' 4import { updateRemoteVideoThumbnail } from '@server/lib/thumbnail'
5import { setVideoTags } from '@server/lib/video' 5import { setVideoTags } from '@server/lib/video'
6import { StoryboardModel } from '@server/models/video/storyboard' 6import { StoryboardModel } from '@server/models/video/storyboard'
7import { VideoCaptionModel } from '@server/models/video/video-caption' 7import { VideoCaptionModel } from '@server/models/video/video-caption'
@@ -48,7 +48,7 @@ export abstract class APVideoAbstractBuilder {
48 return undefined 48 return undefined
49 } 49 }
50 50
51 const miniatureModel = updateRemoteThumbnail({ 51 const miniatureModel = updateRemoteVideoThumbnail({
52 fileUrl: miniatureIcon.url, 52 fileUrl: miniatureIcon.url,
53 video, 53 video,
54 type: ThumbnailType.MINIATURE, 54 type: ThumbnailType.MINIATURE,
@@ -63,12 +63,12 @@ export abstract class APVideoAbstractBuilder {
63 const previewIcon = getPreviewFromIcons(this.videoObject) 63 const previewIcon = getPreviewFromIcons(this.videoObject)
64 if (!previewIcon) return 64 if (!previewIcon) return
65 65
66 const previewModel = updateRemoteThumbnail({ 66 const previewModel = updateRemoteVideoThumbnail({
67 fileUrl: previewIcon.url, 67 fileUrl: previewIcon.url,
68 video, 68 video,
69 type: ThumbnailType.PREVIEW, 69 type: ThumbnailType.PREVIEW,
70 size: previewIcon, 70 size: previewIcon,
71 onDisk: false // Don't fetch the preview that could be big, create a placeholder instead 71 onDisk: false // Lazy download remote previews
72 }) 72 })
73 73
74 await video.addAndSaveThumbnail(previewModel, t) 74 await video.addAndSaveThumbnail(previewModel, t)
diff --git a/server/lib/files-cache/shared/abstract-permanent-file-cache.ts b/server/lib/files-cache/shared/abstract-permanent-file-cache.ts
index 22596c3eb..297461035 100644
--- a/server/lib/files-cache/shared/abstract-permanent-file-cache.ts
+++ b/server/lib/files-cache/shared/abstract-permanent-file-cache.ts
@@ -66,10 +66,10 @@ export abstract class AbstractPermanentFileCache <M extends ImageModel> {
66 }) 66 })
67 } 67 }
68 68
69 private async downloadRemoteFile (image: M) { 69 async downloadRemoteFile (image: M) {
70 logger.info('Download remote image %s lazily.', image.fileUrl) 70 logger.info('Download remote image %s lazily.', image.fileUrl)
71 71
72 await this.downloadImage({ 72 const destination = await this.downloadImage({
73 filename: image.filename, 73 filename: image.filename,
74 fileUrl: image.fileUrl, 74 fileUrl: image.fileUrl,
75 size: this.getImageSize(image) 75 size: this.getImageSize(image)
@@ -78,6 +78,8 @@ export abstract class AbstractPermanentFileCache <M extends ImageModel> {
78 image.onDisk = true 78 image.onDisk = true
79 image.save() 79 image.save()
80 .catch(err => logger.error('Cannot save new image disk state.', { err })) 80 .catch(err => logger.error('Cannot save new image disk state.', { err }))
81
82 return destination
81 } 83 }
82 84
83 private onServeError (options: { 85 private onServeError (options: {
diff --git a/server/lib/thumbnail.ts b/server/lib/thumbnail.ts
index 90f5dc2c8..d95442795 100644
--- a/server/lib/thumbnail.ts
+++ b/server/lib/thumbnail.ts
@@ -39,7 +39,7 @@ function updateLocalPlaylistMiniatureFromExisting (options: {
39 }) 39 })
40} 40}
41 41
42function updatePlaylistMiniatureFromUrl (options: { 42function updateRemotePlaylistMiniatureFromUrl (options: {
43 downloadUrl: string 43 downloadUrl: string
44 playlist: MVideoPlaylistThumbnail 44 playlist: MVideoPlaylistThumbnail
45 size?: ImageSize 45 size?: ImageSize
@@ -127,7 +127,7 @@ function generateLocalVideoMiniature (options: {
127 127
128// --------------------------------------------------------------------------- 128// ---------------------------------------------------------------------------
129 129
130function updateVideoMiniatureFromUrl (options: { 130function updateLocalVideoMiniatureFromUrl (options: {
131 downloadUrl: string 131 downloadUrl: string
132 video: MVideoThumbnail 132 video: MVideoThumbnail
133 type: ThumbnailType 133 type: ThumbnailType
@@ -159,7 +159,7 @@ function updateVideoMiniatureFromUrl (options: {
159 return updateThumbnailFromFunction({ thumbnailCreator, filename, height, width, type, existingThumbnail, fileUrl, onDisk: true }) 159 return updateThumbnailFromFunction({ thumbnailCreator, filename, height, width, type, existingThumbnail, fileUrl, onDisk: true })
160} 160}
161 161
162function updateRemoteThumbnail (options: { 162function updateRemoteVideoThumbnail (options: {
163 fileUrl: string 163 fileUrl: string
164 video: MVideoThumbnail 164 video: MVideoThumbnail
165 type: ThumbnailType 165 type: ThumbnailType
@@ -189,10 +189,10 @@ function updateRemoteThumbnail (options: {
189 189
190export { 190export {
191 generateLocalVideoMiniature, 191 generateLocalVideoMiniature,
192 updateVideoMiniatureFromUrl, 192 updateLocalVideoMiniatureFromUrl,
193 updateLocalVideoMiniatureFromExisting, 193 updateLocalVideoMiniatureFromExisting,
194 updateRemoteThumbnail, 194 updateRemoteVideoThumbnail,
195 updatePlaylistMiniatureFromUrl, 195 updateRemotePlaylistMiniatureFromUrl,
196 updateLocalPlaylistMiniatureFromExisting 196 updateLocalPlaylistMiniatureFromExisting
197} 197}
198 198
diff --git a/server/lib/video-pre-import.ts b/server/lib/video-pre-import.ts
index 1471d4091..381f1f535 100644
--- a/server/lib/video-pre-import.ts
+++ b/server/lib/video-pre-import.ts
@@ -29,7 +29,7 @@ import {
29} from '@server/types/models' 29} from '@server/types/models'
30import { ThumbnailType, VideoImportCreate, VideoImportPayload, VideoImportState, VideoPrivacy, VideoState } from '@shared/models' 30import { ThumbnailType, VideoImportCreate, VideoImportPayload, VideoImportState, VideoPrivacy, VideoState } from '@shared/models'
31import { getLocalVideoActivityPubUrl } from './activitypub/url' 31import { getLocalVideoActivityPubUrl } from './activitypub/url'
32import { updateLocalVideoMiniatureFromExisting, updateVideoMiniatureFromUrl } from './thumbnail' 32import { updateLocalVideoMiniatureFromExisting, updateLocalVideoMiniatureFromUrl } from './thumbnail'
33import { VideoPasswordModel } from '@server/models/video/video-password' 33import { VideoPasswordModel } from '@server/models/video/video-password'
34 34
35class YoutubeDlImportError extends Error { 35class YoutubeDlImportError extends Error {
@@ -266,7 +266,7 @@ async function forgeThumbnail ({ inputPath, video, downloadUrl, type }: {
266 266
267 if (downloadUrl) { 267 if (downloadUrl) {
268 try { 268 try {
269 return await updateVideoMiniatureFromUrl({ downloadUrl, video, type }) 269 return await updateLocalVideoMiniatureFromUrl({ downloadUrl, video, type })
270 } catch (err) { 270 } catch (err) {
271 logger.warn('Cannot process thumbnail %s from youtube-dl.', downloadUrl, { err }) 271 logger.warn('Cannot process thumbnail %s from youtube-dl.', downloadUrl, { err })
272 } 272 }
diff --git a/server/lib/worker/workers/image-downloader.ts b/server/lib/worker/workers/image-downloader.ts
index 4b32f723e..209594589 100644
--- a/server/lib/worker/workers/image-downloader.ts
+++ b/server/lib/worker/workers/image-downloader.ts
@@ -24,6 +24,8 @@ async function downloadImage (options: {
24 24
25 throw err 25 throw err
26 } 26 }
27
28 return destPath
27} 29}
28 30
29module.exports = downloadImage 31module.exports = downloadImage