diff options
Diffstat (limited to 'server/lib/thumbnail.ts')
-rw-r--r-- | server/lib/thumbnail.ts | 118 |
1 files changed, 64 insertions, 54 deletions
diff --git a/server/lib/thumbnail.ts b/server/lib/thumbnail.ts index 02b867a91..d95442795 100644 --- a/server/lib/thumbnail.ts +++ b/server/lib/thumbnail.ts | |||
@@ -7,13 +7,12 @@ import { ThumbnailModel } from '../models/video/thumbnail' | |||
7 | import { MVideoFile, MVideoThumbnail, MVideoUUID } from '../types/models' | 7 | import { MVideoFile, MVideoThumbnail, MVideoUUID } from '../types/models' |
8 | import { MThumbnail } from '../types/models/video/thumbnail' | 8 | import { MThumbnail } from '../types/models/video/thumbnail' |
9 | import { MVideoPlaylistThumbnail } from '../types/models/video/video-playlist' | 9 | import { MVideoPlaylistThumbnail } from '../types/models/video/video-playlist' |
10 | import { downloadImageFromWorker } from './local-actor' | ||
11 | import { VideoPathManager } from './video-path-manager' | 10 | import { VideoPathManager } from './video-path-manager' |
12 | import { processImageFromWorker } from './worker/parent-process' | 11 | import { downloadImageFromWorker, processImageFromWorker } from './worker/parent-process' |
13 | 12 | ||
14 | type ImageSize = { height?: number, width?: number } | 13 | type ImageSize = { height?: number, width?: number } |
15 | 14 | ||
16 | function updatePlaylistMiniatureFromExisting (options: { | 15 | function updateLocalPlaylistMiniatureFromExisting (options: { |
17 | inputPath: string | 16 | inputPath: string |
18 | playlist: MVideoPlaylistThumbnail | 17 | playlist: MVideoPlaylistThumbnail |
19 | automaticallyGenerated: boolean | 18 | automaticallyGenerated: boolean |
@@ -35,11 +34,12 @@ function updatePlaylistMiniatureFromExisting (options: { | |||
35 | width, | 34 | width, |
36 | type, | 35 | type, |
37 | automaticallyGenerated, | 36 | automaticallyGenerated, |
37 | onDisk: true, | ||
38 | existingThumbnail | 38 | existingThumbnail |
39 | }) | 39 | }) |
40 | } | 40 | } |
41 | 41 | ||
42 | function updatePlaylistMiniatureFromUrl (options: { | 42 | function updateRemotePlaylistMiniatureFromUrl (options: { |
43 | downloadUrl: string | 43 | downloadUrl: string |
44 | playlist: MVideoPlaylistThumbnail | 44 | playlist: MVideoPlaylistThumbnail |
45 | size?: ImageSize | 45 | size?: ImageSize |
@@ -57,42 +57,10 @@ function updatePlaylistMiniatureFromUrl (options: { | |||
57 | return downloadImageFromWorker({ url: downloadUrl, destDir: basePath, destName: filename, size: { width, height } }) | 57 | return downloadImageFromWorker({ url: downloadUrl, destDir: basePath, destName: filename, size: { width, height } }) |
58 | } | 58 | } |
59 | 59 | ||
60 | return updateThumbnailFromFunction({ thumbnailCreator, filename, height, width, type, existingThumbnail, fileUrl }) | 60 | return updateThumbnailFromFunction({ thumbnailCreator, filename, height, width, type, existingThumbnail, fileUrl, onDisk: true }) |
61 | } | 61 | } |
62 | 62 | ||
63 | function updateVideoMiniatureFromUrl (options: { | 63 | function updateLocalVideoMiniatureFromExisting (options: { |
64 | downloadUrl: string | ||
65 | video: MVideoThumbnail | ||
66 | type: ThumbnailType | ||
67 | size?: ImageSize | ||
68 | }) { | ||
69 | const { downloadUrl, video, type, size } = options | ||
70 | const { filename: updatedFilename, basePath, height, width, existingThumbnail } = buildMetadataFromVideo(video, type, size) | ||
71 | |||
72 | // Only save the file URL if it is a remote video | ||
73 | const fileUrl = video.isOwned() | ||
74 | ? null | ||
75 | : downloadUrl | ||
76 | |||
77 | const thumbnailUrlChanged = hasThumbnailUrlChanged(existingThumbnail, downloadUrl, video) | ||
78 | |||
79 | // Do not change the thumbnail filename if the file did not change | ||
80 | const filename = thumbnailUrlChanged | ||
81 | ? updatedFilename | ||
82 | : existingThumbnail.filename | ||
83 | |||
84 | const thumbnailCreator = () => { | ||
85 | if (thumbnailUrlChanged) { | ||
86 | return downloadImageFromWorker({ url: downloadUrl, destDir: basePath, destName: filename, size: { width, height } }) | ||
87 | } | ||
88 | |||
89 | return Promise.resolve() | ||
90 | } | ||
91 | |||
92 | return updateThumbnailFromFunction({ thumbnailCreator, filename, height, width, type, existingThumbnail, fileUrl }) | ||
93 | } | ||
94 | |||
95 | function updateVideoMiniatureFromExisting (options: { | ||
96 | inputPath: string | 64 | inputPath: string |
97 | video: MVideoThumbnail | 65 | video: MVideoThumbnail |
98 | type: ThumbnailType | 66 | type: ThumbnailType |
@@ -115,11 +83,12 @@ function updateVideoMiniatureFromExisting (options: { | |||
115 | width, | 83 | width, |
116 | type, | 84 | type, |
117 | automaticallyGenerated, | 85 | automaticallyGenerated, |
118 | existingThumbnail | 86 | existingThumbnail, |
87 | onDisk: true | ||
119 | }) | 88 | }) |
120 | } | 89 | } |
121 | 90 | ||
122 | function generateVideoMiniature (options: { | 91 | function generateLocalVideoMiniature (options: { |
123 | video: MVideoThumbnail | 92 | video: MVideoThumbnail |
124 | videoFile: MVideoFile | 93 | videoFile: MVideoFile |
125 | type: ThumbnailType | 94 | type: ThumbnailType |
@@ -150,34 +119,68 @@ function generateVideoMiniature (options: { | |||
150 | width, | 119 | width, |
151 | type, | 120 | type, |
152 | automaticallyGenerated: true, | 121 | automaticallyGenerated: true, |
122 | onDisk: true, | ||
153 | existingThumbnail | 123 | existingThumbnail |
154 | }) | 124 | }) |
155 | }) | 125 | }) |
156 | } | 126 | } |
157 | 127 | ||
158 | function updatePlaceholderThumbnail (options: { | 128 | // --------------------------------------------------------------------------- |
159 | fileUrl: string | 129 | |
130 | function updateLocalVideoMiniatureFromUrl (options: { | ||
131 | downloadUrl: string | ||
160 | video: MVideoThumbnail | 132 | video: MVideoThumbnail |
161 | type: ThumbnailType | 133 | type: ThumbnailType |
162 | size: ImageSize | 134 | size?: ImageSize |
163 | }) { | 135 | }) { |
164 | const { fileUrl, video, type, size } = options | 136 | const { downloadUrl, video, type, size } = options |
165 | const { filename: updatedFilename, height, width, existingThumbnail } = buildMetadataFromVideo(video, type, size) | 137 | const { filename: updatedFilename, basePath, height, width, existingThumbnail } = buildMetadataFromVideo(video, type, size) |
166 | 138 | ||
167 | const thumbnailUrlChanged = hasThumbnailUrlChanged(existingThumbnail, fileUrl, video) | 139 | // Only save the file URL if it is a remote video |
140 | const fileUrl = video.isOwned() | ||
141 | ? null | ||
142 | : downloadUrl | ||
168 | 143 | ||
169 | const thumbnail = existingThumbnail || new ThumbnailModel() | 144 | const thumbnailUrlChanged = hasThumbnailUrlChanged(existingThumbnail, downloadUrl, video) |
170 | 145 | ||
171 | // Do not change the thumbnail filename if the file did not change | 146 | // Do not change the thumbnail filename if the file did not change |
172 | const filename = thumbnailUrlChanged | 147 | const filename = thumbnailUrlChanged |
173 | ? updatedFilename | 148 | ? updatedFilename |
174 | : existingThumbnail.filename | 149 | : existingThumbnail.filename |
175 | 150 | ||
176 | thumbnail.filename = filename | 151 | const thumbnailCreator = () => { |
152 | if (thumbnailUrlChanged) { | ||
153 | return downloadImageFromWorker({ url: downloadUrl, destDir: basePath, destName: filename, size: { width, height } }) | ||
154 | } | ||
155 | |||
156 | return Promise.resolve() | ||
157 | } | ||
158 | |||
159 | return updateThumbnailFromFunction({ thumbnailCreator, filename, height, width, type, existingThumbnail, fileUrl, onDisk: true }) | ||
160 | } | ||
161 | |||
162 | function updateRemoteVideoThumbnail (options: { | ||
163 | fileUrl: string | ||
164 | video: MVideoThumbnail | ||
165 | type: ThumbnailType | ||
166 | size: ImageSize | ||
167 | onDisk: boolean | ||
168 | }) { | ||
169 | const { fileUrl, video, type, size, onDisk } = options | ||
170 | const { filename: generatedFilename, height, width, existingThumbnail } = buildMetadataFromVideo(video, type, size) | ||
171 | |||
172 | const thumbnail = existingThumbnail || new ThumbnailModel() | ||
173 | |||
174 | // Do not change the thumbnail filename if the file did not change | ||
175 | if (hasThumbnailUrlChanged(existingThumbnail, fileUrl, video)) { | ||
176 | thumbnail.filename = generatedFilename | ||
177 | } | ||
178 | |||
177 | thumbnail.height = height | 179 | thumbnail.height = height |
178 | thumbnail.width = width | 180 | thumbnail.width = width |
179 | thumbnail.type = type | 181 | thumbnail.type = type |
180 | thumbnail.fileUrl = fileUrl | 182 | thumbnail.fileUrl = fileUrl |
183 | thumbnail.onDisk = onDisk | ||
181 | 184 | ||
182 | return thumbnail | 185 | return thumbnail |
183 | } | 186 | } |
@@ -185,14 +188,18 @@ function updatePlaceholderThumbnail (options: { | |||
185 | // --------------------------------------------------------------------------- | 188 | // --------------------------------------------------------------------------- |
186 | 189 | ||
187 | export { | 190 | export { |
188 | generateVideoMiniature, | 191 | generateLocalVideoMiniature, |
189 | updateVideoMiniatureFromUrl, | 192 | updateLocalVideoMiniatureFromUrl, |
190 | updateVideoMiniatureFromExisting, | 193 | updateLocalVideoMiniatureFromExisting, |
191 | updatePlaceholderThumbnail, | 194 | updateRemoteVideoThumbnail, |
192 | updatePlaylistMiniatureFromUrl, | 195 | updateRemotePlaylistMiniatureFromUrl, |
193 | updatePlaylistMiniatureFromExisting | 196 | updateLocalPlaylistMiniatureFromExisting |
194 | } | 197 | } |
195 | 198 | ||
199 | // --------------------------------------------------------------------------- | ||
200 | // Private | ||
201 | // --------------------------------------------------------------------------- | ||
202 | |||
196 | function hasThumbnailUrlChanged (existingThumbnail: MThumbnail, downloadUrl: string, video: MVideoUUID) { | 203 | function hasThumbnailUrlChanged (existingThumbnail: MThumbnail, downloadUrl: string, video: MVideoUUID) { |
197 | const existingUrl = existingThumbnail | 204 | const existingUrl = existingThumbnail |
198 | ? existingThumbnail.fileUrl | 205 | ? existingThumbnail.fileUrl |
@@ -258,6 +265,7 @@ async function updateThumbnailFromFunction (parameters: { | |||
258 | height: number | 265 | height: number |
259 | width: number | 266 | width: number |
260 | type: ThumbnailType | 267 | type: ThumbnailType |
268 | onDisk: boolean | ||
261 | automaticallyGenerated?: boolean | 269 | automaticallyGenerated?: boolean |
262 | fileUrl?: string | 270 | fileUrl?: string |
263 | existingThumbnail?: MThumbnail | 271 | existingThumbnail?: MThumbnail |
@@ -269,6 +277,7 @@ async function updateThumbnailFromFunction (parameters: { | |||
269 | height, | 277 | height, |
270 | type, | 278 | type, |
271 | existingThumbnail, | 279 | existingThumbnail, |
280 | onDisk, | ||
272 | automaticallyGenerated = null, | 281 | automaticallyGenerated = null, |
273 | fileUrl = null | 282 | fileUrl = null |
274 | } = parameters | 283 | } = parameters |
@@ -285,6 +294,7 @@ async function updateThumbnailFromFunction (parameters: { | |||
285 | thumbnail.type = type | 294 | thumbnail.type = type |
286 | thumbnail.fileUrl = fileUrl | 295 | thumbnail.fileUrl = fileUrl |
287 | thumbnail.automaticallyGenerated = automaticallyGenerated | 296 | thumbnail.automaticallyGenerated = automaticallyGenerated |
297 | thumbnail.onDisk = onDisk | ||
288 | 298 | ||
289 | if (oldFilename) thumbnail.previousThumbnailFilename = oldFilename | 299 | if (oldFilename) thumbnail.previousThumbnailFilename = oldFilename |
290 | 300 | ||