Skip to content

Commit 9ea8f6f

Browse files
authored
feat(HikVisionWebPlugin): add OnInitedAsync parameter (#785)
* feat: 重构组件名称 * feat: 增加 OnInitedAsync 回调方法
1 parent e67fab3 commit 9ea8f6f

4 files changed

Lines changed: 148 additions & 51 deletions

File tree

src/components/BootstrapBlazor.HikVision/Components/HikVision.razor renamed to src/components/BootstrapBlazor.HikVision/Components/HikVisionWebPlugin.razor

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
@namespace BootstrapBlazor.Components
22
@inherits BootstrapModuleComponentBase
33

4-
<div @attributes="AdditionalAttributes" class="@ClassString" id="@Id" style="@StyleString">
5-
</div>
4+
<div @attributes="AdditionalAttributes" class="@ClassString" id="@Id" style="@StyleString"></div>

src/components/BootstrapBlazor.HikVision/Components/HikVision.razor.cs renamed to src/components/BootstrapBlazor.HikVision/Components/HikVisionWebPlugin.razor.cs

Lines changed: 69 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77
namespace BootstrapBlazor.Components;
88

99
/// <summary>
10-
/// 海康威视网络摄像机组件
10+
/// 海康威视网络摄像机组件 (Websdk Plugin 插件版本)
1111
/// </summary>
12-
[JSModuleAutoLoader("./_content/BootstrapBlazor.HikVision/Components/HikVision.razor.js")]
13-
public partial class HikVision
12+
[JSModuleAutoLoader("./_content/BootstrapBlazor.HikVision/Components/HikVisionWebPlugin.razor.js", JSObjectReference = true)]
13+
public partial class HikVisionWebPlugin
1414
{
1515
/// <summary>
1616
/// 获得/设置 网络摄像机 IP 地址
@@ -54,6 +54,12 @@ public partial class HikVision
5454
[Parameter]
5555
public string? Height { get; set; }
5656

57+
/// <summary>
58+
/// 获得/设置 插件初始化完成后回调方法
59+
/// </summary>
60+
[Parameter]
61+
public Func<bool, Task> OnInitedAsync { get; set; }
62+
5763
private string? ClassString => CssBuilder.Default("bb-hik")
5864
.AddClassFromAttributes(AdditionalAttributes)
5965
.Build();
@@ -64,6 +70,21 @@ public partial class HikVision
6470
.AddStyleFromAttributes(AdditionalAttributes)
6571
.Build();
6672

73+
/// <summary>
74+
/// 获得 Websdk 插件是否初始化成功
75+
/// </summary>
76+
public bool Inited { get; private set; }
77+
78+
/// <summary>
79+
/// 获得 是否已登录
80+
/// </summary>
81+
public bool IsLogined { get; private set; }
82+
83+
/// <summary>
84+
/// 获得 是否正在实时预览
85+
/// </summary>
86+
public bool IsRealPlaying { get; private set; }
87+
6788
/// <summary>
6889
/// <inheritdoc/>
6990
/// </summary>
@@ -84,9 +105,11 @@ protected override void OnParametersSet()
84105
/// <param name="password"></param>
85106
/// <param name="loginType"></param>
86107
/// <returns></returns>
87-
public async Task Login(string ip, int port, string userName, string password, LoginType loginType = LoginType.Http)
108+
public async Task<bool> Login(string ip, int port, string userName, string password, LoginType loginType = LoginType.Http)
88109
{
89-
await InvokeVoidAsync("login", Id, ip, port, userName, password, (int)loginType);
110+
ThrowIfNotInited();
111+
IsLogined = await InvokeAsync<bool?>("login", Id, ip, port, userName, password, (int)loginType) ?? false;
112+
return IsLogined;
90113
}
91114

92115
/// <summary>
@@ -95,16 +118,23 @@ public async Task Login(string ip, int port, string userName, string password, L
95118
/// <returns></returns>
96119
public async Task Logout()
97120
{
98-
await InvokeVoidAsync("logout", Id);
121+
if (IsLogined)
122+
{
123+
await InvokeVoidAsync("logout", Id);
124+
}
125+
IsLogined = false;
99126
}
100127

101128
/// <summary>
102129
/// 开始实时预览方法
103130
/// </summary>
104131
/// <returns></returns>
105-
public async Task StartRealPlay()
132+
public async Task StartRealPlay(int streamType, int channelId)
106133
{
107-
await InvokeVoidAsync("startRealPlay", Id);
134+
if (IsLogined && !IsRealPlaying)
135+
{
136+
IsRealPlaying = await InvokeAsync<bool?>("startRealPlay", Id, streamType, channelId) ?? false;
137+
}
108138
}
109139

110140
/// <summary>
@@ -113,6 +143,36 @@ public async Task StartRealPlay()
113143
/// <returns></returns>
114144
public async Task StopRealPlay()
115145
{
116-
await InvokeVoidAsync("stopRealPlay", Id);
146+
if (IsLogined && IsRealPlaying)
147+
{
148+
var result = await InvokeAsync<bool?>("stopRealPlay", Id) ?? false;
149+
if (result)
150+
{
151+
IsRealPlaying = false;
152+
}
153+
}
154+
}
155+
156+
private void ThrowIfNotInited()
157+
{
158+
if (!Inited)
159+
{
160+
throw new InvalidOperationException("HikVision Web Plugin not inited");
161+
}
162+
}
163+
164+
/// <summary>
165+
/// 触发 <see cref="OnInitedAsync"/> 回调方法由 JavaScript 调用
166+
/// </summary>
167+
/// <returns></returns>
168+
[JSInvokable]
169+
public async Task TriggerInited(bool inited)
170+
{
171+
Inited = inited;
172+
173+
if (OnInitedAsync != null)
174+
{
175+
await OnInitedAsync(inited);
176+
}
117177
}
118178
}

src/components/BootstrapBlazor.HikVision/Components/HikVision.razor.js renamed to src/components/BootstrapBlazor.HikVision/Components/HikVisionWebPlugin.razor.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import { init as initVision, login, logout, startRealPlay, stopRealPlay, dispose as disposeVision } from '../hikvision.js';
22
import EventHandler from '../../BootstrapBlazor/modules/event-handler.js';
33

4-
export async function init(id) {
4+
export async function init(id, invoke) {
55
const el = document.getElementById(id);
66
if (el === null) {
77
return;
88
}
99

10-
await initVision(id);
10+
const inited = await initVision(id);
11+
await invoke.invokeMethodAsync('TriggerInited', inited);
1112
}
1213

1314
export { login, logout, startRealPlay, stopRealPlay }

src/components/BootstrapBlazor.HikVision/wwwroot/hikvision.js

Lines changed: 75 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,20 @@ export async function init(id) {
1111

1212
const el = document.getElementById(id);
1313
if (el === null) {
14-
return;
14+
return false;
1515
}
1616

1717
const result = await initWindow(id);
1818
if (result.inited === false) {
19-
return;
19+
return false;
2020
}
2121

2222
Data.set(id, {
23-
iWndIndex: result.iWndIndex
23+
iWndIndex: result.iWndIndex,
24+
inited: true
2425
});
26+
27+
return true;
2528
}
2629

2730
const initWindow = id => {
@@ -30,7 +33,7 @@ const initWindow = id => {
3033
bWndFull: true,
3134
iWndowType: 1,
3235
cbSelWnd: function (xmlDoc) {
33-
result.iWndIndex = getTagNameFirstValue(xmlDoc, "SelectWnd")
36+
result.iWndIndex = parseInt(getTagNameFirstValue(xmlDoc, "SelectWnd"));
3437
},
3538
cbDoubleClickWnd: function (iWndIndex, bFullScreen) {
3639

@@ -59,6 +62,14 @@ const initWindow = id => {
5962

6063
export async function login(id, ip, port, userName, password, loginType) {
6164
const vision = Data.get(id);
65+
const { inited, logined } = vision;
66+
if (inited !== true || ip.length === 0 || port <= 0 || userName.length === 0 || password.length === 0) {
67+
return false;
68+
}
69+
if (logined === true) {
70+
return true;
71+
}
72+
6273
vision.szDeviceIdentify = `${ip}_${port}`;
6374
vision.logined = null;
6475
vision.loginErrorCode = null;
@@ -84,9 +95,9 @@ export async function login(id, ip, port, userName, password, loginType) {
8495

8596
return new Promise((resolve, reject) => {
8697
const handler = setInterval(async () => {
87-
if (vision.logined !== void 0) {
98+
if (vision.logined !== null) {
8899
clearInterval(handler)
89-
resolve(vision);
100+
resolve(vision.logined);
90101
}
91102
}, 16);
92103
});
@@ -152,34 +163,27 @@ const getChannelInfo = vision => {
152163
const handler = setInterval(() => {
153164
if (analog_completed && digital_completed && zero_completed) {
154165
clearInterval(handler)
155-
resolve(vision);
166+
resolve();
156167
}
157168
}, 16);
158169
});
159170
}
160171

161-
export function logout(id) {
172+
export async function logout(id) {
162173
const vision = Data.get(id);
163-
const { szDeviceIdentify } = vision;
174+
const { szDeviceIdentify, logined } = vision;
175+
if (logined !== true) {
176+
vision.logined = false;
177+
return;
178+
}
164179

165-
let completed = null;
166-
WebVideoCtrl.I_Logout(szDeviceIdentify).then(() => {
167-
completed = true;
168-
}, () => {
169-
completed = false;
170-
});
180+
stopRealPlay(id);
171181

172-
return new Promise((resolve, reject) => {
173-
const handler = setInterval(() => {
174-
if (completed !== null) {
175-
clearInterval(handler)
176-
resolve(vision);
177-
}
178-
}, 16);
179-
});
182+
await WebVideoCtrl.I_Logout(szDeviceIdentify);
183+
vision.logined = false;
180184
}
181185

182-
export async function startRealPlay(id) {
186+
export async function startRealPlay(id, iStreamType, iChannelID) {
183187
const vision = Data.get(id);
184188
const { iWndIndex, szDeviceIdentify } = vision;
185189

@@ -188,26 +192,28 @@ export async function startRealPlay(id) {
188192

189193
const oWndInfo = WebVideoCtrl.I_GetWindowStatus(iWndIndex);
190194
const iRtspPort = vision.devicePort.iRtspPort;
191-
const iChannelID = 1;
192195
const bZeroChannel = false;
193-
const iStreamType = 1;
194-
196+
let completed = null;
195197
const startRealPlay = function () {
196198
WebVideoCtrl.I_StartRealPlay(szDeviceIdentify, {
199+
iWndIndex: iWndIndex,
197200
iStreamType: iStreamType,
198201
iChannelID: iChannelID,
199202
bZeroChannel: bZeroChannel,
200203
iPort: iRtspPort,
201204
success: function () {
202-
205+
vision.realPlaying = true;
206+
completed = true;
203207
},
204208
error: function (oError) {
205-
209+
vision.realPlaying = false;
210+
completed = false;
206211
}
207212
});
208213
};
209214

210-
if (oWndInfo != null) {
215+
console.log(oWndInfo);
216+
if (oWndInfo !== null) {
211217
WebVideoCtrl.I_Stop({
212218
success: function () {
213219
startRealPlay();
@@ -217,39 +223,70 @@ export async function startRealPlay(id) {
217223
else {
218224
startRealPlay();
219225
}
226+
227+
return new Promise((resolve, reject) => {
228+
const handler = setInterval(() => {
229+
if (completed !== null) {
230+
clearInterval(handler)
231+
resolve(completed);
232+
}
233+
}, 16);
234+
});
220235
}
221236

222237
export function stopRealPlay(id) {
223238
const vision = Data.get(id);
224-
const { iWndIndex, szDeviceIdentify } = vision;
239+
const { iWndIndex, realPlaying } = vision;
240+
241+
if (realPlaying !== true) {
242+
return true;
243+
}
225244

226245
const oWndInfo = WebVideoCtrl.I_GetWindowStatus(iWndIndex);
246+
let completed = null;
227247
if (oWndInfo !== null) {
228248
WebVideoCtrl.I_Stop({
229249
success: function () {
230-
250+
vision.realPlaying = false;
251+
completed = true;
231252
},
232253
error: function (oError) {
233-
254+
completed = false;
234255
}
235256
});
236257
}
258+
259+
return new Promise((resolve, reject) => {
260+
const handler = setInterval(() => {
261+
if (completed !== null) {
262+
clearInterval(handler)
263+
resolve(completed);
264+
}
265+
}, 16);
266+
});
237267
}
238268

239269
export function dispose(id) {
240-
stopRealPlay(id);
241-
logout(id);
270+
const vision = Data.get(id);
271+
Data.remove(id);
272+
273+
const { realPlaying, logined } = vision;
274+
if (realPlaying === true) {
275+
stopRealPlay(id);
276+
}
277+
if (logined === true) {
278+
logout(id);
279+
}
242280
WebVideoCtrl.I_DestroyPlugin();
243281

244-
Data.remove(id);
245282
}
246283

247-
const getTagNameFirstValue = (xmlDoc, tagName) => {
284+
const getTagNameFirstValue = (xmlDoc, tagName, defaultValue = '0') => {
248285
const tags = xmlDoc.getElementsByTagName(tagName);
249286
if (tags.length > 0) {
250287
return tags[0].textContent;
251288
}
252-
return null;
289+
return defaultValue;
253290
}
254291

255292
const getTagNameValues = (xmlDoc, tagName) => {

0 commit comments

Comments
 (0)