]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blobdiff - server/lib/thumbnail.ts
Merge branch 'release/3.2.0' into develop
[github/Chocobozzz/PeerTube.git] / server / lib / thumbnail.ts
index 4bad8d6ca84e8a027bbf15e00a62188c4420ff35..cfee69cfc50df4ad6ef9733357c26f619a87662d 100644 (file)
@@ -1,18 +1,18 @@
-import { copy } from 'fs-extra'
 import { join } from 'path'
+
 import { ThumbnailType } from '../../shared/models/videos/thumbnail.type'
 import { generateImageFromVideoFile } from '../helpers/ffmpeg-utils'
-import { processImage } from '../helpers/image-utils'
+import { generateImageFilename, processImage } from '../helpers/image-utils'
 import { downloadImage } from '../helpers/requests'
 import { CONFIG } from '../initializers/config'
 import { ASSETS_PATH, PREVIEWS_SIZE, THUMBNAILS_SIZE } from '../initializers/constants'
 import { ThumbnailModel } from '../models/video/thumbnail'
-import { MVideoFile, MVideoThumbnail } from '../types/models'
+import { MVideoFile, MVideoThumbnail, MVideoUUID } from '../types/models'
 import { MThumbnail } from '../types/models/video/thumbnail'
 import { MVideoPlaylistThumbnail } from '../types/models/video/video-playlist'
 import { getVideoFilePath } from './video-paths'
 
-type ImageSize = { height: number, width: number }
+type ImageSize = { height?: number, width?: number }
 
 function createPlaylistMiniatureFromExisting (options: {
   inputPath: string
@@ -62,24 +62,24 @@ function createVideoMiniatureFromUrl (options: {
   size?: ImageSize
 }) {
   const { downloadUrl, video, type, size } = options
-  const { filename, basePath, height, width, existingThumbnail } = buildMetadataFromVideo(video, type, size)
+  const { filename: updatedFilename, basePath, height, width, existingThumbnail } = buildMetadataFromVideo(video, type, size)
 
   // Only save the file URL if it is a remote video
   const fileUrl = video.isOwned()
     ? null
     : downloadUrl
 
-  // If the thumbnail URL did not change
-  const existingUrl = existingThumbnail
-    ? existingThumbnail.fileUrl
-    : null
+  const thumbnailUrlChanged = hasThumbnailUrlChanged(existingThumbnail, downloadUrl, video)
+
+  // Do not change the thumbnail filename if the file did not change
+  const filename = thumbnailUrlChanged
+    ? updatedFilename
+    : existingThumbnail.filename
 
-  // If the thumbnail URL did not change and has a unique filename (introduced in 3.2), avoid thumbnail processing
-  const thumbnailUrlChanged = !existingUrl || existingUrl !== downloadUrl || downloadUrl.endsWith(`${video.uuid}.jpg`)
   const thumbnailCreator = () => {
     if (thumbnailUrlChanged) return downloadImage(downloadUrl, basePath, filename, { width, height })
 
-    return copy(existingThumbnail.getPath(), ThumbnailModel.buildPath(type, filename))
+    return Promise.resolve()
   }
 
   return createThumbnailFromFunction({ thumbnailCreator, filename, height, width, type, existingThumbnail, fileUrl })
@@ -141,10 +141,17 @@ function createPlaceholderThumbnail (options: {
   size: ImageSize
 }) {
   const { fileUrl, video, type, size } = options
-  const { filename, height, width, existingThumbnail } = buildMetadataFromVideo(video, type, size)
+  const { filename: updatedFilename, height, width, existingThumbnail } = buildMetadataFromVideo(video, type, size)
+
+  const thumbnailUrlChanged = hasThumbnailUrlChanged(existingThumbnail, fileUrl, video)
 
   const thumbnail = existingThumbnail || new ThumbnailModel()
 
+  // Do not change the thumbnail filename if the file did not change
+  const filename = thumbnailUrlChanged
+    ? updatedFilename
+    : existingThumbnail.filename
+
   thumbnail.filename = filename
   thumbnail.height = height
   thumbnail.width = width
@@ -165,6 +172,15 @@ export {
   createPlaylistMiniatureFromExisting
 }
 
+function hasThumbnailUrlChanged (existingThumbnail: MThumbnail, downloadUrl: string, video: MVideoUUID) {
+  const existingUrl = existingThumbnail
+    ? existingThumbnail.fileUrl
+    : null
+
+  // If the thumbnail URL did not change and has a unique filename (introduced in 3.1), avoid thumbnail processing
+  return !existingUrl || existingUrl !== downloadUrl || downloadUrl.endsWith(`${video.uuid}.jpg`)
+}
+
 function buildMetadataFromPlaylist (playlist: MVideoPlaylistThumbnail, size: ImageSize) {
   const filename = playlist.generateThumbnailName()
   const basePath = CONFIG.STORAGE.THUMBNAILS_DIR
@@ -185,7 +201,7 @@ function buildMetadataFromVideo (video: MVideoThumbnail, type: ThumbnailType, si
     : undefined
 
   if (type === ThumbnailType.MINIATURE) {
-    const filename = video.generateThumbnailName()
+    const filename = generateImageFilename()
     const basePath = CONFIG.STORAGE.THUMBNAILS_DIR
 
     return {
@@ -199,7 +215,7 @@ function buildMetadataFromVideo (video: MVideoThumbnail, type: ThumbnailType, si
   }
 
   if (type === ThumbnailType.PREVIEW) {
-    const filename = video.generatePreviewName()
+    const filename = generateImageFilename()
     const basePath = CONFIG.STORAGE.PREVIEWS_DIR
 
     return {
@@ -236,7 +252,7 @@ async function createThumbnailFromFunction (parameters: {
     fileUrl = null
   } = parameters
 
-  const oldFilename = existingThumbnail
+  const oldFilename = existingThumbnail && existingThumbnail.filename !== filename
     ? existingThumbnail.filename
     : undefined
 
@@ -248,7 +264,8 @@ async function createThumbnailFromFunction (parameters: {
   thumbnail.type = type
   thumbnail.fileUrl = fileUrl
   thumbnail.automaticallyGenerated = automaticallyGenerated
-  thumbnail.previousThumbnailFilename = oldFilename
+
+  if (oldFilename) thumbnail.previousThumbnailFilename = oldFilename
 
   await thumbnailCreator()