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