主頁 > .NET開發 > WEB端播放華為海康大華視頻方案

WEB端播放華為海康大華視頻方案

2022-03-13 06:07:02 .NET開發

WEB端播放華為海康大華視頻方案

類似標題:谷歌瀏覽器播放華為海康大華視頻方案

方案

以下方案相當于給需要播放視頻的WEB系統做了一個專用的瀏覽器,通過專用瀏覽器的CS客戶端組件播放視頻,當然,這個專用瀏覽器是需要安裝的
  1. 使用WPF撰寫一個客戶端程式,嵌入CefSharp瀏覽器控制元件,除了瀏覽器之外無其它界面元素,客戶端表單也沒有邊框和標題欄,如效果圖所示
  2. 瀏覽器加載WEB系統,WEB系統登錄后把Token傳給WPF客戶端,客戶端使用Token可以請求WEB系統的介面,獲取資料,
  3. WEB系統需要播放實時視頻或錄像回放時,使用nanoid.js為播放器生成一個唯一標識,計算播放器在瀏覽器中的位置、長寬,然后把播放器唯一標識、位置、長寬、攝像機設備ID集合通過JS呼叫C#方法傳給客戶端,客戶端根據位置、長寬顯示播放器組件,

說明

  1. WEB端為Vue開發的系統,WEB系統內有Tab頁,如果有子系統跳轉,或window.open,客戶端會打開新表單加載跳轉頁

效果圖

效果圖

效果圖說明

  1. 頁面為BS頁面,視頻彈窗是用layui做的,也是BS的,視頻播放是CS控制元件,WPF通過WindowsFormsHost加載的Winform控制元件播放視頻
  2. 當BS彈窗最大化、還原、移動時,通過JS呼叫C#方法更新視頻播放CS控制元件的位置、長寬
  3. BS彈窗最小化時隱藏視頻播放CS控制元件,還原時顯示
  4. BS彈窗關閉時,釋放視頻播放CS控制元件占用的資源
  5. 視頻播放CS控制元件,全屏功能正常,單視頻全屏功能正常,單視頻僅在視頻播放CS控制元件中最大化顯示功能正常

WEB端測驗頁面代碼

<!DOCTYPE html>
<html>

<head>
    <title>CefSharpDemo</title>

    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <script type="text/javascript" src="https://www.cnblogs.com/s0611163/archive/2022/03/12/jquery-1.9.1.js"></script>
    <script type="text/javascript" src="https://www.cnblogs.com/s0611163/archive/2022/03/12/nanoid.js"></script>
    <script src="https://www.cnblogs.com/s0611163/archive/2022/03/12/layui/layui.js"></script>

    <style type="text/css">
        input {
            height: 21px;
            line-height: 21px;
            border: solid 1px #666;
            outline: none;
        }
    </style>

    <script type="text/javascript">
        //測驗JS呼叫C#方法
        function testCallCSharp() {
            if (jsObjExists()) jsObj.TestCallCSharp("測驗引數123");
        }

        //測驗C#呼叫JS方法
        function testCallJs(data) {
            alert("測驗C#呼叫JS方法:" + data);
        }

        //判斷jsObj是否存在
        function jsObjExists() {
            return typeof (jsObj) != typeof (undefined);
        }

        //獲取url引數
        getQueryString = function (name) {
            var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
            var r = window.location.search.substring(1).match(reg);
            if (r != null) return decodeURIComponent(r[2]);
            return null;
        }
    </script>
</head>

<body>
    <div style="margin-bottom: 10px; font-weight: bold;">
        <span id="title"></span>
    </div>
    <div style="height: 30px;">
        <span>測驗輸入框:</span><input type="text" />
    </div>
    <div style="height: 30px; user-select: none;">
        <span id="msg" style="line-height: 30px;"></span>
    </div>
    <div style="height: 30px; user-select: none;">
        <span id="msg2" style="line-height: 30px;"></span>
    </div>

    <div style="user-select: none;">
        <input type="button" value="https://www.cnblogs.com/s0611163/archive/2022/03/12/測驗呼叫C#方法" title="測驗呼叫C#方法" onclick="testCallCSharp()" />
        <input type="button" value="https://www.cnblogs.com/s0611163/archive/2022/03/12/跳轉" title="跳轉" onclick="openNew()" />
        <input type="button" value="https://www.cnblogs.com/s0611163/archive/2022/03/12/設定Token或登錄資訊" title="設定Token或登錄資訊" onclick="setToken()" />
    </div>
    <div style="user-select: none; margin-top: 20px;">
        <input type="button" value="https://www.cnblogs.com/s0611163/archive/2022/03/12/播放單個視頻" title="播放單個視頻" onclick="playSingle()" />
        <input type="button" value="https://www.cnblogs.com/s0611163/archive/2022/03/12/播放多路視頻" title="播放多路視頻" onclick="playMulti()" />
        <input type="button" value="https://www.cnblogs.com/s0611163/archive/2022/03/12/追加播放" title="追加播放" onclick="appendToPlayMulti()" />
        <input type="button" value="https://www.cnblogs.com/s0611163/archive/2022/03/12/錄像回放" title="錄像回放" onclick="playRecord()" />
        <input type="button" value="https://www.cnblogs.com/s0611163/archive/2022/03/12/追加錄像回放" title="追加錄像回放" onclick="appendToPlayRecord()" />
    </div>
    <div style="position: absolute; float: right; top:5px;right:5px;">
        <input type="button" value="https://www.cnblogs.com/s0611163/archive/2022/03/12/關閉" title="關閉" onclick="closeApp()" />
    </div>

    <!-- 一個BS組件 -->
    <div
        style="position: absolute; float: right; top: 200px; right: 100px; width: 300px; height: 300px; background-color:#FFEE33; padding: 10px; color: #333333;">
        <span>
            這是一個BS組件,視頻能把我擋住
        </span>
        <br />
        <span style="margin-top: 100px; display: block;">
            這是一個BS組件,視頻能把我擋住
        </span>
        <br />
        <span style="margin-top: 100px; display: block;">
            這是一個BS組件,視頻能把我擋住
        </span>
    </div>

    <script type="text/javascript">
        //JS呼叫C#方法的介面,jsObj.XXX(...)
        //下面所有方法,呼叫的C#方法是首字母大寫

        let title = getQueryString("title");
        $("#title").text(title);

        //頁面加載完成時呼叫C#方法
        if (jsObjExists()) jsObj.WebPageLoaded(title);

        //跳轉
        function openNew() {
            window.open("http://localhost:8066/?title=跳轉頁");
        }

        //設定Token或登錄資訊
        function setToken() {
            if (jsObjExists()) jsObj.SetToken("這是登錄資訊或Token");
        }

        //視窗ID
        let windowIdForSingle;
        let windowIdForMulti;
        let windowIdForPlayRecord;

        //播放單個視頻
        function playSingle() {
            if (windowIdForSingle) {
                if (jsObjExists()) jsObj.ShowWindow(windowIdForSingle);
                alert("單個視頻播放視窗已存在");
                return;
            }

            let moveWindow = function () {
                if (!windowIdForSingle) return;
                let left = parseFloat($("#layui-layer" + handle).css('left').replace('px', ''));
                let top = parseFloat($("#layui-layer" + handle).css('top').replace('px', '')) + 51;
                let width = $("#layui-layer" + handle).width();
                let height = $("#layui-layer" + handle).height() - 51;
                jsObj.MoveWindow(windowIdForSingle, left, top, width, height);
            }

            let interval = setInterval(() => {
                moveWindow();
            }, 100);

            windowIdForSingle = nanoid(); //視窗ID
            let handle = layer.open({
                type: 1,
                title: '視頻',
                shadeClose: false,
                shade: false,
                maxmin: true, //開啟最大化最小化按鈕
                area: ['500px', '351px'],
                content: '<div>空白頁面</div>',
                cancel: function () {
                    if (jsObjExists()) {
                        clearInterval(interval);
                        jsObj.CloseWindow(windowIdForSingle);
                        windowIdForSingle = undefined;
                    }
                },
                min: function () {
                    if (jsObjExists()) {
                        jsObj.HideWindow(windowIdForSingle);
                    }
                },
                restore: function () {
                    if (jsObjExists()) {
                        jsObj.ShowWindow(windowIdForSingle);
                        moveWindow();
                    }
                },
                full: function () {
                    moveWindow();
                }
            });

            let left = parseFloat($("#layui-layer" + handle).css('left').replace('px', ''));
            let top = parseFloat($("#layui-layer" + handle).css('top').replace('px', '')) + 51;
            let width = 500;
            let height = 300;

            let cameraId = "BC77ACF9F04D1A48E053070C0822157A"; //攝像機設備ID

            if (jsObjExists()) jsObj.PlaySingle(left, top, width, height, windowIdForSingle, cameraId);
        }

        //播放多個視頻
        function playMulti() {
            if (windowIdForMulti) {
                if (jsObjExists()) jsObj.ShowWindow(windowIdForMulti);
                alert("多路視頻播放視窗已存在,您可以追加播放");
                return;
            }

            let moveWindow = function () {
                if (!windowIdForMulti) return;
                let left = parseFloat($("#layui-layer" + handle).css('left').replace('px', ''));
                let top = parseFloat($("#layui-layer" + handle).css('top').replace('px', '')) + 51;
                let width = $("#layui-layer" + handle).width();
                let height = $("#layui-layer" + handle).height() - 51;
                jsObj.MoveWindow(windowIdForMulti, left, top, width, height);
            }

            let interval = setInterval(() => {
                moveWindow();
            }, 100);

            windowIdForMulti = nanoid(); //視窗ID
            let handle = layer.open({
                type: 1,
                title: '視頻',
                shadeClose: false,
                shade: false,
                maxmin: true, //開啟最大化最小化按鈕
                area: ['1100px', '651px'],
                content: '<div>空白頁面</div>',
                cancel: function () {
                    if (jsObjExists()) {
                        clearInterval(interval);
                        jsObj.CloseWindow(windowIdForMulti);
                        windowIdForMulti = undefined;
                    }
                },
                min: function () {
                    if (jsObjExists()) {
                        jsObj.HideWindow(windowIdForMulti);
                    }
                },
                restore: function () {
                    if (jsObjExists()) {
                        jsObj.ShowWindow(windowIdForMulti);
                        moveWindow();
                    }
                },
                full: function () {
                    moveWindow();
                }
            });

            let left = parseFloat($("#layui-layer" + handle).css('left').replace('px', ''));
            let top = parseFloat($("#layui-layer" + handle).css('top').replace('px', '')) + 51;
            let width = 1000;
            let height = 600;
            let cameraIds = "BC77ACF9F04D1A48E053070C0822157A,BC77ACF9EFE01A48E053070C0822157A"; //攝像機設備ID

            if (jsObjExists()) jsObj.PlayMulti(left, top, width, height, windowIdForMulti, cameraIds);
        }

        //追加播放
        function appendToPlayMulti() {
            let cameraIds = "BC77ACF9EFCE1A48E053070C0822157A,BC77ACF9F0801A48E053070C0822157A"; //攝像機設備ID

            if (jsObjExists()) jsObj.AppendToPlayMulti(windowIdForMulti, cameraIds);
        }

        //錄像回放
        function playRecord() {
            layer.msg("請稍等......", { icon: 1, offset: "t" });

            if (windowIdForPlayRecord) {
                if (jsObjExists()) jsObj.ShowWindow(windowIdForPlayRecord);
                alert("視頻回放彈框已存在,您可以追加回放");
                return;
            }

            let moveWindow = function () {
                if (!windowIdForPlayRecord) return;
                let left = parseFloat($("#layui-layer" + handle).css('left').replace('px', ''));
                let top = parseFloat($("#layui-layer" + handle).css('top').replace('px', '')) + 51;
                let width = $("#layui-layer" + handle).width();
                let height = $("#layui-layer" + handle).height() - 51;
                jsObj.MoveWindow(windowIdForPlayRecord, left, top, width, height);
            }

            let interval = setInterval(() => {
                moveWindow();
            }, 100);

            windowIdForPlayRecord = nanoid(); //視窗ID
            let handle = layer.open({
                type: 1,
                title: '視頻',
                shadeClose: false,
                shade: false,
                maxmin: true, //開啟最大化最小化按鈕
                area: ['1100px', '651px'],
                content: '<div style="padding: 20px;">請稍等......</div>',
                cancel: function () {
                    if (jsObjExists()) {
                        clearInterval(interval);
                        jsObj.CloseWindow(windowIdForPlayRecord);
                        windowIdForPlayRecord = undefined;
                    }
                },
                min: function () {
                    if (jsObjExists()) {
                        jsObj.HideWindow(windowIdForPlayRecord);
                    }
                },
                restore: function () {
                    if (jsObjExists()) {
                        jsObj.ShowWindow(windowIdForPlayRecord);
                        moveWindow();
                    }
                },
                full: function () {
                    moveWindow();
                }
            });

            let left = parseFloat($("#layui-layer" + handle).css('left').replace('px', ''));
            let top = parseFloat($("#layui-layer" + handle).css('top').replace('px', '')) + 51;
            let width = 1100;
            let height = 600;

            let cameraId = "BC77ACF9F04D1A48E053070C0822157A"; //攝像機設備ID
            let startTime = "2022-03-11 15:00:00";
            let endTime = "2022-03-11 16:00:00";

            if (jsObjExists()) jsObj.PlayRecord(left, top, width, height, windowIdForPlayRecord, cameraId, startTime, endTime);
        }

        //追加錄像回放
        function appendToPlayRecord() {
            layer.msg("請稍等......", { icon: 1, offset: "t" });

            let cameraIds = "BC77ACF9EFCE1A48E053070C0822157A"; //攝像機設備ID
            let startTime = "2022-03-11 16:00:00";
            let endTime = "2022-03-11 17:00:00";

            if (jsObjExists()) jsObj.AppendToPlayRecord(windowIdForPlayRecord, cameraIds, startTime, endTime);
        }

        //關閉App
        function closeApp() {
            if (jsObjExists()) jsObj.CloseApp();
        }

    </script>
</body>

</html>

轉載請註明出處,本文鏈接:https://www.uj5u.com/net/441890.html

標籤:.NET技术

上一篇:C# CM框架下一行代碼實作多頁面管理

下一篇:C# CM框架下打造符合MVVM思想的WPF登錄表單

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • WebAPI簡介

    Web體系結構: 有三個核心:資源(resource),URL(統一資源識別符號)和表示 他們的關系是這樣的:一個資源由一個URL進行標識,HTTP客戶端使用URL定位資源,表示是從資源回傳資料,媒體型別是資源回傳的資料格式。 接下來我們說下HTTP. HTTP協議的系統是一種無狀態的方式,使用請求/ ......

    uj5u.com 2020-09-09 22:07:47 more
  • asp.net core 3.1 入口:Program.cs中的Main函式

    本文分析Program.cs 中Main()函式中代碼的運行順序分析asp.net core程式的啟動,重點不是剖析原始碼,而是理清程式開始時執行的順序。到呼叫了哪些實體,哪些法方。asp.net core 3.1 的程式入口在專案Program.cs檔案里,如下。ususing System; us ......

    uj5u.com 2020-09-09 22:07:49 more
  • asp.net網站作為websocket服務端的應用該如何寫

    最近被websocket的一個問題困擾了很久,有一個需求是在web網站中搭建websocket服務。客戶端通過網頁與服務器建立連接,然后服務器根據ip給客戶端網頁發送資訊。 其實,這個需求并不難,只是剛開始對websocket的內容不太了解。上網搜索了一下,有通過asp.net core 實作的、有 ......

    uj5u.com 2020-09-09 22:08:02 more
  • ASP.NET 開源匯入匯出庫Magicodes.IE Docker中使用

    Magicodes.IE在Docker中使用 更新歷史 2019.02.13 【Nuget】版本更新到2.0.2 【匯入】修復單列匯入的Bug,單元測驗“OneColumnImporter_Test”。問題見(https://github.com/dotnetcore/Magicodes.IE/is ......

    uj5u.com 2020-09-09 22:08:05 more
  • 在webform中使用ajax

    如果你用過Asp.net webform, 說明你也算是.NET 開發的老兵了。WEBform應該是2011 2013左右,當時還用visual studio 2005、 visual studio 2008。后來基本都用的是MVC。 如果是新開發的專案,估計沒人會用webform技術。但是有些舊版 ......

    uj5u.com 2020-09-09 22:08:50 more
  • iis添加asp.net網站,訪問提示:由于擴展配置問題而無法提供您請求的

    今天在iis服務器配置asp.net網站,遇到一個問題,記錄一下: 問題:由于擴展配置問題而無法提供您請求的頁面。如果該頁面是腳本,請添加處理程式。如果應下載檔案,請添加 MIME 映射。 WindowServer2012服務器,添加角色安裝完.netframework和iis之后,運行aspx頁面 ......

    uj5u.com 2020-09-09 22:10:00 more
  • WebAPI-處理架構

    帶著問題去思考,大家好! 問題1:HTTP請求和回傳相應的HTTP回應資訊之間發生了什么? 1:首先是最底層,托管層,位于WebAPI和底層HTTP堆疊之間 2:其次是 訊息處理程式管道層,這里比如日志和快取。OWIN的參考是將訊息處理程式管道的一些功能下移到堆疊下端的OWIN中間件了。 3:控制器處理 ......

    uj5u.com 2020-09-09 22:11:13 more
  • 微信門戶開發框架-使用指導說明書

    微信門戶應用管理系統,采用基于 MVC + Bootstrap + Ajax + Enterprise Library的技術路線,界面層采用Boostrap + Metronic組合的前端框架,資料訪問層支持Oracle、SQLServer、MySQL、PostgreSQL等資料庫。框架以MVC5,... ......

    uj5u.com 2020-09-09 22:15:18 more
  • WebAPI-HTTP編程模型

    帶著問題去思考,大家好!它是什么?它包含什么?它能干什么? 訊息 HTTP編程模型的核心就是訊息抽象,表示為:HttPRequestMessage,HttpResponseMessage.用于客戶端和服務端之間交換請求和回應訊息。 HttpMethod類包含了一組靜態屬性: private stat ......

    uj5u.com 2020-09-09 22:15:23 more
  • 部署WebApi隨筆

    一、跨域 NuGet參考Microsoft.AspNet.WebApi.Cors WebApiConfig.cs中配置: // Web API 配置和服務 config.EnableCors(new EnableCorsAttribute("*", "*", "*")); 二、清除默認回傳XML格式 ......

    uj5u.com 2020-09-09 22:15:48 more
最新发布
  • C#多執行緒學習(二) 如何操縱一個執行緒

    <a href="https://www.cnblogs.com/x-zhi/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2943582/20220801082530.png" alt="" /></...

    uj5u.com 2023-04-19 09:17:20 more
  • C#多執行緒學習(二) 如何操縱一個執行緒

    C#多執行緒學習(二) 如何操縱一個執行緒 執行緒學習第一篇:C#多執行緒學習(一) 多執行緒的相關概念 下面我們就動手來創建一個執行緒,使用Thread類創建執行緒時,只需提供執行緒入口即可。(執行緒入口使程式知道該讓這個執行緒干什么事) 在C#中,執行緒入口是通過ThreadStart代理(delegate)來提供的 ......

    uj5u.com 2023-04-19 09:16:49 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    <a href="https://www.cnblogs.com/huangxincheng/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/214741/20200614104537.png" alt="" /&g...

    uj5u.com 2023-04-18 08:39:04 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    一:背景 1. 講故事 前段時間協助訓練營里的一位朋友分析了一個程式卡死的問題,回過頭來看這個案例比較經典,這篇稍微整理一下供后來者少踩坑吧。 二:WinDbg 分析 1. 為什么會卡死 因為是表單程式,理所當然就是看主執行緒此時正在做什么? 可以用 ~0s ; k 看一下便知。 0:000> k # ......

    uj5u.com 2023-04-18 08:33:10 more
  • SignalR, No Connection with that ID,IIS

    <a href="https://www.cnblogs.com/smartstar/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/u36196.jpg" alt="" /></a>...

    uj5u.com 2023-03-30 17:21:52 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:15:33 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:13:31 more
  • C#遍歷指定檔案夾中所有檔案的3種方法

    <a href="https://www.cnblogs.com/xbhp/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/957602/20230310105611.png" alt="" /></a&...

    uj5u.com 2023-03-27 14:46:55 more
  • C#/VB.NET:如何將PDF轉為PDF/A

    <a href="https://www.cnblogs.com/Carina-baby/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2859233/20220427162558.png" alt="" />...

    uj5u.com 2023-03-27 14:46:35 more
  • 武裝你的WEBAPI-OData聚合查詢

    <a href="https://www.cnblogs.com/podolski/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/616093/20140323000327.png" alt="" /><...

    uj5u.com 2023-03-27 14:46:16 more