]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - shared/server-commands/videos/live.ts
Fix broken replay with long live video name
[github/Chocobozzz/PeerTube.git] / shared / server-commands / videos / live.ts
CommitLineData
41fb13c3 1import ffmpeg, { FfmpegCommand } from 'fluent-ffmpeg'
ae22c59f 2import { truncate } from 'lodash'
c55e3d72 3import { buildAbsoluteFixturePath, wait } from '@shared/core-utils'
3545e72c 4import { VideoDetails, VideoInclude, VideoPrivacy } from '@shared/models'
8bd6aa04 5import { PeerTubeServer } from '../server/server'
97969c4e 6
c826f34a
C
7function sendRTMPStream (options: {
8 rtmpBaseUrl: string
9 streamKey: string
10 fixtureName?: string // default video_short.mp4
11 copyCodecs?: boolean // default false
12}) {
13 const { rtmpBaseUrl, streamKey, fixtureName = 'video_short.mp4', copyCodecs = false } = options
14
ca5c612b 15 const fixture = buildAbsoluteFixturePath(fixtureName)
77e9f859
C
16
17 const command = ffmpeg(fixture)
18 command.inputOption('-stream_loop -1')
19 command.inputOption('-re')
c826f34a
C
20
21 if (copyCodecs) {
a1c63fe1
C
22 command.outputOption('-c copy')
23 } else {
c826f34a 24 command.outputOption('-c:v libx264')
a687879e
C
25 command.outputOption('-g 120')
26 command.outputOption('-x264-params "no-scenecut=1"')
c826f34a 27 command.outputOption('-r 60')
c826f34a
C
28 }
29
77e9f859
C
30 command.outputOption('-f flv')
31
32 const rtmpUrl = rtmpBaseUrl + '/' + streamKey
33 command.output(rtmpUrl)
34
35 command.on('error', err => {
36 if (err?.message?.includes('Exiting normally')) return
37
68e70a74 38 if (process.env.DEBUG) console.error(err)
77e9f859
C
39 })
40
41 if (process.env.DEBUG) {
42 command.on('stderr', data => console.log(data))
2732eeff 43 command.on('stdout', data => console.log(data))
77e9f859
C
44 }
45
46 command.run()
47
48 return command
49}
50
41fb13c3 51function waitFfmpegUntilError (command: FfmpegCommand, successAfterMS = 10000) {
ba5a8d89 52 return new Promise<void>((res, rej) => {
97969c4e
C
53 command.on('error', err => {
54 return rej(err)
55 })
56
57 setTimeout(() => {
58 res()
59 }, successAfterMS)
60 })
61}
62
41fb13c3 63async function testFfmpegStreamError (command: FfmpegCommand, shouldHaveError: boolean) {
97969c4e
C
64 let error: Error
65
66 try {
5a05c145 67 await waitFfmpegUntilError(command, 45000)
97969c4e
C
68 } catch (err) {
69 error = err
70 }
71
72 await stopFfmpeg(command)
73
74 if (shouldHaveError && !error) throw new Error('Ffmpeg did not have an error')
75 if (!shouldHaveError && error) throw error
76}
77
41fb13c3 78async function stopFfmpeg (command: FfmpegCommand) {
77e9f859
C
79 command.kill('SIGINT')
80
81 await wait(500)
82}
83
254d3579 84async function waitUntilLivePublishedOnAllServers (servers: PeerTubeServer[], videoId: string) {
8ebf2a5d 85 for (const server of servers) {
89d241a7 86 await server.live.waitUntilPublished({ videoId })
8ebf2a5d
C
87 }
88}
89
4ec52d04 90async function waitUntilLiveWaitingOnAllServers (servers: PeerTubeServer[], videoId: string) {
0305db28 91 for (const server of servers) {
4ec52d04 92 await server.live.waitUntilWaiting({ videoId })
0305db28
JB
93 }
94}
95
4ec52d04
C
96async function waitUntilLiveReplacedByReplayOnAllServers (servers: PeerTubeServer[], videoId: string) {
97 for (const server of servers) {
98 await server.live.waitUntilReplacedByReplay({ videoId })
99 }
100}
101
102async function findExternalSavedVideo (server: PeerTubeServer, liveDetails: VideoDetails) {
3545e72c
C
103 const include = VideoInclude.BLACKLISTED
104 const privacyOneOf = [ VideoPrivacy.INTERNAL, VideoPrivacy.PRIVATE, VideoPrivacy.PUBLIC, VideoPrivacy.UNLISTED ]
105
106 const { data } = await server.videos.list({ token: server.accessToken, sort: '-publishedAt', include, privacyOneOf })
4ec52d04 107
ae22c59f
C
108 const videoNameSuffix = ` - ${new Date(liveDetails.publishedAt).toLocaleString()}`
109 const truncatedVideoName = truncate(liveDetails.name, {
110 length: 120 - videoNameSuffix.length
111 })
112 const toFind = truncatedVideoName + videoNameSuffix
113
114 return data.find(v => v.name === toFind)
4ec52d04
C
115}
116
77e9f859 117export {
4f219914 118 sendRTMPStream,
97969c4e 119 waitFfmpegUntilError,
4f219914
C
120 testFfmpegStreamError,
121 stopFfmpeg,
4ec52d04 122
8ebf2a5d 123 waitUntilLivePublishedOnAllServers,
4ec52d04
C
124 waitUntilLiveReplacedByReplayOnAllServers,
125 waitUntilLiveWaitingOnAllServers,
126
127 findExternalSavedVideo
77e9f859 128}