diff options
Diffstat (limited to 'shared')
-rw-r--r-- | shared/extra-utils/index.ts | 3 | ||||
-rw-r--r-- | shared/extra-utils/requests/requests.ts | 4 | ||||
-rw-r--r-- | shared/extra-utils/videos/live.ts | 102 | ||||
-rw-r--r-- | shared/models/videos/video-create.model.ts | 3 |
4 files changed, 109 insertions, 3 deletions
diff --git a/shared/extra-utils/index.ts b/shared/extra-utils/index.ts index af4d23856..d118b12d2 100644 --- a/shared/extra-utils/index.ts +++ b/shared/extra-utils/index.ts | |||
@@ -13,11 +13,12 @@ export * from './requests/requests' | |||
13 | export * from './requests/check-api-params' | 13 | export * from './requests/check-api-params' |
14 | export * from './server/servers' | 14 | export * from './server/servers' |
15 | export * from './server/plugins' | 15 | export * from './server/plugins' |
16 | export * from './videos/services' | ||
17 | export * from './videos/video-playlists' | 16 | export * from './videos/video-playlists' |
18 | export * from './users/users' | 17 | export * from './users/users' |
19 | export * from './users/accounts' | 18 | export * from './users/accounts' |
20 | export * from './moderation/abuses' | 19 | export * from './moderation/abuses' |
20 | export * from './videos/services' | ||
21 | export * from './videos/live' | ||
21 | export * from './videos/video-abuses' | 22 | export * from './videos/video-abuses' |
22 | export * from './videos/video-blacklist' | 23 | export * from './videos/video-blacklist' |
23 | export * from './videos/video-captions' | 24 | export * from './videos/video-captions' |
diff --git a/shared/extra-utils/requests/requests.ts b/shared/extra-utils/requests/requests.ts index 0e9d67f0b..6b00871e0 100644 --- a/shared/extra-utils/requests/requests.ts +++ b/shared/extra-utils/requests/requests.ts | |||
@@ -63,7 +63,7 @@ function makeUploadRequest (options: { | |||
63 | path: string | 63 | path: string |
64 | token?: string | 64 | token?: string |
65 | fields: { [ fieldName: string ]: any } | 65 | fields: { [ fieldName: string ]: any } |
66 | attaches: { [ attachName: string ]: any | any[] } | 66 | attaches?: { [ attachName: string ]: any | any[] } |
67 | statusCodeExpected?: number | 67 | statusCodeExpected?: number |
68 | }) { | 68 | }) { |
69 | if (!options.statusCodeExpected) options.statusCodeExpected = 400 | 69 | if (!options.statusCodeExpected) options.statusCodeExpected = 400 |
@@ -93,7 +93,7 @@ function makeUploadRequest (options: { | |||
93 | } | 93 | } |
94 | }) | 94 | }) |
95 | 95 | ||
96 | Object.keys(options.attaches).forEach(attach => { | 96 | Object.keys(options.attaches || {}).forEach(attach => { |
97 | const value = options.attaches[attach] | 97 | const value = options.attaches[attach] |
98 | if (Array.isArray(value)) { | 98 | if (Array.isArray(value)) { |
99 | req.attach(attach, buildAbsoluteFixturePath(value[0]), value[1]) | 99 | req.attach(attach, buildAbsoluteFixturePath(value[0]), value[1]) |
diff --git a/shared/extra-utils/videos/live.ts b/shared/extra-utils/videos/live.ts new file mode 100644 index 000000000..f500fdc3e --- /dev/null +++ b/shared/extra-utils/videos/live.ts | |||
@@ -0,0 +1,102 @@ | |||
1 | import * as ffmpeg from 'fluent-ffmpeg' | ||
2 | import { LiveVideoCreate, LiveVideoUpdate, VideoDetails, VideoState } from '@shared/models' | ||
3 | import { buildAbsoluteFixturePath, wait } from '../miscs/miscs' | ||
4 | import { makeGetRequest, makePutBodyRequest, makeUploadRequest } from '../requests/requests' | ||
5 | import { ServerInfo } from '../server/servers' | ||
6 | import { getVideo, getVideoWithToken } from './videos' | ||
7 | |||
8 | function getLive (url: string, token: string, videoId: number | string, statusCodeExpected = 200) { | ||
9 | const path = '/api/v1/videos/live' | ||
10 | |||
11 | return makeGetRequest({ | ||
12 | url, | ||
13 | token, | ||
14 | path: path + '/' + videoId, | ||
15 | statusCodeExpected | ||
16 | }) | ||
17 | } | ||
18 | |||
19 | function updateLive (url: string, token: string, videoId: number | string, fields: LiveVideoUpdate, statusCodeExpected = 204) { | ||
20 | const path = '/api/v1/videos/live' | ||
21 | |||
22 | return makePutBodyRequest({ | ||
23 | url, | ||
24 | token, | ||
25 | path: path + '/' + videoId, | ||
26 | fields, | ||
27 | statusCodeExpected | ||
28 | }) | ||
29 | } | ||
30 | |||
31 | function createLive (url: string, token: string, fields: LiveVideoCreate, statusCodeExpected = 200) { | ||
32 | const path = '/api/v1/videos/live' | ||
33 | |||
34 | let attaches: any = {} | ||
35 | if (fields.thumbnailfile) attaches = { thumbnailfile: fields.thumbnailfile } | ||
36 | if (fields.previewfile) attaches = { previewfile: fields.previewfile } | ||
37 | |||
38 | return makeUploadRequest({ | ||
39 | url, | ||
40 | path, | ||
41 | token, | ||
42 | attaches, | ||
43 | fields, | ||
44 | statusCodeExpected | ||
45 | }) | ||
46 | } | ||
47 | |||
48 | function sendRTMPStream (rtmpBaseUrl: string, streamKey: string) { | ||
49 | const fixture = buildAbsoluteFixturePath('video_short.mp4') | ||
50 | |||
51 | const command = ffmpeg(fixture) | ||
52 | command.inputOption('-stream_loop -1') | ||
53 | command.inputOption('-re') | ||
54 | |||
55 | command.outputOption('-c copy') | ||
56 | command.outputOption('-f flv') | ||
57 | |||
58 | const rtmpUrl = rtmpBaseUrl + '/' + streamKey | ||
59 | command.output(rtmpUrl) | ||
60 | |||
61 | command.on('error', err => { | ||
62 | if (err?.message?.includes('Exiting normally')) return | ||
63 | |||
64 | console.error('Cannot send RTMP stream.', { err }) | ||
65 | }) | ||
66 | |||
67 | if (process.env.DEBUG) { | ||
68 | command.on('stderr', data => console.log(data)) | ||
69 | } | ||
70 | |||
71 | command.run() | ||
72 | |||
73 | return command | ||
74 | } | ||
75 | |||
76 | async function stopFfmpeg (command: ffmpeg.FfmpegCommand) { | ||
77 | command.kill('SIGINT') | ||
78 | |||
79 | await wait(500) | ||
80 | } | ||
81 | |||
82 | async function waitUntilLiveStarts (url: string, token: string, videoId: number | string) { | ||
83 | let video: VideoDetails | ||
84 | |||
85 | do { | ||
86 | const res = await getVideoWithToken(url, token, videoId) | ||
87 | video = res.body | ||
88 | |||
89 | await wait(500) | ||
90 | } while (video.state.id === VideoState.WAITING_FOR_LIVE) | ||
91 | } | ||
92 | |||
93 | // --------------------------------------------------------------------------- | ||
94 | |||
95 | export { | ||
96 | getLive, | ||
97 | updateLive, | ||
98 | waitUntilLiveStarts, | ||
99 | createLive, | ||
100 | stopFfmpeg, | ||
101 | sendRTMPStream | ||
102 | } | ||
diff --git a/shared/models/videos/video-create.model.ts b/shared/models/videos/video-create.model.ts index 59b118567..175327afa 100644 --- a/shared/models/videos/video-create.model.ts +++ b/shared/models/videos/video-create.model.ts | |||
@@ -17,4 +17,7 @@ export interface VideoCreate { | |||
17 | privacy: VideoPrivacy | 17 | privacy: VideoPrivacy |
18 | scheduleUpdate?: VideoScheduleUpdate | 18 | scheduleUpdate?: VideoScheduleUpdate |
19 | originallyPublishedAt?: Date | string | 19 | originallyPublishedAt?: Date | string |
20 | |||
21 | thumbnailfile?: Blob | ||
22 | previewfile?: Blob | ||
20 | } | 23 | } |