diff options
-rw-r--r-- | server/tests/api/transcoding/create-transcoding.ts | 2 | ||||
-rw-r--r-- | server/tests/shared/live.ts | 3 | ||||
-rw-r--r-- | server/tests/shared/streaming-playlists.ts | 7 | ||||
-rw-r--r-- | shared/server-commands/videos/live-command.ts | 2 | ||||
-rw-r--r-- | shared/server-commands/videos/streaming-playlists-command.ts | 78 |
5 files changed, 67 insertions, 25 deletions
diff --git a/server/tests/api/transcoding/create-transcoding.ts b/server/tests/api/transcoding/create-transcoding.ts index 85389a949..5483c8dba 100644 --- a/server/tests/api/transcoding/create-transcoding.ts +++ b/server/tests/api/transcoding/create-transcoding.ts | |||
@@ -226,7 +226,7 @@ function runTests (objectStorage: boolean) { | |||
226 | const resolutions = hlsPlaylist.files.map(f => f.resolution.id) | 226 | const resolutions = hlsPlaylist.files.map(f => f.resolution.id) |
227 | await checkResolutionsInMasterPlaylist({ server: servers[0], playlistUrl: hlsPlaylist.playlistUrl, resolutions }) | 227 | await checkResolutionsInMasterPlaylist({ server: servers[0], playlistUrl: hlsPlaylist.playlistUrl, resolutions }) |
228 | 228 | ||
229 | const shaBody = await servers[0].streamingPlaylists.getSegmentSha256({ url: hlsPlaylist.segmentsSha256Url }) | 229 | const shaBody = await servers[0].streamingPlaylists.getSegmentSha256({ url: hlsPlaylist.segmentsSha256Url, withRetry: true }) |
230 | expect(Object.keys(shaBody)).to.have.lengthOf(5) | 230 | expect(Object.keys(shaBody)).to.have.lengthOf(5) |
231 | } | 231 | } |
232 | } | 232 | } |
diff --git a/server/tests/shared/live.ts b/server/tests/shared/live.ts index 31f92ef19..793503311 100644 --- a/server/tests/shared/live.ts +++ b/server/tests/shared/live.ts | |||
@@ -115,7 +115,8 @@ async function testLiveVideoResolutions (options: { | |||
115 | baseUrlSegment: baseUrl, | 115 | baseUrlSegment: baseUrl, |
116 | videoUUID: video.uuid, | 116 | videoUUID: video.uuid, |
117 | segmentName, | 117 | segmentName, |
118 | hlsPlaylist | 118 | hlsPlaylist, |
119 | withRetry: objectStorage // With object storage, the request may fail because of inconsistent data in S3 | ||
119 | }) | 120 | }) |
120 | 121 | ||
121 | if (originServer.internalServerNumber === server.internalServerNumber) { | 122 | if (originServer.internalServerNumber === server.internalServerNumber) { |
diff --git a/server/tests/shared/streaming-playlists.ts b/server/tests/shared/streaming-playlists.ts index acfb2b408..e4f88bc25 100644 --- a/server/tests/shared/streaming-playlists.ts +++ b/server/tests/shared/streaming-playlists.ts | |||
@@ -51,12 +51,13 @@ async function checkLiveSegmentHash (options: { | |||
51 | videoUUID: string | 51 | videoUUID: string |
52 | segmentName: string | 52 | segmentName: string |
53 | hlsPlaylist: VideoStreamingPlaylist | 53 | hlsPlaylist: VideoStreamingPlaylist |
54 | withRetry?: boolean | ||
54 | }) { | 55 | }) { |
55 | const { server, baseUrlSegment, videoUUID, segmentName, hlsPlaylist } = options | 56 | const { server, baseUrlSegment, videoUUID, segmentName, hlsPlaylist, withRetry = false } = options |
56 | const command = server.streamingPlaylists | 57 | const command = server.streamingPlaylists |
57 | 58 | ||
58 | const segmentBody = await command.getFragmentedSegment({ url: `${baseUrlSegment}/${videoUUID}/${segmentName}` }) | 59 | const segmentBody = await command.getFragmentedSegment({ url: `${baseUrlSegment}/${videoUUID}/${segmentName}`, withRetry }) |
59 | const shaBody = await command.getSegmentSha256({ url: hlsPlaylist.segmentsSha256Url }) | 60 | const shaBody = await command.getSegmentSha256({ url: hlsPlaylist.segmentsSha256Url, withRetry }) |
60 | 61 | ||
61 | expect(sha256(segmentBody)).to.equal(shaBody[segmentName]) | 62 | expect(sha256(segmentBody)).to.equal(shaBody[segmentName]) |
62 | } | 63 | } |
diff --git a/shared/server-commands/videos/live-command.ts b/shared/server-commands/videos/live-command.ts index dc3c5a86e..2e4bc10b5 100644 --- a/shared/server-commands/videos/live-command.ts +++ b/shared/server-commands/videos/live-command.ts | |||
@@ -224,7 +224,7 @@ export class LiveCommand extends AbstractCommand { | |||
224 | const video = await server.videos.get({ id: videoUUID }) | 224 | const video = await server.videos.get({ id: videoUUID }) |
225 | const hlsPlaylist = video.streamingPlaylists[0] | 225 | const hlsPlaylist = video.streamingPlaylists[0] |
226 | 226 | ||
227 | const shaBody = await server.streamingPlaylists.getSegmentSha256({ url: hlsPlaylist.segmentsSha256Url }) | 227 | const shaBody = await server.streamingPlaylists.getSegmentSha256({ url: hlsPlaylist.segmentsSha256Url, withRetry: objectStorage }) |
228 | 228 | ||
229 | if (!shaBody[segmentName]) { | 229 | if (!shaBody[segmentName]) { |
230 | throw new Error('Segment SHA does not exist') | 230 | throw new Error('Segment SHA does not exist') |
diff --git a/shared/server-commands/videos/streaming-playlists-command.ts b/shared/server-commands/videos/streaming-playlists-command.ts index 7b92dcc0a..950808b60 100644 --- a/shared/server-commands/videos/streaming-playlists-command.ts +++ b/shared/server-commands/videos/streaming-playlists-command.ts | |||
@@ -44,31 +44,71 @@ export class StreamingPlaylistsCommand extends AbstractCommand { | |||
44 | } | 44 | } |
45 | } | 45 | } |
46 | 46 | ||
47 | getFragmentedSegment (options: OverrideCommandOptions & { | 47 | async getFragmentedSegment (options: OverrideCommandOptions & { |
48 | url: string | 48 | url: string |
49 | range?: string | 49 | range?: string |
50 | |||
51 | withRetry?: boolean // default false | ||
52 | currentRetry?: number | ||
50 | }) { | 53 | }) { |
51 | return unwrapBody<Buffer>(this.getRawRequest({ | 54 | const { withRetry, currentRetry = 1 } = options |
52 | ...options, | 55 | |
53 | 56 | try { | |
54 | url: options.url, | 57 | const result = await unwrapBody<Buffer>(this.getRawRequest({ |
55 | range: options.range, | 58 | ...options, |
56 | implicitToken: false, | 59 | |
57 | responseType: 'application/octet-stream', | 60 | url: options.url, |
58 | defaultExpectedStatus: HttpStatusCode.OK_200 | 61 | range: options.range, |
59 | })) | 62 | implicitToken: false, |
63 | responseType: 'application/octet-stream', | ||
64 | defaultExpectedStatus: HttpStatusCode.OK_200 | ||
65 | })) | ||
66 | |||
67 | return result | ||
68 | } catch (err) { | ||
69 | if (!withRetry || currentRetry > 5) throw err | ||
70 | |||
71 | await wait(100) | ||
72 | |||
73 | return this.getFragmentedSegment({ | ||
74 | ...options, | ||
75 | |||
76 | withRetry, | ||
77 | currentRetry: currentRetry + 1 | ||
78 | }) | ||
79 | } | ||
60 | } | 80 | } |
61 | 81 | ||
62 | getSegmentSha256 (options: OverrideCommandOptions & { | 82 | async getSegmentSha256 (options: OverrideCommandOptions & { |
63 | url: string | 83 | url: string |
84 | |||
85 | withRetry?: boolean // default false | ||
86 | currentRetry?: number | ||
64 | }) { | 87 | }) { |
65 | return unwrapBodyOrDecodeToJSON<{ [ id: string ]: string }>(this.getRawRequest({ | 88 | const { withRetry, currentRetry = 1 } = options |
66 | ...options, | 89 | |
67 | 90 | try { | |
68 | url: options.url, | 91 | const result = await unwrapBodyOrDecodeToJSON<{ [ id: string ]: string }>(this.getRawRequest({ |
69 | contentType: 'application/json', | 92 | ...options, |
70 | implicitToken: false, | 93 | |
71 | defaultExpectedStatus: HttpStatusCode.OK_200 | 94 | url: options.url, |
72 | })) | 95 | contentType: 'application/json', |
96 | implicitToken: false, | ||
97 | defaultExpectedStatus: HttpStatusCode.OK_200 | ||
98 | })) | ||
99 | |||
100 | return result | ||
101 | } catch (err) { | ||
102 | if (!withRetry || currentRetry > 5) throw err | ||
103 | |||
104 | await wait(100) | ||
105 | |||
106 | return this.getSegmentSha256({ | ||
107 | ...options, | ||
108 | |||
109 | withRetry, | ||
110 | currentRetry: currentRetry + 1 | ||
111 | }) | ||
112 | } | ||
73 | } | 113 | } |
74 | } | 114 | } |