最近在用 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 。 |