1
0
Fork 0
mirror of https://github.com/Chocobozzz/PeerTube.git synced 2025-10-03 09:49:20 +02:00

Add custom upload ability for runners

This commit is contained in:
Chocobozzz 2024-12-12 16:39:21 +01:00
parent 33a68f74dd
commit 5b4c7fc20d
No known key found for this signature in database
GPG key ID: 583A612D890159BE
25 changed files with 421 additions and 87 deletions

View file

@ -10,14 +10,18 @@ import {
RequestRunnerJobResult,
ResultList,
RunnerJobAdmin,
RunnerJobCustomUpload,
RunnerJobLiveRTMPHLSTranscodingPayload,
RunnerJobPayload,
RunnerJobState,
RunnerJobStateType,
RunnerJobSuccessBody,
RunnerJobSuccessPayload,
RunnerJobTranscriptionPayload,
RunnerJobType,
RunnerJobUpdateBody,
RunnerJobVODAudioMergeTranscodingPayload,
RunnerJobVODHLSTranscodingPayload,
RunnerJobVODPayload,
TranscriptionSuccess,
VODHLSTranscodingSuccess,
@ -133,39 +137,6 @@ export class RunnerJobsCommand extends AbstractCommand {
})
}
update (options: OverrideCommandOptions & RunnerJobUpdateBody & { jobUUID: string }) {
const path = '/api/v1/runners/jobs/' + options.jobUUID + '/update'
const { payload } = options
const attaches: { [id: string]: any } = {}
let payloadWithoutFiles = payload
if (isLiveRTMPHLSTranscodingUpdatePayload(payload)) {
if (payload.masterPlaylistFile) {
attaches[`payload[masterPlaylistFile]`] = payload.masterPlaylistFile
}
attaches[`payload[resolutionPlaylistFile]`] = payload.resolutionPlaylistFile
attaches[`payload[videoChunkFile]`] = payload.videoChunkFile
payloadWithoutFiles = omit(payloadWithoutFiles, [ 'masterPlaylistFile', 'resolutionPlaylistFile', 'videoChunkFile' ])
}
return this.postUploadRequest({
...options,
path,
fields: {
...pick(options, [ 'progress', 'jobToken', 'runnerToken' ]),
payload: payloadWithoutFiles
},
attaches,
implicitToken: false,
defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204
})
}
error (options: OverrideCommandOptions & ErrorRunnerJobBody & { jobUUID: string }) {
const path = '/api/v1/runners/jobs/' + options.jobUUID + '/error'
@ -179,32 +150,123 @@ export class RunnerJobsCommand extends AbstractCommand {
})
}
success (options: OverrideCommandOptions & RunnerJobSuccessBody & { jobUUID: string }) {
// ---------------------------------------------------------------------------
update (options: OverrideCommandOptions & RunnerJobUpdateBody & { jobUUID: string, reqPayload?: RunnerJobPayload }) {
const path = '/api/v1/runners/jobs/' + options.jobUUID + '/update'
const { payload } = options
const attaches: { [id: string]: any } = {}
const customUploads: (RunnerJobCustomUpload & { file: Blob | string })[] = []
let payloadWithoutFiles = payload
if (isLiveRTMPHLSTranscodingUpdatePayload(payload)) {
const reqPayload = options.reqPayload as RunnerJobLiveRTMPHLSTranscodingPayload
if (payload.masterPlaylistFile) {
this.updateUploadPayloads({
attachesStore: attaches,
customUploadsStore: customUploads,
file: payload.masterPlaylistFile,
attachName: 'masterPlaylistFile',
customUpload: reqPayload?.output?.masterPlaylistFileCustomUpload
})
attaches[`payload[masterPlaylistFile]`] = payload.masterPlaylistFile
}
this.updateUploadPayloads({
attachesStore: attaches,
customUploadsStore: customUploads,
file: payload.resolutionPlaylistFile,
attachName: 'resolutionPlaylistFile',
customUpload: reqPayload?.output?.resolutionPlaylistFileCustomUpload
})
this.updateUploadPayloads({
attachesStore: attaches,
customUploadsStore: customUploads,
file: payload.videoChunkFile,
attachName: 'videoChunkFile',
customUpload: reqPayload?.output?.videoChunkFileCustomUpload
})
payloadWithoutFiles = omit(payloadWithoutFiles, [ 'masterPlaylistFile', 'resolutionPlaylistFile', 'videoChunkFile' ])
}
return this.uploadRunnerJobRequest({
...options,
path,
fields: {
...pick(options, [ 'progress', 'jobToken', 'runnerToken' ]),
payload: payloadWithoutFiles
},
attaches,
customUploads
})
}
success (options: OverrideCommandOptions & RunnerJobSuccessBody & { jobUUID: string, reqPayload?: RunnerJobPayload }) {
const { payload } = options
const path = '/api/v1/runners/jobs/' + options.jobUUID + '/success'
const attaches: { [id: string]: any } = {}
const customUploads: (RunnerJobCustomUpload & { file: Blob | string })[] = []
let payloadWithoutFiles = payload
if ((isWebVideoOrAudioMergeTranscodingPayloadSuccess(payload) || isHLSTranscodingPayloadSuccess(payload)) && payload.videoFile) {
attaches[`payload[videoFile]`] = payload.videoFile
const reqPayload = options.reqPayload as RunnerJobVODAudioMergeTranscodingPayload | RunnerJobVODHLSTranscodingPayload
this.updateUploadPayloads({
attachesStore: attaches,
customUploadsStore: customUploads,
file: payload.videoFile,
attachName: 'videoFile',
customUpload: reqPayload?.output?.videoFileCustomUpload
})
payloadWithoutFiles = omit(payloadWithoutFiles as VODWebVideoTranscodingSuccess, [ 'videoFile' ])
}
if (isHLSTranscodingPayloadSuccess(payload) && payload.resolutionPlaylistFile) {
attaches[`payload[resolutionPlaylistFile]`] = payload.resolutionPlaylistFile
const reqPayload = options.reqPayload as RunnerJobVODHLSTranscodingPayload
this.updateUploadPayloads({
attachesStore: attaches,
customUploadsStore: customUploads,
file: payload.resolutionPlaylistFile,
attachName: 'resolutionPlaylistFile',
customUpload: reqPayload?.output?.resolutionPlaylistFileCustomUpload
})
payloadWithoutFiles = omit(payloadWithoutFiles as VODHLSTranscodingSuccess, [ 'resolutionPlaylistFile' ])
}
if (isTranscriptionPayloadSuccess(payload) && payload.vttFile) {
attaches[`payload[vttFile]`] = payload.vttFile
const reqPayload = options.reqPayload as RunnerJobTranscriptionPayload
this.updateUploadPayloads({
attachesStore: attaches,
customUploadsStore: customUploads,
file: payload.vttFile,
attachName: 'vttFile',
customUpload: reqPayload?.output?.vttFileCustomUpload
})
payloadWithoutFiles = omit(payloadWithoutFiles as TranscriptionSuccess, [ 'vttFile' ])
}
return this.postUploadRequest({
return this.uploadRunnerJobRequest({
...options,
path,
@ -214,11 +276,63 @@ export class RunnerJobsCommand extends AbstractCommand {
payload: payloadWithoutFiles
},
customUploads
})
}
private updateUploadPayloads (options: {
file: Blob | string
customUpload?: RunnerJobCustomUpload
attachName: string
attachesStore: Record<string, string | Blob>
customUploadsStore: (RunnerJobCustomUpload & { file: Blob | string })[]
}) {
if (options.customUpload) {
options.customUploadsStore.push({ ...options.customUpload, file: options.file })
} else {
options.attachesStore[`payload[${options.attachName}]`] = options.file
}
}
private async uploadRunnerJobRequest (options: OverrideCommandOptions & {
path: string
fields: { [ fieldName: string ]: any }
attaches: { [ fieldName: string ]: any }
customUploads?: (RunnerJobCustomUpload & { file: string | Blob })[]
}) {
for (const customUpload of (options.customUploads || [])) {
await this.customUpload(customUpload)
}
await this.postUploadRequest({
...omit(options, [ 'customUploads' ]),
implicitToken: false,
defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204
})
}
private customUpload (options: RunnerJobCustomUpload & { file: Blob | string }) {
const parsedUrl = new URL(options.url)
const reqOptions = {
url: parsedUrl.origin,
path: parsedUrl.pathname,
attaches: { file: options.file },
implicitToken: false,
defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204
}
if (options.method === 'POST') return this.postUploadRequest(reqOptions)
return this.putUploadRequest(reqOptions)
}
// ---------------------------------------------------------------------------
getJobFile (options: OverrideCommandOptions & { url: string, jobToken: string, runnerToken: string }) {
const { host, protocol, pathname } = new URL(options.url)
@ -256,7 +370,7 @@ export class RunnerJobsCommand extends AbstractCommand {
const jobToken = job.jobToken
const payload: RunnerJobSuccessPayload = { videoFile: 'video_short.mp4' }
await this.success({ runnerToken, jobUUID, jobToken, payload })
await this.success({ runnerToken, jobUUID, jobToken, payload, reqPayload: undefined })
await waitJobs([ this.server ])