3 Commits

Author SHA1 Message Date
copilot-swe-agent[bot]
bd8b4dc44e Fix Bilibili 412 error: inject dm_img risk-control params into yt-dlp wbi/playurl requests 2026-06-11 03:25:30 +00:00
copilot-swe-agent[bot]
e5a7cf7151 Initial plan 2026-06-11 03:18:45 +00:00
huangjianwu
f5bfb43619 docs(readme): 群二维码改为关注公众号回复「交流群」获取
将 README 社区区块中 5 个会过期的微信群二维码,替换为公众号二维码,
关注后回复「交流群」获取最新群码,避免群码失效。与关于页保持一致。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 02:09:03 +08:00
2 changed files with 53 additions and 9 deletions

View File

@@ -386,18 +386,11 @@ docker-compose -f docker-compose.gpu.yml up --build -d
### Contact and Join-联系和加入社区
码加入 BiliNote 交流微信群(共 5 个群,任选一个即可;二维码会定期更新,如已失效请到 [Issues](https://github.com/JefferyHcool/BiliNote/issues) 反馈
描下方公众号二维码,关注后回复 **「交流群」** 即可获取最新的微信交流群二维码(群码会自动更新,避免过期失效
<table align="center">
<tr>
<td align="center"><img src="./doc/wechat-group-1.png" alt="BiliNote 交流群 1" width="200" /><br/>交流群 1</td>
<td align="center"><img src="./doc/wechat-group-2.png" alt="BiliNote 交流群 2" width="200" /><br/>交流群 2</td>
<td align="center"><img src="./doc/wechat-group-3.png" alt="BiliNote 交流群 3" width="200" /><br/>交流群 3</td>
</tr>
<tr>
<td align="center"><img src="./doc/wechat-group-4.png" alt="BiliNote 交流群 4" width="200" /><br/>交流群 4</td>
<td align="center"><img src="./doc/wechat-group-5.png" alt="BiliNote 交流群 5" width="200" /><br/>交流群 5</td>
<td></td>
<td align="center"><img src="./doc/wechat-gzh.png" alt="BiliNote 公众号" width="200" /><br/>BiliNote 公众号</td>
</tr>
</table>

View File

@@ -1,6 +1,9 @@
import base64
import os
import json
import logging
import random
import string
import tempfile
from abc import ABC
from typing import Union, Optional, List
@@ -18,6 +21,54 @@ from app.services.cookie_manager import CookieConfigManager
logger = logging.getLogger(__name__)
def _patch_bilibili_extractor():
"""
Monkey-patch yt-dlp's BilibiliBaseIE._download_playinfo to inject the
dm_img_* / web_location risk-control parameters that Bilibili's
wbi/playurl gateway started requiring (returns HTTP 412 without them).
The parameter format (string.printable source + [:-2] base64 truncation)
mirrors yt-dlp's own implementation for the same fields in the channel
search endpoint (yt_dlp/extractor/bilibili.py, BiliBiliSpaceIE).
"""
try:
from yt_dlp.extractor.bilibili import BilibiliBaseIE
# Guard: skip if already patched (e.g. module reloaded in tests)
if getattr(BilibiliBaseIE._download_playinfo, '_bili_dm_patched', False):
return
_original_download_playinfo = BilibiliBaseIE._download_playinfo
def _patched_download_playinfo(self, bvid, cid, headers=None, query=None):
# Inject dummy risk-control fingerprints expected by Bilibili's gateway.
# The [:-2] truncation and string.printable source intentionally match
# yt-dlp's own pattern used for the x/space/wbi/arc/search endpoint.
extra = {
'web_location': 1550101,
'dm_img_list': '[]',
'dm_img_str': base64.b64encode(
''.join(random.choices(string.printable, k=random.randint(16, 64))).encode()
)[:-2].decode(),
'dm_cover_img_str': base64.b64encode(
''.join(random.choices(string.printable, k=random.randint(32, 128))).encode()
)[:-2].decode(),
'dm_img_inter': '{"ds":[],"wh":[6093,6631,31],"of":[430,760,380]}',
}
# Caller-supplied query params take precedence over the dummy values
merged_query = {**extra, **(query or {})}
return _original_download_playinfo(self, bvid, cid, headers=headers, query=merged_query)
_patched_download_playinfo._bili_dm_patched = True
BilibiliBaseIE._download_playinfo = _patched_download_playinfo
logger.info("Applied Bilibili wbi/playurl dm_img patch to yt-dlp BilibiliBaseIE")
except Exception as e:
logger.warning("Failed to apply Bilibili dm_img patch: %s", e)
_patch_bilibili_extractor()
class BilibiliDownloader(Downloader, ABC):
def __init__(self):
super().__init__()