/** *请求开始接受UVC机器的影像 *通常通过StartPreview(string deviceName)调用 * @param deviceName UVC機器識別文字列 * @param width * @param height */ private void StartPreview(string deviceName, int width, int height) { AndroidDebug.Logd(TAG, "请求开始接受UVC机器的影像:" + deviceName + "-" + width + "-" + height); var info = Get(deviceName); if (info != null) { //连接时 var supportedVideoSize = GetSupportedVideoSize(deviceName); if (supportedVideoSize == null) { AndroidDebug.Logd(TAG, "连接时:fauled to get supported video size"); throw new ArgumentException("fauled to get supported video size"); } //对应分辨率的检查 if (supportedVideoSize.Find(width, height /*,minFps=0.1f, maxFps=121.0f*/) == null) { //不支持指定的分辨率 #if (!NDEBUG && DEBUG && ENABLE_LOG) Console.WriteLine($"{TAG}StartPreview:{width}x{height} is NOT supported."); Console.WriteLine($"{TAG}Info={GetDevice(deviceName)}"); Console.WriteLine($"{TAG}supportedVideoSize={supportedVideoSize}"); #endif AndroidDebug.Logd(TAG, "不支持指定的分辨率"); throw new ArgumentOutOfRangeException($"{width}x{height} is NOT supported."); } if (info.IsOpen && !info.IsPreviewing) { //被open,但未取得影像时 info.SetSize(width, height); info.previewTexture = new Texture2D( width, height, TextureFormat.ARGB32, false, /* mipmap */ true /* linear */); var nativeTexPtr = info.previewTexture.GetNativeTexturePtr(); AndroidDebug.Logd(TAG, "被open,但未取得影像时:" + nativeTexPtr); using (AndroidJavaClass clazz = new AndroidJavaClass(FQCN_PLUGIN)) { clazz.CallStatic("setPreviewTexture", AndroidUtils.GetCurrentActivity(), deviceName, nativeTexPtr.ToInt32(), -1, //PreviewMode,-1:自动选择(Open时指定的PreferH 264标志有效) width, height); } StartCoroutine(info.OnRender()); } } else { AndroidDebug.Logd(TAG, "StartPreview:device name is empty/null"); throw new ArgumentException("device name is empty/null"); } }
/** *要求结束从UVC机器接收影像 * @param deviceName UVC设备识别字符串 */ private void RequestStopPreview(string deviceName) { AndroidDebug.Logd(TAG, "要求结束从UVC机器接收影像:" + deviceName); if (!String.IsNullOrEmpty(deviceName)) { using (AndroidJavaClass clazz = new AndroidJavaClass(FQCN_PLUGIN)) { clazz.CallStatic("stopPreview", AndroidUtils.GetCurrentActivity(), deviceName); } } }
/** * UVC機器からの映像受け取り開始要求をする * 通常はStartPreview(string deviceName)経由で呼び出す * @param deviceName UVC機器識別文字列 * @param width * @param height */ private void StartPreview(string deviceName, int width, int height) { #if (!NDEBUG && DEBUG && ENABLE_LOG) Console.WriteLine($"{TAG}StartPreview:{deviceName}({width}x{height})"); #endif var info = Get(deviceName); if (info != null) { // 接続されているとき var supportedVideoSize = GetSupportedVideoSize(deviceName); if (supportedVideoSize == null) { throw new ArgumentException("fauled to get supported video size"); } // 対応解像度のチェック if (supportedVideoSize.Find(width, height /*,minFps=0.1f, maxFps=121.0f*/) == null) { // 指定した解像度に対応していない #if (!NDEBUG && DEBUG && ENABLE_LOG) Console.WriteLine($"{TAG}StartPreview:{width}x{height} is NOT supported."); Console.WriteLine($"{TAG}Info={GetDevice(deviceName)}"); Console.WriteLine($"{TAG}supportedVideoSize={supportedVideoSize}"); #endif throw new ArgumentOutOfRangeException($"{width}x{height} is NOT supported."); } if (info.IsOpen && !info.IsPreviewing) { // openされているけど映像取得中ではないとき info.SetSize(width, height); info.previewTexture = new Texture2D( width, height, TextureFormat.ARGB32, false, /* mipmap */ true /* linear */); var nativeTexPtr = info.previewTexture.GetNativeTexturePtr(); #if (!NDEBUG && DEBUG && ENABLE_LOG) Console.WriteLine($"{TAG}RequestStartPreview:tex={nativeTexPtr}"); #endif using (AndroidJavaClass clazz = new AndroidJavaClass(FQCN_PLUGIN)) { clazz.CallStatic("setPreviewTexture", AndroidUtils.GetCurrentActivity(), deviceName, nativeTexPtr.ToInt32(), -1, // PreviewMode, -1:自動選択(Open時に指定したPreferH264フラグが有効になる) width, height); } StartCoroutine(info.OnRender()); } } else { throw new ArgumentException("device name is empty/null"); } }
/** * UVC機器からの映像受けとりを終了要求をする * @param deviceName UVC機器識別文字列 */ private void RequestStopPreview(string deviceName) { #if (!NDEBUG && DEBUG && ENABLE_LOG) Console.WriteLine($"{TAG}RequestStopPreviewUVC:{deviceName}"); #endif if (!String.IsNullOrEmpty(deviceName)) { using (AndroidJavaClass clazz = new AndroidJavaClass(FQCN_PLUGIN)) { clazz.CallStatic("stopPreview", AndroidUtils.GetCurrentActivity(), deviceName); } } }
/** * 指定したUSB機器をアクセスするパーミッションを持っているかどうかを取得 * @param deviceName UVC機器識別文字列 */ private bool HasUsbPermission(string deviceName) { if (!String.IsNullOrEmpty(deviceName)) { using (AndroidJavaClass clazz = new AndroidJavaClass(FQCN_PLUGIN)) { return(clazz.CallStatic <bool>("hasPermission", AndroidUtils.GetCurrentActivity(), deviceName)); } } else { return(false); } }
/** *获取指定的UVC设备的对应分辨率 *@param deviceName UVC设备识别字符串 */ private SupportedFormats GetSupportedVideoSize(string deviceName) { AndroidDebug.Logd(TAG, "获取指定的UVC设备的对应分辨率:" + deviceName); if (!String.IsNullOrEmpty(deviceName)) { using (AndroidJavaClass clazz = new AndroidJavaClass(FQCN_PLUGIN)) { return(SupportedFormats.Parse( clazz.CallStatic <string>("getSupportedVideoSize", AndroidUtils.GetCurrentActivity(), deviceName))); } } else { throw new ArgumentException("device name is empty/null"); } }
/** * プラグインを初期化 * uvc-plugin-unityへの処理要求 */ private void InitPlugin() { #if (!NDEBUG && DEBUG && ENABLE_LOG) Console.WriteLine($"{TAG}InitPlugin:"); #endif // IUVCDrawersが割り当てられているかどうかをチェック var hasDrawer = false; if ((UVCDrawers != null) && (UVCDrawers.Length > 0)) { foreach (var drawer in UVCDrawers) { if (drawer is IUVCDrawer) { hasDrawer = true; break; } } } if (!hasDrawer) { // インスペクタでIUVCDrawerが設定されていないときは // このスクリプトがaddされているゲームオブジェクトからの取得を試みる #if (!NDEBUG && DEBUG && ENABLE_LOG) Console.WriteLine($"{TAG}InitPlugin:has no IUVCDrawer, try to get from gameObject"); #endif var drawers = GetComponents(typeof(IUVCDrawer)); if ((drawers != null) && (drawers.Length > 0)) { UVCDrawers = new Component[drawers.Length]; int i = 0; foreach (var drawer in drawers) { UVCDrawers[i++] = drawer; } } } #if (!NDEBUG && DEBUG && ENABLE_LOG) Console.WriteLine($"{TAG}InitPlugin:num drawers={UVCDrawers.Length}"); #endif // aandusbのDeviceDetectorを読み込み要求 using (AndroidJavaClass clazz = new AndroidJavaClass(FQCN_DETECTOR)) { clazz.CallStatic("initUVCDeviceDetector", AndroidUtils.GetCurrentActivity()); } }
/** * 获取指定的UVC设备的信息(现在是vid和pid)作为UVC设备 * @param deviceName UVC设备识别字符串 */ private UVCDevice GetDevice(string deviceName) { AndroidDebug.Logd(TAG, "获取指定的UVC设备的信息1:" + deviceName); if (!String.IsNullOrEmpty(deviceName)) { using (AndroidJavaClass clazz = new AndroidJavaClass(FQCN_PLUGIN)) { AndroidDebug.Logd(TAG, "获取指定的UVC设备的信息2:" + AndroidUtils.GetCurrentActivity()); AndroidDebug.Logd(TAG, "获取指定的UVC设备的信息2:" + clazz.CallStatic <string>("getInfo", AndroidUtils.GetCurrentActivity(), deviceName)); return(UVCDevice.Parse(deviceName, clazz.CallStatic <string>("getInfo", AndroidUtils.GetCurrentActivity(), deviceName))); } } else { throw new ArgumentException("device name is empty/null"); } }
/** * 对指定的UVC设备进行close * @param deviceName UVC设备识别字符串 */ private void Close(string deviceName) { AndroidDebug.Logd(TAG, "对指定的UVC设备进行close:" + deviceName); var info = Get(deviceName); if ((info != null) && (info.activeCameraId != 0)) { info.SetSize(0, 0); info.activeCameraId = 0; info.previewTexture = null; using (AndroidJavaClass clazz = new AndroidJavaClass(FQCN_PLUGIN)) { clazz.CallStatic("closeDevice", AndroidUtils.GetCurrentActivity(), deviceName); } } #if (!NDEBUG && DEBUG && ENABLE_LOG) Console.WriteLine($"{TAG}Close:finished"); #endif }
/** * 启动指定的UVC机器 * @param deviceName UVC设备识别字符串 */ private void Open(string deviceName) { AndroidDebug.Logd(TAG, "USB设备访问权限要求:" + deviceName); var info = Get(deviceName); if (info != null) { AndroidUtils.isPermissionRequesting = false; using (AndroidJavaClass clazz = new AndroidJavaClass(FQCN_PLUGIN)) { info.activeCameraId = clazz.CallStatic <Int32>("openDevice", AndroidUtils.GetCurrentActivity(), deviceName, DefaultWidth, DefaultHeight, PreferH264); } } else { throw new ArgumentException("device name is empty/null"); } }
/** * 指定したUVC機器の対応解像度を取得する * @param deviceName UVC機器識別文字列 */ private SupportedFormats GetSupportedVideoSize(string deviceName) { #if (!NDEBUG && DEBUG && ENABLE_LOG) Console.WriteLine($"{TAG}GetSupportedVideoSize:{deviceName}"); #endif if (!String.IsNullOrEmpty(deviceName)) { using (AndroidJavaClass clazz = new AndroidJavaClass(FQCN_PLUGIN)) { return(SupportedFormats.Parse( clazz.CallStatic <string>("getSupportedVideoSize", AndroidUtils.GetCurrentActivity(), deviceName))); } } else { throw new ArgumentException("device name is empty/null"); } }
/** * USB设备访问权限要求 * @param deviceName UVC设备识别字符串 */ private void RequestUsbPermission(string deviceName) { AndroidDebug.Logd(TAG, "USB设备访问权限要求:" + deviceName); if (!String.IsNullOrEmpty(deviceName)) { AndroidUtils.isPermissionRequesting = true; using (AndroidJavaClass clazz = new AndroidJavaClass(FQCN_PLUGIN)) { clazz.CallStatic("requestPermission", AndroidUtils.GetCurrentActivity(), deviceName); } } else { throw new ArgumentException("device name is empty/null"); } #if (!NDEBUG && DEBUG && ENABLE_LOG) Console.WriteLine($"{TAG}RequestUsbPermission[{Time.frameCount}]:finsihed"); #endif }
/** * 指定したUVC機器をopenする * @param deviceName UVC機器識別文字列 */ private void Open(string deviceName) { #if (!NDEBUG && DEBUG && ENABLE_LOG) Console.WriteLine($"{TAG}Open:{deviceName}"); #endif var info = Get(deviceName); if (info != null) { AndroidUtils.isPermissionRequesting = false; using (AndroidJavaClass clazz = new AndroidJavaClass(FQCN_PLUGIN)) { info.activeCameraId = clazz.CallStatic <Int32>("openDevice", AndroidUtils.GetCurrentActivity(), deviceName, DefaultWidth, DefaultHeight, PreferH264); } } else { throw new ArgumentException("device name is empty/null"); } }
//对Uvc-Plugin-unity的处理要求 /** *初始化插件 */ private void InitPlugin() { AndroidDebug.Logd(TAG, "InitPlugin:"); //确认是否分配了IUVC Drawers var hasDrawer = false; if ((UVCDrawers != null) && (UVCDrawers.Length > 0)) { foreach (var drawer in UVCDrawers) { if (drawer is IUVCDrawer) { hasDrawer = true; break; } } } if (!hasDrawer) { // 在检查器中未设定IUVCD服务器时 //试图从已加载了该脚本的游戏对象中获取 AndroidDebug.Logd(TAG, "InitPlugin:has no IUVCDrawer, try to get from gameObject"); var drawers = GetComponents(typeof(IUVCDrawer)); if ((drawers != null) && (drawers.Length > 0)) { UVCDrawers = new Component[drawers.Length]; int i = 0; foreach (var drawer in drawers) { UVCDrawers[i++] = drawer; } } } using (AndroidJavaClass clazz = new AndroidJavaClass(FQCN_PLUGIN)) { clazz.CallStatic("initDeviceDetector", AndroidUtils.GetCurrentActivity(), gameObject.name); } }