部分開發者在基於 Agora SDK 作視頻聊天應用時,但願能夠在視頻流發出前能夠加入美顏處理。基於這樣的需求,咱們在 SDK 中提供了自採集視頻源接口。在本文中,咱們將講解該接口的使用方法,並經過案例來分析一些常見問題。本文首發於由聲網創建的RTC 開發者社區,若有疑問,請點擊連接直接與做者詢問。html
自採集+美顏的處理流程以下:java
本地視圖顯示,不作具體要求,可用戶本身實現;也可以使用MediaIO 中的 IVideoSink 接口來自定義渲染器,經過 setLocalVideoRenderer來顯示 。canvas
一、 MediaIO 接口
setVideoSource(IVideoSource source)
網絡
實時通信過程當中,Agora SDK 一般會啓動默認的視頻輸入設備,即內置的攝像頭,進行視頻推流。當須要自定義視頻設備時,App 能夠先經過 IVideoSource 接口自定義視頻源,而後調用該方法將自定義的視頻源加入到 SDK 中。ide
即經過IVideoSource中
的onInitiali獲取一個IVideoFrameConsumer
的consumer
對象;而後經過consumer
給SDK傳送視頻數據。佈局
其中,consumer支持接收三種 Buffer 類型的視頻幀數據:ByteBuffer、ByteArray 和 Texture。請調用 getBufferType 方法指定 Buffer 類型。spa
consumer
的傳輸方法:3d
consumeByteBufferFrame、consumeByteArrayFrame、consumeTextureFrame
code
調用示例:orm
mConsumer.consumeByteArrayFrame(data, AgoraVideoFrame.NV21, width, height, rotation, timestamp);
二、push接口
pushExternalVideoFrame( AgoraVideoFrame frame )
該方法主動將視頻幀數據用 AgoraVideoFrame 類封裝後傳遞給 SDK。請確保在你調用本方法前已調用 setExternalVideoSource,並將參數 pushMode 設爲 true,否則調用本方法後會一直報錯。
這裏是直接將視頻數據經過pushExternalVideoFrame直接傳給SDK。
調用示例:
vf.format = AgoraVideoFrame.FORMAT_TEXTURE_2D;
vf.timeStamp = System.currentTimeMillis();
vf.stride = 480;
vf.height = 640;
vf.textureID = fuTexId;
vf.syncMode = true;
vf.eglContext11 = eglContext;
vf.transform = matrix;
boolean result = mRtcEngine.pushExternalVideoFrame(vf);
複製代碼
這裏須要特別注意兩點,
一、timeStamp
必須傳當前系統的時間戳System.currentTimeMillis()
;
二、通訊模式下,push不支持texture;如使用了,遠端會顯示黑屏。
兩個自採集接口對比:
推薦使用MediaIo接口。相對於push接口,MediaIo配置靈活,支持的視頻格式更全,支持頻道內動態切換自採集/sdk採集(setVideoSource(new AgoraDefaultSource());)。
如上流程圖,自採集時本地視圖顯示不在咱們SDK傳輸的範圍內的。所以本地視圖顯示,不作具體要求,可本身實現;也可以使用MediaIO
中的 IVideoSink
接口來自定義渲染器,經過setLocalVideoRenderer
來顯示
注:自採集須要自渲染,這裏不要使用setupLocalVideo
(SDK採集時的)去作本地視圖顯示。
對於接入美顏時出現的問題,總的排查思路是:看出問題的是本地仍是遠端。
一、若本地正常遠端異常,排查Mediaio/push的數據格式處;
二、若本地異常遠端正常,排查本地渲染;
三、若是本地遠端都異常,先排查本地預覽和第三方美顏的渲染處理,而後排查Mediaio/push的處理。
(1)花屏現象
花屏問題通常是視頻格式的問題。
一、若本地預覽正常,遠端花屏。通常出在傳給Mediaio/push
的數據格式處,傳給咱們的數據與採集處理後數據格式不一致致使的,這裏能夠在Mediaio/push
處將視頻數據dump下來看是否正常;
二、若本地預覽花屏,遠端正常。如自採集流程圖所示,通常是採集數據格式和本地視圖渲染的數據不一致致使的;
三、若是上面方式排除了還存在問題,可收集下信息,好比是不是單機出現、SDK自己影響的問題、出現的條件以及dump。
(2)綠屏
綠屏問題通常是分辨率出現問題。
可檢查下,
一、採集視頻數據的分辨率和Mediaio/push
處的寬高是否一致;
二、傳給Mediaio/push處的視頻數據是正常,不爲空;
三、如還存在問題,可收集下信息,好比是不是單機出現、SDK自己影響的問題、出現的條件以及dump。
(3)加頻道後界面卡住,最後收到SDK connection lost 事件(注:該案例爲gongyuhua 分享 )
用戶網絡正常,因此 connection lost 是由於App卡住10s以上致使和服務端之間鏈接超時,根本緣由是界面卡住。
用戶表示註釋掉一個方法後就沒這個現象,檢查發現這個方法裏大部分是聲網SDK的初始化、設置和加頻道。
檢查其中非聲網的調用,發現有開啓自採集和佈局界面的方法。
引導用戶只註釋開啓自採集的方法,現象消失。繼續調查這個自採集方法,發現是使用FaceUnity自帶的採集和渲染。
繼續註釋關鍵代碼,定位到關鍵調用是把一個glView設給canvas。調查這個glView發現是FaceUnity建立的本地預覽視圖。
結論:使用FaceUnity自採集和預覽的狀況下,用戶不須要調用setupLocalVideo。若是用戶經過這個API把Faceunity建立的本地預覽視圖設給SDK,會形成主界面卡住。