123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- #ifndef _CREATELONGFILETHREAD_H_
- #define _CREATELONGFILETHREAD_H_
- #include "BaseRecordThread.h"
- #include "AudioData.h"
- #include "GlobalVariable.h"
- #include "RingQueue.hpp"
- #include <mutex>
- #include <QFile>
- #include <QDir>
- #include <qt5/QtCore/qchar.h>
- /**
- * @brief 录音状态
- *
- */
- enum class eAlarmState
- {
- eAlarm_Init = 0, /* 初始化状态 */
- eAlarm_Recording, /* 录音状态 */
- eAlarm_Stopped, /* 停止状态 */
- eAlarm_Error, /* 错误状态 */
- };
- /**
- 同一个对比项中多个一致性报警时,主通道的录音可能开始录音时间不同,
- 会有多个录音同时存在
- */
- struct AlarmKey_t
- {
- int compareItemID; /* 对比项ID */
- int roadNum; /* 对比通道编号 */
- EAlarmType alarmType; /* 报警类型 */
- QDateTime startTime; /* 报警开始时间 */
- AlarmKey_t(int id, int num, EAlarmType type, const QDateTime& time)
- : compareItemID(id), roadNum(num), alarmType(type), startTime(time) {}
-
- bool operator<(const AlarmKey_t& other) const
- {
- if(compareItemID != other.compareItemID) {
- return compareItemID < other.compareItemID;
- }
- if(roadNum != other.roadNum) {
- return roadNum < other.roadNum;
- }
- if(alarmType != other.alarmType) {
- return alarmType < other.alarmType;
- }
- return startTime < other.startTime;
- }
- };
- /**
- 报警文件队列的值
- */
- struct AlarmValue_t
- {
- QString fileName; /* 报警文件名 */
- eAlarmState state; /* 录音状态 */
- QDateTime startTime; /* 录音开始时间 */
- QDateTime endTime; /* 录音结束时间 */
- AlarmValue_t(const QString& name, eAlarmState s, const QDateTime& start, const QDateTime& end)
- : fileName(name), state(s), startTime(start), endTime(end) {}
- };
- /**
- 这个线程类记录一个长的录音文件,1小时一个文件
- 功能1:记录一个长的录音文件,1小时一个文件
- 1、如果是刚开始录音,到下一个整点记录一个文件,后续都是满1小时一个文件
- 2、数据先放到缓冲区中,满1分钟写一次文件
-
- 功能2:
- 1、录制报警文件
- 2、由其他线程传来报警参数,开启录制,报警结束后,结束录制
- 3、由于静音、过载、反相、一致性报警、噪音报警条件是和对比项相关联的,因此这里可能回同时存在多个录音,
- 根据对比项ID和对比项通道以及报警类型来区分
- 4、报警文件的命名规则:Alarm_CompareItemID_RoadNum_AlarmType_yyyyMMdd_hhmmss-yyyyMMdd_hhmmss.wav
- 例如:Alarm_1_1_Silent_20250101_120000-20250101_120100.wav
-
- 文件夹路径格式:
- 1、长录音文件夹: Application/ACAServerData/Record/yyyy-MM-dd/SoundCardID-RoadNum/Record_yyyy-MM-dd-hh-mm-ss-yyyy-MM-dd-hh-mm-ss.wav
- 例如:Application/2025-01-01/SoundCard1-1/Record_2025-01-01-12-00-00-2025-01-01-12-01-00.wav
- 2、报警录音文件夹:Application/ACAServerData/AlarmWav/yyyy-MM-dd/CompareItemName/Alarm_CompareItemID_RoadNum_AlarmType_yyyyMMdd_hhmmss-yyyyMMdd_hhmmss.wav
- 例如:Application/2025-01-01/1-1/Alarm_1_1_Silent_20250101_120000-20250101_120100.wav
- */
- class CreateLongFileThread : public BaseRecordThread
- {
- public:
- CreateLongFileThread(RecordThreadInfo_t& threadInfo);
- ~CreateLongFileThread() override;
- /* 设置数据 */
- bool setData(const AudioSrcData& srcData) override;
- /* 开启录制 */
- bool startRecordAlarmFile(const AlarmInfo_t& alarmInfo);
- /* 停止录制,alarmInfo既是传入参数,也是传出参数,传出文件路径和开始位置 */
- bool stopRecordAlarmFile(AlarmInfo_t& alarmInfo);
- private:
- /* 执行任务函数 */
- void task() override;
- /* 初始化一些数据 */
- bool initData() override;
- /* 清理数据 */
- void clearData() override;
- /*===============================================================================*/
- /* 写入长记录文件 */
- bool writeLongRecordFile();
- /* 设置今日目录 */
- inline bool setTodayPath(bool isNewFile);
- /* 打开文件 */
- bool openFile(QFile& wavFile, bool isNewFile);
- /* 写入音频数据到文件 */
- bool writeAudioDataToFile(const AudioSrcData& audioData, const QString& fileName);
- /* 生成文件名 */
- inline QString generateFileName(const QDateTime& startTime, const QDateTime& endTime) const;
- /* 判断是否过了整点 */
- inline bool isOneHourPassed();
- /*===============================================================================*/
- /* 写入报警文件 */
- void writeAlarmFile();
- /* 生成报警文件名 */
- inline QString generateAlarmFileName(const AlarmInfo_t& alarmInfo, bool isNewFile);
- /* 设置今日报警文件夹 */
- bool setTodayAlarmPath();
- /* 根据报警类型的枚举获取字符 */
- QString getAlarmTypeString(EAlarmType type) const;
-
- private:
- /* 临时缓存数据, 一分钟写入一次,给这个分配2分钟的数据大小 */
- std::mutex m_mutexBuffer;
- AudioSrcData m_bufferData;
- AudioSrcData m_srcData; /* 当前的音频数据 */
- int32_t m_writeCriticalSize = 0; /* 写入文件的临界大小,单位:字节,缓存超过这个大小就写入文件 */
- int32_t m_oneHourSize = 0; /* 一小时的音频数据大小 */
- QDir m_todayDir; /* 今日目录 */
- QDate m_todayDateRecord; /* 今日日期,记录长文件用 */
- QString m_wavFileName; /* wav文件对象 */
- int m_openFileErrorSize = 0; /* 打开文件错误次数 */
- WavHeader m_wavHeader; /* 当前wav文件头信息 */
- int64_t m_writtenSize = 0; /* 已经写入的数据大小 */
- QDateTime m_writtenStartTime; /* 已经写入数据的开始时间点 */
- QDateTime m_writtenNowTime; /* 已经写入数据的最后时间点 */
- /*===============================================================================*/
- /* 报警文件名,key是报警信息,value是文件信息 */
- std::map<AlarmKey_t, AlarmValue_t> m_mapAlarmFile;
- QDir m_yesterdayDir; /* 昨日目录,用来给还未录制完成的报警文件使用的 */
- QDir m_todayDirAlarm; /* 今日报警目录,这个目录只到日期,里面的子文件夹是对比项相关的 */
- QDate m_todayDateAlarm; /* 今日日期,记录报警文件用 */
- RingQueue<AudioSrcData*> m_ringQueue; /* 环形队列,存储几分钟的数据,用来写入报警文件 */
- QDateTime m_alarmWrittenTime; /* 报警文件中环形队列已写入文件的时间 */
- };
- #endif // _CREATELONGFILETHREAD_H_
|