1
0
Fork 0

Fix playlist thumbnail generation

This commit is contained in:
Chocobozzz 2023-06-19 09:56:12 +02:00
parent 109d4a7f01
commit 53d4db2a8a
No known key found for this signature in database
GPG key ID: 583A612D890159BE
7 changed files with 25 additions and 19 deletions

View file

@ -1,6 +1,6 @@
import express from 'express'
import { join } from 'path'
import { scheduleRefreshIfNeeded } from '@server/lib/activitypub/playlists'
import { VideoMiniaturePermanentFileCache } from '@server/lib/files-cache'
import { Hooks } from '@server/lib/plugins/hooks'
import { getServerActor } from '@server/models/application/application'
import { MVideoPlaylistFull, MVideoPlaylistThumbnail, MVideoThumbnail } from '@server/types/models'
@ -18,7 +18,6 @@ import { resetSequelizeInstance } from '../../helpers/database-utils'
import { createReqFiles } from '../../helpers/express-utils'
import { logger } from '../../helpers/logger'
import { getFormattedObjects } from '../../helpers/utils'
import { CONFIG } from '../../initializers/config'
import { MIMETYPES, VIDEO_PLAYLIST_PRIVACIES } from '../../initializers/constants'
import { sequelizeTypescript } from '../../initializers/database'
import { sendCreateVideoPlaylist, sendDeleteVideoPlaylist, sendUpdateVideoPlaylist } from '../../lib/activitypub/send'
@ -496,7 +495,10 @@ async function generateThumbnailForPlaylist (videoPlaylist: MVideoPlaylistThumbn
return
}
const inputPath = join(CONFIG.STORAGE.THUMBNAILS_DIR, videoMiniature.filename)
// Ensure the file is on disk
const videoMiniaturePermanentFileCache = new VideoMiniaturePermanentFileCache()
const inputPath = await videoMiniaturePermanentFileCache.downloadRemoteFile(videoMiniature)
const thumbnailModel = await updateLocalPlaylistMiniatureFromExisting({
inputPath,
playlist: videoPlaylist,

View file

@ -4,7 +4,7 @@ import { retryTransactionWrapper } from '@server/helpers/database-utils'
import { logger, loggerTagsFactory } from '@server/helpers/logger'
import { CRAWL_REQUEST_CONCURRENCY } from '@server/initializers/constants'
import { sequelizeTypescript } from '@server/initializers/database'
import { updatePlaylistMiniatureFromUrl } from '@server/lib/thumbnail'
import { updateRemotePlaylistMiniatureFromUrl } from '@server/lib/thumbnail'
import { VideoPlaylistModel } from '@server/models/video/video-playlist'
import { VideoPlaylistElementModel } from '@server/models/video/video-playlist-element'
import { FilteredModelAttributes } from '@server/types'
@ -104,7 +104,7 @@ async function updatePlaylistThumbnail (playlistObject: PlaylistObject, playlist
let thumbnailModel: MThumbnail
try {
thumbnailModel = await updatePlaylistMiniatureFromUrl({ downloadUrl: playlistObject.icon.url, playlist })
thumbnailModel = await updateRemotePlaylistMiniatureFromUrl({ downloadUrl: playlistObject.icon.url, playlist })
await playlist.setAndSaveThumbnail(thumbnailModel, undefined)
} catch (err) {
logger.warn('Cannot set thumbnail of %s.', playlistObject.id, { err, ...lTags(playlistObject.id, playlist.uuid, playlist.url) })

View file

@ -1,7 +1,7 @@
import { CreationAttributes, Transaction } from 'sequelize/types'
import { deleteAllModels, filterNonExistingModels } from '@server/helpers/database-utils'
import { logger, LoggerTagsFn } from '@server/helpers/logger'
import { updateRemoteThumbnail } from '@server/lib/thumbnail'
import { updateRemoteVideoThumbnail } from '@server/lib/thumbnail'
import { setVideoTags } from '@server/lib/video'
import { StoryboardModel } from '@server/models/video/storyboard'
import { VideoCaptionModel } from '@server/models/video/video-caption'
@ -48,7 +48,7 @@ export abstract class APVideoAbstractBuilder {
return undefined
}
const miniatureModel = updateRemoteThumbnail({
const miniatureModel = updateRemoteVideoThumbnail({
fileUrl: miniatureIcon.url,
video,
type: ThumbnailType.MINIATURE,
@ -63,12 +63,12 @@ export abstract class APVideoAbstractBuilder {
const previewIcon = getPreviewFromIcons(this.videoObject)
if (!previewIcon) return
const previewModel = updateRemoteThumbnail({
const previewModel = updateRemoteVideoThumbnail({
fileUrl: previewIcon.url,
video,
type: ThumbnailType.PREVIEW,
size: previewIcon,
onDisk: false // Don't fetch the preview that could be big, create a placeholder instead
onDisk: false // Lazy download remote previews
})
await video.addAndSaveThumbnail(previewModel, t)

View file

@ -66,10 +66,10 @@ export abstract class AbstractPermanentFileCache <M extends ImageModel> {
})
}
private async downloadRemoteFile (image: M) {
async downloadRemoteFile (image: M) {
logger.info('Download remote image %s lazily.', image.fileUrl)
await this.downloadImage({
const destination = await this.downloadImage({
filename: image.filename,
fileUrl: image.fileUrl,
size: this.getImageSize(image)
@ -78,6 +78,8 @@ export abstract class AbstractPermanentFileCache <M extends ImageModel> {
image.onDisk = true
image.save()
.catch(err => logger.error('Cannot save new image disk state.', { err }))
return destination
}
private onServeError (options: {

View file

@ -39,7 +39,7 @@ function updateLocalPlaylistMiniatureFromExisting (options: {
})
}
function updatePlaylistMiniatureFromUrl (options: {
function updateRemotePlaylistMiniatureFromUrl (options: {
downloadUrl: string
playlist: MVideoPlaylistThumbnail
size?: ImageSize
@ -127,7 +127,7 @@ function generateLocalVideoMiniature (options: {
// ---------------------------------------------------------------------------
function updateVideoMiniatureFromUrl (options: {
function updateLocalVideoMiniatureFromUrl (options: {
downloadUrl: string
video: MVideoThumbnail
type: ThumbnailType
@ -159,7 +159,7 @@ function updateVideoMiniatureFromUrl (options: {
return updateThumbnailFromFunction({ thumbnailCreator, filename, height, width, type, existingThumbnail, fileUrl, onDisk: true })
}
function updateRemoteThumbnail (options: {
function updateRemoteVideoThumbnail (options: {
fileUrl: string
video: MVideoThumbnail
type: ThumbnailType
@ -189,10 +189,10 @@ function updateRemoteThumbnail (options: {
export {
generateLocalVideoMiniature,
updateVideoMiniatureFromUrl,
updateLocalVideoMiniatureFromUrl,
updateLocalVideoMiniatureFromExisting,
updateRemoteThumbnail,
updatePlaylistMiniatureFromUrl,
updateRemoteVideoThumbnail,
updateRemotePlaylistMiniatureFromUrl,
updateLocalPlaylistMiniatureFromExisting
}

View file

@ -29,7 +29,7 @@ import {
} from '@server/types/models'
import { ThumbnailType, VideoImportCreate, VideoImportPayload, VideoImportState, VideoPrivacy, VideoState } from '@shared/models'
import { getLocalVideoActivityPubUrl } from './activitypub/url'
import { updateLocalVideoMiniatureFromExisting, updateVideoMiniatureFromUrl } from './thumbnail'
import { updateLocalVideoMiniatureFromExisting, updateLocalVideoMiniatureFromUrl } from './thumbnail'
import { VideoPasswordModel } from '@server/models/video/video-password'
class YoutubeDlImportError extends Error {
@ -266,7 +266,7 @@ async function forgeThumbnail ({ inputPath, video, downloadUrl, type }: {
if (downloadUrl) {
try {
return await updateVideoMiniatureFromUrl({ downloadUrl, video, type })
return await updateLocalVideoMiniatureFromUrl({ downloadUrl, video, type })
} catch (err) {
logger.warn('Cannot process thumbnail %s from youtube-dl.', downloadUrl, { err })
}

View file

@ -24,6 +24,8 @@ async function downloadImage (options: {
throw err
}
return destPath
}
module.exports = downloadImage