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_OBJECTpublic: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); // 控制帧率为30fpsm_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); // 控制帧率为30fpsm_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的QImageQImage 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;}