为什么游戏录屏和打开麦克风就不录屏了只能用一个

  之前一直用Directshow技术采集摄像头数据但是觉得涉及的细节比较多,要开发者比较了解Directshow的框架知识学习起来有一点点难度。最近发现很多人问怎么用FFmpeg采集摄像头图像事实仩FFmpeg很早就支持通过DShow获取采集设备(摄像头、打开麦克风就不录屏了)的数据了,只是网上提供的例子比较少如果能用FFmpeg实现采集、编码和錄制(或推流),那整个实现方案就简化很多正因为这个原因,我想尝试做一个FFmpeg采集摄像头视频和打开麦克风就不录屏了音频的程序經过一个星期的努力,终于做出来了我打算把开发的心得和经验分享给大家。我分三部分来讲述:首先第一部分介绍如何用FFmpeg的官方工具(/forum/viewtopic.php?t=722)如果读者运行下面的Demo遇到打开视频采集设备失败,可能也是这个问题引起的. 新版本的FFmpeg(avdevice-58)修复了这个问题。所以如果你遇到这个问题可以通过升级FFmpeg来解决。

  好关于命令行的内容就介绍完了。

  这个程序叫“AVCapture”能从视频采集设备(摄像头,采集卡)获取图像支持图潒预览;还可以采集打开麦克风就不录屏了音频;支持对视频和音频编码,支持录制成文件这是一个MFC开发的窗口程序,界面比较简洁洳下图:

   开始采集前需要选择设备,点击文件菜单的“打开设备”弹出一个设备选择对话框,如下图所示:

  在对话框里选择任意一个视頻设备和音频设备如果想启用某种设备,必须勾选右边的“启用”选项但如果只需要用其中一种采集设备,则可以把其中一个禁用掉

  按“确定”则开始采集数据了。视频和音频会编码后保存到一个文件中这个文件的路径是在配置文件中设置的,打开程序目录下的Config.ini文件则显示如下字段:

File_path就是录制文件的路径。

  采集的图像默认显示到中间的窗口中如果不想预览,可以在主菜单栏的“编辑”菜单中取消勾选“预览视频”

该采集程序实现了枚举采集设备,采集控制、显示图像、视频/音频编码和录制的功能其中输入(Input)、输出(Output)和顯示(Paint)这三个模块分别用一个单独的类进行封装:CAVInputStream,CAVOutputStreamCImagePainter。CAVInputStream负责从采集设备获取数据提供接口获取采集设备的属性,以及提供回调函数紦数据传给上层CAVOutputStream负责对采集的视频和音频流进行编码、封装,保存成一个文件而CImagePainter则用来显示图像,使用了GDI绘图把图像显示到主界面嘚窗口。

采集前我们需要先选择设备把所有的设备名称列出来,其中一个方法可以用第一节介绍的运行ffmpeg命令行工具来列举但是这样有兩个问题:第一,假如设备名称带中文则显示的名称有乱码,因此我们不知道它真实的名称。第二ffmpeg没有API返回系统中安装的采集设备列表,虽然FFmpeg提供了API把设备名称列举出来但是是打印到控制台的,不是通过参数来返回如下面这段代码只能打印输出结果到控制台。但昰对于窗口界面程序没有控制台,怎么获取命令行结果呢

 
我用了一种最传统的做法来解决,就是通过Directshow的COM接口来枚举设备工程里面的EnumDevice接口就实现了枚举设备的功能,函数原型如下:
//枚举指定类型的所有采集设备的名称
 
当然如果读者用的采集设备是固定一种,那么可以凅定采集设备的名称这样做可以省点事。





 
这两个API可以在程序的构造函数和窗口初始化里面调用





首先需要指定采集设备的名称。如果是視频设备类型则名称以“video=”开头;如果是音频设备类型,则名称以“audio=”开头调用avformat_open_input接口打开设备,将设备名称作为参数传进去注意这個设备名称需要转成UTF-8编码。然后调用avformat_find_stream_info获取流的信息得到视频流或音频流的索引号,之后会频繁用到这个索引号来定位视频和音频的Stream信息接着,调用avcodec_open2打开视频解码器或音频解码器实际上,我们可以把设备也看成是一般的文件源而文件一般采用某种封装格式,要播放出來需要进行解复用分离成裸流,然后对单独的视频流、音频流进行解码虽然采集出来的图像或音频都是未编码的,但是按照FFmpeg的常规处悝流程我们需要加上“解码”这个步骤。


 



前面我们已经初始化了InputStream现在需要对OutputStream进行初始化,而要初始化输出流需要知道视频采集的分辨率帧率,输出像素格式等信息还有音频采集设备的采样率,声道数Sample格式,而这些信息可通过CAVInputStream类的接口来获取到下面是初始化OutputStream的代碼:


 
在上面的代码片段中,首先设置了视频和音频的数据回调函数当采集开始时,视频和音频数据就会传递给相应的函数去处理在该程序中,回调函数主要对图像或音频进行编码然后封装成FFmpeg支持的容器(例如mkv/avi/mpg/ts/mp4)。另外需要初始化OutputStream的VideoCodec和AudioCodec的属性,在我的程序中视频编碼器是H264,音频编码器用AAC通过CAVInputStream对象获得输入流的信息之后再赋值给输出流相应的参数。最后调用m_OutputStream对象的OpenOutputStream成员函数打开编码器和录制的容器其中我们需要传入一个输出文件路径作为参数,这个为录制的文件路径路径是在Config.ini文件里配置的。如果OpenOutputStream函数返回true则表示初始化输出流荿功。





接着我们就可以开始采集了。开始采集的函数实现如下:


 
StartCapture函数分别建立了一个读取视频包和读取音频包的线程两个线程各自独竝工作,分别从视频采集设备音频采集设备获取到数据,然后进行后续的处理(注意:两个线程同时向一个文件写数据可能会有同步嘚问题,FFmpeg内部可能没有做多线程安全访问的处理所以最好在自己线程里加一个锁进行互斥,从而保护临界区的安全


其中读取摄像头數据的线程的处理代码如下:


 
在CAVInputStream::ReadVideoPackets()函数中不停地调用 av_read_frame读取采集到的图像帧,接着调用avcodec_decode_video2进行“解码”这样获得了原始的图像,图像可能是RGB或YUV格式解码后的图像通过m_pVideoCBFunc指向的回调函数回调给上层处理,回调函数里可进行后续的一些操作比如对视频帧编码或直接显示。


3.6 编码、封裝成文件


CAVInputStream的工作线程里面读取到的视频帧和音频包通过回调函数传给CAVOuputStream类去处理下面是两个回调函数的实现:


//采集到的视频图像回调
//采集箌的音频数据回调
 
视频回调函数调用了CAVOutputStream的成员函数write_video_frame,这个函数对传入的图像帧进行编码(H264)并且写到指定的封装文件;而音频回调函数則调用了CAVOutputStream的另外一个成员函数write_audio_frame,这个函数负责对音频编码(AAC)然后输出到指定的封装文件。下面是Write_video_frame函数的实现代码:


 
 
 
 
Write_video_frame和write_audio_frame是CAVOutputStream的两个很重要嘚函数其中对音频包的处理略为复杂一些,主要是因为输入的音频和编码后的音频的frame_size不一样中间需要一个Fifo作缓冲队列。另外时间戳PTS的計算也是很关键的弄得不好保存的文件播放视音频就不同步了,具体怎么实现你们看代码吧





补充说明:有些网友下载了工程反映例孓在Win7,Win10系统上运行不了这是因为枚举设备列表的EnumDevice.dll没有编译成Release版造成的,可以从我的另外一个里下载这个库的代码或已编译生成的DLL)


(洳果你觉得本文章写得不错,请点赞一下!)

玩王者荣耀录屏,游戏里和队友开着语音然后开始按键录屏,录完

该楼层疑似违规已被系统折叠 

玩迋者荣耀录屏游戏里和队友开着语音,然后开始按键录屏录完之后一点声音也没有,请问要怎么同时录制游戏里和队友说话的声音还偠打开麦克风就不录屏了声音呢


该楼层疑似违规已被系统折叠 

同求!开麦录屏就没声音


扫二维码下载贴吧客户端

EV录屏可以选择全屏、选区录制還支持添加水印,添加摄像头录制打开麦克风就不录屏了声音、系统声音、麦和系统声音以及不录音频,这样能实现各种组合或者只錄制视频或者音频
EV录屏还可以用来直播,支持所有基于rtmp协议的直播平台个性化设置,可同时流向多个直播平台

EV录屏还是款跨平台应用支持windows ,mac安卓三大平台,小编仅体验了windows与mac平台很好用

我要回帖

更多关于 打开麦克风就不录屏了 的文章

 

随机推荐