ffmpeg录制电脑内部声音(如内部歌曲声音)

本文介绍了如何使用FFmpeg 2017版本在Windows上通过DirectShow捕获音频,选择合适的采样率和通道布局,并进行音频转换,以实现实时录音并保存为MP4文件的过程。

vs版本:2017
ffmpeg版本号:
ffmpeg version N-102642-g864d1ef2fc Copyright © 2000-2021 the FFmpeg developers
built with gcc 8.1.0 (x86_64-win32-seh-rev0, Built by MinGW-W64 project)
configuration: --arch=x86_64 --prefix=/home/ffmpeg_static_x64 --disable-debug
libavutil 57. 0.100 / 57. 0.100
libavcodec 59. 1.100 / 59. 1.100
libavformat 59. 2.101 / 59. 2.101
libavdevice 59. 0.100 / 59. 0.100
libavfilter 8. 0.101 / 8. 0.101
libswscale 6. 0.100 / 6. 0.100
libswresample 4. 0.100 / 4. 0.100

关于ffmpeg的lib和dll,本人在csdn上上传了相关资源,并且免费下载。

本文抓取的是电脑内部声音,需要先安装软件screen capture recorder。
软件的下载地址是
http://sourceforge.net/projects/screencapturer/files/
在安装软件之前,我们先看下电脑支持的设备列表,用的是如下命令
ffmpeg -list_devices true -f dshow -i dummy
在这里插入图片描述
安装了软件之后,我们再看下电脑支持的设备列表
在这里插入图片描述
下面是具体的代码

// FfmpegAudioTest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <Windows.h>
#include <conio.h>

#ifdef	__cplusplus
extern "C"
{
   
   
#endif
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswscale/swscale.h"
#include "libswresample/swresample.h"
#include "libavdevice/avdevice.h"
#include "libavutil/audio_fifo.h"

#pragma comment(lib, "avcodec.lib")
#pragma comment(lib, "avformat.lib")
#pragma comment(lib, "avutil.lib")
#pragma comment(lib, "avdevice.lib")
#pragma comment(lib, "avfilter.lib")

	//#pragma comment(lib, "avfilter.lib")
	//#pragma comment(lib, "postproc.lib")
#pragma comment(lib, "swresample.lib")
#pragma comment(lib, "swscale.lib")
#ifdef __cplusplus
};
#endif




AVFormatContext	*pFormatCtx_Audio = NULL, *pFormatCtx_Out = NULL;

AVCodecContext *pReadCodecContext = NULL;

int AudioIndex_mic;

AVCodecContext	*pCodecEncodeCtx_Audio = NULL;
AVCodec			*pCodecEncode_Audio = NULL;


AVAudioFifo		*fifo_audio = NULL;

SwrContext *audio_convert_ctx = NULL;

uint8_t *picture_buf = NULL, *frame_buf = NULL;

bool bCap = true;

int AudioFrameIndex = 0;


DWORD WINAPI AudioMicCapThreadProc(LPVOID lpParam);

static char *dup_wchar_to_utf8(const wchar_t *w)
{
   
   
	char *s = NULL;
	int l = WideCharToMultiByte(CP_UTF8, 0, w, -1, 0, 0, 0, 0);
	s = (char *)av_malloc(l);
	if (s)
		WideCharToMultiByte(CP_UTF8, 0, w, -1, s, l, 0, 0);
	return s;
}


/* just pick the highest supported samplerate */
static int select_sample_rate(const AVCodec *codec)
{
   
   
	const int *p;
	int best_samplerate = 0;

	if (!codec->supported_samplerates)
		return 44100;

	p = codec->supported_samplerates;
	while (*p) {
   
   
		if (!best_samplerate || abs(44100 - *p) < abs(44100 
<think>好的,我现在需要帮用户解决使用FFmpeg发送声卡数据到另一台电脑时出现的音频不同步问题。首先,我得回想一下用户的问题场景:他们可能在通过FFmpeg实时传输音频,但接收端出现声音延迟或者不同步的情况。这可能涉及多个因素,比如网络延迟、编码延迟、时钟同步问题,或者缓冲设置不当。 首先,我应该考虑网络方面的问题。网络延迟和抖动是常见的原因。用户可能没有足够的带宽,或者网络存在不稳定,导致数据包到达时间不一致。这时候需要建议他们检查网络状况,比如使用ping或者iperf测试延迟和带宽。如果网络确实有问题,可能需要调整码率,或者使用更高效的编码格式,比如opus,因为它的延迟较低。另外,启用UDP协议可能比TCP更适合实时传输,因为TCP的重传机制会增加延迟。 接下来是编码和解码的延迟。用户可能使用了高延迟的编码器,或者编码预设不够优化。例如,使用非常慢的x264预设会增加编码时间,导致延迟累积。这时候建议他们使用更快的编码预设,比如-preset ultrafast,虽然可能会影响压缩效率,但能减少延迟。另外,硬件加速编码,比如用NVENC或VAAPI,也能减少编码时间,降低延迟。 时钟同步也是一个关键因素。FFmpeg内部使用不同的时钟源,如果音频和视频的时钟不同步,或者发送端和接收端的系统时钟有偏差,就会导致不同步。需要检查是否有设置-avioflags direct选项,或者尝试使用-re选项来按照实际时间戳传输,虽然这在实时流中可能不适用。另外,确保接收端正确解析时间戳,可能需要使用ffplay的-avioflags direct或-fflags nobuffer来减少缓冲。 缓冲设置不当同样会导致延迟。用户可能在发送端或接收端设置了过大的缓冲区,导致数据积压。需要调整FFmpeg中的rtbufsize参数,减小发送缓冲区的大小,比如设置-rtbufsize 1M。在接收端,ffplay的-buffer_size也可以调整,减少初始缓冲时间,比如使用-buffer_size 1024。 此外,用户可能没有正确配置时间戳处理。FFmpeg的-avoid_negative_ts make_zero或-genpts选项可能有助于生成正确的时间戳。在接收端,确保时间戳被正确处理,比如使用ffplay的-af aresample=async=1来调整音频同步。 还有可能是硬件问题,比如声卡本身的延迟。建议用户测试本地播放是否有延迟,或者更换声卡驱动。同时,系统负载过高也可能导致处理延迟,需要监控CPU和内存使用情况,确保资源充足。 最后,可能需要分步骤排查问题。比如先测试本地录制和播放是否同步,排除FFmpeg配置问题;再检查网络传输,逐步调整参数。使用工具分析网络流量和延迟,或者启用FFmpeg的调试日志,查看时间戳信息,找出不同步的具体原因。 总结下来,需要从网络、编码、时钟、缓冲、时间戳处理等多个方面逐一排查,调整相应的参数,才能解决声音不同步的问题。同时,建议用户进行系统性的测试,逐步定位问题根源,再针对性地优化设置。</think>以下分步骤排查和解决FFmpeg声卡数据传输声音不同步问题: --- ### **一、基础检查** 1. **测试本地录音延迟** ```bash # 发送端录制声卡并本地播放(先排除FFmpeg自身问题) ffmpeg -f alsa -i hw:0 -f pulse "本地扬声器设备名" ``` 若本地播放已不同步,需检查: - 声卡驱动(尝试更换`alsa`/`pulseaudio`后端) - 系统音频缓冲设置(如PulseAudio的`fragment_size`) 2. **验证网络质量** ```bash # 接收端执行网络测试(替换为接收端IP) iperf3 -c 接收端IP -t 30 ``` - 要求:带宽 > 音频码率 × 2,延迟 < 50ms - 若网络抖动大,优先改用有线网络或优化路由 --- ### **二、关键参数调优** #### ▶ **发送端优化** ```bash ffmpeg \ -f alsa -ac 2 -ar 48000 -thread_queue_size 1024 -i hw:0 \ # 降低采集队列 -c:a libopus -b:a 64k -application lowdelay \ # 低延迟编码 -f mpegts -flush_packets 1 -rtbufsize 1M \ # 减少缓冲 udp://目标IP:端口?pkt_size=1316 # UDP传输 ``` #### ▶ **接收端优化** ```bash ffplay \ -fflags nobuffer -flags low_delay -avioflags direct \ # 禁用缓冲 -f mpegts -i udp://0.0.0.0:端口 \ -af "aresample=async=1:min_comp=0.001" # 动态补偿延迟 ``` --- ### **三、高级调试方案** 1. **时间戳监控** ```bash # 发送端添加调试输出 ffmpeg -loglevel debug ... 2>&1 | grep "pts_time" # 接收端查看解析时间戳 ffplay -debug_ts ... ``` 2. **强制时钟同步** ```bash # 接收端使用主时钟同步(适用于纯音频流) ffplay -sync ext ... ``` 3. **网络QoS保障** ```bash # Linux系统限制音频流优先级(替换为实际网卡名) sudo tc qdisc add dev eth0 root handle 1: prio priomap 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 sudo tc filter add dev eth0 parent 1:0 protocol ip u32 match ip dport 端口 0xffff flowid 1:1 ``` --- ### **四、典型场景解决方案** | 现象 | 解决方案 | |-----------------------|---------------------------------| | 延迟逐渐累积 | 添加`-af aresample=async=1000`(动态重置时钟) | | 突发卡顿后不同步 | 减小`-thread_queue_size` + 限制发送端CPU占用 | | 仅首次连接不同步 | 接收端添加`-probesize 32 -analyzeduration 0` | --- ### **五、终极方案建议** 若仍不同步,可改用专业低延迟传输协议: 1. **RIST协议**:`ffmpeg -f alsa ... -c:a aac -f rist udp://目标IP:端口` 2. **SRT协议**:`ffmpeg -f alsa ... -c:a opus -f srt srt://目标IP:端口?latency=200`
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值