ytdlp.online

Tous les correctifs

Sur cette page

yt-dlp et Rumble : corriger l’erreur JSON 403 avec les données du lecteur

Date de publication

Télécharger le plugin correctif rumble_player.py

Si yt-dlp affiche Unable to download JSON metadata: HTTP Error 403: Forbidden lors du téléchargement d’une vidéo Rumble, vous pouvez charger le plugin de compatibilité fourni dans cet article. Lorsque l’API JSON embedJS/u3 de Rumble renvoie une erreur 403, le plugin récupère automatiquement la page du lecteur intégré officiel (/embed/) de la même vidéo. Il en extrait les données multimédias intégrées et poursuit le téléchargement.

Si vous préférez éviter la configuration d’un plugin local et la conversion manuelle des liens, utilisez notre outil de téléchargement de vidéos Rumble, qui intègre déjà ce correctif.

Repérer d’abord l’étape qui renvoie l’erreur 403

Une erreur 403 peut survenir à trois étapes du téléchargement d’une vidéo Rumble. Ce plugin traite précisément le deuxième cas :

Message d’erreur Requête bloquée Solution
Unable to download webpage: HTTP Error 403 Le HTML de la page de visionnage est bloqué (voir l’issue #15089) Obtenir l’adresse /embed/ via l’API oEmbed officielle et utiliser --impersonate firefox
Unable to download JSON metadata: HTTP Error 403 L’API de métadonnées embedJS/u3 est bloquée (voir l’issue #17496) Utiliser ce plugin : récupérer automatiquement les données intégrées à la page /embed/
Les formats s’affichent, mais une erreur 403 survient pendant le téléchargement des fragments ou du MP4 Le CDN refuse la requête du flux multimédia Vérifier le proxy et les en-têtes de requête, ou choisir une autre résolution

Étapes de correction rapide

1. Enregistrer le fichier du plugin

Dans votre répertoire de travail, créez l’arborescence suivante et enregistrez le code complet du plugin en fin d’article dans rumble_player.py. Il n’est pas nécessaire de modifier le code source de yt-dlp :

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

2. Obtenir l’adresse /embed/ officielle de la vidéo

L’identifiant présent dans l’URL de la page de visionnage Rumble, par exemple v6xxxx, diffère de celui du lecteur intégré, par exemple vb0ofn. Vous ne pouvez donc pas construire l’adresse du lecteur en remplaçant simplement une partie de l’URL. Si vous disposez uniquement du lien de visionnage, interrogez l’API oEmbed publique de Rumble pour obtenir la véritable adresse /embed/ :

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

Dans le champ JSON html de la réponse, recherchez <iframe src="https://rumble.com/embed/xxxx/..." et récupérez l’adresse https://rumble.com/embed/xxxx/.

Si oEmbed renvoie une erreur 403, installez curl_cffi et réessayez avec une empreinte Firefox. Remplacez l’URL d’exemple ci-dessous par l’URL complète de la page de la vidéo.

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"

Si la nouvelle tentative échoue, utilisez l’outil en ligne pour convertir le lien automatiquement.

3. Lister les formats et vérifier le recours au lecteur

Exécutez cette commande depuis le répertoire contenant le dossier plugins, en remplaçant l’URL d’exemple par l’adresse /embed/ de la vidéo souhaitée :

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

La présence de [RumbleEmbed+PlayerFallback] dans le journal confirme que le plugin est chargé :

  • Si l’API JSON renvoie une erreur 403, le message Downloading player webpage apparaît ensuite. Ce message indique seulement que la solution de repli a été déclenchée. Vérifiez que la liste des formats s’affiche ensuite pour confirmer que l’analyse des données a réussi.
  • Si l’API JSON renvoie directement un statut 200 depuis votre réseau, yt-dlp suit son fonctionnement habituel sans envoyer de requête supplémentaire à la page du lecteur.

4. Télécharger la vidéo et vérifier son décodage

Choisissez un identifiant de format dans la sortie de -F, par exemple mp4-360p, puis lancez le téléchargement :

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/"

Voici le journal complet du terminal enregistré lors du test où la solution de repli s’est déclenchée :

[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

Pour vérifier l’intégrité du conteneur MP4 et de ses pistes audio et vidéo après le téléchargement, utilisez ffprobe et 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 -

Fonctionnement : pourquoi les données du lecteur permettent de dépasser l’erreur JSON 403

1. Réutiliser les données intégrées de la même source

Par défaut, RumbleEmbedIE demande directement les métadonnées JSON à https://rumble.com/embedJS/u3/?request=video&ver=2&v=.... Si Cloudflare ou les mécanismes de protection du site bloquent spécifiquement cette API et renvoient HTTP 403, l’extraction s’interrompt.

Or la page du lecteur officiel https://rumble.com/embed/<video_id>/ contient déjà, dans son script, un objet de configuration vidéo de structure identique. Il inclut notamment ua, avec les adresses des flux pour chaque résolution, ainsi que le titre et la durée. Il suffit d’extraire cet objet et de le renvoyer à _download_json pour que le code d’analyse des formats de yt-dlp poursuive son travail sans modification.

2. Supprimer le champ JSON non standard loaded: h()

L’objet intégré à la page n’est pas un littéral JSON valide : il se termine par l’appel de fonction loaded: h(), par exemple :

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

Un parseur JSON échouerait sur h(). Le plugin utilise donc le mécanisme transform_source de _search_json pour retirer, à l’aide d’une expression régulière, uniquement le , loaded: xxx() final avant l’analyse. Le traitement porte entièrement sur du texte en mémoire et n’exécute aucun JavaScript de la page :

  • Sélection précise : seul l’objet dont la clé correspond exactement à la video_id courante est extrait (\b[\w$]+\.f\[\s*["']{video_id}["']\s*\]\s*=). Le résultat doit être un dictionnaire contenant un champ de flux ua non vide.
  • Intervention limitée : la solution de repli ne s’active que lorsque _download_json intercepte un HTTPError de statut 403. Pour les erreurs 401, 404, 429, 500 ou toute autre erreur, ainsi qu’en l’absence d’un objet valide dans la page, l’exception initiale est propagée sans modification.
  • Intégration à notre service en ligne : en plus de charger le plugin, notre service convertit automatiquement les URL de visionnage en adresses /embed/ via oEmbed. Quand --impersonate n’est pas précisé, il utilise par défaut l’empreinte firefox-135.

Code complet du plugin

Enregistrez ce code dans plugins/rumble/yt_dlp_plugins/extractor/rumble_player.py. Il a été validé avec Python 3.12+ et 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
Outils yt-dlp
Voir tous les outils yt-dlp
Aide et documentation yt-dlp