学习FFmpeg简单Samples之音频编码

9 篇文章 2 订阅

实例代码

int audio_Encoder()
{
	int channels = 2;
	int sampleRate = 48000;
	int inSampleFmt = AV_SAMPLE_FMT_S16;

	///4 初始化编码器 AV_CODEC_ID_AAC
	AVCodec* codec = avcodec_find_encoder(AV_CODEC_ID_AAC);
	if (!codec)
	{
		std::cout << "avcodec_find_encoder  failed!" << endl;
		return NULL;
	}
	//音频编码器上下文
	AVCodecContext* ac = avcodec_alloc_context3(codec);
	if (!ac)
	{
		std::cout << "avcodec_alloc_context3  failed!" << endl;
		return NULL;
	}
	std::cout << "avcodec_alloc_context3 success!" << endl;

	ac->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
	ac->codec_tag = 0;
	ac->thread_count = XGetCpuNum();
	ac->time_base = { 1,1000000 };
	ac->bit_rate = 128000;
	ac->sample_rate = sampleRate;
	ac->sample_fmt = AV_SAMPLE_FMT_FLTP;
	ac->channels = 2;
	ac->channel_layout = av_get_default_channel_layout(ac->channels);

	int size = av_samples_get_buffer_size(NULL, 2, 1024, AV_SAMPLE_FMT_FLTP, 1);
	int extradata_size = ac->extradata_size;

	//打开音频编码器
	int ret = avcodec_open2(ac, 0, 0);
	if (ret != 0)
	{
		return XError(ret);
	}
	std::cout << "avcodec_open2 success!" << endl;

	///2 音频重采样 上下文初始化
	SwrContext* asc = NULL;
	asc = swr_alloc_set_opts(asc,
		av_get_default_channel_layout(channels), (AVSampleFormat)AV_SAMPLE_FMT_FLTP, sampleRate,//输出格式
		av_get_default_channel_layout(channels), (AVSampleFormat)inSampleFmt, sampleRate, 0, 0);//输入格式
	if (!asc)
	{
		std::cout << "swr_alloc_set_opts failed!";
		return false;
	}

	ret = swr_init(asc);
	if (ret != 0)
	{
		return XError(ret);
	}
	std::cout << "音频重采样 上下文初始化成功!" << endl;

	///3 音频重采样输出空间分配
	AVFrame* pcm = av_frame_alloc();
	pcm->format = AV_SAMPLE_FMT_FLTP;
	pcm->sample_rate = sampleRate;
	pcm->channels = channels;
	pcm->channel_layout = av_get_default_channel_layout(channels);
	pcm->nb_samples = av_rescale_rnd(1024, sampleRate, sampleRate, AVRounding{ AV_ROUND_UP }); //一帧音频一通道的采用数量
	ret = av_frame_get_buffer(pcm, 0); // 给pcm分配存储空间
	if (ret != 0)
	{
		return XError(ret);
	}

	AVPacket* Encodepacket = av_packet_alloc();

	FILE* inputFile = fopen("audio_record_48k_2_s16.pcm", "rb+");

	FILE* aac = fopen("audio_record_48k_2_fltp.aac", "wb");

	char pcm_buf[10000] = { 0 };

	int frameindex = 0;

	while (fread(pcm_buf, 1, 4096, inputFile) >= 4096)
	{
		const uint8_t* indata[AV_NUM_DATA_POINTERS] = { 0 };
		indata[0] = (const uint8_t *)pcm_buf;

		int len = swr_convert(asc, pcm->data, pcm->nb_samples, //输出参数,输出存储地址和样本数量
			indata, 1024
		);
		
		ret = avcodec_send_frame(ac, pcm);

		if (ret < 0) {
			std::cout << endl;
			continue;
		}

		while (ret >= 0) {
			ret = avcodec_receive_packet(ac, Encodepacket);
			if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
				break;
			}

			if (ret < 0) {
				break;
			}

			fwrite(Encodepacket->data, 1, Encodepacket->size, aac);

			std::cout << "frameindex  : " << frameindex <<" nb_samples :" << len << "  encodeSize:" << Encodepacket->size << endl ;

			frameindex++;
		}

		av_packet_unref(Encodepacket);

	}

	ret = avcodec_send_frame(ac, NULL);
	
	while (ret >= 0) {
		ret = avcodec_receive_packet(ac, Encodepacket);
		if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
			break;
		}

		if (ret < 0) {
			break;
		}

		fwrite(Encodepacket->data, 1, Encodepacket->size, aac);

		std::cout << "frameindex  : " << frameindex  << "  encodeSize:" << Encodepacket->size << endl;

		frameindex++;
	}

	std::fclose(aac);

	av_packet_free(&Encodepacket);

	av_frame_free(&pcm);

	if (asc)
		swr_free(&asc);

	if (ac)
		avcodec_free_context(&ac);

	std::cout << "退出音频录制" << endl;

	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一个基于 FFmpeg 的 C 语言音频编码程序: #include <libavcodec/avcodec.h> #include <libavutil/opt.h> #include <libavutil/audio_fifo.h>int main(int argc, char *argv[]) { //声明编码器上下文 AVCodecContext *codecContext = NULL; //声明编码器 AVCodec *codec = NULL; int ret = 0; //声明音频采样帧 AVFrame *frame = NULL; int gotFrame = 0; //初始化编码器上下文 codecContext = avcodec_alloc_context3(codec); if (!codecContext) { printf("Could not allocate a codec context\n"); return -1; } //选择编码器 codec = avcodec_find_encoder(AV_CODEC_ID_MP3); if (!codec) { printf("Could not find a suitable encoder\n"); return -1; } //设置编码器参数 codecContext->bit_rate = 64000; codecContext->sample_rate = 44100; codecContext->channels = 2; codecContext->channel_layout = AV_CH_LAYOUT_STEREO; codecContext->sample_fmt = AV_SAMPLE_FMT_S16; //打开编码器 ret = avcodec_open2(codecContext, codec, NULL); if (ret < 0) { printf("Could not open the codec\n"); return -1; } //分配音频采样帧 frame = av_frame_alloc(); if (!frame) { printf("Could not allocate an audio frame\n"); return -1; } //设置音频采样帧的参数 frame->nb_samples = codecContext->frame_size; frame->format = codecContext->sample_fmt; frame->channel_layout = codecContext->channel_layout; //分配采样帧的缓冲区 ret = av_frame_get_buffer(frame, 0); if (ret < 0) { printf("Could not allocate the audio data buffers\n"); return -1; } //读取音频采样数据 //... //编码音频采样帧 ret = avcodec_encode_audio2(codecContext, &pkt, frame, &gotFrame); if (ret < 0) { printf("Could not encode the frame\n"); return -1; } //释放资源 av_frame_free(&frame); avcodec_free_context(&codecContext); return 0; }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值