diff options
author | Chocobozzz <me@florianbigard.com> | 2020-09-17 10:00:46 +0200 |
---|---|---|
committer | Chocobozzz <chocobozzz@cpy.re> | 2020-11-09 15:33:04 +0100 |
commit | 1ef65f4c034cc53ab5d55417e52d60e1f7fc1ddb (patch) | |
tree | 8bb02f8dc2590e5071306fb311bdc53289e20336 /server/lib | |
parent | c6c0fa6cd8fe8f752463d8982c3dbcd448739c4e (diff) | |
download | PeerTube-1ef65f4c034cc53ab5d55417e52d60e1f7fc1ddb.tar.gz PeerTube-1ef65f4c034cc53ab5d55417e52d60e1f7fc1ddb.tar.zst PeerTube-1ef65f4c034cc53ab5d55417e52d60e1f7fc1ddb.zip |
Refactor video creation
Diffstat (limited to 'server/lib')
-rw-r--r-- | server/lib/activitypub/videos.ts | 8 | ||||
-rw-r--r-- | server/lib/thumbnail.ts | 17 | ||||
-rw-r--r-- | server/lib/video.ts | 68 |
3 files changed, 75 insertions, 18 deletions
diff --git a/server/lib/activitypub/videos.ts b/server/lib/activitypub/videos.ts index cbbf23be1..096884776 100644 --- a/server/lib/activitypub/videos.ts +++ b/server/lib/activitypub/videos.ts | |||
@@ -68,6 +68,7 @@ import { ActorFollowScoreCache } from '../files-cache' | |||
68 | import { JobQueue } from '../job-queue' | 68 | import { JobQueue } from '../job-queue' |
69 | import { Notifier } from '../notifier' | 69 | import { Notifier } from '../notifier' |
70 | import { createPlaceholderThumbnail, createVideoMiniatureFromUrl } from '../thumbnail' | 70 | import { createPlaceholderThumbnail, createVideoMiniatureFromUrl } from '../thumbnail' |
71 | import { setVideoTags } from '../video' | ||
71 | import { autoBlacklistVideoIfNeeded } from '../video-blacklist' | 72 | import { autoBlacklistVideoIfNeeded } from '../video-blacklist' |
72 | import { getOrCreateActorAndServerAndModel } from './actor' | 73 | import { getOrCreateActorAndServerAndModel } from './actor' |
73 | import { crawlCollectionPage } from './crawl' | 74 | import { crawlCollectionPage } from './crawl' |
@@ -409,8 +410,7 @@ async function updateVideoFromAP (options: { | |||
409 | const tags = videoObject.tag | 410 | const tags = videoObject.tag |
410 | .filter(isAPHashTagObject) | 411 | .filter(isAPHashTagObject) |
411 | .map(tag => tag.name) | 412 | .map(tag => tag.name) |
412 | const tagInstances = await TagModel.findOrCreateTags(tags, t) | 413 | await setVideoTags({ video: videoUpdated, tags, transaction: t, defaultValue: videoUpdated.Tags }) |
413 | await videoUpdated.$set('Tags', tagInstances, sequelizeOptions) | ||
414 | } | 414 | } |
415 | 415 | ||
416 | { | 416 | { |
@@ -594,8 +594,7 @@ async function createVideo (videoObject: VideoTorrentObject, channel: MChannelAc | |||
594 | const tags = videoObject.tag | 594 | const tags = videoObject.tag |
595 | .filter(isAPHashTagObject) | 595 | .filter(isAPHashTagObject) |
596 | .map(t => t.name) | 596 | .map(t => t.name) |
597 | const tagInstances = await TagModel.findOrCreateTags(tags, t) | 597 | await setVideoTags({ video: videoCreated, tags, transaction: t }) |
598 | await videoCreated.$set('Tags', tagInstances, sequelizeOptions) | ||
599 | 598 | ||
600 | // Process captions | 599 | // Process captions |
601 | const videoCaptionsPromises = videoObject.subtitleLanguage.map(c => { | 600 | const videoCaptionsPromises = videoObject.subtitleLanguage.map(c => { |
@@ -604,7 +603,6 @@ async function createVideo (videoObject: VideoTorrentObject, channel: MChannelAc | |||
604 | await Promise.all(videoCaptionsPromises) | 603 | await Promise.all(videoCaptionsPromises) |
605 | 604 | ||
606 | videoCreated.VideoFiles = videoFiles | 605 | videoCreated.VideoFiles = videoFiles |
607 | videoCreated.Tags = tagInstances | ||
608 | 606 | ||
609 | const autoBlacklisted = await autoBlacklistVideoIfNeeded({ | 607 | const autoBlacklisted = await autoBlacklistVideoIfNeeded({ |
610 | video: videoCreated, | 608 | video: videoCreated, |
diff --git a/server/lib/thumbnail.ts b/server/lib/thumbnail.ts index 78d2f69e3..dc86423f8 100644 --- a/server/lib/thumbnail.ts +++ b/server/lib/thumbnail.ts | |||
@@ -42,15 +42,18 @@ function createVideoMiniatureFromUrl (fileUrl: string, video: MVideoThumbnail, t | |||
42 | return createThumbnailFromFunction({ thumbnailCreator, filename, height, width, type, existingThumbnail, fileUrl }) | 42 | return createThumbnailFromFunction({ thumbnailCreator, filename, height, width, type, existingThumbnail, fileUrl }) |
43 | } | 43 | } |
44 | 44 | ||
45 | function createVideoMiniatureFromExisting ( | 45 | function createVideoMiniatureFromExisting (options: { |
46 | inputPath: string, | 46 | inputPath: string |
47 | video: MVideoThumbnail, | 47 | video: MVideoThumbnail |
48 | type: ThumbnailType, | 48 | type: ThumbnailType |
49 | automaticallyGenerated: boolean, | 49 | automaticallyGenerated: boolean |
50 | size?: ImageSize | 50 | size?: ImageSize |
51 | ) { | 51 | keepOriginal?: boolean |
52 | }) { | ||
53 | const { inputPath, video, type, automaticallyGenerated, size, keepOriginal } = options | ||
54 | |||
52 | const { filename, outputPath, height, width, existingThumbnail } = buildMetadataFromVideo(video, type, size) | 55 | const { filename, outputPath, height, width, existingThumbnail } = buildMetadataFromVideo(video, type, size) |
53 | const thumbnailCreator = () => processImage(inputPath, outputPath, { width, height }) | 56 | const thumbnailCreator = () => processImage(inputPath, outputPath, { width, height }, keepOriginal) |
54 | 57 | ||
55 | return createThumbnailFromFunction({ thumbnailCreator, filename, height, width, type, automaticallyGenerated, existingThumbnail }) | 58 | return createThumbnailFromFunction({ thumbnailCreator, filename, height, width, type, automaticallyGenerated, existingThumbnail }) |
56 | } | 59 | } |
diff --git a/server/lib/video.ts b/server/lib/video.ts index a28f31529..6df41e6cd 100644 --- a/server/lib/video.ts +++ b/server/lib/video.ts | |||
@@ -1,9 +1,12 @@ | |||
1 | 1 | import { Transaction } from 'sequelize/types' | |
2 | import { TagModel } from '@server/models/video/tag' | ||
2 | import { VideoModel } from '@server/models/video/video' | 3 | import { VideoModel } from '@server/models/video/video' |
3 | import { FilteredModelAttributes } from '@server/types' | 4 | import { FilteredModelAttributes } from '@server/types' |
4 | import { VideoCreate, VideoPrivacy, VideoState } from '@shared/models' | 5 | import { MTag, MThumbnail, MVideoTag, MVideoThumbnail } from '@server/types/models' |
6 | import { ThumbnailType, VideoCreate, VideoPrivacy } from '@shared/models' | ||
7 | import { createVideoMiniatureFromExisting } from './thumbnail' | ||
5 | 8 | ||
6 | function buildLocalVideoFromCreate (videoInfo: VideoCreate, channelId: number): FilteredModelAttributes<VideoModel> { | 9 | function buildLocalVideoFromReq (videoInfo: VideoCreate, channelId: number): FilteredModelAttributes<VideoModel> { |
7 | return { | 10 | return { |
8 | name: videoInfo.name, | 11 | name: videoInfo.name, |
9 | remote: false, | 12 | remote: false, |
@@ -13,19 +16,72 @@ function buildLocalVideoFromCreate (videoInfo: VideoCreate, channelId: number): | |||
13 | commentsEnabled: videoInfo.commentsEnabled !== false, // If the value is not "false", the default is "true" | 16 | commentsEnabled: videoInfo.commentsEnabled !== false, // If the value is not "false", the default is "true" |
14 | downloadEnabled: videoInfo.downloadEnabled !== false, | 17 | downloadEnabled: videoInfo.downloadEnabled !== false, |
15 | waitTranscoding: videoInfo.waitTranscoding || false, | 18 | waitTranscoding: videoInfo.waitTranscoding || false, |
16 | state: VideoState.WAITING_FOR_LIVE, | ||
17 | nsfw: videoInfo.nsfw || false, | 19 | nsfw: videoInfo.nsfw || false, |
18 | description: videoInfo.description, | 20 | description: videoInfo.description, |
19 | support: videoInfo.support, | 21 | support: videoInfo.support, |
20 | privacy: videoInfo.privacy || VideoPrivacy.PRIVATE, | 22 | privacy: videoInfo.privacy || VideoPrivacy.PRIVATE, |
21 | duration: 0, | ||
22 | channelId: channelId, | 23 | channelId: channelId, |
23 | originallyPublishedAt: videoInfo.originallyPublishedAt | 24 | originallyPublishedAt: videoInfo.originallyPublishedAt |
24 | } | 25 | } |
25 | } | 26 | } |
26 | 27 | ||
28 | async function buildVideoThumbnailsFromReq (options: { | ||
29 | video: MVideoThumbnail | ||
30 | files: { [fieldname: string]: Express.Multer.File[] } | Express.Multer.File[] | ||
31 | fallback: (type: ThumbnailType) => Promise<MThumbnail> | ||
32 | automaticallyGenerated?: boolean | ||
33 | }) { | ||
34 | const { video, files, fallback, automaticallyGenerated } = options | ||
35 | |||
36 | const promises = [ | ||
37 | { | ||
38 | type: ThumbnailType.MINIATURE, | ||
39 | fieldName: 'thumbnailfile' | ||
40 | }, | ||
41 | { | ||
42 | type: ThumbnailType.PREVIEW, | ||
43 | fieldName: 'previewfile' | ||
44 | } | ||
45 | ].map(p => { | ||
46 | const fields = files?.[p.fieldName] | ||
47 | |||
48 | if (fields) { | ||
49 | return createVideoMiniatureFromExisting({ | ||
50 | inputPath: fields[0].path, | ||
51 | video, | ||
52 | type: p.type, | ||
53 | automaticallyGenerated: automaticallyGenerated || false | ||
54 | }) | ||
55 | } | ||
56 | |||
57 | return fallback(p.type) | ||
58 | }) | ||
59 | |||
60 | return Promise.all(promises) | ||
61 | } | ||
62 | |||
63 | async function setVideoTags (options: { | ||
64 | video: MVideoTag | ||
65 | tags: string[] | ||
66 | transaction?: Transaction | ||
67 | defaultValue?: MTag[] | ||
68 | }) { | ||
69 | const { video, tags, transaction, defaultValue } = options | ||
70 | // Set tags to the video | ||
71 | if (tags) { | ||
72 | const tagInstances = await TagModel.findOrCreateTags(tags, transaction) | ||
73 | |||
74 | await video.$set('Tags', tagInstances, { transaction }) | ||
75 | video.Tags = tagInstances | ||
76 | } else { | ||
77 | video.Tags = defaultValue || [] | ||
78 | } | ||
79 | } | ||
80 | |||
27 | // --------------------------------------------------------------------------- | 81 | // --------------------------------------------------------------------------- |
28 | 82 | ||
29 | export { | 83 | export { |
30 | buildLocalVideoFromCreate | 84 | buildLocalVideoFromReq, |
85 | buildVideoThumbnailsFromReq, | ||
86 | setVideoTags | ||
31 | } | 87 | } |