diff options
Diffstat (limited to 'shared/extra-utils/videos/streaming-playlists.ts')
-rw-r--r-- | shared/extra-utils/videos/streaming-playlists.ts | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/shared/extra-utils/videos/streaming-playlists.ts b/shared/extra-utils/videos/streaming-playlists.ts new file mode 100644 index 000000000..0324c739a --- /dev/null +++ b/shared/extra-utils/videos/streaming-playlists.ts | |||
@@ -0,0 +1,76 @@ | |||
1 | import { expect } from 'chai' | ||
2 | import { sha256 } from '@server/helpers/core-utils' | ||
3 | import { HttpStatusCode } from '@shared/core-utils' | ||
4 | import { VideoStreamingPlaylist } from '@shared/models' | ||
5 | import { ServerInfo } from '../server' | ||
6 | |||
7 | async function checkSegmentHash (options: { | ||
8 | server: ServerInfo | ||
9 | baseUrlPlaylist: string | ||
10 | baseUrlSegment: string | ||
11 | videoUUID: string | ||
12 | resolution: number | ||
13 | hlsPlaylist: VideoStreamingPlaylist | ||
14 | }) { | ||
15 | const { server, baseUrlPlaylist, baseUrlSegment, videoUUID, resolution, hlsPlaylist } = options | ||
16 | const command = server.streamingPlaylistsCommand | ||
17 | |||
18 | const playlist = await command.get({ url: `${baseUrlPlaylist}/${videoUUID}/${resolution}.m3u8` }) | ||
19 | |||
20 | const videoName = `${videoUUID}-${resolution}-fragmented.mp4` | ||
21 | |||
22 | const matches = /#EXT-X-BYTERANGE:(\d+)@(\d+)/.exec(playlist) | ||
23 | |||
24 | const length = parseInt(matches[1], 10) | ||
25 | const offset = parseInt(matches[2], 10) | ||
26 | const range = `${offset}-${offset + length - 1}` | ||
27 | |||
28 | const segmentBody = await command.getSegment({ | ||
29 | url: `${baseUrlSegment}/${videoUUID}/${videoName}`, | ||
30 | expectedStatus: HttpStatusCode.PARTIAL_CONTENT_206, | ||
31 | range: `bytes=${range}` | ||
32 | }) | ||
33 | |||
34 | const shaBody = await command.getSegmentSha256({ url: hlsPlaylist.segmentsSha256Url }) | ||
35 | expect(sha256(segmentBody)).to.equal(shaBody[videoName][range]) | ||
36 | } | ||
37 | |||
38 | async function checkLiveSegmentHash (options: { | ||
39 | server: ServerInfo | ||
40 | baseUrlSegment: string | ||
41 | videoUUID: string | ||
42 | segmentName: string | ||
43 | hlsPlaylist: VideoStreamingPlaylist | ||
44 | }) { | ||
45 | const { server, baseUrlSegment, videoUUID, segmentName, hlsPlaylist } = options | ||
46 | const command = server.streamingPlaylistsCommand | ||
47 | |||
48 | const segmentBody = await command.getSegment({ url: `${baseUrlSegment}/${videoUUID}/${segmentName}` }) | ||
49 | const shaBody = await command.getSegmentSha256({ url: hlsPlaylist.segmentsSha256Url }) | ||
50 | |||
51 | expect(sha256(segmentBody)).to.equal(shaBody[segmentName]) | ||
52 | } | ||
53 | |||
54 | async function checkResolutionsInMasterPlaylist (options: { | ||
55 | server: ServerInfo | ||
56 | playlistUrl: string | ||
57 | resolutions: number[] | ||
58 | }) { | ||
59 | const { server, playlistUrl, resolutions } = options | ||
60 | |||
61 | const masterPlaylist = await server.streamingPlaylistsCommand.get({ url: playlistUrl }) | ||
62 | |||
63 | for (const resolution of resolutions) { | ||
64 | const reg = new RegExp( | ||
65 | '#EXT-X-STREAM-INF:BANDWIDTH=\\d+,RESOLUTION=\\d+x' + resolution + ',(FRAME-RATE=\\d+,)?CODECS="avc1.64001f,mp4a.40.2"' | ||
66 | ) | ||
67 | |||
68 | expect(masterPlaylist).to.match(reg) | ||
69 | } | ||
70 | } | ||
71 | |||
72 | export { | ||
73 | checkSegmentHash, | ||
74 | checkLiveSegmentHash, | ||
75 | checkResolutionsInMasterPlaylist | ||
76 | } | ||