diff --git a/recording/docs/encoders.md b/recording/docs/encoders.md index 7748aa400ec3..1fa72635f82e 100644 --- a/recording/docs/encoders.md +++ b/recording/docs/encoders.md @@ -22,7 +22,7 @@ Each run of the benchmark tool records a single video (or audio) file with the g ``` #!/usr/bin/bash -# Define the video arguments and the filename suffix to use for each test. +# Define the output video options for ffmpeg and the filename suffix to use for each test. TESTS=( "-c:v libvpx -deadline:v realtime -b:v 0,rt-b0" "-c:v libvpx -deadline:v realtime -b:v 0 -cpu-used:v 0,rt-b0-cpu0" @@ -49,8 +49,8 @@ TESTS=( for TEST in "${TESTS[@]}" do # Split the input tuple on "," - IFS="," read VIDEO_ARGS FILENAME_SUFFIX <<< "${TEST}" + IFS="," read FFMPEG_OUTPUT_VIDEO FILENAME_SUFFIX <<< "${TEST}" # Run the test - python3 -m nextcloud.talk.recording.Benchmark --length 300 --video-args "${VIDEO_ARGS}" /tmp/recording/files/example.mkv /tmp/recording/files/test-"${FILENAME_SUFFIX}".webm + python3 -m nextcloud.talk.recording.Benchmark --length 300 --ffmpeg-output-video "${FFMPEG_OUTPUT_VIDEO}" /tmp/recording/files/example.mkv /tmp/recording/files/test-"${FILENAME_SUFFIX}".webm done ``` diff --git a/recording/server.conf.in b/recording/server.conf.in index 10a61315f80a..995155288768 100644 --- a/recording/server.conf.in +++ b/recording/server.conf.in @@ -96,11 +96,15 @@ #internalsecret = the-shared-secret-for-internal-clients [ffmpeg] -# The options given to FFmpeg to encode the audio output. The options given here +# The ffmpeg executable (name or full path) and the global options given to +# ffmpeg. The options given here fully override the default global options. +#common = ffmpeg -loglevel level+warning -n + +# The options given to ffmpeg to encode the audio output. The options given here # fully override the default options for the audio output. #outputaudio = -c:a libopus -# The options given to FFmpeg to encode the video output. The options given here +# The options given to ffmpeg to encode the video output. The options given here # fully override the default options for the video output. #outputvideo = -c:v libvpx -deadline:v realtime -crf 10 -b:v 1M diff --git a/recording/src/nextcloud/talk/recording/Benchmark.py b/recording/src/nextcloud/talk/recording/Benchmark.py index b55f38169dc6..cafac515f86e 100644 --- a/recording/src/nextcloud/talk/recording/Benchmark.py +++ b/recording/src/nextcloud/talk/recording/Benchmark.py @@ -164,8 +164,9 @@ def run(self, args): status = RECORDING_STATUS_AUDIO_ONLY if args.audio_only else RECORDING_STATUS_AUDIO_AND_VIDEO recorderArgumentsBuilder = RecorderArgumentsBuilder() - recorderArgumentsBuilder.setFfmpegOutputAudio(args.audio_args.split()) - recorderArgumentsBuilder.setFfmpegOutputVideo(args.video_args.split()) + recorderArgumentsBuilder.setFfmpegCommon(args.ffmpeg_common.split()) + recorderArgumentsBuilder.setFfmpegOutputAudio(args.ffmpeg_output_audio.split()) + recorderArgumentsBuilder.setFfmpegOutputVideo(args.ffmpeg_output_video.split()) recorderArgumentsBuilder.setExtension(f".{extension}") self._recorderArguments = recorderArgumentsBuilder.getRecorderArguments(status, self._display.new_display_var, audioSourceIndex, args.width, args.height, extensionlessFileName) @@ -277,8 +278,9 @@ def main(): parser.add_argument("-l", "--length", help="benchmark duration (in seconds)", default=180, type=int) parser.add_argument("--width", help="output width", default=defaultConfig.getBackendVideoWidth(""), type=int) parser.add_argument("--height", help="output height", default=defaultConfig.getBackendVideoHeight(""), type=int) - parser.add_argument("--audio-args", help="output audio arguments for ffmpeg", default=" ".join(defaultConfig.getFfmpegOutputAudio()), type=str) - parser.add_argument("--video-args", help="output video arguments for ffmpeg", default=" ".join(defaultConfig.getFfmpegOutputVideo()), type=str) + parser.add_argument("--ffmpeg-common", help="ffmpeg executable and global options", default=" ".join(defaultConfig.getFfmpegCommon()), type=str) + parser.add_argument("--ffmpeg-output-audio", help="output audio options for ffmpeg", default=" ".join(defaultConfig.getFfmpegOutputAudio()), type=str) + parser.add_argument("--ffmpeg-output-video", help="output video options for ffmpeg", default=" ".join(defaultConfig.getFfmpegOutputVideo()), type=str) parser.add_argument("--audio-only", help="audio only recording", action="store_true") parser.add_argument("-v", "--verbose", help="verbose mode", action="store_true") parser.add_argument("--verbose-extra", help="extra verbose mode", action="store_true") diff --git a/recording/src/nextcloud/talk/recording/Config.py b/recording/src/nextcloud/talk/recording/Config.py index c1ec3ce0157b..5edea0a34bc9 100644 --- a/recording/src/nextcloud/talk/recording/Config.py +++ b/recording/src/nextcloud/talk/recording/Config.py @@ -205,9 +205,18 @@ def getSignalingSecret(self, signalingUrl): return self._configParser.get('signaling', 'internalsecret', fallback=None) + def getFfmpegCommon(self): + """ + Returns the ffmpeg executable (name or full path) and the global options + given to ffmpeg. + + Defaults to ['ffmpeg', '-loglevel', 'level+warning', '-n']. + """ + return self._configParser.get('ffmpeg', 'common', fallback='ffmpeg -loglevel level+warning -n').split() + def getFfmpegOutputAudio(self): """ - Returns the options given to FFmpeg to encode the audio output. + Returns the options given to ffmpeg to encode the audio output. Defaults to ['-c:a', 'libopus']. """ @@ -215,7 +224,7 @@ def getFfmpegOutputAudio(self): def getFfmpegOutputVideo(self): """ - Returns the options given to FFmpeg to encode the video output. + Returns the options given to ffmpeg to encode the video output. Defaults to ['-c:v', 'libvpx', '-deadline:v', 'realtime', '-crf', '10', '-b:v', '1M']. """ diff --git a/recording/src/nextcloud/talk/recording/RecorderArgumentsBuilder.py b/recording/src/nextcloud/talk/recording/RecorderArgumentsBuilder.py index 6d9099c4dae3..f228fb686aab 100644 --- a/recording/src/nextcloud/talk/recording/RecorderArgumentsBuilder.py +++ b/recording/src/nextcloud/talk/recording/RecorderArgumentsBuilder.py @@ -32,6 +32,7 @@ class RecorderArgumentsBuilder: """ def __init__(self): + self._ffmpegCommon = None self._ffmpegOutputAudio = None self._ffmpegOutputVideo = None self._extension = None @@ -51,7 +52,7 @@ def getRecorderArguments(self, status, displayId, audioSourceIndex, width, heigh :returns: the file name for the recording, with extension. """ - ffmpegCommon = ['ffmpeg', '-loglevel', 'level+warning', '-n'] + ffmpegCommon = self.getFfmpegCommon() ffmpegInputAudio = ['-f', 'pulse', '-i', audioSourceIndex] ffmpegInputVideo = ['-f', 'x11grab', '-draw_mouse', '0', '-video_size', f'{width}x{height}', '-i', displayId] ffmpegOutputAudio = self.getFfmpegOutputAudio() @@ -74,6 +75,12 @@ def getRecorderArguments(self, status, displayId, audioSourceIndex, width, heigh return ffmpegArguments + [outputFileName] + def getFfmpegCommon(self): + if self._ffmpegCommon != None: + return self._ffmpegCommon + + return config.getFfmpegCommon() + def getFfmpegOutputAudio(self): if self._ffmpegOutputAudio != None: return self._ffmpegOutputAudio @@ -95,6 +102,9 @@ def getExtension(self, status): return config.getFfmpegExtensionAudio() + def setFfmpegCommon(self, ffmpegCommon): + self._ffmpegCommon = ffmpegCommon + def setFfmpegOutputAudio(self, ffmpegOutputAudio): self._ffmpegOutputAudio = ffmpegOutputAudio