linuxrtmp伺服器搭建
❶ Mac搭建Nginx流媒體伺服器,進行推流,拉流
Nginx 是非常優秀的開源伺服器,用它來做hls或者rtmp流媒體伺服器是非常不錯的選擇
下面介紹如何在Mac上搭建流媒體伺服器,以便後續的自己研究的項目或者demo向伺服器上進行推流
首先需要安裝brew,brew是一款管理軟體的第三方平台,安裝的方式也很簡單,請自行查閱安裝方式
執行下面2句命令,即可安裝rtmp推流的nginx伺服器
執行完後,可以查看ngix安裝在哪裡
可以看到M1 是安裝在這個目錄下/usr/local/etc/nginx
打開這個目錄,可以看到有個nginx.conf文件,這里就是伺服器的一個配置文件,如果支持rtmp,則裡面的內容會有一個rtmp的json
這個json說明:
1.你本地的nginx伺服器會監聽1935埠號,
2.伺服器會創建一個mytv的程序
後續你可以向這個地址進行推流,並且進行拉流播放
後面我們會使用ffmpeg向這個地址推流
rtmp://localhost:1935/mytv/room
並且用vlc拉取這個地址的流進行播放
執行命令,即可啟動nginx伺服器
驗證是否啟動成功,只需要在瀏覽器中訪問下以下鏈接
在瀏覽器地址欄輸入: http://localhost:8080
出現Welcome to nginx ,代表nginx安裝成功了。
打開配置文件 /usr/local/etc/nginx/nginx.conf
這里推的是flv流,可以正常推,這里需要注意的是伺服器地址一定要寫正確,我的nginx.conf里application配置的是mytv,所以路徑就是mytv,room則是隨便寫都行,代表向程序mytv下的room文件推流
然後電腦上打開vlc這個播放器軟體 點擊File---->Open Network 在彈出來的框中選擇Network然後輸入URL:
驗證時,推流的文件最好搞大點,不然一下推完了,你才去拉取播放,則播放不了,因為這是實時的
vlc使用如下
3.點擊播放即可
可以看到左邊是畫面,右邊是ffmpeg在推流
參考: https://www.jianshu.com/p/cf74a34af15d
❷ 如何在linux操作系統下搭建配置流媒體伺服器系統
在Linux操作系統下搭建配置流媒體伺服器系統方法詳見:https://jingyan..com/article/0eb457e5c8f69303f1a905b3.html
❸ 如果要搭建一個直播平台,直播開發平台中都會用到哪些介面
先,伺服器,是最基本的,也是最重要的,系統只有搭建在伺服器上才能運作。前期基本的伺服器建議阿里雲或者騰訊雲或者其他支持rtmp協議的伺服器,推薦4核8G2M帶寬,系統linux cent os7.x(一般為最新的7.6)可支持前期基本運營,後期可根據在線人數升級伺服器。
域名:域名一般建議使用運營者自己實名備案的,如果是購買的別人的,在運營中可能會掉,域名掉了,APP也就訪問不了了。只有把域名解析到伺服器上,網路才能找到你的。也是必需的
簡訊驗證碼:登錄驗證,市場上很多的驗證碼提供商,價格也是很便宜。
其他登錄方式,如微信快捷登錄,QQ登錄等,需要開通QQ互聯及微信開放平台的授權。
充值支付:最為常見的就是微信支付和支付寶支付,這兩種方式都需要用到公司資質也就是營業執照,微信支付,需要在微信開放平台申請微信支付的商戶號,(微信公眾號不可)審核費用,每年300元。賬期需要看自己的APP種類,一般分為T+1和T+7等,具體的可以咨詢微信官方。支付寶支付是免費的,需要獲取開發者能力,配置相關的參數,回調等。其他的三方支付,需要提供三方支付的介面,及文檔等信息。不過一般不建議三方支付,有丟單的情況。
騰訊雲賬號:騰訊雲在社交方面還是很強大,現在大部分的社交APP還是集成了騰訊的SDK。騰訊的產品首次使用會有一段時間的免費試用,試用過後就需要付費了。
美顏:市面上也是有很多的美顏商家,提供專業 美顏服務,具體的可以和APP開發商商議。
任何一款直播平台開發都會用到很多的技術,開發商也是一樣,會在一套APP內集成多個三方的SDK。在各個領域都有專業的服務商,如果全套的服務都是自己開發,受眾面穩定及兼容性也是非常難以做到最完美的,全部自研的成本將會無限提高。
做直播平台,關鍵是看個人怎麼運營,怎麼能增加用戶的粘性,讓用戶能夠可以持續給平台提供資金流,優質的主播是必不可少的,但是平台的運營策略和推廣力度也會起到至關重要的作用。
❹ 我有一台win2012的伺服器,想自己搭建一個rtmp的直播伺服器,請問需要什麼軟體
這兩天我就在試玩Adobe Media Server 5 extend,流媒體服務所用的環境就是一台win7 64位旗艦版的i5 2.4GHz、4G內存Dell筆記本,3個獨立IP的測試發布終端(Wirecast、Adobe live media encoder、Matrox MonarchHD)都以RTMP協議往伺服器中發布直播流,除了MonarchHD因為只具有有線接入外,全部設備包括AMS所在的筆記本都用無線AP接入一個局域小網。其中MonarchHD publish給筆記本中安裝的AMS推送一個2M碼流的1920x1080 i50 H.264直播流,用各種接收終端接收流都很清晰流暢
我的伺服器用的是小鳥雲的,很穩定,流暢。
❺ linux怎麼啟動 ams服務
時間:2016-03-23來源:linux網站 作者:meteorite91
最近需要使用rtmp伺服器,在red5和AMS之間選擇了AMS來搭建,說先說明一下AMS全稱是adobe media server,在5.0版本之前名稱是FMS(flash media server)。
搭建的環境:64位的centos6.5,PS:AMS只支持64位的系統,不管是windows還是Linux都只有64位,安裝之前要安裝好64位的Linux環境。
在http://www.adobe.com/support/flashmediaserver/downloads_updaters.html下載5.0.3版本的源碼包,在centos切換root許可權,解壓,進入AMS_5.0.3_r3029目錄,運行./installAMS,後面根據提示按enter等鍵即可,需要注意的是在提示輸入IP的時候最好使用自己想用的IP而不是自動檢測,默認的埠是1935和1111,其他都可以默認執行。
❻ linux apache 怎麼安裝rtmp
一,目標: 利用開源或者免費工具實現一個直播系統;同時支持在瀏覽器、播放器和嵌入到 PC 應 用或者移動 APP 中觀看直播。 二,技術選型: 視音頻源端:: Adobe Flash Media Live Encoder 3.2,可以在 windows 和 mac 安裝; 如果你已有一些支持 RTMP 的採集設備,那是最好了; 或許你想在自己的應用中實現,這樣你就必須自己開發處理採集,編碼和協議傳輸了(以後 再表); RTMP Server: FMS -- Adobe 公司出品的伺服器,價格昂貴,當然是最正宗的,因為 RTMP 就是 Adobe 公 司的私有協議; Wowza -- 同樣需要授權費, 大概是$55 per month/instance,效率和穩定性都還不錯; Red5 -- 一個開源實現, 效率和穩定性都稍微差些,由於它是 java 實現的,所以天生支持 跨平台運行; Nignx-rtmp-mole - -nginx 的一個第三方模塊,如果你熟悉 nginx 那是不錯的選擇,當然它 也是免費的,不過功能就沒有其他幾個豐富了; 這里我選擇 nginx+nginx-rtmp-mole 作為伺服器,這是我認為最容易上手的一種方式了(如 果 你 把 windows 作 為 服務 器 那 可 能 麻煩 些 , 官 方 提供 的 windows 二 進 製版 本 是 沒 有 nignx-rtmp-mole 的
❼ 直播系統源碼是如何實現視頻直播以及直播系統搭建的
一、手機直播系統源碼開發實現視頻直播主要有以下四步:
1)前端採集編碼設備:提供直播信號源的採集和編碼壓縮功能,並將信號推送到直播流媒體伺服器上。
2)直播流媒體伺服器:負責直播流的發布和轉播分發功能。
3)WEB伺服器:實現直播節目在終端上的展現。
4)終端設備:包括PC和移動終端。編碼和協議 是實現直播的重要環節:1)網路協議:主要有3種 a. RTSP(Real Time Streaming Protocol)是用來控制聲音或影像的多媒體串流協議, 由Real Networks和Netscape共同提出的;b. RTMP(Real Time Messaging Protocol):實時消息傳送協議是Adobe公司為Flash播放器和伺服器之間音頻、視頻和數據傳輸 開發的開放協議;c. HLS(HTTP Live Streaming):是蘋果公司(Apple Inc.)實現的基於HTTP的流媒體傳輸協議; 2)視頻編碼: Mpeg4, H264等 3)音頻編碼: Mp3, AAC等4)視頻解析度: 標清通常指的是640×480(或768×480);高清指的是1280×720;全高清指的是1920×1080;超高清3840×2160。
二、直播系統源碼搭建伺服器部署重點
直播系統源碼有哪幾塊組成,視頻直播的過程一般可以分為採集、前處理、編碼、傳輸、解碼、渲染這幾個環節,經過這幾個環節之後,我們就可以通過PC端或者移動端進行視頻直播的觀看。直播系統在搭建時會用到多個業務伺服器,共同完成直播系統的業務邏輯流程。通常在伺服器部署時會採用動靜分離分布式部署方式,保障了直播平台的穩定運行。主要用到以下的業務伺服器。
1)消息伺服器:主要用於消息推送,給用戶推送房間聊天消息、私信消息。
2)業務伺服器:手機直播的業務部分、好友關系、直播管理、貨幣系統、禮物系統等。
3)視頻伺服器:視頻直播、點播、轉碼、存儲和點播等。
4)IM即時聊天:使用Node.js服務自主搭建部署聊天伺服器。
5)視頻流(流媒體伺服器):建議採用第三方CDN,開通賬號即可使用。關於CDN方面的內容,我們會在以後的內容中做重點介紹。
6)業務伺服器:網站邏輯基於php-tlinkphp、thinkcmf、mysql、redis。MYSQL 服務提供靜態數據的存儲,REDIS 服務提供數據的緩存、存儲動態數據。
以上便是對直播系統源碼如何實現視頻直播以及搭建伺服器的簡單介紹。搭建直播開發平台之前就是找到一款優質的直播系統源碼,直播系統源碼開發原理比其他軟體更加復雜,而且相對於技術以及其他方面都會有一定的要求。直播系統源碼的穩定性和安全性決定了後期搭建出的直播平台的流暢度、高並發承載及用戶的產品體驗,所以選擇直播源碼的時候一定不要為了貪圖價格便宜,而選擇安全性低,系統功能不會正常更新,bug一堆的源碼。直播系統源碼的開發需要經過推流端(採集、前處理)、服務端處理(編碼、轉碼、錄制、截圖、鑒黃)、播放器(拉流、解碼、渲染和互動系統)。望採納,謝謝
❽ nginx-rtmp模塊簡介
1: Mole Configuration Struct(s)模塊配置結構
這個結構的命名規則為ngx_http_[mole-name]_[main|srv|loc]_conf_t。
main,srv,loc表示這個模塊的作用范圍是配置文件中的main/server/location三種范圍(這個需要記住,後面會經常用到)
2: Mole Directives模塊命令結構
static ngx_command_t ngx_http_echo_commands[] = {
{
ngx_string("echo"), //命令名字
NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, //代表是local配置,帶一個參數
ngx_http_echo, //組裝模塊配置結構
NGX_HTTP_LOC_CONF_OFFSET, //上面的組裝模塊配置獲取完參數後存放到 哪裡?使用這個和下面的offset參數來進行定位
offsetof(ngx_http_echo_loc_conf_t, ed), //同上
},
ngx_null_command //必須使用ngx_null_command作為commands的結束標記
};
3: The Mole Context模塊內容
static ngx_http_mole_t ngx_http_circle_gif_mod ule_ctx
主要是定義了一些鉤子函數, nginx會在不同時期會調用
4: The Mole Definition模塊整合
ngx_mole_t ngx_http_<mole name>_mole = {
NGX_MODULE_V1,
&ngx_http__mole_ctx, /* mole context模塊內容 */
ngx_http__commands, /* mole directives模塊命令*/
NGX_HTTP_MODULE, /* mole type模塊類型,HTTP模塊,或者HTTPS*/
5: Mole Installation模塊安裝
1: ngx_rtmp_live_mole
直播模塊:推拉流同點, 不涉及回源
2: ngx_rtmp_relay_mole
中繼模塊: 1:回源pull 2: 轉推: push
一: 建立rtmp連接, 需要握手
1: ngx_rtmp_handshake_recv()開始握手
2: NGX_RTMP_HANDSHAKE_DONE()握手完成
3: ngx_rtmp_cycle()重新設置讀寫handler
二: 建立網路連接
建立rtmp連接之後, ngx_rtmp_recv函數會利用ngx_event_t結構會獲取推送過來的原始數據, 接受到的數據會存放到ngx_rtmp_stream_t的in鏈表結構中.
1:接受chunk數據
2:分析處理chunk數據, 如果message還沒接受完, 繼續接受數據
3:將chunk組成一個rtmp message, 然後交給ngx_rtmp_receive_message處理, 這個函數根據消息的類型找對應的handle
三: 建立網路流
在建立網路連接後,就需要建立網路流了, 網路流代表了發送多媒體數據的通道. 伺服器和客戶端只能建立一個網路連接, 且多個網路流可以復用這一個網路連接
1: ngx_rtmp_recv接受數據後交給ngx_rtmp_receive_handler, 它會根據類型區別處理, 此時客戶端發送ngx_rtmp_msg_chunk_size類型的消息
2:接受message後跳轉到處理函數ngx_rtmp_amf_message_handler. 處理客戶端發送的amf控制消息. 此時連續接受3個amf數據.
3:調用ngx_rtmp_cmd_create_stream_init初始化網路流. 利用ngx_rtmp_receive_amf獲取接受的amf數據.
4:調用ngx_rtmp_cmd_create_stream創建網路流, 利用ngx_rtmp_send_amf向客戶端發送amf控制消息
四: 傳輸媒體數據
在客戶端和服務端建立網路流之後,接下來就可以傳輸媒體數據了, 一般來講, 媒體數據分為兩部分, 一部分為meta元信息, 另一部分是音視頻數據, 首先傳送的是meta元信息. 然後推送媒體. 伺服器處理如下:
1:從客戶端接受amf命令信息, 然後服務端會利用ngx_rtmp_cmd_publish_init來初始化發布環境. 函數功能: 會讀取剛接受端amf信息
2:利用ngx_rtmp_auto_push_publish, ngx_rtmp_notify_publish, ngx_rtmp_exec_publish建立發布環境,
3:如果conf配置了record命令記錄媒體文件, 此時會調用ngx_rtmp_record_publish來初始化記錄環境;
4:執行ngx_rtmp_access_publish;
[if !supportLists]l [endif]meta信息:
5:接受客戶端amf, 並調用ngx_rtmp_codec_meta_data獲取meta元信息;
6:結合伺服器的參數, 利用ngx_rtmp_codec_reconstruct_meta介面重構meta元信息, 並調用ngx_rtmp_prepare_message組成消息保存
[if !supportLists]l [endif]媒體數據:
7:接受客戶端推送, 根據類型轉到ngx_rtmp_codec_av來處理音視頻數據; 其中利用函數ngx_rtmp_codec_parse_avc_header來處理頭部信息
8:調用record模塊記錄數據, 介面為ngx_rtmp_codec_av;
9:調用live模塊來廣播發布數據, 介面為ngx_rtmp_live_av, 廣播到所有觀察者, 第一次調用介面ngx_rtmp_live_start創建廣播, 之後直接調用ngx_rtmp_append_shared-bufs
rtmp 的 信令交互圖:
1: 播放器端發起play
2: ngx_rtmp_relay_play()
3: ngx_rtmp_relay_pull() --主要建立pull請求, 將遠程拉流的上下文和本地上下文放到鏈表中
ngx_rtmp_relay_create_local_ctx()創建本地上下文
ngx_rtmp_relay_create_remote_ctx()創建遠端上下文
4: ngx_rtmp_relay_create_remote_ctx詳解: 創建遠端session, 開始rtmp信令交互
1: ngx_rtmp_relay_create_connection
2: ngx_rtmp_init_session
注意:此時session中的flashver為「ngx-local-relay「
5: rtmp信令交互流程
核心函數: ngx_rtmp_relay_on_result主要用來接收對端服務端發送的amf消息包,而後按正常rtmp協議請求進行下一步交互,這個主要是當前服務端做為客戶端發起遠程rtmp請求流程
例如: ngx_rtmp_client_handshake(發起握手)
握手完成後調用回調函數: ngx_rtmp_relay_handshake_done
ngx_rtmp_relay_send_connect:發起連接請求, 接著參考rtmp信令交互圖
核心功能:向nginx推送一個直播流,該直播流經 nginx-rtmp 的 ngx_rtmp_live_mole 模塊轉發給 application live 應用,然後使用vlc連接 live,播放該直播流。本質上就是1對多的廣播
參考: http://nginx.org/en/docs/debugging_log.html
1: Nginx-rtmp-mole模塊源碼學習
https://blog.evanxia.com/2017/02/1264
2: nginx_rtmp_relay_mole模塊解讀
https://www.shangmayuan.com/a/d74b78669f804fb5b12cae5a.html
3:開發手冊中文版:包含指令介紹
https://blog.csdn.net/ai2000ai/article/details/55517992
❾ Android平台FFmpeg實現rtmp推流-C++的實現
視頻編碼有幾種方式:
1.硬編碼,使用MediaCodec實現
2.軟編碼,使用FFmpeg或者libx264庫來實現。
本文分享在Android平台視頻編碼-軟編碼的實現,也就是用FFmpeg來實現視頻的編碼,rtmp推流到伺服器上,相機採集視頻將在下一篇文章分享。
流媒體伺服器使用 nginx-rtmp-mole 來進行搭建。
本文所使用FFmpeg的版本是4.1,關於FFmpeg編譯成Android平台so庫如果有需要,我將在下一篇文章分享說明。
視頻編碼比較耗cpu,上傳視頻數據的會耗網路io,所以需要開啟新線程去處理,這里我用HandlerThread來處理視頻的編碼上傳。
初始化編碼相關操作
這里我們使用的是FFmpeg,所以在編碼前我們會先做一些初始化以及參數設置工作。
FFmpeg初始化
av_register_all()
創建輸出格式上下文
avformat_alloc_output_context2()
獲取編碼器
avcodec_find_encoder(AV_CODEC_ID_H264) 獲取H264的編碼器
設置編碼器參數
使用給定的編碼器和參數初始化編碼上下文
avcodec_open2(pCodecCtx, pCodec, ¶m)
創建視頻流
video_st = avformat_new_stream(ofmt_ctx, pCodec)
打開輸出上下文
avio_open(&ofmt_ctx->pb, out_path, AVIO_FLAG_READ_WRITE)
寫入輸出頭信息
avformat_write_header(ofmt_ctx, NULL)
像素格式轉換
AV_PIX_FMT_YUV420P,它是純平面存儲。總共三個平面,分別存放,Y、U、V數據。
當圖像寬是width,高是height時,Y分量的大小就是width×heitht,而U是width×heitht/4,V也是U是width×heitht/4。
H264編碼
首先我們需要了解兩個數據結構AVFrame、AVPacket
AVFrame存放的是原始數據、AVPacket存放的是編碼後的數據。
創建AVPacket
av_new_packet(&enc_pkt, picture_size);
開始編碼
ret = avcodec_encode_video2(pCodecCtx, pFrameYUV);
輸出一幀編碼後的視頻數據
ret = av_write_frame(pCodecCtx, &enc_pkt);
釋放資源
小夥伴們有疑問的可以在下方評論區評論。
❿ rtmp規范1.0全面指南
RTMP(real time messaging protocol)協議
本文為Adobe rtmp規范1.0的中文介紹,其中內容大部分都是翻譯自rtmp官方文檔 rtmp_specification_1.0.pdf
Adobe的實時消息傳輸協議( RTMP )通過可靠的流傳輸(如 TCP [RFC0793] )提供雙向消息多路傳輸服務,用於在端到端之間傳輸帶有時序信息的視頻,音頻和數據消息的並行流。 穿過多層流, RTMP 消息塊流不提供任何控制的優先順序別和相似形式,但是可以用於高層協議提供這樣的優先順序,例如:一段實時視頻服務會選擇丟棄給緩慢的客戶的視頻信息確保音頻信息可以及時被接收。 RTMP消息塊流 包含它自己的入隊協議控制消息,也提供一個高層協議機制用於嵌入用戶的控制消息。
有效負載:Payload
包含在包中的數據,就像音頻樣本或者壓縮的視頻數據。
包:Packet
一個數據包由固定的包頭和有效負載數據組成,一些底層協議或許需要包的封裝來被定義。
埠:Port
在 TCP/IP 協議中定義的用正整數表示的埠號用於在傳輸中提取以區分目標主機的不同應用,用於 OSI 傳輸層的傳輸選擇( TSEL )就是埠。
傳輸地址:Transport address
網路地址和埠的組合識別一個傳輸層終端埠,例如一個IP地址和TCP埠,數據包從一個源傳輸層地址傳送到目標段的傳輸層地址。
消息流:Message stream
一個通信的邏輯通道,允許消息流通。
消息流ID:Message stream ID
每一個消息擁有一個分配的ID識別跟隨的消息流。
消息塊:Chunk
消息的片段,消息被分成小的部分,在他們在網路中發送之前交叉存儲。消息塊確保定製時間戳的端到端全消息傳送,穿過多層流。
消息塊流:Chunk stream
一個通信的邏輯通道,允許消息塊在一個特定的方向上流通,消息塊流可以從客戶端傳送到伺服器,也可以相反。
消息塊流ID:Chunk stream ID
每一個消息塊有一個分配的ID用於識別更隨的消息塊流。
復合技術:Multiplexing
把分開的音視頻數據組合成一條音視頻流的過程,使同時傳送許多音視頻數據成為可能。
逆復合技術:DeMultiplexing
復合的反向過程,交叉存取組裝的音頻視頻數據,使他們成為最初的音視頻數據
遠程過程調用:Remote Procere Call (RPC)
允許客戶端或伺服器在對等端調用子常式或過程的請求。
Action Message Format (AMF)
一種緊湊的二進制格式,用於序列化 ActionScript object graphs 。 可以透過 AMF overHTTP 的方式將 flash 端資料編碼後傳回server,server端的 remoting adaptor 接收到資料後則會解碼回正確的 native 對象,交給正確的程序處理。
所有的整數欄位都被引入到了位元組順序當中,位元組0是第一個顯示出來的,也是一個詞和一個欄位中最重要的。這種順序就是通常所說的「大端」。如果沒有特殊說明,在本文檔中數字常量都是用十進製表示。
除另有規定外, RTMP 中的所有數據都是位元組對齊的。例如,一個16位欄位可能處於奇數位元組偏移處。 在指定填充的地方,填充位元組應該是0。
RTMP 中的時間戳相對於未指定的時期是以整數毫秒為單位給出的。 通常,每個流將以時間戳0開始,但這不是必需的,只要兩個終端在時間點上達成一致。 請注意,這意味著跨多個流(尤其是來自不同主機)的任何同步都需要一些 RTMP 外的其他機制。
時間戳必須始終在線性的增加,允許應用程序處理非同步傳輸,帶寬度量,檢測,和流控制。
由於時間戳長度為32位,因此它們每隔49天,17小時,2分鍾,47.296秒滾動一次。 由於流可以連續運行,可能持續數年, RTMP 應用程序應該在處理時間戳時使用序列號演算法 [RFC1982] ,並且應該能夠處理回繞。 例如,假定所有相鄰的時間戳都在 2^31 - 1 毫秒之間,所以10000會在4000000000之後,而3000000000會在4000000000之前。
時間戳增量delta也被指定為相對於先前時間戳的無符號整數毫秒數。 時間戳增量delta可以是24位或32位。
本節介紹實時消息傳送協議塊流( RTMP塊流 )。 它為更高級別的多媒體流協議提供復用和打包服務。 雖然 RTMP Chunk Stream 旨在與實時消息傳送協議配合使用,但它可以處理發送消息流的任何協議。 每條消息都包含時間戳和有效負載類型標識。 RTMP Chunk Stream 和 RTMP 一起適用於各種音頻 - 視頻應用,從一對一和一對多實時廣播到視頻點播服務,再到互動式會議應用。
當與可靠的傳輸協議(如 TCP [RFC0793] )一起使用時, RTMP塊流 提供了保證所有消息在多個流中按時間排序的端到端傳送。 RTMP塊流 不提供任何優先順序或類似的控制形式,但可以由更高級別的協議提供這種優先順序。
可以拆分成塊以支持復用的消息格式取決於更高級別的協議。 但是,消息格式應該包含下列創建塊所必需的欄位。
時間戳:
消息的時間戳,這個欄位可以傳輸4個位元組。
長度:
消息的有效負載的長度,如果消息頭不能被省略,它應該包含在長度中,這個欄位在消息塊包頭中佔有3個位元組。
類型ID:
協議控制消息的類型欄位的范圍是被保留的,這些傳播信息的消息由 RTMP消息塊 和高層協議處理,所有其他的類型ID可被高層協議使用,對 RTMP消息塊 來說當做不透明的值,實際上, RTMP Chunk Stream 中的任何內容都不需要將這些值用作類型; 所有(非協議)消息可以是相同類型的,或者應用程序可以使用類型id來區分同步蹤跡而不是類型。 該欄位佔用塊頭中的1個位元組。
消息流ID:
消息流ID可以是任意的值。 復合到相同塊流上的不同消息流可以基於它們的消息流ID進行逆復合操作。 除此之外,就 RTMP 塊流而言,這是一個不透明的值。 該欄位以小尾數格式佔用塊頭中的4個位元組。
RTMP 連接始於握手。 rtmp 握手與其他協議的握手不同; 它由三個相同大小的塊組成,而不是由可變大小的塊組成。
客戶端(連接已初始化的終端)和伺服器都發送相同的三個塊。 為了說明,由客戶端發送的3個塊分別為 C0 , C1 , C2 ,由服務端發送的3個塊分別為 S0 , S1 , S2 。
握手以客戶端發送 C0 和 C1 消息塊位開始,客戶端必須等到 S1 到達在發送 C2 。客戶端必須等到 S2 接收到才可以發送其他的數據;服務端必須等到 C0 到達才發送 S0 和 S1 ,在 C1 之後也會等待。服務端必須等到 C1 到達才發送 S2 ,服務端必須等到 C2 到達後才發送其他數據。
C0 和 S0 都是單個8位位元組,可以看成一個8位整形欄位。
8比特版本:在C0中,這個欄位識別客戶端需求的RTMP的版本,在S0中,這個欄位識別伺服器端選擇的RTMP的版本,被定義的是版本3,0到2是早前的版本使用的,4到31保留用於未來使用,32到255還沒有被允許。不能區分客戶的請求的版本的服務應該以3返回,客戶端可以選擇降級到版本3,或放棄握手。
C1 和 S1 包長度為1536個8位位元組,包含以下欄位:
time(4個位元組) :這個欄位包含時間戳,被當做後續消息塊從終端發送的時間點,也許是0,或者一些任意的值。為了同步多路消息塊流,終端或許希望發送其他消息塊流的時間戳的當前值。
zero(4各個位元組) :這個欄位必須全0。
random data(1528個位元組) :這個欄位可以包含任何任意的值,因為每個終端必須區分自己初始化的握手的返回數據和對方初始化的握手的返回數據,這個數據應該發送一些隨機數。但是沒有必要用密碼保護隨機數和動態值。
C2 和 S2 包長度為1536個8位位元組,分別類似於 S1 和 C1 的原樣返回,由一下幾個欄位組成:
time(4個位元組) :
這個欄位必須包含由對端發送的 S1 (對應 C2 )或者 C1 (對應 S2 )的時間戳.
time2(4個位元組) :
這個欄位必須包含先前的由對端發送的數據包( S1 或者 C1 )被讀取的時間戳。
random echo(1528個位元組) :
這個欄位必須包含在對端發送的 S1 (對應 C2 )或 S2 (對應 C1 )數據包中的隨機數據欄位。 任何一方都可以使用 time 和 time2 欄位與當前時間戳一起快速估算連接的帶寬和/或延遲,但這不太可能有用。
下面的表格描述了握手過程的幾個階段
握手後,連接復用一個或多個消息塊流。每個塊流從一個消息流攜帶一種類型的消息。每個創建的塊都有一個與其關聯的唯一ID,稱為塊流ID。這些塊通過網路傳輸。發送時,每個塊必須在下一個塊之前全部發送。在接收端,根據塊流ID將塊組合成消息。
分塊允許將較高級別協議中的大的型消息分解為較小的消息,例如防止較大的低優先順序消息(例如視頻)阻塞較小的高優先順序消息(如音頻或控制)。
分塊還允許以較少的開銷發送小消息,因為分塊頭包含信息的壓縮表示信息,這些壓縮消息本來應該包含在消息本身的。
塊大小是可配置的。它可以使用 Set Chunk Size 控制消息進行設置。
每一個消息塊有頭部和數據組成,頭部自身可以被分割成三個部分:
消息塊基本頭(1到3個位元組) :這個欄位編碼了消息塊流的ID和消息塊的類型,消息塊類型決定了消息包頭的編碼格式,長度完全取決於可變長的消息塊流ID。
消息塊消息頭(0,3,7或11位元組) :這個欄位編碼正在傳送的消息的信息,長度可以利用在消息塊頭中詳細的消息塊類型來決定。
擴展時間戳(0或4位元組) :此欄位在某些情況下是存在的,取決於消息塊消息頭中的編碼時間戳或時間戳增量欄位。
消息塊塊數據(可變大小) :該塊的有效負載,直至配置的最大塊大小。
消息塊基本頭對消息塊流的ID和消息塊的類型進行編碼(在下面的圖表中用 fmt 表示),消息塊類型決定了編碼的消息頭的格式,消息塊基本頭欄位可以是1,2或者3個位元組長,取決於消息塊流ID。
該協議支持多達65597個ID為3-65599的流。 ID0,1和2被保留。 值0指示2位元組形式和64-319范圍內的ID( the second byte + 64 )。 值1表示3位元組形式,ID在64-65599( (the third byte) * 256 + the second byte + 64 )范圍內。 在3-63范圍內的值表示完整的流ID。 塊ID為2的流ID保留,用於低級別的協議控制消息和命令。
在消息塊基本頭中0-5比特(最不重要的)代表了消息塊流ID。
消息塊流ID 2-63 可以被編碼成這個欄位的單位元組的版本號。
塊流ID 64-319可以以2位元組的形式被編碼。 ID計算為(第二個位元組+ 64)。
可以在此欄位的3位元組版本中對塊流ID 64-65599進行編碼。 ID計算為((第三位元組)* 256 +(第二位元組)+64)。
cs id(6比特) :這個欄位包含了消息塊流ID,值從2到63,值0和1用於代表這個欄位的2個或者3個位元組的版本號。
fmt(2比特) :這個欄位標識消息塊消息頭使用的四種格式之一。見下一小節
cs id -64(8或者16個比特) :
這個欄位包含了消息塊流ID減64,例如ID 365在 cs id 段用1表示,在16比特的 cs id -64 段用301表示。
值為64到319的消息塊流ID可以被2位元組或者3位元組的版本號來表示。
在消息塊消息頭中有四種不同的格式,由消息塊基本頭的 fmt 欄位選擇。應該使用最簡潔的表達方式表示每一個消息塊消息頭。
類型0的消息塊有11個位元組長,這個類型必須在消息塊流開始時和消息流的時間戳回溯時使用
時間戳(3個位元組) :對於類型0的塊,消息的絕對時間戳發送到此處。 如果時間戳大於或等於16777215(十六進制 0xFFFFFF ),則該欄位必須是16777215,表示存在擴展時間戳欄位以編碼完整的32位時間戳。 否則,這個欄位應該是整個時間戳。
類型1的消息塊有7個位元組長,消息流ID沒有被包含,這個消息塊得到和先前消息塊同樣的流ID,帶有可變長的消息的流(例如許多視頻格式)在類型0消息塊後應該使用這種格式作為每一個消息的第一個消息塊。
類型2塊頭長度為3個位元組。 流ID和消息長度都不包含在內; 該塊與前面的塊具有相同的流ID和消息長度。 具有固定大小消息的流(例如,某些音頻和數據格式)應該在第一個消息之後使用這種格式作為每個消息的第一個塊。
類型3 的消息塊沒有頭,流ID,消息長度和時間戳delta,這個類型的消息塊在之前的消息塊中取值,當單一的消息被分裂成消息塊,所有的消息塊除了第一個,其餘都應該使用這種類型,流由同樣大小的消息組成。
塊消息頭中每個欄位的描述:
Extended Timestamp 欄位用於編碼大於16777215( 0xFFFFFF )的時間戳或時間戳增量; 也就是說,對於時間戳或時間戳增量,它們不適合類型0,1或2塊的24位欄位。 該欄位對完整的32位時間戳或時間戳增量進行編碼。 這個欄位用於表示將類型0塊的時間戳欄位或類型1或2塊的時間戳增量欄位設置為16777215( 0xFFFFFF )。 當相同塊流ID的最新類型0,1或2的塊指示存在擴展時間戳欄位時,該欄位出現在類型3的塊中。
共有2個示例
本例給出了一個簡單的音頻消息流,這個例子示範了信息的冗餘。
下表顯示了在此流中生成的塊。 從消息3開始,數據傳輸得到優化。 除此之外,每消息只有1位元組的開銷。
本例說明一個很長的消息被分割成很多消息塊。
這里是分割出來的消息塊
消息塊1的包頭數據詳細介紹了307個位元組的消息的全部。
注意這兩個例子,類型3消息塊可以用作兩種不同的方式,第一種是表示一條消息的延續,第二種是表示一條新消息的開始,這個新消息可以從已經存在的數據中衍生出來。
RTMP 塊流使用消息類型ID 1,2,3,5和6作為協議控制消息。 這些消息包含 RTMP Chunk Stream 協議所需的信息。
這些協議控制消息務必具有消息流ID 0 (稱為控制流)並且以塊流ID 2 發送。協議控制消息一旦被接收就會立即生效,同時時間戳被忽略。
協議控制消息1:設置消息塊大小。用來通知對方新的最大的消息塊大小。
消息塊的大小可以被設置成一個默認的值,128位元組,但是客戶端或者服務端可以改變這個值,並且發送消息通知對方更新。例如:假設一個客戶端想要發送131位元組的音頻數據,消息塊的大小為128位元組,在這種情況下,客戶端可以發送這個協議控制消息給服務端以通知消息塊的大小被設置成了131位元組,那麼客戶端就可以用一個消息塊發送音頻數據。
最大塊大小應該不能小於128個位元組,並且必須不能小於1個位元組。 每個方向的最大塊大小都是獨立維護的。
0 : 這一位必須為0。
chunk size 塊大小(31位) :該欄位保存新的最大塊大小(以位元組為單位),這將用於發件人的所有後續塊,直至另行通知。 有效大小為1到2147483647( 0x7FFFFFFF )(含); 但是,大於16777215( 0xFFFFFF )的所有大小都是等效的,因為沒有塊大於一條消息,並且沒有消息大於16777215位元組。
協議控制消息2:中止消息。用於通知對方是否正在等待塊完成消息,然後丟棄部分接收到的消息。 對方接收塊流ID作為該協議消息的有效載荷。 應用程序可能會在關閉時發送此消息,以指示不需要進一步處理消息。
chunk stream ID 塊流ID (32 位) : 該欄位保存塊流ID,對應的當前消息將被丟棄。
客戶端或伺服器在收到等於窗口大小的位元組後,必須向對端發送 Acknowledgement 確認。 窗口大小是發送方未收到接收方確認而發送的最大位元組數。 該消息指定了序列號,它是到當前為止收到的位元組數。
sequence number 序列號(32 位) :欄位表示到當前為止收到的位元組數。
客戶端或伺服器發送此消息以通知對方在發送 Acknowledgement 確認之間使用的窗口大小。 發送人希望在發送窗口大小位元組後得到對方的確認。
客戶端或伺服器發送此消息來限制另一方的輸出帶寬。 收到此消息的另一方通過將已發送但未確認的數據量限制為此消息中指示的窗口大小這種方式用來限制其輸出帶寬。如果窗口大小與發送給此消息發送者的最後一個窗口大小不同,那麼接收此消息的另一方應該使用 "Window Acknowledgement Size" 消息進行響應。
限制類型 Limit Type 是以下值之一:
本部分主要介紹 RTMP 消息的格式,在網路實體之間使用較低級傳輸層(如 RTMP塊流 )傳輸這些消息。
雖然 RTMP 旨在與 RTMP塊流 一起使用,但它可以使用任何其他傳輸協議發送消息。 RTMP Chunk Stream 和 RTMP 一起適用於各種音視頻應用,從一對一和一對多實時廣播到視頻點播服務,再到互動式會議應用。
伺服器和客戶端通過網路發送 RTMP 消息以相互通信。 消息可能包括音頻,視頻,數據或任何其他消息。
RTMP 消息有兩部分,頭部和有效負載。
消息頭包含以下欄位:
消息的另一部分是有效負載,它是消息中包含的實際數據。 例如,它可能是一些音頻樣本或壓縮的視頻數據。
RTMP使用消息類型ID 4 作為用戶控制消息。 這些消息包含RTMP流層使用的信息。 帶有ID 1,2,3,5和6的協議消息由RTMP塊流協議使用。
用戶控制消息應該使用消息流ID 0(稱為控制流),並且當通過RTMP塊流發送時,在消息流ID 2上發送。用戶控制消息在流中被接收時生效, 他們的時間戳被忽略。
客戶端或伺服器發送此消息以通知對端用戶控制事件。 該消息攜帶事件類型和事件數據。
消息數據 Event Data 的前2個位元組用於標識事件類型 Event Type 。 事件類型後面跟著事件數據。 事件數據欄位的大小是可變的。 但是,在消息必須通過RTMP塊流層的情況下,最大塊的大小應該足夠大,以允許這些消息適合單個塊。
本節介紹在伺服器和客戶端之間用於相互通信的不同類型的消息和命令。
在伺服器和客戶端之間交換的不同類型的消息包括用於發送音頻數據的音頻消息,用於發送視頻數據的視頻消息,用於發送任何用戶數據的數據消息,共享對象消息和命令消息。 共享對象消息提供了一種通用的方式來管理多個客戶端和伺服器之間的分布式數據。 命令消息在客戶端和伺服器之間傳送 AMF 編碼的命令。 客戶端或伺服器可以通過流使用命令消息請求對方的遠程過程調用( RPC )。
伺服器和客戶端通過網路發送消息以相互通信。 消息可以是任何類型,包括音頻消息,視頻消息,命令消息,共享對象消息,數據消息和用戶控制消息。
命令消息在客戶端和伺服器之間傳送 AMF 編碼命令。 這些消息的 AMF0 編碼的消息類型值為20, AMF3 編碼的消息類型值為17。 這些消息被發送來執行一些操作,例如 connect , createStream , publish , play , pause 等。 諸如 onstatus , result 等命令消息用於通知發送者有關請求的命令的狀態。 命令消息由命令名稱,事務ID和包含相關參數的命令對象組成。 客戶端或伺服器可以通過流使用命令消息請求對方的遠程過程調用( RPC )。
客戶端或伺服器發送此消息用於向對方發送元數據或任何用戶數據。 元數據包括有關數據(音頻,視頻等)的詳細信息,如創建時間,持續時間,主題等。 AMF0 的消息類型值為18, AMF3 的消息類型值為15。
共享對象是一個Flash對象(name-value對的集合),在多個客戶端,實例等之間同步的。 AMF0 的消息類型19和 AMF3 的消息類型16保留用於共享對象事件。 每條消息可以包含多個事件。
支持以下事件類型:
客戶端或伺服器發送此消息來向對等方發送音頻數據。 消息類型值8保留給音頻消息。
客戶端或伺服器發送此消息以向對等方發送視頻數據。 消息類型值9保留給視頻消息。
聚合消息是單個消息。消息類型22用於聚合消息。
聚合消息的消息流ID會覆蓋聚合內的子消息的消息流ID。
聚合消息的時間戳與第一個子消息之間的差異是用於將子消息的時間戳重新歸一化為流時間尺度的偏移量。 將偏移量添加到每個子消息的時間戳以達到標准化的流時間。 第一個子消息的時間戳應該與聚合消息的時間戳相同,所以偏移量應該為零。
後向指針包含前一個消息的大小,包括其頭部。 它被包含來匹配 FLV 文件的格式並用於向後搜索。
使用聚合消息有幾個性能優勢:
客戶端或伺服器發送此消息以通知對端關於用戶控制事件。
支持以下用戶控制事件類型:
客戶端和伺服器交換 AMF 編碼的命令。發送方發送一條命令消息,其中包含命令名稱,事務ID和包含相關參數的命令對象。例如, connect 命令包含 'app' 參數,它告訴客戶端連接到的伺服器應用程序名稱。接收方處理該命令並以相同的事務ID發送響應。響應字元串可以是 _result , _error 或方法名稱,例如 verifyClient 或 contactExternalServer 。
_result 或 _error 命令字元串表示響應。事務ID指示響應引用的未完成的命令。它與 IMAP 和許多其他協議中的標簽相同。命令字元串中的方法名稱指示發送方正試圖在接收方端運行方法。
以下類對象用於發送各種命令:
NetConnection 管理客戶端應用程序和伺服器之間的雙向連接。 另外,它為非同步遠程方法調用提供支持。
以下命令可以在 NetConnection 上發送:
客戶端向服務端發送連接( connect )命令請求連接一個伺服器應用實例。以下為命令的結構:
以下是連接命令的命令對象中使用的 name-value 對的描述:
audioCodecs 屬性的標志值:
videoCodecs 屬性的標志值:
videoFunction 屬性的標志值:
對象編碼( object Encoding )屬性的值:
以下是服務端到客戶端命令的結構:
以下是連接命令中的消息流:
命令執行期間的消息流是:
NetConnection 對象的調用方法在接收端運行遠程過程調用( RPC )。 被調用的 RPC 名稱作為參數傳遞給 call 命令。
從發送方到接收方的命令結構如下:
響應的命令結構如下:
客戶端將此命令發送到伺服器以創建用於消息通信的邏輯通道。音頻,視頻和元數據的發布是通過使用 createStream 命令創建的流通道執行的。
NetConnection 是默認通信通道,其流ID為0。協議和一些命令消息(包括 createStream )使用默認通信通道。
從客戶端到伺服器的命令結構如下所示:
從伺服器到客戶端的命令結構如下:
NetStream 定義了流式音頻,視頻和數據消息可以通過將客戶端連接到伺服器的 NetConnection 流動的通道。 一個 NetConnection 對象可以為多個數據流支持多個 NetStream 。
以下命令可以由客戶端在 NetStream 上發送到伺服器:
伺服器使用 'onStatus' 命令將 NetStream 狀態更新發送到客戶端:
客戶端將此命令發送到伺服器以播放流。 播放列表也可以使用此命令多次創建。
如果您想要創建一個可在不同直播流或錄像流之間切換的動態播放列表,請多次調用 play ,每次給 reset 傳遞 false 。相反,如果要立即播放指定的數據流,請清空播放隊列中的其他流,給 reset 傳遞 true 。
從客戶端到伺服器的命令結構如下所示:
Play 命令中的消息流: