]>
Commit | Line | Data |
---|---|---|
57f879a5 | 1 | import { expect } from 'chai' |
83903cb6 | 2 | import { basename } from 'path' |
764b1a14 | 3 | import { removeFragmentedMP4Ext } from '@shared/core-utils' |
f304a158 | 4 | import { sha256 } from '@shared/extra-utils' |
4c7e60bc | 5 | import { HttpStatusCode, VideoStreamingPlaylist } from '@shared/models' |
c55e3d72 | 6 | import { PeerTubeServer } from '@shared/server-commands' |
57f879a5 C |
7 | |
8 | async function checkSegmentHash (options: { | |
254d3579 | 9 | server: PeerTubeServer |
57f879a5 C |
10 | baseUrlPlaylist: string |
11 | baseUrlSegment: string | |
57f879a5 C |
12 | resolution: number |
13 | hlsPlaylist: VideoStreamingPlaylist | |
14 | }) { | |
0305db28 | 15 | const { server, baseUrlPlaylist, baseUrlSegment, resolution, hlsPlaylist } = options |
89d241a7 | 16 | const command = server.streamingPlaylists |
57f879a5 | 17 | |
83903cb6 C |
18 | const file = hlsPlaylist.files.find(f => f.resolution.id === resolution) |
19 | const videoName = basename(file.fileUrl) | |
57f879a5 | 20 | |
0305db28 | 21 | const playlist = await command.get({ url: `${baseUrlPlaylist}/${removeFragmentedMP4Ext(videoName)}.m3u8` }) |
764b1a14 | 22 | |
57f879a5 C |
23 | const matches = /#EXT-X-BYTERANGE:(\d+)@(\d+)/.exec(playlist) |
24 | ||
25 | const length = parseInt(matches[1], 10) | |
26 | const offset = parseInt(matches[2], 10) | |
27 | const range = `${offset}-${offset + length - 1}` | |
28 | ||
29 | const segmentBody = await command.getSegment({ | |
0305db28 | 30 | url: `${baseUrlSegment}/${videoName}`, |
57f879a5 C |
31 | expectedStatus: HttpStatusCode.PARTIAL_CONTENT_206, |
32 | range: `bytes=${range}` | |
33 | }) | |
34 | ||
35 | const shaBody = await command.getSegmentSha256({ url: hlsPlaylist.segmentsSha256Url }) | |
36 | expect(sha256(segmentBody)).to.equal(shaBody[videoName][range]) | |
37 | } | |
38 | ||
39 | async function checkLiveSegmentHash (options: { | |
254d3579 | 40 | server: PeerTubeServer |
57f879a5 C |
41 | baseUrlSegment: string |
42 | videoUUID: string | |
43 | segmentName: string | |
44 | hlsPlaylist: VideoStreamingPlaylist | |
45 | }) { | |
46 | const { server, baseUrlSegment, videoUUID, segmentName, hlsPlaylist } = options | |
89d241a7 | 47 | const command = server.streamingPlaylists |
57f879a5 C |
48 | |
49 | const segmentBody = await command.getSegment({ url: `${baseUrlSegment}/${videoUUID}/${segmentName}` }) | |
50 | const shaBody = await command.getSegmentSha256({ url: hlsPlaylist.segmentsSha256Url }) | |
51 | ||
52 | expect(sha256(segmentBody)).to.equal(shaBody[segmentName]) | |
53 | } | |
54 | ||
55 | async function checkResolutionsInMasterPlaylist (options: { | |
254d3579 | 56 | server: PeerTubeServer |
57f879a5 C |
57 | playlistUrl: string |
58 | resolutions: number[] | |
59 | }) { | |
60 | const { server, playlistUrl, resolutions } = options | |
61 | ||
89d241a7 | 62 | const masterPlaylist = await server.streamingPlaylists.get({ url: playlistUrl }) |
57f879a5 C |
63 | |
64 | for (const resolution of resolutions) { | |
65 | const reg = new RegExp( | |
66 | '#EXT-X-STREAM-INF:BANDWIDTH=\\d+,RESOLUTION=\\d+x' + resolution + ',(FRAME-RATE=\\d+,)?CODECS="avc1.64001f,mp4a.40.2"' | |
67 | ) | |
68 | ||
69 | expect(masterPlaylist).to.match(reg) | |
70 | } | |
84cae54e C |
71 | |
72 | const playlistsLength = masterPlaylist.split('\n').filter(line => line.startsWith('#EXT-X-STREAM-INF:BANDWIDTH=')) | |
73 | expect(playlistsLength).to.have.lengthOf(resolutions.length) | |
57f879a5 C |
74 | } |
75 | ||
76 | export { | |
77 | checkSegmentHash, | |
78 | checkLiveSegmentHash, | |
79 | checkResolutionsInMasterPlaylist | |
80 | } |