ytdlp.online
Trang chủ Tampermonkey

Tất cả hướng dẫn sửa lỗi

Mục lục

Sửa lỗi yt-dlp Rumble 403: dùng dữ liệu trình phát khi API JSON thất bại

Ngày đăng

Tải plugin sửa lỗi rumble_player.py

Nếu yt-dlp báo Unable to download JSON metadata: HTTP Error 403: Forbidden khi tải video Rumble, bạn có thể nạp plugin tương thích trong bài này. Khi API JSON embedJS/u3 của Rumble trả về 403, plugin tự động lấy trang trình phát nhúng chính thức (/embed/) của cùng video, trích xuất dữ liệu media có sẵn trong trang và tiếp tục tải.

Nếu không muốn cấu hình plugin trên máy hoặc chuyển đổi liên kết thủ công, bạn có thể dùng trình tải video Rumble của trang web này, đã tích hợp cách sửa lỗi đó.

Xác định bước nào trả về 403

Lỗi 403 khi tải video Rumble có thể xảy ra ở ba giai đoạn. Plugin trong bài này chỉ xử lý trường hợp thứ hai:

Lỗi hoặc triệu chứng Yêu cầu bị chặn Cách xử lý
Unable to download webpage: HTTP Error 403 HTML của trang xem video bị chặn (xem issue #15089) Dùng API oEmbed chính thức để lấy địa chỉ /embed/, kết hợp với --impersonate firefox
Unable to download JSON metadata: HTTP Error 403 API siêu dữ liệu embedJS/u3 bị chặn (xem issue #17496) Dùng plugin trong bài này: tự động chuyển sang đọc dữ liệu nhúng trong trang /embed/
Đã hiển thị danh sách định dạng nhưng bị 403 khi tải phân đoạn hoặc MP4 Yêu cầu luồng media tới CDN bị từ chối Kiểm tra proxy, header của yêu cầu hoặc chọn định dạng có chất lượng khác

Các bước sửa lỗi nhanh

1. Lưu tệp plugin

Tạo các thư mục theo cấu trúc dưới đây trong thư mục làm việc, rồi lưu toàn bộ mã plugin ở cuối bài thành rumble_player.py. Bạn không cần sửa mã nguồn yt-dlp:

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

2. Lấy địa chỉ /embed/ chính thức của video

ID trong URL trang xem Rumble, chẳng hạn v6xxxx, khác với ID của trình phát nhúng, chẳng hạn vb0ofn. Vì vậy, bạn không thể tự ghép địa chỉ nhúng từ ID của trang xem. Nếu chỉ có liên kết trang xem thông thường, hãy gọi API oEmbed công khai của Rumble để lấy địa chỉ /embed/ thực tế:

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

Trong trường html của JSON trả về, tìm <iframe src="https://rumble.com/embed/xxxx/..." rồi lấy phần https://rumble.com/embed/xxxx/.

Nếu oEmbed trả về lỗi 403, hãy cài curl_cffi rồi thử lại với dấu vân tay của Firefox. Thay URL ví dụ bên dưới bằng URL đầy đủ của trang 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"

Nếu vẫn không được, hãy dùng trình tải trực tuyến để tự động chuyển đổi liên kết.

3. Liệt kê định dạng và kiểm tra đường dự phòng

Chạy lệnh sau trong thư mục chứa plugins. Khi sử dụng, thay URL bằng địa chỉ /embed/ của video cần tải:

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

Nếu nhật ký có [RumbleEmbed+PlayerFallback], plugin đã được nạp:

  • Nếu API JSON trả về 403, dòng Downloading player webpage sẽ xuất hiện ngay sau đó, cho biết đường dự phòng đã được kích hoạt. Danh sách định dạng xuất hiện sau dòng này mới xác nhận dữ liệu đã được phân tích thành công.
  • Nếu API JSON trả về 200 trong môi trường mạng hiện tại, yt-dlp tiếp tục dùng quy trình gốc và không gửi thêm yêu cầu tới trang trình phát.

4. Tải video và kiểm tra giải mã

Chọn một ID định dạng từ danh sách của -F, chẳng hạn mp4-360p, rồi tải video:

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

Nhật ký terminal đầy đủ khi đường dự phòng được kích hoạt trong lần thử thực tế:

[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

Để kiểm tra container MP4 cùng các luồng hình ảnh và âm thanh có đầy đủ, không bị hỏng hay không, dùng ffprobe và 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 -

Cơ chế hoạt động: vì sao trang trình phát tránh được lỗi JSON 403?

1. Tái sử dụng dữ liệu nhúng từ cùng trang web

Theo mặc định, RumbleEmbedIE yêu cầu trực tiếp https://rumble.com/embedJS/u3/?request=video&ver=2&v=... để lấy siêu dữ liệu JSON. Nếu Cloudflare hoặc cơ chế kiểm soát truy cập của trang web chỉ chặn API này và trả về HTTP 403, quá trình trích xuất sẽ dừng lại.

Tuy nhiên, mã script của trang nhúng chính thức https://rumble.com/embed/<video_id>/ đã chứa một đối tượng cấu hình video có cấu trúc giống hệt. Đối tượng này bao gồm ua với các địa chỉ luồng theo chất lượng, tiêu đề, thời lượng và các trường khác. Chỉ cần trích xuất đối tượng đó rồi trả về từ _download_json, yt-dlp có thể tiếp tục mà không phải sửa bất kỳ dòng mã phân tích định dạng nào phía sau.

2. Loại bỏ trường không hợp lệ trong JSON (loaded: h())

Đối tượng dữ liệu nhúng trong trang không phải là một literal JSON hợp lệ hoàn toàn. Cuối đối tượng có lời gọi hàm lúc chạy loaded: h(), như sau:

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

Nếu đưa thẳng vào bộ phân tích JSON, h() sẽ gây lỗi cú pháp. Vì vậy, plugin dùng hook transform_source trong _search_json để loại bỏ riêng phần , loaded: xxx() ở cuối bằng biểu thức chính quy trước khi phân tích. Toàn bộ thao tác diễn ra trên văn bản trong bộ nhớ, không thực thi JavaScript của trang:

  • Khớp chính xác: chỉ trích xuất đối tượng có khóa trùng hoàn toàn với video_id hiện tại (\b[\w$]+\.f\[\s*["']{video_id}["']\s*\]\s*=). Đồng thời kiểm tra giá trị trả về là dictionary và chứa trường luồng media ua không rỗng.
  • Can thiệp tối thiểu: chỉ chuyển sang đường dự phòng khi _download_json bắt được HTTPError có mã trạng thái 403. Với lỗi 401, 404, 429, 500 hoặc khi trang không chứa đối tượng hợp lệ, plugin ném lại nguyên ngoại lệ ban đầu.
  • Xử lý bổ sung trên dịch vụ trực tuyến: ngoài việc nạp plugin, dịch vụ của chúng tôi tự động gọi API oEmbed để chuyển URL trang xem do người dùng nhập thành địa chỉ /embed/. Nếu không có tùy chọn --impersonate, dịch vụ mặc định dùng dấu vân tay firefox-135.

Mã plugin đầy đủ

Lưu mã dưới đây thành plugins/rumble/yt_dlp_plugins/extractor/rumble_player.py. Mã đã được kiểm chứng trên Python 3.12+ và 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
Công cụ yt-dlp
Xem tất cả các công cụ yt-dlp
Trợ giúp & Tài liệu yt-dlp