写点什么

跨平台应用开发进阶 (三十):uni-app 实现集成火山视频直播服务

  • 2022-12-21
    江苏
  • 本文字数:4424 字

    阅读完需:约 15 分钟

跨平台应用开发进阶(三十):uni-app 实现集成火山视频直播服务

一、前言

项目开发进程中,业务提出新需求,需要接入视频直播。为此,开始接触火山引擎视频直播。火山引擎方值负责提供观播 SDK,综合考虑现有技术栈,采用集成Web SDK方式,接入观播功能。直播通过企业版腾讯会议方式进行推流操作。

二、技术实现

前端采用 uni-app Webview嵌套H5页面方式,重点处理逻辑集中在H5观播页面中,因为涉及观播activityId值的获取,故需要实现WebviewH5页面双向通信机制。


uni-app 在 App 平台同时支持网络网页和本地网页,但本地网页及相关资源(jscss等文件)必须放在 uni-app 项目根目录->hybrid->html 文件夹下或者 static 目录下,因为这个目录下的文件不会被编译。


注意⚠️:Web SDK以本地网页嵌套集成火山视频方式,目前不支持预告片播放及直播回放功能,故需要将视频直播H5作为一个独立H5应用进行部署。


补充知识点⚠️:每个vue页面,其实都是一个webview,而vue页面里的web-view组件,其实是webview里的一个子webview。这个子webviewappend到父webview上。


var currentWebview = this.$scope.$getAppWebview(); //此对象相当于html5plus里的plus.webview.currentWebview()。在uni-app里vue页面直接使用plus.webview.currentWebview()无效currentWebview.append(wv);//一定要append到当前的页面里!!!才能跟随当前页面一起做动画,一起关闭
复制代码


vue页面内容如下:


<template><!-- 注:使用动态url -->   <view>    <web-view :src="url"></web-view>  <view></template><script>  export default {    data() {      return {        url: ''      }    },    onLoad() {            // 默认一个你的html(h5地址)      this.url =  '/hybrid/html/vedioLive.html'    },          mounted(){            // 需要监听 message 之后触发方法      window.addEventListener("message", this.handlePostMessage);    },    methods: {            // 触发方法      handlePostMessage(data) {        console.log(data)        console.log(data.data.data.arg.data)        if (data.data.data.arg.data == 'h5页面传的值') {          // 给url重新赋值          this.url = ""        } else if (data.data.data.arg.data == '判断返回uniapp页面') {                    // 其他的跳转查看uniapp官网          uni.switchTab({            url: '/pages/xxx/index'          });        }       },    }  }</script>
复制代码


html 页面内容如下:


<!DOCTYPE html><html style="height: 100%" lang="zh-CN">  <head>    <title>直播Demo</title>  <meta charset="utf-8" content="text/html">    <link rel="shortcut icon"      href=//p1-live.byteimg.com/tos-cn-i-gjr78lqtd0/3f061494968a653d3409e0607259939e.png~tplv-gjr78lqtd0-image.image      sizes="16x16">    <meta name="viewport" http-equiv="Content-Type" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,            maximum-scale=1.0, user-scalable=no, shrink-to-fit=no, viewport-fit=cover">        <link rel="stylesheet"      href="https://lf-cdn-tos.bytescm.com/obj/static/livesaas-client/mobile/css/index.1.1.4.css">    <style>      .app {        display: flex;        height: 100%;        flex-direction: column;        /* background-image: url('//p6-live.byteimg.com/tos-cn-i-gjr78lqtd0/923a9e572712a19d5b8c84fa66e90bd6.png~tplv-gjr78lqtd0-image.image'); */    background-color: white!important;        background-size: 100% 100%;        background-attachment: fixed;      }        .player {        width: 100vw;        height: calc(100vw / 16 * 9);      }        .menu {        flex: 1 1;        min-height: 300px;        overflow: hidden;      }    </style>    </head>
<body style=' font-size: 10px; margin: 0; background-color: #080B12; height: 100%; overflow: hidden;'> <div class="app"> <div id="player" class="player"></div> <div id="content" class="menu"></div> </div> <script src="https://lf-cdn-tos.bytescm.com/obj/static/livesaas-client/mobile/js/index.1.1.4.js"></script> <script type="text/javascript" src="https://unpkg.com/@dcloudio/uni-webview-js@0.0.3/index.js"></script> </body> <script> // 等待sdk加载,待触发 `UniAppJSBridgeReady` 事件后,即可调用 uni 的 API。 document.addEventListener('UniAppJSBridgeReady', function() { console.log('-----------UniAppJSBridgeReady------------') // 向应用发送消息 uni.postMessage({ data: { order: 'playRecord' } }); uni.getEnv(function(res) { console.log('当前环境:' + JSON.stringify(res)); }); }); window.msgFromUniapp= function(arg) { console.log('<<<<<<<<<<<<<arg>>>>>>>>>>>:', arg); console.log('<<<<<<<<<<<<<JSON.stringify(arg)>>>>>>>>>>>:', JSON.stringify(arg)); } var webSDK = new window.ByteLiveWebSDK({ activityId: 1740896046764078, token: 'xSfupZ', service: 'liveDemo', mode: 1, modules: [ { id: "player", // 页面元素 ID, 播放器模块会嵌入到此元素内 mode: "player", }, { id: "content", // 页面元素 ID, 菜单模块会嵌入到此元素内 mode: "menu" } ], options: { mobileBackgroundTransparent: true, saveUserInfo: true, } }) webSDK.on('error', console.log); </script></html>
复制代码


有关参数、回调函数等详细用法,详参接口文档。

2.1 web-view 组件在 app 中的窗体关系和 plus.webview 操作方式

uni-appvue页面本身是一个webviewvue页面里的web-view组件,其实是一个子webview。但一个vue页面不能放多个web-view组件,这个组件默认是全屏的(不会覆盖原生头和原生导航)。


使用plus代码获得当前webview的对象后(参考此文https://ask.dcloud.net.cn/article/35036),再获取子webview,其实也可以得到web-view组件所对应的pluswebview对象,进而再使用plus.webview的丰富api


获取子webview时注意时机,获取方法执行太早可能获取不到。

三、双向通信

3.1 uni-app 与内嵌网页通信

uni-app 向内嵌网页发消息


const  _funName='msgFromUniapp',  _data = {    msg:'msg from uniapp'  };const currentWebview = this.$scope.$getAppWebview().children()[0];currentWebview.evalJS(`${_funName}(${JSON.stringify(_data)})`);
复制代码


内嵌网页接收消息


<script type="text/javascript" src="https://gitee.com/dcloud/uni-app/raw/dev/dist/uni.webview.1.5.3.js">window.msgFromUniapp= function(arg) {  console.log(arg);  console.log(JSON.stringify(arg));}
复制代码


3.2 内嵌网页向 uni-app 发消息

web-view访问的网页内引入uni.webview.1.5.3.js,待sdk加载完毕后就可以调用方法postMessage。如下:


// index.html<!DOCTYPE html><html lang="zh-CN">    <head>        <meta charset="utf-8">        <meta http-equiv="X-UA-Compatible" content="IE=edge">        <script type="text/javascript" src="https://gitee.com/dcloud/uni-app/raw/dev/dist/uni.webview.1.5.3.js">        </script>    </head>    <body>        <script>            // 等待sdk加载            document.addEventListener('UniAppJSBridgeReady', function() {                // 向应用发送消息                uni.postMessage({                    data: {                        order: 'playRecord'                    }                });            });        </script>    </body></html>
复制代码


uni-app 接收消息web-view存在的组件内写监听message的方法。如下:


<template>    <web-view @message="message" src="/hybrid/html/index.html"></web-view></template>
<script> export default { data() { return {}; }, methods: { message(arg) { console.loh(arg) }, } };</script>
复制代码


四、实现案例

内嵌 H5 网页代码:


<!DOCTYPE html><html lang="zh-CN">    <head>        <meta charset="utf-8">        <meta http-equiv="X-UA-Compatible" content="IE=edge">      <!-- uni 的 SDK -->      <!-- 需要把 uni.webview.1.5.4.js 下载到自己的服务器 -->      <script type="text/javascript" src="https://unpkg.com/@dcloudio/uni-webview-js@0.0.3/index.js"></script>        </script>    </head>
<body> <script> // 等待sdk加载 document.addEventListener('UniAppJSBridgeReady', function() { // 向应用发送消息 uni.postMessage({ data: { order: 'playRecord' } }); }); window.msgFromUniapp = function(arg) { console.log(JSON.stringify(arg)); } </script> </body></html>
复制代码


uniapp 组件代码:


<template>    <web-view @message='message' src="/hybrid/html/index.html"></web-view></template>
<script> export default { methods: { message(arg) { console.log(JSON.stringify(arg)) this.sendMsgToWebview() }, sendMsgToWebview() { const _funName = 'msgFromUniapp', _data = { msg: 'msg from uniapp' }; const currentWebview = this.$scope.$getAppWebview().children()[0]; currentWebview.evalJS(`${_funName}(${JSON.stringify(_data)})`); } } };</script>
复制代码

五、拓展阅读

发布于: 2022-12-21阅读数: 14
用户头像

No Silver Bullet 2021-07-09 加入

岂曰无衣 与子同袍

评论

发布
暂无评论
跨平台应用开发进阶(三十):uni-app 实现集成火山视频直播服务_uni-app_No Silver Bullet_InfoQ写作社区