diff options
Diffstat (limited to 'server/lib/thumbnail.ts')
-rw-r--r-- | server/lib/thumbnail.ts | 110 |
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 @@ | |||
1 | import { join } from 'path' | ||
2 | |||
3 | import { ThumbnailType } from '../../shared/models/videos/thumbnail.type' | ||
1 | import { generateImageFromVideoFile } from '../helpers/ffmpeg-utils' | 4 | import { generateImageFromVideoFile } from '../helpers/ffmpeg-utils' |
5 | import { processImage } from '../helpers/image-utils' | ||
6 | import { downloadImage } from '../helpers/requests' | ||
2 | import { CONFIG } from '../initializers/config' | 7 | import { CONFIG } from '../initializers/config' |
3 | import { ASSETS_PATH, PREVIEWS_SIZE, THUMBNAILS_SIZE } from '../initializers/constants' | 8 | import { ASSETS_PATH, PREVIEWS_SIZE, THUMBNAILS_SIZE } from '../initializers/constants' |
4 | import { ThumbnailModel } from '../models/video/thumbnail' | 9 | import { ThumbnailModel } from '../models/video/thumbnail' |
5 | import { ThumbnailType } from '../../shared/models/videos/thumbnail.type' | ||
6 | import { processImage } from '../helpers/image-utils' | ||
7 | import { join } from 'path' | ||
8 | import { downloadImage } from '../helpers/requests' | ||
9 | import { MVideoPlaylistThumbnail } from '../types/models/video/video-playlist' | ||
10 | import { MVideoFile, MVideoThumbnail } from '../types/models' | 10 | import { MVideoFile, MVideoThumbnail } from '../types/models' |
11 | import { MThumbnail } from '../types/models/video/thumbnail' | 11 | import { MThumbnail } from '../types/models/video/thumbnail' |
12 | import { MVideoPlaylistThumbnail } from '../types/models/video/video-playlist' | ||
12 | import { getVideoFilePath } from './video-paths' | 13 | import { getVideoFilePath } from './video-paths' |
13 | 14 | ||
14 | type ImageSize = { height: number, width: number } | 15 | type ImageSize = { height: number, width: number } |
15 | 16 | ||
16 | function createPlaylistMiniatureFromExisting ( | 17 | function 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 | ||
30 | function createPlaylistMiniatureFromUrl (downloadUrl: string, playlist: MVideoPlaylistThumbnail, size?: ImageSize) { | 40 | function 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 | ||
43 | function createVideoMiniatureFromUrl (downloadUrl: string, video: MVideoThumbnail, type: ThumbnailType, size?: ImageSize) { | 58 | function 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 | ||
71 | function generateVideoMiniature (video: MVideoThumbnail, videoFile: MVideoFile, type: ThumbnailType) { | 100 | function 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 | ||
82 | function createPlaceholderThumbnail (fileUrl: string, video: MVideoThumbnail, type: ThumbnailType, size: ImageSize) { | 125 | function 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 | ||