2019年2月4日,一年一度的哔哩哔哩拜年祭如约而至。不得不说,今年的拜年祭在节目质量和形式上相较于前三年都有较大的提升。出于在电视上离线播放(即非网络电视,而是读取存储设备上的媒体文件)的需求,及家中的缓慢网速达不到 Bilibili 大会员 1080P+ 无卡顿播放的程度,我利用少量的空余时间对 Bilibili 高清视频的下载方式进行了简单实践,并在本文中进行简单总结。

ID

熟悉B站的用户应该都会了解到,B 站上的视频、音频、专栏文章、用户都是以唯一的 ID 进行标识的。以“【星尘原创】尘降【PV付/COP】”这个视频为例:其视频地址为:https://www.bilibili.com/video/av4402328,该视频所对应的音频的地址为:https://www.bilibili.com/audio/au18065,上传该视频的UP主的个人主页地址为:https://space.bilibili.com/396194。由此我们可以获取到以下类型的唯一 ID:

  • 视频 ID [Anime (Video) ID, aid/avid]:4402328
  • 音频 ID [Audio ID, auid]:18065
  • 用户 ID [User ID, uid]:396194

中包含的“av”、“au”、“cv”等均是为了区分 ID 的类型所用。在 Ajax 请求过程中各 ID 的值均为数字,不包含字符。

在上述例子中没有包括的、实际应用的 ID 类型还有(不完全)[1]

  • 文章 ID [Content Viewing ID, cvid]
  • 内容 ID [Content ID, cid]
  • 通知 ID [Notification ID, nfid]
  • 会员 ID [Member ID, mid]
  • 标签 ID [Tag ID, tid]
  • 顺序 ID [Order ID, oid]
  • 分类 ID [Type ID, typeid]
  • 直播间 ID [Room ID, roomid]
  • 剧集 ID [Episode ID, epid]

在下载视频的时候,起到主要作用的是 aid 和 cid 这两个唯一 ID。aid 和 cid 的区别是:aid 既可以指单个视频,也可以指含有多个视频的播放列表,而 cid 是视频级唯一的。

活动专题页面找 aid

Bilibili 为拜年祭活动设计了专门的活动页面。链接为:

https://www.bilibili.com/blackboard/bnj2019.html

播放拜年祭视频的小电视播放器作为 HTML5 组件放置在活动页面内。使用开发者工具查看视频统计数据的 HTTP 请求,可以发现该播放器播放视频对应的 aid。比如默认情况下播放页面均会展示视频的总播放量、回复数、投币数等。如下图:


不难发现,获取这些统计信息所请求的链接地址(以拜年祭为例)是:

https://api.bilibili.com/x/web-interface/archive/stat?aid=36570401

返回的 JSON 数据(格式化后)如下:

{"code": 0,"message": "0","ttl": 1,"data": {"aid": 36570401,"view": 34739455,"danmaku": 1328696,"reply": 195310,"favorite": 1299858,"coin": 1859584,"share": 300501,"like": 1465982,"now_rank": 0,"his_rank": 0,"no_reprint": 0,"copyright": 1}
}

上面链接和 JSON 数据中“aid”均为视频对应的视频 ID。注:该链接实际上也是获取视频统计数据的 API 接口。在此处不对此链接进行进一步说明。
由此我们得到了拜年祭视频的正常播放地址应为:

http://www.bilibili.com/video/av36570401/

下载1080P及以下清晰度视频的办法

最为简便的方法是,我们可以利用已有的视频下载网站进行下载。这里我们举两个例子。

唧唧下载站,分段法

唧唧视频下载站也是一种下载视频的办法。它通过视频的热度高低来判断视频是否应预先解析和缓存在云端。较热门的视频可以直接从唧唧网站的服务器获取。较冷门的视频则可以通过客户端下载。客户端会尝试直接解析视频直连、修改 Referer 等进行分段下载然后合并。同时,该网站同时也拥有 MP3 转换服务,将视频中的音轨提取、转码后供用户下载。

ParseVideo,直链法

ParseVideo 则不提供客户端和云端缓存。这个网站的作用是直接解析出对应视频、对应清晰度的完整视频的直链,获得的直链可以用下载工具直接下载。例如:2019 拜年祭中,第一部分“珠”的 1080P 清晰度完整视频直链如下:

http://upos-hz-mirrorwcsu.acgvideo.com/upgcxcode/94/37/74633794/74633794-1-208.mp4?ua=tvproj&deadline=1550125016&gen=playurl&nbs=1&oi=2501663261&os=wcsu&trid=c01282c601bb4b0cb444a9b53342fc2e&uipk=5&upsig=556e65a3992c1531227fb43bcb6705a3

视频地址从哪来?

视频地址(参数的作用其实绝大部分都是鉴权和防盗链)可以从 Bilibili 的视频播放页获得。在加载视频前,HTML5 播放器会首先加载一个包含当前清晰度的视频链接的文件,名为 playurl。获取播放地址的完整链接为(登录状态下的 1080P+ 链接,Session MD5 部分隐去):

https://api.bilibili.com/x/player/playurl?avid=36570401&cid=74633794&qn=112&type=&otype=json&fnver=0&fnval=16&session=4710f|sec|

得到的 JSON 数据(格式化并去除转义字符后)类似这样(部分参数含有隐私信息,因此隐去,隐去部分用 |sec| 标识):

{"code": 0,"message": "0","ttl": 1,"data": {"from": "local","result": "suee","message": "","quality": 112,"format": "hdflv2","timelength": 2961402,"accept_format": "hdflv2,flv,flv720,flv480,flv360","accept_description": ["高清 1080P+", "高清 1080P", "高清 720P", "清晰 480P", "流畅 360P"],"accept_quality": [112, 80, 64, 32, 16],"video_codecid": 7,"seek_param": "start","seek_type": "offset","dash": {"duration": 2961,"minBufferTime": 1.5,"video": [{"id": 112,"baseUrl": "http://upos-hz-mirrorks3u.acgvideo.com/upgcxcode/94/37/74633794/74633794-1-30112.m4s?e=ig8eux|sec|&deadline=1550136700&gen=playurl&nbs=1&oi=1885698042&os=ks3u&platform=pc&trid=126ef7|sec|&uipk=5&upsig=c71526|sec|","backupUrl": null,"bandwidth": 5826637,"mimeType": "video/mp4","codecs": "avc1.640028","width": 1920,"height": 1080,"frameRate": "16000/672","sar": "1:1","startWithSap": 1,"SegmentBase": {"Initialization": "0-992","indexRange": "993-8128"},"codecid": 7}],"audio": [{"id": 30280,"baseUrl": "http://upos-hz-mirrorks3u.acgvideo.com/upgcxcode/94/37/74633794/74633794_nb1-1-30280.m4s?e=ig8eux|sec|&deadline=1550136700&gen=playurl&nbs=1&oi=1885698042&os=ks3u&platform=pc&trid=126ef7|sec|&uipk=5&upsig=5f58ae|sec|","backupUrl": null,"bandwidth": 321706,"mimeType": "audio/mp4","codecs": "mp4a.40.2","width": 0,"height": 0,"frameRate": "","sar": "","startWithSap": 0,"SegmentBase": {"Initialization": "0-907","indexRange": "908-8055"},"codecid": 0}, {"id": 30216,"baseUrl": "http://upos-hz-mirrorcos.acgvideo.com/upgcxcode/94/37/74633794/74633794-1-30216.m4s?um_deadline=1550136700&platform=pc&rate=0&oi=1885698042&um_sign=df1a58|sec|&gen=playurl&os=cos&trid=126ef7|sec|","backupUrl": null,"bandwidth": 67238,"mimeType": "audio/mp4","codecs": "mp4a.40.2","width": 0,"height": 0,"frameRate": "","sar": "","startWithSap": 0,"SegmentBase": {"Initialization": "0-907","indexRange": "908-8055"},"codecid": 0}]}}
}

playurl 获取时各个参数的含义:

  • avid,即视频 ID。cid,即该视频所对应的内容 ID。
  • qn,视频质量代码。对应的是 JSON 格式中“accept_quality”这个 list 中的值。
  • otype:数据的呈现形式。可以是 JSON 或 XML。
  • type:用途不明。可能跟平台类型有关。
  • fnver:用途不明。
  • fnval:控制视频的格式。fnval 为 0 时是 FLV 格式,为 1 时是 MP4 格式,为 16时是 DASH 序列。

因此获取视频ID为 36570401(对应的内容ID为 74633794)的 1080P FLV 格式的播放地址(注意:不是直链,也不能直接播放,仅为小电视播放器能够解析的地址)并展示为 XML 格式的链接:

https://api.bilibili.com/x/player/playurl?avid=36570401&cid=74633794&qn=80&otype=xml&fnval=0

以上结束了针对 playurl 的讨论。至于如何构造参数使得 playurl 包含的视频链接可供下载和播放,因为没有更深层的探究,所以此处不继续讨论。但是视频直链中包含“ua=tvproj”字样,又结合 Bilibili 具有 DLNA 投屏功能,可进行初步猜想:“直链”的参数构造应仿照了 App DLNA 投屏时,App 发送给 DLNA 终端的视频链接所附带的参数。

利用 Android App 下载高清视频

Bilibili App 内部本身拥有缓存功能,虽然并非对所有视频开放(比如:受到版权保护只能够在线观看的番剧),但是已开放缓存的视频可以利用“缓存”本身实现下载。

Bilibili 安卓客户端默认的视频缓存位置为:

/storage/emulated/0/Android/data/tv.danmaku.bili/download

该文件夹下包含着 App 缓存的所有视频文件。视频文件的存放位置为 [该视频的视频ID]/[该视频的分P数]/lua.[视频格式].bili2api.[视频质量]/0.blv。例如,2019 拜年祭“珠”部分 1080P+ 缓存完成后的视频文件完整路径为:

/storage/emulated/0/Android/data/tv.danmaku.bili/download/36570401/1/lua.hdflv2.bili2api.112/0.blv

已缓存完成视频的扩展名为 blv(Bilibili Video),未缓存完成的视频的扩展名为 bdl(Bilibili Download)。将已经缓存完毕的 blv 文件复制到其他位置,并改扩展名为 flv(根据“视频格式”进行判断)即可正常播放。

获取弹幕数据

网页前端获取弹幕数据的链接为:

https://api.bilibili.com/x/v1/dm/list.so?oid=74633794

此处 oid 的值即为对应视频 cid 的值。当然你也可以从 App 的缓存中提取弹幕数据。接上例,视频缓存对应的弹幕数据缓存文件完整路径为:

/storage/emulated/0/Android/data/tv.danmaku.bili/download/36570401/1/danmaku.xml

另外,缓存文件夹内包含的其他文件作用列举如下:

  • entry.json 保存缓存视频的基本信息和统计数据。
  • index.json 保存缓存视频的下载地址。
  • 0.blv.4m.sum 保存缓存视频的字节大小。

由于互联网上已有多篇对xml弹幕数据进行综合处理的文章,所以在此处不再进一步讨论弹幕数据的处理相关内容。

加密直播间的密码校验 API

这里直接给出 Bilibili用于校验直播间密码的接口:

https://api.live.bilibili.com/room/v1/Room/verify_room_pwd?room_id=roomid&pwd=pwd

其中,room_id 参数为直播间的房间 ID,pwd 参数为直播间的密码。

参考链接

[1] fython. BilibiliAPIDocs [DB/OL] 获取于2019.2.14

原创。发于https://www.zhouweitong.site/2019/02/13/009-bilibili-playlink-findings/

Bilibili拜年祭启发的小小探索相关推荐

  1. 强化学习之基于伪计数的探索算法

    ©作者|王治海 学校|中国科学技术大学硕士生 研究方向|强化学习与机器博弈 强化学习基于智能体与环境的交互,以最大化累积奖励为目标,学习状态到动作的映射(即策略).本文将主要围绕强化学习中的探索问题展 ...

  2. 【英语-同义词汇词组】enlighten | inspire 表示【启发】时的用法及区别

    这两者的区分是高难度的区分,务必要用心体会.总的来说,两者虽字面上都有启迪之义,但是他们有本质区别.Enlighten有解惑.引向正途的意味,inspire则可以看成是"触发".& ...

  3. AIFramework基本概念整理

    AIFramework基本概念整理 本文介绍: • 对天元 MegEngine 框架中的 Tensor, Operator, GradManager 等基本概念有一定的了解: • 对深度学习中的前向传 ...

  4. 人脸和宇宙是啥关系?看物理学家怎样用重整化群流模型重新理解视觉

    导语 深度学习技术,尤其是生成模型在图像问题处理上大放异彩. 而生成模型之所以展现出强大的多层信号处理能力,与物理学中的重整化群理论密切相关.研究者结合重整化群方法和流模型,开发出可以发现自然作用力的 ...

  5. 学界 | DeepMind论文解读:通过删除神经元来了解深度学习

    作者:杨文 深度神经网络由许多单独的神经元组成,它们以复杂且违反人直觉的方式组合起来,以解决各种具有挑战性的任务.这种复杂性一方面赋予神经网络神秘力量,另一方面,也让它们变成了人类难懂的黑匣子. 了解 ...

  6. 架构 encoder_一种新的超分模型蒸馏架构 (ECCV2020)

    Learning with Privileged Information for Efficient Image Super-Resolution,ECCV2020 作者信息: Paper: Lear ...

  7. 【译】Attacks against machine learning — an overview

    这篇博客文章调查了针对AI(人工智能)系统的攻击技术以及如何防范它们. 在较高级别,对分类器的攻击可以分为三种类型: 对抗性输入 ,这是特制的输入,其目的是可靠地错误分类以逃避检测. 对抗性输入包括旨 ...

  8. 我们需要什么样的开源教育?

    点击上方"开源社"关注我们 | 作者:庄表伟 | 编辑:沈于蓝 | 设计:宋传琪 ‍文章缘起 ‍ 写这篇文章的原因,是和几个朋友的闲聊.再之前,是因为看到了几篇文章 2020-12 ...

  9. 自然数 素数 质数_在Java中获取素数的无限列表

    自然数 素数 质数 一个常见的问题是确定数字的素因式分解. 蛮力方法是审判部门( 维基百科 , 可汗学院 ),但是如果必须考虑多个数字,这需要大量的浪费工作. 一种广泛使用的解决方案是Eratosth ...

  10. jca使用_使用JCA的密码学–提供者中的服务

    jca使用 Java密码体系结构(JCA)是一个可扩展的框架,使您能够使用执行加密操作. JCA还促进实现独立性(程序不应该在乎谁提供加密服务)和实现互操作性(程序不应该与特定加密服务的特定提供者联系 ...

最新文章

  1. react组件回顶部
  2. 院士论坛 | 郭毅可院士:人工智能的热望与冷思考
  3. php curl errno 3,PHP curl_errno函数
  4. 3.1.3 训练/开发/测试集的问题以及注意事项
  5. 如何搭建一个内部组件共享平台
  6. python 跳过_python-pytest学习(九)-跳过用例skip
  7. java 发送邮件_SpringBoot 2.1.5发送验证码邮件
  8. mysql event 变量_DQL--select和MySQL的Event
  9. python django查询12306火车票
  10. matlab fftshift
  11. 多媒体计算机网络机房方案,学校多媒体教室及计算机机房方案1.doc
  12. 大学计算机应用经典案例,大学计算机基础经典实验案例集
  13. 亚马逊后台数据分析-电商数据分析
  14. matlab 布莱克曼,基于MATLAB的布莱克曼窗FIR数字低通滤波器设计程序
  15. CISSP考点拾遗——SDLC(1)
  16. 魏小亮:参加编程竞赛对实际工作的用处
  17. CSS3实现自适应的聊天气泡
  18. 在微博视频,见证“新”博主诞生
  19. xp系统在哪里查看补丁安装?系统补丁查看方法
  20. win7调整屏幕亮度_三星屏幕亮度微调app免费版下载-三星手机屏幕亮度微调软件一键操作版v1.0 最新版...

热门文章

  1. 网传前端大神司徒正美突发病逝,再度思考健康与金钱
  2. JESD204B调试笔记(实用版)
  3. 摄影测量(一):概述
  4. matlab读取图像的RGB
  5. linux远程文件复制,Linux远程复制文件
  6. mysql分页查询如何优化_mysql分页查询优化
  7. python爬取别人qq空间相册_Python_小林的爬取QQ空间相册图片链接程序
  8. 车辆方向盘转角传动比标定方法
  9. 微信小程序-TabBar用法
  10. mbedtls学习--对称加密算法