如何在 pyqt5 中为 windows 创建视频播放器以使用 python 代码播放 mp4?

how to create video player in pyqt5 for windows to play mp4 using python code?

我试图在 windows 10 os 中为 mp4 创建视频播放器。它总是显示错误。我尝试了多种方法。但总是失败

  1. 我试过这个位置的代码https://pythonprogramminglanguage.com/pyqt5-video-widget/
    QMediaPlayer 错误:

  1. 我试过 python-vlc。只有当我已经安装了 vlc 播放器时它才能工作。如果我卸载了 vlc 播放器,它就无法正常工作

vlc 错误:

File "<module1>", line 7, in <module>
  File "D:\Portable_Python\App\Python\lib\site-packages\vlc.py", line 210, in <module>
    dll, plugin_path  = find_lib()
  File "D:\Portable_Python\App\Python\lib\site-packages\vlc.py", line 173, in find_lib
    dll = ctypes.CDLL(p)
  File "D:\Portable_Python\App\Python\lib\ctypes\__init__.py", line 364, in __init__
    self._handle = _dlopen(self._name, mode)
OSError: [WinError 193] %1 is not a valid Win32 application
>>> 
  1. tkvideoplayer

我试过这个位置的代码https://github.com/PaulleDemon/tkVideoPlayer/blob/master/examples/sample_player.py

它工作正常。但我无法将它嵌入到 pyqt5 window.

我在此位置附加了示例视频文件 https://drive.google.com/file/d/1AaTzf3LBUMCztO8hYpF9muPUImVDX1s_/view?usp=sharing

请在任何一个模块中给我一个最佳解决方案。

我在下面添加了简单的代码。这是播放 .avi 文件而不是播放 .mp4 文件

from PyQt5.QtMultimediaWidgets import QVideoWidget
from PyQt5.QtCore import QUrl
from PyQt5.QtWidgets import QApplication, QPushButton
from PyQt5.QtMultimedia import QMediaContent, QMediaPlayer
import sys

class VideoPlayer:
    def __init__(self):
        self.video = QVideoWidget()
        self.video.resize(300, 300)
        self.video.move(0, 0)
        self.player = QMediaPlayer()
        self.player.setVideoOutput(self.video)
        self.player.setMedia(QMediaContent(QUrl.fromLocalFile("D:/2.mp4")))

    def callback(self):
        self.player.setPosition(0) # to start at the beginning of the video every time
        self.video.show()
        self.player.play()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    v = VideoPlayer()
    b = QPushButton('start')
    b.clicked.connect(v.callback)
    b.show()
    sys.exit(app.exec_())

因为找不到直接播放器。我使用 cv 模块和 ffpyplayer 与 pyqt5 集成。暂时解决了我的问题。代码如下。

from ffpyplayer.player import MediaPlayer

from PyQt5 import QtGui,QtCore
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import sys
import threading
import time
import cv2
from PIL import Image
import numpy
import os

class VideoPlayer:
    def __init__(self, filename,volume = 1.0):
        if not os.path.exists(filename):raise FileNotFound(filename)
        self.close = False
        self.state = None
        self.frame = None
        self.l=None
        self.filename = filename
        self.skip_interval=5

        self.player = MediaPlayer(filename, ff_opts={'sync': 'audio', 'paused': False, 'volume': volume, 't': 1e7+1, 'ss': 0})
        time.sleep(1)
        self.duration=self.player.get_metadata()['duration']
        handler_thread = threading.Thread(target=self.play, args=(), daemon=True)
        handler_thread.start()

    def play(self):
        while True:
            frame, self.val = self.player.get_frame()
            if self.val == 'eof':self.close=True
            if self.close == True:
                self.player.toggle_pause()
                self.player.close_player()
                time.sleep(2)
                break

            if isinstance(self.val, str) or self.val == 0.0:waitkey = 32
            else:waitkey = int(self.val * 100)
            pressed_key = cv2.waitKey(waitkey) & 0xFF

            if frame is None:continue

            image, pts = frame
            self.frame = (image, self.val)
            x, y = image.get_size()
            data = image.to_bytearray()[0]
            image =  Image.frombytes("RGB", (x, y), bytes(data))
            image = cv2.cvtColor(numpy.array(image), cv2.COLOR_RGB2BGR)
            self.frame=frame

            if self.l!=None:
                h, w, ch = image.shape
                Image2 = QImage(image.data, w, h, ch * w, QImage.Format_RGB888)
                self.pixmap=QPixmap.fromImage(Image2)
                self.l.setPixmap(self.pixmap)
                self.l.setFixedWidth(self.l.pixmap().width())
                self.l.setFixedHeight(self.l.pixmap().height())
                self.l.parent().update()
            del image


    def seek_p(self):
            if int(self.player.get_pts()) + self.skip_interval < int(self.duration):
                self.player.seek(self.skip_interval, relative=True, accurate=False)
    def seek_m(self):
        if int(self.player.get_pts()) - self.skip_interval > 0:
            self.player.seek(-self.skip_interval, relative=True, accurate=False)



class ed(QWidget):
    def __init__(self,parent=None):
        super().__init__()
        vl=QVBoxLayout()
        self.setLayout(vl)
        pb=QPushButton('play');vl.addWidget(pb);pb.clicked.connect(self.play)
        pb=QPushButton('stop');vl.addWidget(pb);pb.clicked.connect(self.close)
        pb=QPushButton('pause');vl.addWidget(pb);pb.clicked.connect(self.pause)
        pb=QPushButton('seek+');vl.addWidget(pb);pb.clicked.connect(self.seek_p)
        pb=QPushButton('seek-');vl.addWidget(pb);pb.clicked.connect(self.seek_m)
        pb=QPushButton('mute');vl.addWidget(pb);pb.clicked.connect(self.mute)
        pb=QPushButton('vol+');vl.addWidget(pb);pb.clicked.connect(self.vol_p)
        pb=QPushButton('vol-');vl.addWidget(pb);pb.clicked.connect(self.vol_m)
        self.l=QLabel();vl.addWidget(self.l)
    def play2(self):
        self.player=VideoPlayer('D:/2.mp4')
        self.player.l=self.l

    def play(self):
        self.t1=threading.Thread(target=self.play2)
        self.t1.start()

    def pause(self):self.player.player.toggle_pause()
    def seek_p(self):self.player.seek_p()
    def seek_m(self):self.player.seek_m()
    def mute(self):
        try:
            if (self.player.player.get_volume()>0.0):self.player.player.set_volume(0.0)
            else:self.player.player.set_volume(1.0)
        except:pass
    def vol_p(self):
        self.player.player.set_volume(self.player.player.get_volume() + 0.1)
        print(self.player.player.get_volume())
    def vol_m(self):
        self.player.player.set_volume(self.player.player.get_volume() - 0.1)
        print(self.player.player.get_volume())

    def close(self):
        try:
            self.player.close=True
            time.sleep(1)
        except:pass

    def closeEvent(self, event):
        try:
            self.player.close=True
            time.sleep(1)
        except:pass



if __name__ == '__main__':

    app = QApplication(sys.argv)
    window=ed()
    window.showMaximized()
    sys.exit(app.exec_())