以下代码与实现均来源于参考博客,本人只是知识的搬运工。先跑起来,再学改进。
一 nginx-http-flv-module + HTTP-FLV + flv.js
直播3s延迟
1.1 视频服务器
1.1.1 下载 nginx-http-flv-module
懒得自己(学)编译 ,CSDN下载太坑,github上有编译后的Release版,下载后替换原版Nginx中对应文件:
https://github.com/aushy/nginx-http-flv-win32
【回过头看:还是得学linux上怎么编译,比如FFmpeg,apt-get安装的版本号太老,要自己编译的才能用,而且有时候还会报错缺少文件,也需要自己编译;Linux下编译比WIndows下方便多了】
1.1.2 配置 nginx
worker_processes 1;
events {
worker_connections 1024;
}
# HTTP服务
http {
include mime.types;
default_type application/octet-stream;
server {
listen 8080;
server_name localhost;
location /stat.xsl {
root html;
}
location /stat {
rtmp_stat all;
rtmp_stat_stylesheet stat.xsl;
}
location / {
root html;
}
location /live {
flv_live on ; # FLV直播
chunked_transfer_encoding on ; # 支持'Transfer-Encoding: chunked'方式回复
add_header 'Access-Control-Allow-Origin' '*'; # 跨域
add_header 'Access-Control-Allow-Credentials' 'true'; # 跨域
expires -1;
}
location /control { # 控制直播录制
rtmp_control all;
}
location /vod/ {
add_header 'Access-Control-Allow-Origin' '*'; # 跨域
add_header 'Access-Control-Allow-Credentials' 'true'; # 跨域
alias D:/nginx/save/vod/;
}
}
}
rtmp_auto_push on;
rtmp_auto_push_reconnect 1s;
rtmp_socket_dir logs;
# 添加RTMP服务
rtmp {
out_queue 4096;
out_cork 8;
max_streams 128;
timeout 15s;
drop_idle_publisher 15s;
log_interval 5s; #log模块在access.log中记录日志的间隔时间,对调试非常有用
log_size 1m; #log模块用来记录日志的缓冲区大小
server {
listen 1985;
application myapp {
live on ; # RTMP直播
gop_cache on ;
recorder rec1{ # 保存录像
record all manual; # 手动保存
record_unique on;
record_max_size 128M;
record_path D:/nginx/save;
record_suffix -%Y-%m-%d-%H_%M_%S.flv;
}
}
application vod2{ # RMTP点播
play D:/nginx/save/vod;
}
}
}
1.1.3 FFmpeg
ffmpeg -rtsp_transport tcp -i rtsp://UserName:Password@IP_1:554/h264/ch1/main/av_stream -c copy -f flv rtmp://IP_2:Port/AppName/StreamName
字段 | 含义 |
---|---|
UserName | 摄像头后台用户名 |
Password | 摄像头后台密码 |
IP_1 | 摄像头IP |
IP_2 | Nginx所在服务器IP |
Port | Nginx中RTMP监听端口 |
AppName | Nginx中RTMP中Application名称 |
StreamName | 自定义视频流名称 |
1.2 浏览器
1.2.1 直播
<!DOCTYPE html>
<html>
<head></head>
<script src="https://cdn.bootcss.com/flv.js/1.5.0/flv.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<body>
<div><input type="text" id='urlId' value="" /> <button type="button" id="butPlay">播放</button></div>
<div class="mainContainer">
<video name="videoElement" class="centeredVideo" id="videoElement" controls width="1024" height="576" autoplay='true'>
Your browser is too old which doesn't support HTML5 video.
</video>
</div>
</body>
<script>
console.log('start')
// alert(flvjs.isSupported())
if (flvjs.isSupported()) {
play();
}
$("#butPlay").click(function(event){
play();
})
function play(){
var us = $("#urlId").val();
console.info(new Date(), us)
if (!us) {
us = 'mystream'
}
var videoElement = document.getElementById('videoElement');
var flvPlayer = flvjs.createPlayer({
type: 'flv',
enableWorker: true, //浏览器端开启flv.js的worker,多进程运行flv.js
isLive: true, //直播模式
hasAudio: false, //关闭音频
hasVideo: true,
stashInitialSize: 128,
enableStashBuffer: true, //播放flv时,设置是否启用播放缓存,只在直播起作用。
url: 'http://127.0.0.1:8080/live?port=1985&app=myapp&stream=mystream'
});
flvPlayer.attachMediaElement(videoElement);
flvPlayer.load();
flvPlayer.play();
}
</script>
</html>
开始录制:http://127.0.0.1:8080/control/record/start?app=myapp&name=mystream&rec=rec1
结束录制:http://127.0.0.1:8080/control/record/start?app=myapp&name=mystream&rec=rec1
app:Nginx中设置的直播Application名称
name:FFmpeg中自定义的StreamName
rec:Nginx 中设置的Recorder名称
1.2.2 点播
function play(){
var us = $("#urlId").val();
console.info(new Date(), us)
if (!us) {
us = 'mystream'
}
var videoElement = document.getElementById('videoElement');
var flvPlayer = flvjs.createPlayer({
type: 'flv',
enableWorker: true, //浏览器端开启flv.js的worker,多进程运行flv.js
hasAudio: false, //关闭音频
hasVideo: true,
stashInitialSize: 128,
url: 'http://127.0.0.1:8080/vod/aa.flv'
});
flvPlayer.attachMediaElement(videoElement);
flvPlayer.load();
flvPlayer.play();
}
二 nginx-rtmp-module + RMTP + videojs/aliplayer
2.1 视频服务器
直接参考该博客:
https://my.oschina.net/gaga/blog/478480?fromerr=xxLXMG9w
Nginx配置与上面HTTP-FLV中完全一样
2.2 浏览器
这里有个很坑的点:无论是使用aliplayer还是videojs,HTML文件必须放在服务器上(tomcat、nodejs都行)。本地直接打开,无法播放视频。本地打开时:
- aliplayer提示:“不能直接在浏览器打开html文件,请部署到服务端”;
- videojs没有提示,但是不能播放;
注意:
RTMP直播时,FFmpeg推流的端口、Nginx输入的端口、浏览器请求的端口,是相同的。
FFmpeg推流、浏览器请求的URL也是相同的,都是:rtmp://127.0.0.1:1985/myapp/mystream
不知道Nginx起什么作用,以及如何处理
2.2.1 videojs 直播
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<link href="https://cdn.bootcdn.net/ajax/libs/video.js/7.5.4/video-js.min.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/video.js/7.5.4/video.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/videojs-flash/2.2.1/videojs-flash.min.js"></script>
</head>
<body>
<video id="my-player" class="video-js" controls preload="auto" data-setup='{}'>
<source src="rtmp://127.0.0.1:1985/myapp/mystream"></source>
</video>
</body>
</html>
2.2.2 aliplayer 直播
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="IE=edge" >
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"/>
<title></title>
<link rel="stylesheet" href="https://g.alicdn.com/de/prismplayer/2.8.1/skins/default/aliplayer-min.css" />
<script type="text/javascript" charset="utf-8" src="https://g.alicdn.com/de/prismplayer/2.8.1/aliplayer-min.js"></script>
</head>
<body>
<div class="prism-player" id="player-con"></div>
<script>
var player = new Aliplayer({
"id": "player-con",
"source": "rtmp://127.0.0.1:1985/myapp/mystream",
"width": "100%",
"height": "500px",
"autoplay": true,
"isLive": true,
"playsinline": true,
"preload": true,
"controlBarVisibility": "hover",
"useH5Prism": true
}, function (player) {
player._switchLevel = 0;
console.log("播放器创建了。");
}
);
</script>
</body>
三 websocket-relay + websocket + jsmpeg
这个直播延迟真心小,500ms左右,但是没法像用nginx-rtmp那样控制录制,看能不能前端请求时用后端控制ffmpeg录制。而且只支持一路流,要么自己改写websocket-relay脚本。
教程: 下面教程已经很完善,大力推荐;只需注意一点:不要全局安装ws模块,安装到jsmpeg目录下即可,否则一直报错:找不到ws模块。另外,该博客作者提供了支持多路的js文件。
https://my.oschina.net/chengpengvb/blog/1832469
类似方案: 未试验
wsoc_rtsp_proxy.js【服务器】 + html_rtsp_palyer.js【前端插件】
https://blog.csdn.net/u011489205/article/details/79327275
与HTTP-FLV相比为什么延迟这么小?
什么因素导致的:FFmpeg命令?Websocket传输?MPEG2-TS封装?mpeg1video编码?
HTTP-FLV方案能否借鉴?
见 直播与点播之三_进阶、反思、理解、改进
四 补充
4.1 Node-Media-Server方案实现
五 参考
5.1 大力推荐
最简明扼要的实现(HTTP-FLV):
https://blog.csdn.net/u012848709/article/details/106064127
HTTP-FLV优化:
https://blog.csdn.net/string_kai/article/details/100598268
最全面的实现(RTMP):包括,点播、直播、手动录制
https://my.oschina.net/gaga/blog/478480?fromerr=xxLXMG9w
完整的实现(RTMP),提供nginx-rtmp-module:
https://blog.csdn.net/Contex_A17/article/details/82191050
RTMP方案前端播放问题:
https://www.cnblogs.com/FHC1994/p/9981440.html
https://blog.csdn.net/weixin_44021417/article/details/100082067
海康威视摄像头视频流URL:
https://blog.csdn.net/cug_heshun2013/article/details/79434387
jsmpeg方案实现:
http://www.cnweblog.com/fly2700/archive/2019/09/07/325500.html
5.2 一般推荐
jsmpeg方案补充:
https://blog.csdn.net/amhoho/article/details/98940790
https://www.cnblogs.com/warcraft/p/11216228.html
Linux下实现HLS方案:
https://blog.csdn.net/Ricardo18/article/details/89359623
Linux下实现HTTP-FLV方案:
https://blog.csdn.net/caowenjing123/article/details/94623466
海康威视、大华摄像头视频流URL、多路推流:
https://blog.csdn.net/qq_22633333/article/details/96288603
https://blog.csdn.net/qq_34239851/article/details/107078336
WebRTC方案:
WebRTC直播:
https://www.zhihu.com/question/25497090
https://www.zhihu.com/question/22301898
直播和视频会议是两种不同的业务场景,主要关注点不同;WebRTC用于视频会议没异议,用于大范围直播有争议;淘宝直播基于WinRTC改进
WebRTC视频通话:
https://blog.csdn.net/Melod_bc/article/details/61414980
https://blog.csdn.net/weixin_44268792/article/details/106243014
https://www.cnblogs.com/georgewangii/p/4604066.html
WebSocket + MSE:
https://zhuanlan.zhihu.com/p/27248188
http://www.how01.com/post_8RDNRL13o2l0L.html
flvjs是基于MSE:
https://www.zhihu.com/question/57837893
MSE:<video>不支持流;MSE是浏览器新的WebAPI,使得JS直接处理媒体流转为文件,再将文件推到HTML5中的媒体标签中