ffmpeg音频编码示例

来源:互联网 发布:smaat7软件下载 编辑:程序博客网 时间:2024/05/24 08:34
首先,声明:本文代码参考yang xian 的原有代码的基础上添加了注释,另外,因为原先的代码中用的函数,为旧版本的ffmpeg中的,所以,本文中以注释的形式给出了新版本中替换的函数,原文下载地址:http://download.csdn.net/detail/yang_xian521/4399293
/************************************************************************* Copyright(c) 2012  Yang Xian* All rights reserved.** File:AudioEncode.cpp* Brief: 音频的编码* Version: 1.0* Author: Yang Xian* Email: yang_xian521@163.com* Date:2012/06/28* History:************************************************************************/#include <stdlib.h>#include <stdio.h>extern "C"{#include "libavformat/avformat.h"#include "libswscale/swscale.h"};void main(){int16_t *samples;uint8_t *audio_outbuf;int audio_outbuf_size;int audio_input_frame_size;double audio_pts;const char* filename = "test.wav";FILE *fin = fopen("out.pcm", "rb"); //音频源文件 AVOutputFormat *fmt;//数据输出格式AVFormatContext *oc;//AvFormatContext,输入输出格式的一个容器AVStream * audio_st;//保存读出的数据流av_register_all();fmt = guess_format(NULL, filename, NULL);  // guess the format base on the filenameoc = av_alloc_format_context();oc->oformat = fmt;snprintf(oc->filename, sizeof(oc->filename), "%s", filename);audio_st = NULL;if (fmt->audio_codec != CODEC_ID_NONE)  //CODEC_ID_NONE:源代码地址:http://libav.org/doxygen/release/0.8/rtp_8c_source.html{AVCodecContext *c;audio_st = av_new_stream(oc, 1);  //新版中替换为 avformat_new_stream(oc, NULL)c = audio_st->codec;c->codec_id = fmt->audio_codec;c->codec_type = CODEC_TYPE_AUDIO; //新版中替换为:AVMEDIA_TYPE_AUDIOc->bit_rate = 128000;  //比特率c->sample_rate = 44100;  //采样频率c->channels = 2;  //声道数}if (av_set_parameters(oc, NULL) < 0)  //设置初始化参数, 新版本中替换为avformat_write_header();{return;}dump_format(oc, 0, filename, 1);//函数负责为pFormatCtx->streams填充上正确的信息if (audio_st){AVCodecContext* c;AVCodec* codec;c = audio_st->codec;codec = avcodec_find_encoder(c->codec_id);avcodec_open(c, codec);audio_outbuf_size = 1000;audio_outbuf = (uint8_t*)av_malloc(audio_outbuf_size);if (c->frame_size <= 1){audio_input_frame_size = audio_outbuf_size / c->channels;switch (audio_st->codec->codec_id){case CODEC_ID_PCM_S16LE:case CODEC_ID_PCM_S16BE:case CODEC_ID_PCM_U16LE:case CODEC_ID_PCM_U16BE:audio_input_frame_size >>= 1;break;default:break;}}else{audio_input_frame_size = c->frame_size;}samples = (int16_t*)av_malloc(audio_input_frame_size*2*c->channels);}if (!fmt->flags & AVFMT_NOFILE)  //AVFMT_NOFILE meant no seeking support{if (url_fopen(&oc->pb, filename, URL_WRONLY) < 0) //新版本中替换为avio_open(&oc->pb, filename, URL_WRONLY)) < 0){return;}}av_write_header(oc);   //替换为avformat_write_headerfor (;;){if (audio_st){audio_pts = (double)audio_st->pts.val * audio_st->time_base.num / audio_st->time_base.den;}else{audio_pts = 0.0;}if (!audio_st || audio_pts >= 360.0){break;}if (fread(samples, 1, audio_input_frame_size*2*audio_st->codec->channels, fin) <= 0){break;}AVCodecContext* c;AVPacket pkt;av_init_packet(&pkt);c = audio_st->codec;pkt.size = avcodec_encode_audio(c, audio_outbuf, audio_outbuf_size, samples);  //编码//av_rescale_q是用来把时间戳从一个时基调整到另外一个时基时候用的函数。它基本的动作是计算a*b/c,//但是这个函数还是必需的,因为直接计算会有溢出的情况发生pkt.pts = av_rescale_q(c->coded_frame->pts, c->time_base, audio_st->time_base);pkt.flags |= PKT_FLAG_KEY;//新版本中替换为AV_PKT_FLAG_KEYpkt.stream_index = audio_st->index;pkt.data = audio_outbuf;if (av_write_frame(oc, &pkt) != 0){return;}}if (audio_st){avcodec_close(audio_st->codec);av_free(samples);av_free(audio_outbuf);}av_write_trailer(oc);for (int i=0; i<oc->nb_streams; i++){av_freep(&oc->streams[i]->codec);av_freep(&oc->streams[i]);}if (!(fmt->flags & AVFMT_NOFILE)){url_fclose(oc->pb); //替换为avio_close}av_free(oc);fclose(fin);system("pause");}
因为,ffmpeg给以找到合适的文档支持,因此,不对的地方,请大家积极修改。
0 0
原创粉丝点击