]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/tests/plugins/plugin-transcoding.ts
Add runner server tests
[github/Chocobozzz/PeerTube.git] / server / tests / plugins / plugin-transcoding.ts
CommitLineData
1896bca0
C
1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
1896bca0 3import { expect } from 'chai'
d102de1b 4import { getAudioStream, getVideoStream, getVideoStreamFPS } from '@shared/ffmpeg'
c729caf6 5import { VideoPrivacy } from '@shared/models'
1896bca0 6import {
ae2abfd3 7 cleanupTests,
254d3579 8 createSingleServer,
254d3579 9 PeerTubeServer,
4c7e60bc 10 PluginsCommand,
1896bca0
C
11 setAccessTokensToServers,
12 setDefaultVideoChannel,
3e03b961 13 testFfmpegStreamError,
4f219914 14 waitJobs
bf54587a 15} from '@shared/server-commands'
1896bca0 16
254d3579 17async function createLiveWrapper (server: PeerTubeServer) {
1896bca0
C
18 const liveAttributes = {
19 name: 'live video',
89d241a7 20 channelId: server.store.channel.id,
1896bca0
C
21 privacy: VideoPrivacy.PUBLIC
22 }
23
89d241a7 24 const { uuid } = await server.live.create({ fields: liveAttributes })
4f219914
C
25
26 return uuid
1896bca0
C
27}
28
254d3579 29function updateConf (server: PeerTubeServer, vodProfile: string, liveProfile: string) {
89d241a7 30 return server.config.updateCustomSubConfig({
65e6e260 31 newConfig: {
1896bca0 32 transcoding: {
b3eafc5f 33 enabled: true,
65e6e260
C
34 profile: vodProfile,
35 hls: {
36 enabled: true
37 },
38 webtorrent: {
39 enabled: true
40 },
b3eafc5f
C
41 resolutions: {
42 '240p': true,
43 '360p': false,
44 '480p': false,
45 '720p': true
46 }
65e6e260
C
47 },
48 live: {
49 transcoding: {
50 profile: liveProfile,
51 enabled: true,
52 resolutions: {
53 '240p': true,
54 '360p': false,
55 '480p': false,
56 '720p': true
57 }
58 }
1896bca0
C
59 }
60 }
61 })
62}
63
64describe('Test transcoding plugins', function () {
254d3579 65 let server: PeerTubeServer
1896bca0
C
66
67 before(async function () {
68 this.timeout(60000)
69
254d3579 70 server = await createSingleServer(1)
1896bca0
C
71 await setAccessTokensToServers([ server ])
72 await setDefaultVideoChannel([ server ])
73
74 await updateConf(server, 'default', 'default')
75 })
76
77 describe('When using a plugin adding profiles to existing encoders', function () {
78
79 async function checkVideoFPS (uuid: string, type: 'above' | 'below', fps: number) {
89d241a7 80 const video = await server.videos.get({ id: uuid })
1896bca0
C
81 const files = video.files.concat(...video.streamingPlaylists.map(p => p.files))
82
83 for (const file of files) {
84 if (type === 'above') {
85 expect(file.fps).to.be.above(fps)
86 } else {
87 expect(file.fps).to.be.below(fps)
88 }
89 }
90 }
91
92 async function checkLiveFPS (uuid: string, type: 'above' | 'below', fps: number) {
93 const playlistUrl = `${server.url}/static/streaming-playlists/hls/${uuid}/0.m3u8`
c729caf6 94 const videoFPS = await getVideoStreamFPS(playlistUrl)
1896bca0
C
95
96 if (type === 'above') {
97 expect(videoFPS).to.be.above(fps)
98 } else {
99 expect(videoFPS).to.be.below(fps)
100 }
101 }
102
103 before(async function () {
89d241a7 104 await server.plugins.install({ path: PluginsCommand.getPluginTestPath('-transcoding-one') })
1896bca0
C
105 })
106
107 it('Should have the appropriate available profiles', async function () {
89d241a7 108 const config = await server.config.getConfig()
1896bca0 109
3e03b961 110 expect(config.transcoding.availableProfiles).to.have.members([ 'default', 'low-vod', 'input-options-vod', 'bad-scale-vod' ])
13e13377 111 expect(config.live.transcoding.availableProfiles).to.have.members([ 'default', 'high-live', 'input-options-live', 'bad-scale-live' ])
1896bca0
C
112 })
113
13e13377 114 describe('VOD', function () {
1896bca0 115
13e13377
C
116 it('Should not use the plugin profile if not chosen by the admin', async function () {
117 this.timeout(240000)
1896bca0 118
13e13377
C
119 const videoUUID = (await server.videos.quickUpload({ name: 'video' })).uuid
120 await waitJobs([ server ])
1896bca0 121
13e13377
C
122 await checkVideoFPS(videoUUID, 'above', 20)
123 })
1896bca0 124
13e13377
C
125 it('Should use the vod profile', async function () {
126 this.timeout(240000)
1896bca0 127
13e13377 128 await updateConf(server, 'low-vod', 'default')
1896bca0 129
13e13377
C
130 const videoUUID = (await server.videos.quickUpload({ name: 'video' })).uuid
131 await waitJobs([ server ])
1896bca0 132
13e13377
C
133 await checkVideoFPS(videoUUID, 'below', 12)
134 })
d2351bcf 135
13e13377
C
136 it('Should apply input options in vod profile', async function () {
137 this.timeout(240000)
d2351bcf 138
13e13377 139 await updateConf(server, 'input-options-vod', 'default')
d2351bcf 140
13e13377
C
141 const videoUUID = (await server.videos.quickUpload({ name: 'video' })).uuid
142 await waitJobs([ server ])
d2351bcf 143
13e13377
C
144 await checkVideoFPS(videoUUID, 'below', 6)
145 })
d2351bcf 146
13e13377
C
147 it('Should apply the scale filter in vod profile', async function () {
148 this.timeout(240000)
d2351bcf 149
13e13377 150 await updateConf(server, 'bad-scale-vod', 'default')
d2351bcf 151
13e13377
C
152 const videoUUID = (await server.videos.quickUpload({ name: 'video' })).uuid
153 await waitJobs([ server ])
154
155 // Transcoding failed
156 const video = await server.videos.get({ id: videoUUID })
157 expect(video.files).to.have.lengthOf(1)
158 expect(video.streamingPlaylists).to.have.lengthOf(0)
159 })
d2351bcf
TLC
160 })
161
13e13377 162 describe('Live', function () {
1896bca0 163
13e13377
C
164 it('Should not use the plugin profile if not chosen by the admin', async function () {
165 this.timeout(240000)
1896bca0 166
13e13377 167 const liveVideoId = await createLiveWrapper(server)
1896bca0 168
13e13377
C
169 await server.live.sendRTMPStreamInVideo({ videoId: liveVideoId, fixtureName: 'video_very_short_240p.mp4' })
170 await server.live.waitUntilPublished({ videoId: liveVideoId })
171 await waitJobs([ server ])
1896bca0 172
13e13377
C
173 await checkLiveFPS(liveVideoId, 'above', 20)
174 })
1896bca0 175
13e13377
C
176 it('Should use the live profile', async function () {
177 this.timeout(240000)
1896bca0 178
13e13377 179 await updateConf(server, 'low-vod', 'high-live')
1896bca0 180
13e13377 181 const liveVideoId = await createLiveWrapper(server)
1896bca0 182
13e13377
C
183 await server.live.sendRTMPStreamInVideo({ videoId: liveVideoId, fixtureName: 'video_very_short_240p.mp4' })
184 await server.live.waitUntilPublished({ videoId: liveVideoId })
185 await waitJobs([ server ])
1896bca0 186
13e13377
C
187 await checkLiveFPS(liveVideoId, 'above', 45)
188 })
d2351bcf 189
13e13377
C
190 it('Should apply the input options on live profile', async function () {
191 this.timeout(240000)
d2351bcf 192
13e13377 193 await updateConf(server, 'low-vod', 'input-options-live')
d2351bcf 194
13e13377 195 const liveVideoId = await createLiveWrapper(server)
d2351bcf 196
13e13377
C
197 await server.live.sendRTMPStreamInVideo({ videoId: liveVideoId, fixtureName: 'video_very_short_240p.mp4' })
198 await server.live.waitUntilPublished({ videoId: liveVideoId })
199 await waitJobs([ server ])
d2351bcf 200
13e13377
C
201 await checkLiveFPS(liveVideoId, 'above', 45)
202 })
3e03b961 203
13e13377
C
204 it('Should apply the scale filter name on live profile', async function () {
205 this.timeout(240000)
3e03b961 206
13e13377 207 await updateConf(server, 'low-vod', 'bad-scale-live')
3e03b961 208
13e13377 209 const liveVideoId = await createLiveWrapper(server)
3e03b961 210
13e13377
C
211 const command = await server.live.sendRTMPStreamInVideo({ videoId: liveVideoId, fixtureName: 'video_very_short_240p.mp4' })
212 await testFfmpegStreamError(command, true)
213 })
1896bca0 214
13e13377
C
215 it('Should default to the default profile if the specified profile does not exist', async function () {
216 this.timeout(240000)
1896bca0 217
13e13377 218 await server.plugins.uninstall({ npmName: 'peertube-plugin-test-transcoding-one' })
1896bca0 219
13e13377 220 const config = await server.config.getConfig()
1896bca0 221
13e13377
C
222 expect(config.transcoding.availableProfiles).to.deep.equal([ 'default' ])
223 expect(config.live.transcoding.availableProfiles).to.deep.equal([ 'default' ])
224
225 const videoUUID = (await server.videos.quickUpload({ name: 'video', fixture: 'video_very_short_240p.mp4' })).uuid
226 await waitJobs([ server ])
1896bca0 227
13e13377
C
228 await checkVideoFPS(videoUUID, 'above', 20)
229 })
1896bca0
C
230 })
231
232 })
233
234 describe('When using a plugin adding new encoders', function () {
235
236 before(async function () {
89d241a7 237 await server.plugins.install({ path: PluginsCommand.getPluginTestPath('-transcoding-two') })
1896bca0
C
238
239 await updateConf(server, 'test-vod-profile', 'test-live-profile')
240 })
241
242 it('Should use the new vod encoders', async function () {
243 this.timeout(240000)
244
13e13377 245 const videoUUID = (await server.videos.quickUpload({ name: 'video', fixture: 'video_very_short_240p.mp4' })).uuid
1896bca0
C
246 await waitJobs([ server ])
247
764b1a14
C
248 const video = await server.videos.get({ id: videoUUID })
249
250 const path = server.servers.buildWebTorrentFilePath(video.files[0].fileUrl)
1896bca0
C
251 const audioProbe = await getAudioStream(path)
252 expect(audioProbe.audioStream.codec_name).to.equal('opus')
253
c729caf6 254 const videoProbe = await getVideoStream(path)
1896bca0
C
255 expect(videoProbe.codec_name).to.equal('vp9')
256 })
257
258 it('Should use the new live encoders', async function () {
fc8f15d2 259 this.timeout(240000)
1896bca0
C
260
261 const liveVideoId = await createLiveWrapper(server)
262
89d241a7
C
263 await server.live.sendRTMPStreamInVideo({ videoId: liveVideoId, fixtureName: 'video_short2.webm' })
264 await server.live.waitUntilPublished({ videoId: liveVideoId })
1896bca0
C
265 await waitJobs([ server ])
266
267 const playlistUrl = `${server.url}/static/streaming-playlists/hls/${liveVideoId}/0.m3u8`
268 const audioProbe = await getAudioStream(playlistUrl)
269 expect(audioProbe.audioStream.codec_name).to.equal('opus')
270
c729caf6 271 const videoProbe = await getVideoStream(playlistUrl)
1896bca0
C
272 expect(videoProbe.codec_name).to.equal('h264')
273 })
274 })
275
276 after(async function () {
277 await cleanupTests([ server ])
278 })
279})