您的位置:首页 > 其它

ffmpeg音频编码

2012-12-28 16:32 211 查看
以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:水平有限,如以上内容有误,欢迎指正!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: