正好去年過(guò)年的時(shí)候,一個(gè)朋友破解了AirPlay和Chromecast協(xié)議,然后開(kāi)發(fā)了一套技術(shù)能夠截獲和播放任何手機(iOS或是Android)屏幕上的任何內容。想到的第一個(gè)應用是做一個(gè)直播的直播服務(wù)(如有感興趣的投資人,可以聯(lián)系)。比如,通過(guò)屏幕直播,你可以邀請朋友看你正在看的直播的電影,球賽,演唱會(huì ),晚會(huì ),不管是免費的還是付費的。當初的想法是將屏幕的內容,通過(guò)AirPlay或Chromecast,推送到后臺服務(wù)器,然后,受邀的朋友就可以從瀏覽器或是其它視頻播放器觀(guān)看了。為此,我們搭建和開(kāi)發(fā)了一個(gè)直播平臺,現在把我們實(shí)現的過(guò)程記錄下來(lái)和大家共享。
首先,視頻有它的播放協(xié)議。原則上,RTSP,RTMP,HTTP都可以做直播和點(diǎn)播,但一般做直播用RTSP和RTMP,做點(diǎn)播用HTTP。我們選用的是RTMP協(xié)議。
RTMP(Real Time Message Protocol/實(shí)時(shí)信息傳輸協(xié)議)是應用層協(xié)議,靠底層傳輸層協(xié)議(通常是TCP)來(lái)保證信息傳輸的可靠性的。在TCP鏈接建立后,RTMP協(xié)議也要客戶(hù)端和服務(wù)器通過(guò)“握手”來(lái)建立RTMP Connection,然后在Connection上傳輸控制信息。RTMP協(xié)議傳輸時(shí)會(huì )對數據格式化,而實(shí)際傳輸的時(shí)候為了更好地實(shí)現多路復用、分包和信息的公平性,發(fā)送端會(huì )把Message劃分為帶有Message ID的Chunk,每個(gè)Chunk可能是一個(gè)單獨的Message,也可能是Message的一部分,在接受端會(huì )根據Chunk中包含的data的長(cháng)度,message id和message的長(cháng)度把chunk還原成完整的Message,從而實(shí)現信息的收發(fā)。
我們看看兩個(gè)常用的視頻服務(wù)。一個(gè)是由客戶(hù)端向服務(wù)器發(fā)起請求推流到服務(wù)器,這個(gè)就是直播的播放服務(wù),流程如下。

另一個(gè)是由客戶(hù)端向服務(wù)器發(fā)起請求從服務(wù)器端接受數據,可以多次調用,這就是播放服務(wù)。流程如下。

RTMP是直播后面的協(xié)議,有很多的開(kāi)源軟件實(shí)現了,細節我們不再細說(shuō)。下面,我們看看怎么搭建后臺服務(wù)系統。
LEMP棧是指Linux(L), NGINX(E), MySQL(M), PHP(P),還記得LAMP嗎?LEMP既是將NGINX(E)取代了Apache(A)。
首先,用以下命令安裝和啟動(dòng)NGINX web server。
# sudo apt-get update# sudo apt-get install nginx# sudo service nginx start接著(zhù),安裝MySQL。
# sudo apt-get install mysql-server mysql php5-mysql接著(zhù),安裝和配置PHP。
# sudo apt-get install php5-fpmlocation ~ .php$ { try_files $uri =404; fastcgi_pass unix:/var/run/php5-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params;}最后,重新啟動(dòng)NGINX web server。
# sudo service nginx restart這樣,后臺的web server設置好了,可以對外提供網(wǎng)頁(yè)和PHP服務(wù)了。但是,NGINX并不支持RTMP協(xié)議,我們需要下載,編譯,安裝和配置RTMP模塊。
首先,下載NGINX的源代碼,確保環(huán)境下能正確的編譯。
# git clone https://github.com/nginx/nginx.git然后,下載RTMP模塊。
# git clone https://github.com/arut/nginx-rtmp-module.git然后,cd到NGINX的源代碼目錄,config,make和install 剛才下載的RTMP模塊。
# ./configure --add-module=/path/to/nginx-rtmp-module make make install# make# make install最后,在NGINX的配置文件中,加上RTMP相關(guān)的配置,并且重新啟動(dòng)NGINX server。
rtmp { server { listen 1935; chunk_size 4000; # HLS application hls { live on; hls on; hls_path /tmp/hls; } # MPEG-DASH is similar to HLS application dash { live on; dash on; dash_path /tmp/dash; } }}# HTTP can be used for accessing RTMP statshttp { server { listen 8080; # This URL provides RTMP statistics in XML location /stat { rtmp_stat all; # Use this stylesheet to view XML as web page # in browser rtmp_stat_stylesheet stat.xsl; } location /stat.xsl { # XML stylesheet to view RTMP stats. # Copy stat.xsl wherever you want # and put the full directory path here root /path/to/stat.xsl/; } location /hls { # Serve HLS fragments types { application/vnd.apple.mpegurl m3u8; video/mp2t ts; } root /tmp; add_header Cache-Control no-cache; } location /dash { # Serve DASH fragments root /tmp; add_header Cache-Control no-cache; } }}其中看到了服務(wù)器上視頻存儲的格式是HLS,下面需要介紹一下這個(gè)格式。
HLS是一個(gè)由蘋(píng)果公司提出的基于HTTP的流媒體網(wǎng)絡(luò )傳輸協(xié)議,它把整個(gè)流分成一個(gè)個(gè)小的基于HTTP的文件來(lái)下載,每次只下載一些。當媒體流正在播放時(shí),客戶(hù)端可以選擇從許多不同的備用源中以不同的速率下載同樣的資源,允許流媒體會(huì )話(huà)適應不同的數據速率。開(kāi)始播放時(shí),客戶(hù)端會(huì )下載一個(gè)包含元數據的extended M3U (m3u8)playlist文件,用于尋找可用的媒體流。工作原理如下。

m3u8 playlist的文件結構,它不是一個(gè)單獨的文件,而是由一系列文件組成。Index文件和很多的數據文件。

一個(gè)m3u8 playlist的index文件內容。

所有的數據文件,以.ts為后綴,存放在同一目錄下面。

直播客戶(hù)端(后面我們要介紹的OBS)將實(shí)時(shí)視頻推送到NGINX的RTMP模塊。RTMP模塊會(huì )根據配置將視頻流轉換成HLS文件。這時(shí),HLS文件可以使用兩種模式播放。一是點(diǎn)播VOD模式,下載當前時(shí)間點(diǎn)可以獲取到所有index文件和ts文件,并播放。這種模式允許客戶(hù)端訪(fǎng)問(wèn)全部?jì)热?,不一定是?shí)時(shí)內容。二是Live 模式,實(shí)時(shí)生成m3u8和ts文件。它的索引文件一直處于動(dòng)態(tài)變化的,播放的時(shí)候需要不斷下載index文件,以獲得最新生成的ts文件播放視頻。一般來(lái)說(shuō),實(shí)況直播時(shí),會(huì )有一些延時(shí)。下面,來(lái)看一個(gè)JS實(shí)現的HLS player,嵌入到支持HTML5的瀏覽器就可以播放HLS文件。
基于Javascript的HLS Player可以在PC瀏覽器(IE,Chrome,Firefox,Safari,等),iOS的Safari,Android的Chrome,等等支持HTML5的瀏覽器上播放。市面上有很多開(kāi)源的,下面圖中是其中的一種,對于不同瀏覽器的支持都很好。下載以后,按照它給的例子修改HLS的源就可以了。

除了JS的播放器,還有獨立的播放器,ffmpeg是廣泛使用的一種命令行播放器,支持Windows,Linux,Mac等。
ffmpeg是一個(gè)非??斓囊曨l/音頻轉換器,也可以現場(chǎng)抓取音頻/視頻源,并在任意采樣率、尺寸之間調整視頻,以及提供多種高品質(zhì)的濾鏡系統。ffmpeg從任意數量/形式的輸入文件中進(jìn)行讀取,通過(guò)輸入文件選項對輸入文件進(jìn)行設定,并寫(xiě)入到任意數量/形式的輸出文件中。它不但可以對任何格式的音視頻文件相互轉化,而且可以播放任何格式的音視頻文件。它的命令行選項超多,具體細節需要用到時(shí)自己去網(wǎng)上搜索和閱讀。
例如,下面的命令將一個(gè)本地的視頻文件movie.avi推送到服務(wù)器上可以生成HLS格式的文件。
# ffmpeg -loglevel verbose -re -i movie.avi -vcodec libx264 -vprofile baseline -acodec libmp3lame -ar 44100 -ac 1 -f flv rtmp://localhost:1935/hls/movieOBS(Open Broadcaster Software/開(kāi)源直播軟件),它是目前世界上最火的免費開(kāi)源直播軟件。由于它是免費的,而且質(zhì)量高,對比其它軟件就有天生的優(yōu)勢,很多商業(yè)化的直播平臺都支持和推薦使用。下面是它的基礎界面。

OBS能夠講視頻流推送到支持RTMP協(xié)議的服務(wù)器上,需要進(jìn)行一些簡(jiǎn)單的設置。服務(wù)器的地址,和流的密鑰,這樣,可以區分不同的用戶(hù),也保證了不同用戶(hù)的內容安全。

基于上面描述的技術(shù)和開(kāi)源系統,我們用PHP實(shí)現了一個(gè)簡(jiǎn)單的支持多用戶(hù)的直播平臺。用戶(hù)可以注冊,登錄,follow/unfollow,評論,標簽,收看,直播(每個(gè)用戶(hù)有自己的直播密鑰),等等。
源代碼文件目錄。

注冊界面。

播放和評論界面。

直播使用的是OBS,也可以使用你喜歡的直播移動(dòng)App,需要設置系統給每個(gè)用戶(hù)提供的密鑰。收看時(shí),直接選擇用戶(hù)和他正在播放視頻就好了。
直播的精髓都應該討論到了,如果將系統sharding,分層,SOA化,負載均衡,cache,就可以搭建出一個(gè)可擴展的大規模的直播平臺。
聯(lián)系客服