From 7f42c1ad440f5fda87ca42d5e2f664b86f04dfb3 Mon Sep 17 00:00:00 2001
From: interfect <interfect@gmail.com>
Date: Thu, 21 Jan 2021 15:11:53 +0100
Subject: [PATCH] Autodetect format when transcoding files

---
 api/funkwhale_api/music/models.py |  3 +--
 api/funkwhale_api/music/utils.py  |  2 +-
 api/tests/music/test_utils.py     | 21 +++++++++++++++++++++
 changes/changelog.d/1274.bugfix   |  1 +
 4 files changed, 24 insertions(+), 3 deletions(-)
 create mode 100644 changes/changelog.d/1274.bugfix

diff --git a/api/funkwhale_api/music/models.py b/api/funkwhale_api/music/models.py
index f95a8bb3b1..3e39e91e2d 100644
--- a/api/funkwhale_api/music/models.py
+++ b/api/funkwhale_api/music/models.py
@@ -855,8 +855,7 @@ class Upload(models.Model):
         if not input:
             return
 
-        input_format = utils.MIMETYPE_TO_EXTENSION[self.mimetype]
-        audio = pydub.AudioSegment.from_file(input, format=input_format)
+        audio = pydub.AudioSegment.from_file(input)
         return audio
 
     def save(self, **kwargs):
diff --git a/api/funkwhale_api/music/utils.py b/api/funkwhale_api/music/utils.py
index b863f416da..4e94c47a1c 100644
--- a/api/funkwhale_api/music/utils.py
+++ b/api/funkwhale_api/music/utils.py
@@ -105,7 +105,7 @@ def get_actor_from_request(request):
     return actor
 
 
-def transcode_file(input, output, input_format, output_format, **kwargs):
+def transcode_file(input, output, input_format=None, output_format="mp3", **kwargs):
     with input.open("rb"):
         audio = pydub.AudioSegment.from_file(input, format=input_format)
     return transcode_audio(audio, output, output_format, **kwargs)
diff --git a/api/tests/music/test_utils.py b/api/tests/music/test_utils.py
index 67a4212d89..0c477312da 100644
--- a/api/tests/music/test_utils.py
+++ b/api/tests/music/test_utils.py
@@ -1,6 +1,7 @@
 import os
 import pathlib
 import pytest
+import tempfile
 
 from funkwhale_api.music import utils
 
@@ -28,6 +29,7 @@ def test_guess_mimetype_try_using_extension_if_fail(wrong, factories, mocker):
         ("sample.flac", {"bitrate": 1608000, "length": 0.001}),
         ("test.mp3", {"bitrate": 8000, "length": 267.70285714285717}),
         ("test.ogg", {"bitrate": 112000, "length": 1}),
+        ("test.opus", {"bitrate": 0, "length": 1}),  # This Opus file lacks a bitrate
     ],
 )
 def test_get_audio_file_data(name, expected):
@@ -109,3 +111,22 @@ def test_get_dirs_and_files(path, expected, tmpdir):
     (root_path / "System" / "file.ogg").touch()
 
     assert utils.browse_dir(root_path, path) == expected
+
+
+@pytest.mark.parametrize(
+    "name, expected",
+    [
+        ("sample.flac", {"bitrate": 128000, "length": 0}),
+        ("test.mp3", {"bitrate": 16000, "length": 268}),
+        ("test.ogg", {"bitrate": 128000, "length": 1}),
+        ("test.opus", {"bitrate": 128000, "length": 1}),
+    ],
+)
+def test_transcode_file(name, expected):
+    path = pathlib.Path(os.path.join(DATA_DIR, name))
+    with tempfile.NamedTemporaryFile() as dest:
+        utils.transcode_file(path, pathlib.Path(dest.name))
+        with open(dest.name, "rb") as f:
+            result = {k: round(v) for k, v in utils.get_audio_file_data(f).items()}
+
+            assert result == expected
diff --git a/changes/changelog.d/1274.bugfix b/changes/changelog.d/1274.bugfix
new file mode 100644
index 0000000000..8dfe061ace
--- /dev/null
+++ b/changes/changelog.d/1274.bugfix
@@ -0,0 +1 @@
+Changed audio format detection to happen via sniffing and not file extensions (#1274)
-- 
GitLab