项目地址
https://github.com/979451341/RtmpSave

这个项目主要代码我是从雷神那弄过来的,不愧是雷神,我就配个环境搞个界面就可以用代码了。

这一次说的是将RTMP流媒体保存成为一个本地的FLV文件。因为播放视频本身占有很多技术难点,我先不做边获取RTMP流边播放了,这一次主要说如何获取RTMP流。

说说代码

初始化组件和网络环境

    av_register_all();//Networkavformat_network_init();

打开RTMP流,获取RTMP流的信息,并搜索到其中视频流的位置

    //Inputif ((ret = avformat_open_input(&ifmt_ctx, in_filename, 0, 0)) < 0) {printf( "Could not open input file.");goto end;}if ((ret = avformat_find_stream_info(ifmt_ctx, 0)) < 0) {printf( "Failed to retrieve input stream information");goto end;}for(i=0; i<ifmt_ctx->nb_streams; i++)if(ifmt_ctx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO){videoindex=i;break;}

将RTMP流的一些配置信息保存在输入环境信息

    av_dump_format(ifmt_ctx, 0, in_filename, 0);

根据输出flv文件名称和路径得到输出环境信息

    avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, out_filename); //RTMPif (!ofmt_ctx) {printf( "Could not create output context\n");ret = AVERROR_UNKNOWN;goto end;}

把输出环境信息的输出格式信息保存在ofmt

ofmt = ofmt_ctx->oformat;

创建一条输出环境信息的流,就将输如环境信息里一条流复制到其中,并对每一条流的编码做出配置

    for (i = 0; i < ifmt_ctx->nb_streams; i++) {//Create output AVStream according to input AVStreamAVStream *in_stream = ifmt_ctx->streams[i];AVStream *out_stream = avformat_new_stream(ofmt_ctx, in_stream->codec->codec);if (!out_stream) {printf( "Failed allocating output stream\n");ret = AVERROR_UNKNOWN;goto end;}//Copy the settings of AVCodecContextret = avcodec_copy_context(out_stream->codec, in_stream->codec);if (ret < 0) {printf( "Failed to copy context from input to output stream codec context\n");goto end;}out_stream->codec->codec_tag = 0;if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)out_stream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;}

调试函数

av_dump_format(ofmt_ctx, 0, out_filename, 1);

打开输出url路径

    if (!(ofmt->flags & AVFMT_NOFILE)) {ret = avio_open(&ofmt_ctx->pb, out_filename, AVIO_FLAG_WRITE);if (ret < 0) {printf( "Could not open output URL '%s'", out_filename);goto end;}}

向输出环境写入文件头部

    //Write file headerret = avformat_write_header(ofmt_ctx, NULL);if (ret < 0) {printf( "Error occurred when opening output URL\n");goto end;}

配置H264编码器

#if USE_H264BSFAVBitStreamFilterContext* h264bsfc =  av_bitstream_filter_init("h264_mp4toannexb");
#endif

开始循环读帧写入flv文件

读取一帧RTMP流的视屏流数据

        ret = av_read_frame(ifmt_ctx, &pkt);if (ret < 0)break;

计算对应这一帧输入RTMP流数据的一帧输出数据的相关显示帧时间pts,解码帧时间dts,距离上一帧到下一帧的播放时间差距duration

        pkt.pts = av_rescale_q_rnd(pkt.pts, in_stream->time_base, out_stream->time_base, (AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));pkt.dts = av_rescale_q_rnd(pkt.dts, in_stream->time_base, out_stream->time_base, (AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));pkt.duration = av_rescale_q(pkt.duration, in_stream->time_base, out_stream->time_base);

根据H264编码格式转换一帧输出数据

#if USE_H264BSFav_bitstream_filter_filter(h264bsfc, in_stream->codec, NULL, &pkt.data, &pkt.size, pkt.data, pkt.size, 0);
#endif

将这一帧输出数据写入flv文件,然后释放这一帧数据

        ret = av_interleaved_write_frame(ofmt_ctx, &pkt);if (ret < 0) {printf( "Error muxing packet\n");break;}av_free_packet(&pkt);

关闭H264编码器

#if USE_H264BSFav_bitstream_filter_close(h264bsfc);
#endif

释放输入、输出环境

    av_write_trailer(ofmt_ctx);end:avformat_close_input(&ifmt_ctx);/* close output */if (ofmt_ctx && !(ofmt->flags & AVFMT_NOFILE))avio_close(ofmt_ctx->pb);avformat_free_context(ofmt_ctx);if (ret < 0 && ret != AVERROR_EOF) {printf( "Error occurred.\n");return -1;}

说说app的使用

那个点击button就可以了,点击后它会字样会变成started,这样他就在保存RTMP流文件了,再点击end按钮就可以停止保存,这个时候你去相应目录看视频就可以了。

Android 音视频深入 十七 FFmpeg 获取RTMP流保存为flv (附源码下载)相关推荐

  1. android flv 编码器,Android 音视频深入 十七 FFmpeg 获取 RTMP 流保存为 flv (附源码下载)...

    Android 音视频深入 十七 FFmpeg 获取 RTMP 流保存为 flv (附源码下载) 项目地址 https://github.com/979451341/RtmpSave 这个项目主要代码 ...

  2. Android 音视频深入 一 AudioRecord录音生成pcm转换为wav(附源码下载)

    本篇项目地址,求star https://github.com/979451341/Audio-and-video-learning-materials/tree/master/AudioRecord ...

  3. java实现高德地图app,Android 高德地图入门demo,最新高德地图实现方法,附源码及apk...

    [实例简介] Android 高德地图入门demo,最新高德地图实现方法,附源码及apk [实例截图] [核心代码] GaoDeDemo ├── GaoDeDemo │   ├── app │   │ ...

  4. html实现视频网站,仿爱奇艺,搜狐,迅雷看看(附源码)

    文章目录 1.功能模板 1.1 仿爱奇艺 1.2 仿搜狐视频 1.3 仿迅雷看看 1.4 视频播放 1.5 影视公司官网 2.效果和源码 2.1 源代码 2.2 模板目录 源码下载 作者:xcLeig ...

  5. 疯狂python讲义视频 百度云-疯狂Python讲义 PDF高清版附源码

    内容简介 本书全面,深入地介绍了Python编程的相关内容,大致可分为四个部分.*系统部分介绍了Python的基本语法结构,函数编程,类和对象,模块和包,异常处理等: 第二部分主要介绍Python常用 ...

  6. Android 利用广播实现黑名单【指定号码】的短信的拦截 附源码下载链接

    Android 利用广播实现指定号码的短信的拦截 根据最近的学习内容,今天实现了利用广播进行指定号码的拦截 步骤: ①.写一个数据库的帮助类,实现对数据库的创建,总共创建两个数据库psms(受保护的短 ...

  7. Android 统一打包框架(附源码下载)

    唠叨: 把手给我,我带你去吃云浮吃石磨肠粉.云吞面,木瓜渣. 那里的肠粉和广州的不一样,皮很薄很滑,肉馅没广州的那么花里胡哨,只有肉碎和香葱.但吃起来就很香滑,再配上它的甜辣酱.那味道好极了. 云吞面 ...

  8. Android可滑动画板,Android实现画板、写字板功能(附源码下载)

    前言 本文给大家分享一个使用Android开发写字板功能Dem.简单操作内存中的图像.对图像进行简单的处理.绘制直线.以达到写字板的效果 效果图如下 XML布局代码 xmlns:tools=" ...

  9. php写字板代码,Android实现画板、写字板功能(附源码下载)

    前言 本文给大家分享一个使用Android开发写字板功能Dem.简单操作内存中的图像.对图像进行简单的处理.绘制直线.以达到写字板的效果 效果图如下 XML布局代码 xmlns:tools=" ...

最新文章

  1. Lintcode108 Palindrome Partitioning || solution 题解
  2. UVA 10570 Meeting with Aliens
  3. 这个主板制作的是一样的吗?
  4. 对象的指针指向哪里,oc的类信息存放在哪里
  5. 【AWS】AWS云计算赋能数字化转型专题研讨会圆满落幕
  6. 你真的认识 “ 数据中心网络 ” 吗?
  7. bs架构 erp 进销存_从应用架构看生鲜电商信息化建设
  8. mysql数据库开发要求_MYSQL数据库开发规范
  9. linux实现自动远程备份(scp+ssh)
  10. Azure Cosmos DB(Azure 宇宙数据库)--地球已无法阻止微软玩数据库了
  11. M面试题-HTTPS和HTTP的区别
  12. 抖音申请企业蓝v认证的流程是怎样的?
  13. Java中单例设计模式总结
  14. Python飞机大战代码
  15. android 手势截图,小米8手机如何截图/长截屏/手势截屏?小米8四种截图方法
  16. [JZOJ6080]【GDOI2019模拟2019.3.23】IOer【生成函数】【数学】
  17. Python如何调用C
  18. siebel基础配置
  19. Spark 练习之疫情分析
  20. 我的世界服务器指令修复耐久,我的世界修改装备耐久度指令 | 手游网游页游攻略大全...

热门文章

  1. KISSY - Keep It Simple Stupid, Short Sweet, Slim Sexy...
  2. Read和ReadLine及数组的输入方法示例
  3. 大数据服务于政府治理创新
  4. STM32F103RCT6+JQC-3FF-S-Z5VDC继电器模块控制
  5. html分享标题描述图片尺寸,微信分享H5自定义标题描述和图片
  6. 【CAD学习-初级(1)】
  7. 计算机应用英文怎么说,电脑用英文怎么写?
  8. 皮带传动故障诊断要点
  9. word删除空行的方法(总结最好用的)
  10. IDEA报错Error:Module 'shop-common' production: java.lang.IndexOutOfBoundsException