大家好,我是小小明,今天我要实现一个比较奇葩的需求,那就是直接在Jupyter上看B站直播。做到学习、学习(娱乐)两不误。
咱们最终要达到的效果:
获取指定分区直播间id列表
这次我们看直播的区域是:
然后我们该分区的直播间id列表:
import requests
from lxml import etree
def get_room_ids(room_type="学习"):
urls = {"学习": "https://live.bilibili.com/p/eden/area-tags?visit_id=9ynmsmaiie80&areaId=377&parentAreaId=11",
"颜值领域": "https://live.bilibili.com/show/yzly?visit_id=3g19a7bxnb60"}
res = requests.get(urls[room_type])
res.encoding = res.apparent_encoding
html = etree.HTML(res.text)
room_ids = {}
for a in html.xpath("//ul/li/a"):
url = a.xpath("./@href")[0]
tags = a.xpath(".//text()")
room_ids[tags[1]] = url[1:url.find("?")]
return room_ids
room_ids = get_room_ids()
room_ids
{'教建模的大叔': '22590752',
'<python副业>月入2万+直播分享': '23202081',
'前端编程小姐姐在线写游戏网页': '22273117',
'关注老师教你画效果图!': '22911727',
'零基础学Python/前端': '14584642',
'CAD2021速成教学,偷偷讲点干货知识': '22585718',
'Python学习入门到精通': '23158585',
'动画师如何跻身一线项目+高新大厂!': '11167301',
'2021Java行业经验程序员如何突破': '22061829',
'区块链专业人才考证啦': '23192838',
'影视后期教学(C4D/建模/AE)': '22728554',
'SpringBoot深度解析': '22247814',
'璇女神带你学Java': '14358641',
'今天装一把小伙伴的940': '22343807',
'【女流桜花】Aリーグ': '8896347',
'淘宝运营电商卖家开一家网店系统化教学课程': '22994700',
'抽抽抽吉他吧': '21495046',
'3D游戏建模/zbrush学习': '6616562',
'3D美术建模知识分享': '21362289',
'仅需0元设计课,四天带你超车涨薪': '22597780'}
获取指定直播间直播信号源地址
经过一番抓包分析,知道直播信号源的接口地址为:
https://api.live.bilibili.com/xlive/web-room/v1/playUrl/playUrl
获取视频源的地址,只需向上述的连接中传递3个参数,分别为:
- cid : cid序列号
- qn : 播放的视频质量
- platform : 视频的播放形式
import requests
def get_live_url(cid):
playUrl = 'https://api.live.bilibili.com/xlive/web-room/v1/playUrl/playUrl'
params = {
'cid': cid, # cid序列号
'qn': 1000, # 播放的视频质量
'platform': 'h5', # 视频的播放形式
'ptype': 16
}
response = requests.get(playUrl, params=params).json()
text = response['data']['durl']
url = text[-1]['url']
return url
上述代码中指定了视频的播放形式为h5,最终抓到的将是m3u8格式的直播地址。
url = get_live_url(room_ids['3D游戏建模/zbrush学习'])
url
'https://d1--cn-gotcha103.bilivideo.com/live-bvc/484428/live_137444201_2481017.m3u8?cdn=cn-gotcha03&expires=1624862132&len=0&oi=1947748628&pt=h5&qn=10000&trid=10031734853477fb4f7eba52bedbf0ad4958&sigparams=cdn,expires,len,oi,pt,qn,trid&sign=ff26ba84039442d42c59ae2310768bdc&ptype=0&src=9&sl=1&sk=417e709c171a500&order=4'
编写针对m3u8的前端播放器
针对这种地址,一般的本地播放器都是无法直接的。我们想要播放这种地址,需要实现一个h5的专门的播放器,具体需要用到两个js文件:
- video.js
- videojs-contrib-hls.min.js
找到了两个现成的cdn地址,我们无需下载为本地文件,最终代码为:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<link href="https://cdn.bootcss.com/video.js/7.6.5/alt/video-js-cdn.min.css" rel="stylesheet">
<script src="https://cdn.bootcss.com/video.js/6.6.2/video.js"></script>
<script src="https://cdn.bootcss.com/videojs-contrib-hls/5.15.0/videojs-contrib-hls.min.js"></script>
</head>
<body>
<video id="myVideo" class="video-js vjs-default-skin vjs-big-play-centered" controls preload="auto" width="760" height="428" data-setup='{}'>
<source id="source" src="https://d1--cn-gotcha103.bilivideo.com/live-bvc/484428/live_137444201_2481017.m3u8?cdn=cn-gotcha03&expires=1624862132&len=0&oi=1947748628&pt=h5&qn=10000&trid=10031734853477fb4f7eba52bedbf0ad4958&sigparams=cdn,expires,len,oi,pt,qn,trid&sign=ff26ba84039442d42c59ae2310768bdc&ptype=0&src=9&sl=1&sk=417e709c171a500&order=4" type="application/x-mpegURL">
</video>
</body>
<script>
// videojs 简单使用
var myVideo = videojs('myVideo',{
bigPlayButton : true,
textTrackDisplay : false,
posterImage: false,
errorDisplay : false,
})
myVideo.play() // 视频播放
</script>
</html>
最终打开的效果:
经测试完全顺利实现直播播放。
最终将其中可能变化的部分定义出来作为模板得到template.html文件。
开启直播
做完模板我们就可以实现在jupyter中直播了,代码如下:
效果: