海康威视rtsp取流地址(海康威视设置教程)

RTSP视频流显示(海康威视)VLCSDK(C++)ffmpeg+Nginx本文目的主要是想要在html上实时显示海康威视的摄像头数据,笔者尝试了如下三种方式:VLCSDK(C++)ffmpeg+Nginx下面分别说说通过这几种方式如何实现在web页面上显示。VLC填的地址就是摄像头RTSP视频流地址,然后点串流:左上角是这样的说明就已经在转换了:网页显示注意…

大家好,又见面了,我是你们的朋友全栈君。

本文目的主要是想要实时显示海康威视的摄像头数据,笔者尝试了如下几种方式(部分未做完):

  • VLC
  • SDK(C++)
  • ffmpeg+Nginx
  • ffmpeg直接解码RTSP
  • AppEmit
  • WebComponentsKit插件

VLC

如果使用插件需要注意谷歌浏览器版本,本文是在官网下载的软件,下载下来安装并运行:
在这里插入图片描述
填的地址就是摄像头RTSP视频流地址,然后点串流:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
左上角是这样的说明就已经在转换了:
在这里插入图片描述

网页显示

注意资源地址,同一局域网下的要访问就需要把localhost改为转换软件运行电脑的ip地址:

<!DOCTYPE html>
<html lang="en">
<head>
	<title>Video</title>
</head>
<body>
	<video src="http://localhost:8080/test" width="350px" height="250px" controls="controls">
		不支持
	</video>
</body>
</html>

在这里插入图片描述
这种方式转换多路的时候,时间越久延迟会越大,实际运用操作起来比较麻烦。

VLC-Qt库

在知道视频地址的情况下可以使用插件库来解码视频,到官网下载需要的库文件:
在这里插入图片描述
下载完成后解压出来有如下3个文件夹:
在这里插入图片描述

  • include:包含了所需的头文件
  • lib:包含所需的 lib 文件
  • bin:包含了所需的 dll 文件(动态库及插件)
    新建Qt工程:
    在这里插入图片描述
    在.pro文件中添加库所在路径
    在这里插入图片描述
    布局文件如下:
    在这里插入图片描述
    mainWindow.h文件如下:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QFileDialog>
#include <QInputDialog>
#include <VLCQtCore/Common.h>
#include <VLCQtCore/Instance.h>
#include <VLCQtCore/Media.h>
#include <VLCQtCore/MediaPlayer.h>

QT_BEGIN_NAMESPACE
namespace Ui { 
    class MainWindow; }
QT_END_NAMESPACE

class VlcInstance;
class VlcMedia;
class VlcMediaPlayer;

class MainWindow : public QMainWindow
{ 
   
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void openLocal();
    void openUrl();

private:
    Ui::MainWindow *ui;

    VlcInstance *_instance;
    VlcMedia *_media;
    VlcMediaPlayer *_player;

};
#endif // MAINWINDOW_H

mainWindow.c文件如下:

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{ 
   
    ui->setupUi(this);

    _instance = new VlcInstance(VlcCommon::args(), this);
    _player = new VlcMediaPlayer(_instance);
    _player->setVideoWidget(ui->video);
    ui->video->setMediaPlayer(_player);
    ui->volume->setMediaPlayer(_player);
    ui->volume->setVolume(50);
    ui->seek->setMediaPlayer(_player);

    connect(ui->openLocal, &QPushButton::clicked, this, &MainWindow::openLocal);
    connect(ui->openUrl, &QPushButton::clicked, this, &MainWindow::openUrl);
    connect(ui->stop, &QPushButton::clicked, _player, &VlcMediaPlayer::stop);
}

void MainWindow::openLocal()
{ 
   
    QString file =
            QFileDialog::getOpenFileName(this, tr("Open file"),
                                         QDir::homePath(),
                                         tr("Multimedia files(*)"));

    if (file.isEmpty())
        return;

    _media = new VlcMedia(file, true, _instance);

    _player->open(_media);
}

void MainWindow::openUrl()
{ 
   
    QString url =
            QInputDialog::getText(this, tr("Open Url"), tr("Enter the URL you want to play"));

    if (url.isEmpty())
        return;

    _media = new VlcMedia(url, _instance);

    _player->open(_media);
}


MainWindow::~MainWindow()
{ 
   
    delete _player;
    delete _media;
    delete _instance;
    delete ui;
}

使用发布版编译应用,程序会运行失败:
在这里插入图片描述
把下载的bin文件夹下所有文件复制到exe所在路径后再次编译运行即可:
在这里插入图片描述
在这里插入图片描述
这种方式不适合web端

SDK(C++)

本文使用环境如下:

  • 操作系统:win10 64位
  • Qt版本: 5.13.0
  • 编译器版本:mingw73_64

SDK下载。

一定要注意版本。
在这里插入图片描述

编写应用

  1. 下载SDK下来解压,复制如下需要的文件到工程:
    在这里插入图片描述
    改名为:
    在这里插入图片描述
  2. 然后在.pro中添加库路径,:
LIBS+=$$PWD/libs/HCCore.lib
LIBS+=$$PWD/libs/HCNetSDK.lib
LIBS+=$$PWD/libs/GdiPlus.lib
LIBS+=$$PWD/libs/PlayCtrl.lib

LIBS+=$$PWD/libs/HCNetSDKCom/HCAlarm.lib
LIBS+=$$PWD/libs/HCNetSDKCom/HCGeneralCfgMgr.lib
LIBS+=$$PWD/libs/HCNetSDKCom/HCPreview.lib

添加头文件并包含:

#include <windows.h>
#include <head/HCNetSDK.h>

在这里插入图片描述
3. 再把库文件夹中所有dll文件放到编译后exe所在路径(有些用不上,但是全部找出来添加不会有问题):
在这里插入图片描述
4. 然后开始调用函数初始化:

	// 初始化
	bool isok = NET_DVR_Init();
	if(isok == false)
	{ 
   
	    qDebug() << "NET_DVR_Init error;error number is " <<NET_DVR_GetLastError();
	    return;
	}
	//设置连接时间与重连时间
	NET_DVR_SetConnectTime(2000, 1);
	NET_DVR_SetReconnect(10000, true);

点击按钮开始连接(布局中只有一个名为faceRecognition的label和名为connectFaceRecognition的按钮):

int faceRecognitionRealPlayHandle = 0;
int faceRecognitionUserID = 0;

    if(ui->connectFaceRecognition->text() =="连接"){ 
   
        NET_DVR_DEVICEINFO_V30 deviceInfoTmp;
	
	// 摄像头IP,用户名和密码
        faceRecognitionUserID = NET_DVR_Login_V30("192.168.31.168",8000,"admin","chuanghai2017",&deviceInfoTmp);

        if(faceRecognitionUserID<0)
        { 
   
            errorCode = NET_DVR_GetLastError();
            QMessageBox::warning(NULL,"提示",QString("摄像头登陆失败! 错误码:%1").arg(errorCode));
            return;
        }

        //启动预览
        NET_DVR_PREVIEWINFO struPlayInfo;
        struPlayInfo.hPlayWnd = (HWND)ui->faceRecognition->winId();      //设置获取窗口句柄 需要 SDK 解码时句柄设为有效值,仅取流不解码时可设为空
        struPlayInfo.lChannel = 1;       //预览通道号
        struPlayInfo.dwStreamType = 0;      //0-主码流,1-子码流,2-码流 3,3-码流 4,以此类推
        struPlayInfo.dwLinkMode = 0;      //0- TCP 方式,1- UDP 方式,2- 多播方式,3- RTP 方式,4-RTP/RTSP,5-RSTP/HTTP
        struPlayInfo.bBlocked = 1;      //0- 非阻塞取流,1- 阻塞取流
        struPlayInfo.dwDisplayBufNum = 15; //播放库播放缓冲区最大缓冲帧数
        faceRecognitionRealPlayHandle = NET_DVR_RealPlay_V40(faceRecognitionUserID, &struPlayInfo, NULL, NULL);
        if(faceRecognitionRealPlayHandle <0)
        { 
   
            errorCode = NET_DVR_GetLastError();
            QMessageBox::warning(NULL,"提示",QString("摄像头播放失败! 错误码:%1").arg(errorCode));
            NET_DVR_Logout(faceRecognitionUserID);
        }else{ 
   
            ui->connectFaceRecognition->setText("断开");
        }
    }else{ 
   
        //关闭预览
        NET_DVR_StopRealPlay(faceRecognitionRealPlayHandle);
        //注销用户
        NET_DVR_Logout(faceRecognitionUserID);
        ui->connectFaceRecognition->setText("连接");
    }

在这里插入图片描述
这种方式不适合web端

ffmpeg+Nginx

ffmpeg安装比较简单,下载下来把bin目录配置到环境变量,就OK了。
在这里插入图片描述
先运行nginx.exe(需要是已经集成rtmp模块的):
在这里插入图片描述
再打开cmd输入如下并回车:

ffmpeg -i "rtsp://admin:wls771102@192.168.14.175:554/h265/ch1/main/av_stream" -f flv -r 25 -s 640x360 -an rtmp://localhost:1935/live/room

看到这样的状态就可以访问rtmp://localhost:1935/live/room显示图像,不过需要浏览器支持rtmp
在这里插入图片描述
这种方式丢帧明显,图像模糊。

直接使用ffmpeg解码视频

这里对这个demo作者表示感谢,写得确实已经很精简了,也就不说了,作者提到的关闭Shadow build:
在这里插入图片描述
在测试中发现有时候显示会有一半模糊具体原因还不太清除:
在这里插入图片描述

AppEmit

传送门
下载解压后,尝试运行demo获取rtsp视频流:
在这里插入图片描述
依次点击1、3即可看到画面,2位置的输入框需要按规则输入包含rtsp视频流地址信息的json格式描述,页面中列举了简单的测试案例:
在这里插入图片描述
主要代码提取出来:

<!DOCTYPE html>  <!-- manifest="/websocket.appcache"-->
<html >
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    <title> rtsp demo</title>  
    <script type="text/javascript"> </script>
   <style type="text/css"> .Appboxs { 
      margin-top:10px; display: -webkit-box; display: -moz-box; display: -ms-flexbox; display: -webkit-flex;display: flex; display: box; display: flexbox; justify-content:space-around; } </style>  
</head>
<body >

<div class="container">
<input type="text" class="form-control" size="50" style="margin-bottom:3px;" id="input_url" value="ws://localhost:80/appemit?cid=00000-1&sid=1&flag=1" />
<button type="button" id="btn_Flash" onclick="init_App()" >初始化websocket(第一步)</button> 
    <div >  
		<div style="font-size:10px">libvlc:   	 	
		
		<!--双视频源 [{"emit":"open","Obj":"libvlc","AppType":1,"pos":1,"AppId":1,"par":{ "mrl":"rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov","localFile":0},"par0":{"fullscreen":1,"volume":70,"autoplay":1,"controls":1 }},{"emit":"open","Obj":"libvlc","AppType":1,"pos":1,"AppId":2,"par":{ "engine":["--subsdec-encoding=GB18030", "--freetype-font=Microsoft JhengHei","--no-snapshot-preview","-I","dummy" ,"--ignore-config"],"mrl":"rtsp://192.168.161.224/1/h264major","localFile":0},"par0":{"fullscreen":true,"volume":70,"autoplay":true,"controls":true ,"snapPath":"/file/snap/" ,"snapFormat":".bmp","snapRBUTTONDBLCLK":1,"snapWidth":0,"snapHeight":0 }}]-->
		
		<!--单视频源 {"emit":"open","Obj":"libvlc","AppType":1,"pos":1,"AppId":1,"par":{ "mrl":"rtsp://192.168.161.224/1/h264major","localFile":0},"par0":{"fullscreen":1,"volume":70,"autoplay":1,"controls":1,"bgcolor":"2A2937"}}-->
			<input type="text" class="form-control" size="150" style="margin-bottom:3px;" id="input_par" value=' [{ 
    "emit":"open","Obj":"libvlc","AppType":1,"pos":1,"AppId":1,"par":{ "mrl":"rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov","localFile":0},"par0":{ 
    "fullscreen":1,"volume":70,"autoplay":1,"controls":1 }},{ 
    "emit":"open","Obj":"libvlc","AppType":1,"pos":1,"AppId":2,"par":{ "engine":["--subsdec-encoding=GB18030", "--freetype-font=Microsoft JhengHei","--no-snapshot-preview","-I","dummy" ,"--ignore-config"],"mrl":"rtsp://192.168.161.224/1/h264major","localFile":0},"par0":{ 
    "fullscreen":true,"volume":70,"autoplay":true,"controls":true ,"snapPath":"/file/snap/" ,"snapFormat":".bmp","snapRBUTTONDBLCLK":1,"snapWidth":0,"snapHeight":0 }}]'/>
			<button type="button" id="btn_1" onclick="input_App() " >开始(第二步)</button>
		</div>      
	</div>
     <div class="Appboxs" >
		<!-- textarea或者改为div 都可以,绑定嵌入APP的位置, AppEmbed 要一致。如果要跟随浏览器变化大小,设置相对%比例即可-->
 		<div id="AppEmbed1" style="border: solid 1px #F0F0F0; min-width:30px;min-height:20px;width:400px;height:360px" ></div>
		<div id="AppEmbed2" style="border: solid 1px #F0F0F0;min-width:30px;min-height:20px;width:400px;height:360px" ></div>   
	</div>
<!--<script type="text/javascript" src="https://cdn.bootcss.com/pako/1.0.11/pako.min.js"></script> 如果使用Gzip压缩解压数据,则需要引入-->
  <script type="text/javascript" src="AppEmit_1.2_min.js"></script>
<script> //init_App(); //载入页面运行  var init_App=function(){ 
      AE.InitApp(document.getElementById('input_url').value); } var input_App= function(Jdata){ 
      //回调的数据Jdata var ReqPar0={ 
     }; ReqPar0=JSON.parse(document.getElementById("input_par").value); // AE.OpenApp(ReqPar); //执行文本框里的内容 AE.OpenApp(ReqPar0); } </script>
</body>
</html>

WebComponentsKit插件

测试文件下载地址,在nginx-1.10.2\www\hik\codebase下有WebComponentsKit插件,需要先安装。
在这里插入图片描述
nginx的配置文件中如下两部分必须:
在这里插入图片描述

#websocket相关配置
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;


location ~ /ISAPI|SDK/ {
	if ($http_cookie ~ "webVideoCtrlProxy=(.+)") {
	proxy_pass http://$cookie_webVideoCtrlProxy;
	break;
	}
}
location ^~ /webSocketVideoCtrlProxy {
	#web socket
	proxy_http_version 1.1;
	proxy_set_header Upgrade $http_upgrade;
	proxy_set_header Connection "upgrade";
	proxy_set_header Host $host;

	if ($http_cookie ~ "webVideoCtrlProxyWs=(.+)") {
	proxy_pass http://$cookie_webVideoCtrlProxyWs/$cookie_webVideoCtrlProxyWsChannel?$args;
	break;
	}
	if ($http_cookie ~ "webVideoCtrlProxyWss=(.+)") {
	proxy_pass http://$cookie_webVideoCtrlProxyWss/$cookie_webVideoCtrlProxyWsChannel?$args;
	break;
	}
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/126506.html原文链接:https://javaforall.net

(2)
上一篇 2022年4月17日 下午6:40
下一篇 2022年4月17日 下午6:40


相关推荐

  • springmvc之@ResponseBody 和 @RequestBody 注解的区别

    springmvc之@ResponseBody 和 @RequestBody 注解的区别springmvc之@ResponseBody 和 @RequestBody 注解的区别

    2022年4月24日
    44
  • 2021 前端 VUE 面试题总汇

    2021 前端 VUE 面试题总汇一 vue 面试题 1 vue 的生命周期 beforeCreate 实例初始化之后 数据观测和事件配置之前调用 组件的选项对象还没有创建 el 挂载和 data 都没有初始化 无法访问方法和数据 created 实例创建完成之后调用 已经完成了数据观测 属性方法的运算 watch event 事件回调 data 数据初始化已经完成 el 挂载还没有开始 beforeMount 挂载之前调用 el 初始化已经完成 vdom 已经完成 data 和模板的结合生成 html 但是还没有挂载到 html 页面里 mounted 挂载

    2026年3月16日
    2
  • mssql注入与绕过

    0x00前言上篇文章写了mssql的查询方式与mssql和mysql的区别。在注入当中也是有些区别的。下面直接来看到几种mssql注入的方法与特性,绕过方式。因为mssql加aspx的站懒得搭建

    2021年12月11日
    55
  • 科大讯飞股份有限公司副总裁娄超:AI为笔、文旅为卷,星火大模型助力文旅场景的实践分享

    科大讯飞股份有限公司副总裁娄超:AI为笔、文旅为卷,星火大模型助力文旅场景的实践分享

    2026年3月14日
    3
  • AlertDialog(对话框)详解

    AlertDialog(对话框)详解AlertDialog 可以在当前的界面上显示一个对话框 这个对话框是置顶于所有界面元素之上的 能够屏蔽掉其他控件的交互能力 因此 AlertDialog 一般是用于提示一些非常重要的内容或者警告信息 1 创建 AlertDialog 首先 我们来了解一下 AlertDialog 的大体创建顺序 与 TextView Button 这些控件稍有不同 AlertDialog 并

    2026年3月19日
    3
  • 浅析ECMP等价路由

    浅析ECMP等价路由本文转自 https blog csdn net mary article details 本人总结 过了一段时间了 回头再看看等价多路径 发现之前的想法还是有错误 首先 这个 等价 指的到底是什么 其实顾名思义是对的 这里的等价就是从某个路由器到目标地址存在多个相同最低代价的路径 这里的 相同最低代价 指的就是跳数 不涉及带宽之类的因素 上图中

    2026年3月20日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号