#pragma once #include "FFmpegWriter.h" #include "libvideorecord.h" #include "libaudioqueue.h" #include "libvideoqueue.h" #include "CvxText.h" #include "iaudionsinterface.h" #include #include #ifdef _WIN32 #else #include #endif #ifndef CAPTURE_CLOCK #define CAPTURE_CLOCK 8000 #endif #ifndef CAPTURE_FRAME_TIME #define CAPTURE_FRAME_TIME 20 // 20ms per frame #endif #ifndef CAPTURE_FRAME_MAX_LEN #define CAPTURE_FRAME_MAX_LEN 2048 // 48KHZ每20ms输出1920字节 #endif #ifndef RECORD_FAILED_MAX_TIMES #define RECORD_FAILED_MAX_TIMES 5000 #endif // !RECORD_FAILED_MAX_TIMES #ifndef GET_REMOTEVIDEO_FAILED_MAX_TIMES #define GET_REMOTEVIDEO_FAILED_MAX_TIMES 15 #endif // !GET_REMOTEVIDEO_FAILED_MAX_TIMES #ifndef rvc_snprintf #ifdef _WIN32 #define rvc_snprintf _snprintf #else #define rvc_snprintf snprintf #endif // _WIN32 #endif // rvc_snprintf class libvideorecord_impl : public LogApi { public: libvideorecord_impl(bool* pResult, CHostApi* pHostAPI, const char* audioqueuename, const char* videoqueuename, const char* videoqueue2name, const char* salesaudioqueuename, const char* remotevideoqueuename, const char* remoteaudioqueuename); ~libvideorecord_impl(); CHostApi* GetHostApi(); int VideoRecord(); bool StartVideoRecord(int fps, int videoquality, eVideoFormat eFormat, const SubtitleParam* subtitleParam, bool bWholeSection, bool bSessionManage, const char* pathname, int pathlength, const char* pfilename, int filenamelength, Rvc_RecordAudioParam_t* pAudioParam);//开始记录 bool StopVideoRecord(); //退出 bool PauseRecord(); //暂停录像 bool ContinueRecord(); //继续录像 void ChangeFilename(const char* newfilename); #ifdef _WIN32 bool setRightWaterMark(const char* strWaterMark, uint32_t ulen); #else bool setRightWaterMark(const wchar_t* strWaterMark, uint32_t ulen); #endif bool EndRecord(); void Debug(const char* fmt, ...); void vDebug(const char* str, va_list list); public: bool m_bCloseVideo; //是否关闭当前录像 bool m_bReNameVideo; //是否重命名录像文件 CHostApi* m_pHostApi; private: //开始录制视频 bool StartRecord(); //获取指定队列的SIZE int GetVideoFrameSize(int& nWidth, int& nHeight, Clibvideoqueue* queue); //从指定队列读取video bool GetVideoFrame(video_frame* Video, int flags, Clibvideoqueue* queue); bool IsRecordingCamError(int iRecordingCam, eRvcRecordType eRecordType = eStand2Agent); bool InitCvxText(); void GetVideoFullName(); bool AddCvxText(unsigned char** pData, int iDataSize, int iWidth, int iHeight); bool InitRecordWriter(char* filename, int width, int height, int colorbit, int nfps, int nSamplePsec, int nchannels, int nBitPerSample, int nmaxspacing, int nquality, int nOutBitRate, int iAudioType); bool StartRecordWrite(); bool ReceiveRecordVideoData(unsigned char* pData, unsigned long len); bool ReceiveRecordAudioData(unsigned char* pData, unsigned long len); bool EndRecordWrite(); bool ReNameVideo(); bool InitRecordParams(); bool CalcuRecordAudioParams(audio_frame* paudio); bool InitRecordAudioBuffer(); bool Rvc_Timeout(int ms); bool InitAudioQueue(); bool InitVideoQueue(); bool InitMediaQueueInfos(const char* audioqueuename, const char* videoqueuename, const char* videoqueue2name, const char* salesaudioqueuename, const char* remotevideoqueuename, const char* remoteaudioqueuename); bool GetRecordVideoFrameSize(); bool GetRecordAudioFrameSize(); bool InitRecordVideoFrameBuffer(); bool GetRecordAudioParams(audio_frame** paudio); int GetSingleSideVideoFrameSize(int& iWidth, int& iHeight); int GetDoubleSideVideoFrameSize(int& iWidth, int& iHeight); int GetDestTypeVideoFrameSize(int& iWidth, int& iHeight, eRvcRecordType eRecordType); int GetSingleCameraVideoFrameData(videoq_frame* Video, int flags, eRvcRecordType eRecordType); int GetDoubleCameraVideoFrameData(videoq_frame* Video, int flags, const bool bSwitchCam, int iInitCam, eRvcRecordType eRecordType); int GetStand2SVideoFrameData(videoq_frame* Video, int flags, const bool bSwitchCam, int iInitCam, eRvcRecordType eRecordType); int GetDestTypeVideoFrameData(videoq_frame* Video, int flags, const bool bSwitchCam, int iInitCam, eRvcRecordType eRecordType); int GetSingleSideVideoFrameData(videoq_frame* Video, int flags, const bool bSwitchCam, int iInitCam); void LogFailedEvent(eRvcRecordFailedCase eCase, const char* pszMessage, bool bRecordDevFault = false); void MediaSynchronous(); int WriteVideoFrame(); int WriteAudioFrame(); bool GetRecordAudioFrame(); bool GetSingleSideAudioFrame(); bool GetLocalAudioFrame(int iAudioLens); bool GetRemoteAudioFrame(int iAudioLens); bool ReSetRecordParams(); bool InitVideoRecordParams(); int HandleLeftAudioData(); bool AddMuteAudioFrame(bool bLocal, int iAudioFrameSize); bool InitDefaultAudioParams(audio_frame* paudio); bool ResetMediaQueue(); private: bool m_bStopRecord; eRvcRecordType m_eRecordType; //录制双向的视频类型,0:单向录制,1:坐席<->大机双录 eAudioOutPutType m_eAudioType; bool m_bIsAudioNsOn; //是否开启音频降噪功能开关 int m_iNsPolicy; //音频降噪等级 bool m_bIsAudioTransOn; //是否开始音频传输到识别服务器开关 int m_iAudioChannels; //录制音频通道数 bool m_bPauseRecord; bool m_bMuteAudio; int m_nFps; int m_videoquality; eVideoFormat m_eFormat; SubtitleParam m_SubtitleParam; bool m_bWholeSection; bool m_bSessionManage; /************************************************************************/ videoq_frame* m_videoframe; audio_frame* m_audioframe; Clibaudioqueue* m_audioqueue; Clibvideoqueue* m_env_videoqueue; Clibvideoqueue* m_opt_videoqueue; Clibvideoqueue* m_remote_videoqueue; //远端视频,用于双向录像 Clibaudioqueue* m_remote_audioqueue; //远端音频,用于双向录像 Clibaudioqueue* m_local_audioqueue; //本地音频 Clibaudioqueue* m_sales_audioqueue; //现场销售音频 #ifdef _WIN32 HANDLE m_hEventWait; // CreateEvent HANDLE m_hRecordThread; unsigned int m_nRecordthreadId; #else sem_t m_semt; pthread_t m_nRecordthreadId; #endif char m_audioqueuename[MAX_PATH]; char m_env_videoqueuename[MAX_PATH]; char m_opt_videoqueuename[MAX_PATH]; char m_salesaudioqueuename[MAX_PATH]; char m_remotevideoqueuename[MAX_PATH]; char m_remoteaudioqueuename[MAX_PATH]; char m_FileName[MAX_PATH]; char m_PathName[MAX_PATH]; char m_VideoFileName[MAX_PATH]; char m_VideoFomat[MAX_PATH]; bool* m_bResult; char* m_pRecordAudioBuffer; //音频录制拼接BUFFER int m_iRecordAudioBufSize; //音频拼接的缓冲区大小; FFmpegWriter* m_pFFmpegWriter; IAudioNs* m_pAudioNsObj; //audio noise suppression CvxText* m_pText; int m_iFileSerialNum; int m_iAudioFrameSize; //录制音频帧的大小 int m_iVideoFrameSize; //录制视频帧的大小 int m_iWidth; //录制视频帧的长度 int m_iHeight; //录制视频帧的高度 int m_iAudioPerSecBufLen; //每秒音频的长度 int m_iLocalAudioFps; //本地音频频率 int m_iRemoteAudioFps; //远端音频频率 char* m_pRemoteAudioBuffer; //远端音频BUFFER int m_iRecordedTime; //本段视频已录制时间 int m_iRemoteAudioNum; //远端音频数量 int m_iAudioFromQueNum; //从音频队列中取出的音频数量 int m_iRecordVideoNum; //已录制的视频帧数 int m_iRecordAudioNum ; //已录制的音频数 int m_iSubTitleTime; //本段视频添加字幕耗时 int m_iRemoteAudioBufLen; //远端音频拼接BUFFER的当前长度 int m_iAudioBufferLen; //音频录制拼接BUFFER的当前长度 int m_iRemoteVideoFailedTimes; //获取远端视频失败次数 bool m_bSwitchCam; //录制时是否切换摄像头 };