使用ffmpeg转码pcm至aac格式

准备工作

去官网下载源码自己编译所需要的库,或者直接从官网下载已经编写好的库,由于本例是Window平台下的开发,而官网已经有了编译好的库,所以直接下载编译所需要的库文件即可。下载地址:需要下载两个压缩包,Dev版本和Shared版本,其中Dev版本是头文件和lib库文件,Shared是包含运行所需要的dll文件。

下载完成后,需要把这些头文件、静态库、动态链接库引入到我们的工程里面,不过在Windows下面,头文件除了要用到FFMPEG提供的,还要使用另外三个文件:inttypes.h,stdint.h,_mingw.h,这三个文件放到FFMPEG头文件的根目录下即可。

项目工程

代码示例

// C++代码需要加这个!!否则找不到函数的
extern "C"
{
#include "libavcodec\avcodec.h"
#include "libavformat\avformat.h"
#include "libswscale\swscale.h"

// 链接的ffmpeg库,我把所有可能需要用到的都写这里了
#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "avcodec.lib")
#pragma comment (lib, "avdevice.lib")
#pragma comment (lib, "avfilter.lib")
#pragma comment (lib, "avformat.lib")
#pragma comment (lib, "avutil.lib")
#pragma comment (lib, "swresample.lib")
#pragma comment (lib, "swscale.lib")
};

int main(int argc, char* argv[])
{
	AVFormatContext* pFormatCtx;
	AVOutputFormat* fmt;
	AVStream* audio_st;
	AVCodecContext* pCodecCtx;
	AVCodec* pCodec;

	uint8_t* frame_buf;
	AVFrame* frame;
	int size;

	FILE *fileIn = fopen("Beyond.pcm", "rb");
	char* fileOut = "Beyond.aac";		

	// 初始化注册FFMPEG以供使用
	av_register_all();

	// 解码文件格式
	avformat_alloc_output_context2(&pFormatCtx, NULL, NULL, fileOut);
	fmt = pFormatCtx->oformat;

	//注意输出路径
	if (avio_open(&pFormatCtx->pb, fileOut, AVIO_FLAG_READ_WRITE) < 0)
	{
		printf("输出文件打开失败!\n");
		return -1;
	}

	audio_st = avformat_new_stream(pFormatCtx, 0);
	if (audio_st == NULL)
	{
		printf("新建流失败!!!\n");
		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, fileOut, 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++)
	{
		//读入PCM
		if (fread(frame_buf, 1, size, fileIn) < 0)
		{
			printf("文件读取错误!\n");
			return -1;
		}
		else if(feof(fileIn))
		{
			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)
		{
			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(fileIn);

	printf("转码完毕!!!\n");
	return 0;
}

由于FFMPEG会没事就修改接口,所以不同版本的FFMPEG可能会编译不过,反正2015年1月23日17:29:31是可以编译通过的。

参考

最简单的基于FFMPEG的音频编码器(PCM编码为AAC)

时间: 2024-08-24 21:34:36

使用ffmpeg转码pcm至aac格式的相关文章

ffmpeg转码MPEG2-TS的音视频同步机制分析

http://blog.chinaunix.net/uid-26000296-id-3483782.html 一.FFmpeg忽略了adaptation_field()数据FFmpeg忽略了包含PCR值的adaptation_filed数据; 代码(libavformat/mpegts.c)分析如下: /* 解析TS包 */int handle_packet(MpegTSContext *ts, const uint8_t *packet){  ...   pid = AV_RB16(packe

ffmpeg转码时对编码率和固定码率的处理

http://www.rosoo.net/a/201107/14663.html 一般fps在代码里这样表示 Fps = den/num 如果den = 15,num=1,则fps = 15. 如果帧率固定,pts*fps 就表示当前是第几帧. 当输入视频流的帧率不固定,如rmvb ,而输出视频流的帧率固定,ffmpeg作如下处理(参考ffmpeg代码版本0.6.1): 1.  记录和输出视频流ost相对应的输入视频流ist,变量为ost->sync_ist.这是在av_transcode函数进

最新版ffmpeg源码分析

最新版ffmpeg源码分析一:框架 (ffmpeg v0.9) 框架 最新版的ffmpeg中发现了一个新的东西:avconv,而且ffmpeg.c与avconv.c一个模样,一研究才发现是libav下把ffmpeg改名为avconv了. 到底libav与ffmpeg现在是什么个关系?我也搞得希里糊涂的,先不管它了. ffmpeg的主要功能是音视频的转换和处理.其功能之强大已经到了匪夷所思的地步(有点替它吹了).它的主要特点是能做到把多个输入文件中的任意几个流重新组合到输出文件中,当然输出文件也可

FFmpeg源码简单分析:结构体成员管理系统-AVOption

===================================================== FFmpeg的库函数源码分析文章列表: [架构图] FFmpeg源码结构图 - 解码 FFmpeg源码结构图 - 编码 [通用] FFmpeg 源码简单分析:av_register_all() FFmpeg 源码简单分析:avcodec_register_all() FFmpeg 源码简单分析:内存的分配和释放(av_malloc().av_free()等) FFmpeg 源码简单分析:常

FFmpeg源码结构图 - 解码

===================================================== FFmpeg的库函数源码分析文章列表: [架构图] FFmpeg源码结构图 - 解码 FFmpeg源码结构图 - 编码 [通用] FFmpeg 源码简单分析:av_register_all() FFmpeg 源码简单分析:avcodec_register_all() FFmpeg 源码简单分析:内存的分配和释放(av_malloc().av_free()等) FFmpeg 源码简单分析:常

把自定义的demuxer加入ffmpeg源码

.简介:把上一篇文章中的demuxer加入ffmpeg源码中去,使可以用命令行方式调用自定义的demuxer 第一步: 在libavformat目录下新建mkdemuxer.c和mkdemuxer.h,代码如下: mkdemuxer.c: [cpp] view plain copy /* *实现一个自己的demuxer并加入到demuxer链中去 *作者:缪国凯(MK) *[email protected] *2015-6-3 */ #include "mkdemuxer.h" typ

FFmpeg源码简单分析:libswscale的sws_scale()

===================================================== FFmpeg的库函数源码分析文章列表: [架构图] FFmpeg源码结构图 - 解码 FFmpeg源码结构图 - 编码 [通用] FFmpeg 源码简单分析:av_register_all() FFmpeg 源码简单分析:avcodec_register_all() FFmpeg 源码简单分析:内存的分配和释放(av_malloc().av_free()等) FFmpeg 源码简单分析:常

ffmpeg转码视频为mp4

ffmpeg是一个强大视频转码工具 参考的中文文档: https://github.com/biglazy/gist/blob/master/ffmpeg/ffmpeg.txt https://legacy.gitbook.com/book/xdsnet/other-doc-cn-ffmpeg/details centos6.6 64位安装 安装libx264(视频转码必备) git clone git://git.videolan.org/x264.git cd x264 ./configur

又是正版!Win下ffmpeg源码调试分析二(Step into ffmpeg from Opencv for bugs in debug mode with MSVC)

最近工作忙一直没时间写,但是看看网络上这方面的资源确实少,很多都是linux的(我更爱unix,哈哈),而且很多是直接引入上一篇文章的编译结果来做的.对于使用opencv但是又老是被ffmpeg库坑害的朋友们,可能又爱又恨,毕竟用它处理和分析视频是第一选择,不仅是因为俩者配合使用方便,而且ffmpeg几乎囊括了我所知道的所有解编码器,但是正是因为这个导致了一些bug很难定位,所以有必要考虑一下如何快速定位你的ffmpeg bug. sorry,废话多了.首先给个思路: 1.使opencv 的hi