实现语音视频录制(demo源码)

系统 1555 0

在很多语音视频软件系统中,经常有将实时的音频或视频录制为文件保存到磁盘的需求,比如,视频监控系统中录制监控到的视频、视频会议系统中录制整个会议的过程、语音通话系统中录制完整的对话内容、等等。 

一.缘起

最近正在做的一个网络招聘平台的项目,其中有一个模块是这样的,应聘者可以通过该系统的客户端录制自己的视频(自我介绍)上传到服务器,而后,招聘者会在合适的时候浏览这些应聘者的视频。该模块涉及到的主要技术就是语音视频录制技术,它需要把从麦克风采集到的语音数据和从摄像头采集到的视频数据编码并写到.mp4文件中。要完成这些功能,具体来说,需要解决如下几个技术问题:

(1)麦克风数据采集

(2)摄像头数据采集

(3)音频数据编码

(4)视频数据编码

(5)将编码后的数据按.mp4文件格式写入到文件容器中。

(6)保证音频视频播放的同步。

二.Demo实现

如果要从头开始一步步解决这些问题,将是非常艰难的挑战。幸运的是,我们可以通过已有组件的组合来实现这些功能,语音视频数据的采集我们可以借助 OMCS 框架完成,后续的语音视频编码并生成mp4文件,我们可以借助 MFile 组件完成。为了更方便地讲解,这里我们将给出一个具体的demo,它可以录制从本地摄像头和本地麦克风采集的数据并生成mp4文件。demo运行的截图如下所示:

实现语音视频录制(demo源码)

接下来,我们来说说在这个demo中是如何一个个解决上述问题的。

1.语音数据采集

我们可以使用OMCS的MicrophoneConnector组件连接到自己的麦克风设备,这样,扬声器就会播放采集到的语音,而且,我们可以通过通过IMultimediaManager暴露的AudioPlayed事件,来捕获正在播放的语音数据。

2.视频数据采集

同样的,我们可以使用CameraConnector控件连接到自己的摄像头设备,然后,定时器每隔100ms(假设帧频为10fps)调用其GetCurrentImage方法获得正在绘制的Bitmap。

3.后续步骤

后续的4步都可以交由MFile组件搞定,我们大概看一下MFile组件中VideoFileMaker类的签名,就知道怎么做了:

      
        
           public
        
        
          class
        
        
          
             VideoFileMaker
          
           :
          
            IDisposable
          
           { 
        
        
          ///
        
        
          <summary>
        
        
          ///
        
        
           初始化视频文件。 
        
        
          ///
        
        
          </summary>
        
        
          ///
        
        
          <param name="filePath">
        
        
          文件路径
        
        
          </param>
        
        
          ///
        
        
          <param name="videoCodec">
        
        
          视频编码格式
        
        
          </param>
        
        
          ///
        
        
          <param name="videoWidth">
        
        
          视频宽度
        
        
          </param>
        
        
          ///
        
        
          <param name="videoHeight">
        
        
          视频高度
        
        
          </param>
        
        
          ///
        
        
          <param name="videoFrameRate">
        
        
          帧频
        
        
          </param>
        
        
          ///
        
        
          <param name="audioCodec">
        
        
          音频编码格式
        
        
          </param>
        
        
          ///
        
        
          <param name="audioSampleRate">
        
        
          音频采样率。【注:采样位数必须为16位】
        
        
          </param>
        
        
          ///
        
        
          <param name="audioChannelCount">
        
        
          声道数
        
        
          </param>
        
        
          ///
        
        
          <param name="autoSyncToAudio">
        
        
          如果是实时录制,则可传入true,以音频为基准进行同步。
        
        
          </param>
        
        
          void
        
         Initialize(
        
          string
        
         filePath, 
        
          VideoCodecType
        
         videoCodec, 
        
          int
        
         videoWidth, 
        
          int
        
         videoHeight, 
        
          int
        
         videoFrameRate, 
        
          AudioCodecType
        
         audioCodec, 
                        
        
          int
        
         audioSampleRate, 
        
          int
        
         audioChannelCount, 
        
          bool
        
        
           autoSyncToAudio); 
        
        
          ///
        
        
          <summary>
        
        
          ///
        
        
           添加音频帧。 
        
        
          ///
        
        
          </summary>
        
        
          void
        
         AddAudioFrame(
        
          byte
        
        
          [] audioframe); 
        
        
          ///
        
        
          <summary>
        
        
          ///
        
        
           添加视频帧。如果autoSyncToAudio开启,则自动同步到音频。 
        
        
          ///
        
        
          </summary>
        
        
          void
        
        
           AddVideoFrame(
          
            Bitmap
          
           frame); 
        
        
          ///
        
        
          <summary>
        
        
          ///
        
        
           添加视频帧。 
        
        
          ///
        
        
          </summary>
        
        
          ///
        
        
          <param name="frame">
        
        
          视频帧
        
        
          </param>
        
        
          ///
        
        
          <param name="timeStamp">
        
        
          离开始时的时间长度
        
        
          </param>
        
        
          void
        
        
           AddVideoFrame(
          
            Bitmap
          
           frame, TimeSpan timeStamp); 
        
        
          ///
        
        
          <summary>
        
        
          ///
        
        
           关闭视频文件。 
        
        
          ///
        
        
          </summary>
        
        
          ///
        
        
          <param name="waitFinished">
        
        
          如果还有帧等待写入文件,是否等待它们全部写入文件。
        
        
          </param>
        
        
          void
        
         Close(
        
          bool
        
        
           waitFinished); }
        
      
    

首先调用Initialize方法完成初始化,然后,循环调用AddAudioFrame和AddVideoFrame方法,当完成视频录制时,则调用Close方法,即可。很简单,不是吗?

4.主要代码

首先,我们以aa01用户登录到OMCS服务器,然后,在拖拽一个CameraConnector控件和一个MicrophoneConnector组件到主窗体上,然后,让它们都连到自己的摄像头和麦克风。

      
        
          this
        
        .multimediaManager =
        
          
             MultimediaManagerFactory
          
          .GetSingleton(); 
        
        
          this
        
        .multimediaManager.Initialize(
        
          "
        
        
          aa01
        
        
          "
        
        , 
        
          ""
        
        , 
        
          "
        
        
          127.0.0.1
        
        
          "
        
        , 
        
          9900
        
        
          ); 
        
        
           this
        
        .cameraConnector1.BeginConnect(
        
          "
        
        
          aa01
        
        
          "
        
        
          ); 
        
        
          this
        
        .microphoneConnector1.BeginConnect(
        
          "
        
        
          aa01
        
        
          "
        
        );
      
    

接下来,我们初始化VideoFileMaker组件:

      
        this
      
      .videoFileMaker.Initialize(
      
        "
      
      
        test.mp4
      
      
        "
      
      , 
      
        VideoCodecType
      
      .H264, 
      
        this
      
      .multimediaManager.CameraVideoSize.Width, 
      
        this
      
      .multimediaManager.CameraVideoSize.Height, 
      
        10
      
      , 
      
        AudioCodecType
      
      .AAC, 
      
        16000
      
      , 
      
        1
      
      , 
      
        true
      
      
        );
 
      
      
        this
      
      .timer = 
      
        new
      
       System.Threading.Timer(
      
        new
      
       System.Threading.
      
        TimerCallback
      
      (
      
        this
      
      .Callback), 
      
        null
      
       ,
      
        0
      
      , 
      
        100
      
      
        );
 
      
      
        this
      
      .multimediaManager.AudioPlayed += 
      
        new
      
       ESBasic.
      
        CbGeneric
      
      <
      
        byte
      
      []>(multimediaManager_AudioPlayed);         
    

参数中设定,使用h.264对视频进行编码,使用aac对音频进行编码,并生成mp4格式的文件。然后,我们可以通过OMCS获取实时的音频数据和视频数据,并将它们写到文件中。

      
        
           void
        
         multimediaManager_AudioPlayed(
        
          byte
        
        
          [] audio) { 
        
        
          this
        
        
          .videoFileMaker.AddAudioFrame(audio); } 
        
        
          private
        
        
          void
        
         Callback(
        
          object
        
        
           state) { 
          
            Bitmap
          
           bm 
        
        = 
        
          this
        
        
          .cameraConnector1.GetCurrentImage(); 
        
        
          this
        
        
          .videoFileMaker.AddVideoFrame(bm); }
        
      
    

当想结束录制时,则调用Close方法:

      
        
          this
        
        .videoFileMaker.Close(
        
          true
        
        );
      
    

这样录制生成的test.mp4文件就可以直接用我们的QQ影音或暴风影音来播放了。

更多细节,请查看demo源码。

三.Demo下载

Demo源码: VideoRecordDemo.rar

实现语音视频录制(demo源码)


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论