aboutsummaryrefslogtreecommitdiffhomepage
path: root/shared/extra-utils/videos/live.ts
diff options
context:
space:
mode:
Diffstat (limited to 'shared/extra-utils/videos/live.ts')
-rw-r--r--shared/extra-utils/videos/live.ts59
1 files changed, 49 insertions, 10 deletions
diff --git a/shared/extra-utils/videos/live.ts b/shared/extra-utils/videos/live.ts
index a391565a4..f90dd420d 100644
--- a/shared/extra-utils/videos/live.ts
+++ b/shared/extra-utils/videos/live.ts
@@ -1,8 +1,14 @@
1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
3import { expect } from 'chai'
1import * as ffmpeg from 'fluent-ffmpeg' 4import * as ffmpeg from 'fluent-ffmpeg'
5import { pathExists, readdir } from 'fs-extra'
2import { omit } from 'lodash' 6import { omit } from 'lodash'
7import { join } from 'path'
3import { LiveVideo, LiveVideoCreate, LiveVideoUpdate, VideoDetails, VideoState } from '@shared/models' 8import { LiveVideo, LiveVideoCreate, LiveVideoUpdate, VideoDetails, VideoState } from '@shared/models'
4import { buildAbsoluteFixturePath, wait } from '../miscs/miscs' 9import { buildAbsoluteFixturePath, buildServerDirectory, wait } from '../miscs/miscs'
5import { makeGetRequest, makePutBodyRequest, makeUploadRequest } from '../requests/requests' 10import { makeGetRequest, makePutBodyRequest, makeUploadRequest } from '../requests/requests'
11import { ServerInfo } from '../server/servers'
6import { getVideoWithToken } from './videos' 12import { getVideoWithToken } from './videos'
7 13
8function getLive (url: string, token: string, videoId: number | string, statusCodeExpected = 200) { 14function getLive (url: string, token: string, videoId: number | string, statusCodeExpected = 200) {
@@ -47,21 +53,22 @@ function createLive (url: string, token: string, fields: LiveVideoCreate, status
47 }) 53 })
48} 54}
49 55
50async function sendRTMPStreamInVideo (url: string, token: string, videoId: number | string, onErrorCb?: Function) { 56async function sendRTMPStreamInVideo (url: string, token: string, videoId: number | string) {
51 const res = await getLive(url, token, videoId) 57 const res = await getLive(url, token, videoId)
52 const videoLive = res.body as LiveVideo 58 const videoLive = res.body as LiveVideo
53 59
54 return sendRTMPStream(videoLive.rtmpUrl, videoLive.streamKey, onErrorCb) 60 return sendRTMPStream(videoLive.rtmpUrl, videoLive.streamKey)
55} 61}
56 62
57function sendRTMPStream (rtmpBaseUrl: string, streamKey: string, onErrorCb?: Function) { 63function sendRTMPStream (rtmpBaseUrl: string, streamKey: string) {
58 const fixture = buildAbsoluteFixturePath('video_short.mp4') 64 const fixture = buildAbsoluteFixturePath('video_short.mp4')
59 65
60 const command = ffmpeg(fixture) 66 const command = ffmpeg(fixture)
61 command.inputOption('-stream_loop -1') 67 command.inputOption('-stream_loop -1')
62 command.inputOption('-re') 68 command.inputOption('-re')
63 69 command.outputOption('-c:v libx264')
64 command.outputOption('-c copy') 70 command.outputOption('-g 50')
71 command.outputOption('-keyint_min 2')
65 command.outputOption('-f flv') 72 command.outputOption('-f flv')
66 73
67 const rtmpUrl = rtmpBaseUrl + '/' + streamKey 74 const rtmpUrl = rtmpBaseUrl + '/' + streamKey
@@ -70,7 +77,7 @@ function sendRTMPStream (rtmpBaseUrl: string, streamKey: string, onErrorCb?: Fun
70 command.on('error', err => { 77 command.on('error', err => {
71 if (err?.message?.includes('Exiting normally')) return 78 if (err?.message?.includes('Exiting normally')) return
72 79
73 if (onErrorCb) onErrorCb(err) 80 if (process.env.DEBUG) console.error(err)
74 }) 81 })
75 82
76 if (process.env.DEBUG) { 83 if (process.env.DEBUG) {
@@ -94,8 +101,13 @@ function waitFfmpegUntilError (command: ffmpeg.FfmpegCommand, successAfterMS = 1
94 }) 101 })
95} 102}
96 103
97async function testFfmpegStreamError (url: string, token: string, videoId: number | string, shouldHaveError: boolean) { 104async function runAndTestFfmpegStreamError (url: string, token: string, videoId: number | string, shouldHaveError: boolean) {
98 const command = await sendRTMPStreamInVideo(url, token, videoId) 105 const command = await sendRTMPStreamInVideo(url, token, videoId)
106
107 return testFfmpegStreamError(command, shouldHaveError)
108}
109
110async function testFfmpegStreamError (command: ffmpeg.FfmpegCommand, shouldHaveError: boolean) {
99 let error: Error 111 let error: Error
100 112
101 try { 113 try {
@@ -127,6 +139,31 @@ async function waitUntilLiveStarts (url: string, token: string, videoId: number
127 } while (video.state.id === VideoState.WAITING_FOR_LIVE) 139 } while (video.state.id === VideoState.WAITING_FOR_LIVE)
128} 140}
129 141
142async function checkLiveCleanup (server: ServerInfo, videoUUID: string, resolutions: number[] = []) {
143 const basePath = buildServerDirectory(server.internalServerNumber, 'streaming-playlists')
144 const hlsPath = join(basePath, 'hls', videoUUID)
145
146 if (resolutions.length === 0) {
147 const result = await pathExists(hlsPath)
148 expect(result).to.be.false
149
150 return
151 }
152
153 const files = await readdir(hlsPath)
154
155 // fragmented file and playlist per resolution + master playlist + segments sha256 json file
156 expect(files).to.have.lengthOf(resolutions.length * 2 + 2)
157
158 for (const resolution of resolutions) {
159 expect(files).to.contain(`${videoUUID}-${resolution}-fragmented.mp4`)
160 expect(files).to.contain(`${resolution}.m3u8`)
161 }
162
163 expect(files).to.contain('master.m3u8')
164 expect(files).to.contain('segments-sha256.json')
165}
166
130// --------------------------------------------------------------------------- 167// ---------------------------------------------------------------------------
131 168
132export { 169export {
@@ -134,9 +171,11 @@ export {
134 updateLive, 171 updateLive,
135 waitUntilLiveStarts, 172 waitUntilLiveStarts,
136 createLive, 173 createLive,
137 testFfmpegStreamError, 174 runAndTestFfmpegStreamError,
175 checkLiveCleanup,
138 stopFfmpeg, 176 stopFfmpeg,
139 sendRTMPStreamInVideo, 177 sendRTMPStreamInVideo,
140 waitFfmpegUntilError, 178 waitFfmpegUntilError,
141 sendRTMPStream 179 sendRTMPStream,
180 testFfmpegStreamError
142} 181}