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,
19 setAccessTokensToServers,
20 setDefaultVideoChannel,
22 testFfmpegStreamError,
26 } from '../../../../shared/extra-utils'
28 const expect = chai.expect
30 describe('Save replay setting', function () {
31 let servers: ServerInfo[] = []
32 let liveVideoUUID: string
33 let ffmpegCommand: FfmpegCommand
35 async function createLiveWrapper (saveReplay: boolean) {
38 await removeVideo(servers[0].url, servers[0].accessToken, liveVideoUUID)
39 await waitJobs(servers)
43 const attributes: LiveVideoCreate = {
44 channelId: servers[0].videoChannel.id,
45 privacy: VideoPrivacy.PUBLIC,
46 name: 'my super live',
50 const { uuid } = await servers[0].liveCommand.create({ fields: attributes })
54 async function checkVideosExist (videoId: string, existsInList: boolean, getStatus?: number) {
55 for (const server of servers) {
56 const length = existsInList ? 1 : 0
58 const resVideos = await getVideosList(server.url)
59 expect(resVideos.body.data).to.have.lengthOf(length)
60 expect(resVideos.body.total).to.equal(length)
63 await getVideo(server.url, videoId, getStatus)
68 async function checkVideoState (videoId: string, state: VideoState) {
69 for (const server of servers) {
70 const res = await getVideo(server.url, videoId)
71 expect((res.body as VideoDetails).state.id).to.equal(state)
75 async function waitUntilLivePublishedOnAllServers (videoId: string) {
76 for (const server of servers) {
77 await server.liveCommand.waitUntilPublished({ videoId })
81 async function waitUntilLiveSavedOnAllServers (videoId: string) {
82 for (const server of servers) {
83 await server.liveCommand.waitUntilSaved({ videoId })
87 before(async function () {
90 servers = await flushAndRunMultipleServers(2)
92 // Get the access tokens
93 await setAccessTokensToServers(servers)
94 await setDefaultVideoChannel(servers)
96 // Server 1 and server 2 follow each other
97 await doubleFollow(servers[0], servers[1])
99 await servers[0].configCommand.updateCustomSubConfig({
107 resolutions: ConfigCommand.getCustomConfigResolutions(true)
114 describe('With save replay disabled', function () {
116 before(async function () {
120 it('Should correctly create and federate the "waiting for stream" live', async function () {
123 liveVideoUUID = await createLiveWrapper(false)
125 await waitJobs(servers)
127 await checkVideosExist(liveVideoUUID, false, HttpStatusCode.OK_200)
128 await checkVideoState(liveVideoUUID, VideoState.WAITING_FOR_LIVE)
131 it('Should correctly have updated the live and federated it when streaming in the live', async function () {
134 ffmpegCommand = await servers[0].liveCommand.sendRTMPStreamInVideo({ videoId: liveVideoUUID })
136 await waitUntilLivePublishedOnAllServers(liveVideoUUID)
138 await waitJobs(servers)
140 await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200)
141 await checkVideoState(liveVideoUUID, VideoState.PUBLISHED)
144 it('Should correctly delete the video files after the stream ended', async function () {
147 await stopFfmpeg(ffmpegCommand)
149 for (const server of servers) {
150 await server.liveCommand.waitUntilEnded({ videoId: liveVideoUUID })
152 await waitJobs(servers)
154 // Live still exist, but cannot be played anymore
155 await checkVideosExist(liveVideoUUID, false, HttpStatusCode.OK_200)
156 await checkVideoState(liveVideoUUID, VideoState.LIVE_ENDED)
158 // No resolutions saved since we did not save replay
159 await checkLiveCleanup(servers[0], liveVideoUUID, [])
162 it('Should correctly terminate the stream on blacklist and delete the live', async function () {
165 liveVideoUUID = await createLiveWrapper(false)
167 ffmpegCommand = await servers[0].liveCommand.sendRTMPStreamInVideo({ videoId: liveVideoUUID })
169 await waitUntilLivePublishedOnAllServers(liveVideoUUID)
171 await waitJobs(servers)
172 await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200)
175 addVideoToBlacklist(servers[0].url, servers[0].accessToken, liveVideoUUID, 'bad live', true),
176 testFfmpegStreamError(ffmpegCommand, true)
179 await waitJobs(servers)
181 await checkVideosExist(liveVideoUUID, false)
183 await getVideo(servers[0].url, liveVideoUUID, HttpStatusCode.UNAUTHORIZED_401)
184 await getVideo(servers[1].url, liveVideoUUID, HttpStatusCode.NOT_FOUND_404)
187 await waitJobs(servers)
188 await checkLiveCleanup(servers[0], liveVideoUUID, [])
191 it('Should correctly terminate the stream on delete and delete the video', async function () {
194 liveVideoUUID = await createLiveWrapper(false)
196 ffmpegCommand = await servers[0].liveCommand.sendRTMPStreamInVideo({ videoId: liveVideoUUID })
198 await waitUntilLivePublishedOnAllServers(liveVideoUUID)
200 await waitJobs(servers)
201 await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200)
204 testFfmpegStreamError(ffmpegCommand, true),
205 removeVideo(servers[0].url, servers[0].accessToken, liveVideoUUID)
209 await waitJobs(servers)
211 await checkVideosExist(liveVideoUUID, false, HttpStatusCode.NOT_FOUND_404)
212 await checkLiveCleanup(servers[0], liveVideoUUID, [])
216 describe('With save replay enabled', function () {
218 it('Should correctly create and federate the "waiting for stream" live', async function () {
221 liveVideoUUID = await createLiveWrapper(true)
223 await waitJobs(servers)
225 await checkVideosExist(liveVideoUUID, false, HttpStatusCode.OK_200)
226 await checkVideoState(liveVideoUUID, VideoState.WAITING_FOR_LIVE)
229 it('Should correctly have updated the live and federated it when streaming in the live', async function () {
232 ffmpegCommand = await servers[0].liveCommand.sendRTMPStreamInVideo({ videoId: liveVideoUUID })
233 await waitUntilLivePublishedOnAllServers(liveVideoUUID)
235 await waitJobs(servers)
237 await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200)
238 await checkVideoState(liveVideoUUID, VideoState.PUBLISHED)
241 it('Should correctly have saved the live and federated it after the streaming', async function () {
244 await stopFfmpeg(ffmpegCommand)
246 await waitUntilLiveSavedOnAllServers(liveVideoUUID)
247 await waitJobs(servers)
249 // Live has been transcoded
250 await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200)
251 await checkVideoState(liveVideoUUID, VideoState.PUBLISHED)
254 it('Should update the saved live and correctly federate the updated attributes', async function () {
257 await updateVideo(servers[0].url, servers[0].accessToken, liveVideoUUID, { name: 'video updated' })
258 await waitJobs(servers)
260 for (const server of servers) {
261 const res = await getVideo(server.url, liveVideoUUID)
262 expect(res.body.name).to.equal('video updated')
263 expect(res.body.isLive).to.be.false
267 it('Should have cleaned up the live files', async function () {
268 await checkLiveCleanup(servers[0], liveVideoUUID, [ 720 ])
271 it('Should correctly terminate the stream on blacklist and blacklist the saved replay video', async function () {
274 liveVideoUUID = await createLiveWrapper(true)
276 ffmpegCommand = await servers[0].liveCommand.sendRTMPStreamInVideo({ videoId: liveVideoUUID })
277 await waitUntilLivePublishedOnAllServers(liveVideoUUID)
279 await waitJobs(servers)
280 await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200)
283 addVideoToBlacklist(servers[0].url, servers[0].accessToken, liveVideoUUID, 'bad live', true),
284 testFfmpegStreamError(ffmpegCommand, true)
287 await waitJobs(servers)
289 await checkVideosExist(liveVideoUUID, false)
291 await getVideo(servers[0].url, liveVideoUUID, HttpStatusCode.UNAUTHORIZED_401)
292 await getVideo(servers[1].url, liveVideoUUID, HttpStatusCode.NOT_FOUND_404)
295 await waitJobs(servers)
296 await checkLiveCleanup(servers[0], liveVideoUUID, [ 720 ])
299 it('Should correctly terminate the stream on delete and delete the video', async function () {
302 liveVideoUUID = await createLiveWrapper(true)
304 ffmpegCommand = await servers[0].liveCommand.sendRTMPStreamInVideo({ videoId: liveVideoUUID })
305 await waitUntilLivePublishedOnAllServers(liveVideoUUID)
307 await waitJobs(servers)
308 await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200)
311 removeVideo(servers[0].url, servers[0].accessToken, liveVideoUUID),
312 testFfmpegStreamError(ffmpegCommand, true)
316 await waitJobs(servers)
318 await checkVideosExist(liveVideoUUID, false, HttpStatusCode.NOT_FOUND_404)
319 await checkLiveCleanup(servers[0], liveVideoUUID, [])
323 after(async function () {
324 await cleanupTests(servers)