mp4 显示 按帧 pyqt

2024-08-21 08:04
文章标签 显示 pyqt mp4

本文主要是介绍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的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1092589

相关文章

使用PyQt实现简易文本编辑器

《使用PyQt实现简易文本编辑器》这篇文章主要为大家详细介绍了如何使用PyQt5框架构建一个简单的文本编辑器,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录分析主窗口类 (MyWindow)菜单操作语法高亮 (SyntaxHighlighter)运行程序主要组件代码图示分析实现

如何设置vim永久显示行号

《如何设置vim永久显示行号》在Linux环境下,vim默认不显示行号,这在程序编译出错时定位错误语句非常不便,通过修改vim配置文件vimrc,可以在每次打开vim时永久显示行号... 目录设置vim永久显示行号1.临时显示行号2.永www.chinasem.cn久显示行号总结设置vim永久显示行号在li

电脑显示hdmi无信号怎么办? 电脑显示器无信号的终极解决指南

《电脑显示hdmi无信号怎么办?电脑显示器无信号的终极解决指南》HDMI无信号的问题却让人头疼不已,遇到这种情况该怎么办?针对这种情况,我们可以采取一系列步骤来逐一排查并解决问题,以下是详细的方法... 无论你是试图为笔记本电脑设置多个显示器还是使用外部显示器,都可能会弹出“无HDMI信号”错误。此消息可能

第10章 中断和动态时钟显示

第10章 中断和动态时钟显示 从本章开始,按照书籍的划分,第10章开始就进入保护模式(Protected Mode)部分了,感觉从这里开始难度突然就增加了。 书中介绍了为什么有中断(Interrupt)的设计,中断的几种方式:外部硬件中断、内部中断和软中断。通过中断做了一个会走的时钟和屏幕上输入字符的程序。 我自己理解中断的一些作用: 为了更好的利用处理器的性能。协同快速和慢速设备一起工作

安卓链接正常显示,ios#符被转义%23导致链接访问404

原因分析: url中含有特殊字符 中文未编码 都有可能导致URL转换失败,所以需要对url编码处理  如下: guard let allowUrl = webUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else {return} 后面发现当url中有#号时,会被误伤转义为%23,导致链接无法访问

C#实战|大乐透选号器[6]:实现实时显示已选择的红蓝球数量

哈喽,你好啊,我是雷工。 关于大乐透选号器在前面已经记录了5篇笔记,这是第6篇; 接下来实现实时显示当前选中红球数量,蓝球数量; 以下为练习笔记。 01 效果演示 当选择和取消选择红球或蓝球时,在对应的位置显示实时已选择的红球、蓝球的数量; 02 标签名称 分别设置Label标签名称为:lblRedCount、lblBlueCount

webm怎么转换成mp4?这几种方法超多人在用!

webm怎么转换成mp4?WebM作为一种新兴的视频编码格式,近年来逐渐进入大众视野,其背后承载着诸多优势,但同时也伴随着不容忽视的局限性,首要挑战在于其兼容性边界,尽管WebM已广泛适应于众多网站与软件平台,但在特定应用环境或老旧设备上,其兼容难题依旧凸显,为用户体验带来不便,再者,WebM格式的非普适性也体现在编辑流程上,由于它并非行业内的通用标准,编辑过程中可能会遭遇格式不兼容的障碍,导致操

lvgl8.3.6 控件垂直布局 label控件在image控件的下方显示

在使用 LVGL 8.3.6 创建一个垂直布局,其中 label 控件位于 image 控件下方,你可以使用 lv_obj_set_flex_flow 来设置布局为垂直,并确保 label 控件在 image 控件后添加。这里是如何步骤性地实现它的一个基本示例: 创建父容器:首先创建一个容器对象,该对象将作为布局的基础。设置容器为垂直布局:使用 lv_obj_set_flex_flow 设置容器

C# dateTimePicker 显示年月日,时分秒

dateTimePicker默认只显示日期,如果需要显示年月日,时分秒,只需要以下两步: 1.dateTimePicker1.Format = DateTimePickerFormat.Time 2.dateTimePicker1.CustomFormat = yyyy-MM-dd HH:mm:ss Tips:  a. dateTimePicker1.ShowUpDown = t

小程序button控件上下边框的显示和隐藏

问题 想使用button自带的loading图标功能,但又不需要button显示边框线 button控件有一条淡灰色的边框,在控件上了样式 border:none; 无法让button边框隐藏 代码如下: <button class="btn">.btn{border:none; /*一般使用这个就是可以去掉边框了*/} 解决方案 发现button控件有一个伪元素(::after