aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/helpers
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2022-03-04 13:40:02 +0100
committerChocobozzz <chocobozzz@cpy.re>2022-03-09 09:23:10 +0100
commitf443a74649174b2f9347c158e30f8ac7aa3e958a (patch)
treee423bc4e2307477bda4341037b7fa04ad10adae6 /server/helpers
parent01dd04cd5ab7b55d2a9af7d0ebf405bee9579b09 (diff)
downloadPeerTube-f443a74649174b2f9347c158e30f8ac7aa3e958a.tar.gz
PeerTube-f443a74649174b2f9347c158e30f8ac7aa3e958a.tar.zst
PeerTube-f443a74649174b2f9347c158e30f8ac7aa3e958a.zip
Add latency setting support
Diffstat (limited to 'server/helpers')
-rw-r--r--server/helpers/activitypub.ts4
-rw-r--r--server/helpers/custom-validators/activitypub/videos.ts4
-rw-r--r--server/helpers/custom-validators/video-lives.ts11
-rw-r--r--server/helpers/ffmpeg/ffmpeg-live.ts39
4 files changed, 50 insertions, 8 deletions
diff --git a/server/helpers/activitypub.ts b/server/helpers/activitypub.ts
index cbba2f51c..d0bcc6785 100644
--- a/server/helpers/activitypub.ts
+++ b/server/helpers/activitypub.ts
@@ -50,6 +50,10 @@ function getContextData (type: ContextType) {
50 '@type': 'sc:Boolean', 50 '@type': 'sc:Boolean',
51 '@id': 'pt:permanentLive' 51 '@id': 'pt:permanentLive'
52 }, 52 },
53 latencyMode: {
54 '@type': 'sc:Number',
55 '@id': 'pt:latencyMode'
56 },
53 57
54 Infohash: 'pt:Infohash', 58 Infohash: 'pt:Infohash',
55 Playlist: 'pt:Playlist', 59 Playlist: 'pt:Playlist',
diff --git a/server/helpers/custom-validators/activitypub/videos.ts b/server/helpers/custom-validators/activitypub/videos.ts
index a41d37810..80a321117 100644
--- a/server/helpers/custom-validators/activitypub/videos.ts
+++ b/server/helpers/custom-validators/activitypub/videos.ts
@@ -1,10 +1,11 @@
1import validator from 'validator' 1import validator from 'validator'
2import { logger } from '@server/helpers/logger' 2import { logger } from '@server/helpers/logger'
3import { ActivityTrackerUrlObject, ActivityVideoFileMetadataUrlObject } from '@shared/models' 3import { ActivityTrackerUrlObject, ActivityVideoFileMetadataUrlObject } from '@shared/models'
4import { VideoState } from '../../../../shared/models/videos' 4import { LiveVideoLatencyMode, VideoState } from '../../../../shared/models/videos'
5import { ACTIVITY_PUB, CONSTRAINTS_FIELDS } from '../../../initializers/constants' 5import { ACTIVITY_PUB, CONSTRAINTS_FIELDS } from '../../../initializers/constants'
6import { peertubeTruncate } from '../../core-utils' 6import { peertubeTruncate } from '../../core-utils'
7import { exists, isArray, isBooleanValid, isDateValid, isUUIDValid } from '../misc' 7import { exists, isArray, isBooleanValid, isDateValid, isUUIDValid } from '../misc'
8import { isLiveLatencyModeValid } from '../video-lives'
8import { 9import {
9 isVideoDurationValid, 10 isVideoDurationValid,
10 isVideoNameValid, 11 isVideoNameValid,
@@ -65,6 +66,7 @@ function sanitizeAndCheckVideoTorrentObject (video: any) {
65 if (!isBooleanValid(video.isLiveBroadcast)) video.isLiveBroadcast = false 66 if (!isBooleanValid(video.isLiveBroadcast)) video.isLiveBroadcast = false
66 if (!isBooleanValid(video.liveSaveReplay)) video.liveSaveReplay = false 67 if (!isBooleanValid(video.liveSaveReplay)) video.liveSaveReplay = false
67 if (!isBooleanValid(video.permanentLive)) video.permanentLive = false 68 if (!isBooleanValid(video.permanentLive)) video.permanentLive = false
69 if (!isLiveLatencyModeValid(video.latencyMode)) video.latencyMode = LiveVideoLatencyMode.DEFAULT
68 70
69 return isActivityPubUrlValid(video.id) && 71 return isActivityPubUrlValid(video.id) &&
70 isVideoNameValid(video.name) && 72 isVideoNameValid(video.name) &&
diff --git a/server/helpers/custom-validators/video-lives.ts b/server/helpers/custom-validators/video-lives.ts
new file mode 100644
index 000000000..69d08ae68
--- /dev/null
+++ b/server/helpers/custom-validators/video-lives.ts
@@ -0,0 +1,11 @@
1import { LiveVideoLatencyMode } from '@shared/models'
2
3function isLiveLatencyModeValid (value: any) {
4 return [ LiveVideoLatencyMode.DEFAULT, LiveVideoLatencyMode.SMALL_LATENCY, LiveVideoLatencyMode.HIGH_LATENCY ].includes(value)
5}
6
7// ---------------------------------------------------------------------------
8
9export {
10 isLiveLatencyModeValid
11}
diff --git a/server/helpers/ffmpeg/ffmpeg-live.ts b/server/helpers/ffmpeg/ffmpeg-live.ts
index ff571626c..fd20971eb 100644
--- a/server/helpers/ffmpeg/ffmpeg-live.ts
+++ b/server/helpers/ffmpeg/ffmpeg-live.ts
@@ -1,7 +1,7 @@
1import { FfmpegCommand, FilterSpecification } from 'fluent-ffmpeg' 1import { FfmpegCommand, FilterSpecification } from 'fluent-ffmpeg'
2import { join } from 'path' 2import { join } from 'path'
3import { VIDEO_LIVE } from '@server/initializers/constants' 3import { VIDEO_LIVE } from '@server/initializers/constants'
4import { AvailableEncoders } from '@shared/models' 4import { AvailableEncoders, LiveVideoLatencyMode } from '@shared/models'
5import { logger, loggerTagsFactory } from '../logger' 5import { logger, loggerTagsFactory } from '../logger'
6import { buildStreamSuffix, getFFmpeg, getScaleFilter, StreamType } from './ffmpeg-commons' 6import { buildStreamSuffix, getFFmpeg, getScaleFilter, StreamType } from './ffmpeg-commons'
7import { getEncoderBuilderResult } from './ffmpeg-encoders' 7import { getEncoderBuilderResult } from './ffmpeg-encoders'
@@ -15,6 +15,7 @@ async function getLiveTranscodingCommand (options: {
15 15
16 outPath: string 16 outPath: string
17 masterPlaylistName: string 17 masterPlaylistName: string
18 latencyMode: LiveVideoLatencyMode
18 19
19 resolutions: number[] 20 resolutions: number[]
20 21
@@ -26,7 +27,7 @@ async function getLiveTranscodingCommand (options: {
26 availableEncoders: AvailableEncoders 27 availableEncoders: AvailableEncoders
27 profile: string 28 profile: string
28}) { 29}) {
29 const { inputUrl, outPath, resolutions, fps, bitrate, availableEncoders, profile, masterPlaylistName, ratio } = options 30 const { inputUrl, outPath, resolutions, fps, bitrate, availableEncoders, profile, masterPlaylistName, ratio, latencyMode } = options
30 31
31 const command = getFFmpeg(inputUrl, 'live') 32 const command = getFFmpeg(inputUrl, 'live')
32 33
@@ -120,14 +121,21 @@ async function getLiveTranscodingCommand (options: {
120 121
121 command.complexFilter(complexFilter) 122 command.complexFilter(complexFilter)
122 123
123 addDefaultLiveHLSParams(command, outPath, masterPlaylistName) 124 addDefaultLiveHLSParams({ command, outPath, masterPlaylistName, latencyMode })
124 125
125 command.outputOption('-var_stream_map', varStreamMap.join(' ')) 126 command.outputOption('-var_stream_map', varStreamMap.join(' '))
126 127
127 return command 128 return command
128} 129}
129 130
130function getLiveMuxingCommand (inputUrl: string, outPath: string, masterPlaylistName: string) { 131function getLiveMuxingCommand (options: {
132 inputUrl: string
133 outPath: string
134 masterPlaylistName: string
135 latencyMode: LiveVideoLatencyMode
136}) {
137 const { inputUrl, outPath, masterPlaylistName, latencyMode } = options
138
131 const command = getFFmpeg(inputUrl, 'live') 139 const command = getFFmpeg(inputUrl, 'live')
132 140
133 command.outputOption('-c:v copy') 141 command.outputOption('-c:v copy')
@@ -135,22 +143,39 @@ function getLiveMuxingCommand (inputUrl: string, outPath: string, masterPlaylist
135 command.outputOption('-map 0:a?') 143 command.outputOption('-map 0:a?')
136 command.outputOption('-map 0:v?') 144 command.outputOption('-map 0:v?')
137 145
138 addDefaultLiveHLSParams(command, outPath, masterPlaylistName) 146 addDefaultLiveHLSParams({ command, outPath, masterPlaylistName, latencyMode })
139 147
140 return command 148 return command
141} 149}
142 150
151function getLiveSegmentTime (latencyMode: LiveVideoLatencyMode) {
152 if (latencyMode === LiveVideoLatencyMode.SMALL_LATENCY) {
153 return VIDEO_LIVE.SEGMENT_TIME_SECONDS.SMALL_LATENCY
154 }
155
156 return VIDEO_LIVE.SEGMENT_TIME_SECONDS.DEFAULT_LATENCY
157}
158
143// --------------------------------------------------------------------------- 159// ---------------------------------------------------------------------------
144 160
145export { 161export {
162 getLiveSegmentTime,
163
146 getLiveTranscodingCommand, 164 getLiveTranscodingCommand,
147 getLiveMuxingCommand 165 getLiveMuxingCommand
148} 166}
149 167
150// --------------------------------------------------------------------------- 168// ---------------------------------------------------------------------------
151 169
152function addDefaultLiveHLSParams (command: FfmpegCommand, outPath: string, masterPlaylistName: string) { 170function addDefaultLiveHLSParams (options: {
153 command.outputOption('-hls_time ' + VIDEO_LIVE.SEGMENT_TIME_SECONDS) 171 command: FfmpegCommand
172 outPath: string
173 masterPlaylistName: string
174 latencyMode: LiveVideoLatencyMode
175}) {
176 const { command, outPath, masterPlaylistName, latencyMode } = options
177
178 command.outputOption('-hls_time ' + getLiveSegmentTime(latencyMode))
154 command.outputOption('-hls_list_size ' + VIDEO_LIVE.SEGMENTS_LIST_SIZE) 179 command.outputOption('-hls_list_size ' + VIDEO_LIVE.SEGMENTS_LIST_SIZE)
155 command.outputOption('-hls_flags delete_segments+independent_segments') 180 command.outputOption('-hls_flags delete_segments+independent_segments')
156 command.outputOption(`-hls_segment_filename ${join(outPath, '%v-%06d.ts')}`) 181 command.outputOption(`-hls_segment_filename ${join(outPath, '%v-%06d.ts')}`)