Fix video_share_url duplicate key in transcoding job

pull/364/head
Chocobozzz 2018-03-19 15:02:36 +01:00
parent 9d145133d8
commit a797728009
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
6 changed files with 63 additions and 44 deletions

View File

@ -4,7 +4,7 @@
### BREAKING CHANGES ### BREAKING CHANGES
* Update videos list/search/get API response: * Update videos list/search/get API response:
* Removed `resolution` field * Removed `resolution` field
* Removed `resolutionLabel` field * Removed `resolutionLabel` field
* Removed `category` field * Removed `category` field
@ -26,6 +26,10 @@
* Added `privacy.id` field * Added `privacy.id` field
* Added `privacy.label` field * Added `privacy.label` field
### Bug fixes
* Fix video_share_url duplicate key on failed transcoding job
## v1.0.0-alpha.8 ## v1.0.0-alpha.8
@ -60,8 +64,7 @@
### Features ### Features
* Add "Local" in menu that lists only local videos * Add "Local" in menu that lists only local videos
## v1.0.0-alpha.4 ## v1.0.0-alpha.4

View File

@ -56,7 +56,7 @@ async function inboxController (req: express.Request, res: express.Response, nex
specificActor = res.locals.videoChannel specificActor = res.locals.videoChannel
} }
logger.info('Receiving inbox requests for %d activities by %s.', activities.length, res.locals.signature.actor) logger.info('Receiving inbox requests for %d activities by %s.', activities.length, res.locals.signature.actor.url)
await processActivities(activities, res.locals.signature.actor, specificActor) await processActivities(activities, res.locals.signature.actor, specificActor)

View File

@ -1,7 +1,7 @@
import * as ffmpeg from 'fluent-ffmpeg' import * as ffmpeg from 'fluent-ffmpeg'
import { join } from 'path' import { join } from 'path'
import { VideoResolution } from '../../shared/models/videos' import { VideoResolution } from '../../shared/models/videos'
import { CONFIG, MAX_VIDEO_TRANSCODING_FPS } from '../initializers' import { CONFIG, VIDEO_TRANSCODING_FPS } from '../initializers'
import { unlinkPromise } from './core-utils' import { unlinkPromise } from './core-utils'
import { processImage } from './image-utils' import { processImage } from './image-utils'
import { logger } from './logger' import { logger } from './logger'
@ -92,7 +92,9 @@ function transcode (options: TranscodeOptions) {
.outputOption('-movflags faststart') .outputOption('-movflags faststart')
// .outputOption('-crf 18') // .outputOption('-crf 18')
if (fps > MAX_VIDEO_TRANSCODING_FPS) command = command.withFPS(MAX_VIDEO_TRANSCODING_FPS) // Our player has some FPS limits
if (fps > VIDEO_TRANSCODING_FPS.MAX) command = command.withFPS(VIDEO_TRANSCODING_FPS.MAX)
else if (fps < VIDEO_TRANSCODING_FPS.MIN) command = command.withFPS(VIDEO_TRANSCODING_FPS.MIN)
if (options.resolution !== undefined) { if (options.resolution !== undefined) {
// '?x720' or '720x?' for example // '?x720' or '720x?' for example

View File

@ -234,7 +234,10 @@ const CONSTRAINTS_FIELDS = {
} }
let VIDEO_VIEW_LIFETIME = 60000 * 60 // 1 hour let VIDEO_VIEW_LIFETIME = 60000 * 60 // 1 hour
const MAX_VIDEO_TRANSCODING_FPS = 30 const VIDEO_TRANSCODING_FPS = {
MIN: 10,
MAX: 30
}
const VIDEO_RATE_TYPES: { [ id: string ]: VideoRateType } = { const VIDEO_RATE_TYPES: { [ id: string ]: VideoRateType } = {
LIKE: 'like', LIKE: 'like',
@ -445,7 +448,7 @@ export {
VIDEO_LICENCES, VIDEO_LICENCES,
VIDEO_RATE_TYPES, VIDEO_RATE_TYPES,
VIDEO_MIMETYPE_EXT, VIDEO_MIMETYPE_EXT,
MAX_VIDEO_TRANSCODING_FPS, VIDEO_TRANSCODING_FPS,
USER_PASSWORD_RESET_LIFETIME, USER_PASSWORD_RESET_LIFETIME,
IMAGE_MIMETYPE_EXT, IMAGE_MIMETYPE_EXT,
SCHEDULER_INTERVAL, SCHEDULER_INTERVAL,

View File

@ -12,27 +12,42 @@ async function shareVideoByServerAndChannel (video: VideoModel, t: Transaction)
const serverActor = await getServerActor() const serverActor = await getServerActor()
const serverShareUrl = getAnnounceActivityPubUrl(video.url, serverActor) const serverShareUrl = getAnnounceActivityPubUrl(video.url, serverActor)
const serverSharePromise = VideoShareModel.create({ const serverSharePromise = VideoShareModel.findOrCreate({
actorId: serverActor.id, defaults: {
videoId: video.id, actorId: serverActor.id,
url: serverShareUrl videoId: video.id,
}, { transaction: t }) url: serverShareUrl
},
where: {
url: serverShareUrl
},
transaction: t
}).then(([ serverShare, created ]) => {
if (created) return sendVideoAnnounceToFollowers(serverActor, serverShare, video, t)
return undefined
})
const videoChannelShareUrl = getAnnounceActivityPubUrl(video.url, video.VideoChannel.Actor) const videoChannelShareUrl = getAnnounceActivityPubUrl(video.url, video.VideoChannel.Actor)
const videoChannelSharePromise = VideoShareModel.create({ const videoChannelSharePromise = VideoShareModel.findOrCreate({
actorId: video.VideoChannel.actorId, defaults: {
videoId: video.id, actorId: video.VideoChannel.actorId,
url: videoChannelShareUrl videoId: video.id,
}, { transaction: t }) url: videoChannelShareUrl
},
where: {
url: videoChannelShareUrl
},
transaction: t
}).then(([ videoChannelShare, created ]) => {
if (created) return sendVideoAnnounceToFollowers(serverActor, videoChannelShare, video, t)
const [ serverShare, videoChannelShare ] = await Promise.all([ return undefined
serverSharePromise, })
videoChannelSharePromise
])
return Promise.all([ return Promise.all([
sendVideoAnnounceToFollowers(serverActor, videoChannelShare, video, t), serverSharePromise,
sendVideoAnnounceToFollowers(serverActor, serverShare, video, t) videoChannelSharePromise
]) ])
} }

View File

@ -63,8 +63,10 @@ async function onVideoFileOptimizerSuccess (video: VideoModel) {
if (video.privacy !== VideoPrivacy.PRIVATE) { if (video.privacy !== VideoPrivacy.PRIVATE) {
// Now we'll add the video's meta data to our followers // Now we'll add the video's meta data to our followers
await sendCreateVideo(video, undefined) await sequelizeTypescript.transaction(async t => {
await shareVideoByServerAndChannel(video, undefined) await sendCreateVideo(video, t)
await shareVideoByServerAndChannel(video, t)
})
} }
const { videoFileResolution } = await videoDatabase.getOriginalFileResolution() const { videoFileResolution } = await videoDatabase.getOriginalFileResolution()
@ -77,27 +79,21 @@ async function onVideoFileOptimizerSuccess (video: VideoModel) {
) )
if (resolutionsEnabled.length !== 0) { if (resolutionsEnabled.length !== 0) {
try { const tasks: Promise<any>[] = []
await sequelizeTypescript.transaction(async t => {
const tasks: Promise<any>[] = []
for (const resolution of resolutionsEnabled) { for (const resolution of resolutionsEnabled) {
const dataInput = { const dataInput = {
videoUUID: videoDatabase.uuid, videoUUID: videoDatabase.uuid,
resolution resolution
} }
const p = JobQueue.Instance.createJob({ type: 'video-file', payload: dataInput }) const p = JobQueue.Instance.createJob({ type: 'video-file', payload: dataInput })
tasks.push(p) tasks.push(p)
}
await Promise.all(tasks)
})
logger.info('Transcoding jobs created for uuid %s.', videoDatabase.uuid, { resolutionsEnabled })
} catch (err) {
logger.warn('Cannot transcode the video.', err)
} }
await Promise.all(tasks)
logger.info('Transcoding jobs created for uuid %s.', videoDatabase.uuid, { resolutionsEnabled })
} else { } else {
logger.info('No transcoding jobs created for video %s (no resolutions enabled).') logger.info('No transcoding jobs created for video %s (no resolutions enabled).')
return undefined return undefined