Skip to content

Latest commit

 

History

History
14 lines (7 loc) · 2.57 KB

Qt-C++音视频开发.md

File metadata and controls

14 lines (7 loc) · 2.57 KB

Qt/C++音视频开发81-采集本地麦克风/本地摄像头带麦克风/桌面采集和麦克风/本地设备和桌面推流

一、前言

随着直播的兴起,采集本地摄像头和麦克风进行直播推流,也是一个刚需,最简单的做法是直接用 FFmepg 命令行采集并推流,这种方式简单粗暴,但是不能实时预览画面,而且不方便加上一些特殊要求。之前就已经打通了音视频文件和视频流的采集,那是不是可以简单点的方式就能直接加入到原有的框架中呢,答案是可以的,经过一段时间的摸索,发现只要新增少量十几行的代码就行,一个是设置 avformat_open_input() 的第三个参数,指定采集本地设备,一个是设置本地设备的文件名。在 Windows 上,桌面是 gdigrab,本地摄像头和麦克风是 DirectShow。在 Linux 上,桌面是 x11grab,本地摄像头是 v4l2,本地麦克风是 alsa 。网上类似的代码也很多,这里只讲两点。

第一点,最初在同时打开本地摄像头和麦克风的时候,发现声音总是不正常,尽管深知这种思路肯定是对的,还总在转换声音那边下手,死活都不行。就在即将放弃此方案的时候,找遍了网络找相关资料,发现要通过 av_dict_set(options, "audio_buffer_size", "40", 0); 设置一个叫 audio_buffer_size 的参数值,默认这个值很大,导致声音延迟和缓存很大,所以声音画面不同步,把这个值设置小一点,性能相当好,简直完美。

第二点,在使用采集摄像头和麦肯风同步保存到 MP4 文件或者推流的时候,发现一个现象,随着时间的推移,音视频慢慢的不同步,音频延迟越来越大,几分钟内还是正常的,时间到了十分钟以后,慢慢的延迟会越来越大。后面发现,在调用 av_interleaved_write_frame() 函数写入数据的时候,这个函数默认会缓存,改为缓存 av_write_frame() 直接立即写入,就再也没有发生过这个问题,连续测试几天稳得一批。为了尽量提高实时性,目前的方案是直接采集到就解码并编码立即推流,音视频都是,先不做同步,通过 audio_buffer_size 参数的设置以及改成 av_write_frame() 来写入,能够将实时性做到极致。如果使用 FFmepg 命令行,无论如何设置参数,都做不到这个实时性。

x. 参考文章