当前位置: 首页 > news >正文

太原云建站模板优化水平

太原云建站模板,优化水平,淘宝网站建设的优点,成立外贸公司的流程基于安卓系统的执法记录仪、智能头盔等设备#xff0c;设备端录像、录像查询以及录像文件下载是必不可少的功能, 使用GB28181协议下载安卓设备上的录像文件, 检索录像文件是第一步, 先查询再下载#xff0c;这里记录下我实现视音频文件检索的一些细节问题. 检索请求和查询结果…  基于安卓系统的执法记录仪、智能头盔等设备设备端录像、录像查询以及录像文件下载是必不可少的功能, 使用GB28181协议下载安卓设备上的录像文件, 检索录像文件是第一步, 先查询再下载这里记录下我实现视音频文件检索的一些细节问题. 检索请求和查询结果都使用SIP MESSAGEMANSCDP协议. 信令流程: 1. 向安卓设备发送目录查询请求 MESSAGE消息消息体中包含文件检索条件, 消息体类型为:Application/MANSCDPxml  2. 安卓设备向检索方回复200OK, 无消息体.  3. 安卓根据查询条件执行查询查询结果用MESSAGE消息发给检索方消息体类型为:Application/MANSCDPxml  4.检索方回复200OK, 无消息体. 查询条件的详细定义请参考GB28181标准这里给出一个例子: ?xml version1.0 encodingGB2312?QueryCmdTypeRecordInfo/CmdTypeSN73/SNDeviceID64010000001310000003/DeviceIDStartTime2023-08-23T06:07:29/StartTimeEndTime2023-08-23T22:10:31/EndTime/Query 查询开始时间是:2023-08-23 06:07:29, 结束时间: 2023-08-23 10:10:31, StartTime和EndTime类型是xs:dateTime,  xs:dateTime 详细定义请参考W3C XML Schema Definition Language文档.  xs:dateTime非形式化定义YYYY-MM-DDThh:mm:ss,  在国内使用场景中可能不太在意时区问题, 如果遇到时区问题, xs:dateTime也支持时区信息,  例如: 2023-08-23T06:07:29Z 表示UTC时间,  2023-08-23T06:07:2908:00 换算成北京时间是:2023-08-23 14:07:29. 查询条件中的StartTime和EndTime 如何使用没找到详细的说明我的代码实现是这样规定的一:把这个时间范围定义为半闭半开区间也就是: [StartTime, EndTime),  二. 查找文件时只判断录像文件的开始时间是否在[StartTime, EndTime)范围内录像文件的结束时间不考虑. 查询结果的详细定义参考GB28181标准就好下面给出一个有查询结果的例子和一个无查询结果的例子 !----查询结果分两次发送, 总共5条----- !---第一次发送3条--- ?xml version1.0 encodingGB2312?ResponseCmdTypeRecordInfo/CmdTypeSN73/SNDeviceID64010000001310000003/DeviceIDNameanrdoid-dev-test/NameSumNum5/SumNumRecordList Num3ItemDeviceID64010000001310000003/DeviceIDNameanrdoid-dev-test/NameStartTime2023-08-23T12:27:18/StartTimeEndTime2023-08-23T12:27:21/EndTimeSecrecy0/Secrecy/ItemItemDeviceID64010000001310000003/DeviceIDNameanrdoid-dev-test/NameStartTime2023-08-23T12:27:23/StartTimeEndTime2023-08-23T12:27:26/EndTimeSecrecy0/Secrecy/ItemItemDeviceID64010000001310000003/DeviceIDNameanrdoid-dev-test/NameStartTime2023-08-23T16:52:10/StartTimeEndTime2023-08-23T16:53:01/EndTimeSecrecy0/Secrecy/Item/RecordList/Response!---第二次发送2条--- ?xml version1.0 encodingGB2312?ResponseCmdTypeRecordInfo/CmdTypeSN73/SNDeviceID64010000001310000003/DeviceIDNameanrdoid-dev-test/NameSumNum5/SumNumRecordList Num2ItemDeviceID64010000001310000003/DeviceIDNameanrdoid-dev-test/NameStartTime2023-08-23T17:21:18/StartTimeEndTime2023-08-23T17:37:21/EndTimeSecrecy0/Secrecy/ItemItemDeviceID64010000001310000003/DeviceIDNameanrdoid-dev-test/NameStartTime2023-08-23T18:15:22/StartTimeEndTime2023-08-23T18:33:58/EndTimeSecrecy0/Secrecy/Item/RecordList/Response!----没有查询到文件的例子---?xml version1.0 encodingGB2312?ResponseCmdTypeRecordInfo/CmdTypeSN73/SNDeviceID64010000001310000003/DeviceIDNameanrdoid-dev-test/NameSumNum0/SumNum/Response 查询结果的一些实现细节 1. 如果没有查询到文件响应中SumNum元素内容填充0,  且不携带RecordList元素. 2. 根据RFC3428 The size of MESSAGE requests outside of a media session MUST NOT exceed 1300 bytes,会话外的SIP MESSAGE请求大小不能超过1300个字节(1300个字节限制的是整体消息大小不止是Body Length). 针对这个消息大小限制问题, GB28181附录给出两种解决方案 方案一: 对多条查询结果进行拆分确保每个MESSAGE消息大小不超过1300个字节每个响应消息的SN要与查询请求的SN相同, 串行发送, 也就是上一次发送的MESSAGE收到200 OK响应后再发下一批拆分的查询结果, 代码实现上要计算每个SIP消息大小,记录好状态,具体实现起来比较麻烦; 方案二: SIP消息使用TCP传输, 这个需要服务端和安卓设备都支持TCP传输,GB28181要求每条响应消息携带的文件记录数上限为10000条,实际代码实现中建议不要一次发送太多条记录, 要考虑XML解析性能问题大XML解析挺慢的. 另外我建议文件记录中的可选元素场景中不需要的就不加, 尽可能减少XML大小降低信令传输带宽. 我的接口定义和Demo代码: /* * Copyright (C) 1130758427qq.com. All rights reserved. */package com.gb.ntsignalling;public interface GBSIPAgent {void addListener(GBSIPAgentListener listener);void addPlayListener(GBSIPAgentPlayListener playListener);void removePlayListener(GBSIPAgentPlayListener playListener);void addDownloadListener(GBSIPAgentDownloadListener downloadListener);void removeDownloadListener(GBSIPAgentDownloadListener removeListener);void addTalkListener(GBSIPAgentTalkListener talkListener);void removeTalkListener(GBSIPAgentTalkListener talkListener);void addAudioBroadcastListener(GBSIPAgentAudioBroadcastListener audioBroadcastListener);void addDeviceControlListener(GBSIPAgentDeviceControlListener deviceControlListener);void addQueryCommandListener(GBSIPAgentQueryCommandListener queryCommandListener);void addQueryRecordInfoListener(GBSIPAgentQueryRecordInfoListener queryRecordInfoListener);/*历史视音频文件检索应答*/boolean respondRecordInfoQueryCommand(String fromUserName, String fromUserNameAtDomain, String toUserName,String deviceName, RecordQueryInfo queryInfo,java.util.ListRecordFileInfo recordList); }package com.gb.ntsignalling;public interface GBSIPAgentQueryRecordInfoListener {void ntsOnQueryRecordInfoCommand(String fromUserName, String fromUserNameAtDomain,String toUserName,RecordQueryInfo recordQueryInfo); }package com.gb.ntsignalling;public interface RecordQueryInfo {/**命令序列号(必选)*/String getSN();/** 目录设备/视频监控联网系统/区域编码(必选)*/String getDeviceID();/** 录像起始时间(必选)*/String getStartTime();/** 录像终止时间(必选)*/String getEndTime();/** 文件路径名 (可选)*/String getFilePath();/** 录像地址(可选 支持不完全查询)*/String getAddress();/** 保密属性(可选)缺省为0;0:不涉密,1:涉密*/String getSecrecy();/** 录像产生类型(可选)time或alarm 或 manual或all*/String getType();/** 录像触发者ID(可选)*/String getRecorderID();/**录像模糊查询属性(可选)缺省为0;0:不进行模糊查询,此时根据 SIP 消息中 To头域*URI中的ID值确定查询录像位置,若ID值为本域系统ID 则进行中心历史记录检索,若为前*端设备ID则进行前端设备历史记录检索;1:进行模糊查询,此时设备所在域应同时进行中心*检索和前端检索并将结果统一返回.*/String getIndistinctQuery(); }package com.gb.ntsignalling;public class RecordFileInfo {/* 设备/区域编码(必选) */private String mDeviceID;/* 设备/区域名称(必选) */private String mName;/*文件路径名 (可选)*/private String mFilePath;/*录像地址(可选)*/private String mAddress;/*录像开始时间(可选)*/private String mStartTime;/*录像结束时间(可选)*/private String mEndTime;/*保密属性(必选)缺省为0;0:不涉密,1:涉密*/private String mSecrecy 0;/*录像产生类型(可选)time或alarm 或 manual*/private String mType;/*录像触发者ID(可选)*/private String mRecorderID;/*录像文件大小,单位:Byte(可选)*/private String mFileSize;public RecordFileInfo() { }public RecordFileInfo(String deviceID) {this.setDeviceID(deviceID);}public RecordFileInfo(String deviceID, String name) {this.setDeviceID(deviceID);this.setName(name);}public String getDeviceID() {return mDeviceID;}public void setDeviceID(String deviceID) {this.mDeviceID deviceID;}public String getName() {return mName;}public void setName(String name) {this.mName name;}public String getFilePath() {return mFilePath;}public void setFilePath(String filePath) {this.mFilePath filePath;}public String getAddress() {return mAddress;}public void setAddress(String address) {this.mAddress address;}public String getStartTime() {return mStartTime;}public void setStartTime(String startTime) {this.mStartTime startTime;}public String getEndTime() {return mEndTime;}public void setEndTime(String endTime) {this.mEndTime endTime;}public String getSecrecy() {return mSecrecy;}public void setSecrecy(String secrecy) {this.mSecrecy secrecy;}public String getType() {return mType;}public void setType(String type) {this.mType type;}public String getRecorderID() {return mRecorderID;}public void setRecorderID(String recorderID) {this.mRecorderID recorderID;}public String getFileSize() {return mFileSize;}public void setFileSize(String fileSize) {this.mFileSize fileSize;} }package com.mydemo;import com.gb.ntsignalling.GBSIPAgentQueryRecordInfoListener;public class MyAndroidG8181DemoImpl implements GBSIPAgentQueryRecordInfoListener {private static class QueryRecordInfoTask extends RecordExecutorService.CancelableTask {Overridepublic void run() {RecordBaseQuery base_query new RecordBaseQuery(get_canceler(), rec_dir_);java.util.Date start_time_lower base_query.parser_xml_date_time(record_query_info_.getStartTime());java.util.Date start_time_upper base_query.parser_xml_date_time(record_query_info_.getEndTime());if (null start_time_lower || null start_time_upper) {Log.e(TAG, start_time_lower: start_time_lower or start_time_upper: start_time_upper is null);return;}base_query.set_start_time_lower(start_time_lower);base_query.set_start_time_upper(start_time_upper);ListRecordFileDescription file_list base_query.execute();if (is_cancel())return;file_list base_query.sort_by_start_time_asc(file_list);if (is_cancel())return;Listcom.gb.ntsignalling.RecordFileInfo list base_query.to_record_file_info_list(file_list, record_query_info_.getDeviceID(), null);if (is_cancel())return;if (file_list ! null) {for (RecordFileDescription i : file_list)Log.i(TAG, i.toString(base_query.get_print_begin_date_time_format(), base_query.get_print_end_date_time_format()));}if (is_cancel() ||null handler_ || null sip_agent_)return;Handler handler handler_.get();GBSIPAgent sip_agent sip_agent_.get();if (null handler || null sip_agent)return;handler.post(new Runnable() {Overridepublic void run() {if (null this.sip_agent_)return;GBSIPAgent sip_agent this.sip_agent_.get();if (null sip_agent)return;if (this.canceler_ ! null this.canceler_.get())return;String device_name null;sip_agent.respondRecordInfoQueryCommand(from_user_name_, from_user_name_at_domain_,to_user_name_, device_name, this.record_query_info_, this.record_list_);}private WeakReferenceGBSIPAgent sip_agent_;private AtomicBoolean canceler_;private String from_user_name_;private String from_user_name_at_domain_;private String to_user_name_;private RecordQueryInfo record_query_info_;private ListRecordFileInfo record_list_;public Runnable set(GBSIPAgent sip_agent, AtomicBoolean canceler, String from_user_name, String from_user_name_at_domain, String to_user_name,RecordQueryInfo record_query_info, ListRecordFileInfo record_list) {this.sip_agent_ new WeakReference(sip_agent);this.canceler_ canceler;this.from_user_name_ from_user_name;this.from_user_name_at_domain_ from_user_name_at_domain;this.to_user_name_ to_user_name;this.record_query_info_ record_query_info;this.record_list_ record_list;return this;}}.set(sip_agent, get_canceler(), this.from_user_name_, this.from_user_name_at_domain_, this.to_user_name_,this.record_query_info_, list));}public QueryRecordInfoTask set(Handler handler, GBSIPAgent sip_agent, String rec_dir,String from_user_name, String from_user_name_at_domain,String to_user_name, RecordQueryInfo query_info) {this.handler_ new WeakReference(handler);this.sip_agent_ new WeakReference(sip_agent);this.rec_dir_ rec_dir;this.from_user_name_ from_user_name;this.from_user_name_at_domain_ from_user_name_at_domain;this.to_user_name_ to_user_name;this.record_query_info_ query_info;return this;}private WeakReferenceHandler handler_;private WeakReferenceGBSIPAgent sip_agent_;private String rec_dir_;private String from_user_name_;private String from_user_name_at_domain_;private String to_user_name_;private RecordQueryInfo record_query_info_;}Overridepublic void ntsOnQueryRecordInfoCommand(String fromUserName, String fromUserNameAtDomain, final String toUserName,RecordQueryInfo recordQueryInfo) {handler_.post(new Runnable() {Overridepublic void run() {Log.i(TAG, ntsOnQueryRecordInfoCommand from_user_name: from_user_name_ , to_user_name: to_user_name_ , sn: record_query_info_.getSN() , device_id: record_query_info_.getDeviceID() , start_time: record_query_info_.getStartTime() , end_time: record_query_info_.getEndTime());QueryRecordInfoTask query_task new QueryRecordInfoTask();query_task.set(handler_, gb28181_agent_, recDir, from_user_name_, from_user_name_at_domain_, to_user_name_, record_query_info_);if (!record_executor_.submit(query_task))Log.e(TAG, ntsOnQueryRecordInfoCommand call record_executor_.submit failed);}private String from_user_name_;private String from_user_name_at_domain_;private String to_user_name_;private RecordQueryInfo record_query_info_;public Runnable set(String from_user_name, String from_user_name_at_domain, String to_user_name, RecordQueryInfo record_query_info) {this.from_user_name_ from_user_name;this.from_user_name_at_domain_ from_user_name_at_domain;this.to_user_name_ to_user_name;this.record_query_info_ record_query_info;return this;}}.set(fromUserName, fromUserNameAtDomain, toUserName, recordQueryInfo));} } 整个历史视音频文件检索的实现代码较多这里为了方便说明信令流程和关键细节只给出接口定义和基本Demo, 如有不清楚的地方请联系qq: 1130758427, 从协议到一个可靠稳定的代码实现需要花不少精力和时间
http://www.zqtcl.cn/news/228717/

相关文章:

  • 给个高质量的网站做网站优化有前景吗
  • 外贸网站 源怎么利用互联网平台赚钱
  • 营销型网站建设平台wordpress 添加 常规
  • php主做哪种类型网站高端公司小程序建设
  • 网站域名301是什么意思在一呼百应上做网站行吗
  • 怎么做百度口碑网站郑州网站设计专家
  • 珠海网络公司网站建设邯郸铸邯网络信息科技有限公
  • 室内设计者联盟官网哈尔滨百度搜索排名优化
  • 网站公司打电话来说做网站天下信息网
  • 汕头制作企业网站百度舆情监测平台
  • 怎样跟网站做优化呢火狐搜索引擎
  • 如何做网站的维护和推广水利网站建设管理汇报
  • 申请网站就是做网站吗怎样凡科建设网站
  • 怎样做吓人网站网页制作成品图
  • 前端的网站重构怎么做做网站用的编程语言
  • 长沙网站设计多少钱一个月百度网盘app下载安装电脑版
  • 你好南京网站网站开发 seo
  • wordpress 文章延时加载seo软件系统
  • 网站建设与运营答案新浪网站首页
  • 网站怎么做关键词库如何建免费的企业网站
  • 跟老外做网站网络系统管理与维护机考
  • 网站推广方案范例江西南昌小程序开发
  • 烘焙类网站开发时代背景ppt素材模板免费下载
  • 如何制作多网页网站广州品牌seo推广
  • 域名怎么解析到网站什么是asp网站
  • 网站开发的税率做网站文案
  • 网站模板上传工具如何介绍自己设计的网页
  • 河北网站建设价格低国内做外单的网站有哪些
  • wordpress Apache升级优化营商环境的意义
  • 单页式网站系统wordpress自定义字段怎么用