uni-app 实现集成直播服务

举报
SHQ5785 发表于 2023/03/27 08:40:28 2023/03/27
【摘要】 一、前言项目开发进程中,业务提出新需求,需要接入视频直播。为此,开始接触火山引擎视频直播。火山引擎方值负责提供观播SDK,综合考虑现有技术栈,采用集成Web SDK方式,接入观播功能。直播通过企业版腾讯会议方式进行推流操作。 二、技术实现前端采用uni-app Webview嵌套H5页面方式,重点处理逻辑集中在H5观播页面中,因为涉及观播activityId值的获取,故需要实现Webvie...

一、前言

项目开发进程中,业务提出新需求,需要接入视频直播。为此,开始接触火山引擎视频直播。火山引擎方值负责提供观播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>

五、直播

应用火山平台进行直播,取决于直播平台的支持方式,例如企微仅支持拉流直播、腾讯会议仅支持推流直播。

5.1 拉流直播

企业直播支持拉流直播方式。拉流直播是指将获取到的拉流地址的直播画面同步到企业直播间。该功能一般适用于多会场直播的场景。

前提条件:已获取待拉取对象的拉流地址。

操作步骤

  1. 登录企业直播控制台。

  2. 在直播列表中,单击进入直播间。

  3. 在播放器下方,单击开播方式,并单击拉流直播页签。

在这里插入图片描述

输入拉流 URL 地址。

说明⚠️:支持的拉流地址协议类型为 rtmp(推流协议)、rtsphlsflv 等。

  1. 单击开始拉流。

5.2 推流直播

首先需要确保开播平台支持推流直播,支持的话就将观播间url配置至开播平台地址。

观播端生成的房间activityidtoken是与直播间一一绑定的。

六、拓展阅读

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。