最近项目中需要使用ffmpeg实现录音功能,使用的ffmpeg-3.4.4的库,根据源代码dshow.c中的定义

{ "audio_device_number", "set audio device number for devices with same name (starts at 0)", OFFSET(audio_device_number), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, DEC },

在PC机存在两个麦克风设备的场合,添加一个[录音设备选择]对话框,可供用户选择。

打个比方:目前的PC机存在两个音频输入设备:

  • 0:麦克风 (HD Webcam C270)
  • 1:麦克风 (Realtek High Definition Audio)

备注:

  • 0号采集设备可以采集音频与视频,不能播放音频;1号采集设备仅可以采集音频,可以播放音频。
  • PC机设备播放设备只有1个,那就是:麦克风 (Realtek High Definition Audio),即为0号播放设备。
  • 音频采集设备的序号与音频播放设备的序号很可能不一致。

如果指定 0号采集设备:麦克风 (HD Webcam C270)作为音频采集设备,简化代码如下:

char *pchDeviceName = "麦克风 (HD Webcam C270)";
AVInputFormat *m_pAudioInputFormat = av_find_input_format("dshow");
AVDictionary *options = NULL;
av_dict_set(&options, "audio_device_number", "", );
char str_device_gb2312_name[];
_snprintf(str_device_gb2312_name, sizeof(str_device_gb2312_name), "audio=%s", pchDeviceName);
char *pchUtfName = gb2312_to_utf8(str_device_gb2312_name);
int ret = -;
AVFormatContext *m_pAudioFmtCtx = avformat_alloc_context();
ret = avformat_open_input(&m_pAudioFmtCtx, pchUtfName, m_pAudioInputFormat, &options);

这时avformat_open_input函数成功,推测是因为0号音频采集设备与0号音频播放设备都存在所致。

如果指定 1号采集设备:麦克风 (Realtek High Definition Audio)作为音频采集设备,简化代码如下:

char *pchDeviceName = "麦克风 (Realtek High Definition Audio)";
AVInputFormat *m_pAudioInputFormat = av_find_input_format("dshow");
AVDictionary *options = NULL;
av_dict_set(&options, "audio_device_number", "", );
char str_device_gb2312_name[];
_snprintf(str_device_gb2312_name, sizeof(str_device_gb2312_name), "audio=%s", pchDeviceName);
char *pchUtfName = gb2312_to_utf8(str_device_gb2312_name);
int ret = -;
AVFormatContext *m_pAudioFmtCtx = avformat_alloc_context();
ret = avformat_open_input(&m_pAudioFmtCtx, pchUtfName, m_pAudioInputFormat, &options);

这时avformat_open_input函数失败原因是I/O fail,推测是因为1号音频采集设备存在但0号音频播放设备不存在所致。

此时的ffmpeg日志如下:

2019-12-10 13:57:21 076[ERR] Could not find audio only device with name [麦克风 (Realtek High Definition Audio)] among source devices of type audio.
2019-12-10 13:57:21 077[INF] Searching for audio device within video devices for 麦克风 (Realtek High Definition Audio)
2019-12-10 13:57:21 090[ERR] Could not find audio only device with name [麦克风 (Realtek High Definition Audio)] among source devices of type video.

  

解决方法如下(不指定音频设备序号,仅仅指定音频设备名称):

char *pchDeviceName = "麦克风 (Realtek High Definition Audio)";
AVInputFormat *m_pAudioInputFormat = av_find_input_format("dshow");
AVDictionary *options = NULL;
char str_device_gb2312_name[];
_snprintf(str_device_gb2312_name, sizeof(str_device_gb2312_name), "audio=%s", pchDeviceName);
char *pchUtfName = gb2312_to_utf8(str_device_gb2312_name);
int ret = -;
AVFormatContext *m_pAudioFmtCtx = avformat_alloc_context();
ret = avformat_open_input(&m_pAudioFmtCtx, pchUtfName, m_pAudioInputFormat, &options);

不要轻易使用ffmpeg的audio_device_number来设置音频设备的更多相关文章

  1. ffmpeg转码参数设置

    ffmpeg用了很久了,也没有想写点什么. 刚接触ffmpeg也是有大量的不理解的地方,不过慢慢的了解多了基本上都是可以使用的. 本文主要介绍如何使用ffmpeg.exe进行转码.编译好的ffmpeg ...

  2. ffmpeg 速查手册

    ref : http://linux.51yip.com/search/ffmpeg ffmpeg是一个源于Linux的工具软件,是FLV视频转换器,可以轻易地实现FLV向其它格式avi.asf. m ...

  3. [FFmpeg] ffmpeg参数详解

    ffmpeg 参数语法 ffmpeg [[options][`-i' input_file]]... {[options] output_file}... 如果没有输入文件,那么视音频捕捉就会起作用. ...

  4. FFMPEG解码流程

    FFMPEG解码流程:  1. 注册所有容器格式和CODEC: av_register_all()  2. 打开文件: av_open_input_file()  3. 从文件中提取流信息: av_f ...

  5. 【转】ffmpeg参数中文详细解释

    感谢“大神”的无私奉献:http://blog.csdn.net/leixiaohua1020/article/details/15811977 a) 通用选项 -L license-h 帮助-fro ...

  6. ffmpeg视频格式转换(Java)

    命令: 高品质: ffmpeg -i E:\input\a.wmv -ab 128 -acodec libmp3lame -ac 1 -ar 22050 -r 29.97 -qscale 4 -y E ...

  7. c# ffmpeg常用参数

    c#  ffmpeg常用参数 转换文件格式的同时抓缩微图: ffmpeg -i "test.avi" -y -f image2 -ss 8 -t 0.001 -s 350x240 ...

  8. ffmpeg命令学习

    1.组成 程序:ffmpeg.ffplay.ffprobe.ffserverffmpeg:转码程序ffplay:播放程序ffserver:服务器程序 库:libavcodec.libavdevice. ...

  9. FFmpeg介绍及参数详细说明

    FFmpeg是一个开源免费跨平台的视频和音频流方案,属于自由软件,采用LGPL或GPL许可证(依据你选择的组件).它提供了录制.转换以及流化音视频的完整解决方案.它包含了非常先进的音频/视频编解码库l ...

随机推荐

  1. Redis:RedisHelper(5)

    /// <summary> /// Redis 助手 /// </summary> public class RedisHelper { /// <summary> ...

  2. CDialog::DoModal()问题和_WIN32_WINNT

    1.从CDialogEx派生自己的CMyDialog,到DoModal()时总提示 error C2039: "DoModal": 不是"CMyDialog"的 ...

  3. codeforces865C

    Gotta Go Fast CodeForces - 865C You're trying to set the record on your favorite video game. The gam ...

  4. ida 下载

    链接:https://pan.baidu.com/s/1Rs2UOSfroBGf_MIkJv0cGw 提取码:kjqd 官网:https://www.hex-rays.com/updida.shtml

  5. OpsManage安装过程中遇到的问题和解决方案

    系统地址:https://github.com/welliamcao/OpsManage 系统:ubuntu ubuntu使用apt-get进行自动化安装 自带python2.7,不需要再次安装 1. ...

  6. Java 显示锁 之 重入锁 ReentrantLock(七)

    ReentrantLock 重入锁简介 重入锁 ReentrantLock,顾名思义,就是支持同一个线程对资源的重复加锁.另外,该锁还支持获取锁时的公平与非公平性的选择. 重入锁 ReentrantL ...

  7. 给类或者类的对象添加打印内容 def __repr__(self)

    通常情况下 打印一个类或者类的对象 会显示 xx.xx object at 0xaaaaabbbbbbb  只会告诉你这个对象或者类 储存在某个内存中,这是因为你的类没有实现相关的打印功能 print ...

  8. Spring动态切换数据源及事务

    前段时间花了几天来解决公司框架ssm上事务问题.如果不动态切换数据源话,直接使用spring的事务配置,是完全没有问题的.由于框架用于各个项目的快速搭建,少去配置各个数据源配置xml文件等.采用了动态 ...

  9. FFmpeg之av_register_all()

    1. av_register_all() 该函数位于 libavformat/allformats.c 中. 该函数主要是注册所有的编解码器.复用/解复用组件等. /* * Initialize li ...

  10. easyUI之ComboBox(下拉列表框)

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <hea ...