zl程序教程

您现在的位置是:首页 >  云平台

当前栏目

在Jupyter上不仅看直播视频还玩CSS动画,就是这么炫酷

直播动画CSS 视频 这么 就是 Jupyter 炫酷
2023-09-11 14:14:30 时间

大家好,我是小小明。

今天要在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文件在同一目录或子目录下

image-20210628154241672

看在线视频:

show_video("https://www.runoob.com/try/demo_source/mov_bbb.mp4", "70%")

image-20210628154454465

在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%)')]}
])

a

具体原理:

先对目标元素设置过渡时间,参考: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')")

image-20210628164150577

可以看到执行后,弹出了提示窗口。

Jupyter上看直播视频

下面呢,我们打算实现直接在Jupyter上看B站直播。做到学习、学习(娱乐)两不误。

最终要达到的效果:

image-20210628133632586

获取指定分区直播间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播放器中即可播放:

image-20210628175628807

不指定目标参数则指定了参数为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中直播了,代码如下:

image-20210628143415554

效果:

b