zoukankan      html  css  js  c++  java
  • pyqt+vlc 播放rtsp/rtmp地址并嵌入任意frame中

    先上效果图:

     代码:

    import os, platform
    
    # 设置VLC库路径,需在import vlc之前
    os.environ['PYTHON_VLC_MODULE_PATH'] = "./VLC"
    
    import vlc
    
    
    class Player:
        '''
            args:设置 options
        '''
    
        def __init__(self, *args):
            if args:
                instance = vlc.Instance(*args)
                self.media = instance.media_player_new()
            else:
                self.media = vlc.MediaPlayer()
    
        # 设置待播放的url地址或本地文件路径,每次调用都会重新加载资源
        def set_uri(self, uri):
            self.media.set_mrl(uri)
    
        # 播放 成功返回0,失败返回-1
        def play(self, path=None):
            if path:
                self.set_uri(path)
                return self.media.play()
            else:
                return self.media.play()
    
        # 暂停
        def pause(self):
            self.media.pause()
    
        # 恢复
        def resume(self):
            self.media.set_pause(0)
    
        # 停止
        def stop(self):
            self.media.stop()
    
        # 释放资源
        def release(self):
            return self.media.release()
    
        # 是否正在播放
        def is_playing(self):
            return self.media.is_playing()
    
        # 已播放时间,返回毫秒值
        def get_time(self):
            return self.media.get_time()
    
        # 拖动指定的毫秒值处播放。成功返回0,失败返回-1 (需要注意,只有当前多媒体格式或流媒体协议支持才会生效)
        def set_time(self, ms):
            return self.media.get_time()
    
        # 音视频总长度,返回毫秒值
        def get_length(self):
            return self.media.get_length()
    
        # 获取当前音量(0~100)
        def get_volume(self):
            return self.media.audio_get_volume()
    
        # 设置音量(0~100)
        def set_volume(self, volume):
            return self.media.audio_set_volume(volume)
    
        # 返回当前状态:正在播放;暂停中;其他
        def get_state(self):
            state = self.media.get_state()
            if state == vlc.State.Playing:
                return 1
            elif state == vlc.State.Paused:
                return 0
            else:
                return -1
    
        # 当前播放进度情况。返回0.0~1.0之间的浮点数
        def get_position(self):
            return self.media.get_position()
    
        # 拖动当前进度,传入0.0~1.0之间的浮点数(需要注意,只有当前多媒体格式或流媒体协议支持才会生效)
        def set_position(self, float_val):
            return self.media.set_position(float_val)
    
        # 获取当前文件播放速率
        def get_rate(self):
            return self.media.get_rate()
    
        # 设置播放速率(如:1.2,表示加速1.2倍播放)
        def set_rate(self, rate):
            return self.media.set_rate(rate)
    
        # 设置宽高比率(如"16:9","4:3")
        def set_ratio(self, ratio):
            self.media.video_set_scale(0)  # 必须设置为0,否则无法修改屏幕宽高
            self.media.video_set_aspect_ratio(ratio)
    
        # 设置窗口句柄
        def set_window(self, wm_id):
            if platform.system() == 'Windows':
                self.media.set_hwnd(wm_id)
            else:
                self.media.set_xwindow(wm_id)
    
        # 注册监听器
        def add_callback(self, event_type, callback):
            self.media.event_manager().event_attach(event_type, callback)
    
        # 移除监听器
        def remove_callback(self, event_type, callback):
            self.media.event_manager().event_detach(event_type, callback)
    
    
    
    import tkinter as tk
    
    
    class App(tk.Tk):
        def __init__(self):
            super().__init__()
            self.player = Player()#"--audio-visual=visual","--effect-list=scope", "--effect-fft-window=flattop"
            self.title("流媒体播放器")
            # self.create_video_view()
            # self.create_control_view()
            self._canvas = tk.Canvas(self, bg="black")
            self._canvas.pack()
            self.player.set_window(self._canvas.winfo_id())
            self.player.play("rtmp://192.168.1.3:1935/rtmp/test")
    
        def create_video_view(self):
            self._canvas = tk.Canvas(self, bg="black")
            self._canvas.pack()
            self.player.set_window(self._canvas.winfo_id())
    
        # def create_control_view(self):
        #     frame = tk.Frame(self)
        #     tk.Button(frame, text="播放", command=lambda: self.click(0)).pack(side=tk.LEFT, padx=5)
        #     tk.Button(frame, text="暂停", command=lambda: self.click(1)).pack(side=tk.LEFT)
        #     tk.Button(frame, text="停止", command=lambda: self.click(2)).pack(side=tk.LEFT, padx=5)
        #     frame.pack()
    
        # def click(self, action):
        #     if action == 0:
        #         if self.player.get_state() == 0:
        #             self.player.resume()
        #         elif self.player.get_state() == 1:
        #             pass  # 播放新资源
        #         else:
        #             self.player.play("rtmp://192.168.1.3:1935/rtmp/test")
        #     elif action == 1:
        #         if self.player.get_state() == 1:
        #             self.player.pause()
        #     else:
        #         self.player.stop()
    
    
    import sys,win32gui
    from PyQt5.QtWidgets import *
    from PyQt5.QtGui import QPainter, QColor, QFont
    from PyQt5 import QtCore
    
    class Ui_Form(object):
        def setupUi(self, Form):
            Form.setObjectName("Form")
            Form.resize(776, 519)
            self.frame = QFrame(Form)
            self.frame.setGeometry(QtCore.QRect(50, 30, 200, 200))
            self.frame.setStyleSheet("background-color: rgb(85, 255, 255);")
            self.frame.setFrameShape(QFrame.StyledPanel)
            self.frame.setFrameShadow(QFrame.Raised)
            self.frame.setObjectName("frame")
            self.frame_2 = QFrame(Form)
            self.frame_2.setGeometry(QtCore.QRect(60, 280, 221, 141))
            self.frame_2.setStyleSheet("background-color: rgb(85, 170, 255);")
            self.frame_2.setFrameShape(QFrame.StyledPanel)
            self.frame_2.setFrameShadow(QFrame.Raised)
            self.frame_2.setObjectName("frame_2")
            self.frame_3 = QFrame(Form)
            self.frame_3.setGeometry(QtCore.QRect(410, 310, 241, 151))
            self.frame_3.setStyleSheet("background-color: rgb(255, 170, 255);")
            self.frame_3.setFrameShape(QFrame.StyledPanel)
            self.frame_3.setFrameShadow(QFrame.Raised)
            self.frame_3.setObjectName("frame_3")
    
            self.pushButton_area_show = QPushButton(Form)
            self.pushButton_area_show.setText("123")
            self.pushButton_area_show.clicked.connect(self.test)
    
            self.pushButton_area_show = QPushButton(Form)
            self.pushButton_area_show.setText("456")
            self.pushButton_area_show.setGeometry(QtCore.QRect(70, 270, 100, 100))
            self.pushButton_area_show.clicked.connect(self.test2)
    
            self.player = Player("--network-caching=0")#"--audio-visual=visual","--effect-list=scope", "--effect-fft-window=flattop"
            self.player.set_window(self.frame.winId())
            # self.player.play("rtmp://192.168.1.3:1935/rtmp/test")
            # self.player.play("rtmp://192.168.1.5:1935/live/test3")
            # self.player.play("rtsp://admin:castle12345@192.168.1.120:554/LiveMedia/ch1/Media1")
            self.player.play("rtsp://admin:hik12345@192.168.1.64:554/h264/ch01/sub/av_stream")
    
            # calc_hwnd = win32gui.FindWindow(None, u"rtmp://192.168.1.3:1935/rtmp/test")
            # print(calc_hwnd)
            # _h = self.frame.winId()
            # print(_h)
            # win32gui.SetParent(calc_hwnd, _h)
    
            self.retranslateUi(Form)
            QtCore.QMetaObject.connectSlotsByName(Form)
    
        def retranslateUi(self, Form):
            _translate = QtCore.QCoreApplication.translate
            Form.setWindowTitle(_translate("Form", "Form"))
    
        def test(self):
            print(1)
            self.player.stop()
    
        def test2(self):
            print(2)
            self.player.play("rtmp://192.168.1.3:1935/rtmp/test")
            
            
    class App2(QWidget,Ui_Form):
        def __init__(self):
            super(App2,self).__init__()
            self.setupUi(self)
    
    if "__main__" == __name__:
        # app = App()
        # app.mainloop()
        app = QApplication(sys.argv)
        ex = App2()
        ex.show()
        sys.exit(app.exec_())
    

      代码说明:

    # 设置VLC库路径,需在import vlc之前
    os.environ['PYTHON_VLC_MODULE_PATH'] = "./VLC"

    这段代码是引入VLC,在项目当前目录下放入VLC

     VLC下载地址:https://www.videolan.org/

    可删除部分不必要文件减少项目体积

    import vlc

    安装python-vlc

    #这个要先安装python-vlc
    pip install python-vlc

    Player是封装的播放器类直接引用

    import tkinter as tk
    ......

    这段代码是给使用tkinter开发

    最后是

    PyQt5

    安装教程可参考:https://www.cnblogs.com/wohuiyijiu/p/12454130.html

    重要的三行代码(其余都是绘制控件,不做说明):

    self.player = Player("--network-caching=0")#"--audio-visual=visual","--effect-list=scope", "--effect-fft-window=flattop"
    self.player.set_window(self.frame.winId())
    # self.player.play("rtmp://192.168.1.3:1935/rtmp/test")
    # self.player.play("rtmp://192.168.1.5:1935/live/test3")
    # self.player.play("rtsp://admin:castle12345@192.168.1.120:554/LiveMedia/ch1/Media1")
    self.player.play("rtsp://admin:hik12345@192.168.1.64:554/h264/ch01/sub/av_stream")

    初始化播放器->设置句柄(设置在哪个frame播放,这里也不一定是frame,只要控件支持获取句柄应该都能播放)->传入播放地址播放

    代码没有整理(界面和操作分离),有很多注释部分也有参考价值,告辞!

  • 相关阅读:
    DFS初级算法题练习 POJ2488 POJ3009 POJ1088
    分支限界法基础练习笔记
    PuyoPuyo DFS算法练习
    回溯法基础练习笔记
    java基础:I/O流学习笔记
    synchronized锁的各种用法及注意事项
    20.04搭建ROS2
    西安 交建交通科技 招聘信息
    在.NET2.0中使用LINQ
    sqlite+VS2010+EF
  • 原文地址:https://www.cnblogs.com/wohuiyijiu/p/12840934.html
Copyright © 2011-2022 走看看