我司提供的IviewsSample项目可以正常运行,为了确保运行正常,在打开这个项目之后,在DevEco Studio界面上,按Ctrl + Shift + Alt + S,然后选择Signing Configs,登录账号并且勾选Support HarmonyOS和Automatically generate signature,生成一个签名。
SDK 里面包含了从注册,到最终观看设备视频,以及拍照、录像、对讲、变声、开锁等功能,具体需要哪些功能代码,可根据贵司项目需要进行删改。
登录、注册、获取设备列表等功能均为正常的网络请求,根据接口要求填写相关的参数请求即可,SDK只是提供访问示例,这些代码可以根据贵司使用的网络请求框架进行编写。
设备配网、观看设备直播这些功能,需要依赖相关的动态库,该部分代码需要将相关的代码和动态库负责到贵司的项目里面。目前我司仅提供arm64-v8a和x86_64两种CPU架构的动态库,若需要其他CPU架构的动态库,可以联系相关负责人。
目前我司有三个服务器如下:
中国大陆
正常网络请求:https://chniot.lancens.com:6448/
IOT地址:chniot.lancens.com
欧洲地区
正常网络请求:https://euriot.lancens.com:6448/
IOT地址:euriot.lancens.com
其他地区
正常网络请求:https://usaiot.lancens.com:6448/
IOT地址:usaiot.lancens.com
找到项目的module.json5文件,这个文件一般在”项目名/entry/src/main“目录下,其中entry是项目创建时默认名称,若贵司项目有修改,需以实际为准。然后在module.json5这个json文件中,module属性下面,增加requestPermissions属性,并且添加下面几个权限
xxxxxxxxxx
{
"module": {
..
"requestPermissions": [
{
"name": "ohos.permission.INTERNET"
},
{
"name": "ohos.permission.GET_WIFI_INFO",
},
{
"name": "ohos.permission.MICROPHONE",
"reason": "$string:Language0001",
"usedScene": {
"abilities": [
"EntryAbility"
],
"when": "always"
}
},
{
"name": "ohos.permission.ACCESS_BLUETOOTH",
"reason": "$string:Language0002",
"usedScene": {
"abilities": [
"EntryAbility"
],
"when": "always"
}
}
]
}
}
权限说明:
权限 | 说明 | 是否必须 |
---|---|---|
ohos.permission.INTERNET | 网络权限 | 是,基础权限必须 |
ohos.permission.GET_WIFI_INFO | 获取wifi信息 | 否,如果设备需要使用AP配网,或获取WiFi信息,则必须 |
ohos.permission.MICROPHONE | 麦克风权限 | 否,如果需要对讲功能,则必须 |
ohos.permission.ACCESS_BLUETOOTH | 访问蓝牙权限 | 否,如果设备需要使用蓝牙配网,则必须 |
其中,麦克风权限和蓝牙权限需要用户授权,所以需要在权限申请里面,增加申请原因(reason)和使用场景(usedScene),内容根据项目实际进行填写,如何填写,可以查看鸿蒙开发文档--声明权限
①将IviewsSample项目里面entry/libs的文件,全部放入贵司对应的目录下
②将entry\src\main下面的cpp目录同样拷贝到贵司对应的目录下。
③在项目entry\src的build-profile.json5文件里面,增加对Native的配置
x
{
。。。。
"buildOption": {
"externalNativeOptions": {
"path": "./src/main/cpp/CMakeLists.txt",
"arguments": "",
"cppFlags": "",
"abiFilters": ["x86_64", "arm64-v8a"]
}
},
。。。。
}
注:其中,path指向的是对应的CMakeLists.txt文件的路径,而abiFilters是需要编译哪些CPU架构,一般手机都是arm64-v8a,模拟器则是x86_64,可根据项目实际需要进行填写。
④在项目entry\src的oh-package.json5文件里面,增加对这几个动态库的引用
x
{
..
"dependencies": {
"libiviews_yuv_render.so": "file:./src/main/cpp/types/libiviews_yuv_render",
"libiviews_psd.so": "file:./src/main/cpp/types/libiviews_psd",
"libiviews_lanudp.so": "file:./src/main/cpp/types/libiviews_lanudp",
"libiviews_avapis.so": "file:./src/main/cpp/types/libiviews_avapis",
"libiviews_decoder.so": "file:./src/main/cpp/types/libiviews_decoder",
"libiviews_yuv.so": "file:./src/main/cpp/types/libiviews_yuv",
"libiviews_apm.so": "file:./src/main/cpp/types/libiviews_apm",
"libiviews_voaac.so": "file:./src/main/cpp/types/libiviews_voaac",
"libiviews_st.so": "file:./src/main/cpp/types/libiviews_st",
..
}
}
注意:上面的引用,引用路径如果不一样,需要修改!
cpp文件下的c++代码说明,这个是一个yuv渲染的程序,生成的动态库名称叫做iviews_yuv_render,如果贵司已经有cpp目录,需根据内部源码进行调整。
①直播流程可以查看直播流程图
②将src/main/ets/api下面的代码拷贝进入项目
③在项目里面增加播放控件
x
XComponent({
id: this.xComponentId,
type: XComponentType.TEXTURE,
libraryname: 'iviews_yuv_render'
})
.onLoad((xComponentContext?: object) => {
if (xComponentContext) {
this.xComponentContext = xComponentContext as XComponentContext;
}
})
.width('100%')
.height(300)
.backgroundColor(Color.Black)
在XComponent属性中:libraryname必须要和动态库里面的一样,否则会出错,如果贵司将cpp里面的代码调整过,库名改动过,这个也必须要改
④在连接连接设备之前,为了确保连接的地址没问题,需要先设置设备连接的IOT服务器地址
x
import IVIEWSAVAPIs from 'libiviews_avapis.so';
IVIEWSAVAPIs.init(服务器地址);
这个设置一般在项目启动时,或者用户修改了连接的服务器区域,区域和IOT地址见文档第一节内容。
⑤获取直播令牌(注意,不是登录的Token),这个是需要根据我司的登录Token去获取的,调用下面接口获取
xxxxxxxxxx
v1/api/user/device/all/${uid}/token
⑥创建连接
x
this.avClient = new AvClient(uid, token, callback, device, orientation, liveCallback);
参数说明:
uid:设备UID
token:直播令牌(不是登录的Token)
callback:连接和指令回调
device:设备类型
orientation:设备旋转角度
liveCallback:直播数据回调,包括yuv数据、码流变化、视频大小变化,如果不直播,改参数可以不传
两个回调创建如下
x
callback: AvClientCallback = {
commandCallback: (uid: string, cmd: number, data: Uint8Array | null, obj: object | number | null) => {
switch (cmd) {
//这里处理与设备交互时,指令收取的情况
}
},
clientResultCallBack: async (uid: string, avIndex: number) => {
////当avIndex >= 0表示建立IOT成功,否则失败,可能原因是设备不在线,或者网络原因
if (avIndex >= 0) {
//这里是连接成功,发给设备的所有指令都必须是在连接成功的情况下
} else {
//连接IOT失败,可能原因,网络或者设备离线
}
}
};
liveCallback: AvClientLiveCallback = {
recvVideoData: async (yuvData: Uint8Array, width: number, height: number) => {
//渲染画面,width和height是画面的大小
if (this.xComponentContext) {
this.xComponentContext.showYuv(yuvData, width, height);
}
},
onStreamChange: (oldStream: number, newStream: number) => {
//码流格式变化,比如h264变成jpg这种的
},
onStreamSizeChange: (): void => {
//视频流画面大小改变
}
};
⑦观看直播,调用方法
x
//其中currentCameraId是由于部分设备有多个摄像头,发送对应的摄像头ID,获取对应的摄像头实时画面,如果只有一个,填入-100即可
DeviceFunc.requestAvStart(this.avClient, this.currentCameraId)
⑧退出直播
x
//退出直播前先发送停止直播指令
DeviceFunc.requestAvStop(this.avClient);
//然后调用关闭
if (this.avClient) {
this.avClient.closeClient();
}
this.avClient = undefined
直播时异常情况处理
由于网络环境、业务和一些不可控的因素,无法保障每次连接设备观看直播都能成功,这部分逻辑可结合直播流程图来分析,所以需要对一些异常情况做处理,这个过程需要根据企业的业务逻辑自行编写逻辑(提示用户、重连...)
获取连接令牌
这个步骤是单纯的网络请求,根据请求结果做处理即可
AvClient回调的clientResultCallBack方法,当参数avIndex小于0时。
出现这种情况说明设备掉线或者无法连接服务器成功,这种情况建议关闭连接,释放资源
指令返回
由于业务逻辑等问题,当收到指令27(APP_CTRL_DEVICE_OFFLINE)或10002(APP_CTRL_USER_ONLINE_RESP)时,说明设备离线或者被其他人占用,这种情况就可以关闭连接释放资源
当发送直播指令,若APP长时间没有收到P2P地址<指令9>
出现这种情况,建议重连,即释放AvClient资源,然后走重新获取连接令牌的流程
当获取到P2P地址<指令9>,但是commandCallback回调的obj的值小于0
这种情况说明建立P2P失败,无法建立连接通道,这种情况可以关闭连接,释放资源
当获取到P2P地址<指令9>,并且obj的值>=0,但是一直没有显示画面
这种情况有可能是网络太差,导致画面数据传输有问题。若长时间没有显示,可以关闭连接重连。
排查具体是什么原因连接不上设备
当你发现无法连接设备时,你可以在下述代码中,增加日志打印来确定是什么原因导致的。
在AvClient里面找到下面的callback函数,然后增加打印:
xxxxxxxxxx
callback(type: number, cmd: number, len: number, data: Uint8Array | null) {
console.log('打印>>>', "callback: " + type + " " + cmd + " " + len);
}
根据type和len的值,来判断是什么原因
当type值为TYPE.IVIEWS_CONNECTION:
xxxxxxxxxx
0:连接成功
-1:连接失败
-2:连接断开
当type值为TYPE.IVIEWS_LOGIN:
xxxxxxxxxx
0:成功
-1:设备离线或者设备不存在
-2:注册信息错误
-3:重复登录
-4:验证错误,直播token错误或者分享设备不在分享时段
当type值为TYPE.P2P_CONNECTION:
xxxxxxxxxx
0:成功
-3:P2P超时
-101:P2P连接关闭
其他:P2P失败
AP配网的功能是通过连接设备WiFi,发送需要连接的网络信息给设备,设备根据网络信息连接网络,然后用户添加这个设备。而需要进行AP配网,则需要libiviews_lanudp.so这个库,具体的使用请查看entry\src\main\ets\pages\apconfig下面的代码。
蓝牙配网的功能是通过连接设备蓝牙,然后通过发送蓝牙配网请求,设备联网成功之后,会返回UID,然后用户根据UID添加设备,需要的蓝牙配网相关代码在entry\src\main\ets\pages\blconfig,而这个目录下面的manager目录则是相关的蓝牙配网以来代码。
1、设备不支持AP配网
①不使用pages/apconfig下面的代码
②删除对应动态库:libs/${OHOS_ARCH}/libiviews_lanudp.so,并且将cpp/types/libiviews_lanudp删除,移除entry/oh-package.json5里面libiviews_lanudp.so的引用
2、设备不支持蓝牙配网
①不使用pages/blconfig下面的代码
3、不需要变声功能
①删除SoundTouch.ets这个文件,然后报错的地方,全部删除
②删除对应动态库:libs/${OHOS_ARCH}/libiviews_st.so,并且将cpp/types/libiviews_st删除,移除entry/oh-package.json5里面libiviews_st.so的引用
4、设备不支持临时密码
①不使用pages/temporarypwd下面的代码
②删除对应动态库:libs/${OHOS_ARCH}/libiviews_psd.so,并且将cpp/types/libiviews_psd删除,移除entry/oh-package.json5里面libiviews_psd.so的引用
①删除Mp4Recoder.ets这个文件,然后报错的地方,全部删除
②删除对应动态库:libs/${OHOS_ARCH}/libiviews_voaac.so,并且将cpp/types/libiviews_voaac删除,移除entry/oh-package.json5里面libiviews_voaac.so的引用
最后编辑时间:2024年11月29日