Python流媒体播放器(基于VLC)
⽂章⽬录
⽹上关于Python的⾳视频播放⽰例都集中在简单的多媒体库或者PyGame这样的游戏库,有些库使⽤简单,但功能单⼀,有些库功能丰富,⽀持的格式多,但使⽤繁琐。那有没有⼀种功能丰富全⾯⼜使⽤简单,⽽且还能⽀持流媒体播放的库呢?答案是有的。
VLC就是我们今天的主⾓。官⽹地址:
根据官⽹的介绍,它是⼀款⾃由、开源的跨平台多媒体播放器及框架,它全⾯⽀持绝⼤部分的多媒体格式,以及各类流媒体协议。也就是说,使⽤它既能播放本地⾳视频⽂件,也能在线播放各类流媒体资源。
这是⽬前全⽹最全⾯的⼀篇关于VLC的Python语⾔绑定的使⽤教程,本⼈浏览了其API⽂档,从⽂档中直接提炼出了Python语⾔绑定的使⽤⽅法,本篇以Windows平台为主,如果读者朋友觉得有⽤,请点赞⽀持!
环境准备
更新:
对于很多⼈反应各种动态库报错问题,⾸先说明⼀点,严格按照本⽂步骤操作,其次,作为Python开发者,应当有版本兼容问题的觉悟。本⽂写作时,Python3.8版本尚未正式发布,后⾯许多⼈使⽤Python3.8及其之后版本运⾏本⽂⽰例,导致加载动态库存在问题。具体问题原因早在博主GitHub 仓库已经提出了,见
VLC 安装
VLC实际上是⽐较知名的开源多媒体播放器,要使⽤这个库,⾸先需要在电脑上安装VLC,我们可以直接在上述的中下载并安装它,有⼀点需要特别注意,如果本地安装的Python是32位,则你必须下载32位的VLC,64位则下64位的VLC,必须与Python的版本对应,否则⽆法使⽤。
事实上,我并不推荐这样直接安装。试想⼀下,如果我们使⽤Python开发⼀个基于VLC的播放器发布出去,却要求⽤户在使⽤之前,先安装⼀个VLC播放器,岂不是很荒谬?那么如何将VLC集成到Python程序中来,才是问题的关键。
关于这个问题,没有到相关资料,只能通过查看python-vlc绑定的源码来寻⽅法。
安装python-vlc 绑定
VLC是纯C语⾔开发的框架,Python想要更简单的调⽤,需要安装⼀个python-vlc 绑定,实际上就是⼀
个vlc.py模块,它封装了VLC动态库的接⼝,让我们使⽤更简单。
python -m pip install python-vlc
完成安装后,我们在site-packages中到vlc.py源码,查看其对VLC动态库的加载代码,可以发现,在Windows系统上,vlc.py是通过查询Windows注册表的⽅式来搜索路径并加载VLC的dll动态库的。但它其中也提供了⼀个配置环境变量PYTHON_VLC_MODULE_PATH的加载⽅式,这样我们就能在尽可能不修改vlc.py源码的前提下完成VLC动态库的集成。
好了,到这⾥,我们只需要去下载⼀个VLC的绿⾊免安装版本即可。由于我的Python环境是64位,这⾥给出⼀个Windows 64位下载地址: 选择vlc-3.0.6-win64.7z即可
下载完成后,解压⽬录,进⼊其中,删除⽆关内容,保留如下⽂件
其中plugins中的内容⾮常多,达到122M,我们可以根据实际情况进⾏剪裁,例如我们只需要做⼀个⾳
频播放器,则可将其中的video相关的⽂件夹删除,还包括gui⽂件夹,因为我们要⾃⼰做界⾯,不需要gui⾥⾯的qt相关的dll。
简单播放⽰例
创建⼀个Python⼯程,将已经剪裁好的vlc-3.0.6⽂件夹拷贝到⼯程根⽬录。然后创建⼀个python脚本,我们对vlc.py再次封装
import os, time
# 设置VLC库路径,需在import vlc之前
import vlc
class Player:
'''
args:设置 options
'''
def__init__(self,*args):
if args:
instance = vlc.Instance(*args)
else:
# 设置待播放的url地址或本地⽂件路径,每次调⽤都会重新加载资源
def set_uri(self, uri):
# 播放成功返回0,失败返回-1
def play(self, path=None):
if path:
self.set_uri(path)
dia.play()
else:
dia.play()
# 暂停
def pause(self):
# 恢复
def resume(self):
# 停⽌
def stop(self):
# 释放资源
def release(self):
lease()
# 是否正在播放
def is_playing(self):
dia.is_playing()
dia.is_playing()
# 已播放时间,返回毫秒值
def get_time(self):
_time()
# 拖动指定的毫秒值处播放。成功返回0,失败返回-1 (需要注意,只有当前多媒体格式或流媒体协议⽀持才会⽣效) def set_time(self, ms):
_time()
# ⾳视频总长度,返回毫秒值
def get_length(self):
_length()
# 获取当前⾳量(0~100)
def get_volume(self):
dia.audio_get_volume()
# 设置⾳量(0~100)
def set_volume(self, volume):
dia.audio_set_volume(volume)
# 返回当前状态:正在播放;暂停中;其他
def get_state(self):
state = _state()
if state == vlc.State.Playing:
return1
elif state == vlc.State.Paused:
return0
else:
return-1
# 当前播放进度情况。返回0.0~1.0之间的浮点数
def get_position(self):
_position()
# 拖动当前进度,传⼊0.0~1.0之间的浮点数(需要注意,只有当前多媒体格式或流媒体协议⽀持才会⽣效)
def set_position(self, float_val):
dia.set_position(float_val)
# 获取当前⽂件播放速率
def get_rate(self):
_rate()
# 设置播放速率(如:1.2,表⽰加速1.2倍播放)
def set_rate(self, rate):
dia.set_rate(rate)
# 设置宽⾼⽐率(如"16:9","4:3")
def set_ratio(self, ratio):
# 注册
def add_callback(self, event_type, callback):
# 移除
def remove_callback(self, event_type, callback):
调⽤代码
def my_call_back(event):
print("call:", _time())
marquee marquee
if"__main__"== __name__:
player = Player()
player.add_callback(vlc.EventType.MediaPlayerTimeChanged, my_call_back)
# 在线播放流媒体视频
player.play("hd.yinyuetai/uploads/videos/common/"
"22970150925A6BB75E20D95798D129EE.flv?sc\u003d17d6a907580e9892"
"\u0026br\u003d1103\u0026vid\u003d2400382\u0026aid\u003d32"
"\u0026area\u003dML\u0026vst\u003d0")
# 播放本地mp3
# player.play("D:/abc.mp3")
# 防⽌当前进程退出
while True:
pass
VLC
上⾯代码中,我们注册了MediaPlayerTimeChanged类型的,表⽰已播放时间变化时回调,可以看到my_call_back会不断回调,因为每播放⼀点都会回调。
除了上述的,VLC的实际上⾮常多,常见的我们列举如下:
MediaPlayerNothingSpecial:vlc处于空闲状态,只是等待发出命令
MediaPlayerOpening:vlc正在打开媒体资源定位器(MRL)
MediaPlayerBuffering(int cache):vlc正在缓冲
MediaPlayerPlaying:vlc正在播放媒体
MediaPlayerPaused:vlc处于暂停状态
MediaPlayerStopped:vlc处于停⽌状态
MediaPlayerForward:vlc通过媒体快进(这永远不会被调⽤)
MediaPlayerBackward:vlc正在快退(这永远不会被调⽤)
MediaPlayerEncounteredError:vlc遇到错误,⽆法继续
MediaPlayerEndReached:vlc已到达当前播放列表的末尾
MediaPlayerTimeChanged:时间发⽣改变
MediaPlayerPositionChanged:进度发⽣改变
MediaPlayerSeekableChanged:流媒体是否可搜索的状态发⽣改变(true表⽰可搜索,false表⽰不可搜索)
MediaPlayerPausableChanged:媒体是否可暂停状态发⽣改变(true表⽰可暂停,false表⽰不可暂停)
MediaPlayerMediaChanged : 媒体发⽣改变
MediaPlayerTitleChanged: 标题发⽣改变(DVD/Blu-ray)
MediaPlayerChapterChanged :章节发⽣改变(DVD/Blu-ray)
MediaPlayerLengthChanged :(在vlc版本<2.2.0仅适⽤于Mozilla)长度已更改
MediaPlayerVout :视频输出的数量发⽣改变
MediaPlayerMuted :静⾳
MediaPlayerUnmuted :取消静⾳
MediaPlayerAudioVolume :⾳量发⽣改变
要查看全部⽀持的,请访问 并搜索EventType类型查看
视频加字幕
在我们上述封装的Player类中添加如下⽅法
def set_marquee(self):
def update_text(self, content):
创建调⽤代码
if"__main__"== __name__:
player = Player("--sub-source=marq")
player.play("hd.yinyuetai/uploads/videos/common/"
"22970150925A6BB75E20D95798D129EE.flv?sc\u003d17d6a907580e9892"
"\u0026br\u003d1103\u0026vid\u003d2400382\u0026aid\u003d32"
"\u0026area\u003dML\u0026vst\u003d0")
player.set_marquee()
player.update_text("%Y-%m-%d %H:%M:%S")
while True:
pass
video_set_marquee_string函数不仅⽀持直接传⼊字符串,还⽀持"%Y-%m-%d %H:%M:%S"这种时间格式,运⾏上述代码后,会在屏幕下⽅显⽰当前时间,且每⼀秒刷新⼀次。
关于⽂本的⼀些属性设置
VideoMarqueeOption.Color :⽂本颜⾊,值为16进制数
VideoMarqueeOption.Enable:是否开启⽂本显⽰,1表⽰开启
VideoMarqueeOption.Opacity:⽂本透明度,0 透明,255 完全不透明
VideoMarqueeOption.Position:⽂本显⽰的位置
VideoMarqueeOption.Refresh:字符串刷新的间隔(毫秒)对时间格式字串刷新有⽤
VideoMarqueeOption.Size:⽂字⼤⼩,单位像素
VideoMarqueeOption.Text:要显⽰的⽂本内容
VideoMarqueeOption.Timeout:⽂本停留时间。0表⽰永远停留(毫秒值)
VideoMarqueeOption.marquee_X:设置显⽰⽂本的x坐标值
VideoMarqueeOption.marquee_Y:设置显⽰⽂本的y坐标值
上⾯的⽰例仅仅显⽰了⼀个固定的时间字符串,下⾯我们看⼀下如何显⽰连续的字幕

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。