搭建个人直播服务器 vvipi 发表于2019年8月8日,阅读:4632 ### 前言 某天在steam玩上古卷轴时,朋友想看看现场直播。尝试steam自带的直播功能发现卡顿明显,可能是服务器在国外的缘故。又试着在斗鱼上直播给他看,结果没过几十分钟发现被禁播了,我才想起来上古卷轴可能和黑魂一样是禁播游戏,真是哭笑不得。还是得自己动手,搭个直播服务器。 一番搜索之后,逐渐找到了实现的思路,花了两天时间实现了主要的功能,记录下来备忘,也给有缘搜索到的朋友一个参考。 ### 关于搜索 在实现技术需求的过程中,我们经常碰到的情况是对问题和解决方案认知不足导致无法找到正确的搜索关键词。当我们最终提出正确的问题,找到答案的过程反而是水到渠成。 当我脑子里对需求的认知还停留在私人的直播服务器时,搜索关键词可能会是“直播服务器、个人直播服务器、p2p直播......”。用这些关键词在知乎或搜索引擎搜索出来的内容,画风离解决方案还有一段距离。其中不乏一些收费软件和无关信息。 一番浏览筛选之后,当搜索关键词向“nginx、搭建流媒体视频服务器”靠拢时,解决的思路基本上已经明确了。 当我们开始动手,并把搜索关键词改成“nginx推流验证、flv.min.js下载...”,事情就变得朴实无华且枯燥起来。 ### 环境和方案 操作系统:ubuntu 推流软件:obs studio 视频服务器:nginx-http-flv-module 推流验证:nginx直接实现,免装php 播放:vlc播放器、网页播放 ### 安装nginx和nginx-http-flv-module模块 如果希望一键安装lnmp环境,可以参考[米米的博客的这篇文章](https://zhangshuqiao.org/2018-01/%E5%9F%BA%E4%BA%8ENginx%E6%90%AD%E5%BB%BA%E8%A7%86%E9%A2%91%E7%9B%B4%E6%92%AD%E6%9C%8D%E5%8A%A1%E5%99%A8/ "米米的博客的这篇文章")。 如果之前已经通过apt-get方式安装过nginx,可以下载与已安装版本相同的nginx源码包重新编译,在编译过程中添加nginx-http-flv-module模块。 如果是全新安装,且不想安装mysql和php,按照下面的步骤: - 安装各种依赖的库 ```bash apt-get update apt-get install gcc build-essential openssl libssl-dev libpcre3 libpcre3-dev zlib1g-dev ``` - 下载nginx源码安装包 全新安装在http://nginx.org/download/ 页面选择较新的版本下载即可。 `wget http://nginx.org/download/nginx-1.15.10.tar.gz` - 解压缩 `tar -zxvf nginx-1.15.10.tar.gz` - 下载nginx-http-flv-module `git clone https://github.com/winshining/nginx-http-flv-module.git` - 编译安装 ``` cd /root/nginx-1.15.10 ./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_v2_module --with-http_ssl_module --with-http_gzip_static_module --with-http_sub_module --add-module=/root/nginx-http-flv-module make make install ``` nginx的configure参数中`--add-module=`后面是下载保存nginx-http-flv-module的路径。 如果是搭建视频服务器,上面的参数就可以了,如果有更多需求,建议详细了解一下configure参数。[参考链接](http://nginx.org/en/docs/configure.html "参考链接") - 创建软链接,这样在命令行可以直接运行nginx `ln -s /usr/local/nginx/sbin/nginx /usr/sbin/nginx` - 指定nginx.conf文件的位置 `nginx -c /usr/local/nginx/conf/nginx.conf` ### 配置nginx 直接上完整的nginx.conf文件,`vi /usr/local/nginx/conf/nginx.conf ` ``` # 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; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; # gzip on; server { listen 9000 default_server; # 国外vps无需备案,可以直接改80端口 server_name localhost; index index.html index.htm; root /home/www/; # web服务器的根目录,根据实际情况修改 # 加入hls支持 location /hls { types { application/vnd.apple.mpegurl m3u8; #或 application/x-mpegURL video/mp2t ts; } alias /home/hls; # 视频流文件目录,根据实际情况修改 expires -1; add_header Cache-Control no-cache; add_header Access-Control-Allow-Origin *; } # 加入http-flv支持 location /flv { flv_live on; chunked_transfer_encoding on; } # 简单密码验证 location /auth{ default_type text/html; set $pass 0; set $mycode 123456a; # 在这里设置用于验证的密码 if ($query_string ~* "pass=(.+)$") { # ~* 正则匹配请求中包含pass=的参数 set $pass $1; # $1取匹配到的第一个参数 } if ($pass = $mycode) { return 200; } if ($pass != $mycode) { return 404; } } # 处理静态资源 location ~ ^\/static\/.*$ { root /home/www; } } } rtmp { server { listen 1935; # 监听的端口 chunk_size 4000; # 视频文件播放 application vod { play /home/hls/video; } # rtmp推流请求路径 application live { live on; record off; notify_method get; publish_notify on; # 开启推流验证 on_publish http://yourdomain.com:9000/auth; # 推流验证页面,根据实际情况修改,建议填ip或域名并带端口,不填localhost或127.0.0.1 hls on; hls_path /home/hls/; # 视频流hls切片文件目录(自己创建) hls_fragment 3s; # hls单个切片时长,会影响延迟 hls_playlist_length 32s; # hls总缓存时间,会影响延迟 meta on; # 如果http-flv播放时首帧出现问题,可改为off gop_cache on; # 可以减少首帧延迟 } } } ``` 修改配置后`nginx -s reload`载入新配置。 ### 创建相关目录和文件 ``` # web服务器根目录 mkdir /home/www # 静态资源目录 mkdir /home/www/static # 视频流hls切片文件目录 mkdir /home/hls # 保存录像或者上传录像的目录 mkdir /home/hls/video # 创建网站首页 touch /home/www/index.html # 编辑首页内容 vi /home/www/index.html ``` 参考米米的博客写的第一种首页,适合edge浏览器和手机上的浏览器 ```html <!--index.html--> <html> <body> <video autoplay webkit-playsinline controls> <source src="http://yourdomain.com:9000/hls/test.m3u8" type="application/vnd.apple.mpegurl" /> <p class="warning">Your browser does not support HTML5 video.</p> </video> </body> </html> ``` 使用flv.js的第二种首页,就是在flv.js的示例加了一行`isLive: true,`。 ``` <!--index.html--> <html> <body> <script src="/static/flv.min.js"></script> <video id="videoElement"></video> <script> if (flvjs.isSupported()) { var videoElement = document.getElementById('videoElement'); var flvPlayer = flvjs.createPlayer({ type: 'flv', isLive: true, url: 'http://yourdomain:9000/flv?app=live&stream=test' }); flvPlayer.attachMediaElement(videoElement); flvPlayer.load(); flvPlayer.play(); } </script> </body> </html> ``` flv.min.js这个文件找了半天才找到,可以直接使用cdn: `https://cdn.bootcss.com/flv.js/1.5.0/flv.min.js` 或者下载并放在`/home/www/static`。 ### obs studio设置  - 推流服务器: `rtmp://yourdomain:1935/live` - 串流密钥 `test?pass=123456a` 串流密钥决定hls文件夹下生存的视频文件名称,输入test,生成的就是test.m3u8。输入mylive,生成的就是mylive.m3u8。 用于验证的密码`?pass=123456a`应该填在串流密钥后面,而不是填在推流服务器后面。填`rtmp://yourdomain:1935/live?pass=123456a`是连不上的。 ### 查看播放效果 在obs中开始推流,可用以下方法查看效果。 方法1(第一种首页): 在edge浏览器/手机浏览器中打开`yourdomain.com:9000`,查看直播效果。 方法2(第二种首页): 在支持html5的浏览器中打开`yourdomain.com:9000`,查看直播效果。 方法3: 在vlc播放器中选择“打开网络串流”,填入: `rtmp://yourdomain:1935/live/test` 或者`http://yourdomain.com:9000/flv?app=live&stream=test` 方法4(播放录像): 将录像文件test.flv传到`/home/hlf/video`目录 在vlc播放器中选择“打开网络串流”,填入: `rtmp://yourdomain.com:1935/vod/test.flv` 需要注意的是几种情况下链接的格式不太一样,端口、路径都有点区别 ``` # 推流地址 rtmp://yourdomain.com:1935/live # hls播放地址 http://yourdomain.com:9000/hls/test.m3u8 # vlc播放直播地址 rtmp://yourdomain.com:1935/live/test http://yourdomain.com:9000/flv?app=live&stream=test # vlc播放服务器上的文件 rtmp://yourdomain.com:1935/vod/test.flv ``` ### 其他 - 如果已开启防火墙,需打开用到的1935和9000端口。命令是`ufw allow 1935`和`ufw allow 9000` - 如果有安全组,同样需要打开用到的1935和9000端口。 - 推流验证可以用其他方式实现,不希望多装个php环境所以选择nginx直接验证。搜索"nginx推流验证”了解更多。 - 如果nginx安装时指定了用户(例如用户为www),需要确保该用户可以访问`/home/www`和`/home/hls`,命令是`chown -R www:www /home/www`和`chown -R www:www /home/hls`