RTMP服務器搭建

一、流媒體

流媒體(Streaming media),也叫做流式媒體。是指將一連串的多媒體數據壓縮后,經過互聯網分段發(fā)送數據,在互聯網上即時傳輸影音以供觀賞的一種技術與過程。此技術使得數據包可以像流水一樣發(fā)送。

流媒體文件一般都較大,如果使用下載的方式進行傳輸,所需要的存儲容量也較大;同時由于網絡帶寬的限制,下載常常要花數分鐘甚至數小時,所以這種處理方法延遲也很大。使用流式傳輸時,將聲音和視頻等時基媒體數據分段,連續(xù)實時發(fā)送到用戶的設備,用戶不必等到整個文件全部下載完畢,而只需經過幾秒或十數秒的啟動延時即可進行觀看。當聲音和視頻等時基媒體在客戶機上播放時,文件的剩余部分將在后臺從服務器繼續(xù)下載。流式不僅使啟動延時成十倍、百倍地縮短,而且不需要太大的緩存容量。流式傳輸避免了用戶必須等待整個文件全部下載完才能觀看的缺點。流媒體的一個非常典型、火爆的應用場景:直播。近幾年,直播行業(yè)是蒸蒸日上。

二、流媒體協議

常見的流媒體協議有:RTMP、HLS 等。

1、RTMP(Real-Time Messaging Protocol),譯為:實時消息傳輸協議,由 Adobe 公司出品。默認基于 TCP 的 1935 端口。

2、HLS(HTTP Live Streaming),基于 HTTP 的流媒體網絡傳輸協議,蘋果公司出品。參考:RFC 8216

本文主要介紹如何搭建一臺 RTMP 服務器,為學習 RTMP 協議做準備。想研究清楚 RTMP ,我們可以使用抓包的方式窺探 RTMP 數據包的格式(抓包工具可以使用 Wireshark)。想要抓包就需要有推流操作,前提是我們要有一個 RTMP 服務器,那么下面開始 RTMP 服務器環(huán)境的搭建。

三、服務器環(huán)境搭建

我們自己想要搭建一個 RTMP 服務器環(huán)境有 2 種方式:1、購買云服務器;2、使用虛擬機搭建。本文選擇的是使用虛擬機的方式搭建,那么接下來服務器系統是應該選擇 MacOS 還是 Windows 呢?都不是!絕大部分公司的服務器都不會用這兩款操作系統,實際工作中服務器使用的是 Linux 系統,MacOS 和 Windows 這么好用,也都是可以作為服務器系統的,為什么偏偏選擇 Linux 呢?是因為 Linux 可以裁剪安裝。所以我們也選擇使用 Linux 系統來搭建一個 RTMP 服務器環(huán)境,Linux 最大的使用場景就是做服務器。下面我們要安裝的 CentOS 就是 Linux 系統,Linux 系統衍生出來的版本非常多,比如 Ubuntu、Red Hat 等等。當然以學習為目的使用 MacOS 或者 Windows 搭建服務器環(huán)境也是可以的。

1、安裝虛擬機軟件

我本地的系統是 MacOS,首先在我們本地安裝一個虛擬機軟件,我使用的虛擬機軟件是 VMWare。

2、安裝 CentOS

2.1、下載 CentOS

CentOS 可以從網站 centoschina 中下載,上面有 CentOS 的各種版本,我這里下載的是 CentOS-7-x86_64-DVD-1810.iso, CentOS 7.6 是目前比較主流的版本(PS:系統版本只要有一點差異,有些操作就會不一樣,最后的效果也會不一樣)。

2.2、選擇安裝方法,選擇從光盤和映像中安裝,選擇我們下載到本地的鏡像文件 CentOS-7-x86_64-DVD-1810.iso,使用非快捷安裝的方式進行安裝

選擇安裝方法
已選擇鏡像文件

2.2、語言選擇,選擇簡體中文即可:

語言選擇

2.3、進入安裝信息摘要,不要著急操作等待掃描加載完成,設置完成頁面如下。首先日期和時間、鍵盤、語音支持選項不需要我們更改:

安裝信息摘要

2.4、檢查安裝源,不需要操作:

安裝源

2.5、軟件選擇,最小安裝只有命令行界面,沒有圖形界面,比較適合做服務器,是一個最小 Linux 系統,但是可能對于不會命令行的新手不太友好。我們選擇 GNOME 桌面選項,選擇GNOME 桌面選項安裝后就是一個有圖像界面的 Linux 系統,同時附加選項可以勾選:1、傳統 X Windows 系統的兼容性;2、兼容性程序庫;3、開發(fā)工具。如下圖:

軟件選擇

2.6、上一步操作完成后等待檢查依賴完成,繼續(xù)選擇安裝位置選項,建議我們自己來分區(qū),把硬盤空間分成三個區(qū):boot(引導區(qū))、swap(交換分區(qū))、root(根區(qū)),選擇其他存儲選項下的我要配置分區(qū):

安裝目標位置

進入到手動配置分區(qū)頁面,,我們點擊 + 開始分區(qū):

手動分區(qū)

添加 boot(引導區(qū)),分配 1G 大小即可,設備類型選擇標準分區(qū),文件系統選擇ext4

添加引導區(qū)-1
添加引導區(qū)-2

添加 swap(交換分區(qū)),分配 2G 大小即可,一般來說內存給的多少空間建議分配多少空間,設備類型選擇標準分區(qū),文件系統選擇swap

添加交換分區(qū)-1
添加交換分區(qū)-2

添加 root(根分區(qū)),省下多少空間就給根分區(qū)分配多少空間,期望容量不填寫即可。設備類型選擇標準分區(qū),文件系統選擇ext4

根分區(qū)-1
根分區(qū)-2

2.7、設置網絡,打開以太網:

打開以太網

2.8、設置 ROOT 密碼和創(chuàng)建用戶,最后等待安裝完成:

配置
設置 ROOT 密碼
創(chuàng)建用戶

2.9、帶有圖形界面的 Linux 系統安裝完成頁面如下:

CentOS 7.6

3、安裝服務器軟件

我們在 MacOS 上虛擬出一個 Linux 系統,但是我們還不能稱之為服務器。想讓 Linux 系統變成一個服務器,我們還需要安裝一個服務器軟件并啟動 RTMP 服務,服務器軟件一旦啟動,就會占用 Linux 系統的一個端口,RTMP 服務默認占用1935 端口。客戶端推流推到 1935 端口,RTMP 服務器軟件通過1935 端口就可以得到流數據,客戶端也可以通過 1935 端口 進行拉流。

接下來安裝服務器軟件 nginx。不同的服務器軟件干的事情是不一樣的,比較知名的兩款服務器軟件是 tomcat 和 nginx。tomcat 一般用做 Java 服務器。nginx 一般用做反向代理和前端網頁服務器。nginx 雖然是一款高性能的開源web服務器,但是默認是不支持 RTMP 的。同時需要安裝一個模塊 nginx-rtmp-module。

3.2、下載 nginx 和 nginx-rtmp-module

首先在 nginx 官網 下載最新穩(wěn)定版本的 nginx。在 github 下載 nginx-rtmp-module,最新穩(wěn)定版本在 tags 中查找。

我把 nginx 和 nginx-rtmp-module 下載到了本地 MacOS 系統,需要把這兩個文件共享到 Linux 服務器上去??梢栽?MacOS 和 Linux 兩個系統之間設置一個共享文件夾。首先在虛擬機硬件設置->共享->啟用共享文件夾并添加一個共享文件夾 nginx-shared,然后重啟 Linux 系統:

設置共享文件夾

然后把 MacOS 系統下的共享文件夾nginx-shared掛載到 Linux 系統的 mnt/nginx-shared 文件夾(mnt 用于臨時掛載其他文件系統):

# Linux 系統終端
# 查看文件夾共享成功與否
[root@centos76 ~]# vmware-hgfsclient
tmp-shared
# 在 /mnt 下創(chuàng)建文件夾 rtmp-shared
[root@centos76 ~]# mkdir /mnt/rtmp-shared
# 掛載到對應目錄
[root@centos76 ~]# vmhgfs-fuse .host:/rtmp-shared /mnt/rtmp-shared

mnt/nginx-shared文件下可以看到文件 nginx-1.20.1.tar.gz 和 nginx-rtmp-module-1.2.2.tar.gz 說明已經掛載成功,在 Linux 系統下訪問mnt/nginx-shared就相當于訪問本地 MacOS 系統下的nginx-shared文件夾:

[root@centos76 ~]# ls /mnt/rtmp-shared
nginx-1.20.1.tar.gz  nginx-rtmp-module-1.2.2.tar.gz

3.2、配置 & 編譯 nginx

解壓 nginx-1.20.1.tar.gz 和 nginx-rtmp-module-1.2.2.tar.gz:

# 解壓 nginx-1.20.1.tar.gz 
[root@centos76 rtmp]# tar -zxvf nginx-1.20.1.tar.gz
# 解壓 nginx-rtmp-module-1.2.2.tar.gz
[root@centos76 rtmp]# tar -zxvf nginx-rtmp-module-1.2.2.tar.gz

構建編譯環(huán)境,編譯 nginx 源碼時需要和 nginx-rtmp-module 源碼一起編譯,nginx 是主代碼,nginx-rtmp-module 可以理解為是一個插件(nginx 源碼可單獨編譯,nginx-rtmp-module 源碼是不可以單獨編譯的,單獨編譯的 nginx 是不支持 RTMP 的,將 nginx-rtmp-module 源碼一起參與編譯是為了增加 nginx 的功能,讓其支持 RTMP):

[root@centos76 rtmp]# cd nginx-1.20.1
# --prefix=設置安裝路徑
# --add-module=參與編譯的子模塊
[root@centos76 nginx-1.20.1]# ./configure --prefix=/usr/local/nginx --add-module=../nginx-rtmp-module-1.2.2 --with-http_ssl_module

執(zhí)行完configure,打印了+ ngx_rtmp_module was configured說明成功編譯了nginx-rtmp-module,但是出現了另外一個問題,PCRE這個庫找不到。

...
+ ngx_rtmp_module was configured
checking for PCRE library ... not found
checking for PCRE library in /usr/local/ ... not found
checking for PCRE library in /usr/include/pcre/ ... not found
checking for PCRE library in /usr/pkg/ ... not found
checking for PCRE library in /opt/Local/ ... not found
...

接下來需要使用使用 yum來安裝一下pcreyum類似于brew),prce 可以理解為是已經編譯好的庫,可以直接拿來用,但是如果是被拿來參與其他庫的編譯,必須安裝 prce 對應的 devel 包:

[root@centos76 nginx-1.20.1]# yum install -y pcre pcre-devel

安裝完成pcre執(zhí)行configure命令,發(fā)現pcre找到了,但又有一個新的問題,openssl找不到:

...
+ ngx_rtmp_module was configured
checking for PCRE library ... found
checking for PCRE JIT support ... found
checking for OpenSSL library ... not found
checking for OpenSSL library in /usr/local/ ... not found
checking for OpenSSL library in /usr/pkg/ ... not found
checking for OpenSSL library in /opt/local/ ... not found
...

繼續(xù)安裝openssl:

[root@centos76 nginx-1.20.1]# yum install -y openssl openssl-devel

安裝完成openssl再次執(zhí)行configure命令,最終打印了creating objs/Makefile,到目前為止說明已經沒有問題了,并且會在目錄nginx-1.20.1下生成一個Makefile文件。

...
creating objs/Makefile

Configuration summary
  + using system PCRE library
  + using system OpenSSL library
  + using system zlib library
...

我們發(fā)現 nginx 不僅依賴了pcreopenssl,也依賴了zlib,為什么剛剛不報錯呢?是因為當前 Linux 已經安裝了zlib,我們在安裝 Linux 的時候勾選了開發(fā)工具,勾選開發(fā)工具會幫我們安裝一些開發(fā)常用的庫,比如gcczlib等等 。

PS:熟悉 nginx 的話,也可以一條指令安裝依賴庫:

[root@centos76 nginx-1.20.1]# yum install -y pcre pcre-devel openssl openssl-devel zlib zlib-devel

最后執(zhí)行 make命令開始編譯:

[root@centos76 nginx-1.20.1]# make & make install

編譯安裝完成后/usr/local/nginx文件夾下會有 4 個文件夾:

[root@centos76 nginx-1.20.1]# cd /usr/local/nginx
[root@centos76 nginx]# ls -l
drwxr-xr-x.  2 root   root 4096 6月  23 9:16 conf  # 配置文件
drwxr-xr-x.  2 root   root 4096 6月  22 10:48 html
drwxr-xr-x.  2 root   root 4096 6月  22 10:58 logs
drwxr-xr-x.  2 root   root 4096 6月  22 10:48 sbin  # 可行性程序

3.3、啟動 nginx

執(zhí)行sbin目錄下的nginx可執(zhí)行程序,就在后臺啟動了一臺 nginx 服務器:

[root@centos76 nginx]# ./sbin/nginx

nginx 服務器啟動成功后,在 Linux 系統下打開瀏覽器輸入虛擬機 IP 地址就可以看到如下頁面(我們看到的頁面文件是在 nginx 的html目錄下)。nginx 服務器默認支持 http 協議,并且默認監(jiān)聽80 端口http協議默認也是80 端口),可以查看conf目錄下的配置文件nginx.conf

Welcome to nginx

同時查看80 端口占用情況,會發(fā)現80 端口正在被 nginx 和 firefox 瀏覽器占用:

[root@centos76 nginx]# lsof -i:80
COMMAND   PID   USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
nginx    9116   root    7u  IPv4  61486      0t0  TCP *:http (LISTEN)
nginx    9118 nobody    3u  IPv4 236966      0t0  TCP wangleiios:http->wangleiios:33302 (ESTABLISHED)
nginx    9118 nobody    7u  IPv4  61486      0t0  TCP *:http (LISTEN)
firefox 25366   root   65u  IPv4 236965      0t0  TCP wangleiios:33302->wangleiios:http (ESTABLISHED)

目前 Linux 系統和本地 MacOS 系統是處在同一個局域網中,可以互相ping通,那么在本地 MacOS 系統下的瀏覽器是否可以訪問 nginx 服務器呢?你會發(fā)現訪問不了,是因為 Linux 服務器防火墻把80 端口關閉了,不對外開放,所以還需要我們打開端口:

# 查看端口情況,返回 no 代表被關閉
[root@centos76 nginx]# firewall-cmd --query-port=80/tcp
no
# 獲取 zone 名稱,一般是 public
[root@centos76 nginx]# firewall-cmd --get-active-zones
public
# 打開端口
[root@centos76 nginx]# firewall-cmd --zone=public --add-port=80/tcp --permanent
success
# 重啟防火墻,再次查看端口情況,就會返回 yes 了
[root@centos76 nginx]# firewall-cmd --reload
success

這樣我們就可以從外部訪問 nginx 服務器了。接下來我們希望它能監(jiān)聽1935 端口,支持 RTMP 協議。首先修改conf目錄下的核心配置文件nginx.conf,添加如下文本(文本中 rtmp 和 http 同級別):

rtmp {
    server {
        listen 1935; # 監(jiān)聽端口
        chunk_size 4000; # 消息快大小,通常情況下,一個有效的消息,如果數據量超出當前 chunk_size 的話,則會被拆分成多個分塊來分批傳輸
        application live { # 請求路徑/應用名稱 例如:http://192.168.1.7:1935/live/01
            live on;
        }
    }
}

修改nginx.conf之前如果 nginx 已經啟動,那么需要重啟 nginx,配置文件才能生效:

# 查看 nginx 的 PID
[root@centos76 nginx]# lsof -i:80
COMMAND   PID   USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
nginx    9116   root    7u  IPv4  61486      0t0  TCP *:http (LISTEN)
nginx    9118 nobody    3u  IPv4 236966      0t0  TCP wangleiios:http->wangleiios:33302 (ESTABLISHED)
nginx    9118 nobody    7u  IPv4  61486      0t0  TCP *:http (LISTEN)
firefox 25366   root   65u  IPv4 236965      0t0  TCP wangleiios:33302->wangleiios:http (ESTABLISHED)
# 殺死 nginx 進程
[root@centos76 nginx]# kill -9 9116 9118
# 啟動 nginx 
[root@centos76 nginx]# ./sbin/nginx
# 查看 1935 端口情況
[root@centos76 nginx]# lsof -i:1935
COMMAND  PID   USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
nginx   9116   root    6u  IPv4  61485      0t0  TCP *:macromedia-fcs (LISTEN)
nginx   9118 nobody    6u  IPv4  61485      0t0  TCP *:macromedia-fcs (LISTEN)

雖然已經成功開啟了 RTMP 服務,但是此時外界是無法訪問的,同樣的需要把1935 端口開放給外界:

[root@centos76 nginx]# firewall-cmd --zone=public --add-port=1935/tcp --permanent
# 重啟防火墻
[root@centos76 nginx]# firewall-cmd --reload

這樣就成功開啟了一個外界可訪問的 RTMP 服務(僅限于局域網內)。

四、使用 FFmpeg 進行推流&拉流

1、使用 FFmpeg 命令行進行推流,我們把一個 mp4 文件當做直播源,推到我們剛剛搭建的 RTMP 服務器上:

$ ffmpeg -i in.mp4 -f flv rtmp://192.168.1.10:1935/live/01 

2、使用 ffplay 進行播放

$ ffplay rtmp://192.168.1.10:1935/live/01

這樣就實現了簡單的推流和拉流,后面就可以利用我們實現的 RTMP 服務器,使用抓包工具去分析 RTMP 協議了。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容