]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/tests/peertube-runner/live-transcoding.ts
17e1f3078080d704e38d3ad1eb226de1e7f77180
[github/Chocobozzz/PeerTube.git] / server / tests / peertube-runner / live-transcoding.ts
1 /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 import { expect } from 'chai'
3 import {
4 checkPeerTubeRunnerCacheIsEmpty,
5 expectStartWith,
6 PeerTubeRunnerProcess,
7 SQLCommand,
8 testLiveVideoResolutions
9 } from '@server/tests/shared'
10 import { areMockObjectStorageTestsDisabled, wait } from '@shared/core-utils'
11 import { HttpStatusCode, VideoPrivacy } from '@shared/models'
12 import {
13 cleanupTests,
14 createMultipleServers,
15 doubleFollow,
16 findExternalSavedVideo,
17 makeRawRequest,
18 ObjectStorageCommand,
19 PeerTubeServer,
20 setAccessTokensToServers,
21 setDefaultVideoChannel,
22 stopFfmpeg,
23 waitJobs,
24 waitUntilLivePublishedOnAllServers,
25 waitUntilLiveWaitingOnAllServers
26 } from '@shared/server-commands'
27
28 describe('Test Live transcoding in peertube-runner program', function () {
29 let servers: PeerTubeServer[] = []
30 let peertubeRunner: PeerTubeRunnerProcess
31 let sqlCommandServer1: SQLCommand
32
33 function runSuite (options: {
34 objectStorage: boolean
35 }) {
36 const { objectStorage } = options
37
38 it('Should enable transcoding without additional resolutions', async function () {
39 this.timeout(120000)
40
41 const { video } = await servers[0].live.quickCreate({ permanentLive: true, saveReplay: false, privacy: VideoPrivacy.PUBLIC })
42
43 const ffmpegCommand = await servers[0].live.sendRTMPStreamInVideo({ videoId: video.uuid })
44 await waitUntilLivePublishedOnAllServers(servers, video.uuid)
45 await waitJobs(servers)
46
47 await testLiveVideoResolutions({
48 originServer: servers[0],
49 sqlCommand: sqlCommandServer1,
50 servers,
51 liveVideoId: video.uuid,
52 resolutions: [ 720, 480, 360, 240, 144 ],
53 objectStorage,
54 transcoded: true
55 })
56
57 await stopFfmpeg(ffmpegCommand)
58
59 await waitUntilLiveWaitingOnAllServers(servers, video.uuid)
60 await servers[0].videos.remove({ id: video.id })
61 })
62
63 it('Should transcode audio only RTMP stream', async function () {
64 this.timeout(120000)
65
66 const { video } = await servers[0].live.quickCreate({ permanentLive: true, saveReplay: false, privacy: VideoPrivacy.UNLISTED })
67
68 const ffmpegCommand = await servers[0].live.sendRTMPStreamInVideo({ videoId: video.uuid, fixtureName: 'video_short_no_audio.mp4' })
69 await waitUntilLivePublishedOnAllServers(servers, video.uuid)
70 await waitJobs(servers)
71
72 await stopFfmpeg(ffmpegCommand)
73
74 await waitUntilLiveWaitingOnAllServers(servers, video.uuid)
75 await servers[0].videos.remove({ id: video.id })
76 })
77
78 it('Should save a replay', async function () {
79 this.timeout(120000)
80
81 const { video } = await servers[0].live.quickCreate({ permanentLive: true, saveReplay: true })
82
83 const ffmpegCommand = await servers[0].live.sendRTMPStreamInVideo({ videoId: video.uuid })
84 await waitUntilLivePublishedOnAllServers(servers, video.uuid)
85
86 await testLiveVideoResolutions({
87 originServer: servers[0],
88 sqlCommand: sqlCommandServer1,
89 servers,
90 liveVideoId: video.uuid,
91 resolutions: [ 720, 480, 360, 240, 144 ],
92 objectStorage,
93 transcoded: true
94 })
95
96 await stopFfmpeg(ffmpegCommand)
97
98 await waitUntilLiveWaitingOnAllServers(servers, video.uuid)
99 await waitJobs(servers)
100
101 const session = await servers[0].live.findLatestSession({ videoId: video.uuid })
102 expect(session.endingProcessed).to.be.true
103 expect(session.endDate).to.exist
104 expect(session.saveReplay).to.be.true
105
106 const videoLiveDetails = await servers[0].videos.get({ id: video.uuid })
107 const replay = await findExternalSavedVideo(servers[0], videoLiveDetails)
108
109 for (const server of servers) {
110 const video = await server.videos.get({ id: replay.uuid })
111
112 expect(video.files).to.have.lengthOf(0)
113 expect(video.streamingPlaylists).to.have.lengthOf(1)
114
115 const files = video.streamingPlaylists[0].files
116 expect(files).to.have.lengthOf(5)
117
118 for (const file of files) {
119 if (objectStorage) {
120 expectStartWith(file.fileUrl, ObjectStorageCommand.getMockPlaylistBaseUrl())
121 }
122
123 await makeRawRequest({ url: file.fileUrl, expectedStatus: HttpStatusCode.OK_200 })
124 }
125 }
126 })
127 }
128
129 before(async function () {
130 this.timeout(120_000)
131
132 servers = await createMultipleServers(2)
133
134 await setAccessTokensToServers(servers)
135 await setDefaultVideoChannel(servers)
136
137 await doubleFollow(servers[0], servers[1])
138
139 sqlCommandServer1 = new SQLCommand(servers[0])
140
141 await servers[0].config.enableRemoteTranscoding()
142 await servers[0].config.enableTranscoding(true, true, true)
143 await servers[0].config.enableLive({ allowReplay: true, resolutions: 'max', transcoding: true })
144
145 const registrationToken = await servers[0].runnerRegistrationTokens.getFirstRegistrationToken()
146
147 peertubeRunner = new PeerTubeRunnerProcess(servers[0])
148 await peertubeRunner.runServer()
149 await peertubeRunner.registerPeerTubeInstance({ registrationToken, runnerName: 'runner' })
150 })
151
152 describe('With lives on local filesystem storage', function () {
153
154 before(async function () {
155 await servers[0].config.enableTranscoding(true, false, true)
156 })
157
158 runSuite({ objectStorage: false })
159 })
160
161 describe('With lives on object storage', function () {
162 if (areMockObjectStorageTestsDisabled()) return
163
164 before(async function () {
165 await ObjectStorageCommand.prepareDefaultMockBuckets()
166
167 await servers[0].kill()
168
169 await servers[0].run(ObjectStorageCommand.getDefaultMockConfig())
170
171 // Wait for peertube runner socket reconnection
172 await wait(1500)
173 })
174
175 runSuite({ objectStorage: true })
176 })
177
178 describe('Check cleanup', function () {
179
180 it('Should have an empty cache directory', async function () {
181 await checkPeerTubeRunnerCacheIsEmpty(peertubeRunner)
182 })
183 })
184
185 after(async function () {
186 if (peertubeRunner) {
187 await peertubeRunner.unregisterPeerTubeInstance()
188 peertubeRunner.kill()
189 }
190
191 if (sqlCommandServer1) await sqlCommandServer1.cleanup()
192
193 await cleanupTests(servers)
194 })
195 })