### BREAKING CHANGES
-* Update videos list/search/get API response:
+ * Update videos list/search/get API response:
* Removed `resolution` field
* Removed `resolutionLabel` field
* Removed `category` field
* Added `privacy.id` field
* Added `privacy.label` field
+### Bug fixes
+
+ * Fix video_share_url duplicate key on failed transcoding job
+
## v1.0.0-alpha.8
### Features
- * Add "Local" in menu that lists only local videos
-
+ * Add "Local" in menu that lists only local videos
## v1.0.0-alpha.4
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)
import * as ffmpeg from 'fluent-ffmpeg'
import { join } from 'path'
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 { processImage } from './image-utils'
import { logger } from './logger'
.outputOption('-movflags faststart')
// .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) {
// '?x720' or '720x?' for example
}
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 } = {
LIKE: 'like',
VIDEO_LICENCES,
VIDEO_RATE_TYPES,
VIDEO_MIMETYPE_EXT,
- MAX_VIDEO_TRANSCODING_FPS,
+ VIDEO_TRANSCODING_FPS,
USER_PASSWORD_RESET_LIFETIME,
IMAGE_MIMETYPE_EXT,
SCHEDULER_INTERVAL,
const serverActor = await getServerActor()
const serverShareUrl = getAnnounceActivityPubUrl(video.url, serverActor)
- const serverSharePromise = VideoShareModel.create({
- actorId: serverActor.id,
- videoId: video.id,
- url: serverShareUrl
- }, { transaction: t })
+ const serverSharePromise = VideoShareModel.findOrCreate({
+ defaults: {
+ actorId: serverActor.id,
+ videoId: video.id,
+ 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 videoChannelSharePromise = VideoShareModel.create({
- actorId: video.VideoChannel.actorId,
- videoId: video.id,
- url: videoChannelShareUrl
- }, { transaction: t })
+ const videoChannelSharePromise = VideoShareModel.findOrCreate({
+ defaults: {
+ actorId: video.VideoChannel.actorId,
+ videoId: video.id,
+ url: videoChannelShareUrl
+ },
+ where: {
+ url: videoChannelShareUrl
+ },
+ transaction: t
+ }).then(([ videoChannelShare, created ]) => {
+ if (created) return sendVideoAnnounceToFollowers(serverActor, videoChannelShare, video, t)
- const [ serverShare, videoChannelShare ] = await Promise.all([
- serverSharePromise,
- videoChannelSharePromise
- ])
+ return undefined
+ })
return Promise.all([
- sendVideoAnnounceToFollowers(serverActor, videoChannelShare, video, t),
- sendVideoAnnounceToFollowers(serverActor, serverShare, video, t)
+ serverSharePromise,
+ videoChannelSharePromise
])
}
if (video.privacy !== VideoPrivacy.PRIVATE) {
// Now we'll add the video's meta data to our followers
- await sendCreateVideo(video, undefined)
- await shareVideoByServerAndChannel(video, undefined)
+ await sequelizeTypescript.transaction(async t => {
+ await sendCreateVideo(video, t)
+ await shareVideoByServerAndChannel(video, t)
+ })
}
const { videoFileResolution } = await videoDatabase.getOriginalFileResolution()
)
if (resolutionsEnabled.length !== 0) {
- try {
- await sequelizeTypescript.transaction(async t => {
- const tasks: Promise<any>[] = []
-
- for (const resolution of resolutionsEnabled) {
- const dataInput = {
- videoUUID: videoDatabase.uuid,
- resolution
- }
-
- const p = JobQueue.Instance.createJob({ type: 'video-file', payload: dataInput })
- 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)
+ const tasks: Promise<any>[] = []
+
+ for (const resolution of resolutionsEnabled) {
+ const dataInput = {
+ videoUUID: videoDatabase.uuid,
+ resolution
+ }
+
+ const p = JobQueue.Instance.createJob({ type: 'video-file', payload: dataInput })
+ tasks.push(p)
}
+
+ await Promise.all(tasks)
+
+ logger.info('Transcoding jobs created for uuid %s.', videoDatabase.uuid, { resolutionsEnabled })
} else {
logger.info('No transcoding jobs created for video %s (no resolutions enabled).')
return undefined