最近在用 Electron 开发一个客户端 需要集成监控摄像头
摄像头是海康的网络摄像头 通过 RTSP 协议获取到推流视频
通过在 node 主进程创建一个服务 通过 websocket 接受 rtsp 连接
在通过 ffmpeg 转码通过 stream 推到渲染进程
渲染进程通过 flv.js 播放视频
通过转码可以实现 web 页面播放 rtsp 的视频流
但是会有 5~6 秒的延迟 体验很不好
而且 客户端集成 ffmpeg 体积太大了
想了解下 关于 rtsp 转码的方法还有那些 在 node 端可以实现的
主进程创建的 web 服务
import * as express from 'express'
import * as expressWebSocket from 'express-ws'
import ffmpeg from 'fluent-ffmpeg'
import webSocketStream from 'websocket-stream/stream'
const path = require('path')
let ffmpegPath
if (process.env.NODE_ENV === 'development') {
ffmpegPath = path.join(__static, 'ffmpeg', 'bin', 'ffmpeg.exe')
} else {
ffmpegPath = path.join(process.cwd(), 'ffmpeg', 'bin', 'ffmpeg.exe')
}
ffmpeg.setFfmpegPath(ffmpegPath)
// 启动视频转码服务服务
function videoServer () {
let app = express()
app.use(express.static(__dirname))
expressWebSocket(app, null, {
perMessageDeflate: true
})
app.ws('/rtsp/', rtspRequestHandle)
app.listen(8888)
console.log('express listened')
}
// RTSP 转码方法
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)
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)
}
}
export default videoServer
渲染进程通过播放视频
<template>
<div class="video">
<video class="video-box" ref="player"></video>
</div>
</template>
<script>
import flvjs from 'flv.js'
export default {
name: 'videopage',
props: {
rtsp: String
},
data () {
return {
player: null
}
},
mounted () {
if (flvjs.isSupported()) {
let video = this.$refs.player
if (video) {
this.player = flvjs.createPlayer({
type: 'flv',
isLive: true,
url: 'ws://localhost:8888/rtsp/?url=' + this.rtsp
})
this.player.attachMediaElement(video)
try {
this.player.load()
this.player.play()
} catch (error) {
console.log(error)
}
}
}
},
methods: {
getCurrentFrame () {
let video = this.$refs.player
let scale = 1
let canvas = document.createElement('canvas')
canvas.width = video.videoWidth * scale
canvas.height = video.videoHeight * scale
canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height)
return canvas.toDataURL('image/png')
}
},
beforeDestroy () {
this.player.destory()
}
}
</script>
<style lang="scss">
.video {
width: 100%;
height: 100%;
font-size: 0;
video {
width: 100%;
height: 100%;
}
}
</style>
1
yangheng4922 OP 不要沉啊
|
2
yangheng4922 OP 有大佬遇到过这种问题么
|
3
circleee 2020-07-22 08:59:12 +08:00
能转成 rtmp 吗?
|
4
jiobanma 2020-07-22 09:11:41 +08:00
c 的话不知道怎么做,不过我开源了一套 java 的 rtsp-rtmp 的服务,使用开源的 javacv 框架(调用底层 ffmpeg ) 使用了转封装的技术,直接将音视频解复用,然后转封装为 flv 格式的包推出去,因为不涉及编解码 所以 cpu 内存占用率很低。延迟的话大概 1-3s ggitee 地址: https://gitee.com/banmajio/RTSPtoRTMP github: https://github.com/banmajio/RTSPtoRTMP 如果有帮助,劳烦点个 star
|
6
lower 2020-07-22 16:13:56 +08:00
有没有可能直接集成个 vlc 直接取 rtsp 流?
|
7
tangchi695 2020-07-23 11:34:20 +08:00
想问下海康的视频流怎么获取的呢?同样在弄一个有监控的项目,以前没做过视频,不知道怎么在 nvr 上做二次开发。
|
8
SongGG3 2020-07-23 14:14:31 +08:00
试试 input output 添加 -fflags nobuffer -tune zerolatency
然后 flv.js 添加 enableStashBuffer: true |
9
yangheng4922 OP @SongGG3 #8
在 ffmpeg 的配置里面添加么 |
10
yangheng4922 OP @tangchi695 #7 海康可以通过 rtsp 协议获取视频流
|
11
yangheng4922 OP @SongGG3 #8
```javascript ffmpeg(url) .addInputOption('-rtsp_transport', 'tcp', '-buffer_size', '102400', '-fflags', 'nobuffer', '-tune', 'zerolatency') ``` ```javascript flvjs.createPlayer({ type: 'flv', isLive: true, url: 'ws://localhost:8888/rtsp/?url=' + this.rtsp, enableStashBuffer: true // 添加行 }) ``` |
12
yangheng4922 OP @SongGG3 #8 是这样子么
|
13
yangheng4922 OP @SongGG3 #8
我修改了一下参数 但是还是没有明显的改善 |
14
SongGG3 2020-07-27 14:03:02 +08:00
@yangheng4922 output 的参数也加上去 -fflags nobuffer.
flv.js enableStashBuffer: false 才对,忘记改了 |
15
yangheng4922 OP @SongGG3 #14 改了一下 差不多延时控制在 一秒左右
|
16
yangheng4922 OP @SongGG3 #14 我查了文档说是可以通过设置 video.currentTime = this.player.buffered.end(0) 来清除延迟
是可以 但是 视频会一卡一卡的 |
17
lifefriend 2020-07-30 10:47:44 +08:00
@yangheng4922 怎么做到 1s 延迟的。我按照 lz 给出的代码,延迟在 5s 。
|