由於工作需要,項目功能測試用到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相關api下播放流視頻已經達成目的了;后續會繼續寫一下覺得有必要分享的隨筆包括但不限於linux驅動、python、go、流媒體等。
