这一篇博文主要是使用ffmpeg提取h264视频流和pcm音频流,主要是用到上一篇的aac解码成pcm(https://blog.csdn.net/yinsui1839/article/details/80433677)           和主要参考自雷神博客 https://blog.csdn.net/leixiaohua1020/article/details/39767055

代码如下:

/********
*本代码参考自雷神博客 https://blog.csdn.net/leixiaohua1020/article/details/39767055
*
**********/
#ifdef __cplusplus
extern "C"
{
#endif
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavdevice/avdevice.h>
#include<libswresample/swresample.h>
#ifdef __cplusplus
};
#endif#define MAX_AUDIO_FRAME_SIZE  192000
#define SAMPLE_PRT(fmt...)   \do {\printf("[%s]-%d: ", __FUNCTION__, __LINE__);\printf(fmt);\}while(0)//'1': Use H.264 Bitstream Filter
#define USE_H264BSF 1int main(int argc, char* argv[])
{AVFormatContext *ifmt_ctx = NULL;AVPacket pkt;AVCodecContext *a_codecctx;AVCodec *a_codec;int ret, i;int videoindex=-1,audioindex=-1;const char *in_filename  = "./hefang.mp4";const char *out_filename_v = "./hefang.h264";const char *out_filename_a = "./hefang.pcm";int got_picture=0;FILE *fp_audio=fopen(out_filename_a,"wb+");FILE *fp_video=fopen(out_filename_v,"wb+");unsigned char *h264_buf;int h264_len;av_register_all();ifmt_ctx = avformat_alloc_context();//Inputif ((ret = avformat_open_input(&ifmt_ctx, in_filename, 0, 0)) < 0) {printf( "Could not open input file.");return -1;}if ((ret = avformat_find_stream_info(ifmt_ctx, 0)) < 0) {printf( "Failed to retrieve input stream information");return -1;}videoindex=-1;for(i=0; i<ifmt_ctx->nb_streams; i++) {if(ifmt_ctx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO){videoindex=i;}else if(ifmt_ctx->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO){audioindex=i;}}av_dump_format(ifmt_ctx, 0, in_filename, 0);a_codecctx=ifmt_ctx->streams[audioindex]->codec;a_codec=avcodec_find_decoder(a_codecctx->codec_id);if (a_codec == NULL)SAMPLE_PRT("find codec fail");if(avcodec_open2(a_codecctx,a_codec,NULL)<0){SAMPLE_PRT("error avcodec_open2\n");return -1;}AVFrame *frame = av_frame_alloc();//设置转码后输出相关参数//采样的布局方式uint64_t out_channel_layout = AV_CH_LAYOUT_MONO;   //单通道//采样个数int out_nb_samples = 1024;////采样格式enum AVSampleFormat  sample_fmt = AV_SAMPLE_FMT_S16;//采样率int out_sample_rate = 44100;//通道数int out_channels = av_get_channel_layout_nb_channels(out_channel_layout);//创建bufferint buffer_size = av_samples_get_buffer_size(NULL, out_channels, out_nb_samples, sample_fmt, 1);uint8_t *buffer = (uint8_t *)av_malloc(MAX_AUDIO_FRAME_SIZE * 2);int64_t in_channel_layout = av_get_default_channel_layout(a_codecctx->channels);//打开转码器struct SwrContext *convert_ctx = swr_alloc();//设置转码参数convert_ctx = swr_alloc_set_opts(convert_ctx, out_channel_layout, sample_fmt, out_sample_rate, \in_channel_layout, a_codecctx->sample_fmt, a_codecctx->sample_rate, 0, NULL);//初始化转码器swr_init(convert_ctx);#if USE_H264BSFAVBitStreamFilterContext* h264bsfc =  av_bitstream_filter_init("h264_mp4toannexb");
#endif
//        int seek_pos;
//        seek_pos = 19*1000000;
//        av_seek_frame(ifmt_ctx,-1,seek_pos,AVSEEK_FLAG_BACKWARD);while(av_read_frame(ifmt_ctx, &pkt)>=0){if(pkt.stream_index==videoindex){
#if USE_H264BSFav_bitstream_filter_filter(h264bsfc, ifmt_ctx->streams[videoindex]->codec, NULL, &h264_buf, &h264_len, pkt.data, pkt.size, 0);#endiffwrite(h264_buf,1,h264_len,fp_video);av_free(h264_buf);}else if(pkt.stream_index==audioindex){if (avcodec_decode_audio4(a_codecctx,frame, &got_picture, &pkt) < 0) {   //SAMPLE_PRT("error  avcodec_decode_audio4\n");return -1;}if(got_picture>0){swr_convert(convert_ctx, &buffer, MAX_AUDIO_FRAME_SIZE, (const uint8_t **)frame->data, frame->nb_samples);  //转码fwrite(buffer, 1, buffer_size, fp_audio);}got_picture=0;}av_free_packet(&pkt);}
#if USE_H264BSFav_bitstream_filter_close(h264bsfc);
#endiffclose(fp_video);fclose(fp_audio);avformat_close_input(&ifmt_ctx);swr_free(&convert_ctx);if (ret < 0 && ret != AVERROR_EOF) {SAMPLE_PRT( "Error occurred.\n");return -1;}return 0;
}
我刚刚开始用雷神代码的时候发现开发板子上的内存很快就用光了,然后自己仔细查找才发现av_bitstream_filter_filter会给传进去&h264_buf开辟新的空间,所以在用完我就马上释放掉,这个问题才得以解决;

linux下编译: g++ main.cpp -lavformat -lavcodec -lavdevice -lavutil -lz -lm -lswresample

mp4文件可以从我这边下载

https://download.csdn.net/download/yinsui1839/10435102

没有积分可以在评论区留下邮箱

ffmpeg 提取mp4里的h264流和pcm流相关推荐

  1. Android直播开发之旅(17):使用FFmpeg提取MP4中的H264和AAC

    最近在开发中遇到了一个问题,即无法提取到MP4中H264流的关键帧进行处理,且保存到本地的AAC音频也无法正常播放.经过调试分析发现,这是由于解封装MP4得到的H264和AAC是ES流,它们缺失解码时 ...

  2. 使用ffmpeg将mp4文件转为h264文件或者264文件

    1.不解码和从新编码,只是换个格式封装. ffmpeg -i test.mp4 -c copy test.h264 2. 解码再编码 ffmpeg -i test.mp4 -c h264 test.h ...

  3. ffmpeg提取mp4文件中的音频,保存为wav文件

    如题,一个命令行即可: ffmpeg -i 123.mp4 -acodec pcm_s16le -f s16le -ac 1 -ar 16000 -f wav 123.wav 这样就生成了一个wav文 ...

  4. ffmpeg提取音频文件命令并转化成pcm格式

    本文转载自:https://blog.csdn.net/u014552102/article/details/82734278 一.PCM文件的定义    PCM文件:模拟音频信号经模数转换(A/D变 ...

  5. ffmpeg 从mp4上提取H264的nalu

    1.获取数据 ffmpeg读取mp4中的H264数据,并不能直接得到NALU,文件中也没有储存0x00000001的分隔符.下面这张图为packet.data中的数据 从图中可以发现,packet中的 ...

  6. 使用FFMpeg将MP4转为m3u8

    使用ffmpeg将mp4切成ts片段的时候会碰到一个问题,就是生成的m3u8文件里只有最后的五个片段的信息. 这是因为ffmpeg 默认的list size 为5,所以只获得最后的5个片段.为了解决这 ...

  7. FFmpeg提取视频(mp4)中的音频(m4a)

    目的 方法 1. 下载 FFmpeg 下载地址 下载后解压缩,我解压缩到的位置是:D:\Program Files 并将文件夹名称改为ffmpeg 自己可以根据情况,随便解压缩到什么位置都可以 2. ...

  8. 用ffmpeg修改MP4文件头信息,使其支持流式加载及播放

    经常有用户反映,有些网页中加载的mp4文件,有的可以加载一点就开始播放,有的就必须全部加载完才能播. 经核实,主要是头信息的数据顺序有关,用工具:mp4info.exe可以查看mp4文件的结构信息: ...

  9. ffmpeg实现g711音频和H264,H265封装mp4(整理,非原创)

    效果:实现G711和H264,H265存为mp4,录像文件VLC和暴风影音可播放 注:播放mp4音视频没问题,但使用mp4分析工具分析 Sample size有问题(待解决) 修改1: (资料来自:g ...

最新文章

  1. Python基础——for/while循环
  2. Vue.js 技术揭秘学习 (2) Vue 实例挂载的实现
  3. python读取只读word只读_Python用于NLP :处理文本和PDF文件
  4. think in uml-关系
  5. java8根据某个id删选_Java 8可选
  6. python怎么切换中文键盘_python模拟键盘输入 切换键盘布局过程解析
  7. html5 mask,HTML5 Canvas渐进填充与透明实现图像的Mask效果
  8. spark java api通过run as java application运行的方法
  9. php simplexml 删除,请问一下PHP SimpleXML怎么-删除xpath节点
  10. opencv打开的图片应用于nn.Conv2d()(二)
  11. mysql left right 一张图解
  12. ENVI 监督分类Max stdev from Mean 参数IDL中的设置
  13. 浪潮服务器raid虚拟驱动,浪潮服务器RAID 卡驱动
  14. 【LitJson】如何判断字符串中是否有某个key
  15. 欧路词典的词典导入教程
  16. 华为云计算认证考试大纲是什么?华为云计算认证含金量高吗?
  17. SOCK_NONBLOCK,accept4 阻塞与非阻塞SOCKET
  18. Pytorch踩坑记:赋值、浅拷贝、深拷贝三者的区别以及model.state_dict()和model.load_state_dict()的坑点
  19. 锐捷睿易:扩大DHCP掩码导致AP不上线问题
  20. HTML与CSS总结

热门文章

  1. 毕设测试问题记录1-LCD初始化了但是不工作、初始化顺序、两个单片机用485通信异常、串口标志位TXE和TC
  2. 解决 *** error 65: access violation at 0x0000000C : no 'read' permission
  3. Visual Studio 2017(C#)、Microsoft Access 2010搭建ASP.NET网站(页面功能概述一)
  4. Th4.5:using定义模板别名之详述
  5. glew java_支持opengl4.3的glew库(64位)
  6. 某年中某周的开始与结束日期以及某月的开始结束
  7. Redis存储缓存工具类简单封装
  8. 树莓派3B入门使用教程
  9. 在vue-cli里如何对接融云webIM
  10. 手机投屏软件哪个好用,Airserver投屏软件免费下载