1 /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
4 import * as chai from 'chai'
5 import { VideoPrivacy, VideoState } from '@shared/models'
10 flushAndRunMultipleServers,
12 sendRTMPStreamInVideo,
14 setAccessTokensToServers,
15 setDefaultVideoChannel,
21 waitUntilLivePublishedOnAllServers
22 } from '../../../../shared/extra-utils'
24 const expect = chai.expect
26 describe('Test live', function () {
27 let servers: ServerInfo[] = []
29 before(async function () {
32 servers = await flushAndRunMultipleServers(2)
34 // Get the access tokens
35 await setAccessTokensToServers(servers)
36 await setDefaultVideoChannel(servers)
38 await servers[0].configCommand.updateCustomSubConfig({
50 // Server 1 and server 2 follow each other
51 await doubleFollow(servers[0], servers[1])
54 describe('Live socket messages', function () {
56 async function createLiveWrapper () {
57 const liveAttributes = {
59 channelId: servers[0].videoChannel.id,
60 privacy: VideoPrivacy.PUBLIC
63 const res = await createLive(servers[0].url, servers[0].accessToken, liveAttributes)
64 return res.body.video.uuid
67 it('Should correctly send a message when the live starts and ends', async function () {
70 const localStateChanges: VideoState[] = []
71 const remoteStateChanges: VideoState[] = []
73 const liveVideoUUID = await createLiveWrapper()
74 await waitJobs(servers)
77 const videoId = await getVideoIdFromUUID(servers[0].url, liveVideoUUID)
79 const localSocket = servers[0].socketIOCommand.getLiveNotificationSocket()
80 localSocket.on('state-change', data => localStateChanges.push(data.state))
81 localSocket.emit('subscribe', { videoId })
85 const videoId = await getVideoIdFromUUID(servers[1].url, liveVideoUUID)
87 const remoteSocket = servers[1].socketIOCommand.getLiveNotificationSocket()
88 remoteSocket.on('state-change', data => remoteStateChanges.push(data.state))
89 remoteSocket.emit('subscribe', { videoId })
92 const command = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoUUID)
94 await waitUntilLivePublishedOnAllServers(servers, liveVideoUUID)
95 await waitJobs(servers)
97 for (const stateChanges of [ localStateChanges, remoteStateChanges ]) {
98 expect(stateChanges).to.have.length.at.least(1)
99 expect(stateChanges[stateChanges.length - 1]).to.equal(VideoState.PUBLISHED)
102 await stopFfmpeg(command)
104 for (const server of servers) {
105 await waitUntilLiveEnded(server.url, server.accessToken, liveVideoUUID)
107 await waitJobs(servers)
109 for (const stateChanges of [ localStateChanges, remoteStateChanges ]) {
110 expect(stateChanges).to.have.length.at.least(2)
111 expect(stateChanges[stateChanges.length - 1]).to.equal(VideoState.LIVE_ENDED)
115 it('Should correctly send views change notification', async function () {
118 let localLastVideoViews = 0
119 let remoteLastVideoViews = 0
121 const liveVideoUUID = await createLiveWrapper()
122 await waitJobs(servers)
125 const videoId = await getVideoIdFromUUID(servers[0].url, liveVideoUUID)
127 const localSocket = servers[0].socketIOCommand.getLiveNotificationSocket()
128 localSocket.on('views-change', data => { localLastVideoViews = data.views })
129 localSocket.emit('subscribe', { videoId })
133 const videoId = await getVideoIdFromUUID(servers[1].url, liveVideoUUID)
135 const remoteSocket = servers[1].socketIOCommand.getLiveNotificationSocket()
136 remoteSocket.on('views-change', data => { remoteLastVideoViews = data.views })
137 remoteSocket.emit('subscribe', { videoId })
140 const command = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoUUID)
142 await waitUntilLivePublishedOnAllServers(servers, liveVideoUUID)
143 await waitJobs(servers)
145 expect(localLastVideoViews).to.equal(0)
146 expect(remoteLastVideoViews).to.equal(0)
148 await viewVideo(servers[0].url, liveVideoUUID)
149 await viewVideo(servers[1].url, liveVideoUUID)
151 await waitJobs(servers)
153 await waitJobs(servers)
155 expect(localLastVideoViews).to.equal(2)
156 expect(remoteLastVideoViews).to.equal(2)
158 await stopFfmpeg(command)
161 it('Should not receive a notification after unsubscribe', async function () {
164 const stateChanges: VideoState[] = []
166 const liveVideoUUID = await createLiveWrapper()
167 await waitJobs(servers)
169 const videoId = await getVideoIdFromUUID(servers[0].url, liveVideoUUID)
171 const socket = servers[0].socketIOCommand.getLiveNotificationSocket()
172 socket.on('state-change', data => stateChanges.push(data.state))
173 socket.emit('subscribe', { videoId })
175 const command = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoUUID)
177 await waitUntilLivePublishedOnAllServers(servers, liveVideoUUID)
178 await waitJobs(servers)
180 // Notifier waits before sending a notification
183 expect(stateChanges).to.have.lengthOf(1)
184 socket.emit('unsubscribe', { videoId })
186 await stopFfmpeg(command)
187 await waitJobs(servers)
189 expect(stateChanges).to.have.lengthOf(1)
193 after(async function () {
194 await cleanupTests(servers)