将h.264裸码流推送到RTMP服务器
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格式:
[plain]?view plaincopy
一般可以從IP攝像頭的sdk中拿到這種數據,一般sdk會使用如下接口:
[cpp]?view plaincopy
也有的攝像頭沒有B幀,所以dts和pts是一致的,所以后面的時間戳合并成一個:
[cpp]?view plaincopy
或者,使用回調函數,當攝像頭編碼出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
例如:
[plain]?view plaincopy
SRS目前有兩個分支,只有SRS2(即master分支)提供了h.264裸碼流發送的功能,git clone之后要切換到這個分支:
[plain]?view plaincopy
如果你可以使用.h和.a庫,就可以直接編譯srs,可以看到生成了.h和.a文件:
[plain]?view plaincopy
如果是需要將srs-librtmp導出成一個.h和.cpp文件,執行下面的命令,可以看到生成了.h和.cpp文件:
[plain]?view plaincopy
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格式:
[plain]?view plaincopy
[plain]?view plaincopy
查看srs-librtmp目錄,應該是下面的結構:
[plain]?view plaincopy
srs_h264_raw_publish.c讀取h.264裸碼流后,基本上讀取到的就是一個一個的h.264 annexb格式的包,參考read_h264_frame():
[plain]?view plaincopy
連接RTMP和發送的主要函數是:
[cpp]?view plaincopy
這幾個函數就可以把h.264裸碼流發出去了。
編譯和運行
若使用srs-librtmp導出的單個.h和.cpp文件,編譯和運行命令是:
[plain]?view plaincopy
播放的RTMP地址為: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
其中有幾個錯誤可以忽略:
- 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重復,用戶忽略即可。
目前的接口聲明如下,最新的接口聲明以代碼為準:
[cpp]?view plaincopy
srs-librtmp會將h.264包打包成RTMP包,不用用戶每次都要處理。
總結
以上是生活随笔為你收集整理的将h.264裸码流推送到RTMP服务器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux shell脚本基础学习详细介
- 下一篇: Shell 变量--shell教程