ubuntu下使用Qt+ffmpeg采集音频,保存音频文件,简单多线程方式
ui界面增加按钮,按钮文本为开始录制。按钮槽函数:
void MainWindow::on_btn_Open_clicked()
{
if (m_status)
{
m_status = false;
ui->btn_Open->setText(tr("开始录制"));
}
else
{
m_status = true;
ui->btn_Open->setText(tr("停止录制"));
QtConcurrent::run([&](){
// 录制音频函数
openDeviceAndReadData();
});
}
}
用界面按钮控制开始录制和停止录制,使用QtConcurrent实现简单的多线程方式避免主线程卡顿。也可以使用QThread或者object等方式实现多线程,此处逻辑不复杂,所以采用了简单的方式实现多线程。录制函数中用m_status来控制开始和停止。
// 录制函数
void MainWindow::openDeviceAndReadData()
{
// 设置日志级别
av_log_set_level(AV_LOG_DEBUG);
// 注册设备
avdevice_register_all();
// 获取采集格式
AVInputFormat *inputFmt = av_find_input_format("alsa");
int ret = 0;
AVFormatContext *fmt_ctx = nullptr;
char *deviceName = "hw:0,0";
AVDictionary *options = nullptr;
// 打开设备
ret = avformat_open_input(&fmt_ctx, deviceName, inputFmt, &options);
char errors[1024] = {0};
if (ret < 0)
{
av_strerror(ret, errors, 1024);
printf("Failed to open audio device, [%d]%s\n", ret, errors);
return;
}
int count = 0;
AVPacket packet;
av_init_packet(&packet);
// 创建文件
char *outPath = "/opt/document/audio.pcm";
FILE *outFile = fopen(outPath, "wb+");
// 从设备读取数据, 用m_status控制是否读取
while ((ret = av_read_frame(fmt_ctx, &packet) == 0) && m_status)
{
// 写入文件
fwrite(packet.data, packet.size, 1, outFile);
fflush(outFile);
av_log(NULL, AV_LOG_INFO, "Packet size: %d(%p), count = %d\n",
packet.size, packet.data, count++);
// 释放packet空间
av_packet_unref(&packet);
}
// 关闭文件
fclose(outFile);
// 关闭设备,释放上下文空间
avformat_close_input(&fmt_ctx);
av_log(NULL, AV_LOG_DEBUG, "Finish!\n");
}
找到生成的音频文件,我的在/opt/document/audio.pcm,在终端打开,执行如下命令,即可播放刚才录制的音频:
ffplay -ar 44100 -ac 2 -f s16le audio.pcm
我刚刚开始学习音视频的内容,把学习内容记录下来,方便自己查看,也分享给有需要的小伙伴,现在的都是基础,采集出来的音频效果不是特别好,以后会学习进阶篇,到时候再和大家分享更好的新内容。