ytdlp.online

Semua solusi

Di halaman ini

Mengatasi yt-dlp Rumble 403: beralih ke data pemutar saat JSON gagal

Tanggal terbit

Unduh plugin perbaikan rumble_player.py

Jika yt-dlp menampilkan Unable to download JSON metadata: HTTP Error 403: Forbidden saat mengunduh video Rumble, Anda dapat memuat plugin kompatibilitas dalam artikel ini. Ketika API JSON embedJS/u3 Rumble mengembalikan 403, plugin otomatis mengambil halaman pemutar sematan resmi (/embed/) untuk video yang sama. Plugin kemudian mengekstrak data media yang ada di dalam halaman dan melanjutkan unduhan.

Jika tidak ingin mengatur plugin di komputer atau mengonversi tautan secara manual, Anda juga dapat menggunakan pengunduh video Rumble di situs ini, yang sudah menyertakan perbaikan tersebut.

Pastikan tahap yang menghasilkan 403

Error 403 saat mengunduh Rumble dapat terjadi pada tiga tahap. Plugin dalam artikel ini khusus menangani kasus kedua:

Error atau gejala Permintaan yang diblokir Penanganan
Unable to download webpage: HTTP Error 403 HTML halaman tonton diblokir (lihat issue #15089) Gunakan API oEmbed resmi untuk mendapatkan alamat /embed/, bersama --impersonate firefox
Unable to download JSON metadata: HTTP Error 403 API metadata embedJS/u3 diblokir (lihat issue #17496) Gunakan plugin artikel ini: otomatis beralih ke data yang tertanam dalam halaman /embed/
Daftar format sudah muncul, tetapi 403 terjadi saat mengunduh segmen atau MP4 Permintaan stream media ke CDN ditolak Periksa proxy dan header permintaan, atau pilih format dengan kualitas lain

Langkah perbaikan cepat

1. Simpan berkas plugin

Buat struktur folder berikut di direktori kerja, lalu simpan kode plugin lengkap di akhir artikel sebagai rumble_player.py. Tidak perlu mengubah kode sumber yt-dlp:

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

2. Dapatkan alamat /embed/ resmi video

ID dalam URL halaman tonton Rumble, misalnya v6xxxx, berbeda dari ID pemutar sematan, misalnya vb0ofn. Karena itu, Anda tidak dapat langsung menyusun URL sematan menggunakan ID halaman tonton. Jika hanya memiliki tautan halaman tonton biasa, panggil API oEmbed publik Rumble untuk mendapatkan alamat /embed/ yang sebenarnya:

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

Cari <iframe src="https://rumble.com/embed/xxxx/..." dalam kolom html pada respons JSON, lalu ambil bagian https://rumble.com/embed/xxxx/.

Jika oEmbed mengembalikan 403, instal curl_cffi dan coba lagi dengan sidik jari Firefox. Ganti URL contoh di bawah dengan URL lengkap halaman video.

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"

Jika masih gagal, gunakan pengunduh online untuk mengonversi tautan secara otomatis.

3. Tampilkan format yang tersedia dan periksa jalur cadangan

Jalankan perintah berikut dari direktori yang berisi folder plugins. Ganti URL dengan alamat /embed/ video yang dituju:

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

Jika log menampilkan [RumbleEmbed+PlayerFallback], plugin sudah dimuat:

  • Jika API JSON mengembalikan 403, baris Downloading player webpage akan muncul setelahnya. Log ini hanya menandakan bahwa jalur cadangan telah dipicu. Keberhasilan penguraian data baru dapat dipastikan setelah daftar format muncul.
  • Jika API JSON mengembalikan 200 pada kondisi jaringan saat ini, yt-dlp tetap memakai proses aslinya tanpa mengirim permintaan tambahan ke halaman pemutar.

4. Unduh video dan uji dekode

Pilih salah satu ID format dari daftar -F, misalnya mp4-360p, lalu unduh:

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

Berikut log terminal lengkap ketika jalur cadangan dipicu dalam pengujian nyata:

[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

Untuk memeriksa apakah kontainer MP4 serta stream video dan audionya lengkap dan tidak rusak, gunakan ffprobe dan 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 -

Cara kerjanya: mengapa halaman pemutar dapat menghindari JSON 403?

1. Memakai kembali data tertanam dari situs yang sama

Secara default, RumbleEmbedIE meminta https://rumble.com/embedJS/u3/?request=video&ver=2&v=... secara langsung untuk mendapatkan metadata JSON. Jika Cloudflare atau kontrol akses situs memblokir API ini secara khusus dan mengembalikan HTTP 403, proses ekstraksi berhenti.

Namun, skrip halaman sematan resmi https://rumble.com/embed/<video_id>/ sudah memuat objek konfigurasi video dengan struktur yang sama. Objek ini mencakup ua berisi alamat stream untuk setiap kualitas, judul, durasi, dan kolom lainnya. Dengan mengekstrak objek tersebut dan mengembalikannya dari _download_json, yt-dlp dapat melanjutkan proses tanpa mengubah satu baris pun kode pengurai format berikutnya.

2. Menghapus kolom yang tidak sesuai standar JSON (loaded: h())

Objek data yang tertanam di halaman bukan literal JSON yang sepenuhnya valid. Bagian akhirnya berisi pemanggilan fungsi saat runtime, loaded: h(), seperti ini:

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

Jika langsung diberikan kepada pengurai JSON, h() akan menyebabkan error sintaks. Karena itu, plugin memakai hook transform_source dalam _search_json untuk menghapus hanya bagian , loaded: xxx() di akhir melalui ekspresi reguler sebelum penguraian. Seluruh proses menangani teks di memori tanpa menjalankan JavaScript halaman:

  • Pencocokan tepat: hanya mengekstrak objek yang nama kuncinya sama persis dengan video_id saat ini (\b[\w$]+\.f\[\s*["']{video_id}["']\s*\]\s*=). Nilai yang dikembalikan juga diperiksa agar berupa dictionary dengan kolom stream media ua yang tidak kosong.
  • Perubahan minimal: jalur cadangan hanya berjalan ketika _download_json menangkap HTTPError dengan kode status 403. Error 401, 404, 429, 500, atau halaman tanpa objek yang valid akan memunculkan kembali exception aslinya.
  • Penanganan tambahan di layanan online: selain memuat plugin, layanan kami otomatis memanggil API oEmbed untuk mengonversi URL halaman tonton yang dimasukkan pengguna menjadi alamat /embed/. Jika --impersonate tidak ditentukan, layanan menggunakan sidik jari firefox-135 secara default.

Kode plugin lengkap

Simpan kode berikut sebagai plugins/rumble/yt_dlp_plugins/extractor/rumble_player.py. Kode ini telah lolos pengujian dengan Python 3.12+ dan 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
Alat yt-dlp
Lihat semua alat yt-dlp
Bantuan & Dokumen yt-dlp