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,
15 getCustomConfigResolutions,
19 sendRTMPStreamInVideo,
21 setAccessTokensToServers,
22 setDefaultVideoChannel,
24 testFfmpegStreamError,
25 updateCustomSubConfig,
30 waitUntilLivePublished,
32 } from '../../../../shared/extra-utils'
34 const expect = chai.expect
36 describe('Save replay setting', function () {
37 let servers: ServerInfo[] = []
38 let liveVideoUUID: string
39 let ffmpegCommand: FfmpegCommand
41 async function createLiveWrapper (saveReplay: boolean) {
44 await removeVideo(servers[0].url, servers[0].accessToken, liveVideoUUID)
45 await waitJobs(servers)
49 const attributes: LiveVideoCreate = {
50 channelId: servers[0].videoChannel.id,
51 privacy: VideoPrivacy.PUBLIC,
52 name: 'my super live',
56 const res = await createLive(servers[0].url, servers[0].accessToken, attributes)
57 return res.body.video.uuid
60 async function checkVideosExist (videoId: string, existsInList: boolean, getStatus?: number) {
61 for (const server of servers) {
62 const length = existsInList ? 1 : 0
64 const resVideos = await getVideosList(server.url)
65 expect(resVideos.body.data).to.have.lengthOf(length)
66 expect(resVideos.body.total).to.equal(length)
69 await getVideo(server.url, videoId, getStatus)
74 async function checkVideoState (videoId: string, state: VideoState) {
75 for (const server of servers) {
76 const res = await getVideo(server.url, videoId)
77 expect((res.body as VideoDetails).state.id).to.equal(state)
81 async function waitUntilLivePublishedOnAllServers (videoId: string) {
82 for (const server of servers) {
83 await waitUntilLivePublished(server.url, server.accessToken, videoId)
87 async function waitUntilLiveSavedOnAllServers (videoId: string) {
88 for (const server of servers) {
89 await waitUntilLiveSaved(server.url, server.accessToken, videoId)
93 before(async function () {
96 servers = await flushAndRunMultipleServers(2)
98 // Get the access tokens
99 await setAccessTokensToServers(servers)
100 await setDefaultVideoChannel(servers)
102 // Server 1 and server 2 follow each other
103 await doubleFollow(servers[0], servers[1])
105 await updateCustomSubConfig(servers[0].url, servers[0].accessToken, {
112 resolutions: getCustomConfigResolutions(true)
118 describe('With save replay disabled', function () {
120 before(async function () {
124 it('Should correctly create and federate the "waiting for stream" live', async function () {
127 liveVideoUUID = await createLiveWrapper(false)
129 await waitJobs(servers)
131 await checkVideosExist(liveVideoUUID, false, HttpStatusCode.OK_200)
132 await checkVideoState(liveVideoUUID, VideoState.WAITING_FOR_LIVE)
135 it('Should correctly have updated the live and federated it when streaming in the live', async function () {
138 ffmpegCommand = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoUUID)
140 await waitUntilLivePublishedOnAllServers(liveVideoUUID)
142 await waitJobs(servers)
144 await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200)
145 await checkVideoState(liveVideoUUID, VideoState.PUBLISHED)
148 it('Should correctly delete the video files after the stream ended', async function () {
151 await stopFfmpeg(ffmpegCommand)
153 for (const server of servers) {
154 await waitUntilLiveEnded(server.url, server.accessToken, liveVideoUUID)
156 await waitJobs(servers)
158 // Live still exist, but cannot be played anymore
159 await checkVideosExist(liveVideoUUID, false, HttpStatusCode.OK_200)
160 await checkVideoState(liveVideoUUID, VideoState.LIVE_ENDED)
162 // No resolutions saved since we did not save replay
163 await checkLiveCleanup(servers[0], liveVideoUUID, [])
166 it('Should correctly terminate the stream on blacklist and delete the live', async function () {
169 liveVideoUUID = await createLiveWrapper(false)
171 ffmpegCommand = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoUUID)
173 await waitUntilLivePublishedOnAllServers(liveVideoUUID)
175 await waitJobs(servers)
176 await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200)
179 addVideoToBlacklist(servers[0].url, servers[0].accessToken, liveVideoUUID, 'bad live', true),
180 testFfmpegStreamError(ffmpegCommand, true)
183 await waitJobs(servers)
185 await checkVideosExist(liveVideoUUID, false)
187 await getVideo(servers[0].url, liveVideoUUID, HttpStatusCode.UNAUTHORIZED_401)
188 await getVideo(servers[1].url, liveVideoUUID, HttpStatusCode.NOT_FOUND_404)
191 await waitJobs(servers)
192 await checkLiveCleanup(servers[0], liveVideoUUID, [])
195 it('Should correctly terminate the stream on delete and delete the video', async function () {
198 liveVideoUUID = await createLiveWrapper(false)
200 ffmpegCommand = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoUUID)
202 await waitUntilLivePublishedOnAllServers(liveVideoUUID)
204 await waitJobs(servers)
205 await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200)
208 testFfmpegStreamError(ffmpegCommand, true),
209 removeVideo(servers[0].url, servers[0].accessToken, liveVideoUUID)
213 await waitJobs(servers)
215 await checkVideosExist(liveVideoUUID, false, HttpStatusCode.NOT_FOUND_404)
216 await checkLiveCleanup(servers[0], liveVideoUUID, [])
220 describe('With save replay enabled', function () {
222 it('Should correctly create and federate the "waiting for stream" live', async function () {
225 liveVideoUUID = await createLiveWrapper(true)
227 await waitJobs(servers)
229 await checkVideosExist(liveVideoUUID, false, HttpStatusCode.OK_200)
230 await checkVideoState(liveVideoUUID, VideoState.WAITING_FOR_LIVE)
233 it('Should correctly have updated the live and federated it when streaming in the live', async function () {
236 ffmpegCommand = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoUUID)
237 await waitUntilLivePublishedOnAllServers(liveVideoUUID)
239 await waitJobs(servers)
241 await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200)
242 await checkVideoState(liveVideoUUID, VideoState.PUBLISHED)
245 it('Should correctly have saved the live and federated it after the streaming', async function () {
248 await stopFfmpeg(ffmpegCommand)
250 await waitUntilLiveSavedOnAllServers(liveVideoUUID)
251 await waitJobs(servers)
253 // Live has been transcoded
254 await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200)
255 await checkVideoState(liveVideoUUID, VideoState.PUBLISHED)
258 it('Should update the saved live and correctly federate the updated attributes', async function () {
261 await updateVideo(servers[0].url, servers[0].accessToken, liveVideoUUID, { name: 'video updated' })
262 await waitJobs(servers)
264 for (const server of servers) {
265 const res = await getVideo(server.url, liveVideoUUID)
266 expect(res.body.name).to.equal('video updated')
267 expect(res.body.isLive).to.be.false
271 it('Should have cleaned up the live files', async function () {
272 await checkLiveCleanup(servers[0], liveVideoUUID, [ 720 ])
275 it('Should correctly terminate the stream on blacklist and blacklist the saved replay video', async function () {
278 liveVideoUUID = await createLiveWrapper(true)
280 ffmpegCommand = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoUUID)
281 await waitUntilLivePublishedOnAllServers(liveVideoUUID)
283 await waitJobs(servers)
284 await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200)
287 addVideoToBlacklist(servers[0].url, servers[0].accessToken, liveVideoUUID, 'bad live', true),
288 testFfmpegStreamError(ffmpegCommand, true)
291 await waitJobs(servers)
293 await checkVideosExist(liveVideoUUID, false)
295 await getVideo(servers[0].url, liveVideoUUID, HttpStatusCode.UNAUTHORIZED_401)
296 await getVideo(servers[1].url, liveVideoUUID, HttpStatusCode.NOT_FOUND_404)
299 await waitJobs(servers)
300 await checkLiveCleanup(servers[0], liveVideoUUID, [ 720 ])
303 it('Should correctly terminate the stream on delete and delete the video', async function () {
306 liveVideoUUID = await createLiveWrapper(true)
308 ffmpegCommand = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoUUID)
309 await waitUntilLivePublishedOnAllServers(liveVideoUUID)
311 await waitJobs(servers)
312 await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200)
315 removeVideo(servers[0].url, servers[0].accessToken, liveVideoUUID),
316 testFfmpegStreamError(ffmpegCommand, true)
320 await waitJobs(servers)
322 await checkVideosExist(liveVideoUUID, false, HttpStatusCode.NOT_FOUND_404)
323 await checkLiveCleanup(servers[0], liveVideoUUID, [])
327 after(async function () {
328 await cleanupTests(servers)