1 /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
4 import * as chai from 'chai'
5 import { FfmpegCommand } from 'fluent-ffmpeg'
6 import { LiveVideoCreate, VideoDetails, VideoPrivacy, VideoState } from '@shared/models'
7 import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
13 flushAndRunMultipleServers,
18 setAccessTokensToServers,
19 setDefaultVideoChannel,
21 testFfmpegStreamError,
25 } from '../../../../shared/extra-utils'
27 const expect = chai.expect
29 describe('Save replay setting', function () {
30 let servers: ServerInfo[] = []
31 let liveVideoUUID: string
32 let ffmpegCommand: FfmpegCommand
34 async function createLiveWrapper (saveReplay: boolean) {
37 await removeVideo(servers[0].url, servers[0].accessToken, liveVideoUUID)
38 await waitJobs(servers)
42 const attributes: LiveVideoCreate = {
43 channelId: servers[0].videoChannel.id,
44 privacy: VideoPrivacy.PUBLIC,
45 name: 'my super live',
49 const { uuid } = await servers[0].liveCommand.create({ fields: attributes })
53 async function checkVideosExist (videoId: string, existsInList: boolean, getStatus?: number) {
54 for (const server of servers) {
55 const length = existsInList ? 1 : 0
57 const resVideos = await getVideosList(server.url)
58 expect(resVideos.body.data).to.have.lengthOf(length)
59 expect(resVideos.body.total).to.equal(length)
62 await getVideo(server.url, videoId, getStatus)
67 async function checkVideoState (videoId: string, state: VideoState) {
68 for (const server of servers) {
69 const res = await getVideo(server.url, videoId)
70 expect((res.body as VideoDetails).state.id).to.equal(state)
74 async function waitUntilLivePublishedOnAllServers (videoId: string) {
75 for (const server of servers) {
76 await server.liveCommand.waitUntilPublished({ videoId })
80 async function waitUntilLiveSavedOnAllServers (videoId: string) {
81 for (const server of servers) {
82 await server.liveCommand.waitUntilSaved({ videoId })
86 before(async function () {
89 servers = await flushAndRunMultipleServers(2)
91 // Get the access tokens
92 await setAccessTokensToServers(servers)
93 await setDefaultVideoChannel(servers)
95 // Server 1 and server 2 follow each other
96 await doubleFollow(servers[0], servers[1])
98 await servers[0].configCommand.updateCustomSubConfig({
106 resolutions: ConfigCommand.getCustomConfigResolutions(true)
113 describe('With save replay disabled', function () {
115 before(async function () {
119 it('Should correctly create and federate the "waiting for stream" live', async function () {
122 liveVideoUUID = await createLiveWrapper(false)
124 await waitJobs(servers)
126 await checkVideosExist(liveVideoUUID, false, HttpStatusCode.OK_200)
127 await checkVideoState(liveVideoUUID, VideoState.WAITING_FOR_LIVE)
130 it('Should correctly have updated the live and federated it when streaming in the live', async function () {
133 ffmpegCommand = await servers[0].liveCommand.sendRTMPStreamInVideo({ videoId: liveVideoUUID })
135 await waitUntilLivePublishedOnAllServers(liveVideoUUID)
137 await waitJobs(servers)
139 await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200)
140 await checkVideoState(liveVideoUUID, VideoState.PUBLISHED)
143 it('Should correctly delete the video files after the stream ended', async function () {
146 await stopFfmpeg(ffmpegCommand)
148 for (const server of servers) {
149 await server.liveCommand.waitUntilEnded({ videoId: liveVideoUUID })
151 await waitJobs(servers)
153 // Live still exist, but cannot be played anymore
154 await checkVideosExist(liveVideoUUID, false, HttpStatusCode.OK_200)
155 await checkVideoState(liveVideoUUID, VideoState.LIVE_ENDED)
157 // No resolutions saved since we did not save replay
158 await checkLiveCleanup(servers[0], liveVideoUUID, [])
161 it('Should correctly terminate the stream on blacklist and delete the live', async function () {
164 liveVideoUUID = await createLiveWrapper(false)
166 ffmpegCommand = await servers[0].liveCommand.sendRTMPStreamInVideo({ videoId: liveVideoUUID })
168 await waitUntilLivePublishedOnAllServers(liveVideoUUID)
170 await waitJobs(servers)
171 await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200)
174 servers[0].blacklistCommand.add({ videoId: liveVideoUUID, reason: 'bad live', unfederate: true }),
175 testFfmpegStreamError(ffmpegCommand, true)
178 await waitJobs(servers)
180 await checkVideosExist(liveVideoUUID, false)
182 await getVideo(servers[0].url, liveVideoUUID, HttpStatusCode.UNAUTHORIZED_401)
183 await getVideo(servers[1].url, liveVideoUUID, HttpStatusCode.NOT_FOUND_404)
186 await waitJobs(servers)
187 await checkLiveCleanup(servers[0], liveVideoUUID, [])
190 it('Should correctly terminate the stream on delete and delete the video', async function () {
193 liveVideoUUID = await createLiveWrapper(false)
195 ffmpegCommand = await servers[0].liveCommand.sendRTMPStreamInVideo({ videoId: liveVideoUUID })
197 await waitUntilLivePublishedOnAllServers(liveVideoUUID)
199 await waitJobs(servers)
200 await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200)
203 testFfmpegStreamError(ffmpegCommand, true),
204 removeVideo(servers[0].url, servers[0].accessToken, liveVideoUUID)
208 await waitJobs(servers)
210 await checkVideosExist(liveVideoUUID, false, HttpStatusCode.NOT_FOUND_404)
211 await checkLiveCleanup(servers[0], liveVideoUUID, [])
215 describe('With save replay enabled', function () {
217 it('Should correctly create and federate the "waiting for stream" live', async function () {
220 liveVideoUUID = await createLiveWrapper(true)
222 await waitJobs(servers)
224 await checkVideosExist(liveVideoUUID, false, HttpStatusCode.OK_200)
225 await checkVideoState(liveVideoUUID, VideoState.WAITING_FOR_LIVE)
228 it('Should correctly have updated the live and federated it when streaming in the live', async function () {
231 ffmpegCommand = await servers[0].liveCommand.sendRTMPStreamInVideo({ videoId: liveVideoUUID })
232 await waitUntilLivePublishedOnAllServers(liveVideoUUID)
234 await waitJobs(servers)
236 await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200)
237 await checkVideoState(liveVideoUUID, VideoState.PUBLISHED)
240 it('Should correctly have saved the live and federated it after the streaming', async function () {
243 await stopFfmpeg(ffmpegCommand)
245 await waitUntilLiveSavedOnAllServers(liveVideoUUID)
246 await waitJobs(servers)
248 // Live has been transcoded
249 await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200)
250 await checkVideoState(liveVideoUUID, VideoState.PUBLISHED)
253 it('Should update the saved live and correctly federate the updated attributes', async function () {
256 await updateVideo(servers[0].url, servers[0].accessToken, liveVideoUUID, { name: 'video updated' })
257 await waitJobs(servers)
259 for (const server of servers) {
260 const res = await getVideo(server.url, liveVideoUUID)
261 expect(res.body.name).to.equal('video updated')
262 expect(res.body.isLive).to.be.false
266 it('Should have cleaned up the live files', async function () {
267 await checkLiveCleanup(servers[0], liveVideoUUID, [ 720 ])
270 it('Should correctly terminate the stream on blacklist and blacklist the saved replay video', async function () {
273 liveVideoUUID = await createLiveWrapper(true)
275 ffmpegCommand = await servers[0].liveCommand.sendRTMPStreamInVideo({ videoId: liveVideoUUID })
276 await waitUntilLivePublishedOnAllServers(liveVideoUUID)
278 await waitJobs(servers)
279 await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200)
282 servers[0].blacklistCommand.add({ videoId: liveVideoUUID, reason: 'bad live', unfederate: true }),
283 testFfmpegStreamError(ffmpegCommand, true)
286 await waitJobs(servers)
288 await checkVideosExist(liveVideoUUID, false)
290 await getVideo(servers[0].url, liveVideoUUID, HttpStatusCode.UNAUTHORIZED_401)
291 await getVideo(servers[1].url, liveVideoUUID, HttpStatusCode.NOT_FOUND_404)
294 await waitJobs(servers)
295 await checkLiveCleanup(servers[0], liveVideoUUID, [ 720 ])
298 it('Should correctly terminate the stream on delete and delete the video', async function () {
301 liveVideoUUID = await createLiveWrapper(true)
303 ffmpegCommand = await servers[0].liveCommand.sendRTMPStreamInVideo({ videoId: liveVideoUUID })
304 await waitUntilLivePublishedOnAllServers(liveVideoUUID)
306 await waitJobs(servers)
307 await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200)
310 removeVideo(servers[0].url, servers[0].accessToken, liveVideoUUID),
311 testFfmpegStreamError(ffmpegCommand, true)
315 await waitJobs(servers)
317 await checkVideosExist(liveVideoUUID, false, HttpStatusCode.NOT_FOUND_404)
318 await checkLiveCleanup(servers[0], liveVideoUUID, [])
322 after(async function () {
323 await cleanupTests(servers)