使用的是 Win11 环境,获取的 Packet Size 为 88200。直接用视频里的公式将 512 改为 11025 ,使用下面命令播放时出现杂音。
ffplay -ar 44100 -ac 2 -f s16le .\audio.pcm
完成代码
void RecThread::recAudio()
{
AVFormatContext* fmt_ctx = nullptr;
AVDictionary* options = nullptr;
char* device_name = QString("audio=麦克风 (Realtek(R) Audio)").toUtf8().data();
// Register audio device.
avdevice_register_all();
// Get format.
const AVInputFormat* i_format = av_find_input_format("dshow");
char errors[1024];
int ret = 0;
if ((ret = avformat_open_input(&fmt_ctx, device_name, i_format, &options)) < 0)
{
av_strerror(ret, errors, 1024);
printf("Failed to open audio device, [%d]%s", ret, errors);
exit(-1);
}
else
{
emit sendDeviceInfo(QString("Device:") + QString(device_name));
}
// Create file.
FILE* out_file = fopen("C:/Users/rolfm/Desktop/audio.pcm", "wb+");
int count = 0;
AVPacket pkt;
av_init_packet(&pkt);
printf("Start.\n");
SwrContext* swr_ctx = NULL;
swr_ctx = swr_alloc_set_opts(NULL,
AV_CH_LAYOUT_STEREO,
AV_SAMPLE_FMT_S16,
44100,
AV_CH_LAYOUT_STEREO,
AV_SAMPLE_FMT_FLT,
44100,
0,
NULL);
if (swr_init(swr_ctx) < 0)
{
printf("Fail to init swr.\n");
exit(-1);
}
uint8_t** src_data = NULL;
int src_linesize = 0;
av_samples_alloc_array_and_samples(&src_data,
&src_linesize,
2,
11025,
AV_SAMPLE_FMT_FLT,
0);
uint8_t** dst_data = NULL;
int dst_linesize = 0;
av_samples_alloc_array_and_samples(&dst_data,
&dst_linesize,
2,
11025,
AV_SAMPLE_FMT_S16,
0);
while ((ret = av_read_frame(fmt_ctx, &pkt)) == 0 && is_started)
{
printf("Pkt size is %d(%p), count=%2d.\n", pkt.size, pkt.data, count);
memcpy((void*)src_data[0], (const void*)pkt.data, pkt.size);
swr_convert(swr_ctx, dst_data, 11025, (const uint8_t**)src_data, 11025);
// Write file.
fwrite((const void*)dst_data[0], dst_linesize, 1, out_file);
count++;
av_packet_unref(&pkt); // Release pkt.
}
// Close file.
fclose(out_file);
if (src_data)
{
av_freep(&src_data[0]);
}
av_freep(&dst_data);
if (dst_data)
{
av_freep(&dst_data[0]);
}
av_freep(&dst_data);
swr_free(&swr_ctx);
// Release ctx.
if (fmt_ctx != nullptr)
{
avformat_close_input(&fmt_ctx);
}
printf("Stop.\n");
}