APP下载
Android
扫描二维码下载安装
Android download qr code
账号
注册
使用邮箱进行注册,填入邮箱和密码之后,点击发送验证码。
将邮箱收到的验证码填入,点击注册即可。
如图示。
邮箱登录
填入完整的邮箱和密码,之后点击登录。如图示。
修改密码
如图所示,进行修改即可。如图示。
忘记密码
如图所示,按照图示进行修改即可。如图示。
设备
多媒体设备
添加设备
按照图示顺序进行操作,默认将房间添加到全屋。
在使用的过程中,需要打开位置服务、蓝牙,以及在设置中,将此应用的位置权限打开。
移除设备
长按图示区域,会弹出提示框。
设备操作
首页点击已添加的设备,会进入此设备的操作界面。包含各种功能控制按钮。默认进入之后,会打开camera。
AI玩具
添加设备
按照图示顺序进行操作,默认将房间添加到全屋。
添加设备之前,请确保此设备已经被移除。(请参考下节:移除设备)
在使用的过程中,需要打开位置服务、蓝牙,以及在设置中,将此应用的位置权限打开。
移除设备
长按图示区域,会弹出提示框。
家庭
默认家庭为:我的家。默认家庭不可被删除。
创建家庭
点击+,输入家庭名称和家庭位置即可,如图示。
修改家庭名称
如图示
删除家庭
如图示
房间
添加房间
如图示
修改房间名称
如图示
删除房间
如图示。
家庭成员
角色以及权限
分为3种角色:创建者、管理员、成员,不同角色权限不同。
角 色 |
邀请 管理员 |
邀请 成员 |
删除 其他成员 |
退出 家庭 |
删除 家庭 |
修改 家庭信息 |
修改 成员角色 |
|---|---|---|---|---|---|---|---|
创 建 者 |
yes |
yes |
yes |
no |
yes |
yes |
yes |
管 理 员 |
no |
yes |
no |
yes |
no |
yes |
no |
成 员 |
no |
no |
no |
yes |
no |
no |
no |
邀请家庭成员
如图示。
删除家庭成员
如图示。
更改其他成员角色
如图示
debug模式
进入debug模式
如图示。
选择配置
如图示,选择你需要的各种配置。
扫描与配网
如图示。
连接
如图示。
功能界面
如图示。
mjpeg解码
名词解释、注释
涉及到的移位操作,每个都会进行无符号处理。
每帧图片数据,会拆成多个数据包,并顺序发送。
每帧图片数据,可能不会一次发送完成。
涉及到的名词解释:
rxData:接收到的mjpeg数据,字节数组。
TransmissionUnpacked:数据结构,未解包的数据对象。
Head:头信息。
CameraPacket:数据结构,携带图片信息的数据结构。
MAGIC_LB:标志位,必须是值为0xD5的字节。
MAGIC_HB:标志位,必须是值为0xF0的字节。
flags:标志位。
timestamp:时间戳,信息发送时间。
sequence:当前包的序列号。
length:携带的CameraPacket的数据长度。
crc:校验码。
id:当前包所在的图片帧的序列号。
eof:当前包是否是所属图片帧的最后一包。1为是,其余为否。
count:当前包在所属图片帧拆包后,对应的序列号。如一帧数据顺序拆了5包,其中一包数据的序列号为3。
size:携带的真实图片数据payload的长度。
ImageFrame:数据结构,解析出的payload根据序列号组装而成。
结构图
流程
从接收到的数据中解析出所有TransimissionUnpacked
从TransimissionUnpacked中取出CameraPacket
对CameraPacket进行解析取值
将CameraPacket组装成ImageFrame
解码器,对ImageFrame进行解码
解包
名词解释
index:int类型,初始为0。
reversed:字节数组,长度为3,初始值均为0。
cached:解包遗留的数据,会继续使用,长度不固定。
unpackedList:未解包的数据列表,顺序链表结构,存储的是TransmissionUnpacked对象。
offset:int类型,初始值为0。
packetList:待组装的数据列表,顺序链表结构,存储的是CameraPacket对象。
imageFrame:正在组装的帧,ImageFrame对象。
取分包数据
如果cached长度为0的话
如果当前index + 16 大于rxData的长度的话
将rxDta的index以及之后的数据,赋值到cached中。
退出循环。
判断条件:rxData的index位为0xD5且index+1位为0xF0
如果满足的话
赋值flags:将rxData的第index+3位左移8位,将rxData的第index+2位数值取出,两个结果进行或操作,将最终结果赋值给flags
赋值timestamp:将rxData的第index+7位左移24位,将rxData的第index+6位左移16位,将rxData的第index+5位左移8位,将rxData的第index+4位取出,四个结果进行或操作,将最终结果赋值给timestamp
赋值sequence:将rxData的第index+9位左移8位,将rxData的第index+8位数值取出,两个结果进行或操作,将最终结果赋值给sequence
赋值length:将rxData的第index+11位左移8位,将rxData的第index+10位数值取出,两个结果进行或操作,将最终结果赋值给sequence
赋值crc:将rxData的第index+12位数值取出,赋值给crc
赋值reversed:将rxData的第index+13、第index+14、第index+15依次填入reversed
不满足
打印异常
退出循环
如果index+16+length大于rxData的长度的话
将rxDta的index以及之后的数据,赋值到cached中
退出循环
以index+16为起始位,以length为长度,将对应的rxData的数据,赋值给一个临时字节数组,channelData
将flags、timeStamp、sequence、crc、length、channelData、reversed赋值给TransmissionUnpacked
将TransmissionUnpacked添加到unpackedList列表之中。
赋值index:index = index+16+length
如果cached长度大于0
如果cache的长度小于16
如果index+16大于rxDdata的长度
赋值offset:cached的长度赋给offset
拓展cached的长度为:offset+rxData的长度-index
将rxDta的index以及之后的数据,赋值到cached的offset之后
退出循环
如果index+16小于等于rxDdata的长度
赋值offset:cached的长度赋给offset
拓展cached的长度为:16
以index为起始位,以16-offset为长度,将对应的rxData的数据,赋值到cached的offset之后
赋值index:index= index + 16 - offset
判断是否满足调教:cached的第0位为0xD5且第一位为0xF0
满足
赋值flags:将cached的第3位左移8位,将cached的第2位数值取出,两个结果进行或操作,将最终结果赋值给flags
赋值timestamp:将cached的第7位左移24位,将cached的第6位左移16位,将cached的第5位左移8位,将cached的第4位取出,四个结果进行或操作,将最终结果赋值给timestamp
赋值sequence:将cached的第9位左移8位,将cached的第8位数值取出,两个结果进行或操作,将最终结果赋值给sequence
赋值length:将cached的第11位左移8位,将cached的第10位数值取出,两个结果进行或操作,将最终结果赋值给sequence
赋值crc:将cached的第12位数值取出,赋值给crc
赋值reversed:将cached的第13、第14、第15依次填入reversed
不满足
打印异常
退出循环
判断是否满足条件:cached的长度小于16+length
满足
如果cached的长度小于16+length
如果index + 16 + length - cached.length大于rxData的length
赋值offset:cached的长度赋给offset
拓展cached的长度为:offset + rxData.length - index
以index为起始位,以rxData.length - index为长度,将对应的rxData的数据,赋值到cached的offset之后
退出循环
赋值offset:cached的长度赋给offset
赋值一个名为copyLen的int变量:值为16 + length - offset
拓展cached的长度为:16+length
以index为起始位,以copyLen为长度,将对应的rxData的数据,赋值到cached的offset之后
赋值index:index = index+copyLen
以16为起始位,以length为长度,将对应的cached的数据,赋值给一个临时字节数组,channelData
将flags、timeStamp、sequence、crc、length、channelData、reversed赋值给TransmissionUnpacked
将TransmissionUnpacked添加到unpackedList列表之中。
cached数据清空
不满足
退出循环
如果index小于rxData的长度的话,继续执行循环
退出循环之后,将cached返回并保存,供下次使用,将unpackedList返回
组图片帧
imageFrame,依次接收并处理每一个TransmissionUnpacked。
取出length,根据length,取出对应的CameraPacket的数据。
CameraPacket,从对应的位中取出id、count、eof、size,根据size取出payload。
判断条件:当前packet和上一个packet的id一致
满足
存入packetList
不满足
清空所有的packetList
不再执行后续流程
判断条件:当前packet的eof值为1
不满足
不再执行后续流程
满足
将packetlist中的所有数据count进行排序。
将链表中的camerapacket的payload赋值到一个字节数组中frameData中,并将链表清空。
frameData,就是最终的图片帧数据。
解码
在解包过程中,会得到图片帧数据,格式为字节数组。
使用解码器进行解码。
android可以使用BitmapFactory.decodeByteArray。