RTMP服务器搭建

一、流媒体

流媒体(Streaming media),也叫做流式媒体。是指将一连串的多媒体数据压缩后,经过互联网分段发送数据,在互联网上即时传输影音以供观赏的一种技术与过程。此技术使得数据包可以像流水一样发送。

流媒体文件一般都较大,如果使用下载的方式进行传输,所需要的存储容量也较大;同时由于网络带宽的限制,下载常常要花数分钟甚至数小时,所以这种处理方法延迟也很大。使用流式传输时,将声音和视频等时基媒体数据分段,连续实时发送到用户的设备,用户不必等到整个文件全部下载完毕,而只需经过几秒或十数秒的启动延时即可进行观看。当声音和视频等时基媒体在客户机上播放时,文件的剩余部分将在后台从服务器继续下载。流式不仅使启动延时成十倍、百倍地缩短,而且不需要太大的缓存容量。流式传输避免了用户必须等待整个文件全部下载完才能观看的缺点。流媒体的一个非常典型、火爆的应用场景:直播。近几年,直播行业是蒸蒸日上。

二、流媒体协议

常见的流媒体协议有: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 服务器环境的搭建。

三、服务器环境搭建

我们自己想要搭建一个 RTMP 服务器环境有 2 种方式:1、购买云服务器;2、使用虚拟机搭建。本文选择的是使用虚拟机的方式搭建,那么接下来服务器系统是应该选择 MacOS 还是 Windows 呢?都不是!绝大部分公司的服务器都不会用这两款操作系统,实际工作中服务器使用的是 Linux 系统,MacOS 和 Windows 这么好用,也都是可以作为服务器系统的,为什么偏偏选择 Linux 呢?是因为 Linux 可以裁剪安装。所以我们也选择使用 Linux 系统来搭建一个 RTMP 服务器环境,Linux 最大的使用场景就是做服务器。下面我们要安装的 CentOS 就是 Linux 系统,Linux 系统衍生出来的版本非常多,比如 Ubuntu、Red Hat 等等。当然以学习为目的使用 MacOS 或者 Windows 搭建服务器环境也是可以的。

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、开发工具。如下图:

软件选择

2.6、上一步操作完成后等待检查依赖完成,继续选择安装位置选项,建议我们自己来分区,把硬盘空间分成三个区:boot(引导区)、swap(交换分区)、root(根区),选择其他存储选项下的我要配置分区:

安装目标位置

进入到手动配置分区页面,,我们点击 + 开始分区:

手动分区

添加 boot(引导区),分配 1G 大小即可,设备类型选择标准分区,文件系统选择ext4

添加引导区-1
添加引导区-2

添加 swap(交换分区),分配 2G 大小即可,一般来说内存给的多少空间建议分配多少空间,设备类型选择标准分区,文件系统选择swap

添加交换分区-1
添加交换分区-2

添加 root(根分区),省下多少空间就给根分区分配多少空间,期望容量不填写即可。设备类型选择标准分区,文件系统选择ext4

根分区-1
根分区-2

2.7、设置网络,打开以太网:

打开以太网

2.8、设置 ROOT 密码和创建用户,最后等待安装完成:

配置
设置 ROOT 密码
创建用户

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 官网 下载最新稳定版本的 nginx。在 github 下载 nginx-rtmp-module,最新稳定版本在 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 下创建文件夹 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

构建编译环境,编译 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

执行完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执行configure命令,发现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
...

继续安装openssl:

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

安装完成openssl再次执行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
...

我们发现 nginx 不仅依赖了pcreopenssl,也依赖了zlib,为什么刚刚不报错呢?是因为当前 Linux 已经安装了zlib,我们在安装 Linux 的时候勾选了开发工具,勾选开发工具会帮我们安装一些开发常用的库,比如gcczlib等等 。

PS:熟悉 nginx 的话,也可以一条指令安装依赖库:

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

最后执行 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

执行sbin目录下的nginx可执行程序,就在后台启动了一台 nginx 服务器:

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

nginx 服务器启动成功后,在 Linux 系统下打开浏览器输入虚拟机 IP 地址就可以看到如下页面(我们看到的页面文件是在 nginx 的html目录下)。nginx 服务器默认支持 http 协议,并且默认监听80 端口http协议默认也是80 端口),可以查看conf目录下的配置文件nginx.conf

Welcome to nginx

同时查看80 端口占用情况,会发现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 服务器呢?你会发现访问不了,是因为 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 服务器了。接下来我们希望它能监听1935 端口,支持 RTMP 协议。首先修改conf目录下的核心配置文件nginx.conf,添加如下文本(文本中 rtmp 和 http 同级别):

rtmp {
    server {
        listen 1935; # 监听端口
        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 协议了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容