了解更多开源请访问:开源基础软件社区https://ost.51cto.com前两篇文章已经介绍了分布式摄像头应用开发的全过程。有兴趣的可以回顾一下:OpenHarmonyDistributedCamera(Part1)OpenHarmonyDistributedCamera(中)本文主要讲的是分布式相机开发过程中遇到的一些问题和思考,因为本地人目前主要是从北方开始,所以我只从应用开发的角度总结目前遇到的问题。如果有一些低级错误,还望各位老师不吝赐教。分布式摄像头问题一览对于开发过程中遇到的一些坑,前面两篇文章简单提到了其中的一些。这里的正则化也是一种复习。1.第一次授权后无法显示相机预览。分析:我们一般在加载MainAbility.ts的onCreate()函数时申请授权。在index.ets页面,回调XComponent组件onLoad()时,会执行初始化相机操作。代码如下:MainAbility.tsconstTAG:string='[DistributedCamera]'letpermissionList:Array=["ohos.permission.MEDIA_LOCATION","ohos.permission.READ_MEDIA","ohos.permission.WRITE_MEDIA","ohos.permission.CAMERA","ohos.permission.MICROPHONE","ohos.permission.DISTRIBUTED_DATASYNC"]exportdefaultclassMainAbilityextendsAbility{asynconCreate(want,launchParam){console.info(`${TAG}onCreate`)globalThis.cameraAbilityContext=this.contextawaitglobalThis.cameraAbilityContext.requestPermissionsFromUser(permissionList)}}index.ets//...//截取部分主代码Column(){XComponent({id:'componentId',type:'surface',controller:this.XComponentController}).onLoad(async()=>{console.info(`${TAG}XComponentonLoadis调用`)this.XComponentController.setXComponentSurfaceSize({surfaceWidth:Resolution.DEFAULT_WIDTH,surfaceHeight:Resolution.DEFAULT_HEIGHT})this.surfaceId=this.XComponentController.getXComponentSurfaceId()console.info(`${TAG}surfaceId:${this.}`)awaitthis.initCamera()}).height('100%').width('100%')}.width('100%').height('75%').margin({bottom:20})//...应用启动后,调用requestPermissionsFromUser()请求权限后,未手动授权,查看相关日志:日志告诉我们页面的生命周期已经开始onShow,页面layout也完成了Loading,XComponent组件回调了onLoad(),但是camera因为没有被授权而无法初始化。此时即使授权成功,也不会再次初始化,导致相机无法启动。知道了原因后,我们就可以有多种关键是授权完成后,需要再次触发初始化摄像头,才能启动摄像头正常预览。我的处理方法:1.在index.ets页面处理授权2.定义是否授权标志,用于判断摄像头是否可以初始化3.定义摄像头标志是否已经初始化,防止这次初始化4.初始化pagepage在函数aboutToAppear()中请求权限,并在权限申请结果中加入初始化相机操作5.XComponent回调onLoad()初始化相机操作不变index.etsprivateisInitCamera:boolean=false//相机是否已经initializedprivateisPermissions:boolean=false//是否完成授权asyncaboutToAppear(){console.info(`${TAG}aboutToAppear`)globalThis.cameraAbilityContext.requestPermissionsFromUser(permissionList).then(async(data)=>{console.info(`${TAG}datapermissions:${JSON.stringify(data.permissions)}`)console.info(`${TAG}dataauthResult:${JSON.stringify(data.authResults)}`)//判断是否授权zation完成letresultCount:number=0for(letresultofdata.authResults){if(result===0){resultCount+=1}}if(resultCount===permissionList.length){this.isPermissions=true}awaitthis.initCamera()//获取缩略图this.mCameraService.getThumbnail(this.functionBackImpl3、加载远程摄像头,在session管理中添加摄像头输出流,无法拍照,预览黑屏分析:两台设备的pin码认证已通过,连接成功,当主人选择一个被控设备,加载相机,过程和加载本地相机一样,过程如下:PreviewOutput)*createSession.addOutput(PhotoOutput)*createSession.commitConfig()*createSession.start()经过排查,发现日志中返回了notfoundinsupportedstreams的异常。详情请查看相关issues原因:创建PhotoOutput时,需要传入支持的照片配置信息Profile,这里的Profile可以通过CmeraManager.getSupportedOutputCapability()返回的相机输出能力CameraOutputCapability对象获取,但是远程相机设备photooutputcapabilitylist返回空,但是通过查看本地相机的photooutputcapability,我们可以知道DAYU200设备支持的Profile信息:photoProfile{"format":2000,"size":{"width":1280,"height":960}}使用photoProfile作为远程摄像头设备构造照片输出流的输入场景照片输出流,并将这个添加到photo会话管理中,但是接口不支持这个摄像头配置,最后是摄像头被关闭,导致黑屏。解决方案:针对这个问题,目前只能根据场景判断是否需要将照片输出流添加到session管理中。对于本地摄像头,可以添加照片输出流来进行照片业务。远程相机不添加照片输出流,这是不可能的。开展图片业务,希望社区有解决办法。4、在不同设备上切换摄像头时,摄像头预览输出流异常,无法显示远程摄像头的图像分析:这个问题可能有多种原因。这里我就说一下我遇到的情况。1.分布式连接阻塞Disconnected,但是因为底层机制的原因,设备下线需要一段时间才能上报(估计5分钟),所以可以连接到应用层的远程设备是实际上是离线的,当然此时不能切换到远程摄像头。2、同问题3描述的一样,因为添加了一个不支持的摄像头配置信息,摄像头被关闭了。解决方法1.等待下线通知,然后重新连接设备,或者等待设备自动完成重新连接。只需重新启动设备即可。2.等待社区的反馈。5.摄像头业务在主线程上执行。需要将业务移到子线程中,防止UI线程被阻塞。预览、拍照、保存图片等线程,目前正在修改优化中。ets的异步线程worker可以参考之前的一篇文章:OpenHarmonystageworker多线程。6、远程摄像头预览数据传输有500ms的延时。分析:在wifi环境下,被控摄像头通过软总线将预览数据传给主控显示,有500ms左右的延时。这个问题需要调查,具体是在那个环境下出现的延迟。7、函数调用分析无权限:用户动态授予:允许不同设备之间的数据(ohos.permission.DISTRIBUTED_DATASYNC)交换权限后DeviceManager.startDeviceDiscovery()开始发现外围设备一直有异常,日志提示:discoverFaildata={"subscribeId":26386,"reason":-20007,"errInfo":"无函数调用权限。"}原因:非系统应用无法使用DeviceManager。详情请参考:issues解决方案:系统应用通过签名来区别于普通应用,所以只要将签名UnsgnedReleasedProfileTemplate.json文件中的app-feature值修改为ohos_system_app,就是一个系统应用。了解更多开源请访问:开源基础软件社区https://ost.51cto.com