幾乎每個新人都必問的問題:RTMP那個URL推流時應該填什么,什么是vhost,什么是app?RTMP和HLS的優勢參考:[HLS](https://github.com/ossrs/srs/wiki/v1_CN_DeliveryHLS)應用場景Vhost的主要應用場景包括:
* 一個分發網絡支持多個客戶:譬如CDN,一個分發網絡中,有N個客戶公用一套流媒體系統,如何區分用戶,計費,監控等等?通過app么?大家可能都叫做live之類。最好是通過各自的域名。
* 不同的應用配置:譬如FMLE推上來的流是h264+mp3,可以將音頻轉碼后放到其他的vhost分發hls,這樣接入h264+mp3的vhost就不用切hls。
總之,vhost作為應用配置的單元,能隔離客戶,應用不同的配置。
* * *
### 標準RTMP URL
標準RTMP URL指的是最大兼容的RTMP URL,基本上所有的服務器和播放器都能識別的URL,和HTTP URL其實很相似,例如:
| HTTP | Schema | Host | Port | App | Stream |
| --- | --- | --- | --- | --- | --- |
| http://192.168.1.10:80/players/srs\_player.html | http | 192.168.1.10 | 80 | players | srs\_player.html
| rtmp://192.168.1.10:1935/live/livestream | rtmp | 192.168.1.10 | 1935 | live | livestream
其中:
* Schema:協議頭,HTTP為HTTP或HTTPS,RTMP為RTMP/RTMPS/RTMPE/RTMPT等眾多協議,還有新出的RTMFP。
* Host:主機,表示要連接的主機,可以為主機DNS名稱或者IP地址。商用時,一般不會用IP地址,而是DNS名稱,這樣可以用CDN分發內容(CDN一般使用DNS調度,即不同網絡和地理位置的用戶,通過DNS解析到的IP不一樣,實現用戶的就近訪問)。
* Port:端口,HTTP默認為80,RTMP默認為1935。當端口沒有指定時,使用默認端口。
* Path:路徑,HTTP訪問的文件路徑。
* App:RTMP的Application(應用)名稱,可以類比為文件夾。以文件夾來分類不同的流,沒有特殊約定,可以任意劃分。
* Stream:RTMP的Stream(流)名稱,可以類比為文件。
* * *
### **NoVhost**
**其實**,vhost大多數用戶都用不到,而且不推薦用,有點復雜。一般的用戶用app就可以了。因為vhost/app/stream,只是一個分類方法而已;vhost需要在配置文件中說明,app/stream都不需要配置。什么時候用vhost?如果你是提供服務,譬如你有100個客戶,都要用一套平臺,走同樣的流媒體服務器分發。那可以每個客戶一個vhost,這樣他們的app和stream可以相同都可以。一般的用法,舉個例子,有個視頻網站,自己搭建服務器,所以只有他自己一個客戶,就不要用vhost了,直接用app就足夠了。假設視頻網站提供聊天服務,聊天有不同的話題類型,每個話題就是一個app,譬如:軍事欄目,讀書欄目,歷史欄目三個分類,每個分類下面有很多聊天室。只要這么配置就好:
~~~plain
listen 1935;vhost __defaultVhost__ {}
~~~
生成網頁時,譬如軍事欄目的網頁,都用app名稱為`military`,某個聊天室叫做`火箭`,這個頁面的流可以用:`rtmp://yourdomain.com/military/rock`,編碼器也推這個流,所有觀看這個`軍事欄目/火箭`聊天室的頁面的人,都播放這個流。軍事欄目另外的網頁,都用同樣的app名稱`military`,但是流不一樣,譬如某個聊天室叫做`雷達`,這個頁面的流可以用:`rtmp://yourdomain.com/military/radar`,推流和觀看一樣。如此類推,軍事欄目頁面生成時,不用更改srs的任何配置。也就是說,新增聊天室,不用改服務器配置;新增分類,譬如加個`公開課`的聊天室,也不用改服務器配置。足夠簡單!另外,讀書欄目可以用app名稱為`reader`,欄目下的某個聊天室叫`紅樓夢`,這個頁面的流可以用:`rtmp://yourdomain.com/reader/red_mansion`,所有在這個聊天室的人都是播放這個流。
* * *
### Vhost的應用
RTMP的Vhost和HTTP的Vhost概念是一樣的:虛擬主機。詳見下表(假設域名demo.srs.com被解析到IP為192.168.1.10的服務器):

**Vhost主要的作用是:**
* 支持多用戶:當一臺服務器需要服務多個客戶,譬如CDN有cctv(央視)和wasu(華數傳媒)兩個客戶時,如何隔離他們兩個的資源?相當于不同的用戶共用一臺計算機,他們可以在自己的文件系統建立同樣的文件目錄結構,但是彼此不會沖突。
* 域名調度:CDN分發內容時,需要讓用戶訪問離自己最近的邊緣節點,邊緣節點再從源站或上層節點獲取數據,達到加速訪問的效果。一般的做法就是Host是DNS域名,這樣可以根據用戶的信息解析到不同的節點。
* 支持多配置:有時候需要使用不同的配置,考慮一個支持多終端(PC/Apple/Android)的應用,PC上RTMP分發,Apple和Android是HLS分發,如何讓PC延遲最低,同時HLS也能支持,而且終端播放時盡量地址一致(降低終端開發難度)?可以使用兩個Vhost,PC和HLS;PC配置為最低延遲的RTMP,并且將流轉發給HLS的Vhost,可以對音頻轉碼(可能不是H264/AAC)后切片為HLS。PC和HLS這兩個Vhost的配置肯定是不一樣的,播放時,流名稱是一樣,只需要使用不同的Host就可以。
**Vhost支持多用戶**
假設cctv和wasu都運行在一臺邊緣節點(192.168.1.10)上,用戶訪問這兩個媒體的流時,Vhost的作用見下表:
| RTMP | Host | port | vhost | App | stream |
| --- | --- |--- |--- |--- |--- |
| rtmp://show.cctv.cn/live/livestream | 192.168.1.10 | 1935 | show.cctv.cn | | live | livestream |
| rtmp://show.wasu.cn/live/livestream | 192.168.1.10 | 1935 | show.wasu.cn | | live | livestream |
在邊緣節點(192.168.1.10)上的SRS,需要配置Vhost,例如:
~~~plain
listen 1935;vhost show.cctv.cn {}vhost show.wasu.cn {}
~~~
### Vhost支持多配置
以上面舉的例子,若cctv需要延遲最低(意味著啟動時只有聲音,畫面是黑屏),而wasu需要快速啟動(打開就能看到視頻,服務器cache了最后一個gop,延遲會較大)。只需要對這兩個Vhost進行不同的配置,例如:
~~~plain
listen 1935;vhost show.cctv.cn { chunk_size 128;}vhost show.wasu.cn { chunk_size 4906;}
~~~
總之,這兩個Vhost的配置完全沒有關系,不會相互影響。
* * *
##### \_\_defaultVhost\_\_
FMS的\_\_defaultVhost\_\_是默認的vhost,當用戶請求的vhost沒有匹配成功時,若配置了defaultVhost,則使用它來提供服務。若匹配失敗,也沒有defaultVhost,則返回錯誤。譬如,服務器192.168.1.10上的SRS配置如下:
~~~plain
listen 1935;vhost demo.srs.com { enabled on;}
~~~
那么,當用戶訪問以下vhost時:
* rtmp://demo.srs.com/live/livestream:成功,匹配vhost為demo.srs.com
* rtmp://192.168.1.10/live/livestream:失敗,沒有找到vhost,也沒有defaultVhost。
**defaultVhost**和其他vhost的規則一樣,只是用來匹配那些沒有匹配成功的vhost的請求的。
* * *
##### 訪問指定的Vhost
如何訪問某臺服務器上的Vhost?有兩個方法:
* 配置hosts:**因為Vhost實際上就是DNS解析**,所以可以配置客戶端的hosts,將域名(Vhost)解析到指定的服務器,就可以訪問這臺服務器上的指定的vhost。
* 使用app的參數:需要服務器支持。在app后面帶參數指定要訪問的Vhost。SRS支持**?vhost=VHOST**和...vhost...VHOST這兩種方式,后面的方式是避免一些播放器不識別?和=等特殊字符。
普通用戶不用這么麻煩,直接訪問RTMP地址就好了,有時候運維需要看某臺機器上的Vhost的流是否有問題,就需要這種特殊的訪問方式。考慮下面的例子:
~~~plain
RTMP URL: rtmp://demo.srs.com/live/livestream邊緣節點數目:50臺邊緣節點IP:192.168.1.100 至 192.168.1.150邊緣節點SRS配置: listen 1935; vhost demo.srs.com { mode remote; origin: xxxxxxx; }
~~~
各種訪問方式見下表:

訪問其他服務器的流也類似。
* * *
##### The Publish URL of FMLE
FMLE推流時,URL那個地方,有三個可以輸入的框,參考[Adobe FMLE](http://help.adobe.com/en_US/FlashMediaLiveEncoder/3.0/Using/WS5b3ccc516d4fbf351e63e3d11c104ba878-7ff7.html):
* FMS URL: 需要輸入rtmp://host:port/app,例如:rtmp://demo.srs.com/live
* Backup URL: 備份的服務器,格式同FMS URL。若指定了備份服務器,FMLE會同時推送給這兩個服務器。
* Stream: 流名稱,例如:livestream
實際上是將RTMP URL分成了兩部分,stream前面那部分和stream。為何要這么搞?我猜想有以下原因:
* 支持多級app和Stream:我們目前舉的例子都是一級app和一級stream,實際上RTMP支持多級app和stream,就像子文件夾,實際上很少用得到。所以SRS的URL都是一個地址,默認最后一個/后面就是stream,前面是app。
* 支持流名稱帶參數:Adobe的鬼HLS/HDS非常之麻煩,那個地址是個惡心的完全不一致。參考[FMS livepkgr](http://help.adobe.com/en_US/flashmediaserver/devguide/WSd391de4d9c7bd609-52e437a812a3725dfa0-8000.html#WSd391de4d9c7bd609-52e437a812a3725dfa0-7ff5),例如發布一個rtmp,并切片成HLS:
~~~plain
FMLE:FMS URL: rtmp://demo.srs.com/livepkgrStream: livestream?adbe-live-event=liveeventClient:RTMP: rtmp://demo.srs.com/livepkgr/livestreamHLS: http://demo.srs.com/hls-live/livepkgr/_definst_/liveevent/livestream.m3u8HDS: http://demo.srs.com/hds-live/livepkgr/_definst_/liveevent/livestream.f4m
~~~
沒有比這個更惡心的東西了。比較SRS的簡潔方案:
~~~plain
FMLE: FMS URL: rtmp://demo.srs.com/livepkgrStream: livestreamClient:RTMP: rtmp://demo.srs.com/livepkgr/livestreamHLS: http://demo.srs.com/livepkgr/livestream.m3u8HDS: not support yet.
~~~
既然談到了RTMP URL中的參數,下一章就說說這個。
### RTMP URL參數
RTMP URL一般是不帶參數,類似于http的query,有時候為了特殊的要求,會在RTMP URL中帶參數,譬如:
* Vhost:前面講過,在app后面加參數,可以訪問指定服務器的指定Vhost。這個SRS的特殊約定,方便排錯。
* FMLE的Stream后面的參數,指定event之類的。SRS不需要這么麻煩,HLS是內置支持,無需這種復雜的配置。Callback也是http的,FMS為了支持服務器端腳本,需要很復雜的配置和復雜的參數,實在是很麻煩的設計。
* token認證:SRS還未實現。在連接服務器時,在app后面指定token(方式和vhost一樣),例如rtmp://server/live?vhost=xxx&token=xxx/livestream,服務器可以取出token,進行驗證,若驗證失敗則斷開連接,這種是比Refer更高級的防盜鏈。
app和stream后面帶參數,這兩者有何區別,為何SRS把參數放在app后面?客戶端播放流的as3代碼大約是:
~~~plain
// how to play url: rtmp://demo.srs.com/live/livestreamconn =newNetConnection();conn.connect("rtmp://demo.srs.com/live");stream =newNetStream(conn);stream.play("livestream");
~~~
從RTMP協議的角度來看:
* NetConnection.connect(vhost+app):這一步會完成握手,connect到vhost,切換到app。類似于登錄到vhost后,cd到app這個目錄。也就是vhost的驗證,都可以在這一步做,也就是指定vhost也是在一步了,所以app后面跟的參數都是和vhost/app相關的。
* NetStream.play(stream):這一步是播放指定的直播流。所以和stream相關的事件,都可以傳遞參數,譬如Adobe的event。SRS是沒有這些事件的,流啟動時,若配置了HLS會自動開始切片。
* * *
### SRS的URL規則
SRS只做簡化的事情,絕對不把簡單的事情搞復雜。SRS的RTMP URL使用標準的RTMP URL,一般不需要對app和stream加參數,或者更改他們的意義。除了兩個地方:
* vhost支持參數訪問:為了方便運維訪問某臺服務器的vhost,不需要設置hosts。不影響普通用戶。
* 支持token驗證:為了支持token驗證,在app后面帶參數,這個是token驗證必須的方式。
另外,SRS建議用戶使用一級app和一級stream,不使用多級app和多級stream。譬如:
~~~plain
// 不推薦使用的多級app或streamrtmp://demo.srs.com/show/live/livestreamrtmp://demo.srs.com/show/live/livestream/2013
~~~
srs播放器(srs\_player)和srs編碼器(srs\_publisher)不支持多級app和stream,他們認為最后一個斜杠(/)后面的就是stream,前面的是app。即:
~~~plain
// srs_player和srs_publisher的解析方式:// play or publish the following rtmp URL:rtmp://demo.srs.com/show/live/livestream/2013schema: rtmphost/vhost: demo.srs.comapp: show/live/livestreamstream: 2013
~~~
做此簡化的好處是,srs播放器和編碼器,只需要指定一個url,而且兩者的url是一樣的。SRS常見的三種RTMP URL,詳細見下表:

### SRS的Vhost
SRS的full.conf配置文件中,有很多Vhost,主要是為了說明各個功能,每個功能都單獨列出一個vhost。所有功能都放在demo.srs.com這個vhost中。
CategoryVhost說明RTMPdefaultVhost默認Vhost的配置,只支持RTMP功能RTMPchunksize.vhost.com如何設置chunk size的實例。其他Vhost將此配置打開,即可設置chunk size。Forwardsame.vhost.forward.vhost.comForward實例:將流轉發到同一個vhost。HLSwith-hls.vhost.comHLS實例:如何開啟HLS,以及HLS的相關配置。HLSno-hls.vhost.comHLS實例:如何禁用HLS。RTMPmin.delay.comRTMP最低延遲:如何配置最低延遲的RTMP流RTMPrefer.anti_suck.comRefer實例:如何配置Refer防盜鏈。RTMPbandcheck.srs.com帶寬測試用的vhost,srs測速默認連接到這個vhost。這個vhost配置了帶寬測速的key,可測速間隔和最大測速帶寬限制。其他Vhost也可以支持測速,只要把這個配置項打開,然后在測速播放器的參數中指明另外的vhostRTMPremoved.vhost.com禁用vhost實例:如何禁用vhost。Callbackhooks.callback.vhost.com設置http callback的實例,當這些事件發生時,SRS會調用指定的http api。其他Vhost將這些配置打開,就可以支持http callback。Transcodemirror.transcode.vhost.com轉碼實例:使用ffmpeg的實例filter,將視頻做鏡像翻轉處理。其他Vhost添加這個配置,就可以對流進行轉碼。注:所有轉碼的流都需要重新推送到SRS,使用不同的流名稱(vhost和app也可以不一樣)。Transcodecrop.transcode.vhost.com轉碼實例:剪裁視頻filter。其他vhost添加此filter,即可對視頻進行剪裁。注:所有轉碼的流都需要重新推送到SRS,使用不同的流名稱(vhost和app也可以不一樣)。Transcodelogo.transcode.vhost.com轉碼實例:添加圖片/視頻水印。其他vhost添加這些配置,可以加圖片/視頻水印。注:所有轉碼的流都需要重新推送到SRS,使用不同的流名稱(vhost和app也可以不一樣)。Transcodeaudio.transcode.vhost.com轉碼實例:只對音頻轉碼。其他vhost添加此配置,可只對音頻轉碼。注:所有轉碼的流都需要重新推送到SRS,使用不同的流名稱(vhost和app也可以不一樣)。Transcodecopy.transcode.vhost.com轉碼實例:只轉封裝。類似于forward功能。Transcodeall.transcode.vhost.com轉碼實例:對上面的實例的匯總。Transcodeffempty.transcode.vhost.com調用ffempty程序轉碼,這個只是一個stub,打印出參數而已。用作調試用,看參數是否傳遞正確。Transcodeapp.transcode.vhost.com轉碼實例:只對匹配的app的流進行轉碼。Transcodestream.transcode.vhost.com轉碼實例:只對匹配的流進行轉碼。
SRS的demo.conf配置文件中,包含了demo用到的一些vhost,參考[Usage: Demo](https://github.com/ossrs/srs/wiki/v1_CN_SampleDemo)。
CategoryVhost說明DEMOplayerssrs_player播放的演示流,按照Readme的Step會推流到這個vhost,demo頁面打開后播放的流就是這個vhost中的流DEMOplayers_pubsrs編碼器推流到players這個vhost,然后轉碼后將流推送到這個vhost,并切片為hls,srs編碼器播放的帶字幕的流就是這個vhost的流DEMOplayers_pub_rtmpsrs編碼器演示頁面中的低延時播放器,播放的就是這個vhost的流,這個vhost關閉了gop cache,關閉了hls,讓延時最低(在1秒內)DEMOdemo.srs.comsrs的演示vhost,Readme的step最后的12路流演示,以及播放器的12路流延時,都是訪問的這個vhost。包含了SRS所有的功能。Othersdev開發用的,可忽略
- 序言
- 編解碼
- H264
- HEVC碼流解析
- H264編碼原理
- 多媒體封裝
- MP4
- 學好 MP4,讓直播更給力
- AAC
- FLV
- 流媒體協議
- RTSP
- RTCP
- RTP
- H265 RTP封包筆記
- SDP
- RTMP
- RTMP URL
- rtmp url基礎
- webrtc
- 編譯
- 最簡單的編譯webrtc方案
- Webrtc音視頻會議之Webrtc“不求甚解”
- Webrtc音視頻會議之Mesh/MCU/SFU三種架構
- 音頻傳輸之Jitter Buffer設計與實現
- Janus
- Webrtc音視頻會議之Janus編譯
- Webrtc音視頻會議之Janus源碼架構設計
- webrtc服務器-janus房間管理
- 源碼分析
- WebRTC視頻JitterBuffer詳解
- 走讀Webrtc 中的視頻JitterBuffer(一)
- 走讀webrtc 中的視頻JitterBuffer(二)
- webrtc視頻幀率控制算法機制
- 目標碼率丟幀-1
- 目標幀率丟幀-2
- 29 如何使用Medooze 實現多方視頻會議
- FFmpeg
- FFmpeg編譯
- Window10下編譯最新版FFmpeg的方法步驟
- FFMPEG靜態庫編譯
- ffmpeg實現畫中畫
- FFmpeg推流器
- ffmpeg-aac
- OpenCV
- OpenCV學習筆記——視頻的邊緣檢測
- 圖像特征點匹配(視頻質量診斷、畫面抖動檢測)
- 圖像質量診斷