1.QT多媒体模块
1)摄像头设备信息类QCameraInfo
QList<QCameraInfo> avaliableCameras(),返回QCameraInfo类的列表,表示系统可用的摄像头设备列表;
QCameraInfo defaultCamera(),返回系统缺省的摄像头设备信息。
2)摄像头控制类QCamera
3) 静态图片抓取类QCameraImageCapture
4) 视频和音频录制类QMediaRecorder
功能截图:
下面是双摄像头循环录制视频代码
util.h
#ifndef UTI_H
#define UTI_H
#include <QDialog>
#include <QCameraInfo>
#include <QCameraViewfinder>
#include <QCameraImageCapture>
#include <QMediaRecorder>
#include <QCamera>
#include <QLabel>
#include <QSound>
#include <QMessageBox>
#include <QFile>
#include <QUrl>
#include <QDir>
#include <QFileDialog>
#include <sys/vfs.h>
#include <QFileInfo>
#include <QDateTime>
#include <QDate>
#include <QTimer>
#include <QStorageInfo>
#include <QFileSystemWatcher>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
//默认视频文件夹最大值为10GB
#define MaximumVideoCapacity 10 //70兆
#define VideoSaveDir "/video"
#define PictrueSaveDir "/picture"
#define VideoManagement "/EquipLog"
struct VideoInfo
{
QString videoName;//视频名称
QString videoSize;//视频大小
QString videoCreationTime;//视频创建时间
QString cycle;//视频循环周期
QString path;//视频绝对路径
QString part1;//备用字段1
QString part2;//备用字段2
VideoInfo()
{
videoName = "";
videoSize = "";
videoCreationTime = "";
cycle = "";
path = "";
part1 = "";
part2 = "";
}
void clearInfo()
{
videoName = "";
videoSize = "";
videoCreationTime = "";
cycle = "";
path = "";
part1 = "";
part2 = "";
}
};
double dirFileSize(const QString &path);
bool getPathSpace(const QString & path, double &nRemainingSpaceSize, double &nTotalSpaceSize);
bool getPathSpaceForQT(double &nRemainingSpaceSize, double &nTotalSpaceSize);
QString getCurrentDate(QString strFormat);
#endif // UTI_H
util.cpp
#include "util.h"
//比较慢,仅限于只有一级目录文件夹统计大小用
double dirFileSize(const QString &path)
{
QDir dir(path);
double size = 0.0;
//dir.entryInfoList(QDir::Files)返回文件信息
foreach(QFileInfo fileInfo, dir.entryInfoList(QDir::Files))
{
//计算文件大小
size += fileInfo.size();
}
//dir.entryList(QDir::Dirs|QDir::NoDotAndDotDot)返回所有子目录,并进行过滤
foreach(QString subDir, dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot))
{
//若存在子目录,则递归调用dirFileSize()函数
size += dirFileSize(path + QDir::separator() + subDir);
}
size = size / 1024.0; //KB
size = size / 1024.0; //MB
return size;
}
//C++获取系统磁盘空间情况
bool getPathSpace(const QString & path, double &nRemainingSpaceSize, double &nTotalSpaceSize)
{
struct statfs diskInfo;
statfs(path.toUtf8().data(), &diskInfo);
nRemainingSpaceSize = (diskInfo.f_bavail * diskInfo.f_bsize)/1024.0/1024.0;
nTotalSpaceSize = (diskInfo.f_blocks * diskInfo.f_bsize)/1024.0/1024.0;
//qDebug("%s 总大小:%.0lfMB 可用大小:%.0lfMB",path.toStdString().c_str(),(diskInfo.f_blocks * diskInfo.f_bsize)/1024.0/1024.0,(diskInfo.f_bavail * diskInfo.f_bsize)/1024.0/1024.0);
return true;
}
//QT类获取系统磁盘情况
bool getPathSpaceForQT(double &nRemainingSpaceSize, double &nTotalSpaceSize)
{
QStorageInfo storage = QStorageInfo::root();
storage.refresh(); //获得最新磁盘信息
if (storage.isReadOnly())
{
//qDebug() << "isReadOnly:" << storage.isReadOnly();
}
nRemainingSpaceSize = storage.bytesAvailable()/1024.0/1024.0;
nTotalSpaceSize = storage.bytesTotal()/1024.0/1024.0;
//qDebug() << "name:" << storage.name();
//qDebug() << "fileSystemType:" << storage.fileSystemType(); //fileSystemType: "ext4"
// qDebug() << "size:" << storage.bytesTotal()/1024.0/1024.0 << "MB";
//qDebug() << "availableSize:" << storage.bytesAvailable()/1024.0/1024.0 << "MB";
}
QString getCurrentDate(QString strFormat)
{
QDateTime currentTime = QDateTime::currentDateTime();
QString strTime = currentTime.toString(strFormat); //yyyy-MM-dd-hh-mm-ss
return strTime;
}
camera.h
#ifndef CAMERA_H
#define CAMERA_H
#include <QObject>
#include <QCameraInfo>
#include <QCameraViewfinder>
#include <QCameraImageCapture>
#include <QMediaRecorder>
#include <QCamera>
#include <QLabel>
#include <QSound>
#include <QMessageBox>
#include <QFile>
#include <QUrl>
#include <QDir>
#include <QFileDialog>
#include <sys/vfs.h>
#include <QFileInfo>
#include <QDateTime>
#include <QDate>
#include <QTimer>
#include <QStorageInfo>
#include <QFileSystemWatcher>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include "util.h"
class Camera : public QObject
{
Q_OBJECT
public:
explicit Camera( QString cameraName,QSqlDatabase &sqlDB, QObject *parent = nullptr, QString videoPath = "", QCamera *pCamera = nullptr);
~Camera();
/**************摄像头1循环录制***********************/
bool setVideoCycle(int nSecond);
int startVideoRecord();
int stopVideoRecord();
public:
/*************摄像头1************************/
QCamera * m_pCurCamera; //摄像头1指针
QMediaRecorder* m_pMediaRecorder;//摄像头1录像
QCameraImageCapture *imageCapture; //摄像头1抓图
void initCamera(QCamera *m_pCurCamera);//初始化
void initImageCapture();//初始化静态画图
void initVideoRecorder();//初始化视频录制
bool insertIntoVideosTable(VideoInfo info);
bool upDateFileSize(VideoInfo info);
private slots:
void on_m_timer_timeout();
public:
/********************摄像头************************/
int m_nVideoCycle; //摄像头视频循环周期(单位:秒)
bool m_bStartVideoByCycle; //摄像头是否是循环录制。
bool m_bVideoIsStart;//摄像头是否已开始录制
VideoInfo m_currentRecordFileInfo;//摄像头当前录像的文件名
QTimer *m_timer;//为了给视频录制服务启动一些开启时间,用个QTimer去延时启动录像功能。
QString m_strVideoPath; //存视频的文件夹
QString m_strVideo_2Path; //存视频的文件夹
QString m_strPicturePath;//存截图
QSqlDatabase m_sqlDB;
QString m_strVideomanageDBPath;
QString m_cameraName;
signals:
void saveVideoToNewFile(QString filePath);
void addNewVideo(QFileInfo &info);
};
#endif // CAMERA_H
camera.cpp
#include "camera.h"
Camera::Camera(QString cameraName,QSqlDatabase &sqlDB, QObject *parent, QString videoPath, QCamera *pCamera) : QObject(parent)
{
m_cameraName = cameraName;
m_pCurCamera = pCamera;
m_nVideoCycle = 0;
m_bVideoIsStart = false;
m_bStartVideoByCycle = false;
m_currentRecordFileInfo.clearInfo();
m_pMediaRecorder = NULL;
m_strVideoPath = videoPath;
m_sqlDB = sqlDB;
initCamera(m_pCurCamera);
m_timer = new QTimer(this);
m_timer->setInterval(4000);
m_timer->start();
connect(m_timer, SIGNAL(timeout()), this ,SLOT(on_m_timer_timeout()));
}
Camera::~Camera()
{
upDateFileSize(m_currentRecordFileInfo);
m_timer->stop();
m_timer->deleteLater();
}
bool Camera::setVideoCycle(int nSecond)
{
m_nVideoCycle = nSecond;
}
int Camera::startVideoRecord()
{
if(m_pCurCamera == NULL)
{
return -1;
}
if(m_pCurCamera->isAvailable() == false || m_pMediaRecorder->errorString() != "")
{
if(m_pMediaRecorder->errorString() != "")
{
qDebug() << "mediaRecorder->errorString():" << m_pMediaRecorder->errorString();
}
qDebug() << "m_pCurCamera->errorString():" << m_pCurCamera->errorString();
return -1;
}
if(m_nVideoCycle == 0)
{
m_nVideoCycle = 3 * 60; //默认3分钟
}
m_bStartVideoByCycle = true;
{
//开始录制
if(m_bVideoIsStart == true)
{
return -1;
}
if (!m_pMediaRecorder->isAvailable())
{
return -1;
}
if (m_pCurCamera->captureMode() != QCamera::CaptureVideo)
{
m_pCurCamera->setCaptureMode(QCamera::CaptureVideo);
}
//on_startVideoRecordBtn_clicked();
QString strPath = m_strVideoPath;
QDir dir;
if(!dir.exists(strPath))
{
bool res = dir.mkpath(strPath);
}
strPath += "/" + m_cameraName + "_";
strPath.append(getCurrentDate("yyyy-MM-dd-hh-mm-ss"));
m_pMediaRecorder->setOutputLocation(QUrl::fromLocalFile(strPath));
m_pMediaRecorder->record();
if(m_pMediaRecorder->errorString() != "")
{
QMediaRecorder::Error error = m_pMediaRecorder->error();
QMediaRecorder::State st = m_pMediaRecorder->state();
QMediaRecorder::Status status = m_pMediaRecorder->status();
qDebug() << "mediaRecorder error:" << m_pMediaRecorder->errorString();
return -1;
}
else
{
if(m_pMediaRecorder->errorString() == "")
{
m_timer->stop();
}
m_bVideoIsStart = true;
QString strTempPath = strPath;
if(strPath.contains(".webm") == false)
{
strTempPath += ".webm";
}
QFileInfo info(strTempPath);
//m_VideoFilenameVec.push_front(info);
emit addNewVideo(info);
//向数据库插入新数据
VideoInfo tempInfo;
tempInfo.videoName = info.fileName();
tempInfo.videoCreationTime = getCurrentDate("yyyy-MM-dd hh:mm:ss:zzz");
tempInfo.cycle = QString::number(m_nVideoCycle);
tempInfo.path = info.filePath();
bool bResult = insertIntoVideosTable(tempInfo);
if(bResult == false)
{
return -1;
}
m_currentRecordFileInfo = tempInfo;
emit saveVideoToNewFile(info.filePath());
return 1;
}
}
}
int Camera::stopVideoRecord()
{
if(m_pCurCamera == NULL)
{
QMessageBox::warning(nullptr, "警告", "当前无摄像头在录制", QMessageBox::Ok);
}
//终止循环录制
m_pMediaRecorder->stop();
m_bVideoIsStart = false;
m_bStartVideoByCycle = false;
if(m_currentRecordFileInfo.path != "")
{
upDateFileSize(m_currentRecordFileInfo);
}
m_currentRecordFileInfo.clearInfo();
}
void Camera::initCamera(QCamera *curCamera)
{
//创建QCamera对象
if(curCamera == NULL)
{
return;
}
QCameraViewfinderSettings viewfinderSettings;
viewfinderSettings.setResolution(640, 480);
viewfinderSettings.setMinimumFrameRate(15.0);
viewfinderSettings.setMaximumFrameRate(30.0);
curCamera->setViewfinderSettings(viewfinderSettings);
curCamera->setCaptureMode(QCamera::CaptureVideo);//摄像头1设置为录像
curCamera->start();
initImageCapture();
initVideoRecorder();
}
void Camera::initImageCapture()
{
if(m_pCurCamera == NULL)
{
return;
}
//创建 QCameraImageCapture对象
imageCapture = new QCameraImageCapture(m_pCurCamera,this);
QImageEncoderSettings imageSettings;
imageSettings.setCodec("image/jpeg"); //设置抓图图形编码
imageSettings.setResolution(640, 480); //分辨率
imageSettings.setQuality(QMultimedia::HighQuality);//图片质量
imageCapture->setEncodingSettings(imageSettings);
imageCapture->setBufferFormat(QVideoFrame::Format_Jpeg); //缓冲区格式
imageCapture->setCaptureDestination(QCameraImageCapture::CaptureToFile); //保存目标
}
void Camera::initVideoRecorder()
{
//创建QMediaRecorder对象
if(m_pMediaRecorder == NULL)
{
m_pMediaRecorder = new QMediaRecorder(m_pCurCamera,this);
}
/*QAudioEncoderSettings audioSettings;
audioSettings.setCodec("audio/amr");
audioSettings.setQuality(QMultimedia::HighQuality);
mediaRecorder->setAudioSettings(audioSettings);*/
/*QVideoEncoderSettings videoSettings;
videoSettings.setCodec("video/mpeg2");
videoSettings.setResolution(640, 480);
videoSettings.setQuality(QMultimedia::NormalQuality);
mediaRecorder->setVideoSettings(videoSettings);*/
}
bool Camera::insertIntoVideosTable(VideoInfo info)
{
if(info.videoName == "" || m_sqlDB.isOpen() == false)
{
return false;
}
//向数据库插入新数据
QSqlQuery sqlquery(m_sqlDB);
QString strSql = "insert into videos(video_name,video_size,video_creation_time,cycle,path,part1,part2) values('";
strSql += info.videoName + "','";
strSql += "','";
strSql += info.videoCreationTime + "','";
strSql += info.cycle + "','";
strSql += info.path + "','','')";
if(sqlquery.exec(strSql) == false)
{
//插入数据库失败
qDebug() << "插入数据库失败:" << strSql;
return false;
}
return true;
}
void Camera::on_m_timer_timeout()
{
qDebug() << "timeout....." << getCurrentDate("yyyy-MM-dd hh:mm:ss:zzz");
startVideoRecord();
}
bool Camera::upDateFileSize(VideoInfo info)
{
if(info.path == "" || m_sqlDB.isOpen() == false)
{
return false;
}
QFileInfo videoFile(info.path);
//向数据库更新数据
QSqlQuery sqlquery(m_sqlDB);
QString strSql = "update videos set video_size ='" + QString::number(videoFile.size()) + "' where path='" + videoFile.filePath() + "'";
//qDebug() << "更新:" << strSql;
if(sqlquery.exec(strSql) == false)
{
//更新数据库失败
qDebug() << "更新数据库失败:" << strSql;
return false;
}
return true;
}
cameravideo.h
#ifndef CAMERAVIDEO_H
#define CAMERAVIDEO_H
#include <QDialog>
#include <QCameraInfo>
#include <QCameraViewfinder>
#include <QCameraImageCapture>
#include <QMediaRecorder>
#include <QCamera>
#include <QLabel>
#include <QSound>
#include <QMessageBox>
#include <QFile>
#include <QUrl>
#include <QDir>
#include <QFileDialog>
#include <sys/vfs.h>
#include <QFileInfo>
#include <QDateTime>
#include <QDate>
#include <QTimer>
#include <QStorageInfo>
#include <QFileSystemWatcher>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include "util.h"
#include "camera.h"
QT_BEGIN_NAMESPACE
namespace Ui { class CameraVideo; }
QT_END_NAMESPACE
class CameraVideo : public QDialog
{
Q_OBJECT
public:
CameraVideo(QWidget *parent = nullptr);
~CameraVideo();
void setCycle(quint64 nCycle);
private:
void init();
void initCamera();
bool initCamera1(QCameraInfo &info);
bool initCamera2(QCameraInfo &info);
private:
/*************摄像头************************/
QCamera * curCamera; //摄像头1指针
QCamera * curCamera_2;//摄像头2指针
Camera * m_pCameraClass; //摄像头1数据处理类
Camera * m_pCameraClass_2; //摄像头2数据处理类
void initDBhandle();
void checkTableExist();
//bool upDateFileSize(VideoInfo info);
bool removeOldFile();
void orderFilesByTimeDesc();
QString checkDirCapacity();//检查目录空间大小
void checkCameraIsActive();
private slots:
void onCheckDisk_timeout();
void onDirectoryChanged(const QString& strPath);
void on_addNewVideo(QFileInfo& fileInfo);
/****************摄像头1 槽函数*********************/
void on_camera_saveVideoToNewFile(QString filePath);
//QCamera的槽函数
void on_cameraStateChanged(QCamera::State state);
void on_cameraCaptureModeChanged(QCamera::CaptureModes mode);
//QCameraImageCapture的槽函数
void on_imageReadyForCapture(bool ready);
void on_imageCaptured(int id, const QImage &preview);
void on_imageSaved(int id, const QString &fileName);
// QMediaRecorder的槽函数
void on_videoStateChanged(QMediaRecorder::State state);
void on_videoDurationChanged(qint64 duration);
//void on_videoError(QMediaRecorder::Error error);
/****************摄像头2 槽函数*********************/
void on_camera2_saveVideoToNewFile(QString filePath);
//QCamera的槽函数
void on_camera_2StateChanged(QCamera::State state);
void on_camera_2CaptureModeChanged(QCamera::CaptureModes mode);
//QCameraImageCapture的槽函数
void on_image_2ReadyForCapture(bool ready);
void on_image_2Captured(int id, const QImage &preview);
void on_image_2Saved(int id, const QString &fileName);
// QMediaRecorder的槽函数
void on_video_2StateChanged(QMediaRecorder::State state);
void on_video_2DurationChanged(qint64 duration);
void on_startCameraBtn_clicked();
void on_startCameraBtn_2_clicked();
void on_stopCameraBtn_clicked();
void on_stopCameraBtn_2_clicked();
void on_captureBtn_clicked();
void on_captureBtn_2_clicked();
void on_startVideoRecordBtn_clicked();
void on_startVideoRecordBtn_2_clicked();
void on_stopVideoBtn_clicked();
void on_stopVideoBtn_2_clicked();
void on_quitBtn_clicked();
void on_btnVideoFile_clicked();
void on_btnVideoFile_2_clicked();
void on_chkMute_clicked(bool checked);
void on_chkMute_2_clicked(bool checked);
void on_startCycleVideoBtn_clicked();
void on_startCycleVideoBtn_2_clicked();
void on_stopCycleVIdeoBtn_clicked();
void on_stopCycleVIdeoBtn_2_clicked();
private:
Ui::CameraVideo *ui;
QTimer *m_checkDiskSPaceTimer;//专门检测目录:video空间大小,如果超过就删除旧的视频
QFileSystemWatcher *m_pFSWatcher; //文件监控器
QVector<QFileInfo> m_VideoFilenameVec; //存储所有视频文件信息
QString m_strVideoPath;
QString m_strPicturePath;//存截图
quint64 m_nCycle;
QSqlDatabase m_sqlDB;
QString m_strVideomanageDBPath;
};
#endif // CAMERAVIDEO_H
cameravideo.cpp
#ifndef CAMERAVIDEO_H
#define CAMERAVIDEO_H
#include <QDialog>
#include <QCameraInfo>
#include <QCameraViewfinder>
#include <QCameraImageCapture>
#include <QMediaRecorder>
#include <QCamera>
#include <QLabel>
#include <QSound>
#include <QMessageBox>
#include <QFile>
#include <QUrl>
#include <QDir>
#include <QFileDialog>
#include <sys/vfs.h>
#include <QFileInfo>
#include <QDateTime>
#include <QDate>
#include <QTimer>
#include <QStorageInfo>
#include <QFileSystemWatcher>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include "util.h"
#include "camera.h"
QT_BEGIN_NAMESPACE
namespace Ui { class CameraVideo; }
QT_END_NAMESPACE
class CameraVideo : public QDialog
{
Q_OBJECT
public:
CameraVideo(QWidget *parent = nullptr);
~CameraVideo();
void setCycle(quint64 nCycle);
private:
void init();
void initCamera();
bool initCamera1(QCameraInfo &info);
bool initCamera2(QCameraInfo &info);
private:
/*************摄像头************************/
QCamera * curCamera; //摄像头1指针
QCamera * curCamera_2;//摄像头2指针
Camera * m_pCameraClass; //摄像头1数据处理类
Camera * m_pCameraClass_2; //摄像头2数据处理类
void initDBhandle();
void checkTableExist();
//bool upDateFileSize(VideoInfo info);
bool removeOldFile();
void orderFilesByTimeDesc();
QString checkDirCapacity();//检查目录空间大小
void checkCameraIsActive();
private slots:
void onCheckDisk_timeout();
void onDirectoryChanged(const QString& strPath);
void on_addNewVideo(QFileInfo& fileInfo);
/****************摄像头1 槽函数*********************/
void on_camera_saveVideoToNewFile(QString filePath);
//QCamera的槽函数
void on_cameraStateChanged(QCamera::State state);
void on_cameraCaptureModeChanged(QCamera::CaptureModes mode);
//QCameraImageCapture的槽函数
void on_imageReadyForCapture(bool ready);
void on_imageCaptured(int id, const QImage &preview);
void on_imageSaved(int id, const QString &fileName);
// QMediaRecorder的槽函数
void on_videoStateChanged(QMediaRecorder::State state);
void on_videoDurationChanged(qint64 duration);
//void on_videoError(QMediaRecorder::Error error);
/****************摄像头2 槽函数*********************/
void on_camera2_saveVideoToNewFile(QString filePath);
//QCamera的槽函数
void on_camera_2StateChanged(QCamera::State state);
void on_camera_2CaptureModeChanged(QCamera::CaptureModes mode);
//QCameraImageCapture的槽函数
void on_image_2ReadyForCapture(bool ready);
void on_image_2Captured(int id, const QImage &preview);
void on_image_2Saved(int id, const QString &fileName);
// QMediaRecorder的槽函数
void on_video_2StateChanged(QMediaRecorder::State state);
void on_video_2DurationChanged(qint64 duration);
void on_startCameraBtn_clicked();
void on_startCameraBtn_2_clicked();
void on_stopCameraBtn_clicked();
void on_stopCameraBtn_2_clicked();
void on_captureBtn_clicked();
void on_captureBtn_2_clicked();
void on_startVideoRecordBtn_clicked();
void on_startVideoRecordBtn_2_clicked();
void on_stopVideoBtn_clicked();
void on_stopVideoBtn_2_clicked();
void on_quitBtn_clicked();
void on_btnVideoFile_clicked();
void on_btnVideoFile_2_clicked();
void on_chkMute_clicked(bool checked);
void on_chkMute_2_clicked(bool checked);
void on_startCycleVideoBtn_clicked();
void on_startCycleVideoBtn_2_clicked();
void on_stopCycleVIdeoBtn_clicked();
void on_stopCycleVIdeoBtn_2_clicked();
private:
Ui::CameraVideo *ui;
QTimer *m_checkDiskSPaceTimer;//专门检测目录:video空间大小,如果超过就删除旧的视频
QFileSystemWatcher *m_pFSWatcher; //文件监控器
QVector<QFileInfo> m_VideoFilenameVec; //存储所有视频文件信息
QString m_strVideoPath;
QString m_strPicturePath;//存截图
quint64 m_nCycle;
QSqlDatabase m_sqlDB;
QString m_strVideomanageDBPath;
};
#endif // CAMERAVIDEO_H
main.cpp
#include "cameravideo.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
CameraVideo w;
w.show();
w.setCycle(10);
return a.exec();
}
源码链接:https://download.csdn.net/download/sinat_33419023/15452307