Commit 6ffae9f5 authored by Eliot Berriot's avatar Eliot Berriot
Browse files

Merge branch '867-subsonic-default-transcoding' into 'master'

Resolve "Provide a default format when transcoding via Subsonic"

See merge request funkwhale/funkwhale!807
parents 31478ea6 bfff7930
...@@ -658,3 +658,6 @@ RSA_KEY_SIZE = 2048 ...@@ -658,3 +658,6 @@ RSA_KEY_SIZE = 2048
CREATE_IMAGE_THUMBNAILS = env.bool("CREATE_IMAGE_THUMBNAILS", default=True) CREATE_IMAGE_THUMBNAILS = env.bool("CREATE_IMAGE_THUMBNAILS", default=True)
# we rotate actor keys at most every two days by default # we rotate actor keys at most every two days by default
ACTOR_KEY_ROTATION_DELAY = env.int("ACTOR_KEY_ROTATION_DELAY", default=3600 * 48) ACTOR_KEY_ROTATION_DELAY = env.int("ACTOR_KEY_ROTATION_DELAY", default=3600 * 48)
SUBSONIC_DEFAULT_TRANSCODING_FORMAT = (
env("SUBSONIC_DEFAULT_TRANSCODING_FORMAT", default="mp3") or None
)
...@@ -247,10 +247,6 @@ class SubsonicViewSet(viewsets.GenericViewSet): ...@@ -247,10 +247,6 @@ class SubsonicViewSet(viewsets.GenericViewSet):
if not upload: if not upload:
return response.Response(status=404) return response.Response(status=404)
format = data.get("format", "raw")
if format == "raw":
format = None
max_bitrate = data.get("maxBitRate") max_bitrate = data.get("maxBitRate")
try: try:
max_bitrate = min(max(int(max_bitrate), 0), 320) or None max_bitrate = min(max(int(max_bitrate), 0), 320) or None
...@@ -259,6 +255,16 @@ class SubsonicViewSet(viewsets.GenericViewSet): ...@@ -259,6 +255,16 @@ class SubsonicViewSet(viewsets.GenericViewSet):
if max_bitrate: if max_bitrate:
max_bitrate = max_bitrate * 1000 max_bitrate = max_bitrate * 1000
format = data.get("format", "raw") or None
if max_bitrate and not format:
# specific bitrate requested, but no format specified
# so we use a default one, cf #867. This helps with clients
# that don't send the format parameter, such as DSub.
format = settings.SUBSONIC_DEFAULT_TRANSCODING_FORMAT
elif format == "raw":
format = None
return music_views.handle_serve( return music_views.handle_serve(
upload=upload, upload=upload,
user=request.user, user=request.user,
......
...@@ -261,23 +261,48 @@ def test_stream_format(format, expected, logged_in_api_client, factories, mocker ...@@ -261,23 +261,48 @@ def test_stream_format(format, expected, logged_in_api_client, factories, mocker
@pytest.mark.parametrize( @pytest.mark.parametrize(
"max_bitrate,expected", [(0, None), (192, 192000), (2000, 320000)] "max_bitrate,format,default_transcoding_format,expected_bitrate,expected_format",
[
# no max bitrate, no format, so no transcoding should happen
(0, "", "ogg", None, None),
# same using "raw" format
(0, "raw", "ogg", None, None),
# specified bitrate, but no format, so fallback to default transcoding format
(192, "", "ogg", 192000, "ogg"),
# specified bitrate, but over limit
(2000, "", "ogg", 320000, "ogg"),
# specified format, we use that one
(192, "opus", "ogg", 192000, "opus"),
# No default transcoding format set and no format requested
(192, "", None, 192000, None),
],
) )
def test_stream_bitrate(max_bitrate, expected, logged_in_api_client, factories, mocker): def test_stream_transcode(
max_bitrate,
format,
default_transcoding_format,
expected_bitrate,
expected_format,
logged_in_api_client,
factories,
mocker,
settings,
):
settings.SUBSONIC_DEFAULT_TRANSCODING_FORMAT = default_transcoding_format
url = reverse("api:subsonic-stream") url = reverse("api:subsonic-stream")
mocked_serve = mocker.patch.object( mocked_serve = mocker.patch.object(
music_views, "handle_serve", return_value=Response() music_views, "handle_serve", return_value=Response()
) )
upload = factories["music.Upload"](playable=True) upload = factories["music.Upload"](playable=True)
response = logged_in_api_client.get( response = logged_in_api_client.get(
url, {"id": upload.track.pk, "maxBitRate": max_bitrate} url, {"id": upload.track.pk, "maxBitRate": max_bitrate, "format": format}
) )
mocked_serve.assert_called_once_with( mocked_serve.assert_called_once_with(
upload=upload, upload=upload,
user=logged_in_api_client.user, user=logged_in_api_client.user,
format=None, format=expected_format,
max_bitrate=expected, max_bitrate=expected_bitrate,
proxy_media=True, proxy_media=True,
) )
assert response.status_code == 200 assert response.status_code == 200
......
Added a SUBSONIC_DEFAULT_TRANSCODING_FORMAT env var to support clients that don't provide the format parameter (#867)
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment