一、打开音频设备
设备可以是多媒体文件和物理设备
#ifndef TESTC_H
#define TESTC_H
#include <stdio.h>
#include "libavutil/avutil.h"
#include "libavdevice/avdevice.h" //打开音频设备相关的头文件
#include "libavformat/avformat.h" //ffmpeg下的所有文件都是以格式来呈现的
#endif
输入设备为同目录下的video_2.mp4
#include "testc.h"
void main(int argc, char **argv)
{
int ret = 0;
char errors[1024];
static AVFormatContext *fmt_ctx = NULL; //ffmpeg下的“文件描述符”
char *devicename = "./video_2.mp4";
//register audio device
avdevice_register_all();
//get format
AVInputFormat *iformat = av_find_input_format("alsa");
if( (ret = avformat_open_input(&fmt_ctx, devicename, NULL, NULL)) < 0)
{
av_strerror(ret, errors, 1024);
printf("Failed to open audio device, [%d]%s\n", ret, errors);
return;
};
av_log_set_level(AV_LOG_DEBUG);
av_log(NULL, AV_LOG_DEBUG, "hello, world\n");
return;
}
二、从设备中读取音频数据
内存泄漏注意:创建了必须释放
1. avformat_open_input(&fmt_ctx, devicename, NULL, NULL);
2. avformat_close_input(&fmt_ctx);
1. av_init_packet(&pkt);
2. av_read_frame(fmt_ctx, &pkt)
3. av_packet_unref(&pkt);
所需头文件
#include "libavcodec/avcodec.h"
代码
#include "testc.h"
void main(int argc, char **argv)
{
int ret = 0;
char errors[1024] = {0};
//context
static AVFormatContext *fmt_ctx = NULL; //ffmpeg下的“文件描述符”
//paket
int count = 0;
AVPacket pkt;
char *devicename = "./video_2.mp4";
//register audio device
avdevice_register_all();
//get format
AVInputFormat *iformat = av_find_input_format("alsa");
//open video
if( (ret = avformat_open_input(&fmt_ctx, devicename, NULL, NULL)) < 0)
{
av_strerror(ret, errors, 1024);
printf("Failed to open audio device, [%d]%s\n", ret, errors);
return;
};
av_init_packet(&pkt);
//read data form video
while(ret = (av_read_frame(fmt_ctx, &pkt))== 0&&
count++ < 500) {
av_log(NULL, AV_LOG_INFO, "pkt size is %d(%p), count=%d\n",
pkt.size,pkt.data, count);
av_packet_unref(&pkt);//releas pkt
}
avformat_close_input(&fmt_ctx);//releas ctx
av_log_set_level(AV_LOG_DEBUG);
av_log(NULL, AV_LOG_DEBUG, "finish!\n");
return;
}
三、录制音频
1.创建文件
创建文件来保存采集的音频数据
//create file
char *out = "/home/lee/vido_learn/mytest/audio.pcm";
FILE *outfile = fopen(out,"wb+");
2.写入数据
//write file
fwrite(pkt.data, pkt.size, 1, outfile);
fflush(outfile);
3.关闭文件
//close file
fclose(outfile);
出于效率考虑fwrite()会先把数据写到缓存区,待缓存区有一定大小的块数据后才把通过文件io操作磁盘将数据写入文件,加入fflush()会立即将数据写入磁盘
四、执行程序
执行程序后会生成audio.pcm文件
在命令行使用ffply进行播放
ffplay -ar 44100 -ac 2 -f f32le audio.pcm
-ar 44100 采样率44100Hz
-ac 2 通道数
-f f32le 采样大小32位
五、音频重采样
包含头文件
#include "libswresample/swresample.h"
uint8_t **src_data = NULL;
int src_linesize = 0;
uint8_t **dts_data = NULL;
int dts_linesize = 0;
//4096/4=1024/2=512
//创建输入缓冲区
av_samples_alloc_array_and_samples(&src_data, //输出缓冲区地址
&src_linesize, //缓冲区的大小
2, //通道个数
512, //单通道采样个数
AV_SAMPLE_FMT_FLT,//采样格式
0);
//创建输出缓冲区
av_samples_alloc_array_and_samples(&dts_data, //输出缓冲区地址
&dts_linesize, //缓冲区的大小
2, //通道个数
512, //单通道采样个数
AV_SAMPLE_FMT_S16,//采样格式
0);
//重采样
swr_convert(swr_ctx,
dts_data,
dts_linesize,
(const uint8_t **)src_data,
src_linesize);
标签:ffmpeg,pkt,音频,ctx,ret,采集,av,NULL,fmt From: https://www.cnblogs.com/kn-zheng/p/17685121.html