1. 程式人生 > >Qcon演講紀實:詳解如何在實時視訊通話中實現AR功能

Qcon演講紀實:詳解如何在實時視訊通話中實現AR功能

2018年4月20日-22日,由 infoQ 主辦的 Qcon 2018全球軟體開發大會在北京如期舉行。聲網首席 iOS 研發工程師,iOS 端移動應用產品設計和技術架構負責人龔宇華,受邀分享了《基於 ARkit 和 ARcore,在實時視訊通話中實現 AR 功能》,在演講中剖析了 AR 與 VR 差異,ARKit 的工作原理,以及逐步講解如何基於 ARKit 與聲網Agora SDK 建立 AR 視訊會議場景。

以下為演講精華摘錄:

首先,龔宇華簡要分析了 AR 與 VR 的差別是什麼,“VR 是將人置身於一個完全虛擬的場景中,它發展到極致就會像《黑客帝國》一樣,你所看到的一切都是虛擬的;AR 則是在現實場景中增加虛擬元素,讓兩者結合,就像《鋼鐵俠》電影中的頭盔一樣,在可以檢視周圍環境的同時,顯示虛擬元素”。不只是在電影中,現實中也有很多AR的應用案例,比如曾火爆一時的遊戲 Pocketmon go。

ARKit 如何實現 AR 場景?

在演講中,龔宇華為大家演示瞭如何實現一個 AR 視訊會議場景,實現效果會與我們在電影《王牌特工》中所看到的場景類似(如下圖),特工戴上眼鏡之後,世界另一端的特工的虛擬形象就與他坐在同一張桌旁。

“就像我們說把大象放進冰箱裡三步驟,我們要開啟冰箱,把大象放進去,關上冰箱。那我們實現 AR 的虛擬會議室也是分三步驟,就是實現 AR、實現視訊會議,然後把它兩個結合起來。”龔宇華表示。最終我們會實現下圖中的Demo效果。

目前,蘋果和 Google 分別推出了 ARKit 和 ARCore,為我們在移動端實現 AR 場景降低了門檻。實現AR的原理是怎樣的呢?我們以 ARKit為例,來看下它是如何工作的。如剛剛所說,AR 就是在實際環境中植入虛擬元素,那麼首先要識別出周圍環境,也就是通過 iPhone 的攝像頭來實現。在手機加速計、陀螺儀的幫助下,ARKit 可以識別3D 的環境並判斷手機在環境中的姿態。

通過以上實現過程,我們很容易理解 ARKit 的限制,比如:

  • 光線差:沒有足夠的光或光線過強的鏡面反光。嘗試避免這些光線差的環境。

  • 缺少紋理:如果攝像頭指向一面白牆,那也沒法獲得特徵,ARKit 也去無法找到並追蹤使用者。嘗試避免看向純色、反光表面等地方。

  • 快速移動:通常情況下檢測和估算 3D 姿態只會藉助圖片,如果攝像頭移動太快圖片就會糊,從而導致追蹤失敗。但 ARKit 會利用視覺慣性里程計,綜合圖片資訊和裝置運動感測器來估計使用者轉向的位置。因此 ARKit 在追蹤方面非常強大。

在完成環境識別之後,還需要渲染,通常我們會想到使用 OpenGL 或 Metal 渲染,但是它們的開發成本比較高,所以蘋果想了一辦法,就是通過 SceneKit 進行渲染。

我們可以通過以下幾行程式碼實現 AR,也就是“將大象關進冰箱”的第一步。

 @IBOutlet weak var sceneView: ARSCNView!
 override func viewDidAppear(_ animated: Bool) {
     super.viewDidAppear(animated)
     guard ARWorldTrackingConfiguration.isSupported else {
         return
     }
     let configuration = ARWorldTrackingConfiguration()
     configuration.planeDetection = .horizontal
     sceneView.session.run(configuration)
}

實現視訊通話功能

我們可以通過聲網Agora SDK 來快速實現視訊通話。在這樣的視訊通話場景中,聲網Agora SDK 具備幾個優勢:

低延時:聲網SDK 實時通訊網路,可實現全球百毫秒級音視訊通話;

快速整合:開發者最快可在30分鐘內完成整合;

全球化部署:支援全球200多個國家與地區。

在下載最新版聲網Agora SDK 後,將其新增到我們的 AR Demo 中。通過以下程式碼,可以基於 Agora 實現視訊會議。

 // 初始化引擎
 let agoraKit = AgoraRtcEngineKit.sharedEngine(withAppId: myAppId,
                                               delegate: self)
 // 設定為傳送端
 agoraKit.setChannelProfile(.liveBroadcasting)
 agoraKit.setClientRole(.broadcaster)
 agoraKit.enableVideo()
 // 加入會議
 agoraKit.joinChannel(byToken: nil,
                     channelId: “QCon2018”,
                     info: nil,
                     uid: 0,
                     joinSuccess: nil)

將視訊通話融入AR場景

在完成視訊會議的搭建之後,我們還需要傳輸本地視訊與音訊。

let videoSource = ARVideoSource()
agoraKit.setVideoSource(videoSource) 

func session(_ session: ARSession, didUpdate frame: ARFrame) {
    videoSource.sendBuffer(frame.capturedImage, timestamp: frame.timestamp)
}

1agoraKit.enableExternalAudioSource(withSampleRate: 44100, channelsPerFrame: 1)
1func session(_ session: ARSession, didOutputAudioSampleBuffer audioSampleBuffer: CMSampleBuffer) {
2 agoraKit.pushExternalAudioFrameSampleBuffer(audioSampleBuffer)
3}
最後,當我們通過SDK獲得了其它使用者發來的音視訊資料後,我們還需要將其渲染到AR環境中,實現方式如下。

 class ARVideoRenderer : NSObject, AgoraVideoSinkProtocol {
     var renderNode: SCNNode!
     func bufferType() -> AgoraVideoBufferType { return .rawData }
     func pixelFormat() -> AgoraVideoPixelFormat { return .I420 }
     func renderRawData(_ rawData: UnsafeMutableRawPointer,
                        size: CGSize,
                        rotation: AgoraVideoRotation) {
         let rgbTexture = createTexture(widthYUV: rawData, size: size, rotation: rotation)
         renderNode.geometry?.firstMaterial?.diffuse.contents = rgbTexture
    }
    func shouldInitialize() -> Bool { return setupMetal() }
    func shouldStart() { }
    func shouldStop() { }
    func shouldDispose() { }
}

我們曾在之前《基於ARKit與Agora SDK實現AR視訊會議》文章中分享了詳細的實現步驟,大家也可以訪問聲網Agora的Githu檢視原始碼。


聲網Agora有獎徵文活動 正在進行中,只要分享你與聲網SDK相關的開發經驗博文,即有機會獲得Cherry紅軸機械鍵盤、T恤等聲網定製獎品。詳情請戳這裡或微信諮詢(ID:dorianz)。