学习FFmpeg简单Samples之音频编码

实例代码

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;
}

猜你喜欢

转载自blog.csdn.net/qq_34940879/article/details/107940929