Repository: blakeblackshear/frigate

Issue:
Set `-user_agent` in `ffmpeg` calls
**Describe what you are trying to accomplish and why in non technical terms**
When spoofing who is connecting to my cameras, I can easily distinguish some like Home Assistant, or Google Chrome. But Frigate is also connected to them, but since `-user_agent` is not set, it's not easi to distinguish.

![image](https://user-images.githubusercontent.com/29582865/201259480-8b263732-8796-47c4-9cd6-2de3f159ebfb.png)

**Describe the solution you'd like**
This can be set with the `-user_agent` ffmpeg flag. In order of usefulness but also in order of difficulty to implement:

1. `-user_agent 'Frigate'` already much better than now
2. `-user_agent 'Frigate/0.11.1'`
3. `-user_agent 'Frigate/0.11.1 FFmpeg'`
4. `-user_agent 'Frigate/0.11.1 FFmpeg/3.1.2'`

I guess that, with the FFmpeg version in the string we don't need the `Lavf59.27.100` either. But it wouldn't hurt to even add the `Lavf59.27.100`, I guess.

**Describe alternatives you've considered**
I can probably set this by myself using the args, but I think this deserves to come by default.

**Additional context**
- Refs https://github.com/AlexxIT/go2rtc/issues/106



Discussion:

Resolving patch:
diff --git a/frigate/config.py b/frigate/config.py
--- a/frigate/config.py
+++ b/frigate/config.py
@@ -32,6 +32,7 @@
     parse_preset_output_record,
     parse_preset_output_rtmp,
 )
+from frigate.version import VERSION
 
 logger = logging.getLogger(__name__)
 
@@ -357,7 +358,13 @@ class BirdseyeCameraConfig(BaseModel):
     )
 
 
-FFMPEG_GLOBAL_ARGS_DEFAULT = ["-hide_banner", "-loglevel", "warning"]
+FFMPEG_GLOBAL_ARGS_DEFAULT = [
+    "-hide_banner",
+    "-loglevel",
+    "warning",
+    "-user_agent",
+    f"FFmpeg Frigate/{VERSION}",
+]
 FFMPEG_INPUT_ARGS_DEFAULT = [
     "-avoid_negative_ts",
     "make_zero",
diff --git a/frigate/util.py b/frigate/util.py
--- a/frigate/util.py
+++ b/frigate/util.py
@@ -1,6 +1,7 @@
 import copy
 import datetime
 import logging
+import shlex
 import subprocess as sp
 import json
 import re
@@ -888,7 +889,7 @@ def vainfo_hwaccel() -> sp.CompletedProcess:
 
 def get_ffmpeg_arg_list(arg: Any) -> list:
     """Use arg if list or convert to list format."""
-    return arg if isinstance(arg, list) else arg.split(" ")
+    return arg if isinstance(arg, list) else shlex.split(arg)
 
 
 class FrameManager(ABC):


Test patch:
diff --git a/frigate/test/test_ffmpeg_presets.py b/frigate/test/test_ffmpeg_presets.py
--- a/frigate/test/test_ffmpeg_presets.py
+++ b/frigate/test/test_ffmpeg_presets.py
@@ -1,5 +1,5 @@
 import unittest
-from frigate.config import FrigateConfig
+from frigate.config import FFMPEG_INPUT_ARGS_DEFAULT, FrigateConfig
 from frigate.ffmpeg_presets import parse_preset_input
 
 
@@ -93,6 +93,16 @@ def test_ffmpeg_input_preset(self):
             " ".join(frigate_config.cameras["back"].ffmpeg_cmds[0]["cmd"])
         )
 
+    def test_ffmpeg_input_args_as_string(self):
+        argsString = " ".join(FFMPEG_INPUT_ARGS_DEFAULT) + ' -some "arg with space"'
+        argsList = FFMPEG_INPUT_ARGS_DEFAULT + ["-some", "arg with space"]
+        self.default_ffmpeg["cameras"]["back"]["ffmpeg"]["input_args"] = argsString
+        frigate_config = FrigateConfig(**self.default_ffmpeg)
+        frigate_config.cameras["back"].create_ffmpeg_cmds()
+        assert set(argsList).issubset(
+            frigate_config.cameras["back"].ffmpeg_cmds[0]["cmd"]
+        )
+
     def test_ffmpeg_input_not_preset(self):
         self.default_ffmpeg["cameras"]["back"]["ffmpeg"]["input_args"] = "-some inputs"
         frigate_config = FrigateConfig(**self.default_ffmpeg)