ffmpeg音频编码

以mp3编码为例,编解码库中提供了两种音频编码api,下面分别给出两个api的用法。好啦,废话不多说,贴出代码供参考。

void audio_encode(const char * inputfilename,const char *outputfilename) {
	AVCodec *codec;
	AVCodecContext *c = NULL;
	int frame_size, out_size, outbuf_size;
	FILE * fin, *fout;
	short *samples;
	uint8_t *outbuf;
	int numberframe = 0;
	int size = 0;
	int FRAME_READ = 0;
       
	printf("Audio encoding\n");
        av_register_all();
	/* find the MP3 encoder */
	codec = avcodec_find_encoder(AV_CODEC_ID_MP3);
	if (!codec) {
		fprintf(stderr, "codec not found\n");
		exit(1);
	}

	c = avcodec_alloc_context();

	/* put sample parameters */
	c->bit_rate = 64000;
      c->sample_rate = 44100;
	c->channels = 2;
	c->sample_fmt = AV_SAMPLE_FMT_S16;

	

	/* open it */
	if (avcodec_open(c, codec) < 0) {
		fprintf(stderr, "could not open codec\n");
		exit(1);
	}

	/* the codec gives us the frame size, in samples */
	frame_size = c->frame_size;
	samples = malloc(frame_size * 2 * c->channels); 

	FRAME_READ = frame_size * 2 * c->channels;

	outbuf_size = 10000;
	outbuf = malloc(outbuf_size);

	fin = fopen(inputfilename, "rb+");
	if (!fin) {
		fprintf(stderr, "could not open %s\n", inputfilename);
		exit(1);
	}

	fout = fopen(outputfilename, "wb");
	if (!fout) {
		fprintf(stderr, "could not open %s\n", outputfilename);
		exit(1);
	}
	for (;;) {
		size = fread(samples, 1, FRAME_READ, fin);
		if (size == 0) {
			break;
		}
		/* encode the samples */
		out_size = avcodec_encode_audio(c, outbuf, outbuf_size, samples);
		fwrite(outbuf, 1, out_size, fout);
		numberframe++;
		printf("save frame %d\n", numberframe);

	}
	fclose(fout);
	free(outbuf);
	free(samples);

	avcodec_close(c);
	av_free(c);
	printf("audio encode finish...");
}


上面程序中用到的音频编码api已经过时了,官方文档中不建议使用,下面看看新的编码api。


static void audio_encode_example(const char *output_filename,const char *input_filename) {
	AVCodec *codec;
	AVCodecContext *c = NULL;
	AVFrame *frame;
	AVPacket pkt;
	int i,ret, got_output;
	int buffer_size;
	FILE *fout, *fin;
	uint8_t *samples;
	int numberframe = 0;

	printf("Encode audio file %s\n", output_filename);
        av_register_all();
	/* find the MP3 encoder */
	codec = avcodec_find_encoder(AV_CODEC_ID_MP3);
	if (!codec) {
		fprintf(stderr, "Codec not found\n");
		exit(1);
	}

	c = avcodec_alloc_context3(codec);

	/* put sample parameters */
	c->bit_rate = 64000;
	c->sample_rate = 44100;
	c->channels = 2;

	
	c->sample_fmt = AV_SAMPLE_FMT_S16;
	

	/* select other audio parameters supported by the encoder */

	c->channel_layout = select_channel_layout(codec);
	

	/* open it */
	if (avcodec_open2(c, codec, NULL ) < 0) {
		fprintf(stderr, "Could not open codec\n");
		exit(1);
	}

	fout = fopen(output_filename, "wb");
	if (!fout) {
		fprintf(stderr, "Could not open %s\n", output_filename);
		exit(1);
	}

	fin = fopen(input_filename, "rb");
	if (!fin) {
		fprintf(stderr, "Could not open %s\n", input_filename);
		exit(1);
	}

	/* frame containing input raw audio */
	frame = avcodec_alloc_frame();
	if (!frame) {
		fprintf(stderr, "Could not allocate audio frame\n");
		exit(1);
	}

	frame->nb_samples = c->frame_size;
	frame->format = c->sample_fmt;
	frame->channel_layout = c->channel_layout;

	/* the codec gives us the frame size, in samples,
	 * we calculate the size of the samples buffer in bytes */
	buffer_size = av_samples_get_buffer_size(NULL, c->channels, c->frame_size,
			c->sample_fmt, 0);
	samples = av_malloc(buffer_size);
	if (!samples) {
		fprintf(stderr, "Could not allocate %d bytes for samples buffer\n",
				buffer_size);
		exit(1);
	}
	/* setup the data pointers in the AVFrame */
	ret = avcodec_fill_audio_frame(frame, c->channels, c->sample_fmt,
			(const uint8_t*) samples, buffer_size, 0);
	if (ret < 0) {
		fprintf(stderr, "Could not setup audio frame\n");
		exit(1);
	}

	for (;;) {

		av_init_packet(&pkt);
		pkt.data = samples;
		pkt.size = fread(samples, 1, buffer_size, fin);
		if (pkt.size == 0) {
			break;
		}

		ret = avcodec_encode_audio2(c, &pkt, frame, &got_output);
		if (ret < 0) {
			fprintf(stderr, "Error encoding audio frame\n");
			exit(1);
		}
		if (got_output) {
			fwrite(pkt.data, 1, pkt.size, fout);
			av_free_packet(&pkt);
			numberframe++;
			printf("save frame %d\n", numberframe);
		}

	}

	/* get the delayed frames */
	for (got_output = 1; got_output; i++) {
	  av_init_packet(&pkt);
		pkt.size=1024;
		ret = avcodec_encode_audio2(c, &pkt, NULL, &got_output);
		if (ret < 0) {
			fprintf(stderr, "Error encoding frame\n");
			exit(1);
		}

		if (got_output) {
			fwrite(pkt.data, 1, pkt.size, fout);
			av_free_packet(&pkt);
		}
	}
	fclose(fout);
	fclose(fin);
	av_freep(&samples);
	avcodec_free_frame(&frame);
	avcodec_close(c);
	av_free(c);
	printf("audio encode finish...");
}




PS:水平有限,如以上内容有误,欢迎指正!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值