bili-sync icon indicating copy to clipboard operation
bili-sync copied to clipboard

下载失败的视频块,重置了几次都不行,有什么好的解决方案么

Open xu373297464 opened this issue 2 months ago • 8 comments

Image

xu373297464 avatar Sep 27 '25 12:09 xu373297464

我的也是,每次重置后在日志里依然报错,但是手机客户端里缓存正常

zh8416 avatar Sep 28 '25 03:09 zh8416

b站cdn的问题,看日志就可以发现访问upos-sz-mirrorbd.bilivideo.com、upos-sz-mirrorbd.bilivideo.com、upos-hz-mirrorakam.akamaized.net、upos-sz-mirrorbdb.bilivideo.com、upos-sz-estgoss.bilivideo.com这些出现404,我挂vpn解决了,可以正常下载,不过最后因为频繁切换ip被风控了,或者也可以尝试在路由器做一个dns劫持,用zhale.me找一个能够访问的ip换上试一试

Image

uparrows avatar Sep 28 '25 14:09 uparrows

设置中的cdn排序有用么 @uparrows

xu373297464 avatar Sep 30 '25 14:09 xu373297464

设置中的cdn排序有用么 @uparrows

试过没有用,目前只有挂代理解决

uparrows avatar Oct 01 '25 09:10 uparrows

报错日志如下:处理视频「【中土群像】霍比特人&指环王(中土不朽,传奇永存)」第 1 页视频失败:failed to download file: HTTP status client error (404 Not Found) for url (https://upos-sz-mirrorhwb.bilivideo.com/upgcxcode/45/14/3631445/3631445_da3-1-30280.m4s......

https://www.bilibili.com/video/BV16s411D7Mp/ 这个接口里,script下面会返回会返回视频和音频的 baseUrl、base_url、backupUrl、backupUrl,而且返回了好几组

下面这组就是audio的第二组数据,可以看到报错404的是backupUrl里的第二个 "baseUrl": "https://upos-sz-estgcos.bilivideo.com/upgcxcode/45/14/3631445/3631445_da3-1-30280.m4s", "base_url": "https://upos-sz-estgcos.bilivideo.com/upgcxcode/45/14/3631445/3631445_da3-1-30280.m4s", "backupUrl": ["https://upos-sz-estgcos.bilivideo.com/upgcxcode/45/14/3631445/3631445_da3-1-30280.m4s", "https://upos-sz-mirrorhwb.bilivideo.com/upgcxcode/45/14/3631445/3631445_da3-1-30280.m4s"], "backup_url": ["https://upos-sz-estgcos.bilivideo.com/upgcxcode/45/14/3631445/3631445_da3-1-30280.m4s", "https://upos-sz-mirrorhwb.bilivideo.com/upgcxcode/45/14/3631445/3631445_da3-1-30280.m4s"]

而抓包可以看到,B站根本没请求这个video/audio后几组数据,直接用第一组数据就完事了 希望可以参考,优化下载链接获取逻辑,从上到下按优先级使用CDN 每组内的baseUrl的CDN404之后,再尝试backupUrl,再尝试后面组的

PS:我已经开启了CDN排序,好像没作用,还是用排名靠后的CDN地址

woweichongzhen avatar Nov 01 '25 05:11 woweichongzhen

下载会尝试所有的 url。未打开 CDN 排序是 baseUrl + backupUrl,打开了是 sorted(baseUrl + backupUrl): https://github.com/amtoaer/bili-sync/blob/ff6db0ad979f05d1ec1a49bc98b0d76c73732b76/crates/bili_sync/src/bilibili/analyzer.rs#L134-L158

报错的是 backupUrl 里的第二个,是因为程序会依次请求所有的 url,成功直接跳出,错误继续尝试下一个,只有试到最后一个都失败才报错。这时报的是请求最后一个(也就是最低优先级)url 的错误。

amtoaer avatar Nov 01 '25 06:11 amtoaer

报错的是30280的audio[1] 里的backupUrl,是不是因为开了音频质量优先的原因,导致192k匹配失败后,没有降级用132k和64k;B站音频是没有提供可选项切换的,可能做了音质自动降级,他请求的是 30232 的音频数据

audio:

  1. "id": 30232
  2. "id": 30280
  3. "id": 30216

"dash": { "duration": 298, "minBufferTime": 1.5, "min_buffer_time": 1.5, "video": [ { "id": 64, "baseUrl": "https://upos-sz-estghw.bilivideo.com/upgcxcode/45/14/3631445/3631445_da3-1-30064.m4s", "base_url": "https://upos-sz-estghw.bilivideo.com/upgcxcode/45/14/3631445/3631445_da3-1-30064.m4s", "backupUrl": [ "https://upos-sz-estghw.bilivideo.com/upgcxcode/45/14/3631445/3631445_da3-1-30064.m4s", "https://upos-sz-mirrorhwb.bilivideo.com/upgcxcode/45/14/3631445/3631445_da3-1-30064.m4s" ], "backup_url": [ "https://upos-sz-estghw.bilivideo.com/upgcxcode/45/14/3631445/3631445_da3-1-30064.m4s", "https://upos-sz-mirrorhwb.bilivideo.com/upgcxcode/45/14/3631445/3631445_da3-1-30064.m4s" ], "bandwidth": 1290306, "mimeType": "video/mp4", "mime_type": "video/mp4", "codecs": "avc1.640028", "width": 1280, "height": 720, "frameRate": "29.412", "frame_rate": "29.412", "sar": "1:1", "startWithSap": 1, "start_with_sap": 1, "SegmentBase": { "Initialization": "0-994", "indexRange": "995-1734" }, "segment_base": { "initialization": "0-994", "index_range": "995-1734" }, "codecid": 7 }, { "id": 32, "baseUrl": "https://upos-sz-estghw.bilivideo.com/upgcxcode/45/14/3631445/3631445_da3-1-30032.m4s", "base_url": "https://upos-sz-estghw.bilivideo.com/upgcxcode/45/14/3631445/3631445_da3-1-30032.m4s", "backupUrl": [ "https://upos-sz-estghw.bilivideo.com/upgcxcode/45/14/3631445/3631445_da3-1-30032.m4s", "https://upos-sz-mirrorhwb.bilivideo.com/upgcxcode/45/14/3631445/3631445_da3-1-30032.m4s" ], "backup_url": [ "https://upos-sz-estghw.bilivideo.com/upgcxcode/45/14/3631445/3631445_da3-1-30032.m4s", "https://upos-sz-mirrorhwb.bilivideo.com/upgcxcode/45/14/3631445/3631445_da3-1-30032.m4s" ], "bandwidth": 788038, "mimeType": "video/mp4", "mime_type": "video/mp4", "codecs": "avc1.64001F", "width": 852, "height": 480, "frameRate": "29.412", "frame_rate": "29.412", "sar": "640:639", "startWithSap": 1, "start_with_sap": 1, "SegmentBase": { "Initialization": "0-999", "indexRange": "1000-1739" }, "segment_base": { "initialization": "0-999", "index_range": "1000-1739" }, "codecid": 7 }, { "id": 16, "baseUrl": "https://upos-sz-estgoss.bilivideo.com/upgcxcode/45/14/3631445/3631445_da3-1-30016.m4s", "base_url": "https://upos-sz-estgoss.bilivideo.com/upgcxcode/45/14/3631445/3631445_da3-1-30016.m4s", "backupUrl": [ "https://upos-sz-estgoss.bilivideo.com/upgcxcode/45/14/3631445/3631445_da3-1-30016.m4s", "https://upos-sz-mirroralib.bilivideo.com/upgcxcode/45/14/3631445/3631445_da3-1-30016.m4s" ], "backup_url": [ "https://upos-sz-estgoss.bilivideo.com/upgcxcode/45/14/3631445/3631445_da3-1-30016.m4s", "https://upos-sz-mirroralib.bilivideo.com/upgcxcode/45/14/3631445/3631445_da3-1-30016.m4s" ], "bandwidth": 351901, "mimeType": "video/mp4", "mime_type": "video/mp4", "codecs": "avc1.64001E", "width": 640, "height": 360, "frameRate": "29.412", "frame_rate": "29.412", "sar": "1:1", "startWithSap": 1, "start_with_sap": 1, "SegmentBase": { "Initialization": "0-1012", "indexRange": "1013-1752" }, "segment_base": { "initialization": "0-1012", "index_range": "1013-1752" }, "codecid": 7 } ], "audio": [ { "id": 30232, "baseUrl": "https://upos-sz-estgcos.bilivideo.com/upgcxcode/45/14/3631445/3631445_da3-1-30232.m4s", "base_url": "https://upos-sz-estgcos.bilivideo.com/upgcxcode/45/14/3631445/3631445_da3-1-30232.m4s", "backupUrl": [ "https://upos-sz-estgcos.bilivideo.com/upgcxcode/45/14/3631445/3631445_da3-1-30232.m4s", "https://upos-sz-mirrorcosb.bilivideo.com/upgcxcode/45/14/3631445/3631445_da3-1-30232.m4s" ], "backup_url": [ "https://upos-sz-estgcos.bilivideo.com/upgcxcode/45/14/3631445/3631445_da3-1-30232.m4s", "https://upos-sz-mirrorcosb.bilivideo.com/upgcxcode/45/14/3631445/3631445_da3-1-30232.m4s" ], "bandwidth": 127235, "mimeType": "audio/mp4", "mime_type": "audio/mp4", "codecs": "mp4a.40.2", "width": 0, "height": 0, "frameRate": "", "frame_rate": "", "sar": "", "startWithSap": 0, "start_with_sap": 0, "SegmentBase": { "Initialization": "0-907", "indexRange": "908-1659" }, "segment_base": { "initialization": "0-907", "index_range": "908-1659" }, "codecid": 0 }, { "id": 30280, "baseUrl": "https://upos-sz-estgcos.bilivideo.com/upgcxcode/45/14/3631445/3631445_da3-1-30280.m4s", "base_url": "https://upos-sz-estgcos.bilivideo.com/upgcxcode/45/14/3631445/3631445_da3-1-30280.m4s", "backupUrl": [ "https://upos-sz-estgcos.bilivideo.com/upgcxcode/45/14/3631445/3631445_da3-1-30280.m4s", "https://upos-sz-mirrorhwb.bilivideo.com/upgcxcode/45/14/3631445/3631445_da3-1-30280.m4s" ], "backup_url": [ "https://upos-sz-estgcos.bilivideo.com/upgcxcode/45/14/3631445/3631445_da3-1-30280.m4s", "https://upos-sz-mirrorhwb.bilivideo.com/upgcxcode/45/14/3631445/3631445_da3-1-30280.m4s" ], "bandwidth": 127235, "mimeType": "audio/mp4", "mime_type": "audio/mp4", "codecs": "mp4a.40.2", "width": 0, "height": 0, "frameRate": "", "frame_rate": "", "sar": "", "startWithSap": 0, "start_with_sap": 0, "SegmentBase": { "Initialization": "0-907", "indexRange": "908-1659" }, "segment_base": { "initialization": "0-907", "index_range": "908-1659" }, "codecid": 0 }, { "id": 30216, "baseUrl": "https://upos-sz-estghw.bilivideo.com/upgcxcode/45/14/3631445/3631445_da3-1-30216.m4s", "base_url": "https://upos-sz-estghw.bilivideo.com/upgcxcode/45/14/3631445/3631445_da3-1-30216.m4s", "backupUrl": [ "https://upos-sz-estghw.bilivideo.com/upgcxcode/45/14/3631445/3631445_da3-1-30216.m4s", "https://upos-sz-mirrorhwb.bilivideo.com/upgcxcode/45/14/3631445/3631445_da3-1-30216.m4s" ], "backup_url": [ "https://upos-sz-estghw.bilivideo.com/upgcxcode/45/14/3631445/3631445_da3-1-30216.m4s", "https://upos-sz-mirrorhwb.bilivideo.com/upgcxcode/45/14/3631445/3631445_da3-1-30216.m4s" ], "bandwidth": 67209, "mimeType": "audio/mp4", "mime_type": "audio/mp4", "codecs": "mp4a.40.2", "width": 0, "height": 0, "frameRate": "", "frame_rate": "", "sar": "", "startWithSap": 0, "start_with_sap": 0, "SegmentBase": { "Initialization": "0-950", "indexRange": "951-1702" }, "segment_base": { "initialization": "0-950", "index_range": "951-1702" }, "codecid": 0 } ], "dolby": { "type": 0, "audio": null }, "flac": null }

woweichongzhen avatar Nov 01 '25 06:11 woweichongzhen

播放器重要的是成功播放,自动降级是可以接受的;而下载器重要的是下载质量,没理由为了不失败,在 API 明确返回 192k 的情况下还尝试请求更低质量的。既然 API 返回了无效的视频流地址,那么下载器就应该正常报错

你给的兜底逻辑对播放器是个不错的策略,但很难适用于下载器。举个极端一点的例子,用户下载一个 4k 视频,b 站返回了 4k、1080p、480p 三个流:

  1. 请求 4k 时由于 b 站 CDN 问题返回了 404 错误;
  2. 请求 1080p 时网络波动卡顿,请求超时;
  3. 请求 480p 时正常下载。

最终的结果是:虽然下载器认为视频下载成功,但隐含的降级逻辑让一个 4k 视频下载到本地时变成了 480p。

我认为这不符合一般用户对下载器行为的预期。

amtoaer avatar Nov 01 '25 16:11 amtoaer

播放器重要的是成功播放,自动降级是可以接受的;而下载器重要的是下载质量,没理由为了不失败,在 API 明确返回 192k 的情况下还尝试请求更低质量的。既然 API 返回了无效的视频流地址,那么下载器就应该正常报错

你给的兜底逻辑对播放器是个不错的策略,但很难适用于下载器。举个极端一点的例子,用户下载一个 4k 视频,b 站返回了 4k、1080p、480p 三个流:

  1. 请求 4k 时由于 b 站 CDN 问题返回了 404 错误;
  2. 请求 1080p 时网络波动卡顿,请求超时;
  3. 请求 480p 时正常下载。

最终的结果是:虽然下载器认为视频下载成功,但隐含的降级逻辑让一个 4k 视频下载到本地时变成了 480p。

我认为这不符合一般用户对下载器行为的预期。

额,其实自动化的下载对视频质量并没有特别高的要求,更多是为了存档一些可能有审核和版权担忧的视频方便,真要解析一些4K的视频其实更倾向于手动用解析软件解析好链接下载下来就立刻处理

nzhijun avatar Dec 01 '25 09:12 nzhijun