2021-10-11 15:20:01 星期一
demo
重要参考
https://ivampiresp.com/2020/04/05/use-the-rtmp-module-of-nginx-to-build-a-streaming-media
基本对着来就行。由于我是在网站上部署,而2021年新版本Chrome对HTTPS的执念非常之强,文中http localhost的方法在HTTPS的环境下常常就不管用了,在GitHub上翻看了很多配置文档才搞定HTTPS的配置,坑实在是太多了。
一些配置文件及常用命令
推流部分
srs配置
centos编译安装
https://github.com/ossrs/srs/wiki/v4_CN_Home#getting-started
Debian(Ubuntu应该差不多,我是用的Debian,按步骤做一点问题没有)
https://www.cnblogs.com/surplus/p/15319061.html
./srs/trunk/conf/https.hls.conf
# the config for srs to delivery hls
# @see https://github.com/ossrs/srs/issues/1657#issuecomment-722971676
# @see full.conf for detail config.
listen 1935;
max_connections 1000;
daemon off;
srs_log_tank console;
http_server {
enabled on;
listen 8080;
dir ./objs/nginx/html;
https {
enabled on;
listen 8088;
key /root/.acme.sh/binaryenfold.xyz/binaryenfold.xyz.key;
cert /root/.acme.sh/binaryenfold.xyz/binaryenfold.xyz.cer;
}
}
vhost __defaultVhost__ {
hls {
enabled on;
hls_fragment 10;
hls_window 60;
hls_path ./objs/nginx/html;
hls_m3u8_file [app]/[stream].m3u8;
hls_ts_file [app]/[stream]-[seq].ts;
}
}
常用命令
以特定conf运行srs
/srs/trunk/objs/srs -c conf/https.hls.conf
/srs/trunk/objs/srs -c conf/https.flv.live.conf
执行脚本
bash /srs/trunk/scripts/lofi.sh
bash /srs/trunk/scripts/lofiflv.sh
查看srs状态
/srs/trunk/etc/init.d/srs status
关闭srs服务
/srs/trunk/etc/init.d/srs grace
重启srs
/srs/trunk/etc/init.d/srs restart
重载srs
/srs/trunk/etc/init.d/srs reload
查看脚本进程
ps -ef | grep lofi.sh
#screen-用screen是为了在退出ssh的时候保持服务运行,当然方法有很多了
screen -S name #name用于命名screen窗口用途
screen -ls #查看进程
screen -r #进入单一进程
screen -r -d 1805 #进入screen进程
screen -X -S 122128 quit #关闭某一进程
ctrl-a +d #保持进程的同时退出当前窗口
自己编写lofi.sh脚本,无限推流lofigirl(需要提前安装好ffmpeg)
./scripts/lofi.sh
#!/bin/sh
while true
do
lofigirl="$(youtube-dl -g https://www.youtube.com/watch?v=5qap5aO4i9A)"
youtube="$(ffmpeg -re -i ${lofigirl} -vcodec copy -acodec copy -bsf:a aac_adtstoasc -f flv -flvflags no_duration_filesize "rtmp://45.77.101.70:1935/live/livestream.m3u8")"
echo "${youtube}"
sleep 10
done
证书管理
推荐用acme.sh
注意秘钥格式只能用rsa(默认配置即可)。我原本用的一键脚本,结果设置的ecc秘钥(如下所示),srs死活验证不出来,看了srs的源码才知道只能用rsa,人家wiki里也不讲两句……
[Wed Oct 6 19:23:08 UTC 2021] Your cert is in: /root/.acme.sh/binaryenfold.xyz_ecc/binaryenfold.xyz.cer
[Wed Oct 6 19:23:08 UTC 2021] Your cert key is in: /root/.acme.sh/binaryenfold.xyz_ecc/binaryenfold.xyz.key
[Wed Oct 6 19:23:08 UTC 2021] The intermediate CA cert is in: /root/.acme.sh/binaryenfold.xyz_ecc/ca.cer
[Wed Oct 6 19:23:08 UTC 2021] And the full chain certs is there: /root/.acme.sh/binaryenfold.xyz_ecc/fullchain.cer
配置完以后应该就可以直接在Safari浏览器(因为hls本就是苹果开发的格式……)拉流了:https://binaryenfold.xyz:8088/live/livestream.m3u8.m3u8
当然用播放器rtmp也可以:
rtmp://binaryenfold.xyz:8080/live/livestream.m3u8.m3u8
当然http也可以:
http://binaryenfold.xyz:8080/live/livestream.m3u8.m3u8
前端
解决完推拉流的问题就到聊天室实现了。需要提的一点是我的npm包是宝塔面板帮我装的,需要自己配置一下centos全局环境变量export PATH=$PATH:/www/server/nvm/versions/node/v14.18.0/bin
。把express,node.js,socket.io都用npm安装好后,再进行后面的步骤。
indexooo.html,这个文档基本是抄的
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0,maximum-scale=1.0, user-scalable=no" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="renderer" content="webkit">
<link rel="stylesheet" href="//cdnjs.loli.net/ajax/libs/mdui/0.4.3/css/mdui.min.css" />
<link rel="icon" href="https://img.moegirl.org.cn/common/7/72/Kanae_midsummer_Icon.png" sizes="32x32" />
<link rel="icon" href="https://img.moegirl.org.cn/common/1/11/Kanae-0.png" sizes="192x192" />
<link rel="apple-touch-icon" href="https://assets.leetcode-cn.com/aliyun-lc-upload/users/cutesnake/avatar_1632978144.png" />
<script src="//cdnjs.loli.net/ajax/libs/mdui/0.4.3/js/mdui.min.js"></script>
<title>Live</title>
</head>
<body class="mdui-drawer-body-left mdui-appbar-with-toolbar mdui-color-yellow-200 mdui-theme-accent-pink">
<header class="mdui-appbar mdui-appbar-fixed">
<div class="mdui-toolbar mdui-color-theme">
<span class="mdui-btn mdui-btn-icon mdui-ripple mdui-ripple-white" mdui-drawer="{target: '#main-drawer', swipe: true}"><i class="mdui-icon material-icons">menu</i></span>
<a href="#" class="mdui-typo-headline mdui-typo-title">Live</a>
<div class="mdui-toolbar-spacer"></div>
</div>
</header>
<div class="mdui-drawer" id="main-drawer">
<div class="mdui-list" mdui-collapse="{accordion: true}" style="margin-bottom: 76px;">
<div class="mdui-collapse-item ">
<div class="mdui-collapse-item-header mdui-list-item mdui-ripple">
<i class="mdui-list-item-icon mdui-icon material-icons mdui-text-color-blue">near_me</i>
<div class="mdui-list-item-content">菜单</div>
<i class="mdui-collapse-item-arrow mdui-icon material-icons">keyboard_arrow_down</i>
</div>
<div class="mdui-collapse-item-body mdui-list">
<a href="./" class="mdui-list-item mdui-ripple ">刷新</a>
<a href="https://blog.cutesnake.top" class="mdui-list-item mdui-ripple ">博客</a>
<a href="https://space.bilibili.com/14173132" class="mdui-list-item mdui-ripple ">bilibili</a>
<a href="https://leetcode-cn.com/u/cutesnake/" class="mdui-list-item mdui-ripple ">leetcode</a>
</div>
</div>
</div>
</div>
<div class="mdui-container" style="float: left;">
<br />
<video preload="auto" class="mdui-video-fluid" poster="https://i.loli.net/2020/04/01/ylL1nsNXDdBxwMT.jpg" id="video" controls></video>
<script src="https://cdn.bootcss.com/hls.js/0.13.2/hls.min.js"></script>
<script>
var video = document.getElementById('video');
if (Hls.isSupported()) {
var hls = new Hls();
hls.loadSource('https://binaryenfold.xyz:8088/live/livestream.m3u8.m3u8');
hls.attachMedia(video);
hls.on(Hls.Events.MANIFEST_PARSED, function() {
video.play();
});
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
video.src = 'https://binaryenfold.xyz:8088/live/livestream.m3u8.m3u8';
video.addEventListener('loadedmetadata', function() {
video.play();
});
}
</script>
<h1 class="mdui-text-color-theme">实时评论区</h1>
<ul id="messages"></ul>
<form name="chat" action="">
<div class="mdui-textfield">
<label class="mdui-textfield-label">昵称</label>
<input class="mdui-textfield-input" id="username" type="text" placeholder="昵称" oninput="getUser()" autocomplete="on" required />
</div>
<div class="mdui-textfield">
<label class="mdui-textfield-label">实时评论</label>
<input class="mdui-textfield-input" id="comment" type="text" onclick="echoUser()" placeholder="请遵守格式,谢谢! 格式为:“昵称:内容”(不包括引号)" autocomplete="off" maxlength="35" required />
<br />
<button class="mdui-btn mdui-btn-raised mdui-ripple mdui-color-theme-accent">发送</button>
</div>
</form>
<script src="/socket.io/socket.io.js"></script>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<script type="text/javascript">
function getUser() {
userName = ($("#username").val());
}
function echoUser() {
$("#comment").attr("value", userName + ':');
}
var socket = io();
$('form').submit(function() {
//点击发送按钮,提交输入的信息
socket.emit('chat message', $('#comment').val());
$('#comment').val(userName + ':');
return false;
});
//接收到chat message时
socket.on('chat message', function(msg) {
//将chat message显示在页面
$('#messages').append($('<li>').text(msg));
});
</script>
<p>直播源:<a href='https://www.youtube.com/watch?v=5qap5aO4i9A'>lofigirl,</a> <a href='https://ivampiresp.com/2020/04/05/%e4%bd%bf%e7%94%a8nginx%e7%9a%84rtmp%e6%a8%a1%e5%9d%97%e6%90%ad%e5%bb%ba%e4%b8%80%e4%b8%aa%e6%b5%81%e5%bc%8f%e5%aa%92%e4%bd%93%ef%bc%88%e7%9b%b4%e6%92%ad%ef%bc%89%e6%9c%8d%e5%8a%a1%e5%99%a8%e5%b9%b6'>搭建教程</a>
我主要在教程基础上解决了srs和socket.io的跨域问题,但是反代理那块socket.io还是没搞定,会报404,没办法大家还是用3000端口访问吧。<a href='https://blog.cutesnake.top/index.php/archives/69/'>这是我的一些配置文件和说明。</a>
</p>
</div>
</body>
</html>
后端
为了适配https,还是花了很长时间才东拼西凑出来。
index.js
const { readFileSync } = require("fs");
const { createServer } = require("https");
const { Server } = require("socket.io");
//使用express模块快速搭建web服务器
const express = require('express');
const app = express();
const httpsServer = createServer({
key: readFileSync("/www/server/panel/vhost/cert/live.cutesnake.top/privkey.pem"),
cert: readFileSync("/www/server/panel/vhost/cert/live.cutesnake.top/fullchain.pem")
}, app);
//使用socket.io监听事件
const io = new Server(httpsServer, {/* */});
//使用express发送css js等静态资源
app.use(express.static('public'));
//express获得GET请求时将indexooo.html文件返回给浏览器
app.get('/',function(req,res){
res.sendFile(__dirname + '/indexooo.html');
});
//socket监听连接事件
io.on('connection', function(socket){
console.log('一个用户上线了');
//socket监听失去连接的事件
socket.on('disconnect', function(){
console.log('一个用户下线了');
});
//当socket监听到了'chat message'事件
socket.on('chat message', function(msg){
//将收到的信息返回给所有客户端
io.emit('chat message',msg);
console.log(msg);
});
});
//服务器监听端口3000
httpsServer.listen(3000,function(){
console.log('https server listening on *:3000');
})
写好以后node index.js
启动服务。
到这基本就OK了。
反代理
最后,反代理一块,后面有篇参考写得很好。我这里socket.io会报404,还是https特有的证书问题,不过我代码应该是没问题的,出错的原因在于我服务器上有很多个证书,可能哪里默认读了其他的证书。如果只有单一一个网站的话应该就问题不大了。还是贴一下我的反代理代码。
#反向代理,这段代码在监听80和443端口的server大括号内
location / {
proxy_pass https://live.cutesnake.top:3000/;
proxy_ssl_certificate /www/server/panel/vhost/cert/live.cutesnake.top/fullchain.pem;
proxy_ssl_certificate_key /www/server/panel/vhost/cert/live.cutesnake.top/privkey.pem;
proxy_ssl_protocols TLSv1.1 TLSv1.2;
proxy_ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
proxy_ssl_verify_depth 1;
proxy_ssl_session_reuse on;
}
一堆参考网站
nginx https反向代理设置
https://docs.nginx.com/nginx/admin-guide/security-controls/securing-http-traffic-upstream/
总体思路
https://ivampiresp.com/2020/04/05/%e4%bd%bf%e7%94%a8nginx%e7%9a%84rtmp%e6%a8%a1%e5%9d%97%e6%90%ad%e5%bb%ba%e4%b8%80%e4%b8%aa%e6%b5%81%e5%bc%8f%e5%aa%92%e4%bd%93%ef%bc%88%e7%9b%b4%e6%92%ad%ef%bc%89%e6%9c%8d%e5%8a%a1%e5%99%a8%e5%b9%b6
https://www.jianshu.com/p/5539ccd8d9c4
反向代理
https://www.cnblogs.com/ysocean/p/9392908.html#_label3
http REFERER
http://www.ruanyifeng.com/blog/2019/06/http-referer.html
简单app
https://www.cnblogs.com/handongyu/p/6260209.html
express配置 https://blog.csdn.net/bwf_erg/article/details/70649536?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_title~default-0.no_search_link&spm=1001.2101.3001.4242
node.js https://nodejs.org/api/https.html#https_https_get_options_callback
socket.io
https://socket.io/docs/v4/server-initialization/#with-an-https-server
成果:
https://live.cutesnake.top:3000
#### 一些无关紧要的话
写博客用到emoji的话emoji后面所有的文字都会被卡掉,白写了好多次才发现,太坑了……