SHO酱的Blog

SHO酱的Blog

Uni-app通过WebView加载网页文件显示海康h5player直播视频

2025-01-02
Uni-app通过WebView加载网页文件显示海康h5player直播视频

Uni-app通过WebView加载网页文件显示海康h5player直播视频

简介

海康的 ws 协议视频流在 uniapp 中使用很多方法实现,但播放效果并不理想;要么加载缓慢,要么卡顿,大多情况是根本无法播放。
网页端通过海康的官方 h5player 效果就还不错;于是把 h5player 放到 uniapp 中试一下, H5 平台是可以直接嵌入并进行播放的,但到了 Android 端就不行了。到处搜罗,最后找到了通过 html 页面调用 h5player 播放视频链接,然后通过 WebView 加载 html 文件来达到使用 h5player 播放视频流的功能。

下载需要的文件

需要分别下载h5player.js文件包uni.webview.js,其中uni.webview.js用于在 uniapp 中 WebView 与 网页程序之间的通讯。

h5player.js 文件:海康开放平台 (hikvision.com) 下载【H5视频播放器开发包】
uni.webview.js 文件:web-view | uni-app官网 (dcloud.io) 找到【uni.webview.js】下载最新版本

下载后把文件拷贝到 uniapp 项目的src/static目录下。
uniapp_h5player_01.png

HTML文件 webplayer.html

同样在src/static目录创建 webplayer.html 文件。

<html>
<head>
    <meta charset="utf-8">
    <meta name=viewportcontent="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no,minimal-ui">
    <meta name="referrer" content="no-referrer">
    <title>海康视频监控</title>
    <script src="./h5player.min.js"></script>
    <script type="text/javascript" src="../uni.webview.1.5.5.js"></script>
    <style type="text/css">
        html,
        body {
            width: 100%;
            height: 100%;
            margin: auto;
            overflow: hidden;
            background-color: #FFFFFF;
            -webkit-user-select: none;
            user-select: none;
        }
        .myplayer {
            width: 100%;
            height: 100%;
            background-color: #000000;
        }
    </style>
</head>
<body>
    <div id="player" class="myplayer"></div>
    <script>
        function getQueryVariable(variable)
        {
            var query = window.location.search.substring(1);
            var vars = query.split("&");
            for (var i=0;i<vars.length;i++) {
                var pair = vars[i].split("=");
                if(pair[0] == variable){return pair[1];}
            }
            return(false);
        }
        const player = new window.JSPlugin({
            szId: 'player',
            szBasePath: "./",
            iMaxSplit: 1,
            iCurrentSplit: 1,
            openDebug: true,
            oStyle: {
                borderSelect: '#000',
            }
        });
        const mode = true;
        let index = 0, playURL = getQueryVariable('url');
        player.JS_Play(playURL, { playURL, mode }, index).then(
            () => {
                player.JS_FullScreenDisplay(true).then(
                    () => { console.log(`wholeFullScreen success`) },
                    e => {
                        console.error(e)
                    }
                )
            },
            e => {
                console.error(e) ;
                alert('视频设备连接失败,请稍后再试');
                uni.postMessage({data: {msg: 'back'}});
            }
        );
    </script>
</body>
</html>

uniapp 播放程序 playApp.vue

<template>
  <ly-container class="use_rpx">
    <template #header>
      <ly-statu-bar title="监测视频"></ly-statu-bar>
    </template>
    <div>
      <div class='flex_column g_bgcolor_white g_radius2 g_pad10l g_mar12b g_mar12t'
           style='width:97vw;height:12vh;margin-left: 1.5vw;'>
        <div class='flex1'></div>
        <div class="flex2 g_color_desc">项目名称</div>
        <div class='flex1'></div>
        <div class='flex2 g_color_text_main'>{{this.entryName || '-'}}</div>
        <div class='flex1'></div>
      </div>
      <div class='flex_column g_bgcolor_white g_radius2 g_pad10l g_mar12b'
           style='width:97vw;height:12vh;margin-left: 1.5vw;'>
        <div class='flex1'></div>
        <div class="flex2 g_color_desc">监控位置</div>
        <div class='flex1'></div>
        <div class='flex2 g_color_text_main'>{{this.videoName || '-'}}</div>
        <div class='flex1'></div>
      </div>
      <div class='flex_column g_bgcolor_white g_radius2 g_pad10l'
           style='width:97vw;height:70vw;margin-left: 1.5vw;'>
        <div class='flex1'></div>
        <div class="flex1 g_color_desc">监控视频</div>
        <div class='flex1'></div>
        <web-view v-if="showVideo" class="videoContainer" id="xgplayer" :src="htmlUrl" @message="receiveData"></web-view>
        <div class='flex1'></div>
      </div>
    </div>
  </ly-container>

</template>

<script>
import {
  getVideoUrls
} from "@/api/video";

export default {
  data() {
    return {
      wsUrl: '',
      cameraIndexCode: '',
      videoName:'',
      entryName:'',
	    showVideo: false,
      htmlUrl: '/static/h5player/webplayer.html',
    }
  },
  mounted () {
    this.videoName=uni.getStorageSync("videoName");
    this.entryName=uni.getStorageSync("entryName");
  },
  onLoad(param) {
    if (param && param.cameraIndexCode) {
      this.cameraIndexCode = param.cameraIndexCode
      this.getVideoUrls()
    }
  },
  methods: {
    getVideoUrls() {
      getVideoUrls(this.cameraIndexCode).then(res => {
        this.wsUrl = res.data;
        this.htmlUrl = `/static/h5player/webplayer.html?url=${this.wsUrl}`;
        this.showVideo = true;
      })
    },
    receiveData (data) {
      console.log("收到来自webview的消息:", data)
      if (data && data.detail && data.detail.data && data.detail.data.length > 0) {
        for (let i = 0; i < data.detail.data.length; i++) {
          if (data.detail.data[i].msg && data.detail.data[i].msg === 'back') {
            uni.navigateBack({});
          }
        }
      }
    },
  }
}
</script>

<style scoped>
.videoContainer {
  width: 100%;
  height: 100%;
}
</style>

参考

uniapp web-view组件双向通信_uniapp webview通信-CSDN博客