日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > C# >内容正文

C#

RTMP协议学习——从握手到播放

發(fā)布時(shí)間:2023/11/11 C# 72 coder
生活随笔 收集整理的這篇文章主要介紹了 RTMP协议学习——从握手到播放 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

從客戶端發(fā)起播放請(qǐng)求,到rtrmp視頻流開(kāi)始播放,大致經(jīng)過(guò)了握手->建立連接->創(chuàng)建流->播放這幾步比較重要的步驟。下面我將結(jié)合wireshark的抓包,對(duì)其中的每個(gè)流程進(jìn)行分析和學(xué)習(xí)。

握手

RTMP協(xié)議基于TCP,TCP建立連接有三次握手。在TCP連接建立以后,會(huì)再進(jìn)行一次RTMP協(xié)議層次的握手。

TCP握手

TCP建立連接的三次握手如圖所示:

從wireshark的抓包中,也可以看到TCP的三次握手。

RTMP握手

在TCP建立連接成功后,rtmp會(huì)再進(jìn)行三次握手。

可以通過(guò)在wireshark的過(guò)濾器中輸入rtmpt來(lái)過(guò)濾RTMP協(xié)議的數(shù)據(jù),如圖所示:


客戶端首先發(fā)送C0、C1到服務(wù)器。其中C1的大小是固定的,為1536個(gè)字節(jié)。服務(wù)端收到C0,C1后,發(fā)送S0,S1給客戶端,S1的大小和C1一樣,為1536個(gè)字節(jié)。服務(wù)端收齊C0,C1后,發(fā)送S2給客戶端,客戶端收齊S0,S1后,發(fā)送C2給服務(wù)端。C2和S2的大小也為1536個(gè)字節(jié)。可以看出來(lái),rtmp協(xié)議握手交換數(shù)據(jù)報(bào)文的大小是固定的。
下圖是引自wiki,可以很清晰的看到客戶端和服務(wù)端的交互流程和包之間的關(guān)系:

C0 and S0

C0和S0都是單一的八位字節(jié),里面包含著客戶端要求的RTMP版本號(hào)



C1 and S1

C1和S1的長(zhǎng)度都是1536個(gè)字節(jié),里面包含著時(shí)間戳,4個(gè)字節(jié)的0和1528個(gè)字節(jié)隨機(jī)生成的數(shù)據(jù)


C2 and S2

C2和S2的長(zhǎng)度是1536個(gè)字節(jié),其中的數(shù)據(jù)包括:

  • time:終端在 S1 (給 C2) 或者 C1 (給 S2) 發(fā)的 timestamp。
  • time2:終端先前發(fā)出數(shù)據(jù)包 (S1 或者 C1) timestamp。
  • random echo:終端發(fā)的 S1 (給 C2) 或者 S2 (給 C1) 的隨機(jī)數(shù)據(jù)。



connect

客戶端

握手完成后,客戶端會(huì)發(fā)送connect命令到服務(wù)端,請(qǐng)求連接一個(gè)服務(wù)器應(yīng)用的實(shí)例。
connect消息組成如下:

其中Command Object包含了多個(gè)字段,來(lái)幫助客戶端和服務(wù)端的連接。
Command Object包含的字段如下:

  • app:客戶端連接到服務(wù)器應(yīng)用端的名字
  • flashver:Flash Player 版本號(hào)。和ApplicationScript getversion() 方法返回的是同一個(gè)字符串。
  • swfUrl:進(jìn)行當(dāng)前連接的 SWF 文件源地址。
  • tcUrl:服務(wù)器 URL。
  • fpad:代理標(biāo)志,如果使用了代理就是 true。
  • audioCodecs:表明客戶端所支持的音頻編碼。
  • videoCodecs:表明支持的視頻編碼。
  • videoFunction:表明所支持的特殊視頻方法。
  • pageUrl:SWF 文件所加載的網(wǎng)頁(yè) URL。
  • objectEncoding:AMF 編碼方法。

總的來(lái)說(shuō),就是包含了版本,流名稱(chēng),url,音視頻編碼等后面播放視頻流時(shí)所用的信息,以保證后續(xù)服務(wù)端發(fā)送的視頻數(shù)據(jù)可以正常播放。
wireshark抓包如下:

服務(wù)端

服務(wù)端收到connect命令后,發(fā)送了幾條消息給客戶端。如下圖所示:

Window Acknowledgement size

Window Acknowledgement size的結(jié)構(gòu)如下:

Window Acknowledgement size是服務(wù)器端用來(lái)通知對(duì)端發(fā)送和應(yīng)答之間窗口大小的。
此例子中發(fā)送的窗口大小為2500000。

Set Peer Bandwidth

該消息里限制對(duì)端輸出帶寬。

限制類(lèi)型取以下值之一:

  • 0 - Hard:對(duì)端應(yīng)該限制其輸出帶寬到指示的窗口大小。

  • 1 - Soft:對(duì)端應(yīng)該限制其輸出帶寬到知識(shí)的窗口大小,或者已經(jīng)有限制在其作用的話就取兩者之間的較小值。

  • 2 - Dynamic:如果先前的限制類(lèi)型為 Hard,處理這個(gè)消息就好像它被標(biāo)記為 Hard,否則的話忽略這個(gè)消息。

Set Chunk Size

設(shè)置塊大小,以通知對(duì)端新的最大塊大小,默認(rèn)為128字節(jié)。

Chunk是消息的一段。消息在網(wǎng)絡(luò)發(fā)送之前被拆分成很多小的部分。Chunk可以確保端到端交付所有消息有序 timestamp,即使有很多不同的流。Chunk的格式如下:

createStream

在connect完成后就可以創(chuàng)建或者訪問(wèn)RTMP流了。

從抓包數(shù)據(jù)可以看到,服務(wù)端向客戶端發(fā)送了三條命令,分別是Window Acknowledgement sizecreateStream和_checkbw

  • Window Acknowledgement size是對(duì)之前服務(wù)端發(fā)送的Set Peer Bandwidth消息的應(yīng)答。
  • _checkbw用于檢查帶寬,來(lái)評(píng)估與服務(wù)器的連接質(zhì)量和帶寬。

主要的消息是creatStream,客戶端發(fā)送此消息到服務(wù)端,創(chuàng)建一個(gè)邏輯通道,用于消息通信。音頻、視頻、元數(shù)據(jù)均通過(guò)createStream創(chuàng)建的數(shù)據(jù)通道進(jìn)行交互。createStream消息的結(jié)構(gòu)如下:

客戶端發(fā)送createStream請(qǐng)求之后,服務(wù)端會(huì)反饋一個(gè)結(jié)果給客戶端,如果成功,則返回_result,如果失敗,則返回_error。
wireshark抓包數(shù)據(jù)如下:

在服務(wù)端返回的數(shù)據(jù)中,最后一個(gè)字段為Stream ID,作為該Stream的唯一標(biāo)識(shí)。此例子中返回的是1,后續(xù)的視頻或音頻的Stream ID就是1。
至此,客戶端和服務(wù)端的通道已經(jīng)建立完成,接下來(lái)就可以進(jìn)行數(shù)據(jù)的傳輸了。

play

createStream成功后,客戶端發(fā)送play命令,通知服務(wù)端開(kāi)始播放視頻流。
play消息有7個(gè)字段,其中最后3個(gè)為可選字段。

  • Command Name: String類(lèi)型,命令的名稱(chēng),為“play”。
  • Transaction ID: Number類(lèi)型,事務(wù)ID。
  • Command Object:命令信息不存在。設(shè)為 null 類(lèi)型。
  • Stream Name: String類(lèi)型,要播放流的名字。
  • Start(可選): Number類(lèi)型,以秒為單位定義開(kāi)始時(shí)間,默認(rèn)值為 -2,表示用戶首先嘗試播放流名字段中定義的直播流。
  • Duration(可選): Number類(lèi)型,以秒為單位定義了回放的持續(xù)時(shí)間。默認(rèn)值為 -1。-1 值意味著一個(gè)直播流會(huì)一直播放直到它不再可用或者一個(gè)錄制流一直播放直到結(jié)束。
  • Reset(可選): Boolean類(lèi)型,定義了是否對(duì)以前的播放列表進(jìn)行 flush。
    wireshark抓包數(shù)據(jù)為:

從抓包數(shù)據(jù)可以看到,此次事務(wù)ID為5;流的名稱(chēng)為“test”;start為-2000ms,即-2s,用戶首先嘗試播放流名字段中定義的直播流。

客戶端發(fā)送play命令來(lái)播放指定流后,就開(kāi)始傳輸音視頻數(shù)據(jù)。后面就是客戶端按照流程對(duì)接收到的數(shù)據(jù)進(jìn)行解協(xié)議,解封裝,解碼..........
........此處省略一萬(wàn)字...........

總結(jié)

以上是生活随笔為你收集整理的RTMP协议学习——从握手到播放的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。