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.ts151
1 files changed, 151 insertions, 0 deletions
diff --git a/server/lib/thumbnail.ts b/server/lib/thumbnail.ts
new file mode 100644
index 000000000..344c28566
--- /dev/null
+++ b/server/lib/thumbnail.ts
@@ -0,0 +1,151 @@
1import { VideoFileModel } from '../models/video/video-file'
2import { generateImageFromVideoFile } from '../helpers/ffmpeg-utils'
3import { CONFIG } from '../initializers/config'
4import { PREVIEWS_SIZE, THUMBNAILS_SIZE } from '../initializers/constants'
5import { VideoModel } from '../models/video/video'
6import { ThumbnailModel } from '../models/video/thumbnail'
7import { ThumbnailType } from '../../shared/models/videos/thumbnail.type'
8import { processImage } from '../helpers/image-utils'
9import { join } from 'path'
10import { downloadImage } from '../helpers/requests'
11import { VideoPlaylistModel } from '../models/video/video-playlist'
12
13type ImageSize = { height: number, width: number }
14
15function createPlaylistThumbnailFromExisting (inputPath: string, playlist: VideoPlaylistModel, keepOriginal = false, size?: ImageSize) {
16 const { filename, outputPath, height, width, existingThumbnail } = buildMetadataFromPlaylist(playlist, size)
17 const type = ThumbnailType.THUMBNAIL
18
19 const thumbnailCreator = () => processImage({ path: inputPath }, outputPath, { width, height }, keepOriginal)
20 return createThumbnailFromFunction({ thumbnailCreator, filename, height, width, type, existingThumbnail })
21}
22
23function createPlaylistThumbnailFromUrl (url: string, playlist: VideoPlaylistModel, size?: ImageSize) {
24 const { filename, basePath, height, width, existingThumbnail } = buildMetadataFromPlaylist(playlist, size)
25 const type = ThumbnailType.THUMBNAIL
26
27 const thumbnailCreator = () => downloadImage(url, basePath, filename, { width, height })
28 return createThumbnailFromFunction({ thumbnailCreator, filename, height, width, type, existingThumbnail, url })
29}
30
31function createVideoThumbnailFromUrl (url: string, video: VideoModel, type: ThumbnailType, size?: ImageSize) {
32 const { filename, basePath, height, width, existingThumbnail } = buildMetadataFromVideo(video, type, size)
33 const thumbnailCreator = () => downloadImage(url, basePath, filename, { width, height })
34
35 return createThumbnailFromFunction({ thumbnailCreator, filename, height, width, type, existingThumbnail, url })
36}
37
38function createVideoThumbnailFromExisting (inputPath: string, video: VideoModel, type: ThumbnailType, size?: ImageSize) {
39 const { filename, outputPath, height, width, existingThumbnail } = buildMetadataFromVideo(video, type, size)
40 const thumbnailCreator = () => processImage({ path: inputPath }, outputPath, { width, height })
41
42 return createThumbnailFromFunction({ thumbnailCreator, filename, height, width, type, existingThumbnail })
43}
44
45function generateVideoThumbnail (video: VideoModel, videoFile: VideoFileModel, type: ThumbnailType) {
46 const input = video.getVideoFilePath(videoFile)
47
48 const { filename, basePath, height, width, existingThumbnail } = buildMetadataFromVideo(video, type)
49 const thumbnailCreator = () => generateImageFromVideoFile(input, basePath, filename, { height, width })
50
51 return createThumbnailFromFunction({ thumbnailCreator, filename, height, width, type, existingThumbnail })
52}
53
54function createPlaceholderThumbnail (url: string, video: VideoModel, type: ThumbnailType, size: ImageSize) {
55 const { filename, height, width, existingThumbnail } = buildMetadataFromVideo(video, type, size)
56
57 const thumbnail = existingThumbnail ? existingThumbnail : new ThumbnailModel()
58
59 thumbnail.filename = filename
60 thumbnail.height = height
61 thumbnail.width = width
62 thumbnail.type = type
63 thumbnail.url = url
64
65 return thumbnail
66}
67
68// ---------------------------------------------------------------------------
69
70export {
71 generateVideoThumbnail,
72 createVideoThumbnailFromUrl,
73 createVideoThumbnailFromExisting,
74 createPlaceholderThumbnail,
75 createPlaylistThumbnailFromUrl,
76 createPlaylistThumbnailFromExisting
77}
78
79function buildMetadataFromPlaylist (playlist: VideoPlaylistModel, size: ImageSize) {
80 const filename = playlist.generateThumbnailName()
81 const basePath = CONFIG.STORAGE.THUMBNAILS_DIR
82
83 return {
84 filename,
85 basePath,
86 existingThumbnail: playlist.Thumbnail,
87 outputPath: join(basePath, filename),
88 height: size ? size.height : THUMBNAILS_SIZE.height,
89 width: size ? size.width : THUMBNAILS_SIZE.width
90 }
91}
92
93function buildMetadataFromVideo (video: VideoModel, type: ThumbnailType, size?: ImageSize) {
94 const existingThumbnail = Array.isArray(video.Thumbnails)
95 ? video.Thumbnails.find(t => t.type === type)
96 : undefined
97
98 if (type === ThumbnailType.THUMBNAIL) {
99 const filename = video.generateThumbnailName()
100 const basePath = CONFIG.STORAGE.THUMBNAILS_DIR
101
102 return {
103 filename,
104 basePath,
105 existingThumbnail,
106 outputPath: join(basePath, filename),
107 height: size ? size.height : THUMBNAILS_SIZE.height,
108 width: size ? size.width : THUMBNAILS_SIZE.width
109 }
110 }
111
112 if (type === ThumbnailType.PREVIEW) {
113 const filename = video.generatePreviewName()
114 const basePath = CONFIG.STORAGE.PREVIEWS_DIR
115
116 return {
117 filename,
118 basePath,
119 existingThumbnail,
120 outputPath: join(basePath, filename),
121 height: size ? size.height : PREVIEWS_SIZE.height,
122 width: size ? size.width : PREVIEWS_SIZE.width
123 }
124 }
125
126 return undefined
127}
128
129async function createThumbnailFromFunction (parameters: {
130 thumbnailCreator: () => Promise<any>,
131 filename: string,
132 height: number,
133 width: number,
134 type: ThumbnailType,
135 url?: string,
136 existingThumbnail?: ThumbnailModel
137}) {
138 const { thumbnailCreator, filename, width, height, type, existingThumbnail, url = null } = parameters
139
140 const thumbnail = existingThumbnail ? existingThumbnail : new ThumbnailModel()
141
142 thumbnail.filename = filename
143 thumbnail.height = height
144 thumbnail.width = width
145 thumbnail.type = type
146 thumbnail.url = url
147
148 await thumbnailCreator()
149
150 return thumbnail
151}