Android 音视频深入 十七 FFmpeg 获取RTMP流保存为flv (附源码下载)
项目地址
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 (附源码下载)相关推荐
- android flv 编码器,Android 音视频深入 十七 FFmpeg 获取 RTMP 流保存为 flv (附源码下载)...
Android 音视频深入 十七 FFmpeg 获取 RTMP 流保存为 flv (附源码下载) 项目地址 https://github.com/979451341/RtmpSave 这个项目主要代码 ...
- Android 音视频深入 一 AudioRecord录音生成pcm转换为wav(附源码下载)
本篇项目地址,求star https://github.com/979451341/Audio-and-video-learning-materials/tree/master/AudioRecord ...
- java实现高德地图app,Android 高德地图入门demo,最新高德地图实现方法,附源码及apk...
[实例简介] Android 高德地图入门demo,最新高德地图实现方法,附源码及apk [实例截图] [核心代码] GaoDeDemo ├── GaoDeDemo │ ├── app │ │ ...
- html实现视频网站,仿爱奇艺,搜狐,迅雷看看(附源码)
文章目录 1.功能模板 1.1 仿爱奇艺 1.2 仿搜狐视频 1.3 仿迅雷看看 1.4 视频播放 1.5 影视公司官网 2.效果和源码 2.1 源代码 2.2 模板目录 源码下载 作者:xcLeig ...
- 疯狂python讲义视频 百度云-疯狂Python讲义 PDF高清版附源码
内容简介 本书全面,深入地介绍了Python编程的相关内容,大致可分为四个部分.*系统部分介绍了Python的基本语法结构,函数编程,类和对象,模块和包,异常处理等: 第二部分主要介绍Python常用 ...
- Android 利用广播实现黑名单【指定号码】的短信的拦截 附源码下载链接
Android 利用广播实现指定号码的短信的拦截 根据最近的学习内容,今天实现了利用广播进行指定号码的拦截 步骤: ①.写一个数据库的帮助类,实现对数据库的创建,总共创建两个数据库psms(受保护的短 ...
- Android 统一打包框架(附源码下载)
唠叨: 把手给我,我带你去吃云浮吃石磨肠粉.云吞面,木瓜渣. 那里的肠粉和广州的不一样,皮很薄很滑,肉馅没广州的那么花里胡哨,只有肉碎和香葱.但吃起来就很香滑,再配上它的甜辣酱.那味道好极了. 云吞面 ...
- Android可滑动画板,Android实现画板、写字板功能(附源码下载)
前言 本文给大家分享一个使用Android开发写字板功能Dem.简单操作内存中的图像.对图像进行简单的处理.绘制直线.以达到写字板的效果 效果图如下 XML布局代码 xmlns:tools=" ...
- php写字板代码,Android实现画板、写字板功能(附源码下载)
前言 本文给大家分享一个使用Android开发写字板功能Dem.简单操作内存中的图像.对图像进行简单的处理.绘制直线.以达到写字板的效果 效果图如下 XML布局代码 xmlns:tools=" ...
最新文章
- Lintcode108 Palindrome Partitioning || solution 题解
- UVA 10570 Meeting with Aliens
- 这个主板制作的是一样的吗?
- 对象的指针指向哪里,oc的类信息存放在哪里
- 【AWS】AWS云计算赋能数字化转型专题研讨会圆满落幕
- 你真的认识 “ 数据中心网络 ” 吗?
- bs架构 erp 进销存_从应用架构看生鲜电商信息化建设
- mysql数据库开发要求_MYSQL数据库开发规范
- linux实现自动远程备份(scp+ssh)
- Azure Cosmos DB(Azure 宇宙数据库)--地球已无法阻止微软玩数据库了
- M面试题-HTTPS和HTTP的区别
- 抖音申请企业蓝v认证的流程是怎样的?
- Java中单例设计模式总结
- Python飞机大战代码
- android 手势截图,小米8手机如何截图/长截屏/手势截屏?小米8四种截图方法
- [JZOJ6080]【GDOI2019模拟2019.3.23】IOer【生成函数】【数学】
- Python如何调用C
- siebel基础配置
- Spark 练习之疫情分析
- 我的世界服务器指令修复耐久,我的世界修改装备耐久度指令 | 手游网游页游攻略大全...
热门文章
- KISSY - Keep It Simple Stupid, Short Sweet, Slim Sexy...
- Read和ReadLine及数组的输入方法示例
- 大数据服务于政府治理创新
- STM32F103RCT6+JQC-3FF-S-Z5VDC继电器模块控制
- html分享标题描述图片尺寸,微信分享H5自定义标题描述和图片
- 【CAD学习-初级(1)】
- 计算机应用英文怎么说,电脑用英文怎么写?
- 皮带传动故障诊断要点
- word删除空行的方法(总结最好用的)
- IDEA报错Error:Module 'shop-common' production: java.lang.IndexOutOfBoundsException