您的位置:首页 > 其它

最简单的基于librtmp的示例:发布H.264(H.264通过RTMP发布)——雷神经典

2017-06-07 19:45 375 查看
http://blog.csdn.net/leixiaohua1020/article/details/42105049

版权声明:本文为博主原创文章,未经博主允许不得转载。

目录(?)[+]

=====================================================

最简单的基于libRTMP的示例系列文章列表:

最简单的基于librtmp的示例:接收(RTMP保存为FLV)

最简单的基于librtmp的示例:发布(FLV通过RTMP发布)

最简单的基于librtmp的示例:发布H.264(H.264通过RTMP发布)

=====================================================

本文记录一个基于libRTMP的发布H.264码流的程序。该程序可以将H.264数据发布到RTMP流媒体服务器。目前这个例子还不是很稳定,下一步还有待修改。

本程序使用回调函数作为输入,通过自定义的回调函数,可以发送本地的文件或者内存中的数据。



函数调用结构图

本程序的函数调用结构图如下所示。
 


整个程序包含3个接口函数:

RTMP264_Connect():建立RTMP连接。

RTMP264_Send():发送数据。

RTMP264_Close():关闭RTMP连接。

按照顺序调用上述3个接口函数就可以完成H.264码流的发送。

结构图中关键函数的作用如下所列。

RTMP264_Connect()中包含以下函数:
InitSockets():初始化Socket

RTMP_Alloc():为结构体“RTMP”分配内存。

RTMP_Init():初始化结构体“RTMP”中的成员变量。

RTMP_SetupURL():设置输入的RTMP连接的URL。

RTMP_EnableWrite():发布流的时候必须要使用。如果不使用则代表接收流。

RTMP_Connect():建立RTMP连接,创建一个RTMP协议规范中的NetConnection。

RTMP_ConnectStream():创建一个RTMP协议规范中的NetStream。

RTMP264_Send()中包含以下函数:
ReadFirstNaluFromBuf():从内存中读取出第一个NAL单元。

ReadOneNaluFromBuf():从内存中读取出一个NAL单元。

h264_decode_sps():解码SPS,获取视频的宽,高,帧率信息。

SendH264Packet():发送一个NAL单元。

SendH264Packet()中包含以下函数:
SendVideoSpsPps():如果是关键帧,则在发送该帧之前先发送SPS和PPS。

SendPacket():组装一个RTMPPacket,调用RTMP_SendPacket()发送出去。

RTMP_SendPacket():发送一个RTMP数据RTMPPacket。

RTMP264_Close()中包含以下函数:
RTMP_Close():关闭RTMP连接。

RTMP_Free():释放结构体“RTMP”。

CleanupSockets():关闭Socket。

源代码

程序提供的3个接口函数的使用方法如下。可以看出接口比较简单。

[cpp] view
plain copy

/** 

 * Simplest Librtmp Send 264 

 * 

 * 雷霄骅,张晖 

 * leixiaohua1020@126.com 

 * zhanghuicuc@gmail.com 

 * 中国传媒大学/数字电视技术 

 * Communication University of China / Digital TV Technology 

 * http://blog.csdn.net/leixiaohua1020 

 * 

 * 本程序用于将内存中的H.264数据推送至RTMP流媒体服务器。 

 * This program can send local h264 stream to net server as rtmp live stream. 

 */  

  

#include <stdio.h>  

#include "librtmp_send264.h"  

  

  

  

FILE *fp_send1;  

  

//读文件的回调函数  

//we use this callback function to read data from buffer  

int read_buffer1(unsigned char *buf, int buf_size ){  

    if(!feof(fp_send1)){  

        int true_size=fread(buf,1,buf_size,fp_send1);  

        return true_size;  

    }else{  

        return -1;  

    }  

}  

  

int main(int argc, char* argv[])  

{  

    fp_send1 = fopen("cuc_ieschool.h264", "rb");  

  

    //初始化并连接到服务器  

    RTMP264_Connect("rtmp://localhost/publishlive/livestream");  

      

    //发送  

    RTMP264_Send(read_buffer1);  

  

    //断开连接并释放相关资源  

    RTMP264_Close();  

  

    return 0;  

}  

接口函数内部的代码比较多,不再详细记录。

下载

Simplest LibRTMP Example

项目主页

SourceForge:https://sourceforge.net/projects/simplestlibrtmpexample/

Github:https://github.com/leixiaohua1020/simplest_librtmp_example

开源中国:http://git.oschina.net/leixiaohua1020/simplest_librtmp_example

CSDN下载:http://download.csdn.net/detail/leixiaohua1020/8291757

本工程包含了LibRTMP的使用示例,包含如下子工程:

simplest_librtmp_receive: 接收RTMP流媒体并在本地保存成FLV格式的文件。

simplest_librtmp_send_flv: 将FLV格式的视音频文件使用RTMP推送至RTMP流媒体服务器。
simplest_librtmp_send264: 将内存中的H.264数据推送至RTMP流媒体服务器。



顶7
 
踩0
 
 
上一篇最简单的基于librtmp的示例:发布(FLV通过RTMP发布)
下一篇最简单的基于FFmpeg的libswscale的示例(YUV转RGB)

  相关文章推荐

• 最简单的基于librtmp的示例:发布H.264(H.264通过RTMP发布)
• 最简单的基于Flash的流媒体示例:RTMP推送和接收(ActionScript)
• 【活动】DevOps直播技术架构养成记
• 直播类
APP 项目开发实战(原理篇)
• 最简单的基于librtmp的示例:发布(FLV通过RTMP发布)
• 我的开源视音频项目汇总
• <如何实现1080P延迟低于500ms的实时超清直播传输技术>
<关于直播,所有的技术细节都在这里了>
• [总结]RTMP流媒体技术零基础学习方法
• RTMP协议分析及H.264打包原理
• 最简单的基于librtmp的示例:接收(RTMP保存为FLV)

参考知识库




.NET知识库

4018关注|839收录




Git知识库

6783关注|615收录

猜你在找

开源大数据技术架构设计
顾荣:开源大数据存储系统Alluxio(原Tachyon)的原理分析与案例简介
美团大数据平台的技术演进
使用Apache Kylin搭建企业级开源大数据分析平台
基于开源软件打造EB级大数据平台
iOS8开发视频教程-Part 4:iOS数据源协议、委托协议与高级视图
Android开发技术-笔试面试题分析二
Redis内存管理和优化
创造数据产品驱动商业价值
C语言及程序设计进阶

查看评论

21楼 cpc_haikuotiankong2017-05-04
17:00发表 [回复]


这三个代码怎么在linux上编译,大神们求助20楼 tjb122016-12-01
09:34发表 [回复]


您好,雷博主。我的 RTMP264_Connect("rtmp://192.168.31.172/oflaDemo"); 这句执行后报Error:Closing connection:NetStream.Failed 我的red5服务器已经搭建了。请您帮助解答下,谢谢
Re: 流萤2016-12-27
17:11发表 [回复]


回复tjb12:rtmp地址格式不是rtmp://地址/appname/streamname么Re: 流萤2016-12-27
17:09发表 [回复]


回复tjb12:博主已经去世了19楼 Poker12162016-11-27
11:16发表 [回复]


致敬18楼 灿哥哥2016-10-19
10:53发表 [回复]


学习了,向雷神致敬17楼 vivanboy2016-08-04
12:30发表 [回复]


这个例子有个小问题,每次发送sps/pps时,时间戳都是0,会导致客户端播放不稳定。

很感谢雷神的无私分享,一路走好!
Re: liuxibo861118292016-08-24
11:43发表 [回复]


回复vivanboy:是的,大家要注意,这个问题很重要,雷神的代码SendVideoSpsPps中

packet->m_nTimeStamp = 0;

这一句,一定要再次设定时间戳,否则会有问题,模糊。

ps:雷神一路走好!16楼 vivanboy2016-07-18
18:13发表 [回复]


这个例子有个很隐秘的bug,导致客户端比较卡顿甚至不播放,搞了2天才解决!不过还是很感谢楼主!
Re: nick__zhang2016-07-21
11:57发表 [回复]


回复vivanboy:你好,我也遇到了卡顿的问题,请问您是怎么解决的,可以讲讲吗,非常感谢。qq:382038752
Re: vivanboy2016-08-04
12:32发表 [回复]


回复zfng2008:qq: 1694856504

你的问题我已经在上面回复,希望能帮到你15楼 nick__zhang2016-07-07
12:14发表 [回复]


博主您好,我按照您的例子,在tcp的server端接收到rtp承载的多媒体数据,然后封成Nalu包,利用librtmp推送到流媒体服务器(red5)上,一路现在是可以。如果是多路推流,我现在是分别建了两个线程,每个线程维护一个rtmp推流的链路,结果发现播放的时候会出现花屏,两路数据有错乱,难道是librtmp不支持多线程的推流,还是这种方法不合理,请问博主对于多路推流有什么好的建议吗?谢谢!14楼 qq_321906592016-05-25
13:52发表 [回复]


这个例子哪里不稳定呀?解决了吗?13楼 shiter2016-04-04
01:19发表 [回复]


麻烦问一下,我这个想用yuv作为一帧一帧的处理一下,完后编码成h264,完后用h264发送rtmp,是不是针对每一帧进行处理的话,每一帧都是关键帧?12楼 xing19762016-03-04
15:26发表 [回复]


雷兄你好,有个问题想请教:我用librtmp连接 crtmpserver服务器,服务器上总是出现这个错误:

e:\work\rtmp\crtmpserver\sources\thelib\src\protocols\rtmp\inboundrtmpprotocol.c

pp:123 This version of player doesn't support validation

e:\work\rtmp\crtmpserver\sources\common\src\utils\misc\crypto.cpp:131 Unable to

compute the shared key

e:\work\rtmp\crtmpserver\sources\thelib\src\protocols\rtmp\inboundrtmpprotocol.c

pp:215 Unable to create shared key

e:\work\rtmp\crtmpserver\sources\thelib\src\protocols\rtmp\basertmpprotocol.cpp:

167 Unable to perform handshake

请问该怎样解决呢?11楼 Ginter_2016-01-19
16:17发表 [回复]


博主能否说一下,例子的使用环境和方式吗?10楼 daydayup2015-12-22
09:49发表 [回复]


RTMP264_Connect("rtmp://localhost/publishlive/livestream"),出现socket 10061错误,请问雷神这是什么原因?其他同学有没有遇到?
Re: shiter2016-03-02
21:40发表 [回复]


回复a511244213:我的是ERROR: RTMP_Connect0, failed to connect socket. 10061 (Unknown error)
Re: gengxt20032016-06-23
23:04发表 [回复]


回复wangyaninglm:这个是要安装RTMP服务器的吧?

我是装了RED5,然后可以。
Re: qq_279661232016-07-16
22:53发表 [回复]


回复gengxt2003:Re: qq_279661232016-07-16
22:52发表 [回复]


回复gengxt2003:请问您下载的RED5还需要自己调试吗?现在急着做推送流这一块,求指导,谢谢!
Re: qq_333622872016-08-05
21:42发表 [回复]


回复qq_27966123:您好,这个问题解决了吗.我也出现了这个问题9楼 purple3292015-11-09
09:42发表 [回复]


雷总你好,我觉得在sps_decode.h中的h264_decode_sps里,获取视频宽高有点问题,在某些H264码流下解析不正确,在此文件第161行seq_scaling_list_present_flag[i]=u(1,buf,StartBit);应该加入如下的if语句,我在解析h.264 high profile的1个文件时发现此问题。

if (seq_scaling_list_present_flag[i] == 1) {...根据结构体定义再解析一些东西...}

另外咨询个问题,你的demo里的librtmp.dll是自己编译的吧?是vc下编译的还是mingw之类的linux环境编译的?我在写的时候,是直接把rtmpdump这个windows工程编译成了静态库,不知道这两种使用方式有没有什么区别?
Re: 雷霄骅2015-11-18
21:06发表 [回复]


回复purple329:兄弟看得很细致啊!多谢指教

我也忘记libRTMP的来源了。。。Linux和Windows下我都试过编译Re: purple3292015-11-12
10:08发表 [回复]


回复purple329:顺便再请教一下,libcrypto.dll是怎么编译出来的?我用vc或mingw编译openssl怎么都出不来这个dll,谢谢8楼 haiyang_wang_cool2015-10-10
10:20发表 [回复]


引用“byteman_wang”的评论:请问博主有没有打算写一个用ffmpeg采集摄像头和音频然后通过rtmp发布的实例程序

你现在写没写这个示例程序啊7楼 haiyang_wang_cool2015-10-10
10:06发表 [回复]


用你的那几个例子写了写测试示例 ,但老是出现各种错误,麻烦你把这几个例子组合一下呗,刚开始做iOS,不是太明白。
Re: 雷霄骅2015-11-18
20:56发表 [回复]


回复haiyang_wang_cool:组合一下的更难学,我是特意给它们分开的~~6楼 JAING2015-09-18
17:12发表 [回复]


神我天天膜拜你,每次都觉得进步了。做软件以前觉得很闷很孤独,看了博主的代码,程序,工程后发现了原来写代码也是一种感悟,自己学的不多懂得也不多,但每次来到博主这总能有新发现总会为自己学到了新知识而感到高兴,感觉回到了小时候学知识是件快乐的事情,是有意义的事。感谢分享让我们更多人能有所体会,能坚持下去。又一个0点突然有感悟多写了几句,希望大家见谅。
Re: 雷霄骅2015-11-18
20:55发表 [回复]


回复jiangwt888:怎么和前面的一段一样⊙_⊙

谢谢兄弟支持,互相学习!5楼 byteman_wang2015-09-16
18:09发表 [回复]


请问博主有没有打算写一个用ffmpeg采集摄像头和音频然后通过rtmp发布的实例程序
Re: 雷霄骅2015-09-29
14:02发表 [回复]


回复byteman_wang:这个只要组合使用我做的那几个例子就可以了~4楼 kmcfly2015-08-19
17:01发表 [回复]


RTMP_ConnectStream 一直打印ERROR:rtmp server requested close

ERROR: authenticating publisher

然后挂掉了 何意?
Re: For_MGP2017-01-12
16:48发表 [回复]


回复u011244446:adobe media server 这个服务开启就不会有这个错误Re: 雷霄骅2015-09-02
13:21发表 [回复]


回复u011244446:这个还没有经验那~3楼 oldmtn2015-07-28
11:12发表 [回复]


博主,你的librtmp是自己编译的?
Re: 雷霄骅2015-09-02
13:20发表 [回复]


回复oldmtn:忘记了,libRTMP编译比较简单~2楼 WQZ3211232015-02-04
16:49发表 [回复]


正在努力学习
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: