准备工作
去官网下载源码自己编译所需要的库,或者直接从官网下载已经编写好的库,由于本例是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是可以编译通过的。
参考
时间: 2024-11-24 13:31:00