diff options
author | Chocobozzz <me@florianbigard.com> | 2022-10-04 10:03:17 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2022-10-04 10:03:17 +0200 |
commit | cfd57d2ca0bb058087f7dc90fcc3e8442b0288e1 (patch) | |
tree | dc899a1504ecac588e5580553e02571e0f5d7e4b /shared/server-commands/videos/live-command.ts | |
parent | 9c0cdc5047918b959ebd5e075ddad81eb7fb93f0 (diff) | |
download | PeerTube-cfd57d2ca0bb058087f7dc90fcc3e8442b0288e1.tar.gz PeerTube-cfd57d2ca0bb058087f7dc90fcc3e8442b0288e1.tar.zst PeerTube-cfd57d2ca0bb058087f7dc90fcc3e8442b0288e1.zip |
Live supports object storage
* Sync live files (segments, master playlist, resolution playlist,
segment sha file) into object storage
* Automatically delete them when the live ends
* Segment sha file is now a file on disk, and not stored in memory
anymore
Diffstat (limited to 'shared/server-commands/videos/live-command.ts')
-rw-r--r-- | shared/server-commands/videos/live-command.ts | 60 |
1 files changed, 50 insertions, 10 deletions
diff --git a/shared/server-commands/videos/live-command.ts b/shared/server-commands/videos/live-command.ts index d804fd883..defae95fb 100644 --- a/shared/server-commands/videos/live-command.ts +++ b/shared/server-commands/videos/live-command.ts | |||
@@ -15,6 +15,7 @@ import { | |||
15 | VideoState | 15 | VideoState |
16 | } from '@shared/models' | 16 | } from '@shared/models' |
17 | import { unwrapBody } from '../requests' | 17 | import { unwrapBody } from '../requests' |
18 | import { ObjectStorageCommand } from '../server' | ||
18 | import { AbstractCommand, OverrideCommandOptions } from '../shared' | 19 | import { AbstractCommand, OverrideCommandOptions } from '../shared' |
19 | import { sendRTMPStream, testFfmpegStreamError } from './live' | 20 | import { sendRTMPStream, testFfmpegStreamError } from './live' |
20 | 21 | ||
@@ -34,6 +35,8 @@ export class LiveCommand extends AbstractCommand { | |||
34 | }) | 35 | }) |
35 | } | 36 | } |
36 | 37 | ||
38 | // --------------------------------------------------------------------------- | ||
39 | |||
37 | listSessions (options: OverrideCommandOptions & { | 40 | listSessions (options: OverrideCommandOptions & { |
38 | videoId: number | string | 41 | videoId: number | string |
39 | }) { | 42 | }) { |
@@ -70,6 +73,8 @@ export class LiveCommand extends AbstractCommand { | |||
70 | }) | 73 | }) |
71 | } | 74 | } |
72 | 75 | ||
76 | // --------------------------------------------------------------------------- | ||
77 | |||
73 | update (options: OverrideCommandOptions & { | 78 | update (options: OverrideCommandOptions & { |
74 | videoId: number | string | 79 | videoId: number | string |
75 | fields: LiveVideoUpdate | 80 | fields: LiveVideoUpdate |
@@ -110,6 +115,8 @@ export class LiveCommand extends AbstractCommand { | |||
110 | return body.video | 115 | return body.video |
111 | } | 116 | } |
112 | 117 | ||
118 | // --------------------------------------------------------------------------- | ||
119 | |||
113 | async sendRTMPStreamInVideo (options: OverrideCommandOptions & { | 120 | async sendRTMPStreamInVideo (options: OverrideCommandOptions & { |
114 | videoId: number | string | 121 | videoId: number | string |
115 | fixtureName?: string | 122 | fixtureName?: string |
@@ -130,6 +137,8 @@ export class LiveCommand extends AbstractCommand { | |||
130 | return testFfmpegStreamError(command, options.shouldHaveError) | 137 | return testFfmpegStreamError(command, options.shouldHaveError) |
131 | } | 138 | } |
132 | 139 | ||
140 | // --------------------------------------------------------------------------- | ||
141 | |||
133 | waitUntilPublished (options: OverrideCommandOptions & { | 142 | waitUntilPublished (options: OverrideCommandOptions & { |
134 | videoId: number | string | 143 | videoId: number | string |
135 | }) { | 144 | }) { |
@@ -163,15 +172,34 @@ export class LiveCommand extends AbstractCommand { | |||
163 | return this.server.servers.waitUntilLog(`${videoUUID}/${segmentName}`, totalSessions * 2, false) | 172 | return this.server.servers.waitUntilLog(`${videoUUID}/${segmentName}`, totalSessions * 2, false) |
164 | } | 173 | } |
165 | 174 | ||
166 | getSegment (options: OverrideCommandOptions & { | 175 | async waitUntilReplacedByReplay (options: OverrideCommandOptions & { |
176 | videoId: number | string | ||
177 | }) { | ||
178 | let video: VideoDetails | ||
179 | |||
180 | do { | ||
181 | video = await this.server.videos.getWithToken({ token: options.token, id: options.videoId }) | ||
182 | |||
183 | await wait(500) | ||
184 | } while (video.isLive === true || video.state.id !== VideoState.PUBLISHED) | ||
185 | } | ||
186 | |||
187 | // --------------------------------------------------------------------------- | ||
188 | |||
189 | getSegmentFile (options: OverrideCommandOptions & { | ||
167 | videoUUID: string | 190 | videoUUID: string |
168 | playlistNumber: number | 191 | playlistNumber: number |
169 | segment: number | 192 | segment: number |
193 | objectStorage?: boolean // default false | ||
170 | }) { | 194 | }) { |
171 | const { playlistNumber, segment, videoUUID } = options | 195 | const { playlistNumber, segment, videoUUID, objectStorage = false } = options |
172 | 196 | ||
173 | const segmentName = `${playlistNumber}-00000${segment}.ts` | 197 | const segmentName = `${playlistNumber}-00000${segment}.ts` |
174 | const url = `${this.server.url}/static/streaming-playlists/hls/${videoUUID}/${segmentName}` | 198 | const baseUrl = objectStorage |
199 | ? ObjectStorageCommand.getPlaylistBaseUrl() | ||
200 | : `${this.server.url}/static/streaming-playlists/hls` | ||
201 | |||
202 | const url = `${baseUrl}/${videoUUID}/${segmentName}` | ||
175 | 203 | ||
176 | return this.getRawRequest({ | 204 | return this.getRawRequest({ |
177 | ...options, | 205 | ...options, |
@@ -182,18 +210,30 @@ export class LiveCommand extends AbstractCommand { | |||
182 | }) | 210 | }) |
183 | } | 211 | } |
184 | 212 | ||
185 | async waitUntilReplacedByReplay (options: OverrideCommandOptions & { | 213 | getPlaylistFile (options: OverrideCommandOptions & { |
186 | videoId: number | string | 214 | videoUUID: string |
215 | playlistName: string | ||
216 | objectStorage?: boolean // default false | ||
187 | }) { | 217 | }) { |
188 | let video: VideoDetails | 218 | const { playlistName, videoUUID, objectStorage = false } = options |
189 | 219 | ||
190 | do { | 220 | const baseUrl = objectStorage |
191 | video = await this.server.videos.getWithToken({ token: options.token, id: options.videoId }) | 221 | ? ObjectStorageCommand.getPlaylistBaseUrl() |
222 | : `${this.server.url}/static/streaming-playlists/hls` | ||
192 | 223 | ||
193 | await wait(500) | 224 | const url = `${baseUrl}/${videoUUID}/${playlistName}` |
194 | } while (video.isLive === true || video.state.id !== VideoState.PUBLISHED) | 225 | |
226 | return this.getRawRequest({ | ||
227 | ...options, | ||
228 | |||
229 | url, | ||
230 | implicitToken: false, | ||
231 | defaultExpectedStatus: HttpStatusCode.OK_200 | ||
232 | }) | ||
195 | } | 233 | } |
196 | 234 | ||
235 | // --------------------------------------------------------------------------- | ||
236 | |||
197 | async countPlaylists (options: OverrideCommandOptions & { | 237 | async countPlaylists (options: OverrideCommandOptions & { |
198 | videoUUID: string | 238 | videoUUID: string |
199 | }) { | 239 | }) { |