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格式:
// SPS 000000016742802995A014016E40 // PPS 0000000168CE3880 // IFrame 0000000165B8041014C038008B0D0D3A071..... // PFrame 0000000141E02041F8CDDC562BBDEFAD2F.....
int device_read(char** pdata, int* psize, int* pdts, int* ppts);
int device_read(char** pdata, int* psize, int* timestamp);
本文描述了如何将拿到的h.264数据,通过RTMP协议发布到RTMP服务器,然后使用RTMP或者HLS播放。
显然发送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
例如:
git clone https://github.com/winlinvip/simple-rtmp-server.git
cd simple-rtmp-server/trunk git checkout master
./configure --disable-all --with-librtmp && make && ls -lh objs/include/srs_librtmp.h objs/lib/srs_librtmp.a
./configure --export-librtmp-single=objs/srs-librtmp && ls -lh objs/srs-librtmp/srs_librtmp.h objs/srs-librtmp/srs_librtmp.cpp
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格式:
// SPS 000000016742802995A014016E40 // PPS 0000000168CE3880 // IFrame 0000000165B8041014C038008B0D0D3A071..... // PFrame 0000000141E02041F8CDDC562BBDEFAD2F.....
wget https://raw.githubusercontent.com/winlinvip/simple-rtmp-server/master/trunk/research/librtmp/srs_h264_raw_publish.c -O objs/srs-librtmp/srs_h264_raw_publish.c --no-check-certificate && wget http://ossrs.net/srs.release/3rdparty/720p.h264.raw -O objs/srs-librtmp/720p.h264.raw
[winlin@dev6 trunk]$ ls -lh objs/srs-librtmp total 5.8M -rw-rw-r-- 1 winlin winlin 5.1M Nov 8 12:39 720p.h264.raw -rw-rw-r-- 1 winlin winlin 633 Nov 16 10:32 example.c -rw-rw-r-- 1 winlin winlin 87K Nov 16 10:36 srs_h264_raw_publish.c -rw-rw-r-- 1 winlin winlin 557K Nov 16 10:32 srs_librtmp.cpp -rw-rw-r-- 1 winlin winlin 20K Nov 16 10:32 srs_librtmp.h
// SPS 000000016742802995A014016E40 // PPS 0000000168CE3880 // IFrame 0000000165B8041014C038008B0D0D3A071..... // PFrame 0000000141E02041F8CDDC562BBDEFAD2F.....
连接RTMP和发送的主要函数是:
srs_rtmp_t rtmp = srs_rtmp_create(rtmp_url); srs_simple_handshake(rtmp); srs_connect_app("rtmp://127.0.0.1/live/livestream"); srs_publish_stream(rtmp); while (!EOF) { read_h264_frame(&data, &size, &dts, &pts); srs_h264_write_raw_frames(rtmp, data, size, dts, pts); }
若使用srs-librtmp导出的单个.h和.cpp文件,编译和运行命令是:
cd objs/srs-librtmp && gcc -g -O0 srs_h264_raw_publish.c srs_librtmp.cpp -o publisher -lstdc++ && ./publisher ./720p.h264.raw rtmp://ossrs.net/live/h264.raw
http://www.ossrs.net/srs.release/trunk/research/players/srs_player.html?server=ossrs.net&vhost=ossrs.net&stream=h264.raw&autostart=true
srs-librtmp定义的h.264裸码流发送接口使用参考:https://github.com/winlinvip/simple-rtmp-server/issues/66#issuecomment-62240521
其中有几个错误可以忽略:
目前的接口声明如下,最新的接口声明以代码为准:
/** * write h.264 raw frame over RTMP to rtmp server. * @param frames the input h264 raw data, encoded h.264 I/P/B frames data. * frames can be one or more than one frame, * each frame prefixed h.264 annexb header, by N[00] 00 00 01, where N>=0, * for instance, frame = header(00 00 00 01) + payload(67 42 80 29 95 A0 14 01 6E 40) * about annexb, @see H.264-AVC-ISO_IEC_14496-10.pdf, page 211. * @paam frames_size the size of h264 raw data. * assert frames_size > 0, at least has 1 bytes header. * @param dts the dts of h.264 raw data. * @param pts the pts of h.264 raw data. * * @remark, user should free the frames. * @remark, the tbn of dts/pts is 1/1000 for RTMP, that is, in ms. * @remark, cts = pts - dts * @remark, use srs_h264_startswith_annexb to check whether frame is annexb format. * @example /trunk/research/librtmp/srs_h264_raw_publish.c * @see https://github.com/winlinvip/simple-rtmp-server/issues/66 * * @return 0, success; otherswise, failed. * for dvbsp error, @see srs_h264_is_dvbsp_error(). * for duplictated sps error, @see srs_h264_is_duplicated_sps_error(). * for duplictated pps error, @see srs_h264_is_duplicated_pps_error(). */ /** For the example file: http://winlinvip.github.io/srs.release/3rdparty/720p.h264.raw The data sequence is: // SPS 000000016742802995A014016E40 // PPS 0000000168CE3880 // IFrame 0000000165B8041014C038008B0D0D3A071..... // PFrame 0000000141E02041F8CDDC562BBDEFAD2F..... User can send the SPS+PPS, then each frame: // SPS+PPS srs_h264_write_raw_frames('000000016742802995A014016E400000000168CE3880', size, dts, pts) // IFrame srs_h264_write_raw_frames('0000000165B8041014C038008B0D0D3A071......', size, dts, pts) // PFrame srs_h264_write_raw_frames('0000000141E02041F8CDDC562BBDEFAD2F......', size, dts, pts) User also can send one by one: // SPS srs_h264_write_raw_frames('000000016742802995A014016E4', size, dts, pts) // PPS srs_h264_write_raw_frames('00000000168CE3880', size, dts, pts) // IFrame srs_h264_write_raw_frames('0000000165B8041014C038008B0D0D3A071......', size, dts, pts) // PFrame srs_h264_write_raw_frames('0000000141E02041F8CDDC562BBDEFAD2F......', size, dts, pts) */ extern int srs_h264_write_raw_frames(srs_rtmp_t rtmp, char* frames, int frames_size, u_int32_t dts, u_int32_t pts ); /** * whether error_code is dvbsp(drop video before sps/pps/sequence-header) error. * * @see https://github.com/winlinvip/simple-rtmp-server/issues/203 * @example /trunk/research/librtmp/srs_h264_raw_publish.c * @remark why drop video? * some encoder, for example, ipcamera, will send sps/pps before each IFrame, * so, when error and reconnect the rtmp, the first video is not sps/pps(sequence header), * this will cause SRS server to disable HLS. */ extern srs_h264_bool srs_h264_is_dvbsp_error(int error_code); /** * whether error_code is duplicated sps error. * * @see https://github.com/winlinvip/simple-rtmp-server/issues/204 * @example /trunk/research/librtmp/srs_h264_raw_publish.c */ extern srs_h264_bool srs_h264_is_duplicated_sps_error(int error_code); /** * whether error_code is duplicated pps error. * * @see https://github.com/winlinvip/simple-rtmp-server/issues/204 * @example /trunk/research/librtmp/srs_h264_raw_publish.c */ extern srs_h264_bool srs_h264_is_duplicated_pps_error(int error_code);