AR+ 实时音视频通话,×××无缝结合
今年中旬 Google 在万众期待下推出了 ARCore,能将现实与数码完美无缝地融合在一起,丰富我们的现实世界。通过它开发者可以更加快速方便地在 Android 平台开发 AR 应用,凭借 AR 技术大量产品能找到新颖的应用场景,甚至开辟出新的一条产品线。
目前市场上已经有不少基于 AR 技术的产品,例如宜家家居的 IKEA Place 应用提供了新型的在线选购家俬方式,用户只需要将手机摄像头摆向想要放置家具的角落,接着选取你想要的家具,通过简单的拖拉以及旋转即可完成布局,查看这件家具是否符合你的心意。
下图为使用 IKEA Place 的示意图,看起来这张椅子还挺适合的 :)
那么假如 AR 与其他技术进行结合,是否会有更激动人心的应用场景呢?
七牛实时音视频云 (以下简称七牛 RTN)基于已被广泛标准化的 WebRTC 技术栈,有全平台的兼容性,支持各大浏览器如 Chrome、Safari、Firefox 以及各端 Android、iOS、Windows 等。强大的七牛实时音视频流媒体网络在全球有 180 多个数据中心,具有强大的链路加速功能,丰富的节点保证了无论客户分布在全球的什么地区都可以获得加速。平均 200ms 的超低延时,为诸多对实时性有苛刻要求的客户场景提供最根本支持,如一对一语聊、聊天室、视频会议、在线教育等对交互性有强需求的场景均十分适合使用七牛 RTN。
在本篇中,我们会结合 Google 官方的示例 hello_ar_java 将 AR 技术融入到实时音视频通话,其中会应用到 1.1.0+ 版本七牛 RTN SDK 的新功能 “外部音视频数据导入”。
以下为效果动图
准备工作0: 集成七牛 RTN SDK 到 AR Demo
在真正开始编码前,我们需要先将相应的项目和环境搭建完成
下载 七牛 RTN SDK 到当前目录 QNRTC-Android
git clone git@github.com:pili-engineering/QNRTC-Android.git
下载 ARCore 到当前目录 arcore-android-sdk
git clone git@github.com:google-ar/arcore-android-sdk.git
拷贝相应七牛 RTN SDK 文件到 hello_ar_java 工程中
- 将文件
QNRTC-Android/releases/qndroid-rtc-1.2.0.jar
拷贝到arcore-android-sdk/samples/hello_ar_java/app/libs/
中(libs 目录需要自行创建) - 将
QNRTC-Android/releases/
下的armeabi、armeabi-v7a、arm64-v8a、x86
等 4 个文件夹拷贝到arcore-android-sdk/samples/hello_ar_java/app/src/main/jniLibs
文件夹中(jniLibs 目录需要自行创建) - 使用 AndroidStudio 打开
arcore-android-sdk/samples/hello_ar_java
工程,修改其中几项配置- 为了让工程引用上面两步中添加的库,打开
app/build.gradle
文件,在dependencies
中增加行implementation fileTree(include: ['*.jar'], dir: 'libs')
- 为了能进行实时通话,需要设置程序使用网络的权限,打开
AndroidManifest.xml
文件,在manifest
标签中增加以下使用权限声明<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
- 为了让工程引用上面两步中添加的库,打开
核心类介绍
在实际编码与代码分析前,我们先简单概述介绍其中会涉及到的核心类
QNRTCManager:七牛 RTN SDK 核心类,提供低延时实时音视频通话能力
Session:ARCore 核心类,管理 AR 系统状态包括摄像头 Camera 采集、点网监测、平面检测等能力
GLSurfaceView & Renderer:Android 系统提供的视图类与渲染类,分别提供负责画面显示与渲染
BackgroundRenderer & ObjectRenderer & PlaneRenderer & PointCloudRenderer: Demo 中提供的渲染类,分别负责以下部分的渲染
- 背景图渲染(摄像头预览原始图)
- 物体及其阴影渲染(Android 模型及其阴影)
- 平面渲染(AR 系统检测到的平面)
- 点云渲染(AR 系统检测到的点云)
准备工作1: 建立基本的实时音视频通话环境
首先需要实现实时音视频的房间事件监听器 QNRoomEventListener
,其需要实现的方法很多,以下只展现这次简单示例需要用到的方法,完整的接口说明在这里
public class HelloArActivity extends AppCompatActivity implements GLSurfaceView.Renderer, QNRoomEventListener {private boolean mPublished = false; // 标识本地是否发布成功...@Overridepublic void onJoinedRoom() {mRTCManager.publish(); // 加入房间成功后,尝试发布}@Overridepublic void onLocalPublished() {mPublished = true; // 发布成功后,标识为 true}...
}
在 onCreate
方法尾部初始化实时音视频通话环境并加入指定房间,其中关于 Room Token 获取的方式可以参考这里
protected void onCreate(Bundle savedInstanceState) {...QNRTCSetting setting = new QNRTCSetting();setting.setExternalVideoInputEnabled(true); // 开启外部视频导入功能mRTCManager.setRoomEventListener(this); // 设置房间事件监听器mRTCManager.initialize(this, setting); // 七牛 RTN SDK 初始化mRTCManager.joinRoom(###Your Room Token###); // 通过 Room Token 加入指定房间
}
准备工作2: 建立基本的 AR 环境
利用 GLSurfaceView & Renderer 为绘制 AR 画面做好准备
在 Activity 类声明中实现 GLSurfaceView.Renderer
接口,在本 Demo 中如下,随即需要我们实现 3 个相应的方法,意义分别在注释中被描述
public class HelloArActivity extends AppCompatActivity implements GLSurfaceView.Renderer, QNRoomEventListener {/*** 显示 Surface 创建完成时回调**/public void onSurfaceCreated(GL10 gl, EGLConfig config) {}.../*** 显示 Surface 尺寸大小改变时回调**/public void onSurfaceChanged(GL10 gl, int width, int height) {}.../*** 显示 Surface 创建完成时回调**/public void onDrawFrame(GL10 gl) {}
}
在实现了 Renderer 渲染类后,我们需要提供用作显示的 Surface,以便让 Renderer 在其上进行渲染显示,GLSurfaceView 就有这种能力。
以下示例代码,从布局 xml 文件中解析出 GLSurfaceView 并设置 Renderer
surfaceView = findViewById(R.id.surfaceview); // 从布局 xml 中解析 GLSurfaceView
...
surfaceView.setRenderer(this); // 设置 Renderer
创建 Session
Session 是 AR 系统的主入口类,在任何 AR 操作前必须先初始化并启动
protected void onResume() {session = new Session(/* context= */ this); // AR 系统初始化...session.resume(); // 开始 AR 会话,尝试开启摄像头,如摄像头被占用,会抛出 CameraNotAvailableException 异常
}
使用 OpenGL Shader 在显示 Surface 上绘制 AR 增强画面
在 AR 会话开始后,摄像头的每一帧数据都能提供以下信息
- 原始摄像头预览数据
- 检测到的平面数组
- 检测到的点云数组
- 平面触摸事件
我们可以在 onDrawFrame
方法中利用以上的事件进行相应的处理,例如遇到平面触摸事件,则在相应的位置放上一个 Android 模型,并且同时绘制出检测到的平面以及点云。
// 绘制背景
private final BackgroundRenderer backgroundRenderer = new BackgroundRenderer();
// 绘制物体
private final ObjectRenderer virtualObject = new ObjectRenderer();
// 绘制物体阴影
private final ObjectRenderer virtualObjectShadow = new ObjectRenderer();
// 绘制平面
private final PlaneRenderer planeRenderer = new PlaneRenderer();
// 绘制云点
private final PointCloudRenderer pointCloudRenderer = new PointCloudRenderer();public void onDrawFrame(GL10 gl) {frame = session.update(); // 获取摄像头原始数据帧(阻塞方法)// Handle one tap per frame.handleTap(frame, camera); // 检测是否有平面点击事件,如有则在相应位置放置 Android 模型...// Draw background.backgroundRenderer.draw(frame); // 将摄像头预览数据作为背景图绘制...// Visualize tracked points.PointCloud pointCloud = frame.acquirePointCloud();pointCloudRenderer.update(pointCloud);pointCloudRenderer.draw(viewmtx, projmtx); // 绘制点云...// Visualize planes.planeRenderer.drawPlanes(session.getAllTrackables(Plane.class), camera.getDisplayOrientedPose(), projmtx); // 绘制平面...// Update and draw the model and its shadow.virtualObject.updateModelMatrix(anchorMatrix, scaleFactor);virtualObjectShadow.updateModelMatrix(anchorMatrix, scaleFactor);virtualObject.draw(viewmtx, projmtx, colorCorrectionRgba, coloredAnchor.color); // 绘制 Android 模型virtualObjectShadow.draw(viewmtx, projmtx, colorCorrectionRgba, coloredAnchor.color); // 绘制 Android 模型的阴影
}
##技术结合: 将 AR 增强画面发布到实时音视频云
在分别实现了基本的 实时音视频通话 和 AR 增强画面 后,现在只需要将它们进行最后的结合。
因为 Session 启动后会占用设备摄像头,因此七牛 RTN SDK 无法进行采集,这时候我们需要使用最新版本提供的功能 ”外部音视频数据导入“。
在发布流前,我们需要获取到 AR 增强画面 的 NV21 格式数据,因为当前七牛 RTN Android SDK 的 “外部视频数据导入” 功能只支持 NV21 格式的数据。
以下示例代码在 onDrawFrame
方法中的尾部添加,将 GLSurfaceView 的 Surface 内容数据读取出来,进行必要的格式转换,接着发布出去
public void onDrawFrame(GL10 gl) {...if (mPublished) { // 只在七牛 RTN 发布流成功后才导入 AR 数据// 将 AR 增强画面 的数据从 GPU 中读取出来GLES20.glReadPixels(0, 0, mSurfaceWidth, mSurfaceHeight, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, mBufferRGBA);// RGBA 转为 NV21(篇幅原因,不在此展开算法)mBufferNV21 = RGBAToNV21(mBufferRGBA, mSurfaceWidth, mSurfaceHeight);// 通过 "外部视频数据导入" 功能将 NV21 数据形式的 AR 增强画面 发布出去mRTCManager.inputVideoFrame(mBufferNV21, mSurfaceWidth, mSurfaceHeight, 0, frame.getTimestamp());}
}
总结
使用 1.1.0+ 版本七牛 RTN SDK 提供的 “外部音视频数据导入” 功能,可以轻松地把 AR 与实时音视频通信结合起来。以上程序基于七牛 RTN SDK 以及相应的 RTN 网络运行,最大可以支持 20 人同时低延时音视频通话。相信不久将来 AR 技术与实时音视频通信的结合会带来更多的应用场景。
转载于:https://blog.51cto.com/7741292/2317763
AR+ 实时音视频通话,×××无缝结合相关推荐
- 关于 TRTC (实时音视频通话模式)在我司的实践
什么是 TRTC 腾讯实时音视频(Tencent Real-Time Communication,TRTC)将腾讯 21 年来在网络与音视频技术上的深度积累,以多人音视频通话和低延时互动直播两大场景化 ...
- 微信小程序集成腾讯IM,实现实时音视频通话,1V1聊天
相关文章: 1.小程序聊天群,发送语音,文字,图片. 2.微信小程序集成腾讯IM,实现实时音视频通话,1V1聊天 3.云开发微信小程序聊天群 4.接入网易云信IM即时通讯的微信小程序聊天室 5.微信小 ...
- 微信小程序集成实时音视频通话功能
微信小程序集成实时音视频通话功能 背景 在项目的开发当中,很多时候,我们会有音频.视频通话的需求,但是一般都不会自己来写,所以我们就需要借助第三方来实现.尤其是这次的项目开发当中,需要在微信小程序当中 ...
- (精华)2020年8月7日 微信小程序 实时音视频通话
微信小程序集成实时音视频通话功能 背景 在项目的开发当中,很多时候,我们会有音频.视频通话的需求,但是一般都不会自己来写,所以我们就需要借助第三方来实现.尤其是这次的项目开发当中,需要在微信小程序当中 ...
- 微信实时音视频通话数据流分析
一.实时音视频的架构 实时音视频通信架构主要包括P2P.SFU.MCU三种方式,其中点对点通信通常以P2P优先,P2P走不通的场景再借助于SFU/MCU. P2P方式,终端之间点对点的相互收发数据流, ...
- 如何展示实时音视频通话时正在说话用户的音浪
1 概述 在 K 歌场景中,经常需要拉多路流并显示其中正在讲话的用户,我们需要甄别用户是否说话.说话音量大小(音浪),并在 UI 上展示,如图: 2 源码下载 下载示例源码 参考文件: src/Exa ...
- 腾讯实时音视频通话sdk集成----小程序版本
参考文章:实时音视频 小程序-无 UI 集成方案-文档中心-腾讯云 1.配置域名添加 2.npm集成 项目中引用trtc-wx包 在项目脚本中直接引入模块此处可引入静态文件构建npm import T ...
- 视频会议/远程医疗/在线教育网页视频实时音视频通话目前有什么优势和不足?
很长时间以来,实时通信能力一直是电信类专用设备(如电话.手机)的专有属性.随着各种互联网应用和移动互联网应用的层出不穷,特别是随着用户接入带宽条件的不断改善,许多新的应用都对实时通信服务有着切实的需求 ...
- 七牛云实时音视频通话集成
1集成sdk,添加权限相关 https://developer.qiniu.com/rtc/8765/prepare-android-development 2下载demo源码 https://git ...
最新文章
- 用终端访问路由器设置端口开发_serial for mac(终端管理软件)v2.0.3
- 【渝粤教育】国家开放大学2018年春季 0434-22T高级英语口语 参考试题
- visual studio for mac在线安装网络错误
- 基于51单片机的医院银行排队叫号系统proteus仿真程序原理图设计
- 工具系列————linux系统中安装fortran编译器(ifort)
- 使用nmake编译Gdal源代码(Win10, VS2022)
- 珍藏5年的5000款photoshop顶尖字体库,这回不用担心没有好的PS字体了!
- Java - @OneToMany注解的mappedBy属性有什么作用?
- python毕业论文参考文献格式范例_毕业论文参考文献规范格式及例子
- EOJ 2527 Fj haozi【dfs】
- IKBC键盘win键失灵解决方法
- Python绘制卫星星下点轨迹图和卫星星座图
- java实现多张图片同时上传
- 那些好用的无版权免费图片网站
- 【原】拯救你的机械硬盘!
- Github每日精选(第77期):Go (Golang) 编写的 HTTP Web 框架gin
- 新唐M480系列单片机写入dataflash数据
- 基于VHDL的具有自动乐曲演奏功能的电子琴设计
- 如何解决:对路径的訪问被拒绝这个问题.
- 高级售前客户服务专员考试