]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blobdiff - shared/server-commands/videos/live-command.ts
Translated using Weblate (Ukrainian)
[github/Chocobozzz/PeerTube.git] / shared / server-commands / videos / live-command.ts
index 3df47ed4d7d8f2799ae84293b71668711197541f..dc3c5a86ef8f45862665448648bcf47644633f00 100644 (file)
@@ -1,9 +1,8 @@
 /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
 
 import { readdir } from 'fs-extra'
-import { omit } from 'lodash'
 import { join } from 'path'
-import { wait } from '@shared/core-utils'
+import { omit, wait } from '@shared/core-utils'
 import {
   HttpStatusCode,
   LiveVideo,
@@ -13,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'
 
@@ -35,6 +36,8 @@ export class LiveCommand extends AbstractCommand {
     })
   }
 
+  // ---------------------------------------------------------------------------
+
   listSessions (options: OverrideCommandOptions & {
     videoId: number | string
   }) {
@@ -71,6 +74,8 @@ export class LiveCommand extends AbstractCommand {
     })
   }
 
+  // ---------------------------------------------------------------------------
+
   update (options: OverrideCommandOptions & {
     videoId: number | string
     fields: LiveVideoUpdate
@@ -103,7 +108,7 @@ export class LiveCommand extends AbstractCommand {
 
       path,
       attaches,
-      fields: omit(fields, 'thumbnailfile', 'previewfile'),
+      fields: omit(fields, [ 'thumbnailfile', 'previewfile' ]),
       implicitToken: true,
       defaultExpectedStatus: HttpStatusCode.OK_200
     }))
@@ -111,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
@@ -131,6 +164,8 @@ export class LiveCommand extends AbstractCommand {
     return testFfmpegStreamError(command, options.shouldHaveError)
   }
 
+  // ---------------------------------------------------------------------------
+
   waitUntilPublished (options: OverrideCommandOptions & {
     videoId: number | string
   }) {
@@ -152,27 +187,85 @@ 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 {
+        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]
+
+        const shaBody = await server.streamingPlaylists.getSegmentSha256({ url: hlsPlaylist.segmentsSha256Url })
+
+        if (!shaBody[segmentName]) {
+          throw new Error('Segment SHA does not exist')
+        }
 
-    return this.server.servers.waitUntilLog(`${videoUUID}/${segmentName}`, totalSessions * 2, false)
+        error = false
+      } catch {
+        error = true
+        await wait(100)
+      }
+    }
   }
 
-  getSegment (options: OverrideCommandOptions & {
+  async waitUntilReplacedByReplay (options: OverrideCommandOptions & {
+    videoId: number | string
+  }) {
+    let video: VideoDetails
+
+    do {
+      video = await this.server.videos.getWithToken({ token: options.token, id: options.videoId })
+
+      await wait(500)
+    } while (video.isLive === true || video.state.id !== VideoState.PUBLISHED)
+  }
+
+  // ---------------------------------------------------------------------------
+
+  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,
@@ -183,18 +276,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
   }) {