需求:将海康的监控视频集成到钉钉的微应用中播放。

1、整体实现方案

1)钉钉开放平台创建一个应用,该应用可以在钉钉手机端的工作台使用。

2)前端功能和后台接口开发完成。

3)项目发布到服务器后,将项目地址配置为该应用的访问地址,此时需要外网访问地址。

2、前端实现方案

1)首页访问时首先获取钉钉的授权码,拿到授权码获取token

2)拿到token调用监控列表接口得到监控列表

3)点击相应的监控,获取播放url,集成海康提供的h5player播放视频

3、难点步骤

3.1 获取钉钉免登授权码

参考钉钉文档,免登授权码 - 钉钉开放平台

在utils文件夹中创建一个dingding.js,将getQuthCode方法导出,在首页调用,代码如下:

// dingding.js
import * as dd from 'dingtalk-jsapi';
import { getTokenData } from '@/api/loginApi'
dd.ready(function () {
    var corpId = '';
    // 获取corpId
    var currentUrl = document.location.toString()
    let list = currentUrl.split('corpId=')
    if (list.length >1){
        for (let i=0;i<list[1].length;i++){
            if ('&#/'.includes(list[1].charAt(i))){
                break 
            }
            corpId+=list[1].charAt(i)
        }
        localStorage.setItem('corpId',corpId)
    }
});
const getQuthCode=()=>{
    //使用SDK 获取免登授权码
    return new Promise((resolve, reject)=>{
        let corpId=localStorage.getItem('corpId')
        dd.runtime.permission.requestAuthCode({
            corpId: corpId,
            onSuccess:async function  (result) {
                let code = result.code; // code即为免登授权码
                // 获取token
                let token = await getTokenData(code)
                localStorage.setItem('token', token);
                resolve()
            }
        });
    })
}
export default {
    getQuthCode
}

// 首页中的部分代码
import dd from "@/utils/dingding";
const initData = async () => {
    dd.getQuthCode().then(async (res) => {
        // some code
    })
}

需要在钉钉的环境下进行调试才能获取到免登授权码,钉钉提供多种调试方法,参考:微应用四端调试工具—网页版 - 钉钉开放平台

我用的是钉钉的四端调试能力,参考:开发者后台统一登录 - 钉钉统一身份认证

选择创建的应用,然后再免登地址中输入前端项目的运行地址,例如:http://localhost:9000?corpId=$CORPID$。地址后边加上?corpId=$CORPID$,是为了获取corpId。输入地址后,点击钉钉端内调试,即可调起钉钉的窗口。

java 海康nvr 视频下载 海康视频下载目录_java 海康nvr 视频下载

3.2 播放视频

在海康的官网中下载demo,地址:海康开放平台

java 海康nvr 视频下载 海康视频下载目录_java 海康nvr 视频下载_02

将demo中的这些文件,复制到自己的项目中。

java 海康nvr 视频下载 海康视频下载目录_vue_03

复制到public目录下,我这里单独建了一个h5player的文件夹

java 海康nvr 视频下载 海康视频下载目录_钉钉_04

在index.html中引入h5player.min.js

java 海康nvr 视频下载 海康视频下载目录_h5_05

在播放页编写代码,注意播放器的dom元素的id必须为player,完整代码如下:

<template>
    <div class="player-box">
        <!-- 此处id必须为player -->
        <div id="player"></div>
    </div>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount, computed, nextTick, watch } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { getPreviewUrl } from '@/api/monitorApi'
const IS_MOVE_DEVICE = document.body.clientWidth < 992 // 是否移动设备
const MSE_IS_SUPPORT = !!window.MediaSource // 是否支持mse
const tabActive = MSE_IS_SUPPORT ? 'mse' : 'decoder'
const mode = computed(() => {
    return tabActive === 'mse' ? 0 : 1
})
const router = useRouter()
const route = useRoute()
const currentUrl = ref('')
const getUrl = async () => {
    let code = route.query.code
    // 获取播放视频的url
    let url = await getPreviewUrl(code)
    currentUrl.value = url
    console.log('url', url)

}
const player = ref(null)
onMounted(() => {
    getUrl()
    nextTick(() => {
        createPlayer()
    })

    window.addEventListener('resize', () => {
        player.value && player.value.JS_Resize()
    })
})
onBeforeUnmount(() => {
    stopPlay()
})
watch(currentUrl, () => {
    // 得到url后播放
    console.log('change')
    realplay()
})
// 初始化播放器
const createPlayer = () => {
    player.value = new window.JSPlugin({
        szId: 'player',
        szBasePath: "/js/h5player/", // 此处配置h5player.min.js所在的文件目录
        iMaxSplit: 1,
        // iMaxSplit: 4,
        iCurrentSplit: 2,
        // iCurrentSplit: IS_MOVE_DEVICE ? 1 : 2,
        bSupporDoubleClickFull: true,
        openDebug: true,
        oStyle: {
            borderSelect: IS_MOVE_DEVICE ? '#409EFF' : '#409EFF',
        }
    })
    // 事件回调绑定
    player.value.JS_SetWindowControlCallback({
        windowEventSelect: function (iWndIndex) {  //插件选中窗口回调
            console.log('windowSelect callback: ', iWndIndex);
        },
        pluginErrorHandler: function (iWndIndex, iErrorCode, oError) {  //插件错误回调
            console.log('插件错误回调pluginError callback: ', iWndIndex, iErrorCode, oError);
            // play()
        },
        windowEventOver: function (iWndIndex) {  //鼠标移过回调
            console.log('鼠标移过回调', iWndIndex);
        },
        windowEventOut: function (iWndIndex) {  //鼠标移出回调
            //console.log(iWndIndex);
        },
        windowEventUp: function (iWndIndex) {  //鼠标mouseup事件回调
            //console.log(iWndIndex);
            console.log('鼠标mouseup事件回调')
            // fullScreen(false)
        },
        windowFullCcreenChange: function (bFull) {  //全屏切换回调
            console.log('全屏切换回调fullScreen callback: ', bFull);
            if (!bFull) {
                console.log('退出全屏')
            }
        },
        firstFrameDisplay: function (iWndIndex, iWidth, iHeight) {  //首帧显示回调
            console.log('firstFrame loaded callback: ', iWndIndex, iWidth, iHeight);
        },
        performanceLack: function () {  //性能不足回调
            console.log('performanceLack callback: ');
            stopPlay()
        }
    });
    player.value.JS_Resize(360, 260).then(
        () => {
            console.info('JS_Resize success')
        },
        (err) => {
            console.info('JS_Resize failed')
        }
    );
}
// 开始播放
const realplay = (url, index) => {
    let playURL = currentUrl.value
    let modeDefault = 0 //mode.value
    player.value.JS_Play(playURL, { playURL, modeDefault }, 0).then(
        () => {
            console.log('realplay success 播放成功')
        },
        e => {
            console.error('playerror', e)
        }
    )
}
// 停止播放
const stopPlay = () => {
    player.value.JS_StopRealPlayAll().then(() => {
        console.log('JS_StopRealPlayAll success 停止播放')
    }, err => {
        console.log('JS_StopRealPlayAll fail', err)
    })
}
// 整体全屏
const fullScreen = (type) => {
    player.value.JS_FullScreenDisplay(type).then(() => {
        console.log('JS_FullScreenDisplay success ')
    }, err => {
        console.log('JS_FullScreenDisplay fail', err)
    })
}
</script>
<style lang="scss">
.player-box {
    display: flex;
    justify-content: center;
}
</style>

3.3 发布

将前端项目和后端项目发布到服务器,在钉钉开放平台的后台配置该应用的访问地址,也就是项目的访问地址即可。