From 9cd3e016aa82671592ae78583139e368cec10681 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Fri, 15 Sep 2023 14:02:17 +0200 Subject: [PATCH 1/4] Replace "FFmpeg" with "ffmpeg" when referring to the executable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit FFmpeg is the project/framework name, while "ffmpeg" is the name of the tool. Signed-off-by: Daniel Calviño Sánchez --- recording/server.conf.in | 4 ++-- recording/src/nextcloud/talk/recording/Config.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/recording/server.conf.in b/recording/server.conf.in index 10a61315f80a..20009093857f 100644 --- a/recording/server.conf.in +++ b/recording/server.conf.in @@ -96,11 +96,11 @@ #internalsecret = the-shared-secret-for-internal-clients [ffmpeg] -# The options given to FFmpeg to encode the audio output. The options given here +# 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/Config.py b/recording/src/nextcloud/talk/recording/Config.py index c1ec3ce0157b..f0cadef16f16 100644 --- a/recording/src/nextcloud/talk/recording/Config.py +++ b/recording/src/nextcloud/talk/recording/Config.py @@ -207,7 +207,7 @@ def getSignalingSecret(self, signalingUrl): 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 +215,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']. """ From 43ecc699e9035bb23d8f3f6d1e6bdfce582408ba Mon Sep 17 00:00:00 2001 From: Rutger Putter Date: Tue, 2 May 2023 13:59:54 +0200 Subject: [PATCH 2/4] feat(ffmpeg): allow custom common options --- recording/server.conf.in | 4 ++++ recording/src/nextcloud/talk/recording/Config.py | 9 +++++++++ .../nextcloud/talk/recording/RecorderArgumentsBuilder.py | 9 ++++++++- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/recording/server.conf.in b/recording/server.conf.in index 20009093857f..995155288768 100644 --- a/recording/server.conf.in +++ b/recording/server.conf.in @@ -96,6 +96,10 @@ #internalsecret = the-shared-secret-for-internal-clients [ffmpeg] +# 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 diff --git a/recording/src/nextcloud/talk/recording/Config.py b/recording/src/nextcloud/talk/recording/Config.py index f0cadef16f16..5edea0a34bc9 100644 --- a/recording/src/nextcloud/talk/recording/Config.py +++ b/recording/src/nextcloud/talk/recording/Config.py @@ -205,6 +205,15 @@ 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. diff --git a/recording/src/nextcloud/talk/recording/RecorderArgumentsBuilder.py b/recording/src/nextcloud/talk/recording/RecorderArgumentsBuilder.py index 6d9099c4dae3..38e6535eeff7 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 From 7aae0ed1ed30fc35f23a15797ee5e8dc0c2d56e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Fri, 15 Sep 2023 14:17:52 +0200 Subject: [PATCH 3/4] Make explicit that audio and video options are given to ffmpeg MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is more consistent with the configuration file, and it will be also more consistent with the argument that will be added to the benchmark to customize the ffmpeg executable and global options. Signed-off-by: Daniel Calviño Sánchez --- recording/docs/encoders.md | 6 +++--- recording/src/nextcloud/talk/recording/Benchmark.py | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) 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/src/nextcloud/talk/recording/Benchmark.py b/recording/src/nextcloud/talk/recording/Benchmark.py index b55f38169dc6..af9c43f6e4e8 100644 --- a/recording/src/nextcloud/talk/recording/Benchmark.py +++ b/recording/src/nextcloud/talk/recording/Benchmark.py @@ -164,8 +164,8 @@ 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.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 +277,8 @@ 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-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") From 92b74622e07e1a1e9860eed675ae64db90f5a12c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Fri, 15 Sep 2023 14:22:06 +0200 Subject: [PATCH 4/4] Allow configuring ffmpeg executable and global options also in benchmark MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Calviño Sánchez --- recording/src/nextcloud/talk/recording/Benchmark.py | 2 ++ .../src/nextcloud/talk/recording/RecorderArgumentsBuilder.py | 3 +++ 2 files changed, 5 insertions(+) diff --git a/recording/src/nextcloud/talk/recording/Benchmark.py b/recording/src/nextcloud/talk/recording/Benchmark.py index af9c43f6e4e8..cafac515f86e 100644 --- a/recording/src/nextcloud/talk/recording/Benchmark.py +++ b/recording/src/nextcloud/talk/recording/Benchmark.py @@ -164,6 +164,7 @@ def run(self, args): status = RECORDING_STATUS_AUDIO_ONLY if args.audio_only else RECORDING_STATUS_AUDIO_AND_VIDEO recorderArgumentsBuilder = RecorderArgumentsBuilder() + recorderArgumentsBuilder.setFfmpegCommon(args.ffmpeg_common.split()) recorderArgumentsBuilder.setFfmpegOutputAudio(args.ffmpeg_output_audio.split()) recorderArgumentsBuilder.setFfmpegOutputVideo(args.ffmpeg_output_video.split()) recorderArgumentsBuilder.setExtension(f".{extension}") @@ -277,6 +278,7 @@ 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("--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") diff --git a/recording/src/nextcloud/talk/recording/RecorderArgumentsBuilder.py b/recording/src/nextcloud/talk/recording/RecorderArgumentsBuilder.py index 38e6535eeff7..f228fb686aab 100644 --- a/recording/src/nextcloud/talk/recording/RecorderArgumentsBuilder.py +++ b/recording/src/nextcloud/talk/recording/RecorderArgumentsBuilder.py @@ -102,6 +102,9 @@ def getExtension(self, status): return config.getFfmpegExtensionAudio() + def setFfmpegCommon(self, ffmpegCommon): + self._ffmpegCommon = ffmpegCommon + def setFfmpegOutputAudio(self, ffmpegOutputAudio): self._ffmpegOutputAudio = ffmpegOutputAudio