Fix video_share_url duplicate key in transcoding job
This commit is contained in:
parent
9d145133d8
commit
a797728009
6 changed files with 63 additions and 44 deletions
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue