本文主要是介绍mp4 显示 按帧 pyqt,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
目录
pyqt安装:
运行报错 xcb:
xcb解决方法:
随窗口改变,拖拽打开mp4:
n加载下一个视频,l加载上一个视频:
固定大小,不能随窗口改变:
pyqt安装:
ubuntu直接安装pip install pyqt5,报错:
File "/tmp/tmpqq_xs870", line 126, in prepare_metadata_for_build_wheel hook = backend.prepare_metadata_for_build_wheel AttributeError: module 'sipbuild.api' has no attribute 'prepare_metadata_for_build_wheel'
解决方法:
pip install pyqt5==5.15.2
运行报错 xcb:
qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "/home/lixiang/.local/lib/python3.8/site-packages/cv2/qt/plugins" even though it was found. This application failed to start because no Qt platform plugin could be initialized. Reinstalling the
xcb解决方法:
【解决】qt.qpa.plugin: Could not load the Qt platform plugin “xcb“-CSDN博客
import os
from PyQt5.QtCore import QLibraryInfo
# from PySide2.QtCore import QLibraryInfo
os.environ["QT_QPA_PLATFORM_PLUGIN_PATH"] = QLibraryInfo.location(QLibraryInfo.PluginsPath
)
随窗口改变,拖拽打开mp4:
import sys
import cv2
from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel, QVBoxLayout, QWidget, QGraphicsView, QGraphicsScene, QGraphicsPixmapItem
from PyQt5.QtGui import QPixmap, QImage
from PyQt5.QtCore import Qt, QTimer
from collections import deque
from pynput import keyboardclass VideoPlayer(QMainWindow):def __init__(self):super().__init__()# 设置窗口self.setWindowTitle('Drag and Drop MP4 Player')self.setGeometry(100, 100, 800, 600)self.setAcceptDrops(True)# 主窗口部件和布局self.widget = QWidget(self)self.layout = QVBoxLayout(self.widget)self.setCentralWidget(self.widget)# 创建QGraphicsView和QGraphicsSceneself.graphics_view = QGraphicsView(self)self.layout.addWidget(self.graphics_view)# 设置 QGraphicsView 的样式表,以去除边框和滚动条self.graphics_view.setStyleSheet("border: none; background: transparent;")self.graphics_view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)self.graphics_view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)self.scene = QGraphicsScene(self)self.graphics_view.setScene(self.scene)self.pixmap_item = QGraphicsPixmapItem()self.scene.addItem(self.pixmap_item)# 创建显示文件路径的QLabelself.file_info_label = QLabel("Drag MP4 file here", self)self.file_info_label.setAlignment(Qt.AlignCenter)self.file_info_label.setStyleSheet("border-top: 1px solid black; border-left: none; border-right: none; border-bottom: none; padding: 10px;") # 只显示上边框self.layout.addWidget(self.file_info_label)# 视频相关变量self.cap = Noneself.frame_buffer = deque(maxlen=300)self.queue_index = -1self.load_new_frame = Trueself.frame_index = -1# 定时器self.timer = QTimer(self)self.timer.timeout.connect(self.display_frame)# 启动键盘监听listener = keyboard.Listener(on_press=self.on_press)listener.start()# 初始化视频文件(确保文件路径可用)self.file_path = Nonedef on_press(self, key):if key == keyboard.Key.right or key == keyboard.Key.space:if self.queue_index < len(self.frame_buffer) - 1:self.queue_index += 1else:self.load_new_frame = Trueelif key == keyboard.Key.left:if self.queue_index > 0:self.queue_index -= 1self.load_new_frame = Falseelif str(key) == "'q'":self.close()def dragEnterEvent(self, event):if event.mimeData().hasUrls():event.accept()else:event.ignore()def dropEvent(self, event):for url in event.mimeData().urls():file_path = url.toLocalFile()if file_path.lower().endswith(".mp4"):self.file_path = file_pathself.file_info_label.setText(f"Loading: {file_path}")self.load_video(file_path)self.setWindowTitle(file_path)def load_video(self, file_path):if self.cap:self.cap.release()self.cap = cv2.VideoCapture(file_path)self.frame_buffer.clear()self.queue_index = -1self.frame_index = -1self.load_new_frame = True# 开始播放视频self.timer.start(30)def display_frame(self):if self.load_new_frame and self.cap:ret, frame = self.cap.read()if not ret:self.load_new_frame = Falsecv2.putText(self.frame_buffer[self.queue_index], str(self.frame_index) + ":end", (20, 70), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 255), 2)else:self.frame_index += 1cv2.putText(frame, str(self.frame_index), (20, 70), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 255), 2)self.frame_buffer.append(frame)self.queue_index = len(self.frame_buffer) - 1self.load_new_frame = Falseif len(self.frame_buffer) > 0:imshow = self.frame_buffer[self.queue_index]self.show_frame(imshow)def show_frame(self, frame):rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)h, w, ch = rgb_frame.shapebytes_per_line = ch * wq_img = QImage(rgb_frame.data, w, h, bytes_per_line, QImage.Format_RGB888)pixmap = QPixmap.fromImage(q_img)self.pixmap_item.setPixmap(pixmap)# 调整视图以适应图像self.fit_image_to_view()def fit_image_to_view(self):if self.pixmap_item.pixmap().isNull():returnself.graphics_view.resetTransform()# 调整视图以适应图像self.graphics_view.fitInView(self.pixmap_item, Qt.KeepAspectRatio)def resizeEvent(self, event):super().resizeEvent(event)self.fit_image_to_view() # 窗口调整大小时调整图片的缩放比例def closeEvent(self, event):if self.cap:self.cap.release()self.timer.stop()event.accept()if __name__ == '__main__':app = QApplication(sys.argv)player = VideoPlayer()player.show() # 显示窗口,使用默认大小,不最大化sys.exit(app.exec_())
n加载下一个视频,l加载上一个视频:
import glob
import os.path
import sys
import cv2import os
from PyQt5.QtCore import QLibraryInfo
# from PySide2.QtCore import QLibraryInfo
os.environ["QT_QPA_PLATFORM_PLUGIN_PATH"] = QLibraryInfo.location(QLibraryInfo.PluginsPath
)from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel, QVBoxLayout, QWidget, QGraphicsView, QGraphicsScene, QGraphicsPixmapItem
from PyQt5.QtGui import QPixmap, QImage
from PyQt5.QtCore import Qt, QTimer
from collections import deque
from pynput import keyboardfrom natsort import natsorted
class VideoPlayer(QMainWindow):def __init__(self):super().__init__()# 设置窗口self.setWindowTitle('Drag and Drop MP4 Player')self.setGeometry(100, 100, 800, 600)self.setAcceptDrops(True)# 主窗口部件和布局self.widget = QWidget(self)self.layout = QVBoxLayout(self.widget)self.setCentralWidget(self.widget)# 创建QGraphicsView和QGraphicsSceneself.graphics_view = QGraphicsView(self)self.layout.addWidget(self.graphics_view)# 设置 QGraphicsView 的样式表,以去除边框和滚动条self.graphics_view.setStyleSheet("border: none; background: transparent;")self.graphics_view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)self.graphics_view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)self.scene = QGraphicsScene(self)self.graphics_view.setScene(self.scene)self.pixmap_item = QGraphicsPixmapItem()self.scene.addItem(self.pixmap_item)# 创建显示文件路径的QLabelself.file_info_label = QLabel("Drag MP4 file here", self)self.file_info_label.setAlignment(Qt.AlignCenter)self.file_info_label.setStyleSheet("border-top: 1px solid black; border-left: none; border-right: none; border-bottom: none; padding: 10px;") # 只显示上边框self.layout.addWidget(self.file_info_label)# 视频相关变量self.cap = Noneself.frame_buffer = deque(maxlen=300)self.queue_index = -1self.load_new_frame = Trueself.frame_index = -1# 定时器self.timer = QTimer(self)self.timer.timeout.connect(self.display_frame)# 启动键盘监听listener = keyboard.Listener(on_press=self.on_press)listener.start()self.file_i=0self.file_list=[]# 初始化视频文件(确保文件路径可用)self.file_path = Noneself.timer_start=Falsedef on_press(self, key):if key == keyboard.Key.right or key == keyboard.Key.space:if self.queue_index < len(self.frame_buffer) - 1:self.queue_index += 1else:self.load_new_frame = Trueelif key == keyboard.Key.left:if self.queue_index > 0:self.queue_index -= 1self.load_new_frame = Falseelif str(key) == "'n'":print('-----', str(key))self.file_i += 1if self.file_i < len(self.file_list):self.load_video(self.file_list[self.file_i])elif str(key) == "'l'":print('-----', str(key))self.file_i -= 1if self.file_i>=0:self.load_video(self.file_list[self.file_i])elif str(key) == "'q'":self.close()def dragEnterEvent(self, event):if event.mimeData().hasUrls():event.accept()else:event.ignore()def dropEvent(self, event):for url in event.mimeData().urls():file_path = url.toLocalFile()if file_path.lower().endswith(".mp4"):self.file_path = file_pathself.load_video(file_path)self.file_list=glob.glob(f"{os.path.dirname(file_path)}/*.mp4")self.file_list=natsorted(self.file_list)self.file_i=0def load_video(self, file_path):if self.cap:self.cap.release()self.file_info_label.setText(f"{file_path}")self.cap = cv2.VideoCapture(file_path)self.frame_buffer.clear()self.queue_index = -1self.frame_index = -1self.load_new_frame = Trueif not self.timer_start:self.timer.start(30)self.timer_start=Truedef display_frame(self):if self.load_new_frame and self.cap:ret, frame = self.cap.read()if not ret:self.load_new_frame = False# self.end_count+=1# if self.end_count > 3:# self.load_video(self.file_path)cv2.putText(self.frame_buffer[self.queue_index], str(self.frame_index) + ":end", (20, 70), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 255), 2)else:print('----append------')self.frame_index += 1self.setWindowTitle(f"w:{frame.shape[1]},h:{frame.shape[0]}")cv2.putText(frame, str(self.frame_index), (20, 70), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 255), 2)self.frame_buffer.append(frame)self.queue_index = len(self.frame_buffer) - 1self.load_new_frame = Falseif len(self.frame_buffer) > 0:imshow = self.frame_buffer[self.queue_index]self.show_frame(imshow)def show_frame(self, frame):rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)h, w, ch = rgb_frame.shapebytes_per_line = ch * wq_img = QImage(rgb_frame.data, w, h, bytes_per_line, QImage.Format_RGB888)pixmap = QPixmap.fromImage(q_img)self.pixmap_item.setPixmap(pixmap)# 调整视图以适应图像self.fit_image_to_view()def fit_image_to_view(self):if self.pixmap_item.pixmap().isNull():returnself.graphics_view.resetTransform()# 调整视图以适应图像self.graphics_view.fitInView(self.pixmap_item, Qt.KeepAspectRatio)def resizeEvent(self, event):super().resizeEvent(event)self.fit_image_to_view() # 窗口调整大小时调整图片的缩放比例def closeEvent(self, event):if self.cap:self.cap.release()self.timer.stop()event.accept()if __name__ == '__main__':app = QApplication(sys.argv)player = VideoPlayer()player.show() # 显示窗口,使用默认大小,不最大化sys.exit(app.exec_())
固定大小,不能随窗口改变:
import sys
import cv2
from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel, QFileDialog, QVBoxLayout, QWidget
from PyQt5.QtGui import QPixmap, QImage
from PyQt5.QtCore import Qt, QTimer
from collections import deque
from pynput import keyboard
import numpy as npclass VideoPlayer(QMainWindow):def __init__(self):super().__init__()# Set up the windowself.setWindowTitle('Drag and Drop MP4 Player')self.setGeometry(100, 100, 800, 600)self.setAcceptDrops(True)# Main widget and layoutself.widget = QWidget(self)self.layout = QVBoxLayout(self.widget)self.setCentralWidget(self.widget)# Label to display video framesself.video_label = QLabel(self)self.video_label.setAlignment(Qt.AlignCenter)self.layout.addWidget(self.video_label)# Instructions labelself.label = QLabel("Drag and drop an MP4 file here to play", self)self.label.setAlignment(Qt.AlignCenter)self.layout.addWidget(self.label)# Video variablesself.cap = Noneself.frame_buffer = deque(maxlen=300)self.queue_index = -1self.load_new_frame = Trueself.frame_index = -1# Timer for video playbackself.timer = QTimer(self)self.timer.timeout.connect(self.display_frame)# Start keyboard listenerlistener = keyboard.Listener(on_press=self.on_press)listener.start()def on_press(self, key):if key == keyboard.Key.right or key == keyboard.Key.space: # Right arrow keyif self.queue_index < len(self.frame_buffer) - 1:self.queue_index += 1else:self.load_new_frame = Trueelif key == keyboard.Key.left: # Left arrow keyif self.queue_index > 0:self.queue_index -= 1self.load_new_frame = Falseelif str(key) == "'q'": # Press 'q' to exitself.close()def dragEnterEvent(self, event):if event.mimeData().hasUrls():event.accept()else:event.ignore()def dropEvent(self, event):for url in event.mimeData().urls():file_path = url.toLocalFile()if file_path.lower().endswith(".mp4"):self.load_video(file_path)def load_video(self, file_path):if self.cap:self.cap.release()self.cap = cv2.VideoCapture(file_path)self.frame_buffer.clear()self.queue_index = -1self.frame_index = -1self.load_new_frame = True# Start playing videoself.timer.start(30) # Start timer to update frames every 30msdef display_frame(self):if self.load_new_frame and self.cap:ret, frame = self.cap.read()if not ret:self.timer.stop()print('Video ended')returnself.frame_index += 1cv2.putText(frame, str(self.frame_index), (20, 70), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 255), 2)self.frame_buffer.append(frame)self.queue_index = len(self.frame_buffer) - 1self.load_new_frame = False# Show the current frameif len(self.frame_buffer) > 0:imshow = self.frame_buffer[self.queue_index]self.show_frame(imshow)def show_frame(self, frame):# Convert the frame from OpenCV (BGR) format to RGB formatrgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)h, w, ch = rgb_frame.shapebytes_per_line = ch * wq_img = QImage(rgb_frame.data, w, h, bytes_per_line, QImage.Format_RGB888)# Set the QPixmap to the QLabelself.video_label.setPixmap(QPixmap.fromImage(q_img).scaled(self.video_label.width(), self.video_label.height(), Qt.KeepAspectRatio))def closeEvent(self, event):if self.cap:self.cap.release()self.timer.stop()event.accept()if __name__ == '__main__':app = QApplication(sys.argv)player = VideoPlayer()player.show()sys.exit(app.exec_())
这篇关于mp4 显示 按帧 pyqt的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!