rtsp实时流通过rtmp推送到服务端
很多朋友都会问到rtsp如何通过rtmp协议推送到服务端,正好前段时间开发了这个功能写在这里,和大家分享下。
首先我想说的是:ffmpeg可以实现这个功能。ffmpeg支持rtsp协议,也支持rtmp。在这个案例中rtsp是输入,
rtmp是输出,ffmpeg实现了转码的功能。下面可出一个整体思路流程图。
图1
如图1所示:在获取都rtsp流以后,解复用(demux)获取ES流packet,最后将ES流封装成rtmp格式并发送
到服务端。
基本思路完毕,下面上代码。
一:初始化ffmpeg库
void Init()
{
av_register_all();
avfilter_register_all();
avformat_network_init();
av_log_set_level(AV_LOG_ERROR);
}
二. 打开rtmp视频流
int OpenInput(char *fileName)
{
context = avformat_alloc_context();
int ret = avformat_open_input(&context, fileName, nullptr,nullptr);
if(ret < )
{
return ret;
}
ret = avformat_find_stream_info(context,nullptr);
auto codecContext = context->streams[]->codec;
ret = avcodec_open2(codecContext, avcodec_find_decoder(codecContext->codec_id), nullptr);
return ret;
}
返回值小于0 表示打开流失败。
三. 创建输出流
int OpenOutput(char *fileName)
{
int ret = ;
ret = avformat_alloc_output_context2(&outputContext, nullptr, "flv", fileName);
if(ret < )
{
goto Error;
}
ret = avio_open2(&outputContext->pb, fileName, AVIO_FLAG_READ_WRITE,nullptr, nullptr);
if(ret < )
{
goto Error;
}
for(int i = ; i < context->nb_streams; i++)
{
AVStream * stream = avformat_new_stream(outputContext, nullptr);
ret = avcodec_copy_context(stream->codec, context->streams[i]->codec); if(ret < )
{
goto Error;
}
}
ret = avformat_write_header(outputContext, nullptr);
if(ret < )
{
goto Error;
}
return ret ;
Error:
if(outputContext)
{
for(int i = ; i < outputContext->nb_streams; i++)
{
avcodec_close(outputContext->streams[i]->codec);
}
avformat_close_input(&outputContext);
}
return ret ;
}
返回值小于0,创建输出流失败,以rtmp格式发送视频流一定要以flv格式初始化output context。
四. 读取Packet
shared_ptr<AVPacket> ReadPacketFromSource()
{
shared_ptr<AVPacket> packet(static_cast<AVPacket*>(av_malloc(sizeof(AVPacket))), [&](AVPacket *p) { av_free_packet(p); av_freep(&p);});
av_init_packet(packet.get());
int ret = av_read_frame(context, packet.get());
if(ret >= )
{
return packet;
}
else
{
return nullptr;
}
}
五. 写Packet到服务端
av_interleaved_write_frame(outputContext, packet.get());
六. 简单demo
int _tmain(int argc, _TCHAR* argv[])
{
string fileInput= "rtsp://admin:admin@172.29.183.103/media/video1/multicast";
string fileOutput="rtmp://127.0.0.1/live/mystream";
Init();
if(OpenInput((char *)fileInput.c_str()) < 0)
{
cout << "Open file Input failed!" << endl;
this_thread::sleep_for(chrono::seconds(1000));
return 0;
}
if(OpenOutput((char *)fileOutput.c_str()) < 0)
{
cout << "Open file Output failed!" << endl;
this_thread::sleep_for(chrono::seconds(1000));
return 0;
}
auto timebase = av_q2d(context->streams[0]->time_base);
while(true)
{
auto packet = ReadPacketFromSource(); if(packet)
{ int ret = av_interleaved_write_frame(outputContext, packet.get());
}
else
{
cout <<"write packet end!"<< endl;
break;
}
}
CloseInput();
CloseOutput();
cout <<"Transcode file end!" << endl;
this_thread::sleep_for(chrono::seconds(1000));
return 0;
}
七. 小结:
经测试,内网rtmp直播延时在1秒以内,公网延时在3,4秒左右。
如需交流,可以加QQ群766718184,或者QQ:350197870
视频教程 播放地址: http://www.iqiyi.com/u/1426749687
视频下载地址:http://www.chungen90.com/?news_3/
Demo下载地址: http://www.chungen90.com/?news_2
rtsp实时流通过rtmp推送到服务端的更多相关文章
- 转载:iOS 推送的服务端实现
参考网址1: iOS消息推送机制的实现 http://www.cnblogs.com/qq78292959/archive/2012/07/16/2593651.html 参考网址2: iOS 推送的 ...
- 用JPUSH极光推送实现服务端向安装了APP应用的手机推送消息(C#服务端接口)
这次公司要我们做一个功能,就是当用户成功注册以后,他登录以后要收到消息,当然这个消息是安装了我们的手机APP应用的手机咯. 极光推送的网站的网址是:https://www.jpush.cn/ 极光推送 ...
- iOS开发推送--客户端 服务端
1.推送过程简介 (1)App启动过程中,使用UIApplication::registerForRemoteNotificationTypes函数与苹果的APNS服务器通信,发出注册远程推送的申请. ...
- 信鸽推送.net 服务端代码
//推送代码 private void send() { #region 安卓推送 XingeApp app = new XingeApp("accessId", "se ...
- Android消息推送的服务端
2.Android消息推送 MQTT服务器采用mosquito http://mosquitto.org/ PHP管理包采用phpmqttclient:https://github.com/toku ...
- 总结:极光推送java服务端(1)
遇到的问题: 1.怎么用极光推送 2.极光推送发送失败报错 返回{ } 3.透传和推送区别以及怎么设置 我的解决方案: 问题1.极光推送类里面有不同的方法,需要发给那些人就调用相应的方法.有安卓.io ...
- erlang-百度云推送Android服务端功能实现-erlang
百度云推送官方地址http://developer.baidu.com/wiki/index.php?title=docs/cplat/push 简单的介绍下原理: 百度云推送支持IOS和Androi ...
- 解决RTMP推送时间戳问题引起HLS切片不均匀导致手机浏览器播放卡顿的问题
本文转自EasyDarwin开源团队成员Kim的博客:http://blog.csdn.net/jinlong0603/article/details/74161115 引言 最近在测试EasyNVR ...
- Windows平台摄像头或屏幕RTMP推送介绍:OBS VS SmartPublisher
好多开发者问道,既然有了OBS,你们为什么还要开发SmartPublisher? 的确,在我们进行Windows平台RTMP推送模块开发之前,市面上为数不多的Windows平台RTMP推流工具当属OB ...
随机推荐
- Cadence仿真利器,Cadence SI / PI Analysis – Sigrity安装及破解指南
Sigrity提供了丰富的千兆比特信号与电源网络分析技术,包括面向系统.印刷电路板(PCB)和IC封装设计的独特的考虑电源影响的信号完整性分析功能. Sigrity分析技术与Cadence Alleg ...
- JavaScript模块化---AMD规范
JavaSript模块化 在了解AMD,CMD规范前,还是需要先来简单地了解下什么是模块化,模块化开发? 模块化是指在解决某一个复杂问题或者一系列的杂糅问题时,依照一种分类的思维把问 题进行系 ...
- vue.js插件使用(01) vue-resource
本文的主要内容如下: 介绍vue-resource的特点 介绍vue-resource的基本使用方法 基于this.$http的增删查改示例 基于this.$resource的增删查改示例 基于int ...
- Cassandra 的压缩策略STCS,LCS 和 DTCS
更新说明: 本文编写时最新的Cassandra版本为2.2,最新的稳定版本为2.1.8 2016年6月23日,增加一篇译文,当下最新版本为3.7 最新的Cassandra 2.1 或者更高的版本支持3 ...
- Internet Explorer 无法启用 JavaScript 怎么办?
在 Internet Expllorer 8/9 中,有些同学在浏览网页时,收到提示:“需要启用 JavaScript …”,并且会发现网页上某些功能不能用了,比如点击网页里的按钮没反应等等. 怎么启 ...
- 【Servlet】—在servlet中常混的请求路径
在页面请求,后台获取相关请求路径是,自己长搞混的几个路径,再次做次标记,不要每次使用想不起来是,都去写一个小的demo来测试. request.getContextPath(); request.ge ...
- OVER Clause是个好东西,常和ROW_NUMBER()、Sum、AVG、Count、Min、Max配合使用
根据SQL官方帮助的实例: USE AdventureWorks2012; GO SELECT ROW_NUMBER() OVER(PARTITION BY PostalCode ORDER BY S ...
- Python基础 第二天
1.http://www.cnblogs.com/beer/p/5672678.html requests和beautifulsoup
- GetType() 和typeof() 的区别
GetType() 非强类型,支持跨程序集发射,用来支持动态引用, A obja=new A(); Type t=obja.GetType() typeof() 强类型,静态的 Type t=type ...
- Java程序员要注意的10个问题————————好东西就是要拿来分享
[本文来自优优码:http://www.uucode.net/201406/ten-issue-for-java],好东西就是要拿来分享 1. Array 转为 ArrayList 很多人会这么写: ...