aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/controllers/api
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2019-08-01 16:54:24 +0200
committerChocobozzz <me@florianbigard.com>2019-08-01 16:54:24 +0200
commit65af03a241aa83ab7ba71278b6c99acd26428b8a (patch)
tree0cc04c31cdf631d11a915ae40389e8fa141f136b /server/controllers/api
parenta21e25ff641854c8b01664cb18655aa420620af6 (diff)
downloadPeerTube-65af03a241aa83ab7ba71278b6c99acd26428b8a.tar.gz
PeerTube-65af03a241aa83ab7ba71278b6c99acd26428b8a.tar.zst
PeerTube-65af03a241aa83ab7ba71278b6c99acd26428b8a.zip
Automatically update playlist thumbnails
Diffstat (limited to 'server/controllers/api')
-rw-r--r--server/controllers/api/video-playlist.ts67
-rw-r--r--server/controllers/api/videos/import.ts4
-rw-r--r--server/controllers/api/videos/index.ts8
3 files changed, 55 insertions, 24 deletions
diff --git a/server/controllers/api/video-playlist.ts b/server/controllers/api/video-playlist.ts
index 540120cca..bd454f553 100644
--- a/server/controllers/api/video-playlist.ts
+++ b/server/controllers/api/video-playlist.ts
@@ -40,6 +40,7 @@ import { JobQueue } from '../../lib/job-queue'
40import { CONFIG } from '../../initializers/config' 40import { CONFIG } from '../../initializers/config'
41import { sequelizeTypescript } from '../../initializers/database' 41import { sequelizeTypescript } from '../../initializers/database'
42import { createPlaylistMiniatureFromExisting } from '../../lib/thumbnail' 42import { createPlaylistMiniatureFromExisting } from '../../lib/thumbnail'
43import { VideoModel } from '../../models/video/video'
43 44
44const reqThumbnailFile = createReqFiles([ 'thumbnailfile' ], MIMETYPES.IMAGE.MIMETYPE_EXT, { thumbnailfile: CONFIG.STORAGE.TMP_DIR }) 45const reqThumbnailFile = createReqFiles([ 'thumbnailfile' ], MIMETYPES.IMAGE.MIMETYPE_EXT, { thumbnailfile: CONFIG.STORAGE.TMP_DIR })
45 46
@@ -171,13 +172,16 @@ async function addVideoPlaylist (req: express.Request, res: express.Response) {
171 172
172 const thumbnailField = req.files['thumbnailfile'] 173 const thumbnailField = req.files['thumbnailfile']
173 const thumbnailModel = thumbnailField 174 const thumbnailModel = thumbnailField
174 ? await createPlaylistMiniatureFromExisting(thumbnailField[0].path, videoPlaylist) 175 ? await createPlaylistMiniatureFromExisting(thumbnailField[0].path, videoPlaylist, false)
175 : undefined 176 : undefined
176 177
177 const videoPlaylistCreated: VideoPlaylistModel = await sequelizeTypescript.transaction(async t => { 178 const videoPlaylistCreated: VideoPlaylistModel = await sequelizeTypescript.transaction(async t => {
178 const videoPlaylistCreated = await videoPlaylist.save({ transaction: t }) 179 const videoPlaylistCreated = await videoPlaylist.save({ transaction: t })
179 180
180 if (thumbnailModel) await videoPlaylistCreated.setAndSaveThumbnail(thumbnailModel, t) 181 if (thumbnailModel) {
182 thumbnailModel.automaticallyGenerated = false
183 await videoPlaylistCreated.setAndSaveThumbnail(thumbnailModel, t)
184 }
181 185
182 // We need more attributes for the federation 186 // We need more attributes for the federation
183 videoPlaylistCreated.OwnerAccount = await AccountModel.load(user.Account.id, t) 187 videoPlaylistCreated.OwnerAccount = await AccountModel.load(user.Account.id, t)
@@ -206,7 +210,7 @@ async function updateVideoPlaylist (req: express.Request, res: express.Response)
206 210
207 const thumbnailField = req.files['thumbnailfile'] 211 const thumbnailField = req.files['thumbnailfile']
208 const thumbnailModel = thumbnailField 212 const thumbnailModel = thumbnailField
209 ? await createPlaylistMiniatureFromExisting(thumbnailField[0].path, videoPlaylistInstance) 213 ? await createPlaylistMiniatureFromExisting(thumbnailField[0].path, videoPlaylistInstance, false)
210 : undefined 214 : undefined
211 215
212 try { 216 try {
@@ -239,7 +243,10 @@ async function updateVideoPlaylist (req: express.Request, res: express.Response)
239 243
240 const playlistUpdated = await videoPlaylistInstance.save(sequelizeOptions) 244 const playlistUpdated = await videoPlaylistInstance.save(sequelizeOptions)
241 245
242 if (thumbnailModel) await playlistUpdated.setAndSaveThumbnail(thumbnailModel, t) 246 if (thumbnailModel) {
247 thumbnailModel.automaticallyGenerated = false
248 await playlistUpdated.setAndSaveThumbnail(thumbnailModel, t)
249 }
243 250
244 const isNewPlaylist = wasPrivatePlaylist && playlistUpdated.privacy !== VideoPlaylistPrivacy.PRIVATE 251 const isNewPlaylist = wasPrivatePlaylist && playlistUpdated.privacy !== VideoPlaylistPrivacy.PRIVATE
245 252
@@ -301,23 +308,17 @@ async function addVideoInPlaylist (req: express.Request, res: express.Response)
301 videoPlaylist.changed('updatedAt', true) 308 videoPlaylist.changed('updatedAt', true)
302 await videoPlaylist.save({ transaction: t }) 309 await videoPlaylist.save({ transaction: t })
303 310
304 await sendUpdateVideoPlaylist(videoPlaylist, t)
305
306 return playlistElement 311 return playlistElement
307 }) 312 })
308 313
309 // If the user did not set a thumbnail, automatically take the video thumbnail 314 // If the user did not set a thumbnail, automatically take the video thumbnail
310 if (videoPlaylist.hasThumbnail() === false) { 315 if (videoPlaylist.hasThumbnail() === false || (videoPlaylist.hasGeneratedThumbnail() && playlistElement.position === 1)) {
311 logger.info('Generating default thumbnail to playlist %s.', videoPlaylist.url) 316 await generateThumbnailForPlaylist(videoPlaylist, video)
312
313 const inputPath = join(CONFIG.STORAGE.THUMBNAILS_DIR, video.getMiniature().filename)
314 const thumbnailModel = await createPlaylistMiniatureFromExisting(inputPath, videoPlaylist, true)
315
316 thumbnailModel.videoPlaylistId = videoPlaylist.id
317
318 await thumbnailModel.save()
319 } 317 }
320 318
319 sendUpdateVideoPlaylist(videoPlaylist, undefined)
320 .catch(err => logger.error('Cannot send video playlist update.', { err }))
321
321 logger.info('Video added in playlist %s at position %d.', videoPlaylist.uuid, playlistElement.position) 322 logger.info('Video added in playlist %s at position %d.', videoPlaylist.uuid, playlistElement.position)
322 323
323 return res.json({ 324 return res.json({
@@ -365,11 +366,17 @@ async function removeVideoFromPlaylist (req: express.Request, res: express.Respo
365 videoPlaylist.changed('updatedAt', true) 366 videoPlaylist.changed('updatedAt', true)
366 await videoPlaylist.save({ transaction: t }) 367 await videoPlaylist.save({ transaction: t })
367 368
368 await sendUpdateVideoPlaylist(videoPlaylist, t)
369
370 logger.info('Video playlist element %d of playlist %s deleted.', videoPlaylistElement.position, videoPlaylist.uuid) 369 logger.info('Video playlist element %d of playlist %s deleted.', videoPlaylistElement.position, videoPlaylist.uuid)
371 }) 370 })
372 371
372 // Do we need to regenerate the default thumbnail?
373 if (positionToDelete === 1 && videoPlaylist.hasGeneratedThumbnail()) {
374 await regeneratePlaylistThumbnail(videoPlaylist)
375 }
376
377 sendUpdateVideoPlaylist(videoPlaylist, undefined)
378 .catch(err => logger.error('Cannot send video playlist update.', { err }))
379
373 return res.type('json').status(204).end() 380 return res.type('json').status(204).end()
374} 381}
375 382
@@ -413,8 +420,13 @@ async function reorderVideosPlaylist (req: express.Request, res: express.Respons
413 await sendUpdateVideoPlaylist(videoPlaylist, t) 420 await sendUpdateVideoPlaylist(videoPlaylist, t)
414 }) 421 })
415 422
423 // The first element changed
424 if ((start === 1 || insertAfter === 0) && videoPlaylist.hasGeneratedThumbnail()) {
425 await regeneratePlaylistThumbnail(videoPlaylist)
426 }
427
416 logger.info( 428 logger.info(
417 'Reordered playlist %s (inserted after %d elements %d - %d).', 429 'Reordered playlist %s (inserted after position %d elements %d - %d).',
418 videoPlaylist.uuid, insertAfter, start, start + reorderLength - 1 430 videoPlaylist.uuid, insertAfter, start, start + reorderLength - 1
419 ) 431 )
420 432
@@ -440,3 +452,22 @@ async function getVideoPlaylistVideos (req: express.Request, res: express.Respon
440 } 452 }
441 return res.json(getFormattedObjects(resultList.data, resultList.total, options)) 453 return res.json(getFormattedObjects(resultList.data, resultList.total, options))
442} 454}
455
456async function regeneratePlaylistThumbnail (videoPlaylist: VideoPlaylistModel) {
457 await videoPlaylist.Thumbnail.destroy()
458 videoPlaylist.Thumbnail = null
459
460 const firstElement = await VideoPlaylistElementModel.loadFirstElementWithVideoThumbnail(videoPlaylist.id)
461 if (firstElement) await generateThumbnailForPlaylist(videoPlaylist, firstElement.Video)
462}
463
464async function generateThumbnailForPlaylist (videoPlaylist: VideoPlaylistModel, video: VideoModel) {
465 logger.info('Generating default thumbnail to playlist %s.', videoPlaylist.url)
466
467 const inputPath = join(CONFIG.STORAGE.THUMBNAILS_DIR, video.getMiniature().filename)
468 const thumbnailModel = await createPlaylistMiniatureFromExisting(inputPath, videoPlaylist, true, true)
469
470 thumbnailModel.videoPlaylistId = videoPlaylist.id
471
472 videoPlaylist.Thumbnail = await thumbnailModel.save()
473}
diff --git a/server/controllers/api/videos/import.ts b/server/controllers/api/videos/import.ts
index 1f08fe20a..04c9b547b 100644
--- a/server/controllers/api/videos/import.ts
+++ b/server/controllers/api/videos/import.ts
@@ -207,7 +207,7 @@ async function processThumbnail (req: express.Request, video: VideoModel) {
207 if (thumbnailField) { 207 if (thumbnailField) {
208 const thumbnailPhysicalFile = thumbnailField[ 0 ] 208 const thumbnailPhysicalFile = thumbnailField[ 0 ]
209 209
210 return createVideoMiniatureFromExisting(thumbnailPhysicalFile.path, video, ThumbnailType.MINIATURE) 210 return createVideoMiniatureFromExisting(thumbnailPhysicalFile.path, video, ThumbnailType.MINIATURE, false)
211 } 211 }
212 212
213 return undefined 213 return undefined
@@ -218,7 +218,7 @@ async function processPreview (req: express.Request, video: VideoModel) {
218 if (previewField) { 218 if (previewField) {
219 const previewPhysicalFile = previewField[0] 219 const previewPhysicalFile = previewField[0]
220 220
221 return createVideoMiniatureFromExisting(previewPhysicalFile.path, video, ThumbnailType.PREVIEW) 221 return createVideoMiniatureFromExisting(previewPhysicalFile.path, video, ThumbnailType.PREVIEW, false)
222 } 222 }
223 223
224 return undefined 224 return undefined
diff --git a/server/controllers/api/videos/index.ts b/server/controllers/api/videos/index.ts
index 973bf1123..155ca4678 100644
--- a/server/controllers/api/videos/index.ts
+++ b/server/controllers/api/videos/index.ts
@@ -223,13 +223,13 @@ async function addVideo (req: express.Request, res: express.Response) {
223 // Process thumbnail or create it from the video 223 // Process thumbnail or create it from the video
224 const thumbnailField = req.files['thumbnailfile'] 224 const thumbnailField = req.files['thumbnailfile']
225 const thumbnailModel = thumbnailField 225 const thumbnailModel = thumbnailField
226 ? await createVideoMiniatureFromExisting(thumbnailField[0].path, video, ThumbnailType.MINIATURE) 226 ? await createVideoMiniatureFromExisting(thumbnailField[0].path, video, ThumbnailType.MINIATURE, false)
227 : await generateVideoMiniature(video, videoFile, ThumbnailType.MINIATURE) 227 : await generateVideoMiniature(video, videoFile, ThumbnailType.MINIATURE)
228 228
229 // Process preview or create it from the video 229 // Process preview or create it from the video
230 const previewField = req.files['previewfile'] 230 const previewField = req.files['previewfile']
231 const previewModel = previewField 231 const previewModel = previewField
232 ? await createVideoMiniatureFromExisting(previewField[0].path, video, ThumbnailType.PREVIEW) 232 ? await createVideoMiniatureFromExisting(previewField[0].path, video, ThumbnailType.PREVIEW, false)
233 : await generateVideoMiniature(video, videoFile, ThumbnailType.PREVIEW) 233 : await generateVideoMiniature(video, videoFile, ThumbnailType.PREVIEW)
234 234
235 // Create the torrent file 235 // Create the torrent file
@@ -329,11 +329,11 @@ async function updateVideo (req: express.Request, res: express.Response) {
329 329
330 // Process thumbnail or create it from the video 330 // Process thumbnail or create it from the video
331 const thumbnailModel = req.files && req.files['thumbnailfile'] 331 const thumbnailModel = req.files && req.files['thumbnailfile']
332 ? await createVideoMiniatureFromExisting(req.files['thumbnailfile'][0].path, videoInstance, ThumbnailType.MINIATURE) 332 ? await createVideoMiniatureFromExisting(req.files['thumbnailfile'][0].path, videoInstance, ThumbnailType.MINIATURE, false)
333 : undefined 333 : undefined
334 334
335 const previewModel = req.files && req.files['previewfile'] 335 const previewModel = req.files && req.files['previewfile']
336 ? await createVideoMiniatureFromExisting(req.files['previewfile'][0].path, videoInstance, ThumbnailType.PREVIEW) 336 ? await createVideoMiniatureFromExisting(req.files['previewfile'][0].path, videoInstance, ThumbnailType.PREVIEW, false)
337 : undefined 337 : undefined
338 338
339 try { 339 try {