音視頻流媒體開發(fā)-目錄
iOS知識點-目錄
Android-目錄
Flutter-目錄
數(shù)據(jù)結構與算法-目錄
uni-pp-目錄
SRS流媒體框架

一、推流
監(jiān)聽完后,是不是有個循環(huán)處理accept?因為要獲取新的連接
每個監(jiān)聽都會對應一個協(xié)程
每個客戶端連接也會對應一個協(xié)程-
監(jiān)聽類型
涉及到創(chuàng)建連接的時候知道什么連接,http 、rtmp要創(chuàng)建不同的連接對象
監(jiān)聽和創(chuàng)建協(xié)程

-
fd和connection的綁定一》SrsServer : :fd2conn -> new Sr sRtmpConn(this, stfd, ip)
SRS流媒體服務器-推流框架分析
核心類:
- SrsServer SRS流媒體服務入口
- SrsBufferListener 監(jiān)聽器,主要是TCP的監(jiān)聽
- SrsTcpListener TCP監(jiān)聽器
- SrsRtmpConn RTMP連接,里面對應了SrsStSocket和SrsCoroutine
- SrsRtmpServer提供與客戶端之間的RTMP-命令-協(xié)議-消息的交互服務,使用* * * SrsRtmpConn提供的socket讀寫數(shù)據(jù)
- SrsSource描述一路播放源,包括推流和拉流的描述
- SrsConsumer拉流消費者,每一路拉流客戶端對應一個SrsConsumer
- SrsStSocket經(jīng)過封裝的socket接口
SrsRecvThread負責接收數(shù)據(jù),但是要注意的是他這里并不是從IO里面讀取數(shù)據(jù)
從SrsRtmpServer類拉取數(shù)據(jù),然后推送到SrsPublishRecvThread(推流用),或者SrsQueueRecvThread(拉流用)
SrsQueueRecvThread主要用于拉流
SrsPublishRecvThread主要用于推流
在客戶端進行推流驗證
ffmpeg -re -i rtmp_test_hd.flv -vcodec copy -acodec copy -f flv -y rtmp:/111.229.231.225/live/livestream
下斷點
b SrsRtmpConn:publishing(SrsSource*)
Breakpoint 8,SrsRtmpConn:publishing (this=Oxa30d00, source=Oxa3bfc0) atsrc/app/srs_app_rtmp_conn.cpp:806806 {
(gdb) bt
#0SrsRtmpConn:publishing (this=0xa30d00, source=Oxa3bfc0) at src/app/srs_app_rtmp_conn.cpp:806
#1 0x00000000004d5229 in SrsRtmpConn:stream_service_cycle (this=Oxa30d00) at src/app/srs_app_rtmp_conn.cpp:534
#2 0x00000000004d4141 in SrsRtmpConn:service_cycle (this=Oxa30d00) atsrc/app/srs_app_rtmp_conn.cpp:388
#3 Ox00000000004d2f09 in SrsRtmpConn:do_cycle (this=Oxa30d00) at src/app/srs_app_rtmp_conn.cpp:209#4 Ox00000000004d10fb in SrsConnection:cycle (this=Oxa30d78) at stc/app/srs_app_conn.cpp:171
#5 Ox0000000000509c88 in SrsSTCoroutine:cycle (this=Oxa30fb0) at src/app/srs_app_st.cpp:198
#6 0x0000000000509cfd in SrsSTCoroutine:pfn (arg=Oxa30fb0) at src/app/srs_app_st.cpp:213
#7 0x00000000005bdd9d in _st_thread_main () at sched.c:337
#8 0x00000000005be515 in st_thread_create (start=Ox5bd719<_st_vp_schedule+170>, arg=Ox700000001,
jginable=1,
st_netfd_poll




二、SRS流媒體服務器-RTMP拉流框架分析
核心類
- SrsServer SRS流媒體服務入口
- SrsBufferListener監(jiān)聽器,主要是TCP的監(jiān)聽
- SrsTcpListener TCP監(jiān)聽器
- SrsRtmpConn RTMP連接,里面對應了SrsStSocket和SrsCoroutine
- SrsRtmpServer提供與客戶端之間的RTMP-命令-協(xié)議-消息的交互服務,使用* SrsRtmpConn 提供的socket讀寫數(shù)據(jù)
- SrsSource描述一路播放源,包括推流和拉流的描述
- SrsConsumer拉流消費者,每一路拉流客戶端對應一個SrsConsumer
- SrsStSocket經(jīng)過封裝的socket接口。
SrsRecvThread負責接收數(shù)據(jù),但是要注意的是他這里并不是從IO里面讀取數(shù)據(jù)
從SrsRtmpServer類拉取數(shù)據(jù),然后推送到SrsPublishRecvThread(推流用),或者SrsQueueRecvThread (拉流用)
SrsQueueRecvThread主要用于拉流,對應的是客戶端-服務器的控制消息,和音視頻消息沒有關系??蛻舳俗x取數(shù)據(jù)還是從consumer的queue里面去讀取。
SrsPublishRecvThread主要用于推流
測試客戶端
在客戶端進行推流驗證
ffmpeg -re -i rtmp_test_hd.flv -vcodec copy -acodec copy -f flv -y rtmp://111.229.231.225/live/livestream
在客戶端拉流驗證
ffplay rtmp://111.229.231.225/live/livestream
重點難點
不同協(xié)程的意義
打斷點
客戶端和服務器直接的交互,非音視頻數(shù)據(jù)
斷點: b SrsRtmpConn::process_play_control_msg(SrsConsumer* ,SrsCommonMessage*)
打印: print *msg
$3 =ivptr.SrsCommonMessage = 0x6b79a8<vtable for SrsCommonMessage+16> , header = (
_vptr.SrsMessageHeader = Ox6b79d8<vtable for SrsMessageHeader+16> , timestamp_delta = 1,payload_length = 10,
message_type = 4 '\004', stream_id = 0, timestamp = 1, perfer_cid = 2}, size = 10, payload = Oxa3aa80""
$4 = fvptr.SrsCommonMessage = 0x6b79a8 <vtable for SrsCommonMessage+16>, header = {
_ vptr.SrsMessageHeader = Ox6b79d8 <vtable for SrsMessageHeader+16> , timestamp_delta = 9130,payload_length = 4,
message_type = 3 1003', stream_id = 0, timestamp = 9131, perfer_cid = 2), size = 4, payload = Oxa74580""}
$5 = f_vptr.SrsCmmonMessage = 0x6b79a8<vtable for SrsCommonMessage+16> , header = f
_ vptr.SrsMessageHeader = Ox6b79d8<vtable for SrsMessageHeader+16>, timestamp_delta = 9280,payload_length = 4,
message type = 3\003', stream_jid = 0, timestamp = 30731, perfer_cid = 2}), size = 4, payload = 0x10325f0""}
以ffmpeg為例
*
* known RTMP packet types
*/
typedef enum RTMPPacketType {
RTMP_PT_CHUNK SIZE =1, /// <chunk size change
RTMP_PT_BYTES_READ = 3, ///< 3 number of bytes read
RTMP_PT_USER_CONTROL, ///< 4 user control
RTMP_PT_WINDOW_ACK_SIZE, /// < window acknowledgement size
RTMP_PT_SET_PEER_BW, ///< peer bandwidth
RTMP_PT_AUDIO= 8,/// < audio packet
RTMP_PT_VIDEO, ///<video packet
RTMP_PT_FLEX_STREAM = 15, /// < Flex shared stream
RTMP_PT_FLEX_OBJECT, ///< Flex shared object
RTMP_PT_FLEX_MESSAGE, /// <Flex shared message
RTMP_PT_NOTIFY, /// < some notification
RTMP_PT_SHARED_OBJ, ///< shared object
RTMP_PT_INVOKE, ///<invoke some stream action
RTMP_PT_METADATA = 22, /// < FLV metadata
}RTMPPacketType;
客戶端讀取的包大于>receive_report_size時,回復RTMP_Pr_BYTES_READ
receive_report_size來自RTMP_PT_WINDOW_ACK_SIZE消息ID
rt->bytes_read += ret;
if (rt->bytes_read - rt->last_bytes_read rt->receive_report_size){
av_log(s, AV_LOG_DEBUG,"sending bytes read report\n" );
if ( (ret = gen_bytes_read(s, rt,rpkt.timestamp + 1))< 0) {
ff_rtmp_packet_destroy (&rpkt);
return ret;
}
rt->last_bytes_read = rt->bytes_read;
}



