aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/tests/api/videos/video-transcoder.ts
diff options
context:
space:
mode:
Diffstat (limited to 'server/tests/api/videos/video-transcoder.ts')
-rw-r--r--server/tests/api/videos/video-transcoder.ts341
1 files changed, 159 insertions, 182 deletions
diff --git a/server/tests/api/videos/video-transcoder.ts b/server/tests/api/videos/video-transcoder.ts
index ea5ffd239..e4892bb24 100644
--- a/server/tests/api/videos/video-transcoder.ts
+++ b/server/tests/api/videos/video-transcoder.ts
@@ -2,36 +2,23 @@
2 2
3import 'mocha' 3import 'mocha'
4import * as chai from 'chai' 4import * as chai from 'chai'
5import { FfprobeData } from 'fluent-ffmpeg'
6import { omit } from 'lodash' 5import { omit } from 'lodash'
7import { join } from 'path' 6import { join } from 'path'
8import { Job } from '@shared/models'
9import { VIDEO_TRANSCODING_FPS } from '../../../../server/initializers/constants'
10import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
11import { 7import {
12 buildAbsoluteFixturePath, 8 buildAbsoluteFixturePath,
13 buildServerDirectory,
14 cleanupTests, 9 cleanupTests,
10 createMultipleServers,
15 doubleFollow, 11 doubleFollow,
16 flushAndRunMultipleServers,
17 generateHighBitrateVideo, 12 generateHighBitrateVideo,
18 generateVideoWithFramerate, 13 generateVideoWithFramerate,
19 getJobsListPaginationAndSort,
20 getMyVideos,
21 getServerFileSize,
22 getVideo,
23 getVideoFileMetadataUrl,
24 getVideosList,
25 makeGetRequest, 14 makeGetRequest,
26 ServerInfo, 15 PeerTubeServer,
27 setAccessTokensToServers, 16 setAccessTokensToServers,
28 updateCustomSubConfig,
29 uploadVideo,
30 uploadVideoAndGetId,
31 waitJobs, 17 waitJobs,
32 webtorrentAdd 18 webtorrentAdd
33} from '../../../../shared/extra-utils' 19} from '@shared/extra-utils'
34import { getMaxBitrate, VideoDetails, VideoResolution, VideoState } from '../../../../shared/models/videos' 20import { getMaxBitrate, HttpStatusCode, VideoResolution, VideoState } from '@shared/models'
21import { VIDEO_TRANSCODING_FPS } from '../../../../server/initializers/constants'
35import { 22import {
36 canDoQuickTranscode, 23 canDoQuickTranscode,
37 getAudioStream, 24 getAudioStream,
@@ -43,37 +30,39 @@ import {
43 30
44const expect = chai.expect 31const expect = chai.expect
45 32
46function updateConfigForTranscoding (server: ServerInfo) { 33function updateConfigForTranscoding (server: PeerTubeServer) {
47 return updateCustomSubConfig(server.url, server.accessToken, { 34 return server.config.updateCustomSubConfig({
48 transcoding: { 35 newConfig: {
49 enabled: true, 36 transcoding: {
50 allowAdditionalExtensions: true, 37 enabled: true,
51 allowAudioFiles: true, 38 allowAdditionalExtensions: true,
52 hls: { enabled: true }, 39 allowAudioFiles: true,
53 webtorrent: { enabled: true }, 40 hls: { enabled: true },
54 resolutions: { 41 webtorrent: { enabled: true },
55 '0p': false, 42 resolutions: {
56 '240p': true, 43 '0p': false,
57 '360p': true, 44 '240p': true,
58 '480p': true, 45 '360p': true,
59 '720p': true, 46 '480p': true,
60 '1080p': true, 47 '720p': true,
61 '1440p': true, 48 '1080p': true,
62 '2160p': true 49 '1440p': true,
50 '2160p': true
51 }
63 } 52 }
64 } 53 }
65 }) 54 })
66} 55}
67 56
68describe('Test video transcoding', function () { 57describe('Test video transcoding', function () {
69 let servers: ServerInfo[] = [] 58 let servers: PeerTubeServer[] = []
70 let video4k: string 59 let video4k: string
71 60
72 before(async function () { 61 before(async function () {
73 this.timeout(30_000) 62 this.timeout(30_000)
74 63
75 // Run servers 64 // Run servers
76 servers = await flushAndRunMultipleServers(2) 65 servers = await createMultipleServers(2)
77 66
78 await setAccessTokensToServers(servers) 67 await setAccessTokensToServers(servers)
79 68
@@ -87,21 +76,20 @@ describe('Test video transcoding', function () {
87 it('Should not transcode video on server 1', async function () { 76 it('Should not transcode video on server 1', async function () {
88 this.timeout(60_000) 77 this.timeout(60_000)
89 78
90 const videoAttributes = { 79 const attributes = {
91 name: 'my super name for server 1', 80 name: 'my super name for server 1',
92 description: 'my super description for server 1', 81 description: 'my super description for server 1',
93 fixture: 'video_short.webm' 82 fixture: 'video_short.webm'
94 } 83 }
95 await uploadVideo(servers[0].url, servers[0].accessToken, videoAttributes) 84 await servers[0].videos.upload({ attributes })
96 85
97 await waitJobs(servers) 86 await waitJobs(servers)
98 87
99 for (const server of servers) { 88 for (const server of servers) {
100 const res = await getVideosList(server.url) 89 const { data } = await server.videos.list()
101 const video = res.body.data[0] 90 const video = data[0]
102 91
103 const res2 = await getVideo(server.url, video.id) 92 const videoDetails = await server.videos.get({ id: video.id })
104 const videoDetails = res2.body
105 expect(videoDetails.files).to.have.lengthOf(1) 93 expect(videoDetails.files).to.have.lengthOf(1)
106 94
107 const magnetUri = videoDetails.files[0].magnetUri 95 const magnetUri = videoDetails.files[0].magnetUri
@@ -117,21 +105,20 @@ describe('Test video transcoding', function () {
117 it('Should transcode video on server 2', async function () { 105 it('Should transcode video on server 2', async function () {
118 this.timeout(120_000) 106 this.timeout(120_000)
119 107
120 const videoAttributes = { 108 const attributes = {
121 name: 'my super name for server 2', 109 name: 'my super name for server 2',
122 description: 'my super description for server 2', 110 description: 'my super description for server 2',
123 fixture: 'video_short.webm' 111 fixture: 'video_short.webm'
124 } 112 }
125 await uploadVideo(servers[1].url, servers[1].accessToken, videoAttributes) 113 await servers[1].videos.upload({ attributes })
126 114
127 await waitJobs(servers) 115 await waitJobs(servers)
128 116
129 for (const server of servers) { 117 for (const server of servers) {
130 const res = await getVideosList(server.url) 118 const { data } = await server.videos.list()
131 119
132 const video = res.body.data.find(v => v.name === videoAttributes.name) 120 const video = data.find(v => v.name === attributes.name)
133 const res2 = await getVideo(server.url, video.id) 121 const videoDetails = await server.videos.get({ id: video.id })
134 const videoDetails = res2.body
135 122
136 expect(videoDetails.files).to.have.lengthOf(4) 123 expect(videoDetails.files).to.have.lengthOf(4)
137 124
@@ -150,47 +137,50 @@ describe('Test video transcoding', function () {
150 137
151 { 138 {
152 // Upload the video, but wait transcoding 139 // Upload the video, but wait transcoding
153 const videoAttributes = { 140 const attributes = {
154 name: 'waiting video', 141 name: 'waiting video',
155 fixture: 'video_short1.webm', 142 fixture: 'video_short1.webm',
156 waitTranscoding: true 143 waitTranscoding: true
157 } 144 }
158 const resVideo = await uploadVideo(servers[1].url, servers[1].accessToken, videoAttributes) 145 const { uuid } = await servers[1].videos.upload({ attributes })
159 const videoId = resVideo.body.video.uuid 146 const videoId = uuid
160 147
161 // Should be in transcode state 148 // Should be in transcode state
162 const { body } = await getVideo(servers[1].url, videoId) 149 const body = await servers[1].videos.get({ id: videoId })
163 expect(body.name).to.equal('waiting video') 150 expect(body.name).to.equal('waiting video')
164 expect(body.state.id).to.equal(VideoState.TO_TRANSCODE) 151 expect(body.state.id).to.equal(VideoState.TO_TRANSCODE)
165 expect(body.state.label).to.equal('To transcode') 152 expect(body.state.label).to.equal('To transcode')
166 expect(body.waitTranscoding).to.be.true 153 expect(body.waitTranscoding).to.be.true
167 154
168 // Should have my video 155 {
169 const resMyVideos = await getMyVideos(servers[1].url, servers[1].accessToken, 0, 10) 156 // Should have my video
170 const videoToFindInMine = resMyVideos.body.data.find(v => v.name === videoAttributes.name) 157 const { data } = await servers[1].videos.listMyVideos()
171 expect(videoToFindInMine).not.to.be.undefined 158 const videoToFindInMine = data.find(v => v.name === attributes.name)
172 expect(videoToFindInMine.state.id).to.equal(VideoState.TO_TRANSCODE) 159 expect(videoToFindInMine).not.to.be.undefined
173 expect(videoToFindInMine.state.label).to.equal('To transcode') 160 expect(videoToFindInMine.state.id).to.equal(VideoState.TO_TRANSCODE)
174 expect(videoToFindInMine.waitTranscoding).to.be.true 161 expect(videoToFindInMine.state.label).to.equal('To transcode')
162 expect(videoToFindInMine.waitTranscoding).to.be.true
163 }
175 164
176 // Should not list this video 165 {
177 const resVideos = await getVideosList(servers[1].url) 166 // Should not list this video
178 const videoToFindInList = resVideos.body.data.find(v => v.name === videoAttributes.name) 167 const { data } = await servers[1].videos.list()
179 expect(videoToFindInList).to.be.undefined 168 const videoToFindInList = data.find(v => v.name === attributes.name)
169 expect(videoToFindInList).to.be.undefined
170 }
180 171
181 // Server 1 should not have the video yet 172 // Server 1 should not have the video yet
182 await getVideo(servers[0].url, videoId, HttpStatusCode.NOT_FOUND_404) 173 await servers[0].videos.get({ id: videoId, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
183 } 174 }
184 175
185 await waitJobs(servers) 176 await waitJobs(servers)
186 177
187 for (const server of servers) { 178 for (const server of servers) {
188 const res = await getVideosList(server.url) 179 const { data } = await server.videos.list()
189 const videoToFind = res.body.data.find(v => v.name === 'waiting video') 180 const videoToFind = data.find(v => v.name === 'waiting video')
190 expect(videoToFind).not.to.be.undefined 181 expect(videoToFind).not.to.be.undefined
191 182
192 const res2 = await getVideo(server.url, videoToFind.id) 183 const videoDetails = await server.videos.get({ id: videoToFind.id })
193 const videoDetails: VideoDetails = res2.body
194 184
195 expect(videoDetails.state.id).to.equal(VideoState.PUBLISHED) 185 expect(videoDetails.state.id).to.equal(VideoState.PUBLISHED)
196 expect(videoDetails.state.label).to.equal('Published') 186 expect(videoDetails.state.label).to.equal('Published')
@@ -211,22 +201,20 @@ describe('Test video transcoding', function () {
211 } 201 }
212 202
213 for (const fixture of [ 'video_short.mkv', 'video_short.avi' ]) { 203 for (const fixture of [ 'video_short.mkv', 'video_short.avi' ]) {
214 const videoAttributes = { 204 const attributes = {
215 name: fixture, 205 name: fixture,
216 fixture 206 fixture
217 } 207 }
218 208
219 await uploadVideo(servers[1].url, servers[1].accessToken, videoAttributes) 209 await servers[1].videos.upload({ attributes })
220 210
221 await waitJobs(servers) 211 await waitJobs(servers)
222 212
223 for (const server of servers) { 213 for (const server of servers) {
224 const res = await getVideosList(server.url) 214 const { data } = await server.videos.list()
225
226 const video = res.body.data.find(v => v.name === videoAttributes.name)
227 const res2 = await getVideo(server.url, video.id)
228 const videoDetails = res2.body
229 215
216 const video = data.find(v => v.name === attributes.name)
217 const videoDetails = await server.videos.get({ id: video.id })
230 expect(videoDetails.files).to.have.lengthOf(4) 218 expect(videoDetails.files).to.have.lengthOf(4)
231 219
232 const magnetUri = videoDetails.files[0].magnetUri 220 const magnetUri = videoDetails.files[0].magnetUri
@@ -238,22 +226,20 @@ describe('Test video transcoding', function () {
238 it('Should transcode a 4k video', async function () { 226 it('Should transcode a 4k video', async function () {
239 this.timeout(200_000) 227 this.timeout(200_000)
240 228
241 const videoAttributes = { 229 const attributes = {
242 name: '4k video', 230 name: '4k video',
243 fixture: 'video_short_4k.mp4' 231 fixture: 'video_short_4k.mp4'
244 } 232 }
245 233
246 const resUpload = await uploadVideo(servers[1].url, servers[1].accessToken, videoAttributes) 234 const { uuid } = await servers[1].videos.upload({ attributes })
247 video4k = resUpload.body.video.uuid 235 video4k = uuid
248 236
249 await waitJobs(servers) 237 await waitJobs(servers)
250 238
251 const resolutions = [ 240, 360, 480, 720, 1080, 1440, 2160 ] 239 const resolutions = [ 240, 360, 480, 720, 1080, 1440, 2160 ]
252 240
253 for (const server of servers) { 241 for (const server of servers) {
254 const res = await getVideo(server.url, video4k) 242 const videoDetails = await server.videos.get({ id: video4k })
255 const videoDetails: VideoDetails = res.body
256
257 expect(videoDetails.files).to.have.lengthOf(resolutions.length) 243 expect(videoDetails.files).to.have.lengthOf(resolutions.length)
258 244
259 for (const r of resolutions) { 245 for (const r of resolutions) {
@@ -269,24 +255,23 @@ describe('Test video transcoding', function () {
269 it('Should transcode high bit rate mp3 to proper bit rate', async function () { 255 it('Should transcode high bit rate mp3 to proper bit rate', async function () {
270 this.timeout(60_000) 256 this.timeout(60_000)
271 257
272 const videoAttributes = { 258 const attributes = {
273 name: 'mp3_256k', 259 name: 'mp3_256k',
274 fixture: 'video_short_mp3_256k.mp4' 260 fixture: 'video_short_mp3_256k.mp4'
275 } 261 }
276 await uploadVideo(servers[1].url, servers[1].accessToken, videoAttributes) 262 await servers[1].videos.upload({ attributes })
277 263
278 await waitJobs(servers) 264 await waitJobs(servers)
279 265
280 for (const server of servers) { 266 for (const server of servers) {
281 const res = await getVideosList(server.url) 267 const { data } = await server.videos.list()
282 268
283 const video = res.body.data.find(v => v.name === videoAttributes.name) 269 const video = data.find(v => v.name === attributes.name)
284 const res2 = await getVideo(server.url, video.id) 270 const videoDetails = await server.videos.get({ id: video.id })
285 const videoDetails: VideoDetails = res2.body
286 271
287 expect(videoDetails.files).to.have.lengthOf(4) 272 expect(videoDetails.files).to.have.lengthOf(4)
288 273
289 const path = buildServerDirectory(servers[1], join('videos', video.uuid + '-240.mp4')) 274 const path = servers[1].servers.buildDirectory(join('videos', video.uuid + '-240.mp4'))
290 const probe = await getAudioStream(path) 275 const probe = await getAudioStream(path)
291 276
292 if (probe.audioStream) { 277 if (probe.audioStream) {
@@ -301,23 +286,22 @@ describe('Test video transcoding', function () {
301 it('Should transcode video with no audio and have no audio itself', async function () { 286 it('Should transcode video with no audio and have no audio itself', async function () {
302 this.timeout(60_000) 287 this.timeout(60_000)
303 288
304 const videoAttributes = { 289 const attributes = {
305 name: 'no_audio', 290 name: 'no_audio',
306 fixture: 'video_short_no_audio.mp4' 291 fixture: 'video_short_no_audio.mp4'
307 } 292 }
308 await uploadVideo(servers[1].url, servers[1].accessToken, videoAttributes) 293 await servers[1].videos.upload({ attributes })
309 294
310 await waitJobs(servers) 295 await waitJobs(servers)
311 296
312 for (const server of servers) { 297 for (const server of servers) {
313 const res = await getVideosList(server.url) 298 const { data } = await server.videos.list()
314 299
315 const video = res.body.data.find(v => v.name === videoAttributes.name) 300 const video = data.find(v => v.name === attributes.name)
316 const res2 = await getVideo(server.url, video.id) 301 const videoDetails = await server.videos.get({ id: video.id })
317 const videoDetails: VideoDetails = res2.body
318 302
319 expect(videoDetails.files).to.have.lengthOf(4) 303 expect(videoDetails.files).to.have.lengthOf(4)
320 const path = buildServerDirectory(servers[1], join('videos', video.uuid + '-240.mp4')) 304 const path = servers[1].servers.buildDirectory(join('videos', video.uuid + '-240.mp4'))
321 const probe = await getAudioStream(path) 305 const probe = await getAudioStream(path)
322 expect(probe).to.not.have.property('audioStream') 306 expect(probe).to.not.have.property('audioStream')
323 } 307 }
@@ -326,26 +310,25 @@ describe('Test video transcoding', function () {
326 it('Should leave the audio untouched, but properly transcode the video', async function () { 310 it('Should leave the audio untouched, but properly transcode the video', async function () {
327 this.timeout(60_000) 311 this.timeout(60_000)
328 312
329 const videoAttributes = { 313 const attributes = {
330 name: 'untouched_audio', 314 name: 'untouched_audio',
331 fixture: 'video_short.mp4' 315 fixture: 'video_short.mp4'
332 } 316 }
333 await uploadVideo(servers[1].url, servers[1].accessToken, videoAttributes) 317 await servers[1].videos.upload({ attributes })
334 318
335 await waitJobs(servers) 319 await waitJobs(servers)
336 320
337 for (const server of servers) { 321 for (const server of servers) {
338 const res = await getVideosList(server.url) 322 const { data } = await server.videos.list()
339 323
340 const video = res.body.data.find(v => v.name === videoAttributes.name) 324 const video = data.find(v => v.name === attributes.name)
341 const res2 = await getVideo(server.url, video.id) 325 const videoDetails = await server.videos.get({ id: video.id })
342 const videoDetails: VideoDetails = res2.body
343 326
344 expect(videoDetails.files).to.have.lengthOf(4) 327 expect(videoDetails.files).to.have.lengthOf(4)
345 328
346 const fixturePath = buildAbsoluteFixturePath(videoAttributes.fixture) 329 const fixturePath = buildAbsoluteFixturePath(attributes.fixture)
347 const fixtureVideoProbe = await getAudioStream(fixturePath) 330 const fixtureVideoProbe = await getAudioStream(fixturePath)
348 const path = buildServerDirectory(servers[1], join('videos', video.uuid + '-240.mp4')) 331 const path = servers[1].servers.buildDirectory(join('videos', video.uuid + '-240.mp4'))
349 332
350 const videoProbe = await getAudioStream(path) 333 const videoProbe = await getAudioStream(path)
351 334
@@ -364,19 +347,21 @@ describe('Test video transcoding', function () {
364 function runSuite (mode: 'legacy' | 'resumable') { 347 function runSuite (mode: 'legacy' | 'resumable') {
365 348
366 before(async function () { 349 before(async function () {
367 await updateCustomSubConfig(servers[1].url, servers[1].accessToken, { 350 await servers[1].config.updateCustomSubConfig({
368 transcoding: { 351 newConfig: {
369 hls: { enabled: true }, 352 transcoding: {
370 webtorrent: { enabled: true }, 353 hls: { enabled: true },
371 resolutions: { 354 webtorrent: { enabled: true },
372 '0p': false, 355 resolutions: {
373 '240p': false, 356 '0p': false,
374 '360p': false, 357 '240p': false,
375 '480p': false, 358 '360p': false,
376 '720p': false, 359 '480p': false,
377 '1080p': false, 360 '720p': false,
378 '1440p': false, 361 '1080p': false,
379 '2160p': false 362 '1440p': false,
363 '2160p': false
364 }
380 } 365 }
381 } 366 }
382 }) 367 })
@@ -385,22 +370,21 @@ describe('Test video transcoding', function () {
385 it('Should merge an audio file with the preview file', async function () { 370 it('Should merge an audio file with the preview file', async function () {
386 this.timeout(60_000) 371 this.timeout(60_000)
387 372
388 const videoAttributesArg = { name: 'audio_with_preview', previewfile: 'preview.jpg', fixture: 'sample.ogg' } 373 const attributes = { name: 'audio_with_preview', previewfile: 'preview.jpg', fixture: 'sample.ogg' }
389 await uploadVideo(servers[1].url, servers[1].accessToken, videoAttributesArg, HttpStatusCode.OK_200, mode) 374 await servers[1].videos.upload({ attributes, mode })
390 375
391 await waitJobs(servers) 376 await waitJobs(servers)
392 377
393 for (const server of servers) { 378 for (const server of servers) {
394 const res = await getVideosList(server.url) 379 const { data } = await server.videos.list()
395 380
396 const video = res.body.data.find(v => v.name === 'audio_with_preview') 381 const video = data.find(v => v.name === 'audio_with_preview')
397 const res2 = await getVideo(server.url, video.id) 382 const videoDetails = await server.videos.get({ id: video.id })
398 const videoDetails: VideoDetails = res2.body
399 383
400 expect(videoDetails.files).to.have.lengthOf(1) 384 expect(videoDetails.files).to.have.lengthOf(1)
401 385
402 await makeGetRequest({ url: server.url, path: videoDetails.thumbnailPath, statusCodeExpected: HttpStatusCode.OK_200 }) 386 await makeGetRequest({ url: server.url, path: videoDetails.thumbnailPath, expectedStatus: HttpStatusCode.OK_200 })
403 await makeGetRequest({ url: server.url, path: videoDetails.previewPath, statusCodeExpected: HttpStatusCode.OK_200 }) 387 await makeGetRequest({ url: server.url, path: videoDetails.previewPath, expectedStatus: HttpStatusCode.OK_200 })
404 388
405 const magnetUri = videoDetails.files[0].magnetUri 389 const magnetUri = videoDetails.files[0].magnetUri
406 expect(magnetUri).to.contain('.mp4') 390 expect(magnetUri).to.contain('.mp4')
@@ -410,22 +394,21 @@ describe('Test video transcoding', function () {
410 it('Should upload an audio file and choose a default background image', async function () { 394 it('Should upload an audio file and choose a default background image', async function () {
411 this.timeout(60_000) 395 this.timeout(60_000)
412 396
413 const videoAttributesArg = { name: 'audio_without_preview', fixture: 'sample.ogg' } 397 const attributes = { name: 'audio_without_preview', fixture: 'sample.ogg' }
414 await uploadVideo(servers[1].url, servers[1].accessToken, videoAttributesArg, HttpStatusCode.OK_200, mode) 398 await servers[1].videos.upload({ attributes, mode })
415 399
416 await waitJobs(servers) 400 await waitJobs(servers)
417 401
418 for (const server of servers) { 402 for (const server of servers) {
419 const res = await getVideosList(server.url) 403 const { data } = await server.videos.list()
420 404
421 const video = res.body.data.find(v => v.name === 'audio_without_preview') 405 const video = data.find(v => v.name === 'audio_without_preview')
422 const res2 = await getVideo(server.url, video.id) 406 const videoDetails = await server.videos.get({ id: video.id })
423 const videoDetails = res2.body
424 407
425 expect(videoDetails.files).to.have.lengthOf(1) 408 expect(videoDetails.files).to.have.lengthOf(1)
426 409
427 await makeGetRequest({ url: server.url, path: videoDetails.thumbnailPath, statusCodeExpected: HttpStatusCode.OK_200 }) 410 await makeGetRequest({ url: server.url, path: videoDetails.thumbnailPath, expectedStatus: HttpStatusCode.OK_200 })
428 await makeGetRequest({ url: server.url, path: videoDetails.previewPath, statusCodeExpected: HttpStatusCode.OK_200 }) 411 await makeGetRequest({ url: server.url, path: videoDetails.previewPath, expectedStatus: HttpStatusCode.OK_200 })
429 412
430 const magnetUri = videoDetails.files[0].magnetUri 413 const magnetUri = videoDetails.files[0].magnetUri
431 expect(magnetUri).to.contain('.mp4') 414 expect(magnetUri).to.contain('.mp4')
@@ -435,26 +418,27 @@ describe('Test video transcoding', function () {
435 it('Should upload an audio file and create an audio version only', async function () { 418 it('Should upload an audio file and create an audio version only', async function () {
436 this.timeout(60_000) 419 this.timeout(60_000)
437 420
438 await updateCustomSubConfig(servers[1].url, servers[1].accessToken, { 421 await servers[1].config.updateCustomSubConfig({
439 transcoding: { 422 newConfig: {
440 hls: { enabled: true }, 423 transcoding: {
441 webtorrent: { enabled: true }, 424 hls: { enabled: true },
442 resolutions: { 425 webtorrent: { enabled: true },
443 '0p': true, 426 resolutions: {
444 '240p': false, 427 '0p': true,
445 '360p': false 428 '240p': false,
429 '360p': false
430 }
446 } 431 }
447 } 432 }
448 }) 433 })
449 434
450 const videoAttributesArg = { name: 'audio_with_preview', previewfile: 'preview.jpg', fixture: 'sample.ogg' } 435 const attributes = { name: 'audio_with_preview', previewfile: 'preview.jpg', fixture: 'sample.ogg' }
451 const resVideo = await uploadVideo(servers[1].url, servers[1].accessToken, videoAttributesArg, HttpStatusCode.OK_200, mode) 436 const { id } = await servers[1].videos.upload({ attributes, mode })
452 437
453 await waitJobs(servers) 438 await waitJobs(servers)
454 439
455 for (const server of servers) { 440 for (const server of servers) {
456 const res2 = await getVideo(server.url, resVideo.body.video.id) 441 const videoDetails = await server.videos.get({ id })
457 const videoDetails: VideoDetails = res2.body
458 442
459 for (const files of [ videoDetails.files, videoDetails.streamingPlaylists[0].files ]) { 443 for (const files of [ videoDetails.files, videoDetails.streamingPlaylists[0].files ]) {
460 expect(files).to.have.lengthOf(2) 444 expect(files).to.have.lengthOf(2)
@@ -480,21 +464,20 @@ describe('Test video transcoding', function () {
480 it('Should transcode a 60 FPS video', async function () { 464 it('Should transcode a 60 FPS video', async function () {
481 this.timeout(60_000) 465 this.timeout(60_000)
482 466
483 const videoAttributes = { 467 const attributes = {
484 name: 'my super 30fps name for server 2', 468 name: 'my super 30fps name for server 2',
485 description: 'my super 30fps description for server 2', 469 description: 'my super 30fps description for server 2',
486 fixture: '60fps_720p_small.mp4' 470 fixture: '60fps_720p_small.mp4'
487 } 471 }
488 await uploadVideo(servers[1].url, servers[1].accessToken, videoAttributes) 472 await servers[1].videos.upload({ attributes })
489 473
490 await waitJobs(servers) 474 await waitJobs(servers)
491 475
492 for (const server of servers) { 476 for (const server of servers) {
493 const res = await getVideosList(server.url) 477 const { data } = await server.videos.list()
494 478
495 const video = res.body.data.find(v => v.name === videoAttributes.name) 479 const video = data.find(v => v.name === attributes.name)
496 const res2 = await getVideo(server.url, video.id) 480 const videoDetails = await server.videos.get({ id: video.id })
497 const videoDetails: VideoDetails = res2.body
498 481
499 expect(videoDetails.files).to.have.lengthOf(4) 482 expect(videoDetails.files).to.have.lengthOf(4)
500 expect(videoDetails.files[0].fps).to.be.above(58).and.below(62) 483 expect(videoDetails.files[0].fps).to.be.above(58).and.below(62)
@@ -503,13 +486,13 @@ describe('Test video transcoding', function () {
503 expect(videoDetails.files[3].fps).to.be.below(31) 486 expect(videoDetails.files[3].fps).to.be.below(31)
504 487
505 for (const resolution of [ '240', '360', '480' ]) { 488 for (const resolution of [ '240', '360', '480' ]) {
506 const path = buildServerDirectory(servers[1], join('videos', video.uuid + '-' + resolution + '.mp4')) 489 const path = servers[1].servers.buildDirectory(join('videos', video.uuid + '-' + resolution + '.mp4'))
507 const fps = await getVideoFileFPS(path) 490 const fps = await getVideoFileFPS(path)
508 491
509 expect(fps).to.be.below(31) 492 expect(fps).to.be.below(31)
510 } 493 }
511 494
512 const path = buildServerDirectory(servers[1], join('videos', video.uuid + '-720.mp4')) 495 const path = servers[1].servers.buildDirectory(join('videos', video.uuid + '-720.mp4'))
513 const fps = await getVideoFileFPS(path) 496 const fps = await getVideoFileFPS(path)
514 497
515 expect(fps).to.be.above(58).and.below(62) 498 expect(fps).to.be.above(58).and.below(62)
@@ -528,29 +511,29 @@ describe('Test video transcoding', function () {
528 expect(fps).to.be.equal(59) 511 expect(fps).to.be.equal(59)
529 } 512 }
530 513
531 const videoAttributes = { 514 const attributes = {
532 name: '59fps video', 515 name: '59fps video',
533 description: '59fps video', 516 description: '59fps video',
534 fixture: tempFixturePath 517 fixture: tempFixturePath
535 } 518 }
536 519
537 await uploadVideo(servers[1].url, servers[1].accessToken, videoAttributes) 520 await servers[1].videos.upload({ attributes })
538 521
539 await waitJobs(servers) 522 await waitJobs(servers)
540 523
541 for (const server of servers) { 524 for (const server of servers) {
542 const res = await getVideosList(server.url) 525 const { data } = await server.videos.list()
543 526
544 const video = res.body.data.find(v => v.name === videoAttributes.name) 527 const video = data.find(v => v.name === attributes.name)
545 528
546 { 529 {
547 const path = buildServerDirectory(servers[1], join('videos', video.uuid + '-240.mp4')) 530 const path = servers[1].servers.buildDirectory(join('videos', video.uuid + '-240.mp4'))
548 const fps = await getVideoFileFPS(path) 531 const fps = await getVideoFileFPS(path)
549 expect(fps).to.be.equal(25) 532 expect(fps).to.be.equal(25)
550 } 533 }
551 534
552 { 535 {
553 const path = buildServerDirectory(servers[1], join('videos', video.uuid + '-720.mp4')) 536 const path = servers[1].servers.buildDirectory(join('videos', video.uuid + '-720.mp4'))
554 const fps = await getVideoFileFPS(path) 537 const fps = await getVideoFileFPS(path)
555 expect(fps).to.be.equal(59) 538 expect(fps).to.be.equal(59)
556 } 539 }
@@ -571,23 +554,23 @@ describe('Test video transcoding', function () {
571 expect(bitrate).to.be.above(getMaxBitrate(VideoResolution.H_1080P, 25, VIDEO_TRANSCODING_FPS)) 554 expect(bitrate).to.be.above(getMaxBitrate(VideoResolution.H_1080P, 25, VIDEO_TRANSCODING_FPS))
572 } 555 }
573 556
574 const videoAttributes = { 557 const attributes = {
575 name: 'high bitrate video', 558 name: 'high bitrate video',
576 description: 'high bitrate video', 559 description: 'high bitrate video',
577 fixture: tempFixturePath 560 fixture: tempFixturePath
578 } 561 }
579 562
580 await uploadVideo(servers[1].url, servers[1].accessToken, videoAttributes) 563 await servers[1].videos.upload({ attributes })
581 564
582 await waitJobs(servers) 565 await waitJobs(servers)
583 566
584 for (const server of servers) { 567 for (const server of servers) {
585 const res = await getVideosList(server.url) 568 const { data } = await server.videos.list()
586 569
587 const video = res.body.data.find(v => v.name === videoAttributes.name) 570 const video = data.find(v => v.name === attributes.name)
588 571
589 for (const resolution of [ '240', '360', '480', '720', '1080' ]) { 572 for (const resolution of [ '240', '360', '480', '720', '1080' ]) {
590 const path = buildServerDirectory(servers[1], join('videos', video.uuid + '-' + resolution + '.mp4')) 573 const path = servers[1].servers.buildDirectory(join('videos', video.uuid + '-' + resolution + '.mp4'))
591 574
592 const bitrate = await getVideoFileBitrate(path) 575 const bitrate = await getVideoFileBitrate(path)
593 const fps = await getVideoFileFPS(path) 576 const fps = await getVideoFileFPS(path)
@@ -602,7 +585,7 @@ describe('Test video transcoding', function () {
602 it('Should not transcode to an higher bitrate than the original file', async function () { 585 it('Should not transcode to an higher bitrate than the original file', async function () {
603 this.timeout(160_000) 586 this.timeout(160_000)
604 587
605 const config = { 588 const newConfig = {
606 transcoding: { 589 transcoding: {
607 enabled: true, 590 enabled: true,
608 resolutions: { 591 resolutions: {
@@ -618,22 +601,21 @@ describe('Test video transcoding', function () {
618 hls: { enabled: true } 601 hls: { enabled: true }
619 } 602 }
620 } 603 }
621 await updateCustomSubConfig(servers[1].url, servers[1].accessToken, config) 604 await servers[1].config.updateCustomSubConfig({ newConfig })
622 605
623 const videoAttributes = { 606 const attributes = {
624 name: 'low bitrate', 607 name: 'low bitrate',
625 fixture: 'low-bitrate.mp4' 608 fixture: 'low-bitrate.mp4'
626 } 609 }
627 610
628 const resUpload = await uploadVideo(servers[1].url, servers[1].accessToken, videoAttributes) 611 const { uuid } = await servers[1].videos.upload({ attributes })
629 const videoUUID = resUpload.body.video.uuid
630 612
631 await waitJobs(servers) 613 await waitJobs(servers)
632 614
633 const resolutions = [ 240, 360, 480, 720, 1080 ] 615 const resolutions = [ 240, 360, 480, 720, 1080 ]
634 for (const r of resolutions) { 616 for (const r of resolutions) {
635 const path = `videos/${videoUUID}-${r}.mp4` 617 const path = `videos/${uuid}-${r}.mp4`
636 const size = await getServerFileSize(servers[1], path) 618 const size = await servers[1].servers.getServerFileSize(path)
637 expect(size, `${path} not below ${60_000}`).to.be.below(60_000) 619 expect(size, `${path} not below ${60_000}`).to.be.below(60_000)
638 } 620 }
639 }) 621 })
@@ -644,11 +626,11 @@ describe('Test video transcoding', function () {
644 it('Should provide valid ffprobe data', async function () { 626 it('Should provide valid ffprobe data', async function () {
645 this.timeout(160_000) 627 this.timeout(160_000)
646 628
647 const videoUUID = (await uploadVideoAndGetId({ server: servers[1], videoName: 'ffprobe data' })).uuid 629 const videoUUID = (await servers[1].videos.quickUpload({ name: 'ffprobe data' })).uuid
648 await waitJobs(servers) 630 await waitJobs(servers)
649 631
650 { 632 {
651 const path = buildServerDirectory(servers[1], join('videos', videoUUID + '-240.mp4')) 633 const path = servers[1].servers.buildDirectory(join('videos', videoUUID + '-240.mp4'))
652 const metadata = await getMetadataFromFile(path) 634 const metadata = await getMetadataFromFile(path)
653 635
654 // expected format properties 636 // expected format properties
@@ -678,8 +660,7 @@ describe('Test video transcoding', function () {
678 } 660 }
679 661
680 for (const server of servers) { 662 for (const server of servers) {
681 const res2 = await getVideo(server.url, videoUUID) 663 const videoDetails = await server.videos.get({ id: videoUUID })
682 const videoDetails: VideoDetails = res2.body
683 664
684 const videoFiles = videoDetails.files 665 const videoFiles = videoDetails.files
685 .concat(videoDetails.streamingPlaylists[0].files) 666 .concat(videoDetails.streamingPlaylists[0].files)
@@ -691,8 +672,7 @@ describe('Test video transcoding', function () {
691 expect(file.metadataUrl).to.contain(servers[1].url) 672 expect(file.metadataUrl).to.contain(servers[1].url)
692 expect(file.metadataUrl).to.contain(videoUUID) 673 expect(file.metadataUrl).to.contain(videoUUID)
693 674
694 const res3 = await getVideoFileMetadataUrl(file.metadataUrl) 675 const metadata = await server.videos.getFileMetadata({ url: file.metadataUrl })
695 const metadata: FfprobeData = res3.body
696 expect(metadata).to.have.nested.property('format.size') 676 expect(metadata).to.have.nested.property('format.size')
697 } 677 }
698 } 678 }
@@ -709,17 +689,14 @@ describe('Test video transcoding', function () {
709 describe('Transcoding job queue', function () { 689 describe('Transcoding job queue', function () {
710 690
711 it('Should have the appropriate priorities for transcoding jobs', async function () { 691 it('Should have the appropriate priorities for transcoding jobs', async function () {
712 const res = await getJobsListPaginationAndSort({ 692 const body = await servers[1].jobs.getJobsList({
713 url: servers[1].url,
714 accessToken: servers[1].accessToken,
715 start: 0, 693 start: 0,
716 count: 100, 694 count: 100,
717 sort: '-createdAt', 695 sort: '-createdAt',
718 jobType: 'video-transcoding' 696 jobType: 'video-transcoding'
719 }) 697 })
720 698
721 const jobs = res.body.data as Job[] 699 const jobs = body.data
722
723 const transcodingJobs = jobs.filter(j => j.data.videoUUID === video4k) 700 const transcodingJobs = jobs.filter(j => j.data.videoUUID === video4k)
724 701
725 expect(transcodingJobs).to.have.lengthOf(14) 702 expect(transcodingJobs).to.have.lengthOf(14)