海康威视监控web实时预览解决方案

海康威视摄像头都试rtsp流,web页面无法加载播放,所以就得转换成web页面可以播放的hls、rtmp等数据流来播放。

一:萤石云

使用萤石云平台,把rtsp转化成ezopen协议,然后使用组件UIKit

最佳实践 · 萤石开放平台API文档

UIKit Javascript · 萤石开放平台API文档

文档概述 · 萤石开放平台API文档

二:

使用海康威视官网插件,或无插件版

海康开放平台

三:使用安防平台预览url接口

根据不同的数据流返回不同的直播流,这里我主要用的hls的流来播放。hls取流有一个坑的就是摄像头编码得设置264.音频选择acc。

海康接口调用封装的是用php写的。

复制代码
<?php
namespace AppModel;
header('Content-type:text/html; Charset=utf-8');
date_default_timezone_set('PRC');
class Haikang
{
    public $pre_url = "https://host:443"; //安防平台故武器地址
    protected $app_key = "appkey"; // key
    protected $app_secret = "secret";
    public $time ;//时间戳
    public $content_type="application/json";//类型
    public $accept="*/*" ;//accept
    
    public $person_list_url = "/artemis/api/resource/v1/encodeDevice/get";//人员列表url
    public $equipment_view_url = "/artemis/api/video/v1/cameras/previewURLs";//获取监控点预览取流URL
    public function __construct($app_key='', $app_secret='')
    {
        if($app_key!='') $this->app_key = $app_key;
        if($app_secret!='') $this->app_secret = $app_secret;
        $this->charset = 'utf-8';
        list($msec, $sec) = explode(' ', microtime());
        $this->time = (float)sprintf('%.0f', (floatval($msec) + floatval($sec)) * 1000);
    }
    function getViewUrl($cameraIndexCode){
        //请求参数
        $postData['cameraIndexCode'] = $cameraIndexCode;
        $postData['streamType'] =0;
        $postData['protocol'] = 'hls';
        $postData['transmode'] = 1;
	$postData['videotype'] = 'h264';
        $sign = $this->get_sign($postData,$this->equipment_view_url);
        $options = array(
                CURLOPT_HTTPHEADER => array(
                    "Accept:".$this->accept,
                    "Content-Type:".$this->content_type,
                    "X-Ca-Key:".$this->app_key,
                    "X-Ca-Signature:".$sign,
                    "Date:".$this->time,
                    "X-Ca-Signature-Headers:"."x-ca-key",
                    )
            );
            
        $result = $this->curlPost($this->pre_url.$this->equipment_view_url,json_encode($postData),$options);
        return json_decode($result,true);
    }
    /**
     * 获取人员列表
     */
    function get_person_list($response){
        //请求参数
        $postData['pageNo'] = isset($response['pageNo']) ? intval($response['pageNo']):"1";
        $postData['pageSize'] = isset($response['pageSize']) ? intval($response['pageSize']):"1000";
        $sign = $this->get_sign($postData,$this->person_list_url);
        $options = array(
                CURLOPT_HTTPHEADER => array(
                    "Accept:".$this->accept,
                    "Content-Type:".$this->content_type,
                    "X-Ca-Key:".$this->app_key,
                    "X-Ca-Signature:".$sign,
                    "Date:".$this->time,
                    "X-Ca-Signature-Headers:"."x-ca-key",
                    )
            );
            
        $result = $this->curlPost($this->pre_url.$this->person_list_url,json_encode($postData),$options);
    
        return json_decode($result,true);
    }
    /**
     * 以appSecret为密钥,使用HmacSHA256算法对签名字符串生成消息摘要,对消息摘要使用BASE64算法生成签名(签名过程中的编码方式全为UTF-8)
     */
    function get_sign($postData,$url){
        $sign_str = $this->get_sign_str($postData,$url); //签名字符串
        
        $priKey=$this->app_secret;
        $sign = hash_hmac('sha256', $sign_str, $priKey,true); //生成消息摘要
        $result = base64_encode($sign);
        return $result;
    }
    function get_sign_str($postData,$url){
        
        $next = "
";
        $str = "POST".$next.$this->accept.$next.$this->content_type.$next.$this->time.$next;
        $str .= "x-ca-key:".$this->app_key.$next;
        $str .= $url;
        return $str;
    }
    public function getSignContent($params) {
        ksort($params);
        $stringToBeSigned = "";
        $i = 0;$len = count($params);
        foreach ($params as $k => $v) {
            if (false === $this->checkEmpty($v) && "@" != substr($v, 0, 1)) {
                // 转换成目标字符集
                $v = $this->characet($v, $this->charset);
                if ($i == 0) {
                    $stringToBeSigned .= "?$k" . "=" . "$v";
                }else {
                    $stringToBeSigned .= "&" . "$k" . "=" . "$v";
                }
                $i++;
            }
        }
        unset ($k, $v);
        return $stringToBeSigned;
    }
    function get_message($postData){
        $str = str_replace(array('{','}','"'),'',json_encode($postData));
        return base64_encode(md5($str));
    }
    /**
     * 校验$value是否非空
     *  if not set ,return true;
     *    if is null , return true;
     **/
    protected function checkEmpty($value) {
        if (!isset($value))
            return true;
        if ($value === null)
            return true;
        if (trim($value) === "")
            return true;
        return false;
    }
    
    /**
     * 转换字符集编码
     * @param $data
     * @param $targetCharset
     * @return string
     */
    function characet($data, $targetCharset) {
        if (!empty($data)) {
            $fileType = $this->charset;
            if (strcasecmp($fileType, $targetCharset) != 0) {
                $data = mb_convert_encoding($data, $targetCharset, $fileType);
            }
        }
        return $data;
    }
    public function curlPost($url = '', $postData = '', $options = array())
    {
        if (is_array($postData)) {
            $postData = http_build_query($postData);
        }
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30); //设置cURL允许执行的最长秒数
        if (!empty($options)) {
            curl_setopt_array($ch, $options);
        }
        //https请求 不验证证书和host
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        $data = curl_exec($ch);
        curl_close($ch);
        return $data;
    }
}

前端video-js插件就可以播放hls的视频流

四:ffpemg

下载并安装FFMPEG

随便找的一个安装教程:https://blog.csdn.net/weixin_44704985/article/details/109532224

安装后需配置到环境变量

下载并安装mediamtx

https://github.com/bluenviron/mediamtx/releases

要是打不开自己想办法

开启mediamtx

如果不进行配置文件修改,使用默认配置,双击mediamtx.exe打开执行文件

使用FFMPEG进行视频推流

打开cmd 运行以下命令

ffmpeg -re -i 你的视频.mp4 -vcodec libvpx -rtsp_transport tcp -f rtsp rtsp://127.0.0.1:8554/stream/h1

这句的含义是:输入流为你指定的视频,可以是本地的文件,也可以是海康的rtsp视频流,如

ffmpeg -re -i rtsp://admin:hik12345@10.16.4.25:554/Streaming/Channels/101 -vcodec libvpx -rtsp_transport tcp -f rtsp rtsp://127.0.0.1:8554/stream/h1

输出流是 rtsp://127.0.0.1:8554/stream

将原视频格式重新编码为libvpx(p8)格式

使用http方式播放视频

在网页中运行以下url

http://127.0.0.1:8889/stream/h1

如果不出意外现在能够进行视频播放

mediamtx部分

我们可以看见,开启软件后会对RTSP、RTMP、HLS、WebRTC、SRT这几种协议类型输入流进行监听

可以通过ffmpeg将视频推送到对应协议的端口

使用FFMPEG进行视频推流(重点)

ffmpeg -re -i 你的视频.mp4 -vcodec libvpx -rtsp_transport tcp -f rtsp rtsp://127.0.0.1:8554/stream/h1

编码时可以设置参数,vcodec:视频编码格式,acodec:音频编码格式

格式有很多,可以使用以下方式查看具体编码格式

ffmpeg -encoders

这里我把输入视频转换为libvpx格式是因为我想直接使用http方式播放视频,而WebRTC只能支持几种格式视频播放

如果你想同时推送多个相机或视频源,可以修改输出路径,如:

rtsp://127.0.0.1:8554/stream/h1

rtsp://127.0.0.1:8554/stream/h2

rtsp://127.0.0.1:8554/stream/h3

。。。

如果是需要推送其他协议视频,请参考ffmpeg的命令行说明

相关推荐
z-robot21 小时前
Nginx 配置代理
前端
用户479492835691521 小时前
Safari 中文输入法的诡异 Bug:为什么输入 @ 会变成 @@? ## 开头 做 @ 提及功能的时候,测试同学用 Safari 测出了个奇怪的问题
前端·javascript·浏览器
没有故事、有酒21 小时前
Ajax介绍
前端·ajax·okhttp
朝新_21 小时前
【SpringMVC】详解用户登录前后端交互流程:AJAX 异步通信与 Session 机制实战
前端·笔记·spring·ajax·交互·javaee
裴嘉靖21 小时前
Vue 生成 PDF 完整教程
前端·vue.js·pdf
毕设小屋vx ylw28242621 小时前
Java开发、Java Web应用、前端技术及Vue项目
java·前端·vue.js
冴羽1 天前
今日苹果 App Store 前端源码泄露,赶紧 fork 一份看看
前端·javascript·typescript
蒜香拿铁1 天前
Angular【router路由】
前端·javascript·angular.js
brzhang1 天前
读懂 MiniMax Agent 的设计逻辑,然后我复刻了一个MiniMax Agent
前端·后端·架构
西洼工作室1 天前
高效管理搜索历史:Vue持久化实践
前端·javascript·vue.js