aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md9
-rw-r--r--server/controllers/activitypub/inbox.ts2
-rw-r--r--server/helpers/ffmpeg-utils.ts6
-rw-r--r--server/initializers/constants.ts7
-rw-r--r--server/lib/activitypub/share.ts47
-rw-r--r--server/lib/job-queue/handlers/video-file.ts40
6 files changed, 65 insertions, 46 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 04b8b7c31..fb6ace20e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,7 +4,7 @@
4 4
5### BREAKING CHANGES 5### BREAKING CHANGES
6 6
7* Update videos list/search/get API response: 7 * Update videos list/search/get API response:
8 * Removed `resolution` field 8 * Removed `resolution` field
9 * Removed `resolutionLabel` field 9 * Removed `resolutionLabel` field
10 * Removed `category` field 10 * Removed `category` field
@@ -26,6 +26,10 @@
26 * Added `privacy.id` field 26 * Added `privacy.id` field
27 * Added `privacy.label` field 27 * Added `privacy.label` field
28 28
29### Bug fixes
30
31 * Fix video_share_url duplicate key on failed transcoding job
32
29 33
30## v1.0.0-alpha.8 34## v1.0.0-alpha.8
31 35
@@ -60,8 +64,7 @@
60 64
61### Features 65### Features
62 66
63 * Add "Local" in menu that lists only local videos 67 * Add "Local" in menu that lists only local videos
64
65 68
66 69
67## v1.0.0-alpha.4 70## v1.0.0-alpha.4
diff --git a/server/controllers/activitypub/inbox.ts b/server/controllers/activitypub/inbox.ts
index 0354d7833..df041aebf 100644
--- a/server/controllers/activitypub/inbox.ts
+++ b/server/controllers/activitypub/inbox.ts
@@ -56,7 +56,7 @@ async function inboxController (req: express.Request, res: express.Response, nex
56 specificActor = res.locals.videoChannel 56 specificActor = res.locals.videoChannel
57 } 57 }
58 58
59 logger.info('Receiving inbox requests for %d activities by %s.', activities.length, res.locals.signature.actor) 59 logger.info('Receiving inbox requests for %d activities by %s.', activities.length, res.locals.signature.actor.url)
60 60
61 await processActivities(activities, res.locals.signature.actor, specificActor) 61 await processActivities(activities, res.locals.signature.actor, specificActor)
62 62
diff --git a/server/helpers/ffmpeg-utils.ts b/server/helpers/ffmpeg-utils.ts
index 4f75ba5a8..4d6cd3a82 100644
--- a/server/helpers/ffmpeg-utils.ts
+++ b/server/helpers/ffmpeg-utils.ts
@@ -1,7 +1,7 @@
1import * as ffmpeg from 'fluent-ffmpeg' 1import * as ffmpeg from 'fluent-ffmpeg'
2import { join } from 'path' 2import { join } from 'path'
3import { VideoResolution } from '../../shared/models/videos' 3import { VideoResolution } from '../../shared/models/videos'
4import { CONFIG, MAX_VIDEO_TRANSCODING_FPS } from '../initializers' 4import { CONFIG, VIDEO_TRANSCODING_FPS } from '../initializers'
5import { unlinkPromise } from './core-utils' 5import { unlinkPromise } from './core-utils'
6import { processImage } from './image-utils' 6import { processImage } from './image-utils'
7import { logger } from './logger' 7import { logger } from './logger'
@@ -92,7 +92,9 @@ function transcode (options: TranscodeOptions) {
92 .outputOption('-movflags faststart') 92 .outputOption('-movflags faststart')
93 // .outputOption('-crf 18') 93 // .outputOption('-crf 18')
94 94
95 if (fps > MAX_VIDEO_TRANSCODING_FPS) command = command.withFPS(MAX_VIDEO_TRANSCODING_FPS) 95 // Our player has some FPS limits
96 if (fps > VIDEO_TRANSCODING_FPS.MAX) command = command.withFPS(VIDEO_TRANSCODING_FPS.MAX)
97 else if (fps < VIDEO_TRANSCODING_FPS.MIN) command = command.withFPS(VIDEO_TRANSCODING_FPS.MIN)
96 98
97 if (options.resolution !== undefined) { 99 if (options.resolution !== undefined) {
98 // '?x720' or '720x?' for example 100 // '?x720' or '720x?' for example
diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts
index d12d96803..3cf9ea36d 100644
--- a/server/initializers/constants.ts
+++ b/server/initializers/constants.ts
@@ -234,7 +234,10 @@ const CONSTRAINTS_FIELDS = {
234} 234}
235 235
236let VIDEO_VIEW_LIFETIME = 60000 * 60 // 1 hour 236let VIDEO_VIEW_LIFETIME = 60000 * 60 // 1 hour
237const MAX_VIDEO_TRANSCODING_FPS = 30 237const VIDEO_TRANSCODING_FPS = {
238 MIN: 10,
239 MAX: 30
240}
238 241
239const VIDEO_RATE_TYPES: { [ id: string ]: VideoRateType } = { 242const VIDEO_RATE_TYPES: { [ id: string ]: VideoRateType } = {
240 LIKE: 'like', 243 LIKE: 'like',
@@ -445,7 +448,7 @@ export {
445 VIDEO_LICENCES, 448 VIDEO_LICENCES,
446 VIDEO_RATE_TYPES, 449 VIDEO_RATE_TYPES,
447 VIDEO_MIMETYPE_EXT, 450 VIDEO_MIMETYPE_EXT,
448 MAX_VIDEO_TRANSCODING_FPS, 451 VIDEO_TRANSCODING_FPS,
449 USER_PASSWORD_RESET_LIFETIME, 452 USER_PASSWORD_RESET_LIFETIME,
450 IMAGE_MIMETYPE_EXT, 453 IMAGE_MIMETYPE_EXT,
451 SCHEDULER_INTERVAL, 454 SCHEDULER_INTERVAL,
diff --git a/server/lib/activitypub/share.ts b/server/lib/activitypub/share.ts
index 53ecd3dab..038f19b7d 100644
--- a/server/lib/activitypub/share.ts
+++ b/server/lib/activitypub/share.ts
@@ -12,27 +12,42 @@ async function shareVideoByServerAndChannel (video: VideoModel, t: Transaction)
12 const serverActor = await getServerActor() 12 const serverActor = await getServerActor()
13 13
14 const serverShareUrl = getAnnounceActivityPubUrl(video.url, serverActor) 14 const serverShareUrl = getAnnounceActivityPubUrl(video.url, serverActor)
15 const serverSharePromise = VideoShareModel.create({ 15 const serverSharePromise = VideoShareModel.findOrCreate({
16 actorId: serverActor.id, 16 defaults: {
17 videoId: video.id, 17 actorId: serverActor.id,
18 url: serverShareUrl 18 videoId: video.id,
19 }, { transaction: t }) 19 url: serverShareUrl
20 },
21 where: {
22 url: serverShareUrl
23 },
24 transaction: t
25 }).then(([ serverShare, created ]) => {
26 if (created) return sendVideoAnnounceToFollowers(serverActor, serverShare, video, t)
27
28 return undefined
29 })
20 30
21 const videoChannelShareUrl = getAnnounceActivityPubUrl(video.url, video.VideoChannel.Actor) 31 const videoChannelShareUrl = getAnnounceActivityPubUrl(video.url, video.VideoChannel.Actor)
22 const videoChannelSharePromise = VideoShareModel.create({ 32 const videoChannelSharePromise = VideoShareModel.findOrCreate({
23 actorId: video.VideoChannel.actorId, 33 defaults: {
24 videoId: video.id, 34 actorId: video.VideoChannel.actorId,
25 url: videoChannelShareUrl 35 videoId: video.id,
26 }, { transaction: t }) 36 url: videoChannelShareUrl
37 },
38 where: {
39 url: videoChannelShareUrl
40 },
41 transaction: t
42 }).then(([ videoChannelShare, created ]) => {
43 if (created) return sendVideoAnnounceToFollowers(serverActor, videoChannelShare, video, t)
27 44
28 const [ serverShare, videoChannelShare ] = await Promise.all([ 45 return undefined
29 serverSharePromise, 46 })
30 videoChannelSharePromise
31 ])
32 47
33 return Promise.all([ 48 return Promise.all([
34 sendVideoAnnounceToFollowers(serverActor, videoChannelShare, video, t), 49 serverSharePromise,
35 sendVideoAnnounceToFollowers(serverActor, serverShare, video, t) 50 videoChannelSharePromise
36 ]) 51 ])
37} 52}
38 53
diff --git a/server/lib/job-queue/handlers/video-file.ts b/server/lib/job-queue/handlers/video-file.ts
index bd9412290..1b41d29e8 100644
--- a/server/lib/job-queue/handlers/video-file.ts
+++ b/server/lib/job-queue/handlers/video-file.ts
@@ -63,8 +63,10 @@ async function onVideoFileOptimizerSuccess (video: VideoModel) {
63 63
64 if (video.privacy !== VideoPrivacy.PRIVATE) { 64 if (video.privacy !== VideoPrivacy.PRIVATE) {
65 // Now we'll add the video's meta data to our followers 65 // Now we'll add the video's meta data to our followers
66 await sendCreateVideo(video, undefined) 66 await sequelizeTypescript.transaction(async t => {
67 await shareVideoByServerAndChannel(video, undefined) 67 await sendCreateVideo(video, t)
68 await shareVideoByServerAndChannel(video, t)
69 })
68 } 70 }
69 71
70 const { videoFileResolution } = await videoDatabase.getOriginalFileResolution() 72 const { videoFileResolution } = await videoDatabase.getOriginalFileResolution()
@@ -77,27 +79,21 @@ async function onVideoFileOptimizerSuccess (video: VideoModel) {
77 ) 79 )
78 80
79 if (resolutionsEnabled.length !== 0) { 81 if (resolutionsEnabled.length !== 0) {
80 try { 82 const tasks: Promise<any>[] = []
81 await sequelizeTypescript.transaction(async t => { 83
82 const tasks: Promise<any>[] = [] 84 for (const resolution of resolutionsEnabled) {
83 85 const dataInput = {
84 for (const resolution of resolutionsEnabled) { 86 videoUUID: videoDatabase.uuid,
85 const dataInput = { 87 resolution
86 videoUUID: videoDatabase.uuid, 88 }
87 resolution 89
88 } 90 const p = JobQueue.Instance.createJob({ type: 'video-file', payload: dataInput })
89 91 tasks.push(p)
90 const p = JobQueue.Instance.createJob({ type: 'video-file', payload: dataInput })
91 tasks.push(p)
92 }
93
94 await Promise.all(tasks)
95 })
96
97 logger.info('Transcoding jobs created for uuid %s.', videoDatabase.uuid, { resolutionsEnabled })
98 } catch (err) {
99 logger.warn('Cannot transcode the video.', err)
100 } 92 }
93
94 await Promise.all(tasks)
95
96 logger.info('Transcoding jobs created for uuid %s.', videoDatabase.uuid, { resolutionsEnabled })
101 } else { 97 } else {
102 logger.info('No transcoding jobs created for video %s (no resolutions enabled).') 98 logger.info('No transcoding jobs created for video %s (no resolutions enabled).')
103 return undefined 99 return undefined