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'
14 flushAndRunMultipleServers,
18 sendRTMPStreamInVideo,
20 setAccessTokensToServers,
21 setDefaultVideoChannel,
23 testFfmpegStreamError,
24 updateCustomSubConfig,
29 waitUntilLivePublished,
31 } from '../../../../shared/extra-utils'
33 const expect = chai.expect
35 describe('Save replay setting', function () {
36 let servers: ServerInfo[] = []
37 let liveVideoUUID: string
38 let ffmpegCommand: FfmpegCommand
40 async function createLiveWrapper (saveReplay: boolean) {
43 await removeVideo(servers[0].url, servers[0].accessToken, liveVideoUUID)
44 await waitJobs(servers)
48 const attributes: LiveVideoCreate = {
49 channelId: servers[0].videoChannel.id,
50 privacy: VideoPrivacy.PUBLIC,
51 name: 'my super live',
55 const res = await createLive(servers[0].url, servers[0].accessToken, attributes)
56 return res.body.video.uuid
59 async function checkVideosExist (videoId: string, existsInList: boolean, getStatus?: number) {
60 for (const server of servers) {
61 const length = existsInList ? 1 : 0
63 const resVideos = await getVideosList(server.url)
64 expect(resVideos.body.data).to.have.lengthOf(length)
65 expect(resVideos.body.total).to.equal(length)
68 await getVideo(server.url, videoId, getStatus)
73 async function checkVideoState (videoId: string, state: VideoState) {
74 for (const server of servers) {
75 const res = await getVideo(server.url, videoId)
76 expect((res.body as VideoDetails).state.id).to.equal(state)
80 async function waitUntilLivePublishedOnAllServers (videoId: string) {
81 for (const server of servers) {
82 await waitUntilLivePublished(server.url, server.accessToken, videoId)
86 async function waitUntilLiveSavedOnAllServers (videoId: string) {
87 for (const server of servers) {
88 await waitUntilLiveSaved(server.url, server.accessToken, videoId)
92 before(async function () {
95 servers = await flushAndRunMultipleServers(2)
97 // Get the access tokens
98 await setAccessTokensToServers(servers)
99 await setDefaultVideoChannel(servers)
101 // Server 1 and server 2 follow each other
102 await doubleFollow(servers[0], servers[1])
104 await updateCustomSubConfig(servers[0].url, servers[0].accessToken, {
125 describe('With save replay disabled', function () {
127 before(async function () {
131 it('Should correctly create and federate the "waiting for stream" live', async function () {
134 liveVideoUUID = await createLiveWrapper(false)
136 await waitJobs(servers)
138 await checkVideosExist(liveVideoUUID, false, HttpStatusCode.OK_200)
139 await checkVideoState(liveVideoUUID, VideoState.WAITING_FOR_LIVE)
142 it('Should correctly have updated the live and federated it when streaming in the live', async function () {
145 ffmpegCommand = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoUUID)
147 await waitUntilLivePublishedOnAllServers(liveVideoUUID)
149 await waitJobs(servers)
151 await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200)
152 await checkVideoState(liveVideoUUID, VideoState.PUBLISHED)
155 it('Should correctly delete the video files after the stream ended', async function () {
158 await stopFfmpeg(ffmpegCommand)
160 for (const server of servers) {
161 await waitUntilLiveEnded(server.url, server.accessToken, liveVideoUUID)
163 await waitJobs(servers)
165 // Live still exist, but cannot be played anymore
166 await checkVideosExist(liveVideoUUID, false, HttpStatusCode.OK_200)
167 await checkVideoState(liveVideoUUID, VideoState.LIVE_ENDED)
169 // No resolutions saved since we did not save replay
170 await checkLiveCleanup(servers[0], liveVideoUUID, [])
173 it('Should correctly terminate the stream on blacklist and delete the live', async function () {
176 liveVideoUUID = await createLiveWrapper(false)
178 ffmpegCommand = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoUUID)
180 await waitUntilLivePublishedOnAllServers(liveVideoUUID)
182 await waitJobs(servers)
183 await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200)
186 addVideoToBlacklist(servers[0].url, servers[0].accessToken, liveVideoUUID, 'bad live', true),
187 testFfmpegStreamError(ffmpegCommand, true)
190 await waitJobs(servers)
192 await checkVideosExist(liveVideoUUID, false)
194 await getVideo(servers[0].url, liveVideoUUID, HttpStatusCode.UNAUTHORIZED_401)
195 await getVideo(servers[1].url, liveVideoUUID, HttpStatusCode.NOT_FOUND_404)
198 await waitJobs(servers)
199 await checkLiveCleanup(servers[0], liveVideoUUID, [])
202 it('Should correctly terminate the stream on delete and delete the video', async function () {
205 liveVideoUUID = await createLiveWrapper(false)
207 ffmpegCommand = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoUUID)
209 await waitUntilLivePublishedOnAllServers(liveVideoUUID)
211 await waitJobs(servers)
212 await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200)
215 testFfmpegStreamError(ffmpegCommand, true),
216 removeVideo(servers[0].url, servers[0].accessToken, liveVideoUUID)
220 await waitJobs(servers)
222 await checkVideosExist(liveVideoUUID, false, HttpStatusCode.NOT_FOUND_404)
223 await checkLiveCleanup(servers[0], liveVideoUUID, [])
227 describe('With save replay enabled', function () {
229 it('Should correctly create and federate the "waiting for stream" live', async function () {
232 liveVideoUUID = await createLiveWrapper(true)
234 await waitJobs(servers)
236 await checkVideosExist(liveVideoUUID, false, HttpStatusCode.OK_200)
237 await checkVideoState(liveVideoUUID, VideoState.WAITING_FOR_LIVE)
240 it('Should correctly have updated the live and federated it when streaming in the live', async function () {
243 ffmpegCommand = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoUUID)
244 await waitUntilLivePublishedOnAllServers(liveVideoUUID)
246 await waitJobs(servers)
248 await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200)
249 await checkVideoState(liveVideoUUID, VideoState.PUBLISHED)
252 it('Should correctly have saved the live and federated it after the streaming', async function () {
255 await stopFfmpeg(ffmpegCommand)
257 await waitUntilLiveSavedOnAllServers(liveVideoUUID)
258 await waitJobs(servers)
260 // Live has been transcoded
261 await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200)
262 await checkVideoState(liveVideoUUID, VideoState.PUBLISHED)
265 it('Should update the saved live and correctly federate the updated attributes', async function () {
268 await updateVideo(servers[0].url, servers[0].accessToken, liveVideoUUID, { name: 'video updated' })
269 await waitJobs(servers)
271 for (const server of servers) {
272 const res = await getVideo(server.url, liveVideoUUID)
273 expect(res.body.name).to.equal('video updated')
274 expect(res.body.isLive).to.be.false
278 it('Should have cleaned up the live files', async function () {
279 await checkLiveCleanup(servers[0], liveVideoUUID, [ 720 ])
282 it('Should correctly terminate the stream on blacklist and blacklist the saved replay video', async function () {
285 liveVideoUUID = await createLiveWrapper(true)
287 ffmpegCommand = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoUUID)
288 await waitUntilLivePublishedOnAllServers(liveVideoUUID)
290 await waitJobs(servers)
291 await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200)
294 addVideoToBlacklist(servers[0].url, servers[0].accessToken, liveVideoUUID, 'bad live', true),
295 testFfmpegStreamError(ffmpegCommand, true)
298 await waitJobs(servers)
300 await checkVideosExist(liveVideoUUID, false)
302 await getVideo(servers[0].url, liveVideoUUID, HttpStatusCode.UNAUTHORIZED_401)
303 await getVideo(servers[1].url, liveVideoUUID, HttpStatusCode.NOT_FOUND_404)
306 await waitJobs(servers)
307 await checkLiveCleanup(servers[0], liveVideoUUID, [ 720 ])
310 it('Should correctly terminate the stream on delete and delete the video', async function () {
313 liveVideoUUID = await createLiveWrapper(true)
315 ffmpegCommand = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoUUID)
316 await waitUntilLivePublishedOnAllServers(liveVideoUUID)
318 await waitJobs(servers)
319 await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200)
322 removeVideo(servers[0].url, servers[0].accessToken, liveVideoUUID),
323 testFfmpegStreamError(ffmpegCommand, true)
327 await waitJobs(servers)
329 await checkVideosExist(liveVideoUUID, false, HttpStatusCode.NOT_FOUND_404)
330 await checkLiveCleanup(servers[0], liveVideoUUID, [])
334 after(async function () {
335 await cleanupTests(servers)