python_vlc 播放http流

时间:2023-03-09 22:30:48
python_vlc 播放http流

  由于工作需要,项目功能测试用到python调用vlc,用于播放一些直播流,各种尝试后终于可以了,其实蛮简单的,就是由于没有参考自己折腾挺浪费时间的,所以把结果贴出来给需要用到的人。

准备工作:  

    1、首先python环境肯定得有;

    2、其次需要用到vlc的python-blindings,其实就是一个vlc.py文件,里边封装了很多常用api供调用(如果只要用系统调用的方式,这一步可以省略);

    3、需要下载一个和python位数相同的vlc播放器,32位或64位,要保证一致,否则又要各种折腾了;

进入正题

  如果要播放的流是很标准的,就是不包含类似“&”这种特殊字符的url,举个例子:浙江卫视[高清]:http://14.29.60.40/live/5/30/847a4e1e97584d39a961f5604e90c1c4.m3u8?type=web.cloudplay;像这种url你可以直接用system()系统调用的方式直接启动vlc.exe,并附加参数url便可播放;如果目的达到了那不用往下看了,否则,继续。

  很不幸我自己项目中要用的url是包含“&”的,这种url通过系统调用的方式将发生截断,效果就是“&”后面的东西被当做非法字段扔掉了,这样一来要测试的url肯定不对,经过各种尝试最终放弃system这种简单方式;选择用python-blindings,下载vlc.py之后各种尝试最终达到播放url的目的,这种情况下url是当做自定义函数的参数传进去的,可以避免被截断;以下贴出两种解决方案,区别是一个带字幕一个不带字幕;

import sys
import http.client
import time
from vlc import VideoMarqueeOption, Position, EventType,Instance class RTSP_Client():
  pass class VLC_Player(): def __init__(self, url):
self.url = url def start_with_marquee(self,timeout=60):
     u"""这种方案是可以带字幕的,根据vlc自带测试源码改写
     """ movie = self.url
# Need --sub-source=marq in order to use marquee below
print(sys.argv[:])
instance = Instance(["--sub-source=marq"] + sys.argv[1:])
try:
media = instance.media_new(movie)
except (AttributeError, NameError) as e:
sys.exit(1)
player = instance.media_player_new()
player.set_media(media)
player.play() # Some marquee examples. Marquee requires '--sub-source marq' in the
# Instance() call above, see <http://www.videolan.org/doc/play-howto/en/ch04.html>
player.video_set_marquee_int(VideoMarqueeOption.Enable, 1)
player.video_set_marquee_int(VideoMarqueeOption.Size, 24) # pixels
player.video_set_marquee_int(VideoMarqueeOption.Position, Position.Bottom)
player.video_set_marquee_int(VideoMarqueeOption.Timeout, 0) # millisec, 0==forever
player.video_set_marquee_int(VideoMarqueeOption.Refresh, 1000) # millisec (or sec?)
##t = '$L / $D or $P at $T'
t = '%Y-%m-%d %H:%M:%S'
player.video_set_marquee_string(VideoMarqueeOption.Text, str_to_bytes(t)) # Some event manager examples. Note, the callback can be any Python
# callable and does not need to be decorated. Optionally, specify
# any number of positional and/or keyword arguments to be passed
# to the callback (in addition to the first one, an Event instance).
event_manager = player.event_manager()
event_manager.event_attach(EventType.MediaPlayerEndReached, end_callback)
event_manager.event_attach(EventType.MediaPlayerPositionChanged, pos_callback, player)
time.sleep(timeout) def start(self,timeout=60):
     u"""这种是最简方案,用来测试播放足够了
     """ instance = Instance()
player = instance.media_player_new()
Media = instance.media_new(self.url)
Media.get_mrl()
player.set_media(Media)
player.play()
     #如果是看直播这里直接写while True 即可
time.sleep(timeout) def str_to_bytes(s):
"""Translate string or bytes to bytes.
"""
if isinstance(s, str):
return bytes(s, encoding="UTF-8")
else:
return s def end_callback(event):
print('End of media stream (event %s)' % event.type)
sys.exit(0) echo_position = False
def pos_callback(event, player):
if echo_position:
sys.stdout.write('\r%s to %.2f%% (%.2f%%)' % (event.type,
event.u.new_position * 100,
player.get_position() * 100))
sys.stdout.flush() if __name__ == "__main__":
   #测试url为浙江卫视直播流
url = "http://14.29.60.40/live/5/30/847a4e1e97584d39a961f5604e90c1c4.m3u8?type=web.cloudplay"
p = VLC_Player(url)
p.start(6000)

  这种播放用的是vlc的动态链接库而不是vlc.exe可执行文件,所以GUI是最简的,想要实现播放暂停之类的可以自己实现。

  下面放出效果图:

  python_vlc 播放http流

  在python通过vlc相关api下播放流视频已经达成目的了;后续会继续写一下觉得有必要分享的随笔包括但不限于linux驱动、python、go、流媒体等。