EasyPlayerPro-win本地音频采集实现

来源:互联网 发布:培训机构网络推广方案 编辑:程序博客网 时间:2024/05/23 14:21

EasyPlayerPro-win本地音频采集实现

需求

在安防行业应用中,除了在本地看到摄像机的视频和进行音频监听外,还有一个重要的功能,那就是对讲. EasyPlayerPro-win为了减轻二次开发者的工作量,将本地音频采集也进行了集成.

功能特点

支持获取本地所有音频输入设备列表;
可任意选择任一音频输入设备;
可设置采样率和采样精度及位率;
可设置编码格式(当前支持G711A,G711U,AAC);

这里写图片描述

实现流程

采用DirectSound8进行本地音频采集;
将采集到的音频数据写入编码队列;
在编码线程中获取源始音频数据,进行音频编码;
编码完成后,将编码数据回调给上层应用;

//获取声音采集设备列表int     GetAudioCaptureDeviceList(int *num, SOUND_CAPTURE_DEVICE_INFO **pDeviceInfo);int     OpenAudioCaptureDevice(int captureDeviceIndex);int     GetSupportWaveFormatList(int *num, WAVEFORMATEX **ppWaveFormatEx);int     StartCapture(int waveFormatExIndex, DirectSoundCaptureCallback callback, void *userptr);int     StopCapture();void    CloseAudioCaptureDevice();static LPTHREAD_START_ROUTINE __stdcall _lpDirectSoundCaptureThread ( LPVOID _pParam );

代码实现

//开始采集音频int     DirectSoundCapturer::StartCapture(int waveFormatExIndex, DirectSoundCaptureCallback callback, void *userptr){if (NULL == pSoundCaptureThread)        return -1;if (NULL == pSoundCaptureThread->pSupportWaveFormatEx)      return -1;if (waveFormatExIndex< 0 || waveFormatExIndex>=pSoundCaptureThread->supportWaveFormatExCount)   return -2;HRESULT hr = S_OK;WAVEFORMATEX *_wfxInput = (WAVEFORMATEX*)&pSoundCaptureThread->pSupportWaveFormatEx[waveFormatExIndex];memcpy(&pSoundCaptureThread->inWaveFormatEx, _wfxInput, sizeof(WAVEFORMATEX));DSCBUFFERDESC   dscbd;ZeroMemory( &dscbd, sizeof(DSCBUFFERDESC) );pSoundCaptureThread->dwNotifySize  = max( 1024, _wfxInput->nAvgBytesPerSec / 8 );pSoundCaptureThread->dwNotifySize -= pSoundCaptureThread->dwNotifySize % _wfxInput->nBlockAlign;pSoundCaptureThread->dwCaptureBufferSize = pSoundCaptureThread->dwNotifySize * 16;dscbd.dwSize        = sizeof(DSCBUFFERDESC);dscbd.dwBufferBytes = pSoundCaptureThread->dwCaptureBufferSize;dscbd.lpwfxFormat   = _wfxInput;hr = pSoundCaptureThread->lpDirectSoundCapture8->CreateCaptureBuffer( &dscbd, &pSoundCaptureThread->lpDSBCapture, NULL);if (FAILED(hr))                                 return -3;if (NULL == pSoundCaptureThread->lpDSBCapture)  return -4;pSoundCaptureThread->dwNextCaptureOffset = 0;hr = pSoundCaptureThread->lpDSBCapture->QueryInterface( IID_IDirectSoundNotify, (PVOID*)&pSoundCaptureThread->lpDSNotify );for( INT i = 0; i < 16; i++ ) {    pSoundCaptureThread->DSBPosNotify[i].dwOffset     = (pSoundCaptureThread->dwNotifySize * i) + pSoundCaptureThread->dwNotifySize - 1;    pSoundCaptureThread->DSBPosNotify[i].hEventNotify = pSoundCaptureThread->hCaptureNotifyEvent;}hr = pSoundCaptureThread->lpDSNotify->SetNotificationPositions( 16, pSoundCaptureThread->DSBPosNotify);hr = pSoundCaptureThread->lpDSBCapture->Start( DSCBSTART_LOOPING );//m_fIsCapture = TRUE;if (SUCCEEDED(hr)){    if (NULL == pSoundCaptureThread->hCaptureNotifyThread)    {        pSoundCaptureThread->flag = 0x01;        pSoundCaptureThread->userPtr = this;        pSoundCaptureThread->captureCallback = callback;        pSoundCaptureThread->callbackUserPtr = userptr;        pSoundCaptureThread->hCaptureNotifyThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)_lpDirectSoundCaptureThread,             pSoundCaptureThread, 0, NULL);        while (pSoundCaptureThread->flag!=0x02 && pSoundCaptureThread->flag!=0x00)  {Sleep(100);}    }}return hr;}//获取源始音频数据int DirectSoundCapturer::ProcessCaptureData(){HRESULT hrRet = 0;LONG    lLockSize;if (NULL == pSoundCaptureThread)            return -1;if (pSoundCaptureThread->flag == 0x03)      return -1;if (NULL == pSoundCaptureThread->lpDSBCapture)  return -1;do {    DWORD   dwCapturePos, dwReadPos;    hrRet = pSoundCaptureThread->lpDSBCapture->GetCurrentPosition( &dwCapturePos, &dwReadPos );    lLockSize = dwReadPos - pSoundCaptureThread->dwNextCaptureOffset;    if( lLockSize < 0 ) lLockSize += pSoundCaptureThread->dwCaptureBufferSize;    // Block align lock size so that we are always write on a boundary    lLockSize -= (lLockSize % pSoundCaptureThread->dwNotifySize);    if( lLockSize == 0 ) {        hrRet = -1;        break;    }    PVOID   pCapturedData[2]   = {NULL, NULL};    DWORD   dwCaptureLength[2] = {0, 0};    // Lock the capture buffer down    hrRet = pSoundCaptureThread->lpDSBCapture->Lock( pSoundCaptureThread->dwNextCaptureOffset,                                 lLockSize,                                  &pCapturedData[0],                                 &dwCaptureLength[0],                                 &pCapturedData[1],                                 &dwCaptureLength[1], 0L );    if( FAILED( hrRet ) ) {        hrRet = -2;        break;    }    if (NULL != pSoundCaptureThread->captureCallback)    {        pSoundCaptureThread->captureCallback(&pSoundCaptureThread->inWaveFormatEx, pSoundCaptureThread->callbackUserPtr,            (unsigned char *)pCapturedData[0], (int)dwCaptureLength[0], (unsigned char *)pCapturedData[1], (int)dwCaptureLength[1]);    }    pSoundCaptureThread->dwNextCaptureOffset += dwCaptureLength[0];    pSoundCaptureThread->dwNextCaptureOffset %= pSoundCaptureThread->dwCaptureBufferSize;       // Circular buffer    if( pCapturedData[1] != NULL ) {        pSoundCaptureThread->dwNextCaptureOffset += dwCaptureLength[1];        pSoundCaptureThread->dwNextCaptureOffset %= pSoundCaptureThread->dwCaptureBufferSize; // Circular buffer    }    pSoundCaptureThread->lpDSBCapture->Unlock( pCapturedData[0], dwCaptureLength[0],                           pCapturedData[1], dwCaptureLength[1] );} while(0);return hrRet;}

关于EasyPlayerPro

EasyPlayerPro是一款全功能的流媒体播放器,支持RTSP、RTMP、HTTP、HLS、UDP、RTP、File等多种流媒体协议播放、支持本地文件播放,支持本地抓拍、本地录像、播放旋转、多屏播放、倍数播放等多种功能特性,核心基于ffmpeg,稳定、高效、可靠、可控,支持Windows、Android、iOS三个平台,目前在多家教育、安防、行业型公司,都得到的应用,广受好评!

EasyPlayerPro:https://github.com/EasyDSS/EasyPlayerPro

点击链接加入群【EasyPlayer & EasyPlayerPro】:544917793

技术支持

  • 邮件:support@easydarwin.org

  • QQ交流群:544917793

EasyPlayerPro是一款非常稳定的全协议/全功能播放器组件,可以通过以上渠道进行更深入的技术与合作咨询;

获取更多信息

EasyDarwin开源流媒体服务器:www.EasyDarwin.org

EasyDSS商用流媒体解决方案:www.EasyDSS.com

EasyNVR无插件直播方案:www.EasyNVR.com

Copyright © EasyDarwin Team 2012-2017

EasyDarwin

阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 高铁追尾 名门二婚追尾总裁全文阅读 温州动车追尾 高速追尾都是后车全责吗 追尾图片 安徽高速多车追尾 京沪高速卡车追尾致6死7伤 卡车司机慧姐追尾死亡 追影 追影索凶 女总裁的全能高手 追影 追忆 国庆追忆 追忆贝壳 往事追忆 追忆逍遥 追忆的贝壳 追忆天空 追忆歌曲 追忆歌词 追忆的意思 追忆的英文 追忆图片 歌曲追忆 此情可待成追忆 此情可待成追忆可是什么意思 fgo追忆的贝壳 此情可待成追忆下一句 追忆逝水年华 此情只待成追忆 追忆什么意思 追忆的近义词 追忆是什么意思 追憶 追悔莫及 追悔 追悔莫及的意思 前任渣了我之后都追悔莫及 追悼词父亲 母亲追悼词 追悼读音