WEB端播放華為海康大華視頻方案
類似標題:谷歌瀏覽器播放華為海康大華視頻方案
方案
以下方案相當于給需要播放視頻的WEB系統做了一個專用的瀏覽器,通過專用瀏覽器的CS客戶端組件播放視頻,當然,這個專用瀏覽器是需要安裝的
- 使用WPF撰寫一個客戶端程式,嵌入CefSharp瀏覽器控制元件,除了瀏覽器之外無其它界面元素,客戶端表單也沒有邊框和標題欄,如效果圖所示
- 瀏覽器加載WEB系統,WEB系統登錄后把Token傳給WPF客戶端,客戶端使用Token可以請求WEB系統的介面,獲取資料,
- WEB系統需要播放實時視頻或錄像回放時,使用nanoid.js為播放器生成一個唯一標識,計算播放器在瀏覽器中的位置、長寬,然后把播放器唯一標識、位置、長寬、攝像機設備ID集合通過JS呼叫C#方法傳給客戶端,客戶端根據位置、長寬顯示播放器組件,
說明
- WEB端為Vue開發的系統,WEB系統內有Tab頁,如果有子系統跳轉,或window.open,客戶端會打開新表單加載跳轉頁
效果圖
效果圖說明
- 頁面為BS頁面,視頻彈窗是用layui做的,也是BS的,視頻播放是CS控制元件,WPF通過WindowsFormsHost加載的Winform控制元件播放視頻
- 當BS彈窗最大化、還原、移動時,通過JS呼叫C#方法更新視頻播放CS控制元件的位置、長寬
- BS彈窗最小化時隱藏視頻播放CS控制元件,還原時顯示
- BS彈窗關閉時,釋放視頻播放CS控制元件占用的資源
- 視頻播放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技术
