1.效果图
2 代码实现
2.1 .h文件
#ifndef VIDEORECORDWIDGET_H
#define VIDEORECORDWIDGET_H
#include <QWidget>
#include<QFileDialog>
#include <QImage>
#include <QLabel>
#include <QTimer>
#include <opencv2/opencv.hpp>
using namespace cv;
namespace Ui {
class VideoRecordWidget;
}
class VideoRecordWidget : public QWidget
{
Q_OBJECT
public:
explicit VideoRecordWidget(QWidget *parent = nullptr);
~VideoRecordWidget();
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
void on_pushButton_3_clicked();
void on_pushButton_5_clicked();
void on_pushButton_4_clicked();
void updateFrame();
void on_pushButton_6_clicked();
private:
Ui::VideoRecordWidget *ui;
VideoCapture capture;
// QTimer timer;
VideoWriter videoWriter;
bool m_video_open;
bool m_video_record;
QTimer timer_open;
QTimer timer_record;
String recordViedo_fileName;
};
#endif // VIDEORECORDWIDGET_H
2.2 .cpp文件
#include "videorecordwidget.h"
#include "ui_videorecordwidget.h"
VideoRecordWidget::VideoRecordWidget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::VideoRecordWidget)
{
ui->setupUi(this);
m_video_open=false;
m_video_record=false;
// connect(&timer, &QTimer::timeout, this, &VideoRecordWidget::updateFrame);
}
VideoRecordWidget::~VideoRecordWidget()
{
delete ui;
}
//开启摄像头
void VideoRecordWidget::on_pushButton_clicked()
{
// 打开摄像头
capture.open(0);
if (!capture.isOpened()) {
qDebug("Failed to open camera.");
return;
}
qDebug()<<"摄像头开启中";
// 开始定时器,以固定间隔刷新显示视频图像
timer_open.start(33); // 控制帧率为30fps
m_video_open=true;
connect(&timer_open, &QTimer::timeout, this, &VideoRecordWidget::updateFrame);
}
//关闭摄像头
void VideoRecordWidget::on_pushButton_2_clicked()
{
// 关闭摄像头
qDebug()<<"摄像头关闭中";
capture.release();
ui->label->clear();
ui->label->setText("视频录制器");
timer_open.stop();
m_video_open=false;
if(m_video_record){
qDebug()<<"结束录制";
m_video_record=false;
timer_record.stop();
videoWriter.release();
}
}
//开始录制
void VideoRecordWidget::on_pushButton_3_clicked()
{
if(m_video_open){
if(videoWriter.isOpened()){
qDebug()<<"已经有录制项目:"<<recordViedo_fileName<<"请先结束录制,再操作";
return;
}
// 获取当前时间作为视频文件名
std::time_t time = std::time(0);
std::ostringstream oss;
oss << "video_" << time << ".avi";
recordViedo_fileName=oss.str();
// std::string filename = oss.str();
ui->lineEdit->setText(recordViedo_fileName.c_str());
qDebug()<<"摄像头开启中-并进行录制,文件名:"<<recordViedo_fileName;
timer_record.start(1000/25); // 控制帧率为30fps
m_video_record=true;
cv::Mat frame;
capture >> frame; // 从视频流中捕获当前帧
int codec = cv::VideoWriter::fourcc('M', 'J', 'P', 'G');
double fps = 25.0;
cv::Size frameSize(frame.cols, frame.rows);
// if(videoWriter.isOpened()){
// videoWriter.write(frame);
// return;
// }
videoWriter.open(recordViedo_fileName, codec, fps, frameSize);
connect(&timer_record, &QTimer::timeout, this, &VideoRecordWidget::updateFrame);
}else{
qDebug()<<"请先打开摄像头";
}
}
//暂停录制
void VideoRecordWidget::on_pushButton_5_clicked()
{
qDebug()<<"暂停录制";
m_video_record=false;
}
//结束录制
void VideoRecordWidget::on_pushButton_4_clicked()
{
qDebug()<<"结束录制";
m_video_record=false;
timer_record.stop();
videoWriter.release();
}
void VideoRecordWidget::updateFrame()
{
if(m_video_open){
cv::Mat frame;
capture >> frame; // 从视频流中捕获当前帧
if (frame.empty()) {
return;
}
// 将OpenCV的Mat图像转换为Qt的QImage
QImage qimage(frame.data, frame.cols, frame.rows, static_cast<int>(frame.step), QImage::Format_BGR888);
QPixmap pixmap = QPixmap::fromImage(qimage);
// 设置QLabel显示图像
ui->label->setPixmap(pixmap.scaled(ui->label->size(), Qt::KeepAspectRatio));
if(m_video_record){
qDebug()<<"录制中";
// 创建 VideoWriter 对象
// 检查是否成功打开视频文件
if (!videoWriter.isOpened())
{
qDebug() << "无法打开视频文件.";
return;
}
videoWriter.write(frame);
}
}
}
//继续录制
void VideoRecordWidget::on_pushButton_6_clicked()
{
qDebug()<<"继续录制";
m_video_record=true;
}