如何在nginx流媒体RTMP上集成FFmpeg转码?

Nginx

1 理论知识

1.1 RTMP的简介

RTMP是Real Time Messaging Protocol(实时消息传输协议)的首字母缩写。该协议基于TCP,是一个协议族,包括RTMP基本协议及RTMPT/RTMPS/RTMPE等多种变种。RTMP是一种设计用来进行实时数据通信的网络协议,主要用来在Flash/AIR平台和支持RTMP协议的流媒体/交互服务器之间进行音视频和数据通信。支持该协议的软件包括Adobe Media Server/Ultrant Media Server/red5等。

1.2 集成FFmpeg目的

Nginx的RTMP模块提供的流媒体功能不足之处就是对很多媒体格式不支持,故需要借助FFmpeg功能来补充。

1.3 FFmpeg官方架构介绍


– 流媒体广播服务器(FFserver),对多个输入源进行转码、重映射、广播
– 输入源(FFmpeg),将音频或视频发送给流媒体播放器
– 媒体播放器
注:官方声明FFserver已经被放弃,本文将使用Nginx的RTMP模块代替

1.4 FFmpeg官方工作模型


– I(Input Sources)输入源,将音频或视频发送到流媒体服务器
– F(Feeds)馈送,接收输入的音频视频源,将单个输入源与多个输出流相关联
– S(Streams)流,为流媒体播放器提供链接点(频道),每个连接点可同时处理多个流媒体播放请求
– P(Media Players)媒体播放器

2 环境

2.1 环境信息

IP Address=10.168.0.51
HostName=rtmp.cmdschool.org
OS=CentOS 7.3

2.2 yum源配置

yum -y install gcc gcc-c++ make expat-devel 
yum -y install rpm-build
yum -y install http://download1.rpmfusion.org/free/el/rpmfusion-free-release-7.noarch.rpm

2.3 创建构建用户

useradd -u 1001 builder

2.4 关闭selinux

setenforce 0
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config

3 构建rpm包部分

3.1 下载安装包

su - builder
cd ~
wget http://nginx.org/packages/centos/7/SRPMS/nginx-1.8.1-1.el7.ngx.src.rpm
wget -O nginx-rtmp-module-master.zip https://codeload.github.com/arut/nginx-rtmp-module/zip/master

3.2 解压并测试构建环境

3.2.1 构建环境和测试

rpm -ivh nginx-1.8.1-1.el7.ngx.src.rpm
rpmbuild -bb rpmbuild/SPECS/nginx.spec

3.2.2 异常情况

如果看到类似提示:

warning: bogus date in %changelog: Thu Aug  5 2014 Sergey Budnevitch <sb@nginx.com>
warning: bogus date in %changelog: Thu Jul 12 2014 Sergey Budnevitch <sb@nginx.com>
warning: bogus date in %changelog: Tue Jul 17 2013 Sergey Budnevitch <sb@nginx.com>
warning: bogus date in %changelog: Tue May  6 2013 Sergey Budnevitch <sb@nginx.com>
warning: bogus date in %changelog: Tue Aug 10 2011 Sergey Budnevitch
error: Failed build dependencies:
        openssl-devel >= 1.0.1 is needed by nginx-1:1.8.1-1.el7.centos.ngx.x86_64
        zlib-devel is needed by nginx-1:1.8.1-1.el7.centos.ngx.x86_64
        pcre-devel is needed by nginx-1:1.8.1-1.el7.centos.ngx.x86_64

请先决绝包的依赖关系然后重试:

exit
yum install -y openssl-devel zlib-devel pcre-devel

3.2.3 正常情况

如果末尾类似的提示表示构建环境测试通过或称重新打包完成:

+ umask 022
+ cd /home/builder/rpmbuild/BUILD
+ cd nginx-1.8.1
+ /bin/rm -rf /home/builder/rpmbuild/BUILDROOT/nginx-1.8.1-1.el6.ngx.x86_64
+ exit 0

3.3 配置增加模块的源文件

unzip nginx-rtmp-module-master.zip
cp -a nginx-rtmp-module-master nginx-rtmp-module
tar zcvf nginx-rtmp-module.tar.gz nginx-rtmp-module
cp nginx-rtmp-module.tar.gz rpmbuild/SOURCES/

3.4 修改构建文件

3.4.1 创建配置文件副本

cp rpmbuild/SPECS/nginx.spec rpmbuild/SPECS/nginx.spec.default

3.4.2 修改配置文件参数

vim rpmbuild/SPECS/nginx.spec

修改如下参数:

Source10: nginx.suse.logrotate
Source11: nginx-rtmp-module.tar.gz
[..]
%setup -q
%setup -T -D -b 11

%build
[..]
        --add-module=../nginx-rtmp-module
                $*
make %{?_smp_mflags}

注:增加第2,5,9行

3.5 重新构建rpm包

rpmbuild -bb rpmbuild/SPECS/nginx.spec
exit

4 配置RTMP服务

4.1 安装nginx包

cd /home/builder/rpmbuild/RPMS/x86_64/
yum -y install nginx-1.8.1-1.el7.centos.ngx.x86_64.rpm

注:以上包可拷贝到其他CentOS7.3的机器上安装

4.2 确认模块启用

nginx -V

显示如下:

nginx version: nginx/1.8.1
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-11) (GCC)
built with OpenSSL 1.0.1e-fips 11 Feb 2013
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --add-module=../nginx-rtmp-module --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module --with-http_auth_request_module --with-mail --with-mail_ssl_module --with-file-aio --with-ipv6 --with-http_spdy_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic'

可见配置的参数后面有加载模块:

--add-module=../nginx-rtmp-module

4.3 程序数据目录

mkdir -p /var/www/html
chown nginx:nginx /var/www/html
chmod 700 /var/www/html

4.4 创建配置文件

vim /etc/nginx/nginx.conf

修改内容如下:

worker_processes 1;

events {
 worker_connections 1024;
}

rtmp {
  server {
    listen 1935;
    chunk_size 4096;
    application myapp {      # 定义一个频道myapp
      live on;
      play /var/www/html;   # 定义频道的根目录
    }
  }
}

http {
 server {
   listen 80;
   location /stat {           # 定义状态的访问URI
     rtmp_stat all;
     rtmp_stat_stylesheet stat.xsl;
   }

   location /stat.xsl {       # 定义状态文件路径
     root /var/www/html;
   }
   
   location / {               # 定义播放器网页访问的URI和根目录
     root /var/www/html;
   }
   
 }
}

4.5 重启服务并配置服务默认启动

systemctl restart nginx
systemctl enable nginx

4.6 配置防火墙

firewall-cmd --permanent --add-port 1935/tcp
firewall-cmd --permanent --add-service http
firewall-cmd --reload
firewall-cmd --list-all

4.7 上传测试文件

拍一个手机视频(MP4文件)上传到频道定义目录“/var/www/html”用于测试(笔者上传的是“1431308733062.mp4”)。
注:由于Nginx的rtmp模块一个简单的流媒体服务器,故对编码格式支持有限,他需要“ffmpeg”来补充。

5 客户端配置

5.1 下载客户端并解压

cd /var/www/html
wget https://ssl.p.jwpcdn.com/player/download/jwplayer-7.10.7.zip
unzip jwplayer-7.10.7.zip

注:下载前要先在官网注册账号

5.2 使用代码加载播放器

vim /var/www/html/index.html

输入如下内容:

<html>
<head>
<script src='./jwplayer-7.10.7/jwplayer.js'></script>
<script>jwplayer.key='******XCUoBbOY0Xq+PLboip3jP7gEy4******==';</script>
</head>
<body>
<div id="player">Loading the player...</div>
<script>
// Setup the player
const player = jwplayer('player').setup({
file: 'rtmp://10.168.0.51/myapp/01'
});

// Listen to an event
player.on('pause', (event) => {
alert('Why did my user pause their video instead of watching it?');
});

// Call the API
const bumpIt = () => {
const vol = player.getVolume();
player.setVolume(vol + 10);
}
bumpIt();
</script>
</body>
</html>

注:修改第3,4,11行,其中第3行是播放器的解压位置,第4行是播放器的SN,第11行是流媒体的绝对路径。

5.3 测试播放

http://10.168.0.51

5.4 监视播放状态

http://10.168.0.51/stat

6 增加频道

6.1 修改配置文件

vim /etc/nginx/nginx.conf

修改内容如下:

worker_processes 1;

events {
 worker_connections 1024;
}

rtmp {
  server {
    listen 1935;
    chunk_size 4096;
    application myapp {      # 定义一个频道myapp
      live on;
      play /var/www/html;   # 定义频道的根目录
    }
    application myapp2 {      # 增加一个频道myapp2
      live on;
    }
  }
}

http {
 server {
   listen 80;
   location /stat {           # 定义状态的访问URI
     rtmp_stat all;
     rtmp_stat_stylesheet stat.xsl;
   }

   location /stat.xsl {       # 定义状态文件路径
     root /var/www/html;
   }
   
   location / {               # 定义播放器网页访问的URI和根目录
     root /var/www/html;
   }
   
 }
}

6.2 重启服务并配置服务默认启动

systemctl restart nginx

7 配置FFmpeg

7.1 安装FFmpeg的包

yum -y install ffmpeg ffmpeg-devel

7.2 测试FFmpeg视频转换

ffmpeg -i 01.rm 01.mp4

注:请自行下载测试文件,如遇到如下错误:

The encoder 'aac' is experimental but experimental codecs are not enabled, add '-strict -2' if you want to use it.

可如此处理:

ffmpeg -i 01.rm -strict -2 01.mp4

7.3 手动测试推送

ffmpeg -re -i /var/www/html/1431308733062.mp4 -vcodec libx264 -vprofile baseline -acodec aac -ar 44100 -strict -2 -ac 1 -f flv -s 1280x720 -q 10 rtmp://127.0.0.1:1935/myapp2/01;

参阅资料
=====================================
RTMP参阅资料
———————————–
http://nginx.org/en/docs/
https://github.com/arut/nginx-rtmp-module
https://github.com/arut/nginx-rtmp-module/wiki/Directives
https://github.com/jwplayer/jwplayer
http://www.tuicool.com/articles/iauQNr
http://www.cuplayer.com/player/PlayerCode/Nginx/2016/0509/2375.html
https://wenku.baidu.com/view/1bb9e587ad51f01dc381f13b.html
https://wenku.baidu.com/view/1bb9e587ad51f01dc381f13b.html
http://blog.sina.com.cn/s/blog_704836f40102wlmh.html
http://www.linuxidc.com/Linux/2015-08/121324.htm

FFmpeg参阅资料
———————————-
官方地址:
http://ffmpeg.org/

YUM源地址:
https://rpmfusion.org/
http://download1.rpmfusion.org/free/el/

FFmpeg的安装方法:
https://trac.ffmpeg.org/wiki/CompilationGuide
https://trac.ffmpeg.org/wiki/CompilationGuide/Centos

Nginx的RTMP触发转码:
http://blog.csdn.net/wutong_login/article/details/42292787
http://www.linuxidc.com/Linux/2015-01/111182p2.htm
PHP触发转码:
http://www.cnblogs.com/georgelu/p/6430475.html

推送流的实现方式:
http://www.jb51.net/article/107405.htm
http://blog.csdn.net/redstarofsleep/article/details/45092147

http://www.cnblogs.com/lidabo/p/5233642.html

整体架构资料
———————————–
https://trac.ffmpeg.org/wiki/ffserver

没有评论

发表回复

Nginx
如何解决https请求不安全http页被阻止问题?

1 前言 一个问题,一篇文章,一出故事。 笔者最近代理公司应用,发现https的页面有请求不安全的h …

Nginx
如何Nginx代理上游的子项目或文件夹?

1 前言 一个问题,一篇文章,一出故事。 笔者接到任务需要把Tomcat的其中一个应用号使用Ngin …

Nginx
如何安装部署RHEL 9 Nignx?

1 前言 一个问题,一篇文章,一出故事。 笔者需要基于RHEL 9部署Nginx环境,于是整理此文。 …