h.264裸码流的格式,参考“H.264-AVC-ISO_IEC_14496-10.pdf, page 211.”,这个文档的下载地址:https://github.com/winlinvip/simple-rtmp-server/tree/develop/trunk/doc/H.264-AVC-ISO_IEC_14496-10.pdf
一个录制的h.264裸码流文件:http://winlinvip.github.io/srs.release/3rdparty/720p.h264.raw,或者:http://ossrs.net/srs.release/3rdparty/720p.h264.raw,里面的格式是annexb格式:
一般可以从IP摄像头的sdk中拿到这种数据,一般sdk会使用如下接口:
也有的摄像头没有B帧,所以dts和pts是一致的,所以后面的时间戳合并成一个:
或者,使用回调函数,当摄像头编码出h.264数据时回调这个函数,格式和上面的也差不多。
本文描述了如何将拿到的h.264数据,通过RTMP协议发布到RTMP服务器,然后使用RTMP或者HLS播放。
srs-librtmp
显然发送h.264的数据得使用RTMP库,rtmpdump提供的librtmp要求是flv/RTMP格式的数据,而srs-librtmp提供了接口直接发送h.264数据。
srs-librtmp是SRS服务器提供的客户端库,SRS项目参考:https://github.com/winlinvip/simple-rtmp-server
srs-librtmp的wiki参考:https://github.com/winlinvip/simple-rtmp-server/wiki/v2_CN_SrsLibrtmp#publish-h264-raw-data
对应的srs的bug参考:https://github.com/winlinvip/simple-rtmp-server/issues/66#issuecomment-62240521
使用git clone下来,可以选择github源,或者国内的其他镜像源,参考:https://github.com/winlinvip/simple-rtmp-server#mirrors
例如:
SRS目前有两个分支,只有SRS2(即master分支)提供了h.264裸码流发送的功能,git clone之后要切换到这个分支:
如果你可以使用.h和.a库,就可以直接编译srs,可以看到生成了.h和.a文件:
如果是需要将srs-librtmp导出成一个.h和.cpp文件,执行下面的命令,可以看到生成了.h和.cpp文件:
srs_h264_raw_publish
SRS提供了例子读取录制的h.264文件并发布到RTMP服务器:https://github.com/winlinvip/simple-rtmp-server/tree/develop/trunk/research/librtmp/srs_h264_raw_publish.c
录制的h.264裸码流文件:http://winlinvip.github.io/srs.release/3rdparty/720p.h264.raw,或者:http://ossrs.net/srs.release/3rdparty/720p.h264.raw,里面的格式是annexb格式:
查看srs-librtmp目录,应该是下面的结构:
srs_h264_raw_publish.c读取h.264裸码流后,基本上读取到的就是一个一个的h.264 annexb格式的包,参考read_h264_frame():
连接RTMP和发送的主要函数是:
这几个函数就可以把h.264裸码流发出去了。
编译和运行
若使用srs-librtmp导出的单个.h和.cpp文件,编译和运行命令是:
播放的RTMP地址为:rtmp://ossrs.net/live/h264.raw,打开下面的链接即可观看流:
接口
srs-librtmp定义的h.264裸码流发送接口使用参考:https://github.com/winlinvip/simple-rtmp-server/issues/66#issuecomment-62240521
其中有几个错误可以忽略:
- srs_h264_is_dvbsp_error:这个是因为IP摄像头在每个I帧前都插入了SPS和PPS,所以在服务器断开重连时,重新调用srslibrtmp的连接和publish函数,不用考虑接下来的帧是否是sps和pps。但是RTMP要求第一个video包是sps/pps,所以srs-librtmp的srs_h264_write_raw_frame()会忽略sps和pps之前的video包,然后返回一个错误码,用户只要忽略这个错误码即可。
- srs_h264_is_duplicated_sps_error:这个因为IP摄像头在每个I帧前都插入sps和pps,这些重复的sps和pps会导致hls频繁的插入discontinue信息,所以srs-librtmp只有在sps和pps都变化时才发送新的sequence header包,而不是每次都发送。所以sps重复时会返回一个错误码,用户忽略这个错误即可。
- srs_h264_is_duplicated_pps_error:这个和上面的错误一样,是pps重复,用户忽略即可。
目前的接口声明如下,最新的接口声明以代码为准:
srs-librtmp会将h.264包打包成RTMP包,不用用户每次都要处理。
http://blog.csdn.net/win_lin/article/details/41170653