本文介绍一个最简单的基于FFMPEG的音频编码器。该编码器实现了PCM音频采样数据编码为AAC的压缩编码数据。编码器代码十分简单,但是每一行代码都很重要。通过看本编码器的源代码,可以了解FFMPEG音频编码的流程。
本程序使用最新版的类库(编译时间为2014.5.6),开发平台为VC2010。所有的配置都已经做好,只需要运行就可以了。
流程图(2014.9.29更新)
下面附一张使用FFmpeg编码音频的流程图。使用该流程,不仅可以编码AAC的音频,而且可以编码MP3,MP2等等各种FFmpeg支持的音频。图中蓝色背景的函数是实际输出数据的函数。浅绿色的函数是音频编码的函数。
简单介绍一下流程中各个函数的意义:
av_register_all():注册FFmpeg所有编解码器。
avformat_alloc_output_context2():初始化输出码流的AVFormatContext。
avio_open():打开输出文件。
av_new_stream():创建输出码流的AVStream。
avcodec_find_encoder():查找编码器。
avcodec_open2():打开编码器。
avformat_write_header():写文件头(对于某些没有文件头的封装格式,不需要此函数。比如说MPEG2TS)。
avcodec_encode_audio2():编码音频。即将AVFrame(存储PCM采样数据)编码为AVPacket(存储AAC,MP3等格式的码流数据)。
av_write_frame():将编码后的视频码流写入文件。
av_write_trailer():写文件尾(对于某些没有文件头的封装格式,不需要此函数。比如说MPEG2TS)。
代码
贴上代码:
/*
*最简单的基于FFmpeg的音频编码器
*Simplest FFmpeg Audio Encoder
*
*雷霄骅 Lei Xiaohua
*leixiaohua1020@126.com
*中国传媒大学/数字电视技术
*Communication University of China / Digital TV Technology
*http://blog.csdn.net/leixiaohua1020
*
*本程序实现了音频PCM采样数据编码为压缩码流(MP3,WMA,AAC等)。
*是最简单的FFmpeg音频编码方面的教程。
*通过学习本例子可以了解FFmpeg的编码流程。
*This software encode PCM data to AAC bitstream.
*It's the simplest audio encoding software based on FFmpeg.
*Suitable for beginner of FFmpeg
*/
#include "stdafx.h"
extern "C"
{
#include "libavcodec\avcodec.h"
#include "libavformat\avformat.h"
#include "libswscale\swscale.h"
};
int _tmain(int argc, _TCHAR* argv[])
{
AVFormatContext* pFormatCtx;
AVOutputFormat* fmt;
AVStream* audio_st;
AVCodecContext* pCodecCtx;
AVCodec* pCodec;
uint8_t* frame_buf;
AVFrame* frame;
int size;
FILE *in_file = fopen("tdjm.pcm", "rb"); //音频PCM采样数据
int framenum=1000; //音频帧数
const char* out_file = "tdjm.aac"; //输出文件路径
av_register_all();
//方法1.组合使用几个函数
pFormatCtx = avformat_alloc_context();
//猜格式
fmt = av_guess_format(NULL, out_file, NULL);
pFormatCtx->oformat = fmt;
//方法2.更加自动化一些
//avformat_alloc_output_context2(&pFormatCtx, NULL, NULL, out_file);
//fmt = pFormatCtx->oformat;
//注意输出路径
if (avio_open(&pFormatCtx->pb,out_file, AVIO_FLAG_READ_WRITE) < 0)
{
printf("输出文件打开失败!\n");
return -1;
}
audio_st = av_new_stream(pFormatCtx, 0);
if (audio_st==NULL){
return -1;
}
pCodecCtx = audio_st->codec;
pCodecCtx->codec_id = fmt->audio_codec;
pCodecCtx->codec_type = AVMEDIA_TYPE_AUDIO;
pCodecCtx->sample_fmt = AV_SAMPLE_FMT_S16;
pCodecCtx->sample_rate= 44100;
pCodecCtx->channel_layout=AV_CH_LAYOUT_STEREO;
pCodecCtx->channels = av_get_channel_layout_nb_channels(pCodecCtx->channel_layout);
pCodecCtx->bit_rate = 64000;
//输出格式信息
av_dump_format(pFormatCtx, 0, out_file, 1);
pCodec = avcodec_find_encoder(pCodecCtx->codec_id);
if (!pCodec)
{
printf("没有找到合适的编码器!\n");
return -1;
}
if (avcodec_open2(pCodecCtx, pCodec,NULL) < 0)
{
printf("编码器打开失败!\n");
return -1;
}
frame = avcodec_alloc_frame();
frame->nb_samples= pCodecCtx->frame_size;
frame->format= pCodecCtx->sample_fmt;
size = av_samples_get_buffer_size(NULL, pCodecCtx->channels,pCodecCtx->frame_size,pCodecCtx->sample_fmt, 1);
frame_buf = (uint8_t *)av_malloc(size);
avcodec_fill_audio_frame(frame, pCodecCtx->channels, pCodecCtx->sample_fmt,(const uint8_t*)frame_buf, size, 1);
//写文件头
avformat_write_header(pFormatCtx,NULL);
AVPacket pkt;
av_new_packet(&pkt,size);
for (int i=0; i<framenum; i++){
//读入PCM
if (fread(frame_buf, 1, size, in_file) < 0)
{
printf("文件读取错误!\n");
return -1;
}else if(feof(in_file)){
break;
}
frame->data[0] = frame_buf; //采样信号
frame->pts=i*100;
int got_frame=0;
//编码
int ret = avcodec_encode_audio2(pCodecCtx, &pkt,frame, &got_frame);
if(ret < 0)
{
printf("编码错误!\n");
return -1;
}
if (got_frame==1)
{
printf("编码成功第%d帧!\n",i);
pkt.stream_index = audio_st->index;
ret = av_write_frame(pFormatCtx, &pkt);
av_free_packet(&pkt);
}
}
//写文件尾
av_write_trailer(pFormatCtx);
//清理
if (audio_st)
{
avcodec_close(audio_st->codec);
av_free(frame);
av_free(frame_buf);
}
avio_close(pFormatCtx->pb);
avformat_free_context(pFormatCtx);
fclose(in_file);
return 0;
}
工程下载地址:
http://download.csdn.net/detail/leixiaohua1020/7324091
SourceForge项目地址:
https://sourceforge.net/projects/simplestffmpegaudioencoder/
PUDN源代码:
http://www.pudn.com/downloads644/sourcecode/multimedia/detail2605236.html
分享到:
相关推荐
该图像编码器实现了音频PCM采样数据编码为AAC码流。 尽管该音频编码器的代码十分简单,但是几乎包含了使用FFMPEG编码一个音频所有必备的API。十分适合FFmpeg的初学者。 工程基于VC2010。 使用了2014.5.6版本的...
simplest_ffmpeg_audio_encoder--最简单的基于FFMPEG的音频编码器(PCM编码为AAC)
该音频编码器实现了音频PCM采样数据编码为AAC码流。 尽管该音频编码器的代码十分简单,但是几乎包含了使用FFMPEG编码一个音频所有必备的API。十分适合FFmpeg的初学者。 1.1版本增加了多平台下编译的支持:Windows,...
win10 x64bit环境做的一个调用新版ffmpeg4.0.2版本的pcm转aac编码器,解决新版ffmpeg不能直接编码成aac问题。
最简单的基于 FFmpeg 的音频编码器 本程序实现了音频 PCM 采样数据编码为压缩码流(MP3,WMA,AAC 等)。是最简单的 FFmpeg 音频编码方面的教程。通过学习本例子可以了解 FFmpeg 的编码流程。
一个完整的视频直播过程,包括采集、处理、编码、封装、推流、传输、转码、分发、解码、播放等。;音频采集音频的采集过程主要通过设备将环境中的...音频编码器:Mp3,AAC等。; 把编码器生成的多媒体内容(视频,音频,
支持的音频编码器:Lame(MP3),MP2,AC3,AAC,WMA,PCM 16 位。 支持使用 H.264(x264)编码器的多线程编码。 许多预定义的转换配置文件。可以将您自己的设置保存到INI文件中。 大量的编码参数:音频和视频的...
本播放器支持PCM_MULAW、PCM_ALAW、AAC编码格式音频的播放。本播放器支持单路播放器与多路播放器,单路播放器中ctYuvOpenglWidget是让让YUV转RGB在GPU中处理而重写的类,ctOpenglWidget则是直接对RGB图像进行渲染。...
该演示允许用户使用麦克风在浏览器会话中记录声音,将原始PCM字节传送到客户端FFMPEG编码器,然后将音频作为AAC编码的MP4文件播放。 我建立了这个项目,作为将上的基于语音的视频播放器从Flash迁移到HTML5的概念...
I帧图像是预测出现在图像序列中的,出现频率指向编码器选择; I帧是P帧和B帧的参考帧(其质量直接影响到同组中以后各帧的质量); IDR帧是帧组GOP的基础帧(第一个(I)帧),在成对的GOP中只有一个ID