跨平台应用开发进阶(三十):uni-app 实现集成火山视频直播服务
Posted No Silver Bullet
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了跨平台应用开发进阶(三十):uni-app 实现集成火山视频直播服务相关的知识,希望对你有一定的参考价值。
文章目录
一、前言
项目开发进程中,业务提出新需求,需要接入视频直播。为此,开始接触火山引擎视频直播。火山引擎方值负责提供观播SDK,综合考虑现有技术栈,采用集成Web SDK
方式,接入观播功能。直播通过企业版腾讯会议方式进行推流操作。
二、技术实现
前端采用uni-app Webview
嵌套H5
页面方式,重点处理逻辑集中在H5
观播页面中,因为涉及观播activityId
值的获取,故需要实现Webview
与H5
页面双向通信机制。
uni-app在 App 平台同时支持网络网页和本地网页,但本地网页及相关资源(js
、css
等文件)必须放在 uni-app 项目根目录->hybrid->html
文件夹下或者 static
目录下,因为这个目录下的文件不会被编译。
注意⚠️:Web SDK
以本地网页嵌套集成火山视频方式,目前不支持预告片播放及直播回放功能,故需要将视频直播H5
作为一个独立H5
应用进行部署。
补充知识点⚠️:每个vue
页面,其实都是一个webview
,而vue
页面里的web-view
组件,其实是webview
里的一个子webview
。这个子webview
被append
到父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-app
的vue
页面本身是一个webview
,vue
页面里的web-view
组件,其实是一个子webview
。但一个vue
页面不能放多个web-view
组件,这个组件默认是全屏的(不会覆盖原生头和原生导航)。
使用plus
代码获得当前webview
的对象后(参考此文https://ask.dcloud.net.cn/article/35036),再获取子webview
,其实也可以得到web-view
组件所对应的plus
的webview
对象,进而再使用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>
五、直播
5.1 拉流直播
企业直播支持拉流直播方式。拉流直播是指将获取到的拉流地址的直播画面同步到企业直播间。该功能一般适用于多会场直播的场景。
前提条件:已获取待拉取对象的拉流地址。
操作步骤
-
登录企业直播控制台。
-
在直播列表中,单击进入直播间。
-
在播放器下方,单击开播方式,并单击拉流直播页签。
输入拉流 URL 地址。
说明⚠️:支持的拉流地址协议类型为 rtmp
(推流协议)、rtsp
、hls
、flv
等。
- 单击开始拉流。
5.2 推流直播
首先需要确保开播平台支持推流直播,支持的话就将观播间url配置至开播平台地址。
观播端生成的房间activityid
与token
是与直播间一一绑定的。
六、拓展阅读
- 《跨平台应用开发进阶(十七) :uni-app实现内嵌H5应用》
- uni-app web-view官方文档说明
- 《在web-view加载的本地及远程HTML中调用uni的API及网页和vue页面通讯》
- 火山引擎视频直播SDK接口说明
- 火山引擎视频直播帮助手册
- 企业版腾讯会议推流直播
以上是关于跨平台应用开发进阶(三十):uni-app 实现集成火山视频直播服务的主要内容,如果未能解决你的问题,请参考以下文章
跨平台应用开发进阶(三十一) :uni-app实现覆盖原生控件导航栏和tabbar全屏弹窗
跨平台应用开发进阶(三十八)uni-app前端监控方案:基调听云APP探究
跨平台应用开发进阶(三十七)uni-app前端监控方案 Sentry 探究