web浏览器播放rtsp视频流,海康监控API

概述

这里记录一下如何让前端播放rtsp协议的视频流

​ 项目中调用海康API,生成的视频流(hls、ws、rtmp等)通过PotPlayer播放器都无法播放,说明视频流有问题,唯独rtsp视频流可以播放。

但是浏览器本身是无法播放rtsp视频的,即使是使用videojs、flvjs等工具。

​ 网上的方案都是通过后端基于ffmpeg工具进行转码。那么我的理解是后端Node起到的是中转作用:调用ffmpeg工具对传入的rtsp流进行转码再传给前端

这里记录整个过程与出现的问题解决

准备

需要三部分的准备:

  • ffmpeg工具
  • nodeJS转码
  • 前端播放

ffmpeg安装与配置

  1. 下载ffmpeg https://ffmpeg.org/download.html

在这里插入图片描述
在这里插入图片描述

  1. 下载并解压完成后

    我这里放在 D:\DevelopSoftware\ffmpeg

  2. 配置环境变量

    我的电脑 => 属性 => 高级系统设置 => 环境变量 => Path => 添加 D:\DevelopSoftware\ffmpeg\bin

    在这里插入图片描述

  3. 打开cmd输入 ffmpeg 或者 ffmpeg -version

    出现东西就说明OK了

    如果 'ffmpeg' 不是内部或外部命令,也不是可运行的程序或批处理文件, 重启cmd窗口, 还是不行的话网上搜一下吧

    在这里插入图片描述

本节参考自 ffmpeg安装教程(windows版)

nodejs编写转码服务

先随便建个文件夹

npm i express express-ws fluent-ffmpeg websocket-stream

或者

yarn add express express-ws fluent-ffmpeg websocket-stream

新建 index.js

var express = require('express')
var expressWebSocket = require('express-ws')
var ffmpeg = require('fluent-ffmpeg')
var webSocketStream = require('websocket-stream/stream')
var WebSocket = require('websocket-stream')
var http = require('http')

ffmpeg.setFfmpegPath('ffmpeg')

// config
let rtspServerPort = 2156

function localServer() {
  let app = express()
  app.use(express.static(__dirname))
  expressWebSocket(app, null, {
    perMessageDeflate: true
  })
  // :id是动态参数, 前端调用时传递, 可以去掉
  app.ws('/rtsp/:id/', rtspRequestHandle)
  app.listen(rtspServerPort)
  console.log('express listened on port : ' + rtspServerPort)
}

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

在这里插入图片描述

前端调用转码服务

新建 demo.html

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <script src="https://cdn.bootcdn.net/ajax/libs/flv.js/1.6.2/flv.min.js"></script>
    <!--  <script src="./js/flv.min.js"></script>-->
    <style>
      body,
      center {
        padding: 0;
        margin: 0;
      }

      .v-container {
        width: 640px;
        height: 360px;
        border: solid 1px red;
      }

      video {
        width: 100%;
        height: 100%;
      }
    </style>
  </head>
  <body>
    <div class="v-container">
      <video id="player1" muted autoplay="autoplay" preload="auto" controls="controls"></video>
    </div>

    <script>
      if (flvjs.isSupported()) {
        var videoElement = document.getElementById('player1')
        var flvPlayer = flvjs.createPlayer({
          type: 'flv',
          url: 'ws://localhost:2156/rtsp/111/?url=rtsp://xxx.xxx.xxx:554/openUrl/jmQgiJi'
        })
        flvPlayer.attachMediaElement(videoElement)
        flvPlayer.load()
      }
    </script>
  </body>
</html>

这两节源自 rtsp视频服务 基于node+ffmpeg 转换为 flv 视频服务

videojs + flvjs使用

yarn add video.js flv.js videojs-flvjs-es6

import videojs from 'video.js'
import flvjs from 'flv.js'
import 'video.js/dist/video-js.css'
import 'videojs-flvjs-es6'

let myPlayer

const initVideo = (videoUrl) => {
  // videojs初始化
  myPlayer = videojs(
    document.querySelector('#videoBox'),   // video元素, vue2或vue3推荐使用ref方式
    {
      // poster: '//vjs.zencdn.net/v/oceans.png',
      autoplay: 'muted', //自动播放
      controls: true, //用户可以与之交互的控件
      loop: true, //视频一结束就重新开始
      muted: true, //默认情况下将使所有音频静音
      // aspectRatio: '16:9', //显示比率
      techOrder: ['html5', 'flvjs'], // 兼容顺序
      flvjs: {
        mediaDataSource: {
          cors: true,
          withCredentials: false,
        },
      },
      controlBar: {
        remainingTimeDisplay: {
          displayNegative: false,
        },
      },
      playbackRates: [0.5, 1, 1.5, 2],
    },
    function onPlayerReady() {
      this.on('play', function () {
        console.log('视频开始播放')
      })
      this.on('pause', function () {
        console.log('视频暂停播放')
      })
      this.on('error', function () {
        console.log('加载错误')
        isError.value = true
      })
    }
  )

  // 播放
  myPlayer.reset()
  myPlayer.src({
    src: 'ws://localhost:2156/rtsp/?url=' + videoUrl,
    type: 'video/x-flv',
  })
  // myPlayer.load('ws://localhost:2156/rtsp/1/?url=rtsp://xxxx:554/openUrl/rMYr6w0')
  myPlayer.play()
}
<video ref="videoPlayer" id="videoBox" style="width:100%;height:100%;"></video>

总结

海康平台支持多种协议的视频流,如果流无法播放,可能是设备配置或者分辨率或者… 出了问题!!

这种事情当然是让后端去处理咯,是跟厂商联调还是怎么着,关我前端啥事儿!!!把精力用到更有意义的地方才是正解,例如像我一样水一篇文章, Nice!

当然,尽量直接使用海康平台API返回的流,转码始终是下策。

感谢各大佬的文章:

rtsp视频服务 基于node+ffmpeg 转换为 flv 视频服务

ffmpeg安装教程(windows版)

要在Unity中播放海康监控视频流,您需要使用海康威视SDK中的播放器组件。以下是一些步骤,供您参考: 1. 下载并安装海康威视SDK。您可以从海康威视官网下载SDK。 2. 在Unity中创建一个新的场景,并创建一个空的游戏对象。 3. 在空的游戏对象上添加一个新的脚本组件,并将其命名为“HikVideoPlayer”。 4. 在“HikVideoPlayer”脚本中,添加以下代码: ```c# using UnityEngine; using System.Collections; using System.Runtime.InteropServices; [RequireComponent(typeof(Renderer))] public class HikVideoPlayer : MonoBehaviour { [DllImport("PlayCtrl")] private static extern bool PlayM4_GetPort(ref int nPort); [DllImport("PlayCtrl")] private static extern bool PlayM4_OpenStream(int nPort, byte[] pFileHeadBuf, int nSize, int nBufPoolSize); [DllImport("PlayCtrl")] private static extern bool PlayM4_Play(int nPort, IntPtr hWnd); [DllImport("PlayCtrl")] private static extern bool PlayM4_Stop(int nPort); [DllImport("PlayCtrl")] private static extern bool PlayM4_CloseStream(int nPort); public string ip = "192.168.1.100"; // 海康监控设备的IP地址 public int port = 8000; // 海康监控设备的端口号 public string username = "admin"; // 海康监控设备的用户名 public string password = "123456"; // 海康监控设备的密码 public int channel = 1; // 海康监控设备的通道号(默认为1) public int streamType = 1; // 海康监控设备的码流类型(主码流为0,子码流为1) public int bufSize = 1024 * 512; // 缓冲区大小 public bool playOnStart = true; // 是否在开始时自动播放视频 private int portNumber = -1; void Start() { if (playOnStart) { Play(); } } public void Play() { if (portNumber == -1) { portNumber = GetPort(); } if (portNumber != -1) { if (OpenStream()) { Play(portNumber); } } } public void Stop() { if (portNumber != -1) { Stop(portNumber); CloseStream(portNumber); portNumber = -1; } } private int GetPort() { int port = -1; PlayM4_GetPort(ref port); return port; } private bool OpenStream() { bool result = false; string url = string.Format("rtsp://{0}:{1}@{2}:{3}/cam/realmonitor?channel={4}&subtype={5}", username, password, ip, port, channel, streamType); byte[] urlBytes = System.Text.Encoding.UTF8.GetBytes(url); result = PlayM4_OpenStream(portNumber, urlBytes, urlBytes.Length, bufSize); return result; } private bool Play(int port) { bool result = false; result = PlayM4_Play(port, IntPtr.Zero); return result; } private bool Stop(int port) { bool result = false; result = PlayM4_Stop(port); return result; } private bool CloseStream(int port) { bool result = false; result = PlayM4_CloseStream(port); return result; } } ``` 5. 在Unity中的场景中,将您想要播放视频的游戏对象上添加一个新的材质,并将材质的Shader设置为“Unlit/Texture”。 6. 将材质的Texture属性设置为“HikVideoPlayer”游戏对象的Renderer组件的Texture属性。 7. 您现在可以在Unity中播放海康监控视频流了。在需要播放视频的地方,只需调用“HikVideoPlayer”脚本的“Play”方法即可。 请注意,上述代码仅是一个示例,并且可能需要根据您的具体需求进行修改。此外,在使用海康威视SDK时,请确保您已经获得了必要的许可证和授权。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值