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'
13 flushAndRunMultipleServers,
17 sendRTMPStreamInVideo,
19 setAccessTokensToServers,
20 setDefaultVideoChannel,
22 testFfmpegStreamError,
23 updateCustomSubConfig,
26 waitUntilLivePublished
27 } from '../../../../shared/extra-utils'
28 import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
30 const expect = chai.expect
32 describe('Save replay setting', function () {
33 let servers: ServerInfo[] = []
34 let liveVideoUUID: string
35 let ffmpegCommand: FfmpegCommand
37 async function createLiveWrapper (saveReplay: boolean) {
40 await removeVideo(servers[0].url, servers[0].accessToken, liveVideoUUID)
41 await waitJobs(servers)
45 const attributes: LiveVideoCreate = {
46 channelId: servers[0].videoChannel.id,
47 privacy: VideoPrivacy.PUBLIC,
48 name: 'my super live',
52 const res = await createLive(servers[0].url, servers[0].accessToken, attributes)
53 return res.body.video.uuid
56 async function checkVideosExist (videoId: string, existsInList: boolean, getStatus?: number) {
57 for (const server of servers) {
58 const length = existsInList ? 1 : 0
60 const resVideos = await getVideosList(server.url)
61 expect(resVideos.body.data).to.have.lengthOf(length)
62 expect(resVideos.body.total).to.equal(length)
65 await getVideo(server.url, videoId, getStatus)
70 async function checkVideoState (videoId: string, state: VideoState) {
71 for (const server of servers) {
72 const res = await getVideo(server.url, videoId)
73 expect((res.body as VideoDetails).state.id).to.equal(state)
77 before(async function () {
80 servers = await flushAndRunMultipleServers(2)
82 // Get the access tokens
83 await setAccessTokensToServers(servers)
84 await setDefaultVideoChannel(servers)
86 // Server 1 and server 2 follow each other
87 await doubleFollow(servers[0], servers[1])
89 await updateCustomSubConfig(servers[0].url, servers[0].accessToken, {
110 describe('With save replay disabled', function () {
112 before(async function () {
116 it('Should correctly create and federate the "waiting for stream" live', async function () {
119 liveVideoUUID = await createLiveWrapper(false)
121 await waitJobs(servers)
123 await checkVideosExist(liveVideoUUID, false, HttpStatusCode.OK_200)
124 await checkVideoState(liveVideoUUID, VideoState.WAITING_FOR_LIVE)
127 it('Should correctly have updated the live and federated it when streaming in the live', async function () {
130 ffmpegCommand = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoUUID)
131 await waitUntilLivePublished(servers[0].url, servers[0].accessToken, liveVideoUUID)
133 await waitJobs(servers)
135 await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200)
136 await checkVideoState(liveVideoUUID, VideoState.PUBLISHED)
139 it('Should correctly delete the video files after the stream ended', async function () {
142 await stopFfmpeg(ffmpegCommand)
144 await waitJobs(servers)
146 // Live still exist, but cannot be played anymore
147 await checkVideosExist(liveVideoUUID, false, HttpStatusCode.OK_200)
148 await checkVideoState(liveVideoUUID, VideoState.LIVE_ENDED)
150 await waitJobs(servers)
152 // No resolutions saved since we did not save replay
153 await checkLiveCleanup(servers[0], liveVideoUUID, [])
156 it('Should correctly terminate the stream on blacklist and delete the live', async function () {
159 liveVideoUUID = await createLiveWrapper(false)
161 ffmpegCommand = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoUUID)
162 await waitUntilLivePublished(servers[0].url, servers[0].accessToken, liveVideoUUID)
164 await waitJobs(servers)
165 await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200)
168 addVideoToBlacklist(servers[0].url, servers[0].accessToken, liveVideoUUID, 'bad live', true),
169 testFfmpegStreamError(ffmpegCommand, true)
172 await waitJobs(servers)
174 await checkVideosExist(liveVideoUUID, false)
176 await getVideo(servers[0].url, liveVideoUUID, HttpStatusCode.UNAUTHORIZED_401)
177 await getVideo(servers[1].url, liveVideoUUID, HttpStatusCode.NOT_FOUND_404)
179 await checkLiveCleanup(servers[0], liveVideoUUID, [])
182 it('Should correctly terminate the stream on delete and delete the video', async function () {
185 liveVideoUUID = await createLiveWrapper(false)
187 ffmpegCommand = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoUUID)
188 await waitUntilLivePublished(servers[0].url, servers[0].accessToken, liveVideoUUID)
190 await waitJobs(servers)
191 await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200)
194 testFfmpegStreamError(ffmpegCommand, true),
195 removeVideo(servers[0].url, servers[0].accessToken, liveVideoUUID)
198 await waitJobs(servers)
200 await checkVideosExist(liveVideoUUID, false, HttpStatusCode.NOT_FOUND_404)
201 await checkLiveCleanup(servers[0], liveVideoUUID, [])
205 describe('With save replay enabled', function () {
207 it('Should correctly create and federate the "waiting for stream" live', async function () {
210 liveVideoUUID = await createLiveWrapper(true)
212 await waitJobs(servers)
214 await checkVideosExist(liveVideoUUID, false, HttpStatusCode.OK_200)
215 await checkVideoState(liveVideoUUID, VideoState.WAITING_FOR_LIVE)
218 it('Should correctly have updated the live and federated it when streaming in the live', async function () {
221 ffmpegCommand = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoUUID)
222 await waitUntilLivePublished(servers[0].url, servers[0].accessToken, liveVideoUUID)
224 await waitJobs(servers)
226 await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200)
227 await checkVideoState(liveVideoUUID, VideoState.PUBLISHED)
230 it('Should correctly have saved the live and federated it after the streaming', async function () {
233 await stopFfmpeg(ffmpegCommand)
235 await waitJobs(servers)
237 // Live has been transcoded
238 await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200)
239 await checkVideoState(liveVideoUUID, VideoState.PUBLISHED)
242 it('Should update the saved live and correctly federate the updated attributes', async function () {
245 await updateVideo(servers[0].url, servers[0].accessToken, liveVideoUUID, { name: 'video updated' })
246 await waitJobs(servers)
248 for (const server of servers) {
249 const res = await getVideo(server.url, liveVideoUUID)
250 expect(res.body.name).to.equal('video updated')
251 expect(res.body.isLive).to.be.false
255 it('Should have cleaned up the live files', async function () {
256 await checkLiveCleanup(servers[0], liveVideoUUID, [ 720 ])
259 it('Should correctly terminate the stream on blacklist and blacklist the saved replay video', async function () {
262 liveVideoUUID = await createLiveWrapper(true)
264 ffmpegCommand = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoUUID)
265 await waitUntilLivePublished(servers[0].url, servers[0].accessToken, liveVideoUUID)
267 await waitJobs(servers)
268 await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200)
271 addVideoToBlacklist(servers[0].url, servers[0].accessToken, liveVideoUUID, 'bad live', true),
272 testFfmpegStreamError(ffmpegCommand, true)
275 await waitJobs(servers)
277 await checkVideosExist(liveVideoUUID, false)
279 await getVideo(servers[0].url, liveVideoUUID, HttpStatusCode.UNAUTHORIZED_401)
280 await getVideo(servers[1].url, liveVideoUUID, HttpStatusCode.NOT_FOUND_404)
282 await checkLiveCleanup(servers[0], liveVideoUUID, [ 720 ])
285 it('Should correctly terminate the stream on delete and delete the video', async function () {
288 liveVideoUUID = await createLiveWrapper(true)
290 ffmpegCommand = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoUUID)
291 await waitUntilLivePublished(servers[0].url, servers[0].accessToken, liveVideoUUID)
293 await waitJobs(servers)
294 await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200)
297 removeVideo(servers[0].url, servers[0].accessToken, liveVideoUUID),
298 testFfmpegStreamError(ffmpegCommand, true)
301 await waitJobs(servers)
303 await checkVideosExist(liveVideoUUID, false, HttpStatusCode.NOT_FOUND_404)
304 await checkLiveCleanup(servers[0], liveVideoUUID, [])
308 after(async function () {
309 await cleanupTests(servers)