diff options
| author | Bobby <[email protected]> | 2024-11-11 13:21:13 -0500 |
|---|---|---|
| committer | Bobby <[email protected]> | 2024-11-11 13:21:13 -0500 |
| commit | 362591adc82bfaccab9d9a0ac316d909a5873920 (patch) | |
| tree | 98ec843593f645b7eda81c9178cce7b1be0fe12a | |
| parent | b87d6b7a67cf29d49130ee4dda47857c111671d6 (diff) | |
| download | yugen-362591adc82bfaccab9d9a0ac316d909a5873920.tar.xz yugen-362591adc82bfaccab9d9a0ac316d909a5873920.zip | |
Fix Gogo Stream
| -rw-r--r-- | templates/watch/watch.html | 4 | ||||
| -rw-r--r-- | watch/urls.py | 1 | ||||
| -rw-r--r-- | watch/views.py | 91 |
3 files changed, 93 insertions, 3 deletions
diff --git a/templates/watch/watch.html b/templates/watch/watch.html index afb8be3..2f85d0b 100644 --- a/templates/watch/watch.html +++ b/templates/watch/watch.html @@ -1211,7 +1211,7 @@ const layout = new VidstackPlayerLayout({ {% for track in streaming_data.tracks %} {% if track.kind == 'thumbnails' %} - thumbnails: "{{ track.file }}", + thumbnails: "/watch/stream?url={{ track.file|urlencode }}", {% endif %} {% endfor %} }); @@ -1219,7 +1219,7 @@ const player = await VidstackPlayer.create({ target: '#video-player', autoStartLoad: true, - src: '{{ stream_url }}', + src: "/watch/stream?url={{ stream_url|urlencode}}", viewType: 'video', streamType: 'on-demand', logLevel: 'warn', diff --git a/watch/urls.py b/watch/urls.py index 467c128..8ba3d9c 100644 --- a/watch/urls.py +++ b/watch/urls.py @@ -11,5 +11,6 @@ urlpatterns = [ path('/update_watch_history', views.update_episode_watch_time, name='update_watch_history'), # path('/clear_discord_status', views.clear_discord_status, name='clear_discord_status'), path('/remove_anime_from_watchlist', views.remove_anime_from_watchlist, name='remove_anime_from_watchlist'), + path('/stream', views.proxy_stream, name='proxy_stream'), # path('/malId:<int:mal_id>$zid:<str:zid>', views.watch_via_zid_mal_id, name='watch_via_zid_mal_id'), # if anilist id is not available ] diff --git a/watch/views.py b/watch/views.py index f9d27d9..a6456db 100644 --- a/watch/views.py +++ b/watch/views.py @@ -8,12 +8,102 @@ from watch.utils import attach_episode_metadata, get_anime_seasons, get_anime_da from django.views.decorators.csrf import csrf_exempt from django.views.decorators.http import require_http_methods import json +from django.http import StreamingHttpResponse, HttpResponse +from django.views.decorators.csrf import csrf_exempt +import requests +import re +from urllib.parse import urljoin, urlparse, quote dotenv.load_dotenv() def index(request): return redirect("home:index") + +@csrf_exempt +def proxy_stream(request): + """ + Proxy streaming content through your server + """ + url = request.GET.get('url') + + if not url: + return HttpResponse('No URL provided', status=400) + + try: + # Make the request to the target server + response = requests.get( + url, + stream=True, + headers={ + 'User-Agent': request.headers.get('User-Agent', ''), + 'Referer': request.headers.get('Referer', ''), + 'Origin': request.headers.get('Origin', ''), + } + ) + + content_type = response.headers.get('content-type', '') + + # Handle M3U8 playlists + if 'm3u8' in content_type or url.endswith('.m3u8'): + content = response.text + base_url = url.rsplit('/', 1)[0] + '/' + + # Modify the playlist URLs to go through our proxy + modified_content = [] + for line in content.splitlines(): + if line.startswith('#'): + modified_content.append(line) + elif line.strip(): # Handle content lines (URLs) + # Handle both absolute and relative URLs + if not line.startswith('http'): + line = urljoin(base_url, line) + proxy_url = f'/watch/stream?url={quote(line)}' + modified_content.append(proxy_url) + else: + modified_content.append(line) + + return HttpResponse( + '\n'.join(modified_content), + content_type='application/vnd.apple.mpegurl' + ) + + # Handle VTT files + elif url.endswith('.vtt'): + content = response.text + # Regular expression to find URLs in VTT file + url_pattern = r'(https?://[^\s<>"]+?(?:jpg|jpeg|png|webp))' + + def replace_url(match): + thumbnail_url = match.group(1) + return f'/watch/stream?url={quote(thumbnail_url)}' + + # Replace all image URLs with proxied versions + modified_content = re.sub(url_pattern, replace_url, content) + + return HttpResponse( + modified_content, + content_type='text/vtt' + ) + + # Handle images (thumbnails) + elif any(ext in url.lower() for ext in ['.jpg', '.jpeg', '.png', '.webp']): + return StreamingHttpResponse( + response.iter_content(chunk_size=8192), + content_type=response.headers.get('content-type'), + status=response.status_code + ) + + # For video segments and other content, stream directly + return StreamingHttpResponse( + response.iter_content(chunk_size=8192), + content_type=response.headers.get('content-type'), + status=response.status_code + ) + + except requests.RequestException as e: + return HttpResponse(f"Error proxying request: {str(e)}", status=500) + def watch(request, anime_id, episode=None): forward_detail = request.GET.get("forward") == "detail" preload_request = request.GET.get("preload") == "true" @@ -77,7 +167,6 @@ def watch(request, anime_id, episode=None): if episode_data: if provider == "zoro": streaming_data = get_zoro_episode_streaming_data(episode_data["id"], mode) - print(streaming_data) else: streaming_data = get_gogo_episode_streaming_data(episode_data["id"]) |
