ytdlp.online

Wszystkie rozwiązania

Na tej stronie

Błąd 403 Rumble w yt-dlp: pobieranie danych z odtwarzacza

Data publikacji

Pobierz wtyczkę naprawczą rumble_player.py

Jeśli podczas pobierania filmu z Rumble yt-dlp zgłasza Unable to download JSON metadata: HTTP Error 403: Forbidden, możesz załadować wtyczkę zgodności z tego artykułu. Gdy interfejs JSON embedJS/u3 serwisu Rumble zwróci błąd 403, wtyczka automatycznie pobierze stronę oficjalnego osadzonego odtwarzacza (/embed/) tego samego filmu, odczyta zawarte w niej dane multimedialne i będzie kontynuować pobieranie.

Jeśli wolisz uniknąć lokalnej konfiguracji wtyczki lub ręcznego przekształcania linków, skorzystaj z naszego narzędzia do pobierania filmów z Rumble, które ma już tę poprawkę.

Ustal, na którym etapie występuje błąd 403

Błąd 403 może wystąpić na trzech różnych etapach pobierania z Rumble. Ta wtyczka rozwiązuje konkretnie drugi przypadek:

Komunikat błędu Miejsce blokady Sposób postępowania
Unable to download webpage: HTTP Error 403 Zablokowano HTML strony filmu (zobacz zgłoszenie #15089) Uzyskaj adres /embed/ za pomocą oficjalnego interfejsu oEmbed i użyj --impersonate firefox
Unable to download JSON metadata: HTTP Error 403 Zablokowano interfejs metadanych embedJS/u3 (zobacz zgłoszenie #17496) Użyj wtyczki z tego artykułu: automatycznie odczyta dane zawarte na stronie /embed/
Lista formatów jest dostępna, ale pobieranie fragmentów lub pliku MP4 kończy się błędem 403 CDN odrzuca żądanie strumienia multimedialnego Sprawdź proxy i nagłówki żądania albo wybierz format o innej jakości

Jak zastosować poprawkę

1. Zapisz plik wtyczki

Utwórz poniższą strukturę folderów w katalogu roboczym i zapisz pełny kod wtyczki jako rumble_player.py. Nie trzeba zmieniać kodu źródłowego yt-dlp:

plugins/
└── rumble/
    └── yt_dlp_plugins/
        └── extractor/
            └── rumble_player.py

2. Uzyskaj oficjalny adres /embed/ filmu

Identyfikator w adresie strony filmu Rumble, na przykład v6xxxx, oraz identyfikator osadzonego odtwarzacza, taki jak vb0ofn, są różne. Nie można więc po prostu zbudować adresu ręcznie z tego samego ID. Jeśli masz tylko zwykły link do filmu, wywołaj publiczny interfejs oEmbed serwisu Rumble, aby uzyskać właściwy adres /embed/:

curl -fsSG --data-urlencode "url=https://rumble.com/your-video.html" "https://rumble.com/api/Media/oembed.json"

W polu html odpowiedzi JSON znajdź <iframe src="https://rumble.com/embed/xxxx/..." i skopiuj część https://rumble.com/embed/xxxx/.

Jeśli oEmbed zwróci błąd 403, zainstaluj curl_cffi i spróbuj ponownie z odciskiem przeglądarki Firefox. Zastąp przykładowy URL poniżej pełnym adresem strony filmu.

python -m pip install curl_cffi
python -c "import sys; from curl_cffi import requests; r = requests.get('https://rumble.com/api/Media/oembed.json', params=dict(url=sys.argv[1]), impersonate='firefox', timeout=15); r.raise_for_status(); print(r.text)" "https://rumble.com/your-video.html"

Jeśli ponowna próba się nie powiedzie, użyj narzędzia online, aby automatycznie przekonwertować link.

3. Wyświetl formaty i sprawdź mechanizm awaryjny

Uruchom polecenie w katalogu zawierającym folder plugins. Zastąp adres docelowym adresem /embed/ filmu:

yt-dlp --ignore-config --plugin-dirs ./plugins --no-cache-dir -v -F "https://rumble.com/embed/vb0ofn/"

Oznaczenie [RumbleEmbed+PlayerFallback] w logu potwierdza załadowanie wtyczki:

  • Jeśli interfejs JSON zwróci błąd 403, pojawi się następnie komunikat Downloading player webpage. Oznacza on tylko, że uruchomiono ścieżkę awaryjną. Dopiero wyświetlona następnie lista formatów potwierdza poprawny odczyt danych.
  • Jeśli w danej sieci interfejs JSON zwróci status 200, działa standardowa ścieżka, bez dodatkowego żądania strony odtwarzacza.

4. Pobierz film i sprawdź dekodowanie

Wybierz identyfikator formatu z listy zwróconej przez -F, na przykład mp4-360p, i pobierz film:

yt-dlp --ignore-config --plugin-dirs ./plugins --no-cache-dir -v --no-playlist -f mp4-360p -o "rumble-test.%(ext)s" "https://rumble.com/embed/vb0ofn/"

Poniżej znajduje się log z testu, podczas którego uruchomiła się ścieżka awaryjna:

[RumbleEmbed+PlayerFallback] vb0ofn: Downloading JSON metadata
[RumbleEmbed+PlayerFallback] vb0ofn: Downloading player webpage
[info] vb0ofn: Downloading 1 format(s): mp4-360p
[download] 100% of    7.85MiB in 00:01:20 at 99.48KiB/s

Aby sprawdzić integralność pobranego kontenera MP4 oraz ścieżek obrazu i dźwięku, użyj ffprobe i ffmpeg:

ffprobe -v error -show_entries stream=codec_name,codec_type,width,height:format=duration,size -of json "rumble-test.mp4"
ffmpeg -nostdin -v error -xerror -i "rumble-test.mp4" -map 0:v:0 -map "0:a:0?" -f null -

Dlaczego strona odtwarzacza pozwala kontynuować po błędzie 403 interfejsu JSON

1. Ponowne wykorzystanie danych ze strony oficjalnego odtwarzacza

Domyślnie RumbleEmbedIE pobiera metadane JSON bezpośrednio z https://rumble.com/embedJS/u3/?request=video&ver=2&v=.... Jeśli Cloudflare lub zabezpieczenia serwisu zablokują ten konkretny interfejs i zwrócą HTTP 403, ekstrakcja zostanie przerwana.

Tymczasem skrypty oficjalnej strony https://rumble.com/embed/<video_id>/ zawierają już obiekt konfiguracji filmu o identycznej strukturze. Obejmuje on pole ua z adresami strumieni poszczególnych jakości, tytuł, czas trwania i inne dane. Wystarczy odczytać ten obiekt i zwrócić go z _download_json, aby dalszy kod yt-dlp mógł przetwarzać formaty bez żadnych zmian.

2. Usunięcie pola niezgodnego z JSON (loaded: h())

Obiekt zapisany na stronie nie jest ścisłym literałem JSON. Na końcu ma wywołanie funkcji wykonywanej w czasie działania, loaded: h(), tak jak w poniższym przykładzie:

u.f["vb0ofn"] = {"ua": {"mp4": {"360": {"url": "https://..."}}}, "title": "...", loaded: h()};

Przekazanie go bezpośrednio do parsera JSON spowoduje błąd składni z powodu h(). Wtyczka korzysta więc z parametru transform_source w _search_json, aby tuż przed parsowaniem usunąć wyrażeniem regularnym wyłącznie końcowy fragment , loaded: xxx(). Cała operacja odbywa się na tekście w pamięci, bez wykonywania JavaScriptu ze strony:

  • Dokładne dopasowanie: odczytywany jest tylko obiekt, którego klucz jest równy bieżącemu video_id (\b[\w$]+\.f\[\s*["']{video_id}["']\s*\]\s*=). Następnie wtyczka sprawdza, czy wynik jest słownikiem zawierającym niepuste pole multimedialne ua.
  • Ograniczony zakres działania: ścieżka awaryjna uruchamia się tylko wtedy, gdy _download_json przechwyci HTTPError ze statusem 403. Przy błędach 401, 404, 429 i 500 lub braku poprawnego obiektu na stronie ponownie zgłaszany jest oryginalny wyjątek.
  • Integracja w naszym serwisie: oprócz ładowania wtyczki nasza usługa online wywołuje oEmbed, aby zamieniać zwykłe linki do filmów na adresy /embed/. Jeśli użytkownik nie poda --impersonate, domyślnie stosowana jest sygnatura przeglądarki firefox-135.

Pełny kod wtyczki

Zapisz poniższy kod jako plugins/rumble/yt_dlp_plugins/extractor/rumble_player.py. Został zweryfikowany z Pythonem 3.12+ i yt-dlp 2026.10.10+:

"""Reuse official player media data when Rumble's JSON endpoint is blocked."""

import re

from yt_dlp.extractor.rumble import RumbleEmbedIE as BaseRumbleEmbedIE
from yt_dlp.networking.exceptions import HTTPError
from yt_dlp.utils import ExtractorError


class RumbleEmbedIE(BaseRumbleEmbedIE, plugin_name='PlayerFallback'):
    def _real_extract(self, url):
        self._player_url = url
        return super()._real_extract(url)

    def _download_json(self, url_or_request, video_id, *args, **kwargs):
        try:
            return super()._download_json(url_or_request, video_id, *args, **kwargs)
        except ExtractorError as error:
            if not isinstance(error.cause, HTTPError) or error.cause.status != 403:
                raise
            webpage = self._download_webpage(self._player_url, video_id, note='Downloading player webpage')
            # Parse this video's object and strip the runtime call without executing page scripts.
            data = self._search_json(
                rf'''\b[\w$]+\.f\[\s*["']{re.escape(video_id)}["']\s*\]\s*=\s*''',
                webpage, 'player data', video_id,
                fatal=False,
                transform_source=lambda source: re.sub(r',\s*loaded\s*:\s*[\w$]+\(\s*\)\s*(?=})', '', source))
            if not isinstance(data, dict) or not data.get('ua'):
                raise error
            return data
Narzędzia yt-dlp
Zobacz wszystkie narzędzia yt-dlp
Pomoc i dokumentacja yt-dlp