天天看點

EasyPlayerPro Windows播放器進行本地對講喊話音頻采集功能實作

需求

在安防行業應用中,除了在本地看到錄影機的視訊和進行音頻監聽外,還有一個重要的功能,那就是對講. EasyPlayerPro-win為了減輕二次開發者的工作量,将本地音頻采集也進行了內建;

功能特點

  • 支援擷取本地所有音頻輸入裝置清單;
  • 可任意選擇任一音頻輸入裝置;
  • 可設定采樣率和采樣精度及位率;
  • 可設定編碼格式(目前支援G711A,G711U,AAC);
EasyPlayerPro Windows播放器進行本地對講喊話音頻采集功能實作

實作流程

  1. 采用DirectSound8進行本地音頻采集;
  2. 将采集到的音頻資料寫入編碼隊列;
  3. 在編碼線程中擷取源始音頻資料,進行音頻編碼;
  4. 編碼完成後,将編碼資料回調給上層應用;
//擷取聲音采集裝置清單
    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 -;
    if (NULL == pSoundCaptureThread->pSupportWaveFormatEx)      return -;

    if (waveFormatExIndex<  || waveFormatExIndex>=pSoundCaptureThread->supportWaveFormatExCount)   return -;

    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( , _wfxInput->nAvgBytesPerSec /  );
    pSoundCaptureThread->dwNotifySize -= pSoundCaptureThread->dwNotifySize % _wfxInput->nBlockAlign;
    pSoundCaptureThread->dwCaptureBufferSize = pSoundCaptureThread->dwNotifySize * ;

    dscbd.dwSize        = sizeof(DSCBUFFERDESC);
    dscbd.dwBufferBytes = pSoundCaptureThread->dwCaptureBufferSize;
    dscbd.lpwfxFormat   = _wfxInput;
    hr = pSoundCaptureThread->lpDirectSoundCapture8->CreateCaptureBuffer( &dscbd, &pSoundCaptureThread->lpDSBCapture, NULL);

    if (FAILED(hr))                                 return -;
    if (NULL == pSoundCaptureThread->lpDSBCapture)  return -;

    pSoundCaptureThread->dwNextCaptureOffset = ;

    hr = pSoundCaptureThread->lpDSBCapture->QueryInterface( IID_IDirectSoundNotify, (PVOID*)&pSoundCaptureThread->lpDSNotify );
    for( INT i = ; i < ; i++ ) 
    {
        pSoundCaptureThread->DSBPosNotify[i].dwOffset     = (pSoundCaptureThread->dwNotifySize * i) + pSoundCaptureThread->dwNotifySize - ;
        pSoundCaptureThread->DSBPosNotify[i].hEventNotify = pSoundCaptureThread->hCaptureNotifyEvent;
    }
    hr = pSoundCaptureThread->lpDSNotify->SetNotificationPositions( , pSoundCaptureThread->DSBPosNotify);

    hr = pSoundCaptureThread->lpDSBCapture->Start( DSCBSTART_LOOPING );
    //m_fIsCapture = TRUE;

    if (SUCCEEDED(hr))
    {
        if (NULL == pSoundCaptureThread->hCaptureNotifyThread)
        {
            pSoundCaptureThread->flag = ;
            pSoundCaptureThread->userPtr = this;
            pSoundCaptureThread->captureCallback = callback;
            pSoundCaptureThread->callbackUserPtr = userptr;
            pSoundCaptureThread->hCaptureNotifyThread = CreateThread(NULL, , (LPTHREAD_START_ROUTINE)_lpDirectSoundCaptureThread, 
                pSoundCaptureThread, , NULL);
            while (pSoundCaptureThread->flag!= && pSoundCaptureThread->flag!=)  {Sleep();}
        }
    }

    return hr;
    }


    //擷取源始音頻資料
    int DirectSoundCapturer::ProcessCaptureData()
    {
    HRESULT hrRet = ;
    LONG    lLockSize;

    if (NULL == pSoundCaptureThread)            return -;
    if (pSoundCaptureThread->flag == )      return -;
    if (NULL == pSoundCaptureThread->lpDSBCapture)  return -;

    do {

        DWORD   dwCapturePos, dwReadPos;
        hrRet = pSoundCaptureThread->lpDSBCapture->GetCurrentPosition( &dwCapturePos, &dwReadPos );

        lLockSize = dwReadPos - pSoundCaptureThread->dwNextCaptureOffset;
        if( lLockSize <  ) lLockSize += pSoundCaptureThread->dwCaptureBufferSize;

        // Block align lock size so that we are always write on a boundary
        lLockSize -= (lLockSize % pSoundCaptureThread->dwNotifySize);
        if( lLockSize ==  ) {
            hrRet = -;
            break;
        }

        PVOID   pCapturedData[]   = {NULL, NULL};
        DWORD   dwCaptureLength[] = {, };

        // Lock the capture buffer down
        hrRet = pSoundCaptureThread->lpDSBCapture->Lock( pSoundCaptureThread->dwNextCaptureOffset,
                                     lLockSize, 
                                     &pCapturedData[],
                                     &dwCaptureLength[],
                                     &pCapturedData[],
                                     &dwCaptureLength[], L );
        if( FAILED( hrRet ) ) {
            hrRet = -;
            break;
        }

        if (NULL != pSoundCaptureThread->captureCallback)
        {
            pSoundCaptureThread->captureCallback(&pSoundCaptureThread->inWaveFormatEx, pSoundCaptureThread->callbackUserPtr,
                (unsigned char *)pCapturedData[], (int)dwCaptureLength[], (unsigned char *)pCapturedData[], (int)dwCaptureLength[]);
        }

        pSoundCaptureThread->dwNextCaptureOffset += dwCaptureLength[];
        pSoundCaptureThread->dwNextCaptureOffset %= pSoundCaptureThread->dwCaptureBufferSize;       // Circular buffer

        if( pCapturedData[] != NULL ) {
            pSoundCaptureThread->dwNextCaptureOffset += dwCaptureLength[];
            pSoundCaptureThread->dwNextCaptureOffset %= pSoundCaptureThread->dwCaptureBufferSize; // Circular buffer
        }

        pSoundCaptureThread->lpDSBCapture->Unlock( pCapturedData[], dwCaptureLength[],
                               pCapturedData[], dwCaptureLength[] );
    } while();

    return hrRet;
    }
           

關于EasyPlayerPro播放器

EasyPlayerPro是一款全功能的流媒體播放器,支援RTSP、RTMP、HTTP、HLS、UDP、RTP、File等多種流媒體協定播放、支援本地檔案播放,支援本地抓拍、本地錄像、播放旋轉、多屏播放、倍數播放等多種功能特性,核心基于ffmpeg,穩定、高效、可靠、可控,支援Windows、Android、iOS三個平台,目前在多家教育、安防、行業型公司,都得到的應用,廣受好評!

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

點選連結加入群【EasyPlayer & EasyPlayerPro】:544917793

技術支援

  • 郵件:[email protected]
  • QQ交流群:544917793

擷取更多資訊

EasyDarwin開源流媒體伺服器:www.EasyDarwin.org

EasyDSS商用流媒體解決方案:www.EasyDSS.com

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

Copyright © EasyDarwin Team 2012-2017

EasyPlayerPro Windows播放器進行本地對講喊話音頻采集功能實作

繼續閱讀