mirror of
https://github.com/Chocobozzz/PeerTube.git
synced 2025-10-04 02:09:37 +02:00
server/server -> server/core
This commit is contained in:
parent
114327d4ce
commit
5a3d0650c9
838 changed files with 111 additions and 111 deletions
18
server/core/lib/transcoding/shared/ffmpeg-builder.ts
Normal file
18
server/core/lib/transcoding/shared/ffmpeg-builder.ts
Normal file
|
@ -0,0 +1,18 @@
|
|||
import { Job } from 'bullmq'
|
||||
import { getFFmpegCommandWrapperOptions } from '@server/helpers/ffmpeg/index.js'
|
||||
import { logger } from '@server/helpers/logger.js'
|
||||
import { FFmpegVOD } from '@peertube/peertube-ffmpeg'
|
||||
import { VideoTranscodingProfilesManager } from '../default-transcoding-profiles.js'
|
||||
|
||||
export function buildFFmpegVOD (job?: Job) {
|
||||
return new FFmpegVOD({
|
||||
...getFFmpegCommandWrapperOptions('vod', VideoTranscodingProfilesManager.Instance.getAvailableEncoders()),
|
||||
|
||||
updateJobProgress: progress => {
|
||||
if (!job) return
|
||||
|
||||
job.updateProgress(progress)
|
||||
.catch(err => logger.error('Cannot update ffmpeg job progress', { err }))
|
||||
}
|
||||
})
|
||||
}
|
2
server/core/lib/transcoding/shared/index.ts
Normal file
2
server/core/lib/transcoding/shared/index.ts
Normal file
|
@ -0,0 +1,2 @@
|
|||
export * from './job-builders/index.js'
|
||||
export * from './ffmpeg-builder.js'
|
|
@ -0,0 +1,21 @@
|
|||
|
||||
import { MUserId, MVideoFile, MVideoFullLight } from '@server/types/models/index.js'
|
||||
|
||||
export abstract class AbstractJobBuilder {
|
||||
|
||||
abstract createOptimizeOrMergeAudioJobs (options: {
|
||||
video: MVideoFullLight
|
||||
videoFile: MVideoFile
|
||||
isNewVideo: boolean
|
||||
user: MUserId
|
||||
videoFileAlreadyLocked: boolean
|
||||
}): Promise<any>
|
||||
|
||||
abstract createTranscodingJobs (options: {
|
||||
transcodingType: 'hls' | 'webtorrent' | 'web-video' // TODO: remove webtorrent in v7
|
||||
video: MVideoFullLight
|
||||
resolutions: number[]
|
||||
isNewVideo: boolean
|
||||
user: MUserId | null
|
||||
}): Promise<any>
|
||||
}
|
2
server/core/lib/transcoding/shared/job-builders/index.ts
Normal file
2
server/core/lib/transcoding/shared/job-builders/index.ts
Normal file
|
@ -0,0 +1,2 @@
|
|||
export * from './transcoding-job-queue-builder.js'
|
||||
export * from './transcoding-runner-job-builder.js'
|
|
@ -0,0 +1,322 @@
|
|||
import Bluebird from 'bluebird'
|
||||
import { computeOutputFPS } from '@server/helpers/ffmpeg/index.js'
|
||||
import { logger } from '@server/helpers/logger.js'
|
||||
import { CONFIG } from '@server/initializers/config.js'
|
||||
import { DEFAULT_AUDIO_RESOLUTION, VIDEO_TRANSCODING_FPS } from '@server/initializers/constants.js'
|
||||
import { CreateJobArgument, JobQueue } from '@server/lib/job-queue/index.js'
|
||||
import { Hooks } from '@server/lib/plugins/hooks.js'
|
||||
import { VideoPathManager } from '@server/lib/video-path-manager.js'
|
||||
import { VideoJobInfoModel } from '@server/models/video/video-job-info.js'
|
||||
import { MUserId, MVideoFile, MVideoFullLight, MVideoWithFileThumbnail } from '@server/types/models/index.js'
|
||||
import { ffprobePromise, getVideoStreamDimensionsInfo, getVideoStreamFPS, hasAudioStream, isAudioFile } from '@peertube/peertube-ffmpeg'
|
||||
import {
|
||||
HLSTranscodingPayload,
|
||||
MergeAudioTranscodingPayload,
|
||||
NewWebVideoResolutionTranscodingPayload,
|
||||
OptimizeTranscodingPayload,
|
||||
VideoTranscodingPayload
|
||||
} from '@peertube/peertube-models'
|
||||
import { getTranscodingJobPriority } from '../../transcoding-priority.js'
|
||||
import { canDoQuickTranscode } from '../../transcoding-quick-transcode.js'
|
||||
import { buildOriginalFileResolution, computeResolutionsToTranscode } from '../../transcoding-resolutions.js'
|
||||
import { AbstractJobBuilder } from './abstract-job-builder.js'
|
||||
|
||||
export class TranscodingJobQueueBuilder extends AbstractJobBuilder {
|
||||
|
||||
async createOptimizeOrMergeAudioJobs (options: {
|
||||
video: MVideoFullLight
|
||||
videoFile: MVideoFile
|
||||
isNewVideo: boolean
|
||||
user: MUserId
|
||||
videoFileAlreadyLocked: boolean
|
||||
}) {
|
||||
const { video, videoFile, isNewVideo, user, videoFileAlreadyLocked } = options
|
||||
|
||||
let mergeOrOptimizePayload: MergeAudioTranscodingPayload | OptimizeTranscodingPayload
|
||||
let nextTranscodingSequentialJobPayloads: (NewWebVideoResolutionTranscodingPayload | HLSTranscodingPayload)[][] = []
|
||||
|
||||
const mutexReleaser = videoFileAlreadyLocked
|
||||
? () => {}
|
||||
: await VideoPathManager.Instance.lockFiles(video.uuid)
|
||||
|
||||
try {
|
||||
await video.reload()
|
||||
await videoFile.reload()
|
||||
|
||||
await VideoPathManager.Instance.makeAvailableVideoFile(videoFile.withVideoOrPlaylist(video), async videoFilePath => {
|
||||
const probe = await ffprobePromise(videoFilePath)
|
||||
|
||||
const { resolution } = await getVideoStreamDimensionsInfo(videoFilePath, probe)
|
||||
const hasAudio = await hasAudioStream(videoFilePath, probe)
|
||||
const quickTranscode = await canDoQuickTranscode(videoFilePath, probe)
|
||||
const inputFPS = videoFile.isAudio()
|
||||
? VIDEO_TRANSCODING_FPS.AUDIO_MERGE // The first transcoding job will transcode to this FPS value
|
||||
: await getVideoStreamFPS(videoFilePath, probe)
|
||||
|
||||
const maxResolution = await isAudioFile(videoFilePath, probe)
|
||||
? DEFAULT_AUDIO_RESOLUTION
|
||||
: buildOriginalFileResolution(resolution)
|
||||
|
||||
if (CONFIG.TRANSCODING.HLS.ENABLED === true) {
|
||||
nextTranscodingSequentialJobPayloads.push([
|
||||
this.buildHLSJobPayload({
|
||||
deleteWebVideoFiles: CONFIG.TRANSCODING.WEB_VIDEOS.ENABLED === false,
|
||||
|
||||
// We had some issues with a web video quick transcoded while producing a HLS version of it
|
||||
copyCodecs: !quickTranscode,
|
||||
|
||||
resolution: maxResolution,
|
||||
fps: computeOutputFPS({ inputFPS, resolution: maxResolution }),
|
||||
videoUUID: video.uuid,
|
||||
isNewVideo
|
||||
})
|
||||
])
|
||||
}
|
||||
|
||||
const lowerResolutionJobPayloads = await this.buildLowerResolutionJobPayloads({
|
||||
video,
|
||||
inputVideoResolution: maxResolution,
|
||||
inputVideoFPS: inputFPS,
|
||||
hasAudio,
|
||||
isNewVideo
|
||||
})
|
||||
|
||||
nextTranscodingSequentialJobPayloads = [ ...nextTranscodingSequentialJobPayloads, ...lowerResolutionJobPayloads ]
|
||||
|
||||
const hasChildren = nextTranscodingSequentialJobPayloads.length !== 0
|
||||
mergeOrOptimizePayload = videoFile.isAudio()
|
||||
? this.buildMergeAudioPayload({ videoUUID: video.uuid, isNewVideo, hasChildren })
|
||||
: this.buildOptimizePayload({ videoUUID: video.uuid, isNewVideo, quickTranscode, hasChildren })
|
||||
})
|
||||
} finally {
|
||||
mutexReleaser()
|
||||
}
|
||||
|
||||
const nextTranscodingSequentialJobs = await Bluebird.mapSeries(nextTranscodingSequentialJobPayloads, payloads => {
|
||||
return Bluebird.mapSeries(payloads, payload => {
|
||||
return this.buildTranscodingJob({ payload, user })
|
||||
})
|
||||
})
|
||||
|
||||
const transcodingJobBuilderJob: CreateJobArgument = {
|
||||
type: 'transcoding-job-builder',
|
||||
payload: {
|
||||
videoUUID: video.uuid,
|
||||
sequentialJobs: nextTranscodingSequentialJobs
|
||||
}
|
||||
}
|
||||
|
||||
const mergeOrOptimizeJob = await this.buildTranscodingJob({ payload: mergeOrOptimizePayload, user })
|
||||
|
||||
await JobQueue.Instance.createSequentialJobFlow(...[ mergeOrOptimizeJob, transcodingJobBuilderJob ])
|
||||
|
||||
await VideoJobInfoModel.increaseOrCreate(video.uuid, 'pendingTranscode')
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
async createTranscodingJobs (options: {
|
||||
transcodingType: 'hls' | 'webtorrent' | 'web-video' // TODO: remove webtorrent in v7
|
||||
video: MVideoFullLight
|
||||
resolutions: number[]
|
||||
isNewVideo: boolean
|
||||
user: MUserId | null
|
||||
}) {
|
||||
const { video, transcodingType, resolutions, isNewVideo } = options
|
||||
|
||||
const maxResolution = Math.max(...resolutions)
|
||||
const childrenResolutions = resolutions.filter(r => r !== maxResolution)
|
||||
|
||||
logger.info('Manually creating transcoding jobs for %s.', transcodingType, { childrenResolutions, maxResolution })
|
||||
|
||||
const { fps: inputFPS } = await video.probeMaxQualityFile()
|
||||
|
||||
const children = childrenResolutions.map(resolution => {
|
||||
const fps = computeOutputFPS({ inputFPS, resolution })
|
||||
|
||||
if (transcodingType === 'hls') {
|
||||
return this.buildHLSJobPayload({ videoUUID: video.uuid, resolution, fps, isNewVideo })
|
||||
}
|
||||
|
||||
if (transcodingType === 'webtorrent' || transcodingType === 'web-video') {
|
||||
return this.buildWebVideoJobPayload({ videoUUID: video.uuid, resolution, fps, isNewVideo })
|
||||
}
|
||||
|
||||
throw new Error('Unknown transcoding type')
|
||||
})
|
||||
|
||||
const fps = computeOutputFPS({ inputFPS, resolution: maxResolution })
|
||||
|
||||
const parent = transcodingType === 'hls'
|
||||
? this.buildHLSJobPayload({ videoUUID: video.uuid, resolution: maxResolution, fps, isNewVideo })
|
||||
: this.buildWebVideoJobPayload({ videoUUID: video.uuid, resolution: maxResolution, fps, isNewVideo })
|
||||
|
||||
// Process the last resolution after the other ones to prevent concurrency issue
|
||||
// Because low resolutions use the biggest one as ffmpeg input
|
||||
await this.createTranscodingJobsWithChildren({ videoUUID: video.uuid, parent, children, user: null })
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
private async createTranscodingJobsWithChildren (options: {
|
||||
videoUUID: string
|
||||
parent: (HLSTranscodingPayload | NewWebVideoResolutionTranscodingPayload)
|
||||
children: (HLSTranscodingPayload | NewWebVideoResolutionTranscodingPayload)[]
|
||||
user: MUserId | null
|
||||
}) {
|
||||
const { videoUUID, parent, children, user } = options
|
||||
|
||||
const parentJob = await this.buildTranscodingJob({ payload: parent, user })
|
||||
const childrenJobs = await Bluebird.mapSeries(children, c => this.buildTranscodingJob({ payload: c, user }))
|
||||
|
||||
await JobQueue.Instance.createJobWithChildren(parentJob, childrenJobs)
|
||||
|
||||
await VideoJobInfoModel.increaseOrCreate(videoUUID, 'pendingTranscode', 1 + children.length)
|
||||
}
|
||||
|
||||
private async buildTranscodingJob (options: {
|
||||
payload: VideoTranscodingPayload
|
||||
user: MUserId | null // null means we don't want priority
|
||||
}) {
|
||||
const { user, payload } = options
|
||||
|
||||
return {
|
||||
type: 'video-transcoding' as 'video-transcoding',
|
||||
priority: await getTranscodingJobPriority({ user, type: 'vod', fallback: undefined }),
|
||||
payload
|
||||
}
|
||||
}
|
||||
|
||||
private async buildLowerResolutionJobPayloads (options: {
|
||||
video: MVideoWithFileThumbnail
|
||||
inputVideoResolution: number
|
||||
inputVideoFPS: number
|
||||
hasAudio: boolean
|
||||
isNewVideo: boolean
|
||||
}) {
|
||||
const { video, inputVideoResolution, inputVideoFPS, isNewVideo, hasAudio } = options
|
||||
|
||||
// Create transcoding jobs if there are enabled resolutions
|
||||
const resolutionsEnabled = await Hooks.wrapObject(
|
||||
computeResolutionsToTranscode({ input: inputVideoResolution, type: 'vod', includeInput: false, strictLower: true, hasAudio }),
|
||||
'filter:transcoding.auto.resolutions-to-transcode.result',
|
||||
options
|
||||
)
|
||||
|
||||
const sequentialPayloads: (NewWebVideoResolutionTranscodingPayload | HLSTranscodingPayload)[][] = []
|
||||
|
||||
for (const resolution of resolutionsEnabled) {
|
||||
const fps = computeOutputFPS({ inputFPS: inputVideoFPS, resolution })
|
||||
|
||||
if (CONFIG.TRANSCODING.WEB_VIDEOS.ENABLED) {
|
||||
const payloads: (NewWebVideoResolutionTranscodingPayload | HLSTranscodingPayload)[] = [
|
||||
this.buildWebVideoJobPayload({
|
||||
videoUUID: video.uuid,
|
||||
resolution,
|
||||
fps,
|
||||
isNewVideo
|
||||
})
|
||||
]
|
||||
|
||||
// Create a subsequent job to create HLS resolution that will just copy web video codecs
|
||||
if (CONFIG.TRANSCODING.HLS.ENABLED) {
|
||||
payloads.push(
|
||||
this.buildHLSJobPayload({
|
||||
videoUUID: video.uuid,
|
||||
resolution,
|
||||
fps,
|
||||
isNewVideo,
|
||||
copyCodecs: true
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
sequentialPayloads.push(payloads)
|
||||
} else if (CONFIG.TRANSCODING.HLS.ENABLED) {
|
||||
sequentialPayloads.push([
|
||||
this.buildHLSJobPayload({
|
||||
videoUUID: video.uuid,
|
||||
resolution,
|
||||
fps,
|
||||
copyCodecs: false,
|
||||
isNewVideo
|
||||
})
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
return sequentialPayloads
|
||||
}
|
||||
|
||||
private buildHLSJobPayload (options: {
|
||||
videoUUID: string
|
||||
resolution: number
|
||||
fps: number
|
||||
isNewVideo: boolean
|
||||
deleteWebVideoFiles?: boolean // default false
|
||||
copyCodecs?: boolean // default false
|
||||
}): HLSTranscodingPayload {
|
||||
const { videoUUID, resolution, fps, isNewVideo, deleteWebVideoFiles = false, copyCodecs = false } = options
|
||||
|
||||
return {
|
||||
type: 'new-resolution-to-hls',
|
||||
videoUUID,
|
||||
resolution,
|
||||
fps,
|
||||
copyCodecs,
|
||||
isNewVideo,
|
||||
deleteWebVideoFiles
|
||||
}
|
||||
}
|
||||
|
||||
private buildWebVideoJobPayload (options: {
|
||||
videoUUID: string
|
||||
resolution: number
|
||||
fps: number
|
||||
isNewVideo: boolean
|
||||
}): NewWebVideoResolutionTranscodingPayload {
|
||||
const { videoUUID, resolution, fps, isNewVideo } = options
|
||||
|
||||
return {
|
||||
type: 'new-resolution-to-web-video',
|
||||
videoUUID,
|
||||
isNewVideo,
|
||||
resolution,
|
||||
fps
|
||||
}
|
||||
}
|
||||
|
||||
private buildMergeAudioPayload (options: {
|
||||
videoUUID: string
|
||||
isNewVideo: boolean
|
||||
hasChildren: boolean
|
||||
}): MergeAudioTranscodingPayload {
|
||||
const { videoUUID, isNewVideo, hasChildren } = options
|
||||
|
||||
return {
|
||||
type: 'merge-audio-to-web-video',
|
||||
resolution: DEFAULT_AUDIO_RESOLUTION,
|
||||
fps: VIDEO_TRANSCODING_FPS.AUDIO_MERGE,
|
||||
videoUUID,
|
||||
isNewVideo,
|
||||
hasChildren
|
||||
}
|
||||
}
|
||||
|
||||
private buildOptimizePayload (options: {
|
||||
videoUUID: string
|
||||
quickTranscode: boolean
|
||||
isNewVideo: boolean
|
||||
hasChildren: boolean
|
||||
}): OptimizeTranscodingPayload {
|
||||
const { videoUUID, quickTranscode, isNewVideo, hasChildren } = options
|
||||
|
||||
return {
|
||||
type: 'optimize-to-web-video',
|
||||
videoUUID,
|
||||
isNewVideo,
|
||||
hasChildren,
|
||||
quickTranscode
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,200 @@
|
|||
import { computeOutputFPS } from '@server/helpers/ffmpeg/index.js'
|
||||
import { logger, loggerTagsFactory } from '@server/helpers/logger.js'
|
||||
import { CONFIG } from '@server/initializers/config.js'
|
||||
import { DEFAULT_AUDIO_RESOLUTION, VIDEO_TRANSCODING_FPS } from '@server/initializers/constants.js'
|
||||
import { Hooks } from '@server/lib/plugins/hooks.js'
|
||||
import {
|
||||
VODAudioMergeTranscodingJobHandler,
|
||||
VODHLSTranscodingJobHandler,
|
||||
VODWebVideoTranscodingJobHandler
|
||||
} from '@server/lib/runners/index.js'
|
||||
import { VideoPathManager } from '@server/lib/video-path-manager.js'
|
||||
import { MUserId, MVideoFile, MVideoFullLight, MVideoWithFileThumbnail } from '@server/types/models/index.js'
|
||||
import { MRunnerJob } from '@server/types/models/runners/index.js'
|
||||
import { ffprobePromise, getVideoStreamDimensionsInfo, getVideoStreamFPS, hasAudioStream, isAudioFile } from '@peertube/peertube-ffmpeg'
|
||||
import { getTranscodingJobPriority } from '../../transcoding-priority.js'
|
||||
import { computeResolutionsToTranscode } from '../../transcoding-resolutions.js'
|
||||
import { AbstractJobBuilder } from './abstract-job-builder.js'
|
||||
|
||||
/**
|
||||
*
|
||||
* Class to build transcoding job in the local job queue
|
||||
*
|
||||
*/
|
||||
|
||||
const lTags = loggerTagsFactory('transcoding')
|
||||
|
||||
export class TranscodingRunnerJobBuilder extends AbstractJobBuilder {
|
||||
|
||||
async createOptimizeOrMergeAudioJobs (options: {
|
||||
video: MVideoFullLight
|
||||
videoFile: MVideoFile
|
||||
isNewVideo: boolean
|
||||
user: MUserId
|
||||
videoFileAlreadyLocked: boolean
|
||||
}) {
|
||||
const { video, videoFile, isNewVideo, user, videoFileAlreadyLocked } = options
|
||||
|
||||
const mutexReleaser = videoFileAlreadyLocked
|
||||
? () => {}
|
||||
: await VideoPathManager.Instance.lockFiles(video.uuid)
|
||||
|
||||
try {
|
||||
await video.reload()
|
||||
await videoFile.reload()
|
||||
|
||||
await VideoPathManager.Instance.makeAvailableVideoFile(videoFile.withVideoOrPlaylist(video), async videoFilePath => {
|
||||
const probe = await ffprobePromise(videoFilePath)
|
||||
|
||||
const { resolution } = await getVideoStreamDimensionsInfo(videoFilePath, probe)
|
||||
const hasAudio = await hasAudioStream(videoFilePath, probe)
|
||||
const inputFPS = videoFile.isAudio()
|
||||
? VIDEO_TRANSCODING_FPS.AUDIO_MERGE // The first transcoding job will transcode to this FPS value
|
||||
: await getVideoStreamFPS(videoFilePath, probe)
|
||||
|
||||
const maxResolution = await isAudioFile(videoFilePath, probe)
|
||||
? DEFAULT_AUDIO_RESOLUTION
|
||||
: resolution
|
||||
|
||||
const fps = computeOutputFPS({ inputFPS, resolution: maxResolution })
|
||||
const priority = await getTranscodingJobPriority({ user, type: 'vod', fallback: 0 })
|
||||
|
||||
const mainRunnerJob = videoFile.isAudio()
|
||||
? await new VODAudioMergeTranscodingJobHandler().create({ video, resolution: maxResolution, fps, isNewVideo, priority })
|
||||
: await new VODWebVideoTranscodingJobHandler().create({ video, resolution: maxResolution, fps, isNewVideo, priority })
|
||||
|
||||
if (CONFIG.TRANSCODING.HLS.ENABLED === true) {
|
||||
await new VODHLSTranscodingJobHandler().create({
|
||||
video,
|
||||
deleteWebVideoFiles: CONFIG.TRANSCODING.WEB_VIDEOS.ENABLED === false,
|
||||
resolution: maxResolution,
|
||||
fps,
|
||||
isNewVideo,
|
||||
dependsOnRunnerJob: mainRunnerJob,
|
||||
priority: await getTranscodingJobPriority({ user, type: 'vod', fallback: 0 })
|
||||
})
|
||||
}
|
||||
|
||||
await this.buildLowerResolutionJobPayloads({
|
||||
video,
|
||||
inputVideoResolution: maxResolution,
|
||||
inputVideoFPS: inputFPS,
|
||||
hasAudio,
|
||||
isNewVideo,
|
||||
mainRunnerJob,
|
||||
user
|
||||
})
|
||||
})
|
||||
} finally {
|
||||
mutexReleaser()
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
async createTranscodingJobs (options: {
|
||||
transcodingType: 'hls' | 'webtorrent' | 'web-video' // TODO: remove webtorrent in v7
|
||||
video: MVideoFullLight
|
||||
resolutions: number[]
|
||||
isNewVideo: boolean
|
||||
user: MUserId | null
|
||||
}) {
|
||||
const { video, transcodingType, resolutions, isNewVideo, user } = options
|
||||
|
||||
const maxResolution = Math.max(...resolutions)
|
||||
const { fps: inputFPS } = await video.probeMaxQualityFile()
|
||||
const maxFPS = computeOutputFPS({ inputFPS, resolution: maxResolution })
|
||||
const priority = await getTranscodingJobPriority({ user, type: 'vod', fallback: 0 })
|
||||
|
||||
const childrenResolutions = resolutions.filter(r => r !== maxResolution)
|
||||
|
||||
logger.info('Manually creating transcoding jobs for %s.', transcodingType, { childrenResolutions, maxResolution })
|
||||
|
||||
// Process the last resolution before the other ones to prevent concurrency issue
|
||||
// Because low resolutions use the biggest one as ffmpeg input
|
||||
const mainJob = transcodingType === 'hls'
|
||||
// eslint-disable-next-line max-len
|
||||
? await new VODHLSTranscodingJobHandler().create({ video, resolution: maxResolution, fps: maxFPS, isNewVideo, deleteWebVideoFiles: false, priority })
|
||||
: await new VODWebVideoTranscodingJobHandler().create({ video, resolution: maxResolution, fps: maxFPS, isNewVideo, priority })
|
||||
|
||||
for (const resolution of childrenResolutions) {
|
||||
const dependsOnRunnerJob = mainJob
|
||||
const fps = computeOutputFPS({ inputFPS, resolution })
|
||||
|
||||
if (transcodingType === 'hls') {
|
||||
await new VODHLSTranscodingJobHandler().create({
|
||||
video,
|
||||
resolution,
|
||||
fps,
|
||||
isNewVideo,
|
||||
deleteWebVideoFiles: false,
|
||||
dependsOnRunnerJob,
|
||||
priority: await getTranscodingJobPriority({ user, type: 'vod', fallback: 0 })
|
||||
})
|
||||
continue
|
||||
}
|
||||
|
||||
if (transcodingType === 'webtorrent' || transcodingType === 'web-video') {
|
||||
await new VODWebVideoTranscodingJobHandler().create({
|
||||
video,
|
||||
resolution,
|
||||
fps,
|
||||
isNewVideo,
|
||||
dependsOnRunnerJob,
|
||||
priority: await getTranscodingJobPriority({ user, type: 'vod', fallback: 0 })
|
||||
})
|
||||
continue
|
||||
}
|
||||
|
||||
throw new Error('Unknown transcoding type')
|
||||
}
|
||||
}
|
||||
|
||||
private async buildLowerResolutionJobPayloads (options: {
|
||||
mainRunnerJob: MRunnerJob
|
||||
video: MVideoWithFileThumbnail
|
||||
inputVideoResolution: number
|
||||
inputVideoFPS: number
|
||||
hasAudio: boolean
|
||||
isNewVideo: boolean
|
||||
user: MUserId
|
||||
}) {
|
||||
const { video, inputVideoResolution, inputVideoFPS, isNewVideo, hasAudio, mainRunnerJob, user } = options
|
||||
|
||||
// Create transcoding jobs if there are enabled resolutions
|
||||
const resolutionsEnabled = await Hooks.wrapObject(
|
||||
computeResolutionsToTranscode({ input: inputVideoResolution, type: 'vod', includeInput: false, strictLower: true, hasAudio }),
|
||||
'filter:transcoding.auto.resolutions-to-transcode.result',
|
||||
options
|
||||
)
|
||||
|
||||
logger.debug('Lower resolutions build for %s.', video.uuid, { resolutionsEnabled, ...lTags(video.uuid) })
|
||||
|
||||
for (const resolution of resolutionsEnabled) {
|
||||
const fps = computeOutputFPS({ inputFPS: inputVideoFPS, resolution })
|
||||
|
||||
if (CONFIG.TRANSCODING.WEB_VIDEOS.ENABLED) {
|
||||
await new VODWebVideoTranscodingJobHandler().create({
|
||||
video,
|
||||
resolution,
|
||||
fps,
|
||||
isNewVideo,
|
||||
dependsOnRunnerJob: mainRunnerJob,
|
||||
priority: await getTranscodingJobPriority({ user, type: 'vod', fallback: 0 })
|
||||
})
|
||||
}
|
||||
|
||||
if (CONFIG.TRANSCODING.HLS.ENABLED) {
|
||||
await new VODHLSTranscodingJobHandler().create({
|
||||
video,
|
||||
resolution,
|
||||
fps,
|
||||
isNewVideo,
|
||||
deleteWebVideoFiles: false,
|
||||
dependsOnRunnerJob: mainRunnerJob,
|
||||
priority: await getTranscodingJobPriority({ user, type: 'vod', fallback: 0 })
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue