ffmpeg录音
Qt 5.9
ffmpeg 4.0.1
audacity https://www.audacityteam.org/
cooledit https://download.csdn.net/download/wyy626562203/10565903
#include <stdio.h>
#include <QAudioDeviceInfo>
#include <qDebug>
#include <QTextCodec>
extern "C"
{
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswscale/swscale.h"
#include "libavdevice/avdevice.h"
}
//Show Dshow Device
void show_dshow_device(){
AVFormatContext *pFormatCtx = avformat_alloc_context();
AVDictionary* options = NULL;
av_dict_set(&options,"list_devices","true",0);
AVInputFormat *iformat = av_find_input_format("dshow");
printf("========Device Info=============\n");
avformat_open_input(&pFormatCtx,"video=dummy",iformat,&options);
printf("================================\n");
}
int main(int argc, char* argv[])
{
AVFormatContext *pFormatCtx;
int i, audioindex;
AVCodecContext *aCodecCtx;
AVCodec *aCodec = NULL;
AVFrame *aFrame;
// 注册解码器
av_register_all();
//注册设备
avdevice_register_all();//Register Device
//显示音视频设备
show_dshow_device();
pFormatCtx = avformat_alloc_context();
//使用Qt接口获取输入设备名称
QString psDevName = "audio=" + QAudioDeviceInfo::availableDevices(QAudio::AudioInput).at(0).deviceName();
AVInputFormat *ifmt = av_find_input_format("dshow");
//打开流设备
if(avformat_open_input(&pFormatCtx,psDevName.toStdString().c_str(),ifmt,NULL)!=0)
{
fprintf(stderr,"Couldn't open input stream.\n");
return -1;
}
audioindex = -1;
aCodecCtx = NULL;
//寻找音频流
for(i=0; i<pFormatCtx->nb_streams; i++)
{
if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO)
{
audioindex=i;
break;
}
}
//没有找到视频流
if(audioindex==-1)
{
printf("Didn't find a video stream.\n");
return -1;
}
//获取解码器上下文
aCodecCtx = pFormatCtx->streams[audioindex]->codec;
//获取音频解码器
aCodec = avcodec_find_decoder(aCodecCtx->codec_id);
if(aCodec == NULL)
{
printf("audio Codec not found.\n");
return -1;
}
//打开音频解码器
if(avcodec_open2(aCodecCtx, aCodec,NULL)<0)
{
printf("Could not open audio codec.\n");
return -1;
}
aFrame=av_frame_alloc();
int ret, got_frame;
AVPacket *packet=(AVPacket *)av_malloc(sizeof(AVPacket));
//打开输出文件
FILE *fp_pcm=fopen("output.pcm","wb");
//输出音频信息
qDebug()<< "sample format: " << aCodecCtx->sample_fmt << "(0-8bit 1-16bit)";
qDebug()<< "sample bit: " << aCodecCtx->bit_rate;
qDebug()<< "sample rate: " << aCodecCtx->sample_rate;
qDebug()<< "sample channels:" << aCodecCtx->channels;
float Time = 0;
for(int i=0;;i++)
{
if (Time > 30) break; //就采集30秒
//读取音频数据
if(av_read_frame(pFormatCtx, packet) < 0)
{
break;
}
//判断是否是音频流
if(packet->stream_index==audioindex)
{
#if 0 //废弃的方法
ret = avcodec_decode_audio4(aCodecCtx, aFrame, &got_frame, packet);
if(ret < 0)
{
fprintf(stderr,"Audio Error.\n");
return -1;
}
if (got_frame)
{
int pcmSize = av_samples_get_buffer_size(NULL,aCodecCtx->channels, aFrame->nb_samples,aCodecCtx->sample_fmt, 1);
uint8_t * pcmBuffer = aFrame->data[0];
float useTime = aFrame->nb_samples * 1.0 / aCodecCtx->sample_rate;
Time += useTime;
qDebug()<<i<<Time<<useTime;
fwrite(pcmBuffer,1,pcmSize,fp_pcm); //写入文件
}
#else //新方法
ret = avcodec_send_packet(aCodecCtx, packet);
if (ret != 0)
{
fprintf(stderr,"Audio Error.\n");
return -1;
}
while( avcodec_receive_frame(aCodecCtx, aFrame) == 0)
{
int pcmSize = av_samples_get_buffer_size(NULL,aCodecCtx->channels, aFrame->nb_samples,aCodecCtx->sample_fmt, 1);
uint8_t * pcmBuffer = aFrame->data[0];
float useTime = aFrame->nb_samples * 1.0 / aCodecCtx->sample_rate;
Time += useTime;
qDebug()<<i<<Time<<useTime;
fwrite(pcmBuffer,1,pcmSize,fp_pcm); //写入文件
}
#endif
}
av_free_packet(packet);
}
fclose(fp_pcm);
if (aFrame != NULL)
{
av_free(aFrame);
aFrame = NULL;
}
if (aCodecCtx != NULL)
avcodec_close(aCodecCtx);
avformat_close_input(&pFormatCtx);
avformat_free_context(pFormatCtx);
return 0;
}