目次
2.1 まず、Haikang の Web プラグインをインストールします。フロントエンドの vue3 コードは次のとおりです。
1. バックエンド
1.1 依存関係のインポート
<dependency>
<groupId>com.hikvision.ga</groupId>
<artifactId>artemis-http-client</artifactId>
<version>1.1.3</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.51</version>
</dependency>
1.2 コード戦闘
新しい ArtemisPostTest クラスを作成します。コードは次のとおりです。認証情報を設定し、ArtemisConfig のホスト、appKey(AK)、appSecret(SK) を設定します。インターフェースのURLを設定します。.インターフェイス入力パラメータを設定します。インターフェイス呼び出し。 doPostStringArtemis メソッド (このメソッドは内部でログイン認証ロジックを実装します) を呼び出し、インターフェイス URL、インターフェイス入力パラメーター、データ送信タイプ、その他の情報を渡して、インターフェイス呼び出しを完了します。
public class ArtemisPostTest {
static {
ArtemisConfig.host = "";// 代理API网关nginx服务器ip端口
ArtemisConfig.appKey = "";// 秘钥appkey
ArtemisConfig.appSecret = "";// 秘钥appSecret
}
/**
* 能力开放平台的网站路径
* TODO 路径不用修改,就是/artemis
*/
private static final String ARTEMIS_PATH = "/artemis";
public static String path="";
public static JSONObject jsonBody=new JSONObject();
/**
* 调用POST请求类型(application/json)接口,这里以入侵报警事件日志为例
* https://open.hikvision.com/docs/918519baf9904844a2b608e558b21bb6#e6798840
*
* @return
*/
public static String callPostStringApi(){
/**
* http://10.33.47.50/artemis/api/scpms/v1/eventLogs/searches
* 根据API文档可以看出来,这是一个POST请求的Rest接口,而且传入的参数值为一个json
* ArtemisHttpUtil工具类提供了doPostStringArtemis这个函数,一共六个参数在文档里写明其中的意思,因为接口是https,
* 所以第一个参数path是一个hashmap类型,请put一个key-value,query为传入的参数,body为传入的json数据
* 传入的contentType为application/json,accept不指定为null
* header没有额外参数可不传,指定为null
*
*/
final String getCamsApi = ARTEMIS_PATH +ArtemisPostTest.path;
Map<String, String> path = new HashMap<String, String>(2) {
{
put("https://", getCamsApi);//根据现场环境部署确认是http还是https
}
};
String body = jsonBody.toJSONString();
String result = ArtemisHttpUtil.doPostStringArtemis(path,body,null,null,"application/json",null);// post请求application/json类型参数
return result;
}
}
新しいエンティティ クラスのカメラ コードは次のとおりです。
@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class Camera {
String cameraIndexCode;
String camereName;
String url;
}
コントローラーで呼び出します。コードは次のとおりです。
まず、ページネーションに従って監視ポイントのリストを取得します(ここでは 3 ページ目を取得し、各ページには 6 つの監視ポイントが含まれています)。
クエリ監視ポイントリストv2
インターフェースの説明
条件に応じてディレクトリ配下の権限を持つ監視ポイントのリストをクエリします。
インターフェイスのバージョン
v2
インターフェースアドレス
/api/リソース/v2/カメラ/検索
リクエストメソッド
役職
データ入稿方法
アプリケーション/json
次に、監視ポイントの一意の識別情報に従ってプレビュー URL を取得します。
インターフェースの説明
1. プラットフォームは正常に動作しており、プラットフォームには機器と監視ポイントの情報が追加されています。
2. プラットフォームには mgc ストリーミング サービスをインストールする必要があります。
3. サードパーティプラットフォームは、openAPI を通じて監視ポイントデータを取得し、独自のビジネスに従って監視ポイントナビゲーションインターフェイスを開発します。
4. このインターフェイスを呼び出してプレビュー ストリームの URL を取得します。プロトコル タイプには、hik、rtsp、rtmp、hls が含まれます。
5. オープン プラットフォームの開発キットを使用したリアルタイム プレビュー、またはリアルタイム プレビュー用の標準 GUI 再生ツールを使用します。
6. データのセキュリティを確保するため、ストリーミング URL には有効時間があり、有効時間は 5 分です。
インターフェイスのバージョン
v2
インターフェースアドレス
/api/video/v2/cameras/previewURLs
リクエストメソッド
役職
データ入稿方法
アプリケーション/json
最後に、属性を割り当てて、確立された Camera エンティティ クラスに割り当てます。
@GetMapping("/test")
public List<Camera> test(){
ArtemisPostTest.path="/api/resource/v1/cameras";
ArtemisPostTest.jsonBody.clear();
ArtemisPostTest.jsonBody.put("pageNo", 3);
ArtemisPostTest.jsonBody.put("pageSize", 6);
String StringeResult = ArtemisPostTest.callPostStringApi();
JSONObject result = (JSONObject) JSONObject.parse(StringeResult);
String data = result.get("data").toString();
JSONObject resultdata = (JSONObject) JSONObject.parse(data);
JSONArray list = resultdata.getJSONArray("list");
// System.out.println("StringeResult结果示例: "+JSONObject.toJSON(StringeResult));
// callPostImgStringApi();
ArtemisPostTest.path="/api/video/v2/cameras/previewURLs";
List<Camera> cameraList=new ArrayList<>();
for (Object i : list) {
Camera camera=new Camera();
JSONObject jsonObject = (JSONObject) JSONObject.parse(i.toString());
String cameraIndexCode = jsonObject.get("cameraIndexCode").toString();
String cameraName = jsonObject.get("cameraName").toString();
ArtemisPostTest.jsonBody.clear();
ArtemisPostTest.jsonBody.put("cameraIndexCode",cameraIndexCode);
ArtemisPostTest.jsonBody.put("protocol","rtsp");
String m = ArtemisPostTest.callPostStringApi();
JSONObject jsonObject1 = (JSONObject) JSONObject.parse(m);
JSONObject data1 = (JSONObject) jsonObject1.get("data");
String url = data1.get("url").toString();
camera.setCameraIndexCode(cameraIndexCode).setCamereName(cameraName).setUrl(url);
cameraList.add(camera);
}
return cameraList;
}
2. フロントエンド
2.1 まず、Haikang の Web プラグインをインストールします。フロントエンドの vue3 コードは次のとおりです。
<template>
<div style="display: flex;flex-direction: row;flex-wrap: wrap">
<div v-for="item in state.list">
<el-button @click="go(item.cameraIndexCode)">预览{
{item.camereName}}</el-button>
</div>
</div>
<div class="main" ref="playWndBox">
<div
id="playWnd"
class="playWnd"
:style="{
height: playWndHeight + 'px',
width: playWndWidth + 'px',
}"
></div>
</div>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount, getCurrentInstance, nextTick,reactive } from 'vue'
import axios from "../utils/axios.js"
const playWndBox = ref(null)
let playWndHeight = ref('')
let playWndWidth = ref('')
let pubKey = ref('')
let oWebControl = ref(null)
let objData = ref({
appkey: "", //海康提供的appkey
ip: "", //海康提供的ip
secret: "", //海康提供的secret
port: 443,
playMode: 0, // 0 预览 1回放
layout: "1x1", //页面展示的模块数【16】
})
const go=(data)=>{
previewVideo(data)
}
const state=reactive({
list:[]
})
const load=()=>{
axios.get("/test").then(res=>{
state.list=res
console.log(res)
})
}
load()
onMounted(() => {
// 获取页面的实例对象
const pageInstance = getCurrentInstance();
// 获取dom节点对象
const tagDomObj = pageInstance.refs.playWndBox;
playWndHeight.value = tagDomObj.clientHeight;
playWndWidth.value = tagDomObj.clientWidth;
// 监听scroll事件,使插件窗口尺寸跟随DIV窗口变化
window.addEventListener("scroll", () => {
console.log(5);
// return
if (oWebControl.value != null) {
oWebControl.JS_Resize(
tagDomObj.clientWidth,
tagDomObj.clientHeight
);
this.setWndCover();
}
});
// 监听resize事件,使插件窗口尺寸跟随DIV窗口变化
window.addEventListener("resize", (e) => {
console.log(0);
if (oWebControl.value != null) {
oWebControl.JS_Resize(
tagDomObj.clientWidth,
tagDomObj.clientHeight
);
this.setWndCover();
}
});
// 初始化播放器插件
nextTick(() => {
initPlugin();
})
})
onBeforeUnmount(() => {
if (oWebControl.value != null) {
// 先让窗口隐藏,规避可能的插件窗口滞后于浏览器消失问题
oWebControl.JS_HideWnd();
// 销毁当前播放的视频
oWebControl.JS_RequestInterface({ funcName: "destroyWnd" });
// 断开与插件服务连接
oWebControl.JS_Disconnect();
}
})
const initPlugin = () => {
oWebControl = new WebControl({
szPluginContainer: "playWnd", // 指定容器id
iServicePortStart: 15900, // 指定起止端口号,建议使用该值
iServicePortEnd: 15900,
szClassId: "23BF3B0A-2C56-4D97-9C03-0CB103AA8F11", // 用于IE10使用ActiveX的clsid
cbConnectSuccess: () => {
// 创建WebControl实例成功
oWebControl
.JS_StartService("window", {
// WebControl实例创建成功后需要启动服务
// 值"./VideoPluginConnect.dll"写死
dllPath: "./VideoPluginConnect.dll",
})
.then(
function () {
// 设置消息回调
oWebControl.JS_SetWindowControlCallback({
// cbIntegrationCallBack: cbIntegrationCallBack,
});
//JS_CreateWnd创建视频播放窗口,宽高可设定
oWebControl
.JS_CreateWnd("playWnd", 1152, 581, { bEmbed: true })//这一部分很重要,两个参数为你盒子的宽高,这样是写死是防止组件加载之前出现白屏;bEmbed: true 防止窗口闪烁
.then(function () {
// 创建播放实例成功后初始化
init();
});
},
function () {
// 启动插件服务失败
}
);
},
// 创建WebControl实例失败
cbConnectError: function () {
// 这里写创建WebControl实例失败时的处理步骤,下面的代码仅做参看,具体实现步骤根据个人需求进行编写!!!!!!!!
// console.log(0);
// oWebControl.value = null;
// // 程序未启动时执行error函数,采用wakeup来启动程序
// window.WebControl.JS_WakeUp("VideoWebPlugin://");
// initCount++;
// if (initCount < 3) {
// setTimeout(function () {
// initPlugin();
// }, 3000);
// } else {
// setTimeout(function () {
// setTimeout(function () {
// $router.push('/home/PlugDown')
// }, 4000)
// }, 4000)
// }
},
cbConnectClose: () => {
// 异常断开:bNormalClose = false
// JS_Disconnect正常断开:bNormalClose = true
// console.log("cbConnectClose");
oWebControl.value = null;
},
});
// oWebControl.JS_CuttingPartWindow(500, 500, 500, 500);
}
// 初始化
const init = (callback) => {
getPubKey(() => {
let appkey = objData.value.appkey; //综合安防管理平台提供的appkey,必填
let secret = setEncrypt(objData.value.secret); //综合安防管理平台提供的secret,必填
let ip = objData.value.ip; //综合安防管理平台IP地址,必填
let playMode = objData.value.playMode; //初始播放模式:0-预览,1-回放
let port = objData.value.port; //综合安防管理平台端口,若启用HTTPS协议,默认443
let snapDir = "D:\\SnapDir"; //抓图存储路径
let videoDir = "D:\\VideoDir"; //紧急录像或录像剪辑存储路径
let layout = objData.value.layout; //playMode指定模式的布局
let enableHTTPS = 1; //是否启用HTTPS协议与综合安防管理平台交互,这里总是填1
let encryptedFields = "secret"; //加密字段,默认加密领域为secret
let showToolbar = 1; //是否显示工具栏,0-不显示,非0-显示
let showSmart = 0; //是否显示移动框线框,0-不显示,非0-显示
let buttonIDs =
"0,16,256,257,258,259,260,512,513,514,515,516,517,768,769"; //自定义工具条按钮
// var toolBarButtonIDs = "2049,2304" // 工具栏上自定义按钮
oWebControl
.JS_RequestInterface({
funcName: "init",
argument: JSON.stringify({
appkey: appkey, //API网关提供的appkey
secret: secret, //API网关提供的secret
ip: ip, //API网关IP地址
playMode: playMode, //播放模式(决定显示预览还是回放界面)
port: port, //端口
snapDir: snapDir, //抓图存储路径
videoDir: videoDir, //紧急录像或录像剪辑存储路径
layout: layout, //布局
enableHTTPS: enableHTTPS, //是否启用HTTPS协议
encryptedFields: encryptedFields, //加密字段
showToolbar: showToolbar, //是否显示工具栏
showSmart: showSmart, //是否显示智能信息
buttonIDs, //自定义工具条按钮
}),
})
.then(function (oData) {
oWebControl.JS_Resize(playWndWidth.value, playWndHeight.value); // 初始化后resize一次,规避firefox下首次显示窗口后插件窗口未与DIV窗口重合问题
if (callback) {
callback();
}
// 隐藏
// oWebControl.JS_HideWnd()
});
});
}
// RSA 加密
let setEncrypt = (value) => {
let encrypt = new window.JSEncrypt();
encrypt.setPublicKey(pubKey);
return encrypt.encrypt(value);
}
// 获取公钥
const getPubKey = (callback) => {
oWebControl
.JS_RequestInterface({
funcName: "getRSAPubKey",
argument: JSON.stringify({
keyLength: 1024,
}),
})
.then(function (oData) {
if (oData.responseMsg.data) {
pubKey = oData.responseMsg.data;
callback();
}
});
}
// 调用这个函数可进行视频播放
// 视频预览功能
const previewVideo = (data) => {
let cameraIndexCode = data; // 获取输入的监控点编号值,必填
let streamMode = 0; // 主子码流标识:0-主码流,1-子码流
let transMode = 1; // 传输协议:0-UDP,1-TCP
let gpuMode = 0; // 是否启用GPU硬解,0-不启用,1-启用
let wndId = -1; // 播放窗口序号(在2x2以上布局下可指定播放窗口)
oWebControl.JS_RequestInterface({
funcName: "startPreview",
argument: JSON.stringify({
cameraIndexCode: cameraIndexCode, // 监控点编号
streamMode: streamMode, // 主子码流标识
transMode: transMode, // 传输协议
gpuMode: gpuMode, // 是否开启GPU硬解
wndId: wndId, // 可指定播放窗口
}),
})
.then(function () {
oWebControl.JS_SetWindowControlCallback({
});
});
}
</script>
<style scoped>
.main {
position: fixed;
top: 50%;
left: 20%;
transform: translateY(-50%);
width: 60vw;
height: 60vh;
margin: auto;
background-color: #ccc;
}
</style>