]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/lib/live/shared/transcoding-wrapper/ffmpeg-transcoding-wrapper.ts
Fix tests
[github/Chocobozzz/PeerTube.git] / server / lib / live / shared / transcoding-wrapper / ffmpeg-transcoding-wrapper.ts
1 import { FfmpegCommand } from 'fluent-ffmpeg'
2 import { getFFmpegCommandWrapperOptions } from '@server/helpers/ffmpeg'
3 import { logger } from '@server/helpers/logger'
4 import { CONFIG } from '@server/initializers/config'
5 import { VIDEO_LIVE } from '@server/initializers/constants'
6 import { VideoTranscodingProfilesManager } from '@server/lib/transcoding/default-transcoding-profiles'
7 import { FFmpegLive } from '@shared/ffmpeg'
8 import { getLiveSegmentTime } from '../../live-utils'
9 import { AbstractTranscodingWrapper } from './abstract-transcoding-wrapper'
10
11 export class FFmpegTranscodingWrapper extends AbstractTranscodingWrapper {
12 private ffmpegCommand: FfmpegCommand
13 private ended = false
14
15 async run () {
16 this.ffmpegCommand = CONFIG.LIVE.TRANSCODING.ENABLED
17 ? await this.buildFFmpegLive().getLiveTranscodingCommand({
18 inputUrl: this.inputLocalUrl,
19
20 outPath: this.outDirectory,
21 masterPlaylistName: this.streamingPlaylist.playlistFilename,
22
23 segmentListSize: this.segmentListSize,
24 segmentDuration: this.segmentDuration,
25
26 toTranscode: this.toTranscode,
27
28 bitrate: this.bitrate,
29 ratio: this.ratio,
30
31 hasAudio: this.hasAudio
32 })
33 : this.buildFFmpegLive().getLiveMuxingCommand({
34 inputUrl: this.inputLocalUrl,
35 outPath: this.outDirectory,
36
37 masterPlaylistName: this.streamingPlaylist.playlistFilename,
38
39 segmentListSize: VIDEO_LIVE.SEGMENTS_LIST_SIZE,
40 segmentDuration: getLiveSegmentTime(this.videoLive.latencyMode)
41 })
42
43 logger.info('Running local live muxing/transcoding for %s.', this.videoUUID, this.lTags())
44
45 this.ffmpegCommand.run()
46
47 let ffmpegShellCommand: string
48 this.ffmpegCommand.on('start', cmdline => {
49 ffmpegShellCommand = cmdline
50
51 logger.debug('Running ffmpeg command for live', { ffmpegShellCommand, ...this.lTags() })
52 })
53
54 this.ffmpegCommand.on('error', (err, stdout, stderr) => {
55 this.onFFmpegError({ err, stdout, stderr, ffmpegShellCommand })
56 })
57
58 this.ffmpegCommand.on('end', () => {
59 this.onFFmpegEnded()
60 })
61
62 this.ffmpegCommand.run()
63 }
64
65 abort () {
66 // Nothing to do, ffmpeg will automatically exit
67 }
68
69 private onFFmpegError (options: {
70 err: any
71 stdout: string
72 stderr: string
73 ffmpegShellCommand: string
74 }) {
75 const { err, stdout, stderr, ffmpegShellCommand } = options
76
77 // Don't care that we killed the ffmpeg process
78 if (err?.message?.includes('Exiting normally')) return
79
80 logger.error('FFmpeg transcoding error.', { err, stdout, stderr, ffmpegShellCommand, ...this.lTags() })
81
82 this.emit('error', { err })
83 }
84
85 private onFFmpegEnded () {
86 if (this.ended) return
87
88 this.ended = true
89 this.emit('end')
90 }
91
92 private buildFFmpegLive () {
93 return new FFmpegLive(getFFmpegCommandWrapperOptions('live', VideoTranscodingProfilesManager.Instance.getAvailableEncoders()))
94 }
95 }