aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/lib/thumbnail.ts
diff options
context:
space:
mode:
Diffstat (limited to 'server/lib/thumbnail.ts')
-rw-r--r--server/lib/thumbnail.ts110
1 files changed, 85 insertions, 25 deletions
diff --git a/server/lib/thumbnail.ts b/server/lib/thumbnail.ts
index 33aa7159c..55478299c 100644
--- a/server/lib/thumbnail.ts
+++ b/server/lib/thumbnail.ts
@@ -1,33 +1,48 @@
1import { join } from 'path'
2
3import { ThumbnailType } from '../../shared/models/videos/thumbnail.type'
1import { generateImageFromVideoFile } from '../helpers/ffmpeg-utils' 4import { generateImageFromVideoFile } from '../helpers/ffmpeg-utils'
5import { processImage } from '../helpers/image-utils'
6import { downloadImage } from '../helpers/requests'
2import { CONFIG } from '../initializers/config' 7import { CONFIG } from '../initializers/config'
3import { ASSETS_PATH, PREVIEWS_SIZE, THUMBNAILS_SIZE } from '../initializers/constants' 8import { ASSETS_PATH, PREVIEWS_SIZE, THUMBNAILS_SIZE } from '../initializers/constants'
4import { ThumbnailModel } from '../models/video/thumbnail' 9import { ThumbnailModel } from '../models/video/thumbnail'
5import { ThumbnailType } from '../../shared/models/videos/thumbnail.type'
6import { processImage } from '../helpers/image-utils'
7import { join } from 'path'
8import { downloadImage } from '../helpers/requests'
9import { MVideoPlaylistThumbnail } from '../types/models/video/video-playlist'
10import { MVideoFile, MVideoThumbnail } from '../types/models' 10import { MVideoFile, MVideoThumbnail } from '../types/models'
11import { MThumbnail } from '../types/models/video/thumbnail' 11import { MThumbnail } from '../types/models/video/thumbnail'
12import { MVideoPlaylistThumbnail } from '../types/models/video/video-playlist'
12import { getVideoFilePath } from './video-paths' 13import { getVideoFilePath } from './video-paths'
13 14
14type ImageSize = { height: number, width: number } 15type ImageSize = { height: number, width: number }
15 16
16function createPlaylistMiniatureFromExisting ( 17function createPlaylistMiniatureFromExisting (options: {
17 inputPath: string, 18 inputPath: string
18 playlist: MVideoPlaylistThumbnail, 19 playlist: MVideoPlaylistThumbnail
19 automaticallyGenerated: boolean, 20 automaticallyGenerated: boolean
20 keepOriginal = false, 21 keepOriginal?: boolean // default to false
21 size?: ImageSize 22 size?: ImageSize
22) { 23}) {
24 const { inputPath, playlist, automaticallyGenerated, keepOriginal = false, size } = options
23 const { filename, outputPath, height, width, existingThumbnail } = buildMetadataFromPlaylist(playlist, size) 25 const { filename, outputPath, height, width, existingThumbnail } = buildMetadataFromPlaylist(playlist, size)
24 const type = ThumbnailType.MINIATURE 26 const type = ThumbnailType.MINIATURE
25 27
26 const thumbnailCreator = () => processImage(inputPath, outputPath, { width, height }, keepOriginal) 28 const thumbnailCreator = () => processImage(inputPath, outputPath, { width, height }, keepOriginal)
27 return createThumbnailFromFunction({ thumbnailCreator, filename, height, width, type, automaticallyGenerated, existingThumbnail }) 29 return createThumbnailFromFunction({
30 thumbnailCreator,
31 filename,
32 height,
33 width,
34 type,
35 automaticallyGenerated,
36 existingThumbnail
37 })
28} 38}
29 39
30function createPlaylistMiniatureFromUrl (downloadUrl: string, playlist: MVideoPlaylistThumbnail, size?: ImageSize) { 40function createPlaylistMiniatureFromUrl (options: {
41 downloadUrl: string
42 playlist: MVideoPlaylistThumbnail
43 size?: ImageSize
44}) {
45 const { downloadUrl, playlist, size } = options
31 const { filename, basePath, height, width, existingThumbnail } = buildMetadataFromPlaylist(playlist, size) 46 const { filename, basePath, height, width, existingThumbnail } = buildMetadataFromPlaylist(playlist, size)
32 const type = ThumbnailType.MINIATURE 47 const type = ThumbnailType.MINIATURE
33 48
@@ -40,7 +55,13 @@ function createPlaylistMiniatureFromUrl (downloadUrl: string, playlist: MVideoPl
40 return createThumbnailFromFunction({ thumbnailCreator, filename, height, width, type, existingThumbnail, fileUrl }) 55 return createThumbnailFromFunction({ thumbnailCreator, filename, height, width, type, existingThumbnail, fileUrl })
41} 56}
42 57
43function createVideoMiniatureFromUrl (downloadUrl: string, video: MVideoThumbnail, type: ThumbnailType, size?: ImageSize) { 58function createVideoMiniatureFromUrl (options: {
59 downloadUrl: string
60 video: MVideoThumbnail
61 type: ThumbnailType
62 size?: ImageSize
63}) {
64 const { downloadUrl, video, type, size } = options
44 const { filename, basePath, height, width, existingThumbnail } = buildMetadataFromVideo(video, type, size) 65 const { filename, basePath, height, width, existingThumbnail } = buildMetadataFromVideo(video, type, size)
45 66
46 // Only save the file URL if it is a remote video 67 // Only save the file URL if it is a remote video
@@ -58,17 +79,31 @@ function createVideoMiniatureFromExisting (options: {
58 type: ThumbnailType 79 type: ThumbnailType
59 automaticallyGenerated: boolean 80 automaticallyGenerated: boolean
60 size?: ImageSize 81 size?: ImageSize
61 keepOriginal?: boolean 82 keepOriginal?: boolean // default to false
62}) { 83}) {
63 const { inputPath, video, type, automaticallyGenerated, size, keepOriginal } = options 84 const { inputPath, video, type, automaticallyGenerated, size, keepOriginal = false } = options
64 85
65 const { filename, outputPath, height, width, existingThumbnail } = buildMetadataFromVideo(video, type, size) 86 const { filename, outputPath, height, width, existingThumbnail } = buildMetadataFromVideo(video, type, size)
66 const thumbnailCreator = () => processImage(inputPath, outputPath, { width, height }, keepOriginal) 87 const thumbnailCreator = () => processImage(inputPath, outputPath, { width, height }, keepOriginal)
67 88
68 return createThumbnailFromFunction({ thumbnailCreator, filename, height, width, type, automaticallyGenerated, existingThumbnail }) 89 return createThumbnailFromFunction({
90 thumbnailCreator,
91 filename,
92 height,
93 width,
94 type,
95 automaticallyGenerated,
96 existingThumbnail
97 })
69} 98}
70 99
71function generateVideoMiniature (video: MVideoThumbnail, videoFile: MVideoFile, type: ThumbnailType) { 100function generateVideoMiniature (options: {
101 video: MVideoThumbnail
102 videoFile: MVideoFile
103 type: ThumbnailType
104}) {
105 const { video, videoFile, type } = options
106
72 const input = getVideoFilePath(video, videoFile) 107 const input = getVideoFilePath(video, videoFile)
73 108
74 const { filename, basePath, height, width, existingThumbnail, outputPath } = buildMetadataFromVideo(video, type) 109 const { filename, basePath, height, width, existingThumbnail, outputPath } = buildMetadataFromVideo(video, type)
@@ -76,10 +111,24 @@ function generateVideoMiniature (video: MVideoThumbnail, videoFile: MVideoFile,
76 ? () => processImage(ASSETS_PATH.DEFAULT_AUDIO_BACKGROUND, outputPath, { width, height }, true) 111 ? () => processImage(ASSETS_PATH.DEFAULT_AUDIO_BACKGROUND, outputPath, { width, height }, true)
77 : () => generateImageFromVideoFile(input, basePath, filename, { height, width }) 112 : () => generateImageFromVideoFile(input, basePath, filename, { height, width })
78 113
79 return createThumbnailFromFunction({ thumbnailCreator, filename, height, width, type, automaticallyGenerated: true, existingThumbnail }) 114 return createThumbnailFromFunction({
115 thumbnailCreator,
116 filename,
117 height,
118 width,
119 type,
120 automaticallyGenerated: true,
121 existingThumbnail
122 })
80} 123}
81 124
82function createPlaceholderThumbnail (fileUrl: string, video: MVideoThumbnail, type: ThumbnailType, size: ImageSize) { 125function createPlaceholderThumbnail (options: {
126 fileUrl: string
127 video: MVideoThumbnail
128 type: ThumbnailType
129 size: ImageSize
130}) {
131 const { fileUrl, video, type, size } = options
83 const { filename, height, width, existingThumbnail } = buildMetadataFromVideo(video, type, size) 132 const { filename, height, width, existingThumbnail } = buildMetadataFromVideo(video, type, size)
84 133
85 const thumbnail = existingThumbnail || new ThumbnailModel() 134 const thumbnail = existingThumbnail || new ThumbnailModel()
@@ -164,12 +213,22 @@ async function createThumbnailFromFunction (parameters: {
164 fileUrl?: string 213 fileUrl?: string
165 existingThumbnail?: MThumbnail 214 existingThumbnail?: MThumbnail
166}) { 215}) {
167 const { thumbnailCreator, filename, width, height, type, existingThumbnail, automaticallyGenerated = null, fileUrl = null } = parameters 216 const {
168 217 thumbnailCreator,
169 // Remove old file 218 filename,
170 if (existingThumbnail) await existingThumbnail.removeThumbnail() 219 width,
220 height,
221 type,
222 existingThumbnail,
223 automaticallyGenerated = null,
224 fileUrl = null
225 } = parameters
226
227 const oldFilename = existingThumbnail
228 ? existingThumbnail.filename
229 : undefined
171 230
172 const thumbnail = existingThumbnail || new ThumbnailModel() 231 const thumbnail: MThumbnail = existingThumbnail || new ThumbnailModel()
173 232
174 thumbnail.filename = filename 233 thumbnail.filename = filename
175 thumbnail.height = height 234 thumbnail.height = height
@@ -177,6 +236,7 @@ async function createThumbnailFromFunction (parameters: {
177 thumbnail.type = type 236 thumbnail.type = type
178 thumbnail.fileUrl = fileUrl 237 thumbnail.fileUrl = fileUrl
179 thumbnail.automaticallyGenerated = automaticallyGenerated 238 thumbnail.automaticallyGenerated = automaticallyGenerated
239 thumbnail.previousThumbnailFilename = oldFilename
180 240
181 await thumbnailCreator() 241 await thumbnailCreator()
182 242