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'
11 setAccessTokensToServers,
12 setDefaultVideoChannel,
16 waitUntilLivePublishedOnAllServers
17 } from '../../../../shared/extra-utils'
19 const expect = chai.expect
21 describe('Test live', function () {
22 let servers: PeerTubeServer[] = []
24 before(async function () {
27 servers = await createMultipleServers(2)
29 // Get the access tokens
30 await setAccessTokensToServers(servers)
31 await setDefaultVideoChannel(servers)
33 await servers[0].config.updateCustomSubConfig({
45 // Server 1 and server 2 follow each other
46 await doubleFollow(servers[0], servers[1])
49 describe('Live socket messages', function () {
51 async function createLiveWrapper () {
52 const liveAttributes = {
54 channelId: servers[0].store.channel.id,
55 privacy: VideoPrivacy.PUBLIC
58 const { uuid } = await servers[0].live.create({ fields: liveAttributes })
62 it('Should correctly send a message when the live starts and ends', async function () {
65 const localStateChanges: VideoState[] = []
66 const remoteStateChanges: VideoState[] = []
68 const liveVideoUUID = await createLiveWrapper()
69 await waitJobs(servers)
72 const videoId = await servers[0].videos.getId({ uuid: liveVideoUUID })
74 const localSocket = servers[0].socketIO.getLiveNotificationSocket()
75 localSocket.on('state-change', data => localStateChanges.push(data.state))
76 localSocket.emit('subscribe', { videoId })
80 const videoId = await servers[1].videos.getId({ uuid: liveVideoUUID })
82 const remoteSocket = servers[1].socketIO.getLiveNotificationSocket()
83 remoteSocket.on('state-change', data => remoteStateChanges.push(data.state))
84 remoteSocket.emit('subscribe', { videoId })
87 const ffmpegCommand = await servers[0].live.sendRTMPStreamInVideo({ videoId: liveVideoUUID })
89 await waitUntilLivePublishedOnAllServers(servers, liveVideoUUID)
90 await waitJobs(servers)
92 for (const stateChanges of [ localStateChanges, remoteStateChanges ]) {
93 expect(stateChanges).to.have.length.at.least(1)
94 expect(stateChanges[stateChanges.length - 1]).to.equal(VideoState.PUBLISHED)
97 await stopFfmpeg(ffmpegCommand)
99 for (const server of servers) {
100 await server.live.waitUntilEnded({ videoId: liveVideoUUID })
102 await waitJobs(servers)
104 for (const stateChanges of [ localStateChanges, remoteStateChanges ]) {
105 expect(stateChanges).to.have.length.at.least(2)
106 expect(stateChanges[stateChanges.length - 1]).to.equal(VideoState.LIVE_ENDED)
110 it('Should correctly send views change notification', async function () {
113 let localLastVideoViews = 0
114 let remoteLastVideoViews = 0
116 const liveVideoUUID = await createLiveWrapper()
117 await waitJobs(servers)
120 const videoId = await servers[0].videos.getId({ uuid: liveVideoUUID })
122 const localSocket = servers[0].socketIO.getLiveNotificationSocket()
123 localSocket.on('views-change', data => { localLastVideoViews = data.views })
124 localSocket.emit('subscribe', { videoId })
128 const videoId = await servers[1].videos.getId({ uuid: liveVideoUUID })
130 const remoteSocket = servers[1].socketIO.getLiveNotificationSocket()
131 remoteSocket.on('views-change', data => { remoteLastVideoViews = data.views })
132 remoteSocket.emit('subscribe', { videoId })
135 const ffmpegCommand = await servers[0].live.sendRTMPStreamInVideo({ videoId: liveVideoUUID })
137 await waitUntilLivePublishedOnAllServers(servers, liveVideoUUID)
138 await waitJobs(servers)
140 expect(localLastVideoViews).to.equal(0)
141 expect(remoteLastVideoViews).to.equal(0)
143 await servers[0].videos.view({ id: liveVideoUUID })
144 await servers[1].videos.view({ id: liveVideoUUID })
146 await waitJobs(servers)
148 expect(localLastVideoViews).to.equal(2)
149 expect(remoteLastVideoViews).to.equal(2)
151 await stopFfmpeg(ffmpegCommand)
154 it('Should not receive a notification after unsubscribe', async function () {
157 const stateChanges: VideoState[] = []
159 const liveVideoUUID = await createLiveWrapper()
160 await waitJobs(servers)
162 const videoId = await servers[0].videos.getId({ uuid: liveVideoUUID })
164 const socket = servers[0].socketIO.getLiveNotificationSocket()
165 socket.on('state-change', data => stateChanges.push(data.state))
166 socket.emit('subscribe', { videoId })
168 const command = await servers[0].live.sendRTMPStreamInVideo({ videoId: liveVideoUUID })
170 await waitUntilLivePublishedOnAllServers(servers, liveVideoUUID)
171 await waitJobs(servers)
173 // Notifier waits before sending a notification
176 expect(stateChanges).to.have.lengthOf(1)
177 socket.emit('unsubscribe', { videoId })
179 await stopFfmpeg(command)
180 await waitJobs(servers)
182 expect(stateChanges).to.have.lengthOf(1)
186 after(async function () {
187 await cleanupTests(servers)