EasyDarwin+flv.js视频直播【web端播放EasyDarwin的rtsp流】
实现摄像头的直播功能其实有许多方案,像是安装vlc插件、rtsp转rtmp然后使用videojs通过flash播放rtmp,以及hls .m3u8等方式
然而现今的浏览器对于vlc插件几乎都不再支持了,flash在2020年也将被chrome停止支持,而.m3u8的方案用来做直播的话似乎延迟很高。最终决定使用B站开源的flv.js。
推流工具使用的是FFmpeg
流媒体服务使用EasyDarwin 【支持录播、直播rtsp流,还有api】
播放客户端使用B站(bilibili)开源的flvjs作为解决方案,其原理是后端用ffmpeg将rtsp视频流转换为flv,然后通过websocket传输flv视频流,然后前端通过websocket获取到视频流后,使用flvjs对视频流再一次处理并进行播放,这是一套无插件无flash免费的视频直播解决方案。
本文使用Windows环境
步骤:
1、搭建FFmpeg
①模拟本地笔记本摄像头推流到服务端
②获取本地摄像头名称
ffmpeg -list_devices true -f dshow -i dummy
③使用FFMpeg推流至EasyDarwin【EasyDarwin搭建图在第二条】
ffmpeg -f dshow -i video="Integrated Webcam" -vcodec libx264 -acodec libvo_aacenc -b 1080k -r 25 -preset:v ultrafast -tune:v zerolatency -f rtsp rtsp://localhost/0206test
2、搭建EasyDarwin,根据https://github.com/EasyDarwin/EasyDarwin,详细的不说了,上图
①EasyDarwin的配置文件,默认为与可执行文件同目录的EasyDarwin.ini文件
编辑器打开EasyDarwin.ini,内容如下:
[http]
port=10008
default_username=admin
default_password=admin
[rtsp]
port=554
; rtsp 超时时间,包括RTSP建立连接与数据收发。
timeout=28800
; 是否使能gop cache。如果使能,服务器会缓存最后一个I帧以及其后的非I帧,以提高播放速度。但是可能在高并发的情况下带来内存压力。
gop_cache_enable=1
; 是否使能推送的同事进行本地存储,使能后则可以进行录像查询与回放。
save_stream_to_local=1
;easydarwin使用ffmpeg工具来进行存储。这里表示ffmpeg的可执行程序的路径
ffmpeg_path=/Users/ze/Downloads/ffmpeg-20180719-9cb3d8f-macos64-shared/bin/ffmpeg
;本地存储所将要保存的根目录。如果不存在,程序会尝试创建该目录。
m3u8_dir_path=/Users/ze/Downloads/EasyDarwinGoM3u8
;切片文件时长。本地存储时,将以该时间段为标准来生成ts文件(该时间+一个I帧间隔),单位秒
ts_duration_second=6
;ffmpeg转码格式,比如可设置为-c:v copy -c:a copy,表示copy源格式;default表示使用ffmpeg内置的输出格式,可能需要转码
/265=default
- save_stream_to_local表示是否开启本地存储。1表示开启,0表示不开启。我们改成1即可
- ffmpeg_path表示ffmpeg的可执行文件的路径。即上一步从ffmpeg下载安装后的路径,如我的mac上的路径为
/Users/apple/Downloads/ffmpeg-20180719-9cb3d8f-macos64-shared/bin/ffmpeg
- m3u8_dir_path表示录像文件的存储目录。设置为一个存在的可读可写目录即可。比如我设置为
/Users/apple/Downloads/EasyDarwinGoM3u8
- 启动EasyDarwin服务,可看到有这样一句
[EasyDarwin] 2018/11/17 12:45:35 rtsp-server.go:67: Prepare to save stream to local....
输出日志,表示配置本地存储成功。
3、使用flv.js,参考https://blog.csdn.net/weixin_42536639/article/details/102870788
Demo github地址:https://github.com/LorinHan/flvjs_test
①后端环境是node express,前端是vue
②将服务pull下来后,安装第三方依赖,websocket-stream
npm install express express-ws fluent-ffmpeg websocket-stream -S -D
npm较慢,可使用淘宝镜像cnpm
③编写代码index.js
其中setFfmpegPath这里是指明了ffmpeg的安装路径
var express = require("express");
var expressWebSocket = require("express-ws");
var ffmpeg = require("fluent-ffmpeg");
ffmpeg.setFfmpegPath("D:/ffmpeg-20191031-7c872df-win64-static/ffmpeg-20191031-7c872df-win64-static/bin/ffmpeg");
var webSocketStream = require("websocket-stream/stream");
var WebSocket = require("websocket-stream");
var http = require("http");
function localServer() {
let app = express();
app.use(express.static(__dirname));
expressWebSocket(app, null, {
perMessageDeflate: true
});
app.ws("/rtsp/:id/", rtspRequestHandle)
app.listen(8888);
console.log("express listened")
}
function rtspRequestHandle(ws, req) {
console.log("rtsp request handle");
const stream = webSocketStream(ws, {
binary: true,
browserBufferTimeout: 1000000
}, {
browserBufferTimeout: 1000000
});
let url = req.query.url;
console.log("rtsp url:", url);
console.log("rtsp params:", req.params);
try {
ffmpeg(url)
.addInputOption("-rtsp_transport", "tcp", "-buffer_size", "102400") // 这里可以添加一些 RTSP 优化的参数
.on("start", function () {
console.log(url, "Stream started.");
})
.on("codecData", function () {
console.log(url, "Stream codecData.")
// 摄像机在线处理
})
.on("error", function (err) {
console.log(url, "An error occured: ", err.message);
})
.on("end", function () {
console.log(url, "Stream end!");
// 摄像机断线的处理
})
.outputFormat("flv").videoCodec("copy").noAudio().pipe(stream);
} catch (error) {
console.log(error);
}
}
localServer();
④ 启动后端,node index.js ,出现以下代表监听成功
⑤ 启动前端:进入项目front目录,执行以下命令,安装依赖,编译代码,运行
· cnpm install
· cnpm run build
· npm run dev
⑥ 出现以下图即为启动成功
4、流程
① 使用上面FFmpeg推流命令 想EasyDarwin推流
② 将rtsp路径改至前端服务中
import flvjs from "flv.js";
export default {
data () {
return {
id: "1",
rtsp: "rtsp://localhost/020666",
player: null
}
}
③ 访问前端服务 http://localhost:8080/#/,将rtsp流播放成功