1 /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
4 import * as chai from 'chai'
5 import { expectStartWith } from '@server/tests/shared'
6 import { areObjectStorageTestsDisabled } from '@shared/core-utils'
7 import { HttpStatusCode, LiveVideoCreate, VideoFile, VideoPrivacy } from '@shared/models'
11 findExternalSavedVideo,
16 setAccessTokensToServers,
17 setDefaultVideoChannel,
20 waitUntilLivePublishedOnAllServers,
21 waitUntilLiveReplacedByReplayOnAllServers,
22 waitUntilLiveWaitingOnAllServers
23 } from '@shared/server-commands'
25 const expect = chai.expect
27 async function createLive (server: PeerTubeServer, permanent: boolean) {
28 const attributes: LiveVideoCreate = {
29 channelId: server.store.channel.id,
30 privacy: VideoPrivacy.PUBLIC,
31 name: 'my super live',
33 permanentLive: permanent
36 const { uuid } = await server.live.create({ fields: attributes })
41 async function checkFiles (files: VideoFile[]) {
42 for (const file of files) {
43 expectStartWith(file.fileUrl, ObjectStorageCommand.getPlaylistBaseUrl())
45 await makeRawRequest(file.fileUrl, HttpStatusCode.OK_200)
49 async function getFiles (server: PeerTubeServer, videoUUID: string) {
50 const video = await server.videos.get({ id: videoUUID })
52 expect(video.files).to.have.lengthOf(0)
53 expect(video.streamingPlaylists).to.have.lengthOf(1)
55 return video.streamingPlaylists[0].files
58 async function streamAndEnd (servers: PeerTubeServer[], liveUUID: string) {
59 const ffmpegCommand = await servers[0].live.sendRTMPStreamInVideo({ videoId: liveUUID })
60 await waitUntilLivePublishedOnAllServers(servers, liveUUID)
62 const videoLiveDetails = await servers[0].videos.get({ id: liveUUID })
63 const liveDetails = await servers[0].live.get({ videoId: liveUUID })
65 await stopFfmpeg(ffmpegCommand)
67 if (liveDetails.permanentLive) {
68 await waitUntilLiveWaitingOnAllServers(servers, liveUUID)
70 await waitUntilLiveReplacedByReplayOnAllServers(servers, liveUUID)
73 await waitJobs(servers)
75 return { videoLiveDetails, liveDetails }
78 describe('Object storage for lives', function () {
79 if (areObjectStorageTestsDisabled()) return
81 let servers: PeerTubeServer[]
83 before(async function () {
86 await ObjectStorageCommand.prepareDefaultBuckets()
88 servers = await createMultipleServers(2, ObjectStorageCommand.getDefaultConfig())
90 await setAccessTokensToServers(servers)
91 await setDefaultVideoChannel(servers)
92 await doubleFollow(servers[0], servers[1])
94 await servers[0].config.enableTranscoding()
97 describe('Without live transcoding', async function () {
100 before(async function () {
101 await servers[0].config.enableLive({ transcoding: false })
103 videoUUID = await createLive(servers[0], false)
106 it('Should create a live and save the replay on object storage', async function () {
109 await streamAndEnd(servers, videoUUID)
111 for (const server of servers) {
112 const files = await getFiles(server, videoUUID)
113 expect(files).to.have.lengthOf(1)
115 await checkFiles(files)
120 describe('With live transcoding', async function () {
121 let videoUUIDPermanent: string
122 let videoUUIDNonPermanent: string
124 before(async function () {
125 await servers[0].config.enableLive({ transcoding: true })
127 videoUUIDPermanent = await createLive(servers[0], true)
128 videoUUIDNonPermanent = await createLive(servers[0], false)
131 it('Should create a live and save the replay on object storage', async function () {
134 await streamAndEnd(servers, videoUUIDNonPermanent)
136 for (const server of servers) {
137 const files = await getFiles(server, videoUUIDNonPermanent)
138 expect(files).to.have.lengthOf(5)
140 await checkFiles(files)
144 it('Should create a live and save the replay of permanent live on object storage', async function () {
147 const { videoLiveDetails } = await streamAndEnd(servers, videoUUIDPermanent)
149 const replay = await findExternalSavedVideo(servers[0], videoLiveDetails)
151 for (const server of servers) {
152 const files = await getFiles(server, replay.uuid)
153 expect(files).to.have.lengthOf(5)
155 await checkFiles(files)
160 after(async function () {
161 await killallServers(servers)