zoukankan      html  css  js  c++  java
  • 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('
    %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相关api下播放流视频已经达成目的了;后续会继续写一下觉得有必要分享的随笔包括但不限于linux驱动、python、go、流媒体等。

  • 相关阅读:
    HDU 3081 Marriage Match II
    HDU 4292 Food
    HDU 4322 Candy
    HDU 4183 Pahom on Water
    POJ 1966 Cable TV Network
    HDU 3605 Escape
    HDU 3338 Kakuro Extension
    HDU 3572 Task Schedule
    HDU 3998 Sequence
    Burning Midnight Oil
  • 原文地址:https://www.cnblogs.com/zhangyi-studio/p/9164453.html
Copyright © 2011-2022 走看看