• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            S.l.e!ep.¢%

            像打了激速一樣,以四倍的速度運轉,開心的工作
            簡單、開放、平等的公司文化;尊重個性、自由與個人價值;
            posts - 1098, comments - 335, trackbacks - 0, articles - 1
              C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

            RTMP 協議研究

            Posted on 2010-01-26 14:14 S.l.e!ep.¢% 閱讀(1921) 評論(0)  編輯 收藏 引用 所屬分類: A·M·F·3

            RTMP 協議研究

            1 協議研究概述
            ?? 協議設計和分析一直都是在工作遇到,正好在這里總結一下,說到協議,在這個網絡的時代,沒有人可以離開它了。他存在我們生活中的任何角落,只不過我們平時,并沒有注意到它的存在,可以這么說如果沒有協議,我們生活和日常的工作生產都不能進行。如果仔細想想你生活中用到的所有東西,協議已經包含其中。那到底什么是協議呢?說的簡單一點就是雙方達成的共識,以便更好的交流,理論上協議是什么呢?如果學過《信號與系統》的人都知道有個簡單的道理,就是信息在經過一個管道的符號集,到另一個符號集時信息不會丟失。

            ??? 任何復雜的事物都有個最簡單的本質,網絡上的協議也是這樣,有個最基本的本質。除去上下層的概念,協議就只剩下通信雙方實體的規則。

            ?? 一般的協議都包含最基本的協議頭,不管是物理層、鏈路層、還是網絡層,這個頭就構成了協議的本質東西。通常協議頭要包含以下最基本的三項信息:

            雙方實體的唯一標示,用來標示通信雙方的實體。
            類型描述或者是凈核描述,標志凈核的內容。
            協議凈核的長度,用來在萃取凈核的內容應用。
            ?? 其中,前兩項是必須要有的,沒有他們,通信雙方的交互根本得不到保證,第三項在不太靈活的通信中可以去掉,而有第二項的類型推出。

            ??? 協議的豐富性,有凈核的多樣性體現。

            ?? 協議頭除了以上的三項,還可以增加更多的信息(比如控制信息、時間信息等),取決于具體的應用。找到這些基本的東西,再去看協議的時候,能夠更好的抓住協議的主體進行分析和設計了。

            ???????????? 如圖?? 協議物理結構

            2 RTMP 協議概述
            ?? RTMP 協議是被 Flash 用于對象、視頻、音頻的傳輸。該協議建立在 TCP 協議或者輪詢 HTTP 協議之上, RTMP 協議就像一個用來裝數據包的容器,這些數據可以是 AMF 格式的數據,也可以是 FLV 中的視 / 音頻數據。一個單一的連接可以通過不同的通道傳輸多路網絡流,這些通道中的包都是按照固定大小的包傳輸的 .

            3 RTMP 協議部分
            3.1 協議頭
            struct RTMP_HEAD

            {

            ????????? char cChannelid : 6;// 第一個字節的后 6 位

            ????????? char cCheadsize ; // 第一個字節的頭兩位

            ????? char cTimer[3];? // 三個字節表示的時間信息

            ????? char cLength[3]; // 三個字節表示的長度

            ????? char cDatatype; // 數據類型

            ????? char sStreamid[4]; // 流標識

            };

            這里有三個最基本的元素(唯一標示 )、(類型 )和(凈核的長度 )分別是: cChannelid 、 cDatatype 和 cLength 。

            3.2 數據類型
            數據類型 決定了協議上層可以做的具體的事情,和使用協議的人必須遵循的規則。

            同時數據類型 說明了凈核 的基本內容。

            RTMP 數據類型:

            0×01? Chunk Size? changes the chunk size for packets?
            0×02? Unknown? anyone know this one??
            0×03? Bytes Read? send every x bytes read by both sides?
            0×04? Ping? ping is a stream control message, has subtypes?
            0×05? Server BW? the servers downstream bw?
            0×06? Client BW? the clients upstream bw?
            0×07? Unknown? anyone know this one??
            0×08? Audio Data? packet containing audio?
            0×09? Video Data? packet containing video data?
            0x0A - 0×11? Unknown? anyone know??
            0×12? Notify? an invoke which does not expect a reply?
            0×13? Shared Object? has subtypes?
            0×14? Invoke? like remoting call, used for stream actions too.?

            3.3 協議的凈核
            ?? RTMP 的協議凈核是用 AMF 格式來描述, AMF 格式本身的產生就是為了 RTMP 協議服務的,最初的 RTMP 采用 XML 的形式傳輸數據,但 XML 只是字符形式的值對的格式傳輸數據,而隨著應用的普及這完全不能滿足要求了,比如對象、結構、數組,甚至可以是數據集,配合 DataGrid 組件可以很方便地顯示數據。
            為了處理復雜數據類型,采用一種獨有的方式使 Flash 與應用服務器間可以來回傳送數據勢在必行。于是 AMF 應運而生。

            AMF 是 Adobe 獨家開發出來的通信協議,它采用二進制壓縮,序列化、反序列化、傳輸數據,從而為 Flash 播放器與 Flash Remoting 網關通信提供了一種輕量級的、高效能的通信方式。如下圖所示。
            ?
            AMF 最大的特色在于可直接將 Flash 內置對象,例如 Object, Array, Date, XML ,傳回服務器端,并且在服務器端自動進行解析成適當的對象,這就減輕了開發人員繁復工作,同時也更省了開發時間。由于 AMF 采用二進制編碼,這種方式可以高度壓縮數據,因此非常適合用 來傳遞大量的資料。數據量越大, Flash Remoting 的傳輸效能就越高,遠遠超過 Web Service 。至于 XML, LoadVars 和 loadVariables() ,它們使用純文本的傳輸方式,效能就更不能與 Flash Remoting 相提并論了。
            注意: Flash Remoting 需要瀏覽器支持 Binary POST , Flash 播放器在 Netscape 6.x. 環境下運行 Flash Remoting 會不起作用( Flash Remoting 調用沒有效果也不返回錯誤), Netscape 7 已經糾正了這個 bug 。對于早期 Safari 和 Chimera 版的蘋果機也有這個問題。
            同樣是輕量級數據交換協議,同樣是通過調用遠程服務,同樣是基于標準的 HTTP 和 HTTPS 協議, Flash Remoting 為什么選擇了使用 AMF 而放棄了 SOAP 與 Flash 播放器通信呢? 有如下原因:
            ?
            SOAP 將數據處理成 XML 格式,相對于二進制的 AFM 太冗長了;?
            AMF 能更有效序列化數據;因為 AMF 的初衷只是為了支持 Flash ActionScript 的數據類型,而 SOAP 卻致力于提供更廣泛的用途;?
            AMF 支持 Flash 播放器 6 只需要瀏覽器增加 4 KB 左右(壓縮后)的大小,而 SOAP 就大多了;?
            SOAP 的一些頭部文件請求在 Flash 播放器 6 不支持。那 Flash 播放器 6 為什么能訪問基于 SOAP 的 Web 服務呢?原來 Flash Remoting 網關將 SOAP 請求在服務器端與轉換成 AFM 格式,然后利用 AFM 與 Flash 播放器通信。另外, AMF 包中包含 onResult 事件(比如說 response 事件)和 onStatus 事件(比如說 error 事件),這些事件對象在 Flash 中可以直接使用。?
            AMF 從 Flash MX 時代的 AMF0 發展到現在的 AMF3 。 AMF3 用作 Flash Playe 9 的 ActionScript 3.0 的默認序列化格式,而 AMF0 則用作舊版的 ActionScript 1.0 和 2.0 的序列化格式。 在網絡傳輸數據方面, AMF3 比 AMF0 更有效率。 AMF3 能將 int 和 uint 對象作為整數( integer )傳輸,并且能序列化 ActionScript 3.0 才支持的數據類型 , 比如 ByteArray , XML 和 Iexternalizable 。

            ????? AMF 很好的解決了內容的豐富性。(具體 AMF 格式參考附件格式文檔)

            3.3.1 AMF中的數據類型Data Types
            AMF0 supports the following data types (with their type field values):

            NUMBER = 0x00
            BOOLEAN = 0x01
            STRING = 0x02
            OBJECT = 0x03
            MOVIECLIP = 0x04
            NULL_VALUE = 0x05
            UNDEFINED = 0x06
            REFERENCE = 0x07
            ECMA_ARRAY = 0x08
            OBJECT_END = 0x09
            STRICT_ARRAY = 0x0a
            DATE = 0x0b
            LONG_STRING = 0x0c
            UNSUPPORTED = 0x0d
            RECORD_SET = 0x0e
            XML_OBJECT = 0x0f
            TYPED_OBJECT = 0x10
            Binary Format
            AMF format for a value/object consists of a type byte (see above) followed by zero or more bytes. This section describes the bytes following the type byte for various types.

            NUMBER (type byte: 0x00)
            Numbers are stored as 8 byte (big endian) float double. On x86 you can just byteswap a double to encode it correctly.

            BOOLEAN (type byte: 0x01)
            A boolean is encoded in one byte. FIXME: is true sent as 0xff? 0x01?

            STRING (type byte: 0x02)
            A string is encoded as a 2 byte (big endian) count (number of bytes) followed by that many bytes of text. Note: there is no null terminator.

            I think the text is assumed to be UTF-8. Can someone double check me on this?

            NULL_VALUE (type byte: 0x05)
            A null has zero bytes following the type byte

            UNDEFINED (type byte: 0x06)
            A undefined has zero bytes following the type byte

            OBJECT (type byte: 0x08)
            An object is encoded as a series of key/value pairs. The key is encoded as a STRING (above) WITH NO TYPE BYTE, and the value is any AMF value.

            The object encoding is terminated by 0x000009 (that is a zero length string key, followed by the OBJECT_END type byte described below.

            OBJECT_END (type byte: 0x09)
            This is not really a value, but a marker for the end of an OBJECT. See above.

            STRICT_ARRAY (type byte: 0x0a)
            This is the encoding for arrays such as ["foo", "bar", 1, 2, 3]. For a hash (a set of key/value pairs) you'll need to use OBJECT above.

            An array is encoded as 4 byte (big endian) integer which is the number of elements in the array, followed by that many AMF values.

            That's it. There's no terminator of any kind.

            Use in shared object files
            While most AMF objects are just a value, there is a special variation used by shared object files for properties. Rather than start with the type field, followed by the length, it starts with a byte count, then the name, and then the regular AMF type field, the length, and then the data.

            3.4 客戶端和服務器的連接過程
            3.4.1客戶和服務器的握手
            ?

            ?? Flash Player 以系統時間作為種子通過某種算法生成的數字簽名,大小是 1537 字節向服務器發起第一次握手,服務器根據客戶端的數字簽名產生一個 3073 字節的驗證包,給客戶端,客戶端在接受到服務器的回應以后會發送一個 1536 字節的回復。

            具體的流程:

            發送第一次握手包 handshark1
            接收第二次握手包 handshark2
            發送的三次握手包 handshark3
            第一個握手包 handshark1 和服務器的回復握手包 handshark2 都是以 0X03 開頭。這三次握手不是 RTMP 協議本身的內容,所以在這并沒有包含 RTMP? 的協議頭。是服務器的廠家自己產品做驗證用的,嚴格的說就是你必須用? Adobe 的客戶端和服務器才能使用我的協議。

            3.4.2客戶和服務器通信
            ?? 具體連接和請求視頻的過程

            發送 rtmp_connect 命令
            . 發送本地帶寬消息 . 默認是 125000
            服務器返回服務器帶寬信息
            服務器返回本地帶寬信息
            服務器返回連接成功消息 "NetConnection.Connect.Success"
            客戶端發送創建流請求 encodeCreateStreamPacket
            服務器返回創建流成功消息
            客戶端發送播放文件消息 Rtmp_Play
            服務器返回 TYPE_CHUNK_SIZE 消息
            服務器返回開始播放消息 "NetStream.Play.Start"
            服務器返回視頻信息 (TYPE_STREAM_METADATA) ,包括大小,寬高,速率等等信息--文件長度可以在這里推算出來
            RTMP 的凈核決定了內容服務, adobe 的服務器采用的 AMF 格式的字串命令來控制視頻的傳輸和播放,具體的字串命令信息如下:(注:字串的定義有廠家( adobe )自己定義,只要滿足 AMF 的格式就可以)

            ?
            ?
            NetConnection.Call.Failed
            NetConnection.Call.BadVersion?
            NetConnection.Connect.AppShutdown
            NetConnection.Connect.Closed
            NetConnection.Connect.Rejected
            NetConnection.Connect.Success
            NetStream.Clear.Success
            NetStream.Clear.Failed
            NetStream.Publish.Start
            NetStream.Publish.BadName
            NetStream.Failed
            NetStream.Unpublish.Success
            NetStream.Record.Start
            NetStream.Record.NoAccess
            NetStream.Record.Stop
            NetStream.Record.Failed
            NetStream.Play.InsufficientBW
            NetStream.Play.Start
            NetStream.Play.StreamNotFound
            NetStream.Play.Stop
            NetStream.Play.Failed
            NetStream.Play.Reset
            NetStream.Play.PublishNotify
            NetStream.Play.UnpublishNotify
            NetStream.Data.Start
            Application.Script.Error
            Application.Script.Warning
            Application.Resource.LowMemory
            Application.Shutdown
            Application.GC
            Play
            Pause
            demoService.getListOfAvailableFLVs
            getStreamLength
            connect
            app
            flashVer
            swfUrl
            tcUrl
            fpad
            capabilities
            audioCodecs
            audioCodecs
            videoCodecs
            videoFunction
            pageUrl
            createStream
            deleteStream
            duration
            framerate
            audiocodecid
            audiodatarate
            videocodecid
            videodatarate
            height
            width
            3.4.2數據的萃取
            ????? 在服務器返回開始播放消息 "NetStream.Play.Start" 之后,服務器就會開始給客戶端傳輸數據了,一般數據的萃取都是先解析協議的頭,然后根據協議頭中數據類型和凈核長度就可以把數據部分取出, RTMP 協議也是這樣。

            struct RTMP_HEAD

            {

            ????????? char cChannelid : 6;// 第一個字節的后 6 位

            ????????? char cCheadsize ; // 第一個字節的頭兩位

            ????? char cTimer[3];? // 三個字節表示的時間信息

            ????? char cLength[3]; // 三個字節表示的長度

            ????? char cDatatype; // 數據類型

            ????? char sStreamid[4]; // 流標識

            }

            ????? 首先判斷 cDatatype 是那種類型,然后根據不同的類型進行萃取數據部分,進行不同的處理,獲取視頻的數據的方式先看是否是一下的類型:

            0×08? Audio Data? packet containing audio?
            0×09? Video Data? packet containing video data?

            ?
            根據凈核的長度讀取出內存中的音視頻數據,這里的音視頻數據是有一定編碼格式的數據,這個取決于應用的具體配置, Flash play 使用的是 FLV 的格式。要對這部分數據進行存取,還有做一部分工作,對 FLV 的視頻數據進行去殼,取出數據保存文件就可以了。


            本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/chenyanxu/archive/2009/09/02/4511087.aspx

            亚洲国产精品一区二区三区久久| 亚洲午夜精品久久久久久浪潮| 亚洲综合精品香蕉久久网| 久久有码中文字幕| 久久久久久久综合综合狠狠| 久久久99精品一区二区 | 精品国产乱码久久久久久郑州公司| 久久无码高潮喷水| 久久人人爽人人爽人人片av高请| 久久综合亚洲欧美成人| 久久er热视频在这里精品| 欧美日韩中文字幕久久伊人| 久久精品国产亚洲av瑜伽| 思思久久好好热精品国产| 亚洲狠狠婷婷综合久久蜜芽| 久久精品免费一区二区三区| 久久久久18| 久久99精品国产自在现线小黄鸭 | 亚洲中文字幕无码一久久区| 久久精品九九亚洲精品| 久久精品国产一区二区三区日韩| 久久亚洲精品无码播放| 色欲综合久久躁天天躁蜜桃| 97久久天天综合色天天综合色hd| 久久精品无码一区二区三区日韩 | 久久96国产精品久久久| 久久免费大片| 久久久精品一区二区三区| 亚洲欧洲久久av| 99久久婷婷免费国产综合精品| 久久久久久无码国产精品中文字幕 | 久久久精品免费国产四虎| 久久精品aⅴ无码中文字字幕不卡 久久精品aⅴ无码中文字字幕重口 | 久久国产亚洲精品| 青青久久精品国产免费看| 精品国产乱码久久久久久浪潮| 国内精品伊人久久久久| 麻豆精品久久久一区二区| 91麻精品国产91久久久久| 精品国产91久久久久久久a| 久久久久国产成人精品亚洲午夜|