<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                ## 一篇文章搞清楚直播協議RTMP 說起RTMP協議,相信很多人都比較陌生,這個協議相對HTTP、HTTPS、TCP等我們常見的協議而言,我們在工作中確實較少接觸它,但是對現在如火如荼的直播行業,RTMP是一個重要的協議,它在實時音視頻場景中使用非常廣泛,而且目前市占率很高。 本文的主要內容是分析RTMP的協議,當然不是純理論分析,這樣沒多大意思,還是結合實踐抓包文件來具體分析,這樣才能較好地理解RTMP的內涵。具體如何抓包見本文末尾的“**Android抓包**”模塊。希望你閱讀完本章之后,自己也能簡單地動手操作一下,這樣理解深刻一下。 原版的協議內容太冗長了,感興趣可以看一下https://www.adobe.com/devnet/rtmp.html ## **RTMP基礎介紹** RTMP協議的主要特點: * RTMP協議是應用層協議,是要靠底層可靠的傳輸層(TCP) * 協議(通常是TCP)來保證信息傳輸的可靠性的。在基于傳輸層協議的鏈接建立完成后,RTMP協議也要客戶端和服務器通過“握手”來建立基于傳輸層鏈接之上的RTMP Connection鏈接。播放一個RTMP協議的流媒體需要經過以下幾個步驟:握手,建立網絡連接,建立網絡流,播放。服務器和客戶端之間只能建立一個網絡連接,但是基于該連接可以創建很多網絡流。 ![](https://img.kancloud.cn/00/d7/00d70718fe8b42bcd358499ee656eb44_656x273.png) **這兒埋下一個小疑問?為什么傳輸層已經建立了TCP連接,RTMP還需要再次建立一個連接,有這個必要嗎?** * RTMP協議傳輸時會對數據做自己的格式化,這種格式的消息我們稱之為RTMP Message,而實際傳輸的時候為了更好地實現多路復用、分包和信息的公平性,發送端會把Message劃分為帶有Message ID的Chunk,每個Chunk可能是一個單獨的Message,也可能是Message的一部分,在接受端會根據chunk中包含的data的長度,message id和message的長度把chunk還原成完整的Message,從而實現信息的收發。 ## **RTMP握手** RTMP基于TCP,已知TCP需要3次握手才可以建立連接,在TCP3次握手成功之后,應用層的RTMP也是需要握手的,就是認證過程。具體的認證過程如下: ![](https://img.kancloud.cn/06/bb/06bbb542043ad5a06a267a37d318f528_534x341.png) * 客戶端發送 C0、C1、 C2,服務器發送 S0、 S1、 S2。 * 首先,客戶端發送 C0 表示自己的版本號,不必等對方的回復,然后發送 C1 表示自己的時間戳。 * 服務器只有在收到 C0 的時候,才能返回 S0,表明自己的版本號,如果版本不匹配,可以斷開連接。 * 服務器發送完 S0 后,也不用等什么,就直接發送自己的時間戳 S1。客戶端收到 S1 的時候,發一個知道了對方時間戳的 ACK C2。同理服務器收到 C1 的時候,發一個知道了對方時間戳的 ACK S2。 * 握手建立完成。 現在回答上面提出的問題,為什么RTMP還需要單獨建立一個連接? **因為它們需要商量一些事情,保證以后的傳輸能正常進行。主要就是兩個事情,一個是版本號,如果客戶端、服務器的版本號不一致,則不能工作。另一個就是時間戳,視頻播放中,時間是很重要的,后面的數據流互通的時候,經常要帶上時間戳的差值,因而一開始雙方就要知道對方的時間戳。** 光講純理論,沒意思,還是抓包看一下具體的流程吧。 ### 1.首先TCP?3次握手 ![](https://img.kancloud.cn/5e/0a/5e0ab00883c4cbcbc7803593a22a8eb6_1080x171.png) ### 2.RTMP握手過程 ![](https://img.kancloud.cn/3a/5d/3a5d88a3255fb775becd7ef3f658c5c2_1080x253.png) 我們發現真實發包是C0+C1一起發;S0、S1、S2一起發。但是發送的時候還是會嚴格按照時序來控制的,這樣才能真正校驗好版本號等字段。 ![](https://img.kancloud.cn/86/2a/862a0510601060118643184009d2fae9_800x100.png) ***** ## **拉流** RTMP拉流的核心流程如下: ![](https://img.kancloud.cn/a1/f9/a1f9ba68238533faf438a172599410ab_604x886.png) ### 1.建立網絡連接 ![](https://img.kancloud.cn/c3/ea/c3eac4debe527cb98c17ee33668f9af4_1080x480.png) 客戶端發送命令消息中的“連接”(connect)到服務器,請求與一個服務應用實例建立連接。 **StreamID** : 是每個消息的唯一標識,劃分成Chunk和還原Chunk為Message的時候都是根據這個ID來辨識是否是同一個消息的Chunk的,這里面為0說明這個消息是初始的0消息。 **Chunk stream ID**:一個RTMP message會拆分成多個chunk,同一個Chunk Stream ID必然屬于同一個Message。這樣在傳送過程中發過來的chunk就是通過chunk stream ID最終組裝成功我一個完成的message數據的。 **message type id** (消息的類型id):表示實際發送的數據的類型,如8代表音頻數據、9代表視頻數據。如下面的兩張圖,這樣看上去是不是好理解一點了。 ![](https://img.kancloud.cn/2d/a2/2da279e559ff3b4b50508d94b56ce081_734x256.png) **Format:**指的是chunk type。共有4種不同的格式,其中第一種格式字段為0,可以表示其他三種表示的所有數據,但由于其他三種格式是基于對之前chunk的差量化的表示,因此可以更簡潔地表示相同的數據,實際使用的時候還是應該采用盡量少的字節表示相同意義的數據。因為type ??0是表示不同數據,其他是差量,所以可以想象如果搜不到type ?? 0的包說明這個流肯定有問題。可以通過“rtmp.header.format == 0”過濾。 ### 2.建立一個網絡流 網絡流代表了發送多媒體數據的通道。服務器和客戶端之間只能建立一個網絡連接,且多個網絡流可以復用這一個網絡連接。這個在上面已經反復說過。 客戶端向服務器請求創建流: ![](https://img.kancloud.cn/dc/5c/dc5c7bb15d3fffa334b720362f552a39_1080x508.png) 服務器收到請求后向客戶端發送\_result(),對創建流的消息進行響應。此時NetStream創建完成。 ![](https://img.kancloud.cn/17/a2/17a2b6037e472f1f69865085aaa187b6_1080x477.png) ### 3.Play 播放 ?客戶端發送命令消息中的“播放”(play)命令到服務器。 ![](https://img.kancloud.cn/d0/78/d07897f600ee26070c02a0e31d435cfd_1080x529.png) 接收到播放命令后,服務器發送設置塊大小(ChunkSize)協議消息。 服務器發送用戶控制消息中的“streambegin”,告知客戶端流ID。 ![](https://img.kancloud.cn/65/11/651123cc720588eecf5f9455306ded1f_1080x315.png) 播放命令成功的話,服務器發送命令消息中的“響應狀態” NetStream.Play.Start,告知客戶端“播放”命令執行成功。 ![](https://img.kancloud.cn/52/55/5255f2e008623dde79d018f65bd5fcc4_1080x204.png) 我們發現執行了3個動作,分別如下: ![](https://img.kancloud.cn/28/a7/28a79e2fe674ca7ad65ba49e26b6915e_887x488.png) ![](https://img.kancloud.cn/90/a5/90a5d64d8357cc52fe8e886003fe8826_643x390.png) ![](https://img.kancloud.cn/1b/a1/1ba10da166f7aab68b82a22d2cd6e1a8_938x603.png) 共用一個Stream ID,并且在可以播放消息回來之后,已經解析出視頻的基本屬性。 ***** ## 推流 分析完拉流的所有操作,其實推流也是類似的,區別在Play ---> Publishing了。 ![](https://img.kancloud.cn/08/b5/08b50d97235395a30002f36246e40b99_657x890.png) **Android抓包** * 進入網站:https://www.androidtcpdump.com/android-tcpdump/downloads,下載最新版本的android tcpdump工具,現在最新版本是4.9.3 * 找一個root的手機,將下載好的tcpdump文件先push到/sdcard/ 下面,adb push tcpdump /sdcard/tcpdump * adb shell進入手機adb 模式下,cp -rf /sdcard/tcpdump /data/local/,將tcpdump拷貝到/data/local/目錄下 * chmod 777 /data/tcpdump,賦予tcpdump完全的執行權限 * ./data/local/tcpdump -i any -p -s 0 -w /sdcard/capture.pcap * 然后開始訪問rtmp的請求,訪問完成后,會在/sdcard/目錄下生成capture.pcap文件 * adb pull /sdcard/capture.pcap ,本地使用wireshare分析capture.pcap文件 * rtmp的測試源提供一個:rtmp://58.200.131.2:1935/livetv/hunantv 回復**RTMP抓包**我把本次的capture.pcap發給你。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看