From 505551f31252e46f1bb6b84ad84dba8b00db240c Mon Sep 17 00:00:00 2001 From: Dispatcharr Date: Mon, 17 Mar 2025 15:06:47 -0500 Subject: [PATCH 1/6] Updated M3U stream URLs Changed M3U urls to use proxy --- apps/output/urls.py | 2 +- apps/output/views.py | 6 +++++- core/views.py | 4 ++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/apps/output/urls.py b/apps/output/urls.py index 9b92eb94..02e43c83 100644 --- a/apps/output/urls.py +++ b/apps/output/urls.py @@ -12,5 +12,5 @@ urlpatterns = [ re_path(r'^epg/?$', generate_epg, name='generate_epg'), # Allow both `/stream/` and `/stream//` - re_path(r'^stream/(?P\d+)/?$', stream_view, name='stream'), + re_path(r'^stream/(?P[0-9a-fA-F\-]+)/?$', stream_view, name='stream'), ] diff --git a/apps/output/views.py b/apps/output/views.py index 92319e93..cffc20e1 100644 --- a/apps/output/views.py +++ b/apps/output/views.py @@ -22,7 +22,11 @@ def generate_m3u(request): f'#EXTINF:-1 tvg-id="{tvg_id}" tvg-name="{tvg_name}" tvg-logo="{tvg_logo}" ' f'tvg-chno="{channel_number}" group-title="{group_title}",{channel.name}\n' ) - stream_url = request.build_absolute_uri(reverse('output:stream', args=[channel.id])) + + base_url = request.build_absolute_uri('/')[:-1] + stream_url = f"{base_url}/proxy/ts/stream/{channel.uuid}" + + #stream_url = request.build_absolute_uri(reverse('output:stream', args=[channel.id])) m3u_content += extinf_line + stream_url + "\n" response = HttpResponse(m3u_content, content_type="application/x-mpegURL") diff --git a/core/views.py b/core/views.py index a5852171..397783fb 100644 --- a/core/views.py +++ b/core/views.py @@ -29,7 +29,7 @@ def settings_view(request): return render(request, 'settings.html') -def stream_view(request, stream_id): +def stream_view(request, channel_uuid): """ Streams the first available stream for the given channel. It uses the channel’s assigned StreamProfile. @@ -40,7 +40,7 @@ def stream_view(request, stream_id): redis_client = redis.Redis(host=settings.REDIS_HOST, port=6379, db=int(getattr(settings, "REDIS_DB", "0"))) # Retrieve the channel by the provided stream_id. - channel = Channel.objects.get(channel_number=stream_id) + channel = Channel.objects.get(uuid=channel_uuid) logger.debug("Channel retrieved: ID=%s, Name=%s", channel.id, channel.name) # Ensure the channel has at least one stream. From 0842da93935582319c0667ba23de70b3ed33a424 Mon Sep 17 00:00:00 2001 From: dekzter Date: Mon, 17 Mar 2025 20:27:58 -0400 Subject: [PATCH 2/6] added real ip --- docker/nginx.conf | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docker/nginx.conf b/docker/nginx.conf index 26098d95..077914f7 100644 --- a/docker/nginx.conf +++ b/docker/nginx.conf @@ -5,6 +5,8 @@ server { location / { include uwsgi_params; uwsgi_pass unix:/app/uwsgi.sock; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location /assets/ { @@ -25,6 +27,8 @@ server { proxy_pass http://127.0.0.1:5656; proxy_buffering off; proxy_set_header Connection keep-alive; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } # WebSockets for real-time communication @@ -46,5 +50,7 @@ server { proxy_read_timeout 3600s; proxy_send_timeout 3600s; client_max_body_size 0; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } } From a2b451f4b0cf4862e100088dc8b3372b3f93f79d Mon Sep 17 00:00:00 2001 From: dekzter Date: Mon, 17 Mar 2025 20:42:45 -0400 Subject: [PATCH 3/6] updated ffmpeg profile --- core/migrations/0006_set_locked_stream_profiles.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/migrations/0006_set_locked_stream_profiles.py b/core/migrations/0006_set_locked_stream_profiles.py index 808180ce..f26e6e89 100644 --- a/core/migrations/0006_set_locked_stream_profiles.py +++ b/core/migrations/0006_set_locked_stream_profiles.py @@ -13,7 +13,7 @@ def lock_or_create_profiles(apps, schema_editor): "name": "ffmpeg", "command": "ffmpeg", "parameters": "-i {streamUrl} -c:v copy -c:a copy -f mpegts pipe:1", - "new_parameters": "-i {streamUrl} -user_agent {userAgent} -c:v copy -c:a copy -f mpegts pipe:1", + "new_parameters": "-user_agent {userAgent} -i {streamUrl} -c:v copy -c:a copy -f mpegts pipe:1", }, { "name": "streamlink", From 8b17ab31684f89004bf212cde8fa478ce5373d50 Mon Sep 17 00:00:00 2001 From: dekzter Date: Mon, 17 Mar 2025 20:44:12 -0400 Subject: [PATCH 4/6] another ffmpeg update --- core/migrations/0006_set_locked_stream_profiles.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/migrations/0006_set_locked_stream_profiles.py b/core/migrations/0006_set_locked_stream_profiles.py index f26e6e89..1b525dc1 100644 --- a/core/migrations/0006_set_locked_stream_profiles.py +++ b/core/migrations/0006_set_locked_stream_profiles.py @@ -13,7 +13,7 @@ def lock_or_create_profiles(apps, schema_editor): "name": "ffmpeg", "command": "ffmpeg", "parameters": "-i {streamUrl} -c:v copy -c:a copy -f mpegts pipe:1", - "new_parameters": "-user_agent {userAgent} -i {streamUrl} -c:v copy -c:a copy -f mpegts pipe:1", + "new_parameters": "-user_agent {userAgent} -i {streamUrl} -c copy -f mpegts pipe:1", }, { "name": "streamlink", From 3bd9e5a2ef4694db5b350fcaa35ebac01d1d0293 Mon Sep 17 00:00:00 2001 From: dekzter Date: Mon, 17 Mar 2025 20:52:27 -0400 Subject: [PATCH 5/6] increased notification size --- frontend/src/App.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index ff8ae3b6..4d2476b4 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -83,7 +83,7 @@ const App = () => { withNormalizeCSS > - + Date: Mon, 17 Mar 2025 21:27:09 -0400 Subject: [PATCH 6/6] fixed serializer to include locked --- apps/m3u/serializers.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/m3u/serializers.py b/apps/m3u/serializers.py index fe2f598e..391794a1 100644 --- a/apps/m3u/serializers.py +++ b/apps/m3u/serializers.py @@ -36,12 +36,13 @@ class M3UAccountSerializer(serializers.ModelSerializer): required=True ) profiles = M3UAccountProfileSerializer(many=True, read_only=True) + read_only_fields = ['locked'] class Meta: model = M3UAccount fields = [ 'id', 'name', 'server_url', 'uploaded_file', 'server_group', - 'max_streams', 'is_active', 'created_at', 'updated_at', 'filters', 'user_agent', 'profiles' + 'max_streams', 'is_active', 'created_at', 'updated_at', 'filters', 'user_agent', 'profiles', 'locked' ] class ServerGroupSerializer(serializers.ModelSerializer):