头文件:
#define __STDC_CONSTANT_MACROS
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavdevice/avdevice.h>
}
AVInputFormat类型表示一种输入文件/输入设备的数据格式
AVFormatContext类型表示音视频的格式内容
AVDictionary类型表示相关的配置项,如摄像头设备有图像大小的配置
AVPacket类型用于装载一帧数据
1. av_register_all();
2. avdevice_register_all();
3. 准备参数
AVInputFormat *ifmt = av_find_input_format("alsa");
AVFormatContext *fmtContxt = avformat_alloc_context();
AVDictionary *options = NULL;
av_dict_set(&options, "sample_rate", "44100", 0);
av_dict_set(&options, "channels", "1", 0);
4. 使用指定的参数, 打开指定的设备
if (avformat_open_input(&fmtContxt, "default", ifmt, &options) < 0)
{
perror("avformat open");
return 1;
}
5. 打开设备后, 可检查声音数据格式.
AVCodecID id = fmtContxt->streams[0]->codec->codec_id;
qDebug() << id << " " << avcodec_get_name(id);
6. 准备一帧数据的空间,及读取数据:
AVPacket *packet = (AVPacket *)av_malloc(sizeof(AVPacket));
av_read_frame(fmtContxt, packet);
7. 封装成一个wav文件. wav文件格式参考http:
大概来说wav其实就一个文件头+pcm数据组成.
录制60秒的wav文件
WavHeader header(44100, 16, 1, 60);
FILE *fl = fopen("/my.wav", "w");
fwrite(&header, sizeof(header), 1, fl);
int len = 44100*1*2*60;
for (int n = 0; n < len;)
{
if (av_read_frame(fmtContxt, packet) < 0)
{
perror("read frame failed");
return 1;
}
qDebug() << packet->size;
n += packet->size;
fwrite(packet->data, packet->size, 1, fl);
}
fclose(fl);
附wav文件头的类型:
class WavHeader {
private:
unsigned char ChunkID[4];
unsigned int ChunkSize;
unsigned char Format[4];
unsigned char Subchunk1ID[4];
unsigned int Subchunk1Size;
unsigned short AudioFormat;
unsigned short NumChannels;
unsigned int SampleRate;
unsigned int ByteRate;
unsigned short BlockAlign;
unsigned short BitsPerSample;
unsigned char Subchunk2ID[4];
unsigned int Subchunk2Size;
public:
WavHeader (int rate, int bits, int channels, int sec)
{
strcpy((char *)ChunkID, "RIFF");
Subchunk2Size = (sec * rate * channels * bits)>>3;
ChunkSize = 36 + Subchunk2Size;
strcpy((char *)Format, "WAVE");
strcpy((char *)Subchunk1ID, "fmt ");
Subchunk1Size = 16;
AudioFormat = 1;
NumChannels = channels;
SampleRate = rate;
ByteRate = (rate * channels * bits)>>3;
BlockAlign = (channels * bits)>>3;
BitsPerSample = bits;
strcpy((char *)Subchunk2ID, "data");
Subchunk2Size = (sec * rate * channels * bits)>>3;
}
};
参考:
http://blog.csdn.net/leixiaohua1020