+ const video = buildVideo(res.locals.videoChannel.id, body, youtubeDLInfo)
+
+ let thumbnailModel: MThumbnail
+
+ // Process video thumbnail from request.files
+ thumbnailModel = await processThumbnail(req, video)
+
+ // Process video thumbnail from url if processing from request.files failed
+ if (!thumbnailModel && youtubeDLInfo.thumbnailUrl) {
+ thumbnailModel = await processThumbnailFromUrl(youtubeDLInfo.thumbnailUrl, video)
+ }
+
+ let previewModel: MThumbnail
+
+ // Process video preview from request.files
+ previewModel = await processPreview(req, video)
+
+ // Process video preview from url if processing from request.files failed
+ if (!previewModel && youtubeDLInfo.thumbnailUrl) {
+ previewModel = await processPreviewFromUrl(youtubeDLInfo.thumbnailUrl, video)
+ }
+
+ const tags = body.tags || youtubeDLInfo.tags
+ const videoImportAttributes = {
+ targetUrl,
+ state: VideoImportState.PENDING,
+ userId: user.id
+ }
+ const videoImport = await insertIntoDB({
+ video,
+ thumbnailModel,
+ previewModel,
+ videoChannel: res.locals.videoChannel,
+ tags,
+ videoImportAttributes,
+ user
+ })
+
+ // Get video subtitles
+ try {
+ const subtitles = await getYoutubeDLSubs(targetUrl)
+
+ logger.info('Will create %s subtitles from youtube import %s.', subtitles.length, targetUrl)
+
+ for (const subtitle of subtitles) {
+ const videoCaption = new VideoCaptionModel({
+ videoId: video.id,
+ language: subtitle.language
+ }) as MVideoCaptionVideo
+ videoCaption.Video = video
+
+ // Move physical file
+ await moveAndProcessCaptionFile(subtitle, videoCaption)
+
+ await sequelizeTypescript.transaction(async t => {
+ await VideoCaptionModel.insertOrReplaceLanguage(video.id, subtitle.language, null, t)
+ })
+ }
+ } catch (err) {
+ logger.warn('Cannot get video subtitles.', { err })
+ }
+
+ // Create job to import the video
+ const payload = {
+ type: 'youtube-dl' as 'youtube-dl',
+ videoImportId: videoImport.id,
+ generateThumbnail: !thumbnailModel,
+ generatePreview: !previewModel,
+ fileExt: youtubeDLInfo.fileExt
+ ? `.${youtubeDLInfo.fileExt}`
+ : '.mp4'
+ }
+ await JobQueue.Instance.createJobWithPromise({ type: 'video-import', payload })
+
+ auditLogger.create(getAuditIdFromRes(res), new VideoImportAuditView(videoImport.toFormattedJSON()))
+
+ return res.json(videoImport.toFormattedJSON()).end()
+}
+
+function buildVideo (channelId: number, body: VideoImportCreate, importData: YoutubeDLInfo) {