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 10a61315f80..20009093857 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 c1ec3ce0157..f0cadef16f1 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 7894cd93e8c208b53663c3a1eae3e83ba6f1b6fd 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 Signed-off-by: Rutger Putter --- 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 20009093857..99515528876 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 f0cadef16f1..5edea0a34bc 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 6d9099c4dae..38e6535eeff 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 17e83788d0451ba6d74bcf1a711cee98e87a7caf 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 7748aa400ec..1fa72635f82 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 b55f38169dc..af9c43f6e4e 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 30163315e013c0960b484ddc4be42e462e8bd1b5 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 Signed-off-by: Rutger Putter --- 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 af9c43f6e4e..cafac515f86 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 38e6535eeff..f228fb686aa 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