APP下载

基于Android的智能可视化指挥系统

2022-10-01廖列法张幸平

计算机工程与设计 2022年9期
关键词:音频客户端消息

廖列法,张幸平

(江西理工大学 信息工程学院,江西 赣州 341000)

0 引 言

随着人工智能时代的来临以及Android智能设备的普及,针对移动端的应用越来越广泛,移动设备上的应用技术已成为当前科技领域热门的研究方向。传统的指挥系统中要求使用专用设备,比如对讲机、照相机、GPS等,对设备要求性较高、负担较大。与此同时,支持的功能和使用界面较为简单,没有良好的用户体验感,无法满足日益增长的用户需求。近些年智能指挥类系统在各行各业都有不断的被提出及应用,比如基于Android的应急指挥系统[1]、调度指挥系统[2]、扁平化的图形类指挥系统[3]等,但这些系统主要还是采用传统的Client/Server技术,系统架构部署较为复杂,对服务器要求较高。因此基于当前主流的Spring Cloud[4]微服务架构体系实现一套满足云服务器下分布式集群化的轻量型实时可视化指挥系统具有非常重要的应用与研究价值。

本文设计并实现了一种基于Android的智能可视化指挥系统。为了满足大用户、高并发、可扩展的部署需求,该系统采用了采用Spring Cloud微服务架构和Ngnix[5]、Redis[6]、Nodejs[7]、Mysql[8]等技术。采用3种定位技术(网络[9]、GPS[10]和离线[11])来保证用户位置的实时获取,设计用户上下消息、语音控制类消息,通过自主的实时传输协议实现信息的实时传输,同时以地图为基本元素,展示可视化指挥的所有功能。既增强了传统指挥系统的功能,实现了直观、可视化的展现方式,又提供了一套轻量型的实时可视化指挥系统方案。

1 系统方案设计

方案设计的基本要求是支持在多台云服务器上进行分布式和集群化的部署,以保证所开发系统的稳定性、可靠性和可扩展性。接下来,我们将从系统的组织框架、整体架构和功能架构进行具体介绍。

1.1 系统组织架构

在Spring Cloud微服务的框架下,根据不同的功能,设计的功能服务模块包括音频服务(Audi)、上下线服务(Online)、转发服务(Forward)、消息通知服务(Notification),以及线程池同步服务。其中音频服务模块提供了视频和音频消息的相关接口,上线下服务模块提供了用户状态的相关接口,转发服务模块提供了消息的转发接口,消息通知服务模块提供了通知的相关接口,线程池同步服务模块提供了不同线程之间数据的同步。根据消息的类型,该系统设计的消息类型分为聊天文本、消息类文本(同步消息、下线消息、推送消息和通知消息)、图像、视频流、语音流等。图1展示了如上所述的系统组织架构。

图1 系统组织框架

1.2 系统整体架构

该系统涉及的主要模块包括2个消息通知服务(notify server1和server2)、缓存服务(Redis)、消息服务进程(接收和转发)、通知推送服务平台(包含自主和第三方的消息推送服务)、Android移动端等。其中,所有加入的移动客户端都会与消息通知服务器建立连接,而负载均衡模块负责分配新加入设备需要连接的服务器。具体来说,消息的发生到接收会涉及以下过程。首先,消息发送到消息通知服务器;其次,消息通知服务将消息以异步的方式存入数据库和缓存(Redis)中;第三,查询目标用户连接的服务器;第四,将消息转发到上一步查询到的服务器中;最后,接收到消息的服务器将数据推送到相应的客户端。图2显示了整个系统的架构和消息流转。

图2 系统架构

1.3 系统功能架构

系统采用C/S架构,客户端与服务器之间通过TCP协议通信。服务器提供的功能包括数据的持久化存储(数据库)、语音流和视频流数据的实时传输、文本类消息的实时中转(即时文本、位置类、控制类和状态类消息)。同时以Nginx为负载均衡反向代理服务,Redis为主从的集群方案,Nodejs为应用服务器,Mysql为数据存储服务来提供一套高可用、高并发的集群化解决方案。

客户端提供的功能包括良好的使用界面、流数据的处理(如,发送、接收、解析和播放)、文本数据的处理(如,即时文本、位置类、控制类和状态类等消息的解析和转发),以及用户位置的实时获获取、转发和解析。图3展示了该系统的功能架构。

图3 系统功能架构

如图3所示,客户端支持的设备为Android的移动端和PAD端(系统版本号为4.0以上)。根据功能划分,客户端首先会连接Nginx服务器。该服务器作为负载均衡模块,它将根据权重配比将所有请求进行随机分发,以确保动静分离。其次,所有的交互数据将会由相应的Nodjs服务器进行处理。该服务器作为数据处理的核心模块,它将根据事件类型,通过异步的方式进行高效的数据传送,以实现不同终端之间的数据交互。最后,为了保证数据的高速存取,临时存储的Session数据(如,会话状态数据)存入缓存服务模块(Redis),以实现Nodejs服务器之间的数据共享。永久性存储的数据则存入数据库模块(Mysql),非永久性存储且常访问的数据则存入内存模块中。

2 系统软件设计

2.1 服务器软件设计

服务器是整个系统的数据中转和处理中心。图4展示了整个数据的处理流程。当服务器收到支持的所有消息(用户上线和下线、语音流数据、实时位置、麦空闲状态、锁麦状态等)等数据时直接透传到系统中所有在线的用户。收到抢麦消息时查询用户的信息,如果用户具有管理员权限,则进入强制抢麦模式,若当前有人正在说话,则将用户踢下保证抢麦的成功,同时将抢麦成功消息回调给用户,如果用户是普通权限,则进入正常抢麦模式,若当前有人正在说话,则抢麦失败,相反则抢麦成功,同时将抢麦结果消息回调给用户。

图4 服务器数据流程

2.2 客户端软件设计

客户端主要包括登录和可视化对讲两个模块,其功能流程如图5所示,图5中,用户在登录界面填写用户名、密码、房间名、服务器地址等信息与服务器建立连接,完成登录操作。登录成功后则进入对讲主界面,此模块主要包含用户位置信息、对讲功能、抢麦功能的展示。其中位置信息的展示主要包含用户上下线时动态的增加或删除用户、更新用户列表,用户位置发生变化时,在地图上动态改变用户的位置坐标。对讲功能主要包含语音流数据的采集、编码、转发和语音流数据的接收、转码和播放。抢麦功能首先是发送抢麦指令到服务器。如果服务器返回成功的状态,则开始实时语音对讲流程,对语音流数据进行实时的采集和编码转发、接收和解码播放。相反,如果抢麦失败,则在界面上显示相关提示信息。

图5 客户端功能流程

3 技术挑战及解决方法

数据传送的实时性和可靠性是整个系统的关键,而涉及的主要数据是实时获取的用户定位信息和实时采集的语音流消息。因此,如何确保传输这些数据的效率和稳定性该系统面临的主要挑战。简单来说,需要满足的基本要求是:终端用户将大量的位置消息和语音流数据进行封装,经服务器处理和中转,到达指定的目标用户后,实时的在终端设备上进行实时的解码、界面展示和语音播放。

3.1 音频的采集与播放

(1)音频流的采集

通过调用原生API(AudioRecord)采集音频流数据,采集参数分别为音频源(MediaRecorder.AudioSource.MIC)、采样率(16 000 Hz)、音频通道(单通道:CHANNEL_IN_MONO)、音频格式(16位:ENCODING_PCM_16Bit)。整个音频流的采集过程主要包括以下步骤:第一步,通过上面的初始化参数建立AudioRecord对象。第二步,开启一个AudioCollectionThread线程,在该线程中采集音频流数据,并调用回调函数接口(sendAudioFrame)。第三步,在回调函数sendAudioFrame中,利用Speex[12]对语音流数据进行编码后,再将封装的数据传输到服务器。这一过程涉及的主要代码如下:

collectionRecord = new AudioRecord(collectionSource, collectionRateInHz, collectionChannel, collectionFormat, readBufferSize);

@Override

public void run() {

while (!isNeedExit) {

byte[] readBuffer = new byte[readBufferSize];

int count = collectionRecord.read(readBuffer, 0, readBufferSize);

onAudioFrameListener.sendAudioFrame(readBuffer, readBufferSize);

}

(2)音频流的解码和播放

首先是音频流数据的解码。解码方式与采集方式相似,使用的是系统的另一个API(AudioTrack)。解码接口的传入参数与采集时的参数一致,分别为16 000 Hz、单通道、16位。整个音频流的解码和播放过程主要包括以下步骤:第一步,通过上面的初始化参数建立AudioTrack对象。第二步,开启一个AudioDecodeThread线程,在该线程中接收音频流数据。第三步,利用Speex对语音流数据进行解码后,再将获得的原始音频流数据写入AudioPlayTrack进行播放。这一过程涉及的主要代码如下:

audioPlayTrack = new AudioPlayTrack(dataType, da-taRateInHz, dataChannel, dataFormat,

dataBufferSize, PLAY_AUDIO_MODE);

@Override

public void run() {

while (needPlaying) {

int readSize = ReceiveAudioStreamLib.receive_play_pcm(AudioStreamUtils.receive_steam, readBuffer, dataBufferSize);

if (readSize > 0) {

audioPlayTrack.write(readBuffer, 0, readSize);

}

}

}

3.2 位置的实时展示

通过百度地图Android SDK[13]进行位置展示和定位,使用的参数分别为高精度模式(ParamHightAccuracy)、gcj02坐标系、1 s的间隔频率,并开启GPS、室内定位。整个过程通过注册监听回调接口的方式完成。首先,通过上述的初始化参数进行接口的注册。其次,注册成功后,终端设备上用户的位置变化会实时反馈到receiveDecive-Location函数。最后,对每次收到的位置信息进行解析,若用户位置发生了变化,则通过AudioStreamUtils.send-CustomDataToServer函数发送到目标用户,并在终端设备的地图上实施更新位置。这一过程涉及的主要代码如下:

LocationClientOption locParam = currentLocClient.getLocOption();

locParam.setLocationMode(ParamHightAccuracy);

locParam.setCoorType("gcj02");

locParam.setLocationNotify(true);

currentLocClient.startIndoorMode();

currentLocClient.regDeviceLocationRecall(mRegDeviceLocationRecall);

@Override

public void receiveDeviceLocation(BDLocation currentLoc) {

AudioStreamUtils.sendCustomDataToServer(currentLoc);

}

当位置消息到达服务器时,首先该服务器会检索当前在线的终端用户,然后根据用户列表将该消息透传给每一个用户。然后,终端用户收到该消息时,则在终端设备的地图上实施对应用户的位置。这一过程涉及的主要代码如下:

其三,19世纪40年代的英国刚刚面临第一次工业大萧条,社会开始骚乱,工人运动兴起,社会思想家托马斯·卡莱尔通过比较现在与过去,无情地揭露出新时代产生的种种弊端,并呼吁社会改造,这帮作为社会意识形态建构组成部分的艺术创作群体树立了明确的斗争对象,即专横的艺术体制。

@Override

public void receiveData(String data) {

dataUtils.updateDeviceFromCustomData(data);

}

3.3 自定义的消息传输协议

为了进一步提高系统在多用户使用场景下的并发能力和可用性,除了满足分布式、集群化部署的架构要求外,还设计了一套定制化的、轻巧的、高效的消息传输协议[14,15]。该协议库底层采用C语言实现和封装,然后再通过JNA(Java Native Access)调用的方式进行访问。该协议库的主要代码如下:

(1)建立连接

AudioStreamUtils.connectServer(String deviceParam, String teamParam, String serverIP,int serverPort, int advancedFlag)

实现说明:调用系统函数Socket建立与服务器的TCP连接,同时将deviceParam、teamParam、advancedFlag参数传递到服务器,参数说明见表1。

表1 参数说明

(2)断开连接

AudioStreamUtils.disconnectServer()

实现说明:将Socket连接断开。

(3)请求麦

AudioStreamUtils.requestMic()

实现说明:发送请求麦的消息到服务器。

(4)释放麦

AudioStreamUtils.freeMic()

实现说明:发送释放麦的消息到服务器。

(5)发送音频流数据

AudioStreamUtils.sendCollectionAudioData (byte[] audioData, int audioSize)

实现说明:将音频消息通过Socket发送到服务器,参数说明见表2。

表2 参数说明

(6)接收音频流数据

AudioStreamUtils.getCollectionAudioData(int audioSize)

实现说明:通过线程实时获取Socket收到的音频数据,再将音频数据放入到音频流处理模块,参数说明见表3。

表3 参数说明

(7)发送定制化消息

AudioStreamUtils.sendCustomMessage(String customMessage)

实现说明:将自定义消息通过Socket发送到服务器,参数说明见表4。

表4 参数说明

(8)注册回调函数

AudioStreamUtils.registerAudioRecallEvent

实现说明:定义回调接口并注册回调函数,回调接口见表5。

表5 回调函数

回调参数见表6。

表6 回调函数的参数

消息格式见表7。

表7 消息格式说明

支持的消息类型如下:

1)新用户加入

cmdStatus=newEnter,表8列出了返回值。

表8 回调-新用户加入

2)用户申请麦

cmdStatus=grapMike,表9列出了返回值。

表9 回调-用户申请麦

3)用户结束麦

cmdStatus=releaseMike,表10列出了返回值。

表10 回调-用户结束麦

4)转发到指定用户

cmdStatus=fwdUser,表11列出了返回值。

表11 回调-转发到指定用户

5)转发到所有在线用户

cmdStatus=fwdAllUser,表12列出了返回值。

表12 回调-转发到所有在线用户

4 系统评估和效果展示

为了评估系统的性能和稳定性,首先在腾讯云上部署了该系统,采用的服务器配置如下:实例配置(CPU:2核,内存:4 G)、操作系统(CentOS 7.8 64位)、公网带宽(5 Mbps)、高性能云硬盘(1 T)。其次,客户端类型采用了Android的移动设备和PAD终端设备,涉及多个厂商不同系统版本的Android设备,比如华为的P40 Pro、小米的MIX4、三星的Note8、OPPO的R9、vivo的X80。

在当前主流的品牌和系统上的测试结果如下。首先,客户端中包含的人机交互界面能适配所测试的全部机型,具有良好的UI适配性。其次,在4G和Wifi网络下,测试过程中未出现连接断开、数据延时、数据终端等异常情况,因此,在网络较佳的情况下使用过程流畅。在网络较弱或信号不稳定的情况下(比如,电梯里),客户端能即时给出相应提示,并能够在网络恢复后重新连接上服务器,恢复终端设备状态和同步当前在线设备和位置信息。由此说明,客户端的异常机制进一步确保了客户端的可用性。最后,由于可用于测试的Android移动设备和PAD终端的数量有限,我们利用额外的自动化测试工具对服务器的稳定性和并发能力进行了测试。表13从并发设备(数量)、文本消息(条)、CPU利用率、响应时间(秒)等指标进行了总结。

表13 服务器的并发测试结果

如表13所示,并发设备数量从200增加到400,400增加到800,800增加到1600时,CPU利用率的变化分别为0.4%、0.6%、0.9%,说明该服务器所需的系统资源较低,可认为是一种轻量型服务器。与此同时,消息数量在200~1600之间时,服务器的响应时间在0.59 s至0.72 s之间,进一步表明了该服务器的消息处理能力。

最后,图6~图8展示了客户端的用户登录界面和可视化对讲界面(其它设备正在讲话、当前设备正在讲话)的使用效果。

图6 用户登录界面

图7 可视化对讲界面-有人正在说话

图8 可视化对讲界面-正在说话

图7、图8中,顶部会动态显示当前在线的用户,地图上会标注每个在线用户的位置,点击底部圆型按钮可以发起对讲,同时在所有终端设备的顶部栏实时提示当前说明的终端用户。同样,如果某一终端设备离线,所有终端设备上的顶部栏和地图界面都会进行实时更新。

5 结束语

随着人工智能与移动互联网技术的快速发展,针对Android智能设备的应用越来越广泛,在Android智能设备上实现一套可视化指挥系统,既能增强指挥系统的功能,又能提供多元化的界面展示,更好适应互联网时代用户的需求。下一步的研究将在另一主流的iOS系统上实现相应的指挥系统。

猜你喜欢

音频客户端消息
你的手机安装了多少个客户端
你的手机安装了多少个客户端
一张图看5G消息
如何看待传统媒体新闻客户端的“断舍离”?
必须了解的音频基础知识 家庭影院入门攻略:音频认证与推荐标准篇
基于Daubechies(dbN)的飞行器音频特征提取
晚步见道旁花开
音频分析仪中低失真音频信号的发生方法
Pro Tools音频剪辑及修正
新华社推出新版客户端 打造移动互联新闻旗舰