diff options
Diffstat (limited to 'shared')
-rw-r--r-- | shared/extra-utils/videos/live.ts | 46 | ||||
-rw-r--r-- | shared/models/videos/video-create.model.ts | 5 |
2 files changed, 45 insertions, 6 deletions
diff --git a/shared/extra-utils/videos/live.ts b/shared/extra-utils/videos/live.ts index 65942db0a..a391565a4 100644 --- a/shared/extra-utils/videos/live.ts +++ b/shared/extra-utils/videos/live.ts | |||
@@ -1,9 +1,9 @@ | |||
1 | import * as ffmpeg from 'fluent-ffmpeg' | 1 | import * as ffmpeg from 'fluent-ffmpeg' |
2 | import { LiveVideoCreate, LiveVideoUpdate, VideoDetails, VideoState } from '@shared/models' | 2 | import { omit } from 'lodash' |
3 | import { LiveVideo, LiveVideoCreate, LiveVideoUpdate, VideoDetails, VideoState } from '@shared/models' | ||
3 | import { buildAbsoluteFixturePath, wait } from '../miscs/miscs' | 4 | import { buildAbsoluteFixturePath, wait } from '../miscs/miscs' |
4 | import { makeGetRequest, makePutBodyRequest, makeUploadRequest } from '../requests/requests' | 5 | import { makeGetRequest, makePutBodyRequest, makeUploadRequest } from '../requests/requests' |
5 | import { getVideoWithToken } from './videos' | 6 | import { getVideoWithToken } from './videos' |
6 | import { omit } from 'lodash' | ||
7 | 7 | ||
8 | function getLive (url: string, token: string, videoId: number | string, statusCodeExpected = 200) { | 8 | function getLive (url: string, token: string, videoId: number | string, statusCodeExpected = 200) { |
9 | const path = '/api/v1/videos/live' | 9 | const path = '/api/v1/videos/live' |
@@ -47,7 +47,14 @@ function createLive (url: string, token: string, fields: LiveVideoCreate, status | |||
47 | }) | 47 | }) |
48 | } | 48 | } |
49 | 49 | ||
50 | function sendRTMPStream (rtmpBaseUrl: string, streamKey: string) { | 50 | async function sendRTMPStreamInVideo (url: string, token: string, videoId: number | string, onErrorCb?: Function) { |
51 | const res = await getLive(url, token, videoId) | ||
52 | const videoLive = res.body as LiveVideo | ||
53 | |||
54 | return sendRTMPStream(videoLive.rtmpUrl, videoLive.streamKey, onErrorCb) | ||
55 | } | ||
56 | |||
57 | function sendRTMPStream (rtmpBaseUrl: string, streamKey: string, onErrorCb?: Function) { | ||
51 | const fixture = buildAbsoluteFixturePath('video_short.mp4') | 58 | const fixture = buildAbsoluteFixturePath('video_short.mp4') |
52 | 59 | ||
53 | const command = ffmpeg(fixture) | 60 | const command = ffmpeg(fixture) |
@@ -63,7 +70,7 @@ function sendRTMPStream (rtmpBaseUrl: string, streamKey: string) { | |||
63 | command.on('error', err => { | 70 | command.on('error', err => { |
64 | if (err?.message?.includes('Exiting normally')) return | 71 | if (err?.message?.includes('Exiting normally')) return |
65 | 72 | ||
66 | console.error('Cannot send RTMP stream.', { err }) | 73 | if (onErrorCb) onErrorCb(err) |
67 | }) | 74 | }) |
68 | 75 | ||
69 | if (process.env.DEBUG) { | 76 | if (process.env.DEBUG) { |
@@ -75,6 +82,34 @@ function sendRTMPStream (rtmpBaseUrl: string, streamKey: string) { | |||
75 | return command | 82 | return command |
76 | } | 83 | } |
77 | 84 | ||
85 | function waitFfmpegUntilError (command: ffmpeg.FfmpegCommand, successAfterMS = 10000) { | ||
86 | return new Promise((res, rej) => { | ||
87 | command.on('error', err => { | ||
88 | return rej(err) | ||
89 | }) | ||
90 | |||
91 | setTimeout(() => { | ||
92 | res() | ||
93 | }, successAfterMS) | ||
94 | }) | ||
95 | } | ||
96 | |||
97 | async function testFfmpegStreamError (url: string, token: string, videoId: number | string, shouldHaveError: boolean) { | ||
98 | const command = await sendRTMPStreamInVideo(url, token, videoId) | ||
99 | let error: Error | ||
100 | |||
101 | try { | ||
102 | await waitFfmpegUntilError(command, 10000) | ||
103 | } catch (err) { | ||
104 | error = err | ||
105 | } | ||
106 | |||
107 | await stopFfmpeg(command) | ||
108 | |||
109 | if (shouldHaveError && !error) throw new Error('Ffmpeg did not have an error') | ||
110 | if (!shouldHaveError && error) throw error | ||
111 | } | ||
112 | |||
78 | async function stopFfmpeg (command: ffmpeg.FfmpegCommand) { | 113 | async function stopFfmpeg (command: ffmpeg.FfmpegCommand) { |
79 | command.kill('SIGINT') | 114 | command.kill('SIGINT') |
80 | 115 | ||
@@ -99,6 +134,9 @@ export { | |||
99 | updateLive, | 134 | updateLive, |
100 | waitUntilLiveStarts, | 135 | waitUntilLiveStarts, |
101 | createLive, | 136 | createLive, |
137 | testFfmpegStreamError, | ||
102 | stopFfmpeg, | 138 | stopFfmpeg, |
139 | sendRTMPStreamInVideo, | ||
140 | waitFfmpegUntilError, | ||
103 | sendRTMPStream | 141 | sendRTMPStream |
104 | } | 142 | } |
diff --git a/shared/models/videos/video-create.model.ts b/shared/models/videos/video-create.model.ts index 9e980529d..732d508d1 100644 --- a/shared/models/videos/video-create.model.ts +++ b/shared/models/videos/video-create.model.ts | |||
@@ -2,15 +2,16 @@ import { VideoPrivacy } from './video-privacy.enum' | |||
2 | import { VideoScheduleUpdate } from './video-schedule-update.model' | 2 | import { VideoScheduleUpdate } from './video-schedule-update.model' |
3 | 3 | ||
4 | export interface VideoCreate { | 4 | export interface VideoCreate { |
5 | name: string | ||
6 | channelId: number | ||
7 | |||
5 | category?: number | 8 | category?: number |
6 | licence?: number | 9 | licence?: number |
7 | language?: string | 10 | language?: string |
8 | description?: string | 11 | description?: string |
9 | support?: string | 12 | support?: string |
10 | channelId: number | ||
11 | nsfw?: boolean | 13 | nsfw?: boolean |
12 | waitTranscoding?: boolean | 14 | waitTranscoding?: boolean |
13 | name: string | ||
14 | tags?: string[] | 15 | tags?: string[] |
15 | commentsEnabled?: boolean | 16 | commentsEnabled?: boolean |
16 | downloadEnabled?: boolean | 17 | downloadEnabled?: boolean |