真无聊!居然在Jupyter上看B站的直播 学习3D建模

大家好,我是小小明,今天我要实现一个比较奇葩的需求,那就是直接在Jupyter上看B站直播。做到学习、学习(娱乐)两不误。

咱们最终要达到的效果:

真无聊!居然在Jupyter上看B站的直播 学习3D建模

获取指定分区直播间id列表

这次我们看直播的区域是:

真无聊!居然在Jupyter上看B站的直播 学习3D建模

然后我们该分区的直播间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>

最终打开的效果:

真无聊!居然在Jupyter上看B站的直播 学习3D建模

经测试完全顺利实现直播播放。

最终将其中可能变化的部分定义出来作为模板得到template.html文件。

开启直播

做完模板我们就可以实现在jupyter中直播了,代码如下:

真无聊!居然在Jupyter上看B站的直播 学习3D建模

效果:

真无聊!居然在Jupyter上看B站的直播 学习3D建模

上一篇:extJs 常用的正则表达式


下一篇:让你的js代码高大上