X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=shared%2Fserver-commands%2Fvideos%2Flive-command.ts;h=73f4eefd331a94086c625b55b41c1898d0f6aeff;hb=81f14b911211be065448e92bcc253f470c5ff2a9;hp=d804fd883b53287b2656b1fe5e369525e4e60215;hpb=bbd5aa7ead5f1554a0872963f957effc26d8c630;p=github%2FChocobozzz%2FPeerTube.git diff --git a/shared/server-commands/videos/live-command.ts b/shared/server-commands/videos/live-command.ts index d804fd883..73f4eefd3 100644 --- a/shared/server-commands/videos/live-command.ts +++ b/shared/server-commands/videos/live-command.ts @@ -12,9 +12,11 @@ import { ResultList, VideoCreateResult, VideoDetails, + VideoPrivacy, VideoState } from '@shared/models' import { unwrapBody } from '../requests' +import { ObjectStorageCommand, PeerTubeServer } from '../server' import { AbstractCommand, OverrideCommandOptions } from '../shared' import { sendRTMPStream, testFfmpegStreamError } from './live' @@ -34,6 +36,8 @@ export class LiveCommand extends AbstractCommand { }) } + // --------------------------------------------------------------------------- + listSessions (options: OverrideCommandOptions & { videoId: number | string }) { @@ -70,6 +74,8 @@ export class LiveCommand extends AbstractCommand { }) } + // --------------------------------------------------------------------------- + update (options: OverrideCommandOptions & { videoId: number | string fields: LiveVideoUpdate @@ -110,6 +116,34 @@ export class LiveCommand extends AbstractCommand { return body.video } + async quickCreate (options: OverrideCommandOptions & { + saveReplay: boolean + permanentLive: boolean + privacy?: VideoPrivacy + }) { + const { saveReplay, permanentLive, privacy = VideoPrivacy.PUBLIC } = options + + const { uuid } = await this.create({ + ...options, + + fields: { + name: 'live', + permanentLive, + saveReplay, + replaySettings: { privacy }, + channelId: this.server.store.channel.id, + privacy + } + }) + + const video = await this.server.videos.getWithToken({ id: uuid }) + const live = await this.get({ videoId: uuid }) + + return { video, live } + } + + // --------------------------------------------------------------------------- + async sendRTMPStreamInVideo (options: OverrideCommandOptions & { videoId: number | string fixtureName?: string @@ -130,6 +164,8 @@ export class LiveCommand extends AbstractCommand { return testFfmpegStreamError(command, options.shouldHaveError) } + // --------------------------------------------------------------------------- + waitUntilPublished (options: OverrideCommandOptions & { videoId: number | string }) { @@ -151,27 +187,90 @@ export class LiveCommand extends AbstractCommand { return this.waitUntilState({ videoId, state: VideoState.LIVE_ENDED }) } - waitUntilSegmentGeneration (options: OverrideCommandOptions & { + async waitUntilSegmentGeneration (options: OverrideCommandOptions & { + server: PeerTubeServer videoUUID: string playlistNumber: number segment: number - totalSessions?: number + objectStorage: boolean + objectStorageBaseUrl?: string }) { - const { playlistNumber, segment, videoUUID, totalSessions = 1 } = options + const { + server, + objectStorage, + playlistNumber, + segment, + videoUUID, + objectStorageBaseUrl = ObjectStorageCommand.getMockPlaylistBaseUrl() + } = options + const segmentName = `${playlistNumber}-00000${segment}.ts` + const baseUrl = objectStorage + ? join(objectStorageBaseUrl, 'hls') + : server.url + '/static/streaming-playlists/hls' + + let error = true + + while (error) { + try { + // Check fragment exists + await this.getRawRequest({ + ...options, + + url: `${baseUrl}/${videoUUID}/${segmentName}`, + implicitToken: false, + defaultExpectedStatus: HttpStatusCode.OK_200 + }) + + const video = await server.videos.get({ id: videoUUID }) + const hlsPlaylist = video.streamingPlaylists[0] + + // Check SHA generation + const shaBody = await server.streamingPlaylists.getSegmentSha256({ url: hlsPlaylist.segmentsSha256Url, withRetry: objectStorage }) + if (!shaBody[segmentName]) { + throw new Error('Segment SHA does not exist') + } + + // Check fragment is in m3u8 playlist + const subPlaylist = await server.streamingPlaylists.get({ url: `${baseUrl}/${video.uuid}/${playlistNumber}.m3u8` }) + if (!subPlaylist.includes(segmentName)) throw new Error('Fragment does not exist in playlist') + + error = false + } catch { + error = true + await wait(100) + } + } + } + + async waitUntilReplacedByReplay (options: OverrideCommandOptions & { + videoId: number | string + }) { + let video: VideoDetails + + do { + video = await this.server.videos.getWithToken({ token: options.token, id: options.videoId }) - return this.server.servers.waitUntilLog(`${videoUUID}/${segmentName}`, totalSessions * 2, false) + await wait(500) + } while (video.isLive === true || video.state.id !== VideoState.PUBLISHED) } - getSegment (options: OverrideCommandOptions & { + // --------------------------------------------------------------------------- + + getSegmentFile (options: OverrideCommandOptions & { videoUUID: string playlistNumber: number segment: number + objectStorage?: boolean // default false }) { - const { playlistNumber, segment, videoUUID } = options + const { playlistNumber, segment, videoUUID, objectStorage = false } = options const segmentName = `${playlistNumber}-00000${segment}.ts` - const url = `${this.server.url}/static/streaming-playlists/hls/${videoUUID}/${segmentName}` + const baseUrl = objectStorage + ? ObjectStorageCommand.getMockPlaylistBaseUrl() + : `${this.server.url}/static/streaming-playlists/hls` + + const url = `${baseUrl}/${videoUUID}/${segmentName}` return this.getRawRequest({ ...options, @@ -182,18 +281,30 @@ export class LiveCommand extends AbstractCommand { }) } - async waitUntilReplacedByReplay (options: OverrideCommandOptions & { - videoId: number | string + getPlaylistFile (options: OverrideCommandOptions & { + videoUUID: string + playlistName: string + objectStorage?: boolean // default false }) { - let video: VideoDetails + const { playlistName, videoUUID, objectStorage = false } = options - do { - video = await this.server.videos.getWithToken({ token: options.token, id: options.videoId }) + const baseUrl = objectStorage + ? ObjectStorageCommand.getMockPlaylistBaseUrl() + : `${this.server.url}/static/streaming-playlists/hls` - await wait(500) - } while (video.isLive === true || video.state.id !== VideoState.PUBLISHED) + const url = `${baseUrl}/${videoUUID}/${playlistName}` + + return this.getRawRequest({ + ...options, + + url, + implicitToken: false, + defaultExpectedStatus: HttpStatusCode.OK_200 + }) } + // --------------------------------------------------------------------------- + async countPlaylists (options: OverrideCommandOptions & { videoUUID: string }) {