以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:水平有限,如以上内容有误,欢迎指正!