未来会场基于 Unreal Engine打造,场景精细、功能丰富,但用户无需下载,无需高端的手机配置,在小程序上即可享受高清、流畅的虚拟参会体验,这是通过接入应用云渲染产品来实现的。本篇文档将基于该案例,为你剖析如何接入应用云渲染产品,如何从零开始搭建这样一个全真互联未来会场小程序,整体流程可参考下图:
接入前:应用开发
首先,你需要打造一个可在 Windows 环境下稳定运行的应用程序,在应用层面开发实现必要的功能。
例如,全真互联未来会场应用程序内实现了以下功能:
·支持通过键盘 WASD/上下左右来操控人物移动,鼠标左键拖动操控视角:可通过引入虚拟摇杆插件适配手机端操作(详细请参见 步骤2-前端-基础用法)。
·支持多人在线互动:建立一个 服务器 主持多人会话,所有其他用户使用 部署至应用云渲染的客户端连接到该服务器。
·多人视频、语音、文字聊天功能。
·嵌入图片/视频/直播流、实现虚拟形象表情动作、场景内放烟花、灯光秀等更多功能和玩法。
注意:说明:
注意:以上功能不是接入应用云渲染的必要条件,你可以按需实现,应用云渲染对你应用内功能的具体实现没有特殊要求,你也无需在 Unity 或 Unreal Engine 中进行特殊配置。不过为了实现更好的终端用户体验,在技术接入阶段(步骤2)你可以对应用做些针对性的调整,如将应用设置为无边框模式并开启自适应桌面分辨率(具体请参见步骤2-前端-高级功能)。
步骤1:控制台部署应用并测试效果
1. 将应用程序包体通过控制台上传部署至云端(参考应用上传 和应用启动参数配置)。
2. 新建项目并关联上传的应用程序(参考新建项目)。
3. 在项目下购买并发 (参考 购买并发包)。
4. 进行效果测试。
更多指引请参考快速入门 和 控制台操作指南。
步骤2:下载接入 Demo 搭建业务前端和后台
完成效果测试后,为了实现云渲染服务管理、更好的前端操作体验、小程序适配等,你还需要搭建自己的客户端程序以及后台服务,接入应用云渲染提供的各终端 SDK和后端 API ,我们提供接入 Demo帮助你快速实现业务上线。
以下将基于我们提供的 JS 接入 Demo 和 后台 Demo,为你剖析前端和后台功能和用法,详细请查看这篇 步骤2-前端部分 和 步骤2-后台部分。
步骤2一前端部分步骤2—后台部分基础概念开发一个 H5 页面,通过小程序的 web-view 组件加载云渲染画面基础用法 – 页面准备工作在页面中引入初始化脚本或代码中 import TCGSDK基础用法 – 编写页面代码初始化 TCGSDK,在移动端模拟键鼠操作,引入摇杆插件高级功能 – 多点触控实现多个指针(手指)同时操控云应用高级功能 – 移动端自适应屏幕分辨率实现云渲染画面总是铺满全屏,适配移动端不同手机尺寸、屏幕分辨率高级功能 – 屏幕旋转在移动端手机竖屏显示时候可设置屏幕旋转,将横屏流旋转为竖屏显示。高级功能 – 数据通道实现 Web 页面与云上应用数据互传,例如透传微信名和头像信息云端应用高级功能 – 排队功能当用户在线数大于资源并发数量时,建议业务引入用户排队系统,提升用户体验基础概念搭建下后台服务调用应用云渲染云 API,负责启动应用、关闭应用、排队等功能。基础用法 – 启动应用锁定应用云渲染并发,获取 ServerSession 返回给客户端,启动云渲染服务高级功能 – 排队功能当用户在线数大于资源并发数量时,建议业务引入用户排队系统,提升用户体验
一、基础概念
由于小程序暂时不支持 WebRTC,所以我们可以开发一个 H5 页面,然后通过小程序的 web-view 组件加载云渲染画面。
二、基础用法 – 页面准备工作
·在页面中引入初始化脚本(JS SDK 下载)。
<script src="path/to/sdk" charset="utf-8"></script>
·或代码中 import。
import TCGSDK from 'path-to-TCGSDK';
三、基础用法 – 编写页面代码
1. 初始化 TCGSDK。
TCGSDK.init({…initOptions})
2. 在 onInitSuccess 回调中启动项目,获取 ServerSession。
onInitSuccess: async () => { await StartProject();}
3. 获取 ServerSession 成功,启动云渲染。如期望实现排队功能,可参考 排队功能。
TCGSDK.start(ServerSession);
4. 启动成功后在移动端,模拟键鼠操作。
onTouchEvent: async (res) => { // res type 为 array,array 长度代表当前手机屏幕触摸的手指数 // console.log('onTouchEvent', res); // 针对单指触控操作 if (res.length === 1) { const { id, type, pageX, pageY } = res.pop(); // console.log('onTouchEvent', id, type, pageX, pageY); // 模拟将鼠标移到触摸点 TCGSDK.mouseMove(id, type, pageX, pageY); // 判断 touchstart 发送鼠标左键按下 if (type === 'touchstart') { TCGSDK.sendRawEvent({ type: 'mouseleft', down: true }); } // 判断 touchend 或 touchcancel 发送鼠标左键抬起 if (type === 'touchend' || type === 'touchcancel') { TCGSDK.sendRawEvent({ type: 'mouseleft', down: false }); } }}
5. 引入摇杆插件,摇杆插件通常对应键盘 WASD/上下左右 按键。
5.1 添加以下代码引入插件。
<script type="text/javascript" src="path/to/joystick.js"></script>
5.2 在 onConnectSuccess 回调函数中创建摇杆。
// 添加摇杆 plugin-point 为需要挂载插件的 element 的 IDconst j = new CloudGamingPlugin.joystick({ zone: document.querySelector('#plugin-point'),});
应用云渲染效果测试体验页面;键鼠操作模拟、虚拟摇杆引入等基础功能演示
四、完整代码如下:
注意替换 TCGSDK,Joystick plugin 的路径
<!doctype html><html><head> <meta charset="utf-8" /> <meta name="apple-mobile-web-app-capable" content="yes" /> <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0" /> <title>腾讯云-云渲染-应用云渲染-从零实现腾讯云生态大会云渲染小程序</title> <style> * { padding: 0; margin: 0; } html, body { width: 100%; height: 100%; overflow: hidden; font-family: '黑体', 'Microsoft YaHei', 'Arial', 'sans-serif'; } #demo-container { width: 100%; height: 100%; } </style></head><body> <div id="demo-container"> <div id="mount-point"></div> </div> <script type="text/javascript" src="path/to/tcg-sdk"></script> <script type="text/javascript" src="path/to/joystick.js"></script> <script type="text/javascript" src="https://cdn.bootcdn.net/ajax/libs/axios/0.26.1/axios.min.js"></script> <script> // 对于应用云渲染,后台服务接口 StartProject 其实就是后台串行调用了云API的 ApplyConcurrent + CreateSession // 申请并发(ApplyConcurrent) https://cloud.tencent.com/document/api/1547/72827 // 创建会话(CreateSession) https://cloud.tencent.com/document/api/1547/72826 const StartProject = async () => { const url = 'https://xxxx/StartProject'; // 后台端实现可以参考后台 demo 方案 // 其他选填参数可以参考 ApplyConcurrent 接口文档 const { data } = await axios.post(url, { ProjectId: 'project-id', // 项目Id UserId: 'user-id', // 用户Id,不同用户应该采用不同 UserId,同一UserId,会存在互踢现象 ClientSession: TCGSDK.getClientSession(), }); console.log('%c StartProject res', 'color: blue; font-size: 14px', data); const { Code, SessionDescribe: { ServerSession } } = data; if (Code === 0) { TCGSDK.start(ServerSession); } else { // 请求异常处理 } } // 云渲染接入功能流程说明可以参考 https://ex.cloud-gaming.myqcloud.com/cloud_gaming_web/docs/index.html TCGSDK.init({ appid: 1234567, mount: 'mount-point', debugSetting: { showLog: true, }, // 连接成功回调 onConnectSuccess: async (res) => { console.log('onConnectSuccess', res); }, // 网络中断/被踢触发此回调 onDisconnect: (res) => { console.log('onDisconnect', res); // 添加摇杆 plugin-point 为需要挂载插件的 element 的 ID const j = new CloudGamingPlugin.joystick({ zone: document.querySelector('#plugin-point'), }); }, onWebrtcStatusChange: (res) => { console.log('onWebrtcStatusChange', res); }, // 移动端触摸,模拟发送 PC 上指令 onTouchEvent: async (res) => { // res type 为 array,array 长度代表当前手机屏幕触摸的手指数 // console.log('onTouchEvent', res); // 针对单指触控操作 if (res.length === 1) { const { id, type, pageX, pageY } = res.pop(); // console.log('onTouchEvent', id, type, pageX, pageY); // 模拟将鼠标移到触摸点 TCGSDK.mouseMove(id, type, pageX, pageY); // 判断 touchstart 发送鼠标左键按下 if (type === 'touchstart') { TCGSDK.sendRawEvent({ type: 'mouseleft', down: true }); } // 判断 touchend 或 touchcancel 发送鼠标左键抬起 if (type === 'touchend' || type === 'touchcancel') { TCGSDK.sendRawEvent({ type: 'mouseleft', down: false }); } } }, onInitSuccess: async (res) => { console.log('%c onInitSuccess', 'color: red', res); await StartProject(); } }); </script></body></html>
五、高级功能 – 多点触控
移动端多点触控可以分为两种形式:
·云端应用支持多点触控,支持触摸事件,可直接设置 init 参数 clientInteractMode: 'touch',SDK 回自动发送 touch 相关指令致应用。
·云端应用不支持多点触控,仅支持鼠标键盘,可根据 onTouchEvent 回调,拿到对应触摸点坐标,发送 键盘/鼠标 指令完成业务逻辑。
六、高级功能 – 移动端自适应屏幕分辨率
因为移动端不同手机尺寸有不同分辨率,期望云渲染画面总是铺满手机屏幕需要根据不同手机尺寸,设置不同的推流分辨率。由于需要同时配置云上应用和前端页面,具体步骤请参见 技术接入-自适应分辨率。
七、高级功能 – 屏幕旋转
对于应用云渲染场景,由于云端总是推横屏流(宽大于高),所以在移动端手机竖屏显示时候可设置屏幕旋转,则将横屏流旋转为竖屏显示。屏幕旋转也可以搭配摇杆使用,摇杆插件已做兼容。
提供以下两种方法:
·(推荐使用)TCGSDK init 参数中设置 autoRotateContainer: boolean,自动旋转屏幕。业务方不需要任何操作,所有逻辑 TCGSDK 接管。
·调用 TCGSDK.setVideoOrientation 方法,旋转屏幕。
八、高级功能 – 数据通道
如果期望实现 Web 页面与云上应用数据互传可以使用数据通道功能,例如透传微信名和头像信息至云端应用。数据通道相关逻辑建议在 onConnectSuccess 回调中执行,调用 createCustomDataChannel 接口,发送数据类型支持 string 和二进制数据。详细实现流程及代码可以参考 技术接入-数据通道。
未来会场小程序;通过数据通道,将用户授权的微信名和头像信息透传至云端应用
九、高级功能 – 排队功能
当用户在线数大于资源并发数量时,建议业务引入用户排队系统,提升用户体验。
排队逻辑涉及前后台,前端代码可参考 排队示例,签名逻辑可以根据业务需求决定是否添加,后台部分请查看这篇 步骤2-后台-高级功能,更多详细内容请参见 技术接入-排队功能。
未来会场小程序;用户排队效果
十、基础概念
业务需要搭建下自己的后台服务去调用应用云渲染云 API,才能为你的客户服务。业务后台主要负责启动应用、关闭应用、排队等功能。
十一、基础用法 – 启动应用
1. 后台服务调用云渲染 API ApplyConcurrent() 锁定云渲染并发,收到成功回调后执行下一步。
nodejs 版本Golang 版本// Depends on tencentcloud-sdk-nodejs version 4.0.3 or higherconst tencentcloud = require("tencentcloud-sdk-nodejs");const CarClient = tencentcloud.car.v20220110.Client;// 实例化一个认证对象,入参需要传入腾讯云账户secretId,secretKey,此处还需注意密钥对的保密// 密钥可前往https://console.cloud.tencent.com/cam/capi网站进行获取const clientConfig = { credential: { secretId: "SecretId", secretKey: "SecretKey", }, region: "", profile: { httpProfile: { endpoint: "car.tencentcloudapi.com", }, },};const client = new CarClient(clientConfig);const params = { "UserId": "user-id", "UserIp": "user-ip", "ProjectId": "project-id"};client.ApplyConcurrent(params).then( (data) => { console.log(data); }, (err) => { console.error("error", err); });package mainimport ( "fmt" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile" car "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/car/v20220110")func main() { // 实例化一个认证对象,入参需要传入腾讯云账户secretId,secretKey,此处还需注意密钥对的保密 // 密钥可前往https://console.cloud.tencent.com/cam/capi网站进行获取 credential := common.NewCredential( "SecretId", "SecretKey", ) // 实例化一个client选项,可选的,没有特殊需求可以跳过 cpf := profile.NewClientProfile() cpf.HttpProfile.Endpoint = "car.tencentcloudapi.com" // 实例化要请求产品的client对象,clientProfile是可选的 client, _ := car.NewClient(credential, "", cpf) // 实例化一个请求对象,每个接口都会对应一个request对象 request := car.NewApplyConcurrentRequest() request.UserId = common.StringPtr("user-id") request.UserIp = common.StringPtr("user-ip") request.ProjectId = common.StringPtr("project-id") // 返回的resp是一个ApplyConcurrentResponse的实例,与请求对象对应 response, err := client.ApplyConcurrent(request) if _, ok := err.(*errors.TencentCloudSDKError); ok { fmt.Printf("An API error has returned: %s", err) return } if err != nil { panic(err) } // 输出json格式的字符串回包 fmt.Printf("%s", response.ToJsonString())}
2. 后台服务调用云渲染 API CreateSession() ,获取成功回调中的 ServerSession 返回给客户端。
nodejs 版本Golang 版本// Depends on tencentcloud-sdk-nodejs version 4.0.3 or higherconst tencentcloud = require("tencentcloud-sdk-nodejs");const CarClient = tencentcloud.car.v20220110.Client;// 实例化一个认证对象,入参需要传入腾讯云账户secretId,secretKey,此处还需注意密钥对的保密// 密钥可前往https://console.cloud.tencent.com/cam/capi网站进行获取const clientConfig = { credential: { secretId: "SecretId", secretKey: "SecretKey", }, region: "", profile: { httpProfile: { endpoint: "car.tencentcloudapi.com", }, },};const client = new CarClient(clientConfig);const params = { "UserId": "user-id", "UserIp": "user-ip", "ClientSession": "client-session"};client.CreateSession(params).then( (data) => { console.log(data); }, (err) => { console.error("error", err); });package mainimport ( "fmt" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile" car "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/car/v20220110")func main() { // 实例化一个认证对象,入参需要传入腾讯云账户secretId,secretKey,此处还需注意密钥对的保密 // 密钥可前往https://console.cloud.tencent.com/cam/capi网站进行获取 credential := common.NewCredential( "SecretId", "SecretKey", ) // 实例化一个client选项,可选的,没有特殊需求可以跳过 cpf := profile.NewClientProfile() cpf.HttpProfile.Endpoint = "car.tencentcloudapi.com" // 实例化要请求产品的client对象,clientProfile是可选的 client, _ := car.NewClient(credential, "", cpf) // 实例化一个请求对象,每个接口都会对应一个request对象 request := car.NewCreateSessionRequest() request.UserId = common.StringPtr("user-id") request.UserIp = common.StringPtr("user-ip") request.ClientSession = common.StringPtr("client-session") // 返回的resp是一个CreateSessionResponse的实例,与请求对象对应 response, err := client.CreateSession(request) if _, ok := err.(*errors.TencentCloudSDKError); ok { fmt.Printf("An API error has returned: %s", err) return } if err != nil { panic(err) } // 输出json格式的字符串回包 fmt.Printf("%s", response.ToJsonString())}
完整代码可以参考后台 Demo。
十二、高级功能 – 排队功能
当用户在线数大于资源并发数量时,建议业务引入用户排队系统,提升用户体验,具体操作请参见 排队功能。
更多介绍
更多功能说明请查看 技术接入 文档 和 SDK 文档,如你有任何疑问或建议,或有特殊产品功能需求,请联系我们获得帮助。
十三、并发包购买参考
对于类似全真互联未来会场的应用场景,一般在活动期间购买百-千路包天并发资源支持短期高并发用户需求,再购买数十路包月并发资源支持长期运营使用,即可满足业务需要,具体数量取决于实际业务需求。更多说明请参考 计费说明-根据业务场景选择最佳计费方式,如你有特殊计费需求,请联系我们。
十四、体验小程序完整功能
除了接入应用云渲染产品,全真互联未来会场小程序还整合了腾讯云快直播、TRTC、IM、Avatar、数智人等产品和前沿技术,实现了虚拟形象、多人互动、直播、AI问答等多种玩法。手机微信搜索“腾讯全球数字生态大会-未来会场”小程序,即可体验完整功能,更多说明请参见走进未来——全真互联未来会场,今年的亮点都在这里!
注意:说明:
注意:建议你使用手机体验“腾讯全球数字生态大会-未来会场”小程序,效果更佳!