aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/tests/api/videos/video-hls.ts
diff options
context:
space:
mode:
Diffstat (limited to 'server/tests/api/videos/video-hls.ts')
-rw-r--r--server/tests/api/videos/video-hls.ts121
1 files changed, 66 insertions, 55 deletions
diff --git a/server/tests/api/videos/video-hls.ts b/server/tests/api/videos/video-hls.ts
index 03ac3f321..961f0e617 100644
--- a/server/tests/api/videos/video-hls.ts
+++ b/server/tests/api/videos/video-hls.ts
@@ -2,38 +2,30 @@
2 2
3import 'mocha' 3import 'mocha'
4import * as chai from 'chai' 4import * as chai from 'chai'
5import { join } from 'path' 5import { basename, join } from 'path'
6import { removeFragmentedMP4Ext, uuidRegex } from '@shared/core-utils'
6import { 7import {
7 checkDirectoryIsEmpty, 8 checkDirectoryIsEmpty,
8 checkResolutionsInMasterPlaylist, 9 checkResolutionsInMasterPlaylist,
9 checkSegmentHash, 10 checkSegmentHash,
10 checkTmpIsEmpty, 11 checkTmpIsEmpty,
11 cleanupTests, 12 cleanupTests,
13 createMultipleServers,
12 doubleFollow, 14 doubleFollow,
13 flushAndRunMultipleServers,
14 getPlaylist,
15 getVideo,
16 makeRawRequest, 15 makeRawRequest,
17 removeVideo, 16 PeerTubeServer,
18 ServerInfo,
19 setAccessTokensToServers, 17 setAccessTokensToServers,
20 updateCustomSubConfig,
21 updateVideo,
22 uploadVideo,
23 waitJobs, 18 waitJobs,
24 webtorrentAdd 19 webtorrentAdd
25} from '../../../../shared/extra-utils' 20} from '@shared/extra-utils'
26import { VideoDetails } from '../../../../shared/models/videos' 21import { HttpStatusCode, VideoStreamingPlaylistType } from '@shared/models'
27import { VideoStreamingPlaylistType } from '../../../../shared/models/videos/video-streaming-playlist.type'
28import { DEFAULT_AUDIO_RESOLUTION } from '../../../initializers/constants' 22import { DEFAULT_AUDIO_RESOLUTION } from '../../../initializers/constants'
29import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
30 23
31const expect = chai.expect 24const expect = chai.expect
32 25
33async function checkHlsPlaylist (servers: ServerInfo[], videoUUID: string, hlsOnly: boolean, resolutions = [ 240, 360, 480, 720 ]) { 26async function checkHlsPlaylist (servers: PeerTubeServer[], videoUUID: string, hlsOnly: boolean, resolutions = [ 240, 360, 480, 720 ]) {
34 for (const server of servers) { 27 for (const server of servers) {
35 const resVideoDetails = await getVideo(server.url, videoUUID) 28 const videoDetails = await server.videos.get({ id: videoUUID })
36 const videoDetails: VideoDetails = resVideoDetails.body
37 const baseUrl = `http://${videoDetails.account.host}` 29 const baseUrl = `http://${videoDetails.account.host}`
38 30
39 expect(videoDetails.streamingPlaylists).to.have.lengthOf(1) 31 expect(videoDetails.streamingPlaylists).to.have.lengthOf(1)
@@ -47,14 +39,17 @@ async function checkHlsPlaylist (servers: ServerInfo[], videoUUID: string, hlsOn
47 if (hlsOnly) expect(videoDetails.files).to.have.lengthOf(0) 39 if (hlsOnly) expect(videoDetails.files).to.have.lengthOf(0)
48 else expect(videoDetails.files).to.have.lengthOf(resolutions.length) 40 else expect(videoDetails.files).to.have.lengthOf(resolutions.length)
49 41
42 // Check JSON files
50 for (const resolution of resolutions) { 43 for (const resolution of resolutions) {
51 const file = hlsFiles.find(f => f.resolution.id === resolution) 44 const file = hlsFiles.find(f => f.resolution.id === resolution)
52 expect(file).to.not.be.undefined 45 expect(file).to.not.be.undefined
53 46
54 expect(file.magnetUri).to.have.lengthOf.above(2) 47 expect(file.magnetUri).to.have.lengthOf.above(2)
55 expect(file.torrentUrl).to.equal(`http://${server.host}/lazy-static/torrents/${videoDetails.uuid}-${file.resolution.id}-hls.torrent`) 48 expect(file.torrentUrl).to.match(
56 expect(file.fileUrl).to.equal( 49 new RegExp(`http://${server.host}/lazy-static/torrents/${uuidRegex}-${file.resolution.id}-hls.torrent`)
57 `${baseUrl}/static/streaming-playlists/hls/${videoDetails.uuid}/${videoDetails.uuid}-${file.resolution.id}-fragmented.mp4` 50 )
51 expect(file.fileUrl).to.match(
52 new RegExp(`${baseUrl}/static/streaming-playlists/hls/${videoDetails.uuid}/${uuidRegex}-${file.resolution.id}-fragmented.mp4`)
58 ) 53 )
59 expect(file.resolution.label).to.equal(resolution + 'p') 54 expect(file.resolution.label).to.equal(resolution + 'p')
60 55
@@ -67,11 +62,11 @@ async function checkHlsPlaylist (servers: ServerInfo[], videoUUID: string, hlsOn
67 expect(torrent.files[0].path).to.exist.and.to.not.equal('') 62 expect(torrent.files[0].path).to.exist.and.to.not.equal('')
68 } 63 }
69 64
65 // Check master playlist
70 { 66 {
71 await checkResolutionsInMasterPlaylist(hlsPlaylist.playlistUrl, resolutions) 67 await checkResolutionsInMasterPlaylist({ server, playlistUrl: hlsPlaylist.playlistUrl, resolutions })
72 68
73 const res = await getPlaylist(hlsPlaylist.playlistUrl) 69 const masterPlaylist = await server.streamingPlaylists.get({ url: hlsPlaylist.playlistUrl })
74 const masterPlaylist = res.text
75 70
76 for (const resolution of resolutions) { 71 for (const resolution of resolutions) {
77 expect(masterPlaylist).to.contain(`${resolution}.m3u8`) 72 expect(masterPlaylist).to.contain(`${resolution}.m3u8`)
@@ -79,12 +74,18 @@ async function checkHlsPlaylist (servers: ServerInfo[], videoUUID: string, hlsOn
79 } 74 }
80 } 75 }
81 76
77 // Check resolution playlists
82 { 78 {
83 for (const resolution of resolutions) { 79 for (const resolution of resolutions) {
84 const res = await getPlaylist(`${baseUrl}/static/streaming-playlists/hls/${videoUUID}/${resolution}.m3u8`) 80 const file = hlsFiles.find(f => f.resolution.id === resolution)
81 const playlistName = removeFragmentedMP4Ext(basename(file.fileUrl)) + '.m3u8'
82
83 const subPlaylist = await server.streamingPlaylists.get({
84 url: `${baseUrl}/static/streaming-playlists/hls/${videoUUID}/${playlistName}`
85 })
85 86
86 const subPlaylist = res.text 87 expect(subPlaylist).to.match(new RegExp(`${uuidRegex}-${resolution}-fragmented.mp4`))
87 expect(subPlaylist).to.contain(`${videoUUID}-${resolution}-fragmented.mp4`) 88 expect(subPlaylist).to.contain(basename(file.fileUrl))
88 } 89 }
89 } 90 }
90 91
@@ -92,23 +93,31 @@ async function checkHlsPlaylist (servers: ServerInfo[], videoUUID: string, hlsOn
92 const baseUrlAndPath = baseUrl + '/static/streaming-playlists/hls' 93 const baseUrlAndPath = baseUrl + '/static/streaming-playlists/hls'
93 94
94 for (const resolution of resolutions) { 95 for (const resolution of resolutions) {
95 await checkSegmentHash(baseUrlAndPath, baseUrlAndPath, videoUUID, resolution, hlsPlaylist) 96 await checkSegmentHash({
97 server,
98 baseUrlPlaylist: baseUrlAndPath,
99 baseUrlSegment: baseUrlAndPath,
100 videoUUID,
101 resolution,
102 hlsPlaylist
103 })
96 } 104 }
97 } 105 }
98 } 106 }
99} 107}
100 108
101describe('Test HLS videos', function () { 109describe('Test HLS videos', function () {
102 let servers: ServerInfo[] = [] 110 let servers: PeerTubeServer[] = []
103 let videoUUID = '' 111 let videoUUID = ''
104 let videoAudioUUID = '' 112 let videoAudioUUID = ''
105 113
106 function runTestSuite (hlsOnly: boolean) { 114 function runTestSuite (hlsOnly: boolean) {
115
107 it('Should upload a video and transcode it to HLS', async function () { 116 it('Should upload a video and transcode it to HLS', async function () {
108 this.timeout(120000) 117 this.timeout(120000)
109 118
110 const res = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'video 1', fixture: 'video_short.webm' }) 119 const { uuid } = await servers[0].videos.upload({ attributes: { name: 'video 1', fixture: 'video_short.webm' } })
111 videoUUID = res.body.video.uuid 120 videoUUID = uuid
112 121
113 await waitJobs(servers) 122 await waitJobs(servers)
114 123
@@ -118,8 +127,8 @@ describe('Test HLS videos', function () {
118 it('Should upload an audio file and transcode it to HLS', async function () { 127 it('Should upload an audio file and transcode it to HLS', async function () {
119 this.timeout(120000) 128 this.timeout(120000)
120 129
121 const res = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'video audio', fixture: 'sample.ogg' }) 130 const { uuid } = await servers[0].videos.upload({ attributes: { name: 'video audio', fixture: 'sample.ogg' } })
122 videoAudioUUID = res.body.video.uuid 131 videoAudioUUID = uuid
123 132
124 await waitJobs(servers) 133 await waitJobs(servers)
125 134
@@ -129,7 +138,7 @@ describe('Test HLS videos', function () {
129 it('Should update the video', async function () { 138 it('Should update the video', async function () {
130 this.timeout(10000) 139 this.timeout(10000)
131 140
132 await updateVideo(servers[0].url, servers[0].accessToken, videoUUID, { name: 'video 1 updated' }) 141 await servers[0].videos.update({ id: videoUUID, attributes: { name: 'video 1 updated' } })
133 142
134 await waitJobs(servers) 143 await waitJobs(servers)
135 144
@@ -139,14 +148,14 @@ describe('Test HLS videos', function () {
139 it('Should delete videos', async function () { 148 it('Should delete videos', async function () {
140 this.timeout(10000) 149 this.timeout(10000)
141 150
142 await removeVideo(servers[0].url, servers[0].accessToken, videoUUID) 151 await servers[0].videos.remove({ id: videoUUID })
143 await removeVideo(servers[0].url, servers[0].accessToken, videoAudioUUID) 152 await servers[0].videos.remove({ id: videoAudioUUID })
144 153
145 await waitJobs(servers) 154 await waitJobs(servers)
146 155
147 for (const server of servers) { 156 for (const server of servers) {
148 await getVideo(server.url, videoUUID, HttpStatusCode.NOT_FOUND_404) 157 await server.videos.get({ id: videoUUID, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
149 await getVideo(server.url, videoAudioUUID, HttpStatusCode.NOT_FOUND_404) 158 await server.videos.get({ id: videoAudioUUID, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
150 } 159 }
151 }) 160 })
152 161
@@ -176,7 +185,7 @@ describe('Test HLS videos', function () {
176 } 185 }
177 } 186 }
178 } 187 }
179 servers = await flushAndRunMultipleServers(2, configOverride) 188 servers = await createMultipleServers(2, configOverride)
180 189
181 // Get the access tokens 190 // Get the access tokens
182 await setAccessTokensToServers(servers) 191 await setAccessTokensToServers(servers)
@@ -192,24 +201,26 @@ describe('Test HLS videos', function () {
192 describe('With only HLS enabled', function () { 201 describe('With only HLS enabled', function () {
193 202
194 before(async function () { 203 before(async function () {
195 await updateCustomSubConfig(servers[0].url, servers[0].accessToken, { 204 await servers[0].config.updateCustomSubConfig({
196 transcoding: { 205 newConfig: {
197 enabled: true, 206 transcoding: {
198 allowAudioFiles: true, 207 enabled: true,
199 resolutions: { 208 allowAudioFiles: true,
200 '240p': true, 209 resolutions: {
201 '360p': true, 210 '240p': true,
202 '480p': true, 211 '360p': true,
203 '720p': true, 212 '480p': true,
204 '1080p': true, 213 '720p': true,
205 '1440p': true, 214 '1080p': true,
206 '2160p': true 215 '1440p': true,
207 }, 216 '2160p': true
208 hls: { 217 },
209 enabled: true 218 hls: {
210 }, 219 enabled: true
211 webtorrent: { 220 },
212 enabled: false 221 webtorrent: {
222 enabled: false
223 }
213 } 224 }
214 } 225 }
215 }) 226 })