这段时间工作上需要在Android设备上读取视频。摄像头用的是奥比中光的3D摄像头。我手上的摄像头的彩色通道使用的的UVC协议的。
在Xamarin上可用的UVC的封装基本上没有,只有一个小伙在Xamarin的论坛上说到可以绑定成功,并提供了测试的APK,可惜是是没有提供bind的库。
没有办法了,只能自力更生了。
一、绑定Java的AAR库
这里有三个原生库绑定:
- usbcameracommon.aar
- common.aar
- uvccamera.aar
其中common.aar是最复杂的,里面有很多地方无法直接绑定,特别是CollectionMap,这里面很神奇的put函数怎么调整都无法绑定成功,最终只能去掉这个类了。
其他的绑定就比较容易了。
<metadata> <attr path="/api/package[@name='com.serenegiant.media']/interface[@name='IRecorder']" name="managedName">IRecorder</attr> <attr path="/api/package[@name='com.serenegiant.mediaeffect']/interface[@name='IEffect']" name="managedName">IEffect</attr> <attr path="/api/package[@name='com.serenegiant.utils']/class[@name='CollectionMap']/method[@name='entrySet' and count(parameter)=0]" name="managedReturn">System.Collections.ICollection</attr> <attr path="/api/package[@name='com.serenegiant.utils']/class[@name='CollectionMap']/method[@name='get' and count(parameter)=1 and parameter[1][@type='java.lang.Object']]" name="managedReturn">Java.Lang.Object</attr> <attr path="/api/package[@name='com.serenegiant.utils']/class[@name='CollectionMap']/method[@name='remove' and count(parameter)=1 and parameter[1][@type='java.lang.Object']]" name="managedReturn">Java.Lang.Object</attr> <attr path="/api/package[@name='com.serenegiant.utils']/class[@name='CollectionMap']/method[@name='values' and count(parameter)=0]" name="managedReturn">System.Collections.ICollection</attr> <attr path="/api/package[@name='com.serenegiant.utils']/class[@name='CollectionMap']/method[@name='put' and count(parameter)=2 and parameter[1][@type='K'] and parameter[2][@type='java.util.Collection<V>']]" name="managedReturn">Java.Lang.Object</attr> <attr path="/api/package[@name='com.serenegiant.utils']/class[@name='CollectionMap']/method[@name='put' and count(parameter)=2 and parameter[1][@type='K'] and parameter[2][@type='java.util.Collection<V>']]" name="managedReturn">Java.Lang.Object</attr> <attr path="/api/package[@name='com.serenegiant.utils']/class[@name='CollectionMap']/method[@name='put' and count(parameter)=2 and parameter[1][@type='K'] and parameter[2][@type='java.util.Collection<V>']]/parameter[2]" name="managedType">Java.Lang.Object</attr> <attr path="/api/package[@name='com.serenegiant.mediaeffect']/class[@name='MediaEffect']/method[@name='resize' and count(parameter)=2 and parameter[1][@type='int'] and parameter[2][@type='int']]" name="managedReturn">Com.Serenegiant.Mediaeffect.IEffect</attr> <attr path="/api/package[@name='com.serenegiant.mediaeffect']/class[@name='MediaEffectGLESBase']/method[@name='resize' and count(parameter)=2 and parameter[1][@type='int'] and parameter[2][@type='int']]" name="managedReturn">Com.Serenegiant.Mediaeffect.IEffect</attr> <remove-node path="/api/package[@name='com.serenegiant.widget']/class[@name='AspectScaledTextureView']/method[@name='setSurfaceTextureListener' and count(parameter)=1 and parameter[1][@type='android.view.TextureView.SurfaceTextureListener']]" /> <remove-node path="/api/package[@name='com.serenegiant.utils']/class[@name='CollectionMap']" /> <remove-node path="/api/package[@name='com.serenegiant.widget']/interface[@name='CustomRecycleViewListener']" /> <remove-node path="/api/package[@name='com.serenegiant.glutils']/class[@name='EGLBase10']" /> <remove-node path="/api/package[@name='com.serenegiant.glutils']/class[@name='EGLBase14']" /> </metadata>
由于一个Android绑定库只能绑定一个aar,绑定好以后再引用到主项目是有问题的,所以有引用关系的绑定库之间还需要各自引用相关的的绑定库。
二、绑定Native库
Native库的绑定十分纠结,默认找到的库是armeabi-v7a的,在Android原生的环境下可以运行,但是在Xamarin的Android死活不能运行,指认arm64-v8a的库。
下载了UVCCamera源代码生成了arm64-v8a后,程序可以运行起来,可是初始化摄像头的时候出现“could not open camera:err=-1”,这个在官网看了一下,大多提到了NDK的问题,VS2019安装的NDK是1.9的。因此删除后重新安装1.4的,结果就正常了。
详细代码参见GitHub