diff options
Diffstat (limited to 'server/tests/api/transcoding/video-studio.ts')
-rw-r--r-- | server/tests/api/transcoding/video-studio.ts | 377 |
1 files changed, 0 insertions, 377 deletions
diff --git a/server/tests/api/transcoding/video-studio.ts b/server/tests/api/transcoding/video-studio.ts deleted file mode 100644 index ba68f8e24..000000000 --- a/server/tests/api/transcoding/video-studio.ts +++ /dev/null | |||
@@ -1,377 +0,0 @@ | |||
1 | import { expect } from 'chai' | ||
2 | import { checkPersistentTmpIsEmpty, checkVideoDuration, expectStartWith } from '@server/tests/shared' | ||
3 | import { areMockObjectStorageTestsDisabled, getAllFiles } from '@shared/core-utils' | ||
4 | import { VideoStudioTask } from '@shared/models' | ||
5 | import { | ||
6 | cleanupTests, | ||
7 | createMultipleServers, | ||
8 | doubleFollow, | ||
9 | ObjectStorageCommand, | ||
10 | PeerTubeServer, | ||
11 | setAccessTokensToServers, | ||
12 | setDefaultVideoChannel, | ||
13 | VideoStudioCommand, | ||
14 | waitJobs | ||
15 | } from '@shared/server-commands' | ||
16 | |||
17 | describe('Test video studio', function () { | ||
18 | let servers: PeerTubeServer[] = [] | ||
19 | let videoUUID: string | ||
20 | |||
21 | async function renewVideo (fixture = 'video_short.webm') { | ||
22 | const video = await servers[0].videos.quickUpload({ name: 'video', fixture }) | ||
23 | videoUUID = video.uuid | ||
24 | |||
25 | await waitJobs(servers) | ||
26 | } | ||
27 | |||
28 | async function createTasks (tasks: VideoStudioTask[]) { | ||
29 | await servers[0].videoStudio.createEditionTasks({ videoId: videoUUID, tasks }) | ||
30 | await waitJobs(servers) | ||
31 | } | ||
32 | |||
33 | before(async function () { | ||
34 | this.timeout(120_000) | ||
35 | |||
36 | servers = await createMultipleServers(2) | ||
37 | |||
38 | await setAccessTokensToServers(servers) | ||
39 | await setDefaultVideoChannel(servers) | ||
40 | |||
41 | await doubleFollow(servers[0], servers[1]) | ||
42 | |||
43 | await servers[0].config.enableMinimumTranscoding() | ||
44 | |||
45 | await servers[0].config.enableStudio() | ||
46 | }) | ||
47 | |||
48 | describe('Cutting', function () { | ||
49 | |||
50 | it('Should cut the beginning of the video', async function () { | ||
51 | this.timeout(120_000) | ||
52 | |||
53 | await renewVideo() | ||
54 | await waitJobs(servers) | ||
55 | |||
56 | const beforeTasks = new Date() | ||
57 | |||
58 | await createTasks([ | ||
59 | { | ||
60 | name: 'cut', | ||
61 | options: { | ||
62 | start: 2 | ||
63 | } | ||
64 | } | ||
65 | ]) | ||
66 | |||
67 | for (const server of servers) { | ||
68 | await checkVideoDuration(server, videoUUID, 3) | ||
69 | |||
70 | const video = await server.videos.get({ id: videoUUID }) | ||
71 | expect(new Date(video.publishedAt)).to.be.below(beforeTasks) | ||
72 | } | ||
73 | }) | ||
74 | |||
75 | it('Should cut the end of the video', async function () { | ||
76 | this.timeout(120_000) | ||
77 | await renewVideo() | ||
78 | |||
79 | await createTasks([ | ||
80 | { | ||
81 | name: 'cut', | ||
82 | options: { | ||
83 | end: 2 | ||
84 | } | ||
85 | } | ||
86 | ]) | ||
87 | |||
88 | for (const server of servers) { | ||
89 | await checkVideoDuration(server, videoUUID, 2) | ||
90 | } | ||
91 | }) | ||
92 | |||
93 | it('Should cut start/end of the video', async function () { | ||
94 | this.timeout(120_000) | ||
95 | await renewVideo('video_short1.webm') // 10 seconds video duration | ||
96 | |||
97 | await createTasks([ | ||
98 | { | ||
99 | name: 'cut', | ||
100 | options: { | ||
101 | start: 2, | ||
102 | end: 6 | ||
103 | } | ||
104 | } | ||
105 | ]) | ||
106 | |||
107 | for (const server of servers) { | ||
108 | await checkVideoDuration(server, videoUUID, 4) | ||
109 | } | ||
110 | }) | ||
111 | }) | ||
112 | |||
113 | describe('Intro/Outro', function () { | ||
114 | |||
115 | it('Should add an intro', async function () { | ||
116 | this.timeout(120_000) | ||
117 | await renewVideo() | ||
118 | |||
119 | await createTasks([ | ||
120 | { | ||
121 | name: 'add-intro', | ||
122 | options: { | ||
123 | file: 'video_short.webm' | ||
124 | } | ||
125 | } | ||
126 | ]) | ||
127 | |||
128 | for (const server of servers) { | ||
129 | await checkVideoDuration(server, videoUUID, 10) | ||
130 | } | ||
131 | }) | ||
132 | |||
133 | it('Should add an outro', async function () { | ||
134 | this.timeout(120_000) | ||
135 | await renewVideo() | ||
136 | |||
137 | await createTasks([ | ||
138 | { | ||
139 | name: 'add-outro', | ||
140 | options: { | ||
141 | file: 'video_very_short_240p.mp4' | ||
142 | } | ||
143 | } | ||
144 | ]) | ||
145 | |||
146 | for (const server of servers) { | ||
147 | await checkVideoDuration(server, videoUUID, 7) | ||
148 | } | ||
149 | }) | ||
150 | |||
151 | it('Should add an intro/outro', async function () { | ||
152 | this.timeout(120_000) | ||
153 | await renewVideo() | ||
154 | |||
155 | await createTasks([ | ||
156 | { | ||
157 | name: 'add-intro', | ||
158 | options: { | ||
159 | file: 'video_very_short_240p.mp4' | ||
160 | } | ||
161 | }, | ||
162 | { | ||
163 | name: 'add-outro', | ||
164 | options: { | ||
165 | // Different frame rate | ||
166 | file: 'video_short2.webm' | ||
167 | } | ||
168 | } | ||
169 | ]) | ||
170 | |||
171 | for (const server of servers) { | ||
172 | await checkVideoDuration(server, videoUUID, 12) | ||
173 | } | ||
174 | }) | ||
175 | |||
176 | it('Should add an intro to a video without audio', async function () { | ||
177 | this.timeout(120_000) | ||
178 | await renewVideo('video_short_no_audio.mp4') | ||
179 | |||
180 | await createTasks([ | ||
181 | { | ||
182 | name: 'add-intro', | ||
183 | options: { | ||
184 | file: 'video_very_short_240p.mp4' | ||
185 | } | ||
186 | } | ||
187 | ]) | ||
188 | |||
189 | for (const server of servers) { | ||
190 | await checkVideoDuration(server, videoUUID, 7) | ||
191 | } | ||
192 | }) | ||
193 | |||
194 | it('Should add an outro without audio to a video with audio', async function () { | ||
195 | this.timeout(120_000) | ||
196 | await renewVideo() | ||
197 | |||
198 | await createTasks([ | ||
199 | { | ||
200 | name: 'add-outro', | ||
201 | options: { | ||
202 | file: 'video_short_no_audio.mp4' | ||
203 | } | ||
204 | } | ||
205 | ]) | ||
206 | |||
207 | for (const server of servers) { | ||
208 | await checkVideoDuration(server, videoUUID, 10) | ||
209 | } | ||
210 | }) | ||
211 | |||
212 | it('Should add an outro without audio to a video with audio', async function () { | ||
213 | this.timeout(120_000) | ||
214 | await renewVideo('video_short_no_audio.mp4') | ||
215 | |||
216 | await createTasks([ | ||
217 | { | ||
218 | name: 'add-outro', | ||
219 | options: { | ||
220 | file: 'video_short_no_audio.mp4' | ||
221 | } | ||
222 | } | ||
223 | ]) | ||
224 | |||
225 | for (const server of servers) { | ||
226 | await checkVideoDuration(server, videoUUID, 10) | ||
227 | } | ||
228 | }) | ||
229 | }) | ||
230 | |||
231 | describe('Watermark', function () { | ||
232 | |||
233 | it('Should add a watermark to the video', async function () { | ||
234 | this.timeout(120_000) | ||
235 | await renewVideo() | ||
236 | |||
237 | const video = await servers[0].videos.get({ id: videoUUID }) | ||
238 | const oldFileUrls = getAllFiles(video).map(f => f.fileUrl) | ||
239 | |||
240 | await createTasks([ | ||
241 | { | ||
242 | name: 'add-watermark', | ||
243 | options: { | ||
244 | file: 'custom-thumbnail.png' | ||
245 | } | ||
246 | } | ||
247 | ]) | ||
248 | |||
249 | for (const server of servers) { | ||
250 | const video = await server.videos.get({ id: videoUUID }) | ||
251 | const fileUrls = getAllFiles(video).map(f => f.fileUrl) | ||
252 | |||
253 | for (const oldUrl of oldFileUrls) { | ||
254 | expect(fileUrls).to.not.include(oldUrl) | ||
255 | } | ||
256 | } | ||
257 | }) | ||
258 | }) | ||
259 | |||
260 | describe('Complex tasks', function () { | ||
261 | it('Should run a complex task', async function () { | ||
262 | this.timeout(240_000) | ||
263 | await renewVideo() | ||
264 | |||
265 | await createTasks(VideoStudioCommand.getComplexTask()) | ||
266 | |||
267 | for (const server of servers) { | ||
268 | await checkVideoDuration(server, videoUUID, 9) | ||
269 | } | ||
270 | }) | ||
271 | }) | ||
272 | |||
273 | describe('HLS only studio edition', function () { | ||
274 | |||
275 | before(async function () { | ||
276 | // Disable Web Videos | ||
277 | await servers[0].config.updateExistingSubConfig({ | ||
278 | newConfig: { | ||
279 | transcoding: { | ||
280 | webVideos: { | ||
281 | enabled: false | ||
282 | } | ||
283 | } | ||
284 | } | ||
285 | }) | ||
286 | }) | ||
287 | |||
288 | it('Should run a complex task on HLS only video', async function () { | ||
289 | this.timeout(240_000) | ||
290 | await renewVideo() | ||
291 | |||
292 | await createTasks(VideoStudioCommand.getComplexTask()) | ||
293 | |||
294 | for (const server of servers) { | ||
295 | const video = await server.videos.get({ id: videoUUID }) | ||
296 | expect(video.files).to.have.lengthOf(0) | ||
297 | |||
298 | await checkVideoDuration(server, videoUUID, 9) | ||
299 | } | ||
300 | }) | ||
301 | }) | ||
302 | |||
303 | describe('Server restart', function () { | ||
304 | |||
305 | it('Should still be able to run video edition after a server restart', async function () { | ||
306 | this.timeout(240_000) | ||
307 | |||
308 | await renewVideo() | ||
309 | await servers[0].videoStudio.createEditionTasks({ videoId: videoUUID, tasks: VideoStudioCommand.getComplexTask() }) | ||
310 | |||
311 | await servers[0].kill() | ||
312 | await servers[0].run() | ||
313 | |||
314 | await waitJobs(servers) | ||
315 | |||
316 | for (const server of servers) { | ||
317 | await checkVideoDuration(server, videoUUID, 9) | ||
318 | } | ||
319 | }) | ||
320 | |||
321 | it('Should have an empty persistent tmp directory', async function () { | ||
322 | await checkPersistentTmpIsEmpty(servers[0]) | ||
323 | }) | ||
324 | }) | ||
325 | |||
326 | describe('Object storage studio edition', function () { | ||
327 | if (areMockObjectStorageTestsDisabled()) return | ||
328 | |||
329 | const objectStorage = new ObjectStorageCommand() | ||
330 | |||
331 | before(async function () { | ||
332 | await objectStorage.prepareDefaultMockBuckets() | ||
333 | |||
334 | await servers[0].kill() | ||
335 | await servers[0].run(objectStorage.getDefaultMockConfig()) | ||
336 | |||
337 | await servers[0].config.enableMinimumTranscoding() | ||
338 | }) | ||
339 | |||
340 | it('Should run a complex task on a video in object storage', async function () { | ||
341 | this.timeout(240_000) | ||
342 | await renewVideo() | ||
343 | |||
344 | const video = await servers[0].videos.get({ id: videoUUID }) | ||
345 | const oldFileUrls = getAllFiles(video).map(f => f.fileUrl) | ||
346 | |||
347 | await createTasks(VideoStudioCommand.getComplexTask()) | ||
348 | |||
349 | for (const server of servers) { | ||
350 | const video = await server.videos.get({ id: videoUUID }) | ||
351 | const files = getAllFiles(video) | ||
352 | |||
353 | for (const f of files) { | ||
354 | expect(oldFileUrls).to.not.include(f.fileUrl) | ||
355 | } | ||
356 | |||
357 | for (const webVideoFile of video.files) { | ||
358 | expectStartWith(webVideoFile.fileUrl, objectStorage.getMockWebVideosBaseUrl()) | ||
359 | } | ||
360 | |||
361 | for (const hlsFile of video.streamingPlaylists[0].files) { | ||
362 | expectStartWith(hlsFile.fileUrl, objectStorage.getMockPlaylistBaseUrl()) | ||
363 | } | ||
364 | |||
365 | await checkVideoDuration(server, videoUUID, 9) | ||
366 | } | ||
367 | }) | ||
368 | |||
369 | after(async function () { | ||
370 | await objectStorage.cleanupMock() | ||
371 | }) | ||
372 | }) | ||
373 | |||
374 | after(async function () { | ||
375 | await cleanupTests(servers) | ||
376 | }) | ||
377 | }) | ||