大家好,我是小小明。
今天要在Jupyter上玩点前端的东西:
- 在jupyter上玩转HTML:Jupyter上看MP4视频
- 在Jupyter上玩转CSS:设置Pandas表格的动画样式
- 在Jupyter上玩转JavaScript:在Jupyter上看直播视频
首先来点简单的,在jupyter上玩转HTML:
Jupyter上看视频
看本地视频:
from IPython.display import HTML
def show_video(url, width="100%"):
html = f"""<video controls="" name="media" data-fullscreen-container="true" width="{width}">
<source src="{url}" type="video/mp4">
</video>"""
return HTML(html)
show_video("a.mp4", "30%")
注意:仅支持相对路径,要求视频文件和ipynb文件在同一目录或子目录下
看在线视频:
show_video("https://www.runoob.com/try/demo_source/mov_bbb.mp4", "70%")
在Jupyter上玩转CSS:
让Jupyter上的Pandas表格跟着鼠标动起来
旋转:
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.rand(5, 2), columns=['data1', 'data2'])
df['key1'] = ['a', 'a', 'b', 'b', 'e']
df['key2'] = ['one', 'two', 'one', 'two', 'one']
df.style.set_table_styles([
{'selector': 'tr',
'props': [('transition-duration', '1s')]},
{'selector': 'tr:hover',
'props': [('transform', ' rotate(360deg)')]}
])
位移:
df.style.set_table_styles([
{'selector': 'tr',
'props': [('transition-duration', '1s')]},
{'selector': 'tr:hover',
'props': [('transform', 'translate(90%)')]}
])
具体原理:
先对目标元素设置过渡时间,参考:https://www.runoob.com/css3/css3-transitions.html
然后通过伪类hover设置鼠标移动到目标元素的特殊样式。
上面两种样式变化使用了2D变化的两个方法,参考:https://www.runoob.com/css3/css3-2dtransforms.html
最后我们在Jupyter上玩转JavaScript:
执行JavaScript命令
要在jupyter中执行JavaScript很简单,直接使用Javascript命令就可以执行:
from IPython.display import Javascript
Javascript("alert('执行了一段JavaScript')")
可以看到执行后,弹出了提示窗口。
Jupyter上看直播视频
下面呢,我们打算实现直接在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, platform='h5'):
playUrl = 'https://api.live.bilibili.com/xlive/web-room/v1/playUrl/playUrl'
params = {
'cid': cid, # cid序列号
'qn': 10000, # 播放的视频质量
'platform': platform, # 视频的播放形式
'ptype': 16
}
response = requests.get(playUrl, params=params).json()
text = response['data']['durl']
url = text[-1]['url']
return url
可以传入参数web,可以获取flv的流媒体格式:
url = get_live_url(room_ids['璇女神带你学Java'], 'web')
url
'https://d1--cn-gotcha04.bilivideo.com/live-bvc/370442/live_381426464_8387123_1500.flv?cdn=cn-gotcha04&expires=1624877425&len=0&oi=1947748628&pt=web&qn=150&trid=1000a40949329fc44be7ad3f64f48b5e6102&sigparams=cdn,expires,len,oi,pt,qn,trid&sign=04b8a67515e5bc3f16cb4b386adebffb&ptype=0&src=9&sl=1&sk=417e709c171a500&order=4'
对于这种形式的地址,使用网页播放器需要特殊的解码库。由于本地播放器可以直接播放,本人觉得也没有必要开发针对这种格式的网页播放器。
对于上述地址直接粘贴到potplayer播放器中即可播放:
不指定目标参数则指定了参数为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'
这个地址直接粘贴到potplayer中是无法直接播放的,这是因为这个m3u8是一个嵌套的地址(真实的m3u8地址存在于这个文件中),我们将真实的地址提取出来就可以直接粘贴到potplayer进行播放了。
提取代码如下:
def get_real_url(url):
r = requests.get(url, headers={
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36"})
for line in r.text.splitlines():
if line.startswith("http"):
url = line
break
return url
real_url = get_real_url(url)
print(real_url)
https://236809363.cloudvdn.com/a.m3u8?cdn=cn-gotcha03&domain=d1--cn-gotcha103.bilivideo.com&expires=1624885067&len=0&oi=1947748628&order=4&player=oMgAAAUu2rUWvYwW&pt=h5&ptype=0&qn=10000&secondToken=secondToken%3A3pgIk9iJHnT4GCnoFdgLimMFp-I&sign=dd58d00836aa06776e6f2b0d933a3aee&sigparams=cdn%2Cexpires%2Clen%2Coi%2Cpt%2Cqn%2Ctrid&sk=87af7c4a512d23a&sl=1&src=8&streamid=live-qn%3Alive-qn%2Flive_8086004_8646306&trid=1003e246434329364ba685ff4d5ecff153a0&v3=1
不过我们开发的前端播放器针对嵌套的m3u8地址也是可以直接直播的:
编写针对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>
最终打开的效果:
经测试完全顺利实现直播播放。
最终将其中可能变化的部分以{xxx}形式定义出来作为模板,得到template.html文件(留给读者们自行补充)。
开启直播
做完模板我们就可以实现在Jupyter中直播了,代码如下:
效果: