1
0
Fork 0
mirror of https://github.com/Chocobozzz/PeerTube.git synced 2025-10-04 18:29:27 +02:00

server/server -> server/core

This commit is contained in:
Chocobozzz 2023-10-04 15:13:25 +02:00
parent 114327d4ce
commit 5a3d0650c9
No known key found for this signature in database
GPG key ID: 583A612D890159BE
838 changed files with 111 additions and 111 deletions

View file

@ -0,0 +1,111 @@
import { LiveVideoErrorType } from '@peertube/peertube-models'
import { LoggerTagsFn } from '@server/helpers/logger.js'
import { MStreamingPlaylistVideo, MVideoLiveVideo } from '@server/types/models/index.js'
import EventEmitter from 'events'
interface TranscodingWrapperEvents {
'end': () => void
'error': (options: { err: Error }) => void
}
declare interface AbstractTranscodingWrapper {
on<U extends keyof TranscodingWrapperEvents>(
event: U, listener: TranscodingWrapperEvents[U]
): this
emit<U extends keyof TranscodingWrapperEvents>(
event: U, ...args: Parameters<TranscodingWrapperEvents[U]>
): boolean
}
interface AbstractTranscodingWrapperOptions {
streamingPlaylist: MStreamingPlaylistVideo
videoLive: MVideoLiveVideo
lTags: LoggerTagsFn
sessionId: string
inputLocalUrl: string
inputPublicUrl: string
fps: number
toTranscode: {
resolution: number
fps: number
}[]
bitrate: number
ratio: number
hasAudio: boolean
segmentListSize: number
segmentDuration: number
outDirectory: string
}
abstract class AbstractTranscodingWrapper extends EventEmitter {
protected readonly videoLive: MVideoLiveVideo
protected readonly toTranscode: {
resolution: number
fps: number
}[]
protected readonly sessionId: string
protected readonly inputLocalUrl: string
protected readonly inputPublicUrl: string
protected readonly fps: number
protected readonly bitrate: number
protected readonly ratio: number
protected readonly hasAudio: boolean
protected readonly segmentListSize: number
protected readonly segmentDuration: number
protected readonly videoUUID: string
protected readonly outDirectory: string
protected readonly lTags: LoggerTagsFn
protected readonly streamingPlaylist: MStreamingPlaylistVideo
constructor (options: AbstractTranscodingWrapperOptions) {
super()
this.lTags = options.lTags
this.videoLive = options.videoLive
this.videoUUID = options.videoLive.Video.uuid
this.streamingPlaylist = options.streamingPlaylist
this.sessionId = options.sessionId
this.inputLocalUrl = options.inputLocalUrl
this.inputPublicUrl = options.inputPublicUrl
this.fps = options.fps
this.toTranscode = options.toTranscode
this.bitrate = options.bitrate
this.ratio = options.ratio
this.hasAudio = options.hasAudio
this.segmentListSize = options.segmentListSize
this.segmentDuration = options.segmentDuration
this.outDirectory = options.outDirectory
}
abstract run (): Promise<void>
abstract abort (error?: LiveVideoErrorType): void
}
export {
type AbstractTranscodingWrapperOptions,
AbstractTranscodingWrapper
}

View file

@ -0,0 +1,107 @@
import { FfmpegCommand } from 'fluent-ffmpeg'
import { getFFmpegCommandWrapperOptions } from '@server/helpers/ffmpeg/index.js'
import { logger } from '@server/helpers/logger.js'
import { CONFIG } from '@server/initializers/config.js'
import { VIDEO_LIVE } from '@server/initializers/constants.js'
import { VideoTranscodingProfilesManager } from '@server/lib/transcoding/default-transcoding-profiles.js'
import { FFmpegLive } from '@peertube/peertube-ffmpeg'
import { getLiveSegmentTime } from '../../live-utils.js'
import { AbstractTranscodingWrapper } from './abstract-transcoding-wrapper.js'
export class FFmpegTranscodingWrapper extends AbstractTranscodingWrapper {
private ffmpegCommand: FfmpegCommand
private aborted = false
private errored = false
private ended = false
async run () {
this.ffmpegCommand = CONFIG.LIVE.TRANSCODING.ENABLED
? await this.buildFFmpegLive().getLiveTranscodingCommand({
inputUrl: this.inputLocalUrl,
outPath: this.outDirectory,
masterPlaylistName: this.streamingPlaylist.playlistFilename,
segmentListSize: this.segmentListSize,
segmentDuration: this.segmentDuration,
toTranscode: this.toTranscode,
bitrate: this.bitrate,
ratio: this.ratio,
hasAudio: this.hasAudio
})
: this.buildFFmpegLive().getLiveMuxingCommand({
inputUrl: this.inputLocalUrl,
outPath: this.outDirectory,
masterPlaylistName: this.streamingPlaylist.playlistFilename,
segmentListSize: VIDEO_LIVE.SEGMENTS_LIST_SIZE,
segmentDuration: getLiveSegmentTime(this.videoLive.latencyMode)
})
logger.info('Running local live muxing/transcoding for %s.', this.videoUUID, this.lTags())
let ffmpegShellCommand: string
this.ffmpegCommand.on('start', cmdline => {
ffmpegShellCommand = cmdline
logger.debug('Running ffmpeg command for live', { ffmpegShellCommand, ...this.lTags() })
})
this.ffmpegCommand.on('error', (err, stdout, stderr) => {
this.onFFmpegError({ err, stdout, stderr, ffmpegShellCommand })
})
this.ffmpegCommand.on('end', () => {
this.onFFmpegEnded()
})
this.ffmpegCommand.run()
}
abort () {
if (this.ended || this.errored || this.aborted) return
logger.debug('Killing ffmpeg after live abort of ' + this.videoUUID, this.lTags())
this.ffmpegCommand.kill('SIGINT')
this.aborted = true
this.emit('end')
}
private onFFmpegError (options: {
err: any
stdout: string
stderr: string
ffmpegShellCommand: string
}) {
const { err, stdout, stderr, ffmpegShellCommand } = options
// Don't care that we killed the ffmpeg process
if (err?.message?.includes('Exiting normally')) return
if (this.ended || this.errored || this.aborted) return
logger.error('FFmpeg transcoding error.', { err, stdout, stderr, ffmpegShellCommand, ...this.lTags() })
this.errored = true
this.emit('error', { err })
}
private onFFmpegEnded () {
if (this.ended || this.errored || this.aborted) return
logger.debug('Live ffmpeg transcoding ended for ' + this.videoUUID, this.lTags())
this.ended = true
this.emit('end')
}
private buildFFmpegLive () {
return new FFmpegLive(getFFmpegCommandWrapperOptions('live', VideoTranscodingProfilesManager.Instance.getAvailableEncoders()))
}
}

View file

@ -0,0 +1,3 @@
export * from './abstract-transcoding-wrapper.js'
export * from './ffmpeg-transcoding-wrapper.js'
export * from './remote-transcoding-wrapper.js'

View file

@ -0,0 +1,21 @@
import { LiveRTMPHLSTranscodingJobHandler } from '@server/lib/runners/index.js'
import { AbstractTranscodingWrapper } from './abstract-transcoding-wrapper.js'
export class RemoteTranscodingWrapper extends AbstractTranscodingWrapper {
async run () {
await new LiveRTMPHLSTranscodingJobHandler().create({
rtmpUrl: this.inputPublicUrl,
sessionId: this.sessionId,
toTranscode: this.toTranscode,
video: this.videoLive.Video,
outputDirectory: this.outDirectory,
playlist: this.streamingPlaylist,
segmentListSize: this.segmentListSize,
segmentDuration: this.segmentDuration
})
}
abort () {
this.emit('end')
}
}