利用pyside/pyQt实现视频播放器,并利用pyinstaller 打包发布

第一次用pyqt/pyside,遇到了很多问题。所有遇到的问题都是在视频发布这块遇到的,但最终还是成功了,在这里把遇到的问题总结一下。

读取视频中的帧,逐帧显示,显示的格式必须是Qimage,但是用cv2读取的帧格式是numpy array,必须把它转换成为Qimage,于是尝试了:

  1. 利用pyqtgraph: 

将numpy类型的frame通过pyqtgraph 转换为Qimage,随后通过setPixmap显示,程序在IDLE执行正确,但是在发布的时候,遇到了很多恶心的问题,由于是帮别人做,本人没有那么多时间去解决这个问题,于是采用了第二种办法。

                frame,stat=pyqtgraph.makeARGB(frame, lut=None, levels=None, scale=None, useRGBA=True)
                frame=pyqtgraph.makeQImage(frame, alpha=None, copy=True ,transpose=False)#
                
                frame=QPixmap.fromImage(frame)
                self.pictureLabel.setPixmap(frame)
2.利用PIL将图像保存,随后再通过Qimage读取,直接转换为Qimage格式:

但是用遇到了新的问题,通过cv2.VideoCapture("001.avi")读取的视频文件,通过下面的转化,颜色通道居然乱了,本人尝试过利用numpy.roll()将通道翻转,但效果不理想,而且减慢了速度,实在无奈~,于是有尝试了第三种办法

                frame=Image.fromarray(frame)
                frame.save('2.jpg') 
                self.image.load("2.jpg")
                self.pictureLabel.setPixmap(QPixmap.fromImage(self.image))
3.利用cv2.cv.fromarray()转换读取的numpy帧,然后保存再读取~

这次成功了,通过pyinstaller打包以后终于可以正常显示了。

                frame=cv2.cv.fromarray(frame)
                cv2.cv.SaveImage('2.jpg',frame)
                self.image.load("2.jpg")
                self.pictureLabel.setPixmap(QPixmap.fromImage(self.image))

以上三种方法在IDLE中执行没有错误,就是在打包发布的时候遇到了错误。而且在包含pyqtgraph库的时候,打包发布过程中遇到了很多困难,最终迫使我放弃了使用pyqtgraph.

在利用pyinstaller打包的时候,也遇到了一些问题,本文用的是pyinstaller 2.1 版本.

首先cd进入pyinstaller  , python setup.py install, 随后执行 python pyinstaller  -F -w yourpy.py (-F是打包为一个文件,-w是windows版,没有小黑窗)。

建议在每一次打包之前都执行一次 python setup.py install (因此会避免很多麻烦)

在视频窗口的背景上放了一张图片,设为背景,如果他没有显示,在C:\Python27\Lib\site-packages\PyQt4\plugins找到imageformats这个文件夹,和exe放在一块,就行了,好了贴上程序:

程序有三个按钮,每个按钮按下去之后,会连续播放两个视频,再按一下会暂停。最终界面如下:


# -*- coding: utf-8 -*-


from PySide.QtGui import * 
from PySide.QtCore import *
import PySide
import sys
import cv2
import time
from PIL import Image
import numpy

class MainWindow(PySide.QtGui.QWidget):
    
    
##    video_list=[\
##                r"d:\data\单井ch4扩散视频.mpeg",\
##                r"d:\data\单井h2s扩散视频.mpeg",\
##                r"d:\data\集气站ch4扩散视频.mpeg",\
##                r"d:\data\集气站h2s扩散视频.mpeg",\
##                r"d:\data\输气管线ch4扩散视频.mpeg",\
##                r"d:\data\输气管线h2s扩散视频.mpeg",\
##                ]
    
    def __init__(self,parent = None):
        PySide.QtGui.QWidget.__init__(self)
        self.setWindowTitle(u'天然气泄漏fluent数值模拟视频演示')
        self.status_1= 0 # 0: init 1:play vedio 2:camera
        self.status_2= 0
        self.status_3= 0
        
##        self.video_1_0=self.video_list[0]
##        self.video_1_1=self.video_list[1]
##        self.video_2_0=self.video_list[2]
##        self.video_2_1=self.video_list[3]
##        self.video_3_0=self.video_list[4]
##        self.video_3_1=self.video_list[5]

##        self.video_1_0=r"d:\data\单井ch4扩散视频.mpeg"
##        self.video_1_1=r"d:\data\单井h2s扩散视频.mpeg"
##        self.video_2_0=r"d:\data\集气站ch4扩散视频.mpeg"
##        self.video_2_1=r"d:\data\集气站h2s扩散视频.mpeg"
##        self.video_3_0=r"d:\data\输气管线ch4扩散视频.mpeg"
##        self.video_3_1=r"d:\data\输气管线h2s扩散视频.mpeg"
####
        self.video_1_0=r"d:\data\001.mpeg"
        self.video_1_1=r"d:\data\002.mpeg"
        self.video_2_0=r"d:\data\003.mpeg"
        self.video_2_1=r"d:\data\004.mpeg"
        self.video_3_0=r"d:\data\005.mpeg"
        self.video_3_1=r"d:\data\006.mpeg"




        
        self.next_video_flag=False
        
        
        
        self.image = QImage()

        #set video file
        self.playCapture_1_0 = cv2.VideoCapture(self.video_1_0)
        self.playCapture_1_1 = cv2.VideoCapture(self.video_1_1)
        self.playCapture_2_0 = cv2.VideoCapture(self.video_2_0)
        self.playCapture_2_1 = cv2.VideoCapture(self.video_2_1)
        self.playCapture_3_0 = cv2.VideoCapture(self.video_3_0)
        self.playCapture_3_1 = cv2.VideoCapture(self.video_3_1)

        self.playButton_1 = QPushButton(u"输送管线")
        self.playButton_2 = QPushButton(u"单井")
        self.playButton_3 = QPushButton(u"集气站")
       
        vbox = QVBoxLayout() #vertical layout
        vbox.addWidget(self.playButton_1)
        vbox.addWidget(self.playButton_2)
        vbox.addWidget(self.playButton_3)


        self.pictureLabel = QLabel("picture")
        
        hbox=QHBoxLayout()
        hbox.addStretch(0)
        hbox.addLayout(vbox)
        hbox.addWidget(self.pictureLabel)
        self.setLayout(hbox)
        self.set_background()
           

        # set timeout
        self.timer_1 = Timer() # save video
        self.timer_2 = Timer() # save video
        self.timer_3 = Timer() # save video
        self.playTimer_1 = Timer("updatePlay()")
        self.playTimer_2 = Timer("updatePlay()")
        self.playTimer_3 = Timer("updatePlay()")
        
        self.connect(self.playTimer_1, SIGNAL("updatePlay()"), self.PlayVideo_1)
        self.connect(self.playTimer_2, SIGNAL("updatePlay()"), self.PlayVideo_2)
        self.connect(self.playTimer_3, SIGNAL("updatePlay()"), self.PlayVideo_3)
        
        #self.connect(exitButton, SIGNAL("clicked()"), app, SLOT("quit()"))
        self.connect(self.playButton_1, SIGNAL("clicked()"), self.VideoPlayPause_1)
        self.connect(self.playButton_2, SIGNAL("clicked()"), self.VideoPlayPause_2)
        self.connect(self.playButton_3, SIGNAL("clicked()"), self.VideoPlayPause_3)
        
    def set_background(self):
        self.image.load(r"d:/data/background.jpg")
        self.pictureLabel.setPixmap(QPixmap.fromImage(self.image))   

    def PlayVideo_1(self):
        if self.next_video_flag==False and self.status_1==1 and self.status_2!=1 and self.status_3!=1 :
            stat,frame = self.playCapture_1_0.read()
            
            if stat==False:
                self.next_video_flag=True
            else :
                #print 'frame'
                frame=cv2.cv.fromarray(frame)
                cv2.cv.SaveImage('2.jpg',frame)
                self.image.load("2.jpg")
                self.pictureLabel.setPixmap(QPixmap.fromImage(self.image))

        if self.next_video_flag==True and self.status_1==1 and self.status_2!=1 and self.status_3!=1 :
            stat,frame = self.playCapture_1_1.read()
            if stat==False:
                self.next_video_flag=False
                self.playTimer_1.stop()
                self.timer_1.stop()
                self.set_background()
                self.status_1, playStr=(1,u"输送管线")
                self.playButton_1.setText(playStr)
                self.playCapture_1_0 = cv2.VideoCapture(self.video_1_0)
                self.status_1=0

            else :
                frame=cv2.cv.fromarray(frame)
                cv2.cv.SaveImage('2.jpg',frame)
                self.image.load("2.jpg")
                self.pictureLabel.setPixmap(QPixmap.fromImage(self.image))
           

    def PlayVideo_2(self):
        if self.next_video_flag==False and self.status_2==1 and self.status_1!=1 and self.status_3!=1 :
            stat,frame = self.playCapture_2_0.read()
            if stat==False:
                self.next_video_flag=True

            else :
                frame=cv2.cv.fromarray(frame)
                cv2.cv.SaveImage('2.jpg',frame)
                self.image.load("2.jpg")
                self.pictureLabel.setPixmap(QPixmap.fromImage(self.image))

              

        if self.next_video_flag==True and self.status_2==1 and self.status_1!=1 and self.status_3!=1 :
            stat,frame = self.playCapture_2_1.read()
            if stat==False:
                self.next_video_flag=False
                self.playTimer_2.stop()
                self.timer_2.stop()
                self.set_background()
                self.status_2, playStr=(1,u"单井")
                self.playButton_2.setText(playStr)
                self.playCapture_2_0 = cv2.VideoCapture(self.video_2_0)
                self.status_2=0

            else :
                frame=cv2.cv.fromarray(frame)
                cv2.cv.SaveImage('2.jpg',frame)
                self.image.load("2.jpg")
                self.pictureLabel.setPixmap(QPixmap.fromImage(self.image))

                   
    def PlayVideo_3(self):
        if self.next_video_flag==False and self.status_3==1 and self.status_2!=1 and self.status_1!=1 :
            stat,frame = self.playCapture_3_0.read()
            if stat==False:
                self.next_video_flag=True

            else :
                frame=cv2.cv.fromarray(frame)
                cv2.cv.SaveImage('2.jpg',frame)
                self.image.load("2.jpg")
                self.pictureLabel.setPixmap(QPixmap.fromImage(self.image))

              

        if self.next_video_flag==True and self.status_3==1 and self.status_2!=1 and self.status_1!=1 :
            stat,frame = self.playCapture_3_1.read()
            if stat==False:
                self.next_video_flag=False
                self.playTimer_3.stop()
                self.timer_3.stop()
                self.set_background()
                self.status_3, playStr=(1,u"集气站")
                self.playButton_3.setText(playStr)
                self.playCapture_3_0 = cv2.VideoCapture(self.video_3_0)
                self.status_3=0

            else :
                frame=cv2.cv.fromarray(frame)
                cv2.cv.SaveImage('2.jpg',frame)
                self.image.load("2.jpg")
                self.pictureLabel.setPixmap(QPixmap.fromImage(self.image))

          
        
    def VideoPlayPause_1(self):
        self.playCapture_2_0 = cv2.VideoCapture(self.video_2_0)
        self.playCapture_2_1 = cv2.VideoCapture(self.video_2_1)
        self.playCapture_3_0 = cv2.VideoCapture(self.video_3_0)
        self.playCapture_3_1 = cv2.VideoCapture(self.video_3_1)
        self.status_1, playStr = ((1,u'暂停'),
                                            (0,u"输送管线"),
                                            (1,u'暂停'))[self.status_1]

        self.playButton_1.setText(playStr)
        
        if self.status_1 is 1: #play video
            self.timer_1.stop()
            self.playTimer_1.start()
        else:
            self.playTimer_1.stop()


    def VideoPlayPause_2(self):
        self.playCapture_1_0 = cv2.VideoCapture(self.video_1_0)
        self.playCapture_1_1 = cv2.VideoCapture(self.video_1_1)
        self.playCapture_3_0 = cv2.VideoCapture(self.video_3_0)
        self.playCapture_3_1 = cv2.VideoCapture(self.video_3_1)
        self.status_2, playStr = ((1,u'暂停'),
                                            (0,u"单井"),
                                            (1,u'暂停'))[self.status_2]

        self.playButton_2.setText(playStr)
        
        if self.status_2 is 1: #play video
            self.timer_2.stop()
            self.playTimer_2.start()
        else:
            self.playTimer_2.stop()

            
    def VideoPlayPause_3(self):
        
        self.playCapture_1_0 = cv2.VideoCapture(self.video_1_0)
        self.playCapture_1_1 = cv2.VideoCapture(self.video_1_1)
        self.playCapture_2_0 = cv2.VideoCapture(self.video_2_0)
        self.playCapture_2_1 = cv2.VideoCapture(self.video_2_1)

        self.status_3, playStr= ((1,u'暂停'),
                               (0,u"集气站"),
                               (1,u'暂停'))[self.status_3]

        self.playButton_3.setText(playStr)
        
        if self.status_3 is 1: #play video
            self.timer_3.stop()
            self.playTimer_3.start()
        else:
            self.playTimer_3.stop()


class Timer(QThread):
    def __init__(self, signal = "updateTime()", parent = None):
        super(Timer, self).__init__(parent)
        self.stoped = False
        self.signal = signal
        self.mutex = QMutex()
        
    def run(self):
        with QMutexLocker(self.mutex):
            self.stoped = False
        while True:
            if self.stoped:
                return
            
            self.emit(SIGNAL(self.signal))
            time.sleep(0.04)
            
    def stop(self):
        with QMutexLocker(self.mutex):
            self.stoped = True
            
    def isStoped(self):
        with QMutexLocker(self.mutex):
            return self.stoped

if __name__ == "__main__":
    import PySide
    app = QApplication(sys.argv)
    main = MainWindow()
    main.show()
    sys.exit(app.exec_())




评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值