关于 RTSP 用 FFMPEG 转 flv 在 Nodejs 中的播放延迟问题

关于 RTSP 用 FFMPEG 转 flv 在 Nodejs 中的播放延迟问题

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


18 回复

不要沉啊


有大佬遇到过这种问题么

能转成 rtmp 吗?

c 的话不知道怎么做,不过我开源了一套 java 的 rtsp-rtmp 的服务,使用开源的 javacv 框架(调用底层 ffmpeg ) 使用了转封装的技术,直接将音视频解复用,然后转封装为 flv 格式的包推出去,因为不涉及编解码 所以 cpu 内存占用率很低。延迟的话大概 1-3s ggitee 地址: https://gitee.com/banmajio/RTSPtoRTMP github: https://github.com/banmajio/RTSPtoRTMP 如果有帮助,劳烦点个 star

rtmp 最多用到年底

有没有可能直接集成个 vlc 直接取 rtsp 流?

想问下海康的视频流怎么获取的呢?同样在弄一个有监控的项目,以前没做过视频,不知道怎么在 nvr 上做二次开发。

试试 input output 添加 -fflags nobuffer -tune zerolatency

然后 flv.js 添加 enableStashBuffer: true

#8
在 ffmpeg 的配置里面添加么

#7 海康可以通过 rtsp 协议获取视频流

#8
javascript<br>ffmpeg(url)<br>.addInputOption('-rtsp_transport', 'tcp', '-buffer_size', '102400', '-fflags', 'nobuffer', '-tune', 'zerolatency')<br>

javascript<br>flvjs.createPlayer({<br> type: 'flv',<br> isLive: true,<br> url: 'ws://localhost:8888/rtsp/?url=' + this.rtsp,<br> enableStashBuffer: true // 添加行<br>})<br>

#8 是这样子么

#8
我修改了一下参数 但是还是没有明显的改善

output 的参数也加上去 -fflags nobuffer.
flv.js enableStashBuffer: false 才对,忘记改了

#14 改了一下 差不多延时控制在 一秒左右

#14 我查了文档说是可以通过设置 video.currentTime = this.player.buffered.end(0) 来清除延迟
是可以 但是 视频会一卡一卡的

怎么做到 1s 延迟的。我按照 lz 给出的代码,延迟在 5s 。

关于RTSP使用FFmpeg转FLV在Node.js中的播放延迟问题,这通常涉及到流媒体的传输、处理和播放等多个环节。以下是一些可能的解决思路和代码示例,以帮助你减少播放延迟。

  1. 优化FFmpeg转码参数: 确保FFmpeg的转码参数尽可能高效,减少不必要的处理和延迟。例如,使用-c:v copy来直接复制视频流,避免重新编码。

    ffmpeg -i rtsp://your_rtsp_stream -c:v copy -c:a aac -f flv - | node your_server.js
    
  2. 使用内存流: 在Node.js中,可以使用内存流(如stream模块)来减少I/O操作带来的延迟。

    const { spawn } = require('child_process');
    const { PassThrough } = require('stream');
    
    const ffmpeg = spawn('ffmpeg', ['-i', 'rtsp://your_rtsp_stream', '-c:v', 'copy', '-c:a', 'aac', '-f', 'flv', '-']);
    const passThrough = new PassThrough();
    
    ffmpeg.stdout.pipe(passThrough);
    
    // Now you can use `passThrough` as the source for your FLV player
    
  3. 调整播放缓冲设置: 在播放器端,调整缓冲设置以减少初始加载时间。这取决于你使用的播放器库或框架。

  4. 网络优化: 确保网络传输稳定且带宽充足,以减少因网络抖动或带宽不足导致的延迟。

综上所述,通过优化FFmpeg参数、使用内存流、调整播放缓冲设置以及进行网络优化,你可以有效减少RTSP转FLV在Node.js中的播放延迟。

回到顶部