使用nginx搭建rtmp+http_flv服务器实现直播推流 - Go语言中文社区

使用nginx搭建rtmp+http_flv服务器实现直播推流


使用nginx搭建rtmp+http_flv服务器实现直播推流

1.概述

项目中要实现安卓手机上的直播功能,因为涉及网络安全,不允许使用第三方的直播推流服务器,所以需要自建一台直播推流的视频服务器,将搭建过程记录如下。

2.服务器配置

现场服务器均为Windows Server版本,但nginx安装第三方模块需要在Linux系统下进行,在Windows下的安装非常麻烦,而且稳定性不好,所以考虑在Windows服务器上安装CentOS的虚拟机,在虚拟机上安装nginx,然后使用端口映射到主机端口上实现相关功能

2.1.安装vmware虚拟机软件

在服务器上安装了VMware Workstation 12 Pro

2.2.安装CentOS7操作系统

使用CentOS-7-x86_64-DVD-1908.iso安装操作系统,安装时虚拟机网络使用NAT地址转换

2.3.设置虚拟机为共享虚拟机

虚拟机必须设置为共享虚拟机才可以开机自启动,在左侧虚拟机列表中,右键虚拟机,然后选择“管理-共享”菜单,按提示一步一步设置为共享虚拟机,设置后即可开机自启动。

2.4.配置端口映射

在菜单:“编辑-虚拟网络编辑器”中打开虚拟网络编辑器,选择类型为“NAT模式”的行,在下面找到【NAT设置】按钮,点击后打开NAT设置窗口,点击添加即可添加端口映射

3.安装Nginx服务器软件

3.1.准备工作

打开命令行,安装编译相关软件

yum -y install unzip
yum -y install gcc-c++ 
yum -y install pcre pcre-devel  
yum -y install zlib zlib-devel 
yum -y install openssl openssl-devel

3.2.下载Nginx源文件

从github下载nginx的源代码

https://github.com/nginx/nginx

注:打不开网站的话,安装【Steam++】软件进行网络加速

下载后,拷贝nginx源文件到/home/nginx下并解压,
解压后目录为/home/nginx/nginx-1.23.1

3.3.下载nginx-http-flv-module模块

从github下载nginx-http-flv-module的源代码

https://github.com/winshining/nginx-http-flv-module

拷贝nginx-http-flv-module源文件并解压到/usr/local/nginx下,nginx目录不存在时则创建之
解压后目录为/usr/local/nginx/nginx-http-flv-module

注:nginx-http-flv-module模块是基于 nginx-rtmp-module 的流媒体服务器,所以在编译时无需再引入nginx-rtmp-module,而且nginx-rtmp-module的各项配置也是兼容的。

3.4.编译安装Nginx软件

进入/home/nginx/nginx-1.23.1目录下执行以下命令
sudo ./configure --prefix=/usr/local/nginx --with-http_ssl_module --add-module=/usr/local/nginx/nginx-http-flv-module
sudo make
sudo make install

此时nginx已安装成功,可以执行/usr/local/nginx/sbin/nginx -V查看版本号,会输出以下内容:

nginx version: nginx/1.23.1
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC) 
built with OpenSSL 1.0.2k-fips  26 Jan 2017
TLS SNI support enabled
configure arguments: --add-module=../nginx-http-flv-module

如果安装之后需要增加模块,可以使用configure命令添加配置,然后make,之后不要make install ,将编译的二进制文件手动拷贝到sbin目录下即可

cp ./objs/nginx /usr/local/nginx/sbin/

3.5.修改nginx配置文件

安装后的nginx配置文件中没有rtmp的相关配置,需要自行配置相关内容,以下是完整的配置文件内容

#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}

rtmp {
    server {
        listen 1985;

        application live {
            live on;
            gop_cache on;
            publish_notify on;
            on_publish http://172.16.70.234:8080/swms/oa/index_notifyLiveStart.action;
            #on_update http://172.16.70.234:8080/swms/oa/index_notifyLiveStart.action;
            on_publish_done http://172.16.70.234:8080/swms/oa/index_notifyLiveStop.action;
        }
    }
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    server {
        listen       8080;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   html;
            index  index.html index.htm;
        }

        location /live {
            flv_live on;
        }

        location /flv {
            add_header 'Access-Control-Allow-Origin' '*';
            flv_live on;
            chunked_transfer_encoding on;
        }

        location /stat {
            rtmp_stat all;
            rtmp_stat_stylesheet stat.xsl;
        }

        location /stat.xsl {
            root nginx-http-flv-module/;
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

    }

}

其中rtmp段和http->server->location中的/live, /flv, /stat, /stat.xsl为新增段落

3.6.启动nginx

现在就可以启动nginx了,使用以下命令控制nginx

#启动
sudo /usr/local/nginx/sbin/nginx
#停止
sudo /usr/local/nginx/sbin/nginx -s stop
#重新加载配置文件
sudo /usr/local/nginx/sbin/nginx -s reload

3.7.安装nginx为服务

创建服务描述文件

vi /usr/lib/systemd/system/nginx.service

内容如下:

[Unit]
Description=nginx - web server
After=network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf
ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/usr/local/nginx/sbin/nginx -s stop
ExecQuit=/usr/local/nginx/sbin/nginx -s quit
PrivateTmp=true

[Install]
WantedBy=multi-user.target

然后重新加载服务配置

systemctl daemon-reload

然后就可以使用服务命令控制nginx了

#停止Nginx服务
sbin/nginx -s stop

#开启Nginx服务
systemctl start nginx

#查看Nginx服务状态,出现【active (running)】表示服务正在运行
systemctl status nginx

#设置开机启动
systemctl enable nginx.service

4.推流测试

使用ffmpeg进行测试

#视频文件推流:
ffmpeg.exe -re -i c:\ffmpeg\inputfile.mp4 -vcodec libx264 -acodec aac -f flv rtmp://127.0.0.1:1985/live/mp4

#桌面推流
ffmpeg -f gdigrab -i desktop -vcodec libx264 -preset:v ultrafast -tune:v zerolatency -f flv rtmp://127.0.0.1:1985/live/desk1

#拉流测试
ffplay.exe rtmp://localhost:1985/live/mp4

5.网页播放

因为rtmp协议在网页上播放时需要使用flash插件,但现在各大浏览器已经不再支持flash插件了,所以需要使用http_flv协议实现网页播放的功能,这也是选择了nginx-http-flv-module模块的原因,在网页上播放http_flv需要使用bilibili开源的flv.js组件

https://github.com/bilibili/flv.js

可以下载源码进行编译,也可以直接下载编译好的Releases 版本的flv.js文件

http://bilibili.github.io/flv.js/dist/flv.js
https://github.com/bilibili/flv.js/releases/download/v1.6.2/flv.js

使用方法如下:

 <script src="flv.js"></script>
 <video id="videoElement" width="360" height="480"></video>
<script>
	var url = 'http://localhost:8080/flv?port=1985&app=live&stream=mp4';
  if (url && flvjs.isSupported()) {
      var videoElement = document.getElementById('videoElement');
      window.flvPlayer = flvjs.createPlayer({
          type: 'flv',
          url: url
      });
      flvPlayer.attachMediaElement(videoElement);
      flvPlayer.load();
      flvPlayer.play();
  }
</script>

可以对FlvPlayer进行封装,监听相关事件,实现网络中断再次接通后重新加载播放功能

var liveOpt = {
	liveStat:0,//直播是否开始,0未开始 1已开始
	livePlayUrl:'http://....',//直播观看地址
	flvPlayer:null,
	startLive : function(){
		if (this.liveStat==1 && flvjs.isSupported()) {
			var videoElement = document.getElementById('videoElement');
			var flvPlayer = this.flvPlayer = flvjs.createPlayer({
			    type: 'flv',
			    isLive:true,
			    url: this.livePlayUrl
			}, {isLive:true});
		    flvPlayer.attachMediaElement(videoElement);
			flvPlayer.on(flvjs.Events.ERROR, ()=>{
				console.log('ERROR', arguments);
				this.restartHandle = clearTimeout(this.restartHandle);
				this.restartHandle = setTimeout(this.restartLive.bind(this), 3000);
			});
			this.metaArrived = false;
			flvPlayer.on(flvjs.Events.METADATA_ARRIVED, ()=>{
				console.log('METADATA_ARRIVED', arguments)
				if(this.metaArrived){//如果第二次发来Meta信息,说明是断线后重连了,此时重新初始化控件
					this.restartLive();
				}
				this.metaArrived = true;
			});
	     	flvPlayer.load();
	      	flvPlayer.play();
		}
		else{
			setTimeout(startLive, 600);
		}
	},
	stopLive : function (){
			if(this.flvPlayer){
				try{
					this.flvPlayer.destroy();
				}
				catch(e){}
				this.flvPlayer = null;
			}
	},
	restartLive:function(){
		console.log('try to restart live!')
		this.stopHandle && clearTimeout(this.stopHandle);
		this.startHandle && clearTimeout(this.startHandle);
		this.stopHandle = setTimeout(this.stopLive.bind(this), 1000);
		this.startHandle = setTimeout(this.startLive.bind(this), 2000);
	}
};
版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/shuaijie506/article/details/126406024
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2023-01-02 18:18:13
  • 阅读 ( 185 )
  • 分类:Go Web框架

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢