Agora SDK和Vuforia SDK共享视频

本文内容

在本文中我将介绍如何将Vuforia的视频共享给Agora系统,利用声网提供的免费平台将实时视频内容共享出去。这次的案例中涉及两个技术点,一个是Vuforia的视频接口获取,一个是Agora系统以外部视频源的方式进行实时视频的传输。同时我们也通过这个小案例来熟悉两款SDK的使用。

SDK简介

本篇文章我们将介绍两款SDK:

第一款是声网的SDK,主要功能是进行实时视音频的传输、消息传输,兼容 iOS、Android、Windows、macOS、Web、小程序、RTOS、Flutter、Electron、React Native、Unity、Unreal 等 20 大开发平台。对于注册用户,每个月均有10000分钟的免费时长,这对于普通开发者进行如那件的开发和测试已经是足够的了,并且实测在4G网络的情况下端到端延迟<400ms,开发测试也是十分良好的体验,同时还有免费的后台管理系统对应用进行监控,这个后面用到时候再细说。

第二款是Vuforia的SDK,这是一款增强现实的底层SDK,也是可以免费使用的,是以Licence授权形式授权用户使用,对于没有购买Licence的开发者在视频画面的左下角会有“Vufiria”标志,当让对于开发者来说问题不大。

开发环境

主机:windows 10

引擎:Unity 3D 2019.3.1、Visual Studio 2015

实现步骤

我们将通过如下方式进行本次项目的实现。首先Vuforia支持以注册事件的方式回调自身因为AR所独占的视频数据,而Agora本身支持独占相机资源也支持以外部视频源的方式进行直播,我们需要将这两部分结合起来。同时,做这个视频共享的目的还有一个,就是将Unity 3D渲染的3D效果也同步直播出去,这才是最根本的目的。

第一步:导入SDK

(1)打开Unity 3D,创建工程。进入Unity的官方商城,分别获取到Vuforia的开发SDK和Agora的开发SDK

顺利导入之后,简单看一下结构:将所有相关内容作为一个Package放到一个文件夹是很好的习惯,不用担心里面的Plugins,系统会自动寻找其中的插件。基于Unity平台,目前Agora支持安卓、Iphone、Mac、Win32/64,不过还没有基于Unity3D平台的Html5的插件,期待未来能有实现(毕竟比较擅长Unity,其他不太熟悉)

​​​

使用Agora要使用licence,下面看一下注册和licence申请:

网址:https://www.agora.io/cn/

注册:输入相关信息

申请licence:成功登录尽可进入项目页面,在项目页面中即可创建项目(记得实名制哦)。

水晶球:项目的详细数据分析,这个功能目前我们还用不到,后面再介绍

​​​

(2)再来简单看一下需要配合来做的Vuforia。前面介绍过了,这是一款可以给开发者免费试用(加水印)的增强现实SDK,同样支持多平台的使用。

需要注意的是,我们同样需要申请licence,地址:https://developer.vuforia.com/

打开“0-Main”场景,在下图的左下角点击“Open Vuforia.....”即可进入到相关配置页面,即输入licence的界面。

​​

(3)小结:熟悉了本教程所用的两种SDK及其结构、功能、注册和Licence申请,对于这两种SDK有各种技术能力,感兴趣的同学可以在官方网站多停留一会。

第二步:Vuforia的准备工作

这一步中我们将完成一个AR场景的搭建,完成Vuforia视频的获取、屏幕截屏作为后期Agora视频源的输入。

(1)搭建AR场景:打开上图中“0-Main”场景,完成licence输入,选中场景中“ImageTarget”,在右侧“Image Target Behaviour”中选中如下内置识别图

(注意:首次选择From Database 会提示导入数据,请不要拒绝^_^,其次记得电脑上查摄像头)。点击运行或者CTRL+P运行,将摄像头对准识别图(识别图在Assets/Editor/Vuforia/ImageTargetTextures/VuforiaMars_Images/)即可看到模型在图片上。

​​

(2)编写代码:简单介绍一下,这个脚本中我们使用了Vuforia提供的注册回调机制,将自身从相机获取的视频共享出来。要注意一下这其中比较重要的像素格式,同样在Agora系统中也会有像素格式的问题。

A:透明度 R:红色 G:绿 B:蓝

ARGB_4444:每个像素占四位,即A=4,R=4,G=4,B=4,那么一个像素点占4+4+4+4=16位 

 ARGB_8888:每个像素占四位,即A=8,R=8,G=8,B=8,那么一个像素点占8+8+8+8=32位

 RGB_565:每个像素占四位,即R=5,G=6,B=5,没有透明度,那么一个像素点占5+6+5=16位

GrayScale:像素占四位,即R=G=B=gray

如下,“TakeScreen”函数是对整个Scene中一个Camera场景进行截图,目的是获取渲染后的相机效果。

...

public class VuforiaImageShare : MonoBehaviour

{

    public UnityEngine.UI.RawImage tex;

    public UnityEngine.UI.RawImage screenImage;

    public Camera renderCamera;

    #region PRIVATE_MEMBERS

    private PIXEL_FORMAT mPixelFormat = PIXEL_FORMAT.UNKNOWN_FORMAT;

    private bool mFormatRegistered = false;

    #endregion // PRIVATE_MEMBERS

    #region MONOBEHAVIOUR_METHODS

    //作为共享的图片数据

    Texture2D mTexture;

    Texture2D screenShot;

    Rect mRect;

    private RenderTexture renderTex;

    //启用相机画面或者屏幕渲染画面

    public bool useCam = true;

    void Start()

    {

        //注册的图片返回格式,有多种格式可选GRAYSCALE/RGBA8888/RGB565等常见格式

#if UNITY_EDITOR

        mPixelFormat = PIXEL_FORMAT.RGBA8888; // Need Grayscale for Editor 经测试,在Editor模式同样可以RGBA8888

#else

          mPixelFormat = PIXEL_FORMAT.RGB888; // Use RGB888 for mobile

#endif

        //注册回调

        // Register Vuforia life-cycle callbacks:

        VuforiaARController.Instance.RegisterVuforiaStartedCallback(OnVuforiaStarted);

        VuforiaARController.Instance.RegisterTrackablesUpdatedCallback(OnTrackablesUpdated);

        VuforiaARController.Instance.RegisterOnPauseCallback(OnPause);

        #endregion // MONOBEHAVIOUR_METHODS

        // 创建一个RenderTexture对象 

        renderTex = new RenderTexture((int)Screen.width, (int)Screen.height, 0);

    }

...

将以上脚本挂在任一场景中GameObject上,拖入对应的参数脚本运行程序,可以看到左下角为屏幕实时渲染的截图(包含渲染过的3D模型),右下角为实时获取的Vuforia实时回调图片。

​​

(3)小结:至此我们完成了对于Agora数据的录入准备工作,包括视频原始数据和经过渲染的屏幕数据(较重要),后期在视频会议、远程协助等方面可以有比较多的应用。

第三步:Agora应用

我们在这一步将熟悉Agora的流程,跑通demo,学习外部视频源输入的代码。

(1)学习Demo场景。在如下场景中,输入按照之前步骤在agora官网创建项目获得的AppID,点击运行即可进入视频房间(是不是很简单(*^▽^*))。

​​

下面简单介绍几个重要函数:打开脚本“TestHelloUnityVideo”这里面的“loadEngine”即为Agora引擎重要的初始化步骤。

...

public void loadEngine(string appId)

    {

        // start sdk

        Debug.Log("initializeEngine");

        if (mRtcEngine != null)

        {

            Debug.Log("Engine exists. Please unload it first!");

            return;

        }

        // init engine

        mRtcEngine = IRtcEngine.GetEngine(appId);

        // enable log

        mRtcEngine.SetLogFilter(LOG_FILTER.DEBUG | LOG_FILTER.INFO | LOG_FILTER.WARNING | LOG_FILTER.ERROR | LOG_FILTER.CRITICAL);

    }

...

下面的“join”函数,为用户加入房间以及各种回调函数的设计:

...

public void join(string channel)

    {

        Debug.Log("calling join (channel = " + channel + ")");

        if (mRtcEngine == null)

            return;

        // set callbacks (optional)

        mRtcEngine.OnJoinChannelSuccess = onJoinChannelSuccess;

        mRtcEngine.OnUserJoined = onUserJoined;

        mRtcEngine.OnUserOffline = onUserOffline;

        // enable video

        mRtcEngine.EnableVideo();

        // allow camera output callback

        mRtcEngine.EnableVideoObserver();

        // join channel

        mRtcEngine.JoinChannel(channel, null, 0);

    }

...

接下来的“leave”函数,切记在程序退出时记得关闭,不然可能会导致一些bug。

...

public void leave()

    {

        Debug.Log("calling leave");

        if (mRtcEngine == null)

            return;

        // leave channel

        mRtcEngine.LeaveChannel();

        // deregister video frame observers in native-c code

        mRtcEngine.DisableVideoObserver();

    }

...

(2)接下来,我们要完成Agora系统的外置视频源输入,有以下内容:

(a)设置Agora的SDK为外置视频源模式,在“join”函数中, mRtcEngine.SetExternalVideoSource(true, false);

请确保你是在调用pushExternalVideoFrame前已调用 setExternalVideoSource, 并将参数 pushMode 设为 true ,不然调用本方法后会一直报错。

(b)添加外部视频源推送函数,需要注意的是:

VIDEO_PIXEL_FORMAT.VIDEO_PIXEL_RGBA;目前已经支持多种视频格式,在unity中不必讲RGBA再转换成BGRA(赞~)

externalVideoFrame.cropLeft;等四个位置,这里是做视频的裁剪

externalVideoFrame.rotation = 0;这里在移动端具有重要作用,作为视频的旋转设置

(c)依据第二步我们所获得的视频图片数据源(两种哈),形成完整的Agroa外置视频源系统代码(详细代码可在工程中查看):


这一步我们将两个系统进行融合,下图是简单场景编写,详细内容会在附件连接中提供下载。下图为Agroa的AR识别场景,在开启后将可以看到AR场景并开启外部视频源的数据推送。

在此之前,我们需要将Agroa例程中的“SceneHome”输出为exe可运行程序(请记得licence和BuildSetting添加场景)。

导出后,请先运行编辑器中的AR场景,因为要抢占开发电脑的摄像头(agroa默认取第一个摄像头),创建好系统场景;

之后开启事先导出的Agroa的例程场景,输入频道号“Agora”即可,分别看一下只传输视频和传输AR视频的效果

下面是切换了AR渲染后的效果,可以明显看到在右侧客户端画面中,出现了渲染过的3D人物。

待解决的问题

(1)通过传送渲染过的相机,对计算能力的要求,目前本机I7 9700k,1050TI显卡,编辑器内可以达到60帧,是否有更高效的方法?

(2)仔细观察会发现,左侧屏幕中,Vuforia回调的视频画面是上下反转的,而传到左侧,又反转了一次;是什么问题该如何处理;

(3)仔细观察会发现,右侧原始画面在左侧展示时候,虽然压缩了但是明显的也被裁减了,这是为什么呢?

相关资源

论坛:

Agora开发者中心:https://docs.agora.io/cn

AgoraGit仓库:https://github.com/AgoraIO

本次源代码:

链接:https://pan.baidu.com/s/1DIQNFTrSUHsARhRH_KchNQ

提取码:n8ne

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容