diff --git a/src/components/BootstrapBlazor.HikVision/Components/HikVision.razor b/src/components/BootstrapBlazor.HikVision/Components/HikVisionWebPlugin.razor
similarity index 79%
rename from src/components/BootstrapBlazor.HikVision/Components/HikVision.razor
rename to src/components/BootstrapBlazor.HikVision/Components/HikVisionWebPlugin.razor
index e4b02995..87b87f8e 100644
--- a/src/components/BootstrapBlazor.HikVision/Components/HikVision.razor
+++ b/src/components/BootstrapBlazor.HikVision/Components/HikVisionWebPlugin.razor
@@ -1,5 +1,4 @@
@namespace BootstrapBlazor.Components
@inherits BootstrapModuleComponentBase
-
-
+
diff --git a/src/components/BootstrapBlazor.HikVision/Components/HikVision.razor.cs b/src/components/BootstrapBlazor.HikVision/Components/HikVisionWebPlugin.razor.cs
similarity index 57%
rename from src/components/BootstrapBlazor.HikVision/Components/HikVision.razor.cs
rename to src/components/BootstrapBlazor.HikVision/Components/HikVisionWebPlugin.razor.cs
index a8fa5e3e..40d87b33 100644
--- a/src/components/BootstrapBlazor.HikVision/Components/HikVision.razor.cs
+++ b/src/components/BootstrapBlazor.HikVision/Components/HikVisionWebPlugin.razor.cs
@@ -7,10 +7,10 @@
namespace BootstrapBlazor.Components;
///
-/// 海康威视网络摄像机组件
+/// 海康威视网络摄像机组件 (Websdk Plugin 插件版本)
///
-[JSModuleAutoLoader("./_content/BootstrapBlazor.HikVision/Components/HikVision.razor.js")]
-public partial class HikVision
+[JSModuleAutoLoader("./_content/BootstrapBlazor.HikVision/Components/HikVisionWebPlugin.razor.js", JSObjectReference = true)]
+public partial class HikVisionWebPlugin
{
///
/// 获得/设置 网络摄像机 IP 地址
@@ -54,6 +54,12 @@ public partial class HikVision
[Parameter]
public string? Height { get; set; }
+ ///
+ /// 获得/设置 插件初始化完成后回调方法
+ ///
+ [Parameter]
+ public Func OnInitedAsync { get; set; }
+
private string? ClassString => CssBuilder.Default("bb-hik")
.AddClassFromAttributes(AdditionalAttributes)
.Build();
@@ -64,6 +70,21 @@ public partial class HikVision
.AddStyleFromAttributes(AdditionalAttributes)
.Build();
+ ///
+ /// 获得 Websdk 插件是否初始化成功
+ ///
+ public bool Inited { get; private set; }
+
+ ///
+ /// 获得 是否已登录
+ ///
+ public bool IsLogined { get; private set; }
+
+ ///
+ /// 获得 是否正在实时预览
+ ///
+ public bool IsRealPlaying { get; private set; }
+
///
///
///
@@ -84,9 +105,11 @@ protected override void OnParametersSet()
///
///
///
- public async Task Login(string ip, int port, string userName, string password, LoginType loginType = LoginType.Http)
+ public async Task Login(string ip, int port, string userName, string password, LoginType loginType = LoginType.Http)
{
- await InvokeVoidAsync("login", Id, ip, port, userName, password, (int)loginType);
+ ThrowIfNotInited();
+ IsLogined = await InvokeAsync("login", Id, ip, port, userName, password, (int)loginType) ?? false;
+ return IsLogined;
}
///
@@ -95,16 +118,23 @@ public async Task Login(string ip, int port, string userName, string password, L
///
public async Task Logout()
{
- await InvokeVoidAsync("logout", Id);
+ if (IsLogined)
+ {
+ await InvokeVoidAsync("logout", Id);
+ }
+ IsLogined = false;
}
///
/// 开始实时预览方法
///
///
- public async Task StartRealPlay()
+ public async Task StartRealPlay(int streamType, int channelId)
{
- await InvokeVoidAsync("startRealPlay", Id);
+ if (IsLogined && !IsRealPlaying)
+ {
+ IsRealPlaying = await InvokeAsync("startRealPlay", Id, streamType, channelId) ?? false;
+ }
}
///
@@ -113,6 +143,36 @@ public async Task StartRealPlay()
///
public async Task StopRealPlay()
{
- await InvokeVoidAsync("stopRealPlay", Id);
+ if (IsLogined && IsRealPlaying)
+ {
+ var result = await InvokeAsync("stopRealPlay", Id) ?? false;
+ if (result)
+ {
+ IsRealPlaying = false;
+ }
+ }
+ }
+
+ private void ThrowIfNotInited()
+ {
+ if (!Inited)
+ {
+ throw new InvalidOperationException("HikVision Web Plugin not inited");
+ }
+ }
+
+ ///
+ /// 触发 回调方法由 JavaScript 调用
+ ///
+ ///
+ [JSInvokable]
+ public async Task TriggerInited(bool inited)
+ {
+ Inited = inited;
+
+ if (OnInitedAsync != null)
+ {
+ await OnInitedAsync(inited);
+ }
}
}
diff --git a/src/components/BootstrapBlazor.HikVision/Components/HikVision.razor.js b/src/components/BootstrapBlazor.HikVision/Components/HikVisionWebPlugin.razor.js
similarity index 73%
rename from src/components/BootstrapBlazor.HikVision/Components/HikVision.razor.js
rename to src/components/BootstrapBlazor.HikVision/Components/HikVisionWebPlugin.razor.js
index 198f5c39..88a03384 100644
--- a/src/components/BootstrapBlazor.HikVision/Components/HikVision.razor.js
+++ b/src/components/BootstrapBlazor.HikVision/Components/HikVisionWebPlugin.razor.js
@@ -1,13 +1,14 @@
import { init as initVision, login, logout, startRealPlay, stopRealPlay, dispose as disposeVision } from '../hikvision.js';
import EventHandler from '../../BootstrapBlazor/modules/event-handler.js';
-export async function init(id) {
+export async function init(id, invoke) {
const el = document.getElementById(id);
if (el === null) {
return;
}
- await initVision(id);
+ const inited = await initVision(id);
+ await invoke.invokeMethodAsync('TriggerInited', inited);
}
export { login, logout, startRealPlay, stopRealPlay }
diff --git a/src/components/BootstrapBlazor.HikVision/wwwroot/hikvision.js b/src/components/BootstrapBlazor.HikVision/wwwroot/hikvision.js
index 6581b125..d95263af 100644
--- a/src/components/BootstrapBlazor.HikVision/wwwroot/hikvision.js
+++ b/src/components/BootstrapBlazor.HikVision/wwwroot/hikvision.js
@@ -11,17 +11,20 @@ export async function init(id) {
const el = document.getElementById(id);
if (el === null) {
- return;
+ return false;
}
const result = await initWindow(id);
if (result.inited === false) {
- return;
+ return false;
}
Data.set(id, {
- iWndIndex: result.iWndIndex
+ iWndIndex: result.iWndIndex,
+ inited: true
});
+
+ return true;
}
const initWindow = id => {
@@ -30,7 +33,7 @@ const initWindow = id => {
bWndFull: true,
iWndowType: 1,
cbSelWnd: function (xmlDoc) {
- result.iWndIndex = getTagNameFirstValue(xmlDoc, "SelectWnd")
+ result.iWndIndex = parseInt(getTagNameFirstValue(xmlDoc, "SelectWnd"));
},
cbDoubleClickWnd: function (iWndIndex, bFullScreen) {
@@ -59,6 +62,14 @@ const initWindow = id => {
export async function login(id, ip, port, userName, password, loginType) {
const vision = Data.get(id);
+ const { inited, logined } = vision;
+ if (inited !== true || ip.length === 0 || port <= 0 || userName.length === 0 || password.length === 0) {
+ return false;
+ }
+ if (logined === true) {
+ return true;
+ }
+
vision.szDeviceIdentify = `${ip}_${port}`;
vision.logined = null;
vision.loginErrorCode = null;
@@ -84,9 +95,9 @@ export async function login(id, ip, port, userName, password, loginType) {
return new Promise((resolve, reject) => {
const handler = setInterval(async () => {
- if (vision.logined !== void 0) {
+ if (vision.logined !== null) {
clearInterval(handler)
- resolve(vision);
+ resolve(vision.logined);
}
}, 16);
});
@@ -152,34 +163,27 @@ const getChannelInfo = vision => {
const handler = setInterval(() => {
if (analog_completed && digital_completed && zero_completed) {
clearInterval(handler)
- resolve(vision);
+ resolve();
}
}, 16);
});
}
-export function logout(id) {
+export async function logout(id) {
const vision = Data.get(id);
- const { szDeviceIdentify } = vision;
+ const { szDeviceIdentify, logined } = vision;
+ if (logined !== true) {
+ vision.logined = false;
+ return;
+ }
- let completed = null;
- WebVideoCtrl.I_Logout(szDeviceIdentify).then(() => {
- completed = true;
- }, () => {
- completed = false;
- });
+ stopRealPlay(id);
- return new Promise((resolve, reject) => {
- const handler = setInterval(() => {
- if (completed !== null) {
- clearInterval(handler)
- resolve(vision);
- }
- }, 16);
- });
+ await WebVideoCtrl.I_Logout(szDeviceIdentify);
+ vision.logined = false;
}
-export async function startRealPlay(id) {
+export async function startRealPlay(id, iStreamType, iChannelID) {
const vision = Data.get(id);
const { iWndIndex, szDeviceIdentify } = vision;
@@ -188,26 +192,28 @@ export async function startRealPlay(id) {
const oWndInfo = WebVideoCtrl.I_GetWindowStatus(iWndIndex);
const iRtspPort = vision.devicePort.iRtspPort;
- const iChannelID = 1;
const bZeroChannel = false;
- const iStreamType = 1;
-
+ let completed = null;
const startRealPlay = function () {
WebVideoCtrl.I_StartRealPlay(szDeviceIdentify, {
+ iWndIndex: iWndIndex,
iStreamType: iStreamType,
iChannelID: iChannelID,
bZeroChannel: bZeroChannel,
iPort: iRtspPort,
success: function () {
-
+ vision.realPlaying = true;
+ completed = true;
},
error: function (oError) {
-
+ vision.realPlaying = false;
+ completed = false;
}
});
};
- if (oWndInfo != null) {
+ console.log(oWndInfo);
+ if (oWndInfo !== null) {
WebVideoCtrl.I_Stop({
success: function () {
startRealPlay();
@@ -217,39 +223,70 @@ export async function startRealPlay(id) {
else {
startRealPlay();
}
+
+ return new Promise((resolve, reject) => {
+ const handler = setInterval(() => {
+ if (completed !== null) {
+ clearInterval(handler)
+ resolve(completed);
+ }
+ }, 16);
+ });
}
export function stopRealPlay(id) {
const vision = Data.get(id);
- const { iWndIndex, szDeviceIdentify } = vision;
+ const { iWndIndex, realPlaying } = vision;
+
+ if (realPlaying !== true) {
+ return true;
+ }
const oWndInfo = WebVideoCtrl.I_GetWindowStatus(iWndIndex);
+ let completed = null;
if (oWndInfo !== null) {
WebVideoCtrl.I_Stop({
success: function () {
-
+ vision.realPlaying = false;
+ completed = true;
},
error: function (oError) {
-
+ completed = false;
}
});
}
+
+ return new Promise((resolve, reject) => {
+ const handler = setInterval(() => {
+ if (completed !== null) {
+ clearInterval(handler)
+ resolve(completed);
+ }
+ }, 16);
+ });
}
export function dispose(id) {
- stopRealPlay(id);
- logout(id);
+ const vision = Data.get(id);
+ Data.remove(id);
+
+ const { realPlaying, logined } = vision;
+ if (realPlaying === true) {
+ stopRealPlay(id);
+ }
+ if (logined === true) {
+ logout(id);
+ }
WebVideoCtrl.I_DestroyPlugin();
- Data.remove(id);
}
-const getTagNameFirstValue = (xmlDoc, tagName) => {
+const getTagNameFirstValue = (xmlDoc, tagName, defaultValue = '0') => {
const tags = xmlDoc.getElementsByTagName(tagName);
if (tags.length > 0) {
return tags[0].textContent;
}
- return null;
+ return defaultValue;
}
const getTagNameValues = (xmlDoc, tagName) => {