ytdlp.online
Início Tampermonkey

Todas as soluções

Nesta página

Erro 403 do Rumble no yt-dlp: usar os dados do player

Data de publicação

Baixar plugin de correção rumble_player.py

Se o yt-dlp mostrar Unable to download JSON metadata: HTTP Error 403: Forbidden ao baixar um vídeo do Rumble, carregue o plugin de compatibilidade deste artigo. Quando a API JSON embedJS/u3 do Rumble retorna 403, o plugin busca automaticamente a página do player incorporado oficial (/embed/) do mesmo vídeo, extrai os dados de mídia incluídos nela e continua o download.

Se preferir evitar a configuração local do plugin ou a conversão manual dos links, use nossa ferramenta para baixar vídeos do Rumble, que já inclui essa solução.

Identifique em qual etapa ocorre o erro 403

Um erro 403 pode ocorrer em três etapas diferentes do download no Rumble. Este plugin resolve especificamente a segunda:

Mensagem de erro Onde ocorre o bloqueio O que fazer
Unable to download webpage: HTTP Error 403 O HTML da página do vídeo é bloqueado (veja a issue #15089) Obtenha o endereço /embed/ pela API oEmbed oficial e use --impersonate firefox
Unable to download JSON metadata: HTTP Error 403 A API de metadados embedJS/u3 é bloqueada (veja a issue #17496) Use o plugin deste artigo: ele recorre automaticamente aos dados incluídos na página /embed/
A lista de formatos aparece, mas o download dos fragmentos ou do MP4 retorna 403 A CDN rejeita a requisição da mídia Verifique o proxy e os cabeçalhos da requisição ou escolha outro formato de qualidade

Passos para aplicar a correção

1. Salve o arquivo do plugin

Crie esta estrutura de pastas no diretório de trabalho e salve o código completo do plugin como rumble_player.py. Não é necessário alterar o código-fonte do yt-dlp:

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

2. Obtenha o endereço /embed/ oficial do vídeo

O ID presente na URL da página do Rumble, como v6xxxx, e o ID do player incorporado, como vb0ofn, são diferentes. Por isso, não basta montar o endereço manualmente com o mesmo ID. Se tiver apenas o link normal do vídeo, consulte a API oEmbed pública do Rumble para obter o endereço /embed/ correto:

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

No campo html do JSON retornado, procure <iframe src="https://rumble.com/embed/xxxx/..." e copie a parte https://rumble.com/embed/xxxx/.

Se o oEmbed retornar um erro 403, instale curl_cffi e tente novamente com a impressão digital do Firefox. Substitua a URL de exemplo abaixo pelo endereço completo da página do vídeo.

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"

Se a nova tentativa falhar, use a ferramenta online para converter o link automaticamente.

3. Liste os formatos e verifique a alternativa

Execute o comando no diretório que contém a pasta plugins. Substitua o endereço pela URL /embed/ do vídeo desejado:

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

A identificação [RumbleEmbed+PlayerFallback] no log confirma que o plugin foi carregado:

  • Se a API JSON retornar 403, a linha seguinte mostrará Downloading player webpage. Essa linha confirma apenas que a alternativa foi acionada. A lista de formatos precisa aparecer em seguida para confirmar que os dados foram analisados com sucesso.
  • Se a API JSON retornar 200 na sua conexão, o processamento original continua, sem uma requisição adicional à página do player.

4. Baixe o vídeo e confira a decodificação

Escolha um ID na lista de formatos retornada por -F, como mp4-360p, e execute o download:

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

Este é o log do terminal no teste em que a alternativa foi acionada:

[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

Para verificar a integridade do contêiner MP4 e das faixas de áudio e vídeo baixadas, use ffprobe e 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 -

Como a página do player permite continuar após o erro 403 de JSON

1. Reutilizar os dados incluídos na página oficial

Por padrão, RumbleEmbedIE solicita os metadados JSON diretamente a https://rumble.com/embedJS/u3/?request=video&ver=2&v=.... Se o Cloudflare ou as medidas de proteção do site bloquearem especificamente essa API com HTTP 403, a extração é interrompida.

No entanto, os scripts da página oficial https://rumble.com/embed/<video_id>/ já contêm um objeto de configuração do vídeo com a mesma estrutura. Ele inclui o campo ua com os endereços das diferentes qualidades, o título, a duração e outros dados. Ao extrair esse objeto e retorná-lo em _download_json, o código de processamento de formatos do yt-dlp pode continuar sem alterações.

2. Remover o campo que não é JSON válido (loaded: h())

O objeto incluído na página não é um literal JSON estrito. Ele termina com uma chamada de função em tempo de execução, loaded: h(), como neste exemplo:

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

Se o objeto for passado diretamente a um analisador JSON, h() causará um erro de sintaxe. Por isso, o plugin usa o parâmetro transform_source de _search_json para remover, com uma expressão regular, apenas o trecho final , loaded: xxx() antes da análise. Toda a operação é feita sobre texto em memória, sem executar JavaScript da página:

  • Correspondência exata: extrai somente o objeto cuja chave é igual ao video_id atual (\b[\w$]+\.f\[\s*["']{video_id}["']\s*\]\s*=) e verifica se o resultado é um dicionário com um campo de mídia ua não vazio.
  • Intervenção limitada: a alternativa só é acionada quando _download_json captura um HTTPError com status 403. Erros 401, 404, 429 ou 500, ou a ausência de um objeto válido na página, fazem a exceção original ser lançada novamente, sem alterações.
  • Integração no nosso serviço: além de carregar o plugin, nosso serviço online usa a API oEmbed para converter os links normais dos vídeos em endereços /embed/. Quando --impersonate não é especificado, utiliza por padrão a identidade de navegador firefox-135.

Código completo do plugin

Salve o código abaixo como plugins/rumble/yt_dlp_plugins/extractor/rumble_player.py. Ele foi verificado com Python 3.12+ e 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
Ferramentas yt-dlp
Visualizar todas as ferramentas yt-dlp
Ajuda e documentação do yt-dlp