]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/tests/api/videos/video-imports.ts
stricter youtubedl format selectors (#3516)
[github/Chocobozzz/PeerTube.git] / server / tests / api / videos / video-imports.ts
1 /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
3 import 'mocha'
4 import * as chai from 'chai'
5 import {
6 cleanupTests,
7 doubleFollow,
8 flushAndRunMultipleServers,
9 getMyUserInformation,
10 getMyVideos,
11 getVideo,
12 getVideosList,
13 immutableAssign,
14 listVideoCaptions,
15 ServerInfo,
16 setAccessTokensToServers,
17 testCaptionFile,
18 updateCustomSubConfig
19 } from '../../../../shared/extra-utils'
20 import { areHttpImportTestsDisabled, testImage } from '../../../../shared/extra-utils/miscs/miscs'
21 import { waitJobs } from '../../../../shared/extra-utils/server/jobs'
22 import {
23 getMagnetURI,
24 getMyVideoImports,
25 getYoutubeHDRVideoUrl,
26 getYoutubeVideoUrl,
27 importVideo
28 } from '../../../../shared/extra-utils/videos/video-imports'
29 import { VideoCaption, VideoDetails, VideoImport, VideoPrivacy, VideoResolution } from '../../../../shared/models/videos'
30
31 const expect = chai.expect
32
33 describe('Test video imports', function () {
34 let servers: ServerInfo[] = []
35 let channelIdServer1: number
36 let channelIdServer2: number
37
38 if (areHttpImportTestsDisabled()) return
39
40 async function checkVideosServer1 (url: string, idHttp: string, idMagnet: string, idTorrent: string) {
41 const resHttp = await getVideo(url, idHttp)
42 const videoHttp: VideoDetails = resHttp.body
43
44 expect(videoHttp.name).to.equal('small video - youtube')
45 // FIXME: youtube-dl seems broken
46 // expect(videoHttp.category.label).to.equal('News & Politics')
47 // expect(videoHttp.licence.label).to.equal('Attribution')
48 expect(videoHttp.language.label).to.equal('Unknown')
49 expect(videoHttp.nsfw).to.be.false
50 expect(videoHttp.description).to.equal('this is a super description')
51 expect(videoHttp.tags).to.deep.equal([ 'tag1', 'tag2' ])
52 expect(videoHttp.files).to.have.lengthOf(1)
53
54 const originallyPublishedAt = new Date(videoHttp.originallyPublishedAt)
55 expect(originallyPublishedAt.getDate()).to.equal(14)
56 expect(originallyPublishedAt.getMonth()).to.equal(0)
57 expect(originallyPublishedAt.getFullYear()).to.equal(2019)
58
59 const resMagnet = await getVideo(url, idMagnet)
60 const videoMagnet: VideoDetails = resMagnet.body
61 const resTorrent = await getVideo(url, idTorrent)
62 const videoTorrent: VideoDetails = resTorrent.body
63
64 for (const video of [ videoMagnet, videoTorrent ]) {
65 expect(video.category.label).to.equal('Misc')
66 expect(video.licence.label).to.equal('Unknown')
67 expect(video.language.label).to.equal('Unknown')
68 expect(video.nsfw).to.be.false
69 expect(video.description).to.equal('this is a super torrent description')
70 expect(video.tags).to.deep.equal([ 'tag_torrent1', 'tag_torrent2' ])
71 expect(video.files).to.have.lengthOf(1)
72 }
73
74 expect(videoTorrent.name).to.contain('你好 世界 720p.mp4')
75 expect(videoMagnet.name).to.contain('super peertube2 video')
76
77 const resCaptions = await listVideoCaptions(url, idHttp)
78 expect(resCaptions.body.total).to.equal(2)
79 }
80
81 async function checkVideoServer2 (url: string, id: number | string) {
82 const res = await getVideo(url, id)
83 const video: VideoDetails = res.body
84
85 expect(video.name).to.equal('my super name')
86 expect(video.category.label).to.equal('Entertainment')
87 expect(video.licence.label).to.equal('Public Domain Dedication')
88 expect(video.language.label).to.equal('English')
89 expect(video.nsfw).to.be.false
90 expect(video.description).to.equal('my super description')
91 expect(video.tags).to.deep.equal([ 'supertag1', 'supertag2' ])
92
93 expect(video.files).to.have.lengthOf(1)
94
95 const resCaptions = await listVideoCaptions(url, id)
96 expect(resCaptions.body.total).to.equal(2)
97 }
98
99 before(async function () {
100 this.timeout(30_000)
101
102 // Run servers
103 servers = await flushAndRunMultipleServers(2)
104
105 await setAccessTokensToServers(servers)
106
107 {
108 const res = await getMyUserInformation(servers[0].url, servers[0].accessToken)
109 channelIdServer1 = res.body.videoChannels[0].id
110 }
111
112 {
113 const res = await getMyUserInformation(servers[1].url, servers[1].accessToken)
114 channelIdServer2 = res.body.videoChannels[0].id
115 }
116
117 await doubleFollow(servers[0], servers[1])
118 })
119
120 it('Should import videos on server 1', async function () {
121 this.timeout(60_000)
122
123 const baseAttributes = {
124 channelId: channelIdServer1,
125 privacy: VideoPrivacy.PUBLIC
126 }
127
128 {
129 const attributes = immutableAssign(baseAttributes, { targetUrl: getYoutubeVideoUrl() })
130 const res = await importVideo(servers[0].url, servers[0].accessToken, attributes)
131 expect(res.body.video.name).to.equal('small video - youtube')
132 expect(res.body.video.thumbnailPath).to.equal(`/static/thumbnails/${res.body.video.uuid}.jpg`)
133 expect(res.body.video.previewPath).to.equal(`/lazy-static/previews/${res.body.video.uuid}.jpg`)
134 await testImage(servers[0].url, 'video_import_thumbnail', res.body.video.thumbnailPath)
135 await testImage(servers[0].url, 'video_import_preview', res.body.video.previewPath)
136
137 const resCaptions = await listVideoCaptions(servers[0].url, res.body.video.id)
138 const videoCaptions: VideoCaption[] = resCaptions.body.data
139 expect(videoCaptions).to.have.lengthOf(2)
140
141 const enCaption = videoCaptions.find(caption => caption.language.id === 'en')
142 expect(enCaption).to.exist
143 expect(enCaption.language.label).to.equal('English')
144 expect(enCaption.captionPath).to.equal(`/lazy-static/video-captions/${res.body.video.uuid}-en.vtt`)
145 await testCaptionFile(servers[0].url, enCaption.captionPath, `WEBVTT
146 Kind: captions
147 Language: en
148
149 00:00:01.600 --> 00:00:04.200
150 English (US)
151
152 00:00:05.900 --> 00:00:07.999
153 This is a subtitle in American English
154
155 00:00:10.000 --> 00:00:14.000
156 Adding subtitles is very easy to do`)
157
158 const frCaption = videoCaptions.find(caption => caption.language.id === 'fr')
159 expect(frCaption).to.exist
160 expect(frCaption.language.label).to.equal('French')
161 expect(frCaption.captionPath).to.equal(`/lazy-static/video-captions/${res.body.video.uuid}-fr.vtt`)
162 await testCaptionFile(servers[0].url, frCaption.captionPath, `WEBVTT
163 Kind: captions
164 Language: fr
165
166 00:00:01.600 --> 00:00:04.200
167 Français (FR)
168
169 00:00:05.900 --> 00:00:07.999
170 C'est un sous-titre français
171
172 00:00:10.000 --> 00:00:14.000
173 Ajouter un sous-titre est vraiment facile`)
174 }
175
176 {
177 const attributes = immutableAssign(baseAttributes, {
178 magnetUri: getMagnetURI(),
179 description: 'this is a super torrent description',
180 tags: [ 'tag_torrent1', 'tag_torrent2' ]
181 })
182 const res = await importVideo(servers[0].url, servers[0].accessToken, attributes)
183 expect(res.body.video.name).to.equal('super peertube2 video')
184 }
185
186 {
187 const attributes = immutableAssign(baseAttributes, {
188 torrentfile: 'video-720p.torrent' as any,
189 description: 'this is a super torrent description',
190 tags: [ 'tag_torrent1', 'tag_torrent2' ]
191 })
192 const res = await importVideo(servers[0].url, servers[0].accessToken, attributes)
193 expect(res.body.video.name).to.equal('你好 世界 720p.mp4')
194 }
195 })
196
197 it('Should list the videos to import in my videos on server 1', async function () {
198 const res = await getMyVideos(servers[0].url, servers[0].accessToken, 0, 5, 'createdAt')
199
200 expect(res.body.total).to.equal(3)
201
202 const videos = res.body.data
203 expect(videos).to.have.lengthOf(3)
204 expect(videos[0].name).to.equal('small video - youtube')
205 expect(videos[1].name).to.equal('super peertube2 video')
206 expect(videos[2].name).to.equal('你好 世界 720p.mp4')
207 })
208
209 it('Should list the videos to import in my imports on server 1', async function () {
210 const res = await getMyVideoImports(servers[0].url, servers[0].accessToken, '-createdAt')
211
212 expect(res.body.total).to.equal(3)
213 const videoImports: VideoImport[] = res.body.data
214 expect(videoImports).to.have.lengthOf(3)
215
216 expect(videoImports[2].targetUrl).to.equal(getYoutubeVideoUrl())
217 expect(videoImports[2].magnetUri).to.be.null
218 expect(videoImports[2].torrentName).to.be.null
219 expect(videoImports[2].video.name).to.equal('small video - youtube')
220
221 expect(videoImports[1].targetUrl).to.be.null
222 expect(videoImports[1].magnetUri).to.equal(getMagnetURI())
223 expect(videoImports[1].torrentName).to.be.null
224 expect(videoImports[1].video.name).to.equal('super peertube2 video')
225
226 expect(videoImports[0].targetUrl).to.be.null
227 expect(videoImports[0].magnetUri).to.be.null
228 expect(videoImports[0].torrentName).to.equal('video-720p.torrent')
229 expect(videoImports[0].video.name).to.equal('你好 世界 720p.mp4')
230 })
231
232 it('Should have the video listed on the two instances', async function () {
233 this.timeout(120_000)
234
235 await waitJobs(servers)
236
237 for (const server of servers) {
238 const res = await getVideosList(server.url)
239 expect(res.body.total).to.equal(3)
240 expect(res.body.data).to.have.lengthOf(3)
241
242 const [ videoHttp, videoMagnet, videoTorrent ] = res.body.data
243 await checkVideosServer1(server.url, videoHttp.uuid, videoMagnet.uuid, videoTorrent.uuid)
244 }
245 })
246
247 it('Should import a video on server 2 with some fields', async function () {
248 this.timeout(60_000)
249
250 const attributes = {
251 targetUrl: getYoutubeVideoUrl(),
252 channelId: channelIdServer2,
253 privacy: VideoPrivacy.PUBLIC,
254 category: 10,
255 licence: 7,
256 language: 'en',
257 name: 'my super name',
258 description: 'my super description',
259 tags: [ 'supertag1', 'supertag2' ]
260 }
261 const res = await importVideo(servers[1].url, servers[1].accessToken, attributes)
262 expect(res.body.video.name).to.equal('my super name')
263 })
264
265 it('Should have the videos listed on the two instances', async function () {
266 this.timeout(120_000)
267
268 await waitJobs(servers)
269
270 for (const server of servers) {
271 const res = await getVideosList(server.url)
272 expect(res.body.total).to.equal(4)
273 expect(res.body.data).to.have.lengthOf(4)
274
275 await checkVideoServer2(server.url, res.body.data[0].uuid)
276
277 const [ , videoHttp, videoMagnet, videoTorrent ] = res.body.data
278 await checkVideosServer1(server.url, videoHttp.uuid, videoMagnet.uuid, videoTorrent.uuid)
279 }
280 })
281
282 it('Should import a video that will be transcoded', async function () {
283 this.timeout(120_000)
284
285 const attributes = {
286 name: 'transcoded video',
287 magnetUri: getMagnetURI(),
288 channelId: channelIdServer2,
289 privacy: VideoPrivacy.PUBLIC
290 }
291 const res = await importVideo(servers[1].url, servers[1].accessToken, attributes)
292 const videoUUID = res.body.video.uuid
293
294 await waitJobs(servers)
295
296 for (const server of servers) {
297 const res = await getVideo(server.url, videoUUID)
298 const video: VideoDetails = res.body
299
300 expect(video.name).to.equal('transcoded video')
301 expect(video.files).to.have.lengthOf(4)
302 }
303 })
304
305 it('Should import no HDR version on a HDR video', async function () {
306 this.timeout(120_000)
307
308 const config = {
309 transcoding: {
310 enabled: true,
311 resolutions: {
312 '240p': false,
313 '360p': false,
314 '480p': false,
315 '720p': false,
316 '1080p': true, // the resulting resolution shouldn't be higher than this, and not vp9.2/av01
317 '1440p': false,
318 '2160p': false
319 },
320 webtorrent: { enabled: true },
321 hls: { enabled: false }
322 },
323 import: {
324 videos: {
325 http: {
326 enabled: true
327 },
328 torrent: {
329 enabled: true
330 }
331 }
332 }
333 }
334 await updateCustomSubConfig(servers[0].url, servers[0].accessToken, config)
335
336 const attributes = {
337 name: 'hdr video',
338 targetUrl: getYoutubeHDRVideoUrl(),
339 channelId: channelIdServer1,
340 privacy: VideoPrivacy.PUBLIC
341 }
342 const res1 = await importVideo(servers[0].url, servers[0].accessToken, attributes)
343 const videoUUID = res1.body.video.uuid
344
345 await waitJobs(servers)
346
347 // test resolution
348 const res2 = await getVideo(servers[0].url, videoUUID)
349 const video: VideoDetails = res2.body
350 expect(video.name).to.equal('hdr video')
351 const maxResolution = Math.max.apply(Math, video.files.map(function (o) { return o.resolution.id }))
352 expect(maxResolution, 'expected max resolution not met').to.equals(VideoResolution.H_1080P)
353 })
354
355 after(async function () {
356 await cleanupTests(servers)
357 })
358 })