]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/tests/api/videos/video-hls.ts
Add hls support on server
[github/Chocobozzz/PeerTube.git] / server / tests / api / videos / video-hls.ts
CommitLineData
09209296
C
1/* tslint:disable:no-unused-expression */
2
3import * as chai from 'chai'
4import 'mocha'
5import {
6 checkDirectoryIsEmpty,
7 checkTmpIsEmpty,
8 doubleFollow,
9 flushAndRunMultipleServers,
10 flushTests,
11 getPlaylist,
12 getSegment,
13 getSegmentSha256,
14 getVideo,
15 killallServers,
16 removeVideo,
17 ServerInfo,
18 setAccessTokensToServers,
19 updateVideo,
20 uploadVideo,
21 waitJobs
22} from '../../../../shared/utils'
23import { VideoDetails } from '../../../../shared/models/videos'
24import { VideoStreamingPlaylistType } from '../../../../shared/models/videos/video-streaming-playlist.type'
25import { sha256 } from '../../../helpers/core-utils'
26import { join } from 'path'
27
28const expect = chai.expect
29
30async function checkHlsPlaylist (servers: ServerInfo[], videoUUID: string) {
31 const resolutions = [ 240, 360, 480, 720 ]
32
33 for (const server of servers) {
34 const res = await getVideo(server.url, videoUUID)
35 const videoDetails: VideoDetails = res.body
36
37 expect(videoDetails.streamingPlaylists).to.have.lengthOf(1)
38
39 const hlsPlaylist = videoDetails.streamingPlaylists.find(p => p.type === VideoStreamingPlaylistType.HLS)
40 expect(hlsPlaylist).to.not.be.undefined
41
42 {
43 const res2 = await getPlaylist(hlsPlaylist.playlistUrl)
44
45 const masterPlaylist = res2.text
46
47 expect(masterPlaylist).to.contain('#EXT-X-STREAM-INF:BANDWIDTH=55472,RESOLUTION=640x360,FRAME-RATE=25')
48
49 for (const resolution of resolutions) {
50 expect(masterPlaylist).to.contain(`${resolution}.m3u8`)
51 }
52 }
53
54 {
55 for (const resolution of resolutions) {
56 const res2 = await getPlaylist(`http://localhost:9001/static/playlists/hls/${videoUUID}/${resolution}.m3u8`)
57
58 const subPlaylist = res2.text
59 expect(subPlaylist).to.contain(resolution + '_000.ts')
60 }
61 }
62
63 {
64 for (const resolution of resolutions) {
65
66 const res2 = await getSegment(`http://localhost:9001/static/playlists/hls/${videoUUID}/${resolution}_000.ts`)
67
68 const resSha = await getSegmentSha256(hlsPlaylist.segmentsSha256Url)
69
70 const sha256Server = resSha.body[ resolution + '_000.ts' ]
71 expect(sha256(res2.body)).to.equal(sha256Server)
72 }
73 }
74 }
75}
76
77describe('Test HLS videos', function () {
78 let servers: ServerInfo[] = []
79 let videoUUID = ''
80
81 before(async function () {
82 this.timeout(120000)
83
84 servers = await flushAndRunMultipleServers(2, { transcoding: { enabled: true, hls: { enabled: true } } })
85
86 // Get the access tokens
87 await setAccessTokensToServers(servers)
88
89 // Server 1 and server 2 follow each other
90 await doubleFollow(servers[0], servers[1])
91 })
92
93 it('Should upload a video and transcode it to HLS', async function () {
94 this.timeout(120000)
95
96 {
97 const res = await uploadVideo(servers[ 0 ].url, servers[ 0 ].accessToken, { name: 'video 1', fixture: 'video_short.webm' })
98 videoUUID = res.body.video.uuid
99 }
100
101 await waitJobs(servers)
102
103 await checkHlsPlaylist(servers, videoUUID)
104 })
105
106 it('Should update the video', async function () {
107 await updateVideo(servers[0].url, servers[0].accessToken, videoUUID, { name: 'video 1 updated' })
108
109 await waitJobs(servers)
110
111 await checkHlsPlaylist(servers, videoUUID)
112 })
113
114 it('Should delete the video', async function () {
115 await removeVideo(servers[0].url, servers[0].accessToken, videoUUID)
116
117 await waitJobs(servers)
118
119 for (const server of servers) {
120 await getVideo(server.url, videoUUID, 404)
121 }
122 })
123
124 it('Should have the playlists/segment deleted from the disk', async function () {
125 for (const server of servers) {
126 await checkDirectoryIsEmpty(server, 'videos')
127 await checkDirectoryIsEmpty(server, join('playlists', 'hls'))
128 }
129 })
130
131 it('Should have an empty tmp directory', async function () {
132 for (const server of servers) {
133 await checkTmpIsEmpty(server)
134 }
135 })
136
137 after(async function () {
138 killallServers(servers)
139
140 // Keep the logs if the test failed
141 if (this['ok']) {
142 await flushTests()
143 }
144 })
145})