利用FFmpeg本地音频和网络视频进行录像

avformat_open_input      最近公司在做法院项目,需要将相机的画面和本地法官说话的声音整合到一个录像文件中,为此,专门收集了不少资料。决定用FFmpeg+winapi采集音频+sdl播放

 

      首先FFmpeg,是一款开源的音视频算法库,可以实现打开本地和网络资源、解码、编码、存储等一系列操作。

一、FFMPEG的工作流程

二、winapi采集音频

        Windows自带的API函数waveInOpen打开音频采集

WAVEFORMATEX waveform;

waveform.wFormatTag = WAVE_FORMAT_PCM;//声音格式为PCM 
 waveform.nSamplesPerSec = AUDIO_SAMP_RATE;//采样率,16000次/秒 
 waveform.wBitsPerSample = AUDIO_SAMP_BIT;//采样比特,16bits/次 
 waveform.nChannels = AUDIO_CHANNEL;//采样声道数,2声道 
 waveform.nAvgBytesPerSec = AUDIO_SAMP_RATE* AUDIO_SAMP_BIT *AUDIO_CHANNEL / 8;//每秒的数据率,就是每秒能采集多少字节的数据 
 waveform.nBlockAlign = AUDIO_SAMP_BIT*AUDIO_CHANNEL / 8;//一个块的大小,采样bit的字节数乘以声道数 
 waveform.cbSize = 0;//一般为0 

 //使用waveInOpen函数开启音频采集 
 if (MMSYSERR_NOERROR  != waveInOpen(&hWaveIn, 0, &waveform, (DWORD)(DeviceAudioCallback), DWORD(this), CALLBACK_FUNCTION))
 {
  return FALSE;
 }

       设置采集声音需要的缓冲区

DWORD bufsize = m_nAudioFrmSize;//AUDIO_SAMP_RATE/AUDIO_DEVICE_SAMP_CNT_PER_SECOND;
 pBuffer1 = (BYTE*)malloc(bufsize);
 pBuffer2 = (BYTE*)malloc(bufsize);

 wHdr1.lpData = (LPSTR)pBuffer1;
 wHdr1.dwBufferLength = bufsize;
 wHdr1.dwBytesRecorded = 0;
 wHdr1.dwUser = 0;
 wHdr1.dwFlags = 0;
 wHdr1.dwLoops = 1;
 wHdr1.lpNext = NULL;
 wHdr1.reserved = 0;
 //将建立好的wHdr1做为备用 
 waveInPrepareHeader(hWaveIn, &wHdr1, sizeof(WAVEHDR));

   这里的bufsize可以根据自己的需要进行设定,当声音采集调节dwBytesRecorded=dwBufferLength后,回调函数返回。也就是说当收集的声音将缓冲区填满后返回。    

  开始声音采集:waveInStart

收到声音后回调函数

DWORD WINAPI CRecordRtspAndMicrophone::DeviceAudioCallback(HWAVEIN hwavein, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
{
 
 CRecordRtspAndMicrophone *pDlg = (CRecordRtspAndMicrophone*)dwInstance;
 if (NULL == pDlg) return FALSE;
 int re(0)
  ;
 switch (uMsg)
 {
  case WIM_OPEN:
   break;
  case WIM_DATA:
   pDlg->InputAudioData((PWAVEHDR)dwParam1);
   waveInAddBuffer(hwavein, (PWAVEHDR)dwParam1, sizeof (WAVEHDR));
   break;
  case WIM_CLOSE:
   break;
  default:
   break;
 }
 return 0;
}

当数据为WIM_DATA的时候 可以将PCM声音送入到共享缓冲区中

三、SDL播放实时视频

      收到图像包---->解码---->显示

      为了将SDL窗口绑定到目标窗口中,可以调用SDL_putenv设置与窗口绑定

  char sdl_var[64];
  sprintf(sdl_var, "SDL_WINDOWID=%d",m_hWnd);//主窗口句柄  
  SDL_putenv(sdl_var);

SDL_putenv------>SDL_Init-

SDL_SetVideoMode---创建一个窗口

SDL_CreateYUVOverlay--创建一个图像空间

SDL_DisplayYUVOverlay--显示图像空间

   在这个过程中需要用到缩放 缩放函数为sws_scale

具体每个环节的讲解 我会上传到空间



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值