技术背景

今天,我们主要讲讲Android平台GB28181接入模块的技术对接,Android平台GB28181接入模块设计的目的,可实现不具备国标音视频能力的 Android终端,通过平台注册接入到现有的GB/T28181—2016服务,可用于如智能监控、智慧零售、智慧教育、远程办公、生产运输、智慧交通、车载或执法记录仪等场景。

Android终端除支持常规的音视频数据接入外,还可以支持移动设备位置(MobilePosition)订阅和通知、语音广播和语音对讲、云台控制回调和预置位查询,支持对接数据类型如下:

  • 编码前数据(目前支持的有YV12/NV21/NV12/I420/RGB24/RGBA32/RGB565等数据类型);
  • 编码后数据(如无人机等264/HEVC数据,或者本地解析的MP4音视频数据);
  • 拉取RTSP或RTMP流并接入至GB28181平台(比如其他IPC的RTSP流,可通过Android平台GB28181接入到国标平台)。

功能支持

  •  ​[视频格式]H.264/H.265(Android H.265硬编码);
  • [音频格式]G.711 A律、AAC;
  • [音量调节]Android平台采集端支持实时音量调节;
  • [H.264硬编码]支持H.264特定机型硬编码;
  • [H.265硬编码]支持H.265特定机型硬编码;
  • [软硬编码参数配置]支持gop间隔、帧率、bit-rate设置;
  • [软编码参数配置]支持软编码profile、软编码速度、可变码率设置;
  • 支持纯视频、音视频PS打包传输;
  • 支持RTP OVER UDP和RTP OVER TCP被动模式;
  • 支持信令通道网络传输协议TCP/UDP设置;
  • 支持注册、注销,支持注册刷新及注册有效期设置;
  • 支持设备目录查询应答;
  • 支持心跳机制,支持心跳间隔、心跳检测次数设置;
  • 支持移动设备位置(MobilePosition)订阅和通知;
  • 支持语音广播;
  • 支持语音对讲;
  • 支持云台控制和预置位查询;
  • [实时水印]支持动态文字水印、png水印;
  • [镜像]Android平台支持前置摄像头实时镜像功能;
  • [实时静音]支持实时静音/取消静音;
  • [实时快照]支持实时快照;
  • [降噪]支持环境音、手机干扰等引起的噪音降噪处理、自动增益、VAD检测;
  • [外部编码前视频数据对接]支持YUV数据对接;
  • [外部编码前音频数据对接]支持PCM对接;
  • [外部编码后视频数据对接]支持外部H.264数据对接;
  • [外部编码后音频数据对接]外部AAC数据对接;
  • [扩展录像功能]支持和录像SDK组合使用,录像相关功能。​

系统要求

  • SDK支持Android 4.4及以上版本;
  • 支持的CPU架构:armv7, arm64, x86, x86_64。

准备工作

  • 确保SmartPublisherJniV2.java放到com.daniulive.smartpublisher包名下(可在其他包名下调用);
  • 如需集成语音广播、语音对讲功能,确保SmartPlayerJniV2.java放到com.daniulive.smartplayer包名下(可在其他包名下调用);
  • smartavengine.jar和smartgbsipagent.jar加入到工程;
  • 拷贝libSmartPublisher.so和libSmartPlayer.so(如需语音广播或语音对讲)到工程;
  • AndroidManifast.xml添加相关权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" ></uses-permission>
<uses-permission android:name="android.permission.INTERNET" ></uses-permission>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
  • Load相关so:
static {  System.loadLibrary("SmartPublisher");System.loadLibrary("SmartPlayer");
}
  • build.gradle配置32/64位库:
splits {abi {enable truereset()// Specifies a list of ABIs that Gradle should create APKs forinclude 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64' //select ABIs to build APKs for// Specify that we do not want to also generate a universal APK that includes all ABIsuniversalApk true}
}
  • 如需集成到自己系统测试,请用大牛直播SDK的app name,授权版按照授权app name正常使用即可;
  • 如何改app-name,strings.xml做以下修改:
<string name="app_name">SmartPublisherSDKDemo</string>

接口详解

以Android平台Camera2对接为例,信令部分需要实现如下标红接口:

public class MainActivity extends Activity implements ViewTreeObserver.OnGlobalLayoutListener, Camera2Listener,GBSIPAgentListener, GBSIPAgentPlayListener, GBSIPAgentAudioBroadcastListener,GBSIPAgentDeviceControlListener, GBSIPAgentQueryCommandListener, GBSIPAgentTalkListener{
}

媒体数据处理接口,可参照SmartPublisherJniV2.java,如需语音广播或语音对讲,可参照SmartPlayerJniV2.java。

信令处理

GBSIPAgentListener主要系GB28181注册、心跳、DevicePosition等,如注册成功、注册超时、注册网络传输层错误、心跳异常、设备位置请求处理:

public interface GBSIPAgentListener
{/*注册成功* @param dateString: 服务器日期,用来校准设备端时间,用户自行决定是否校准设备时间*/void ntsRegisterOK(String dateString);/**注册超时*/void ntsRegisterTimeout();/**注册网络传输层异常*/void ntsRegisterTransportError(String errorInfo);/**心跳达到异常次数*/void ntsOnHeartBeatException(int exceptionCount, String lastExceptionInfo);/** 设备位置请求, 这个主要用在移动设备位置订阅上* @param interval 请求间隔, 单位是毫秒*/void ntsOnDevicePositionRequest(String deviceId, int interval);
}

GBSIPAgentPlayListener主要系GB28181的Invite、Ack、Bye等处理:

public interface GBSIPAgentPlayListener {/**收到s=Play的实时视音频点播*/void ntsOnInvitePlay(String deviceId, SessionDescription sessionDescription);/**发送play invite response 异常*/void ntsOnPlayInviteResponseException(String deviceId, int statusCode, String errorInfo);/** 收到CANCEL play INVITE请求*/void ntsOnCancelPlay(String deviceId);/** 收到Ack*/void ntsOnAckPlay(String deviceId);/** 收到Bye*/void ntsOnByePlay(String deviceId);/** 不是在收到BYE Message情况下, 终止Play*/void ntsOnTerminatePlay(String deviceId);/** Play会话对应的对话终止, 一般不会出发这个回调,目前只有在响应了200K, 但在64*T1时间后还没收到ACK,才可能会出发收到这个, 请做相关清理处理*/void ntsOnPlayDialogTerminated(String deviceId);
}

GBSIPAgentAudioBroadcastListener主要系GB28181语音广播处理相关,如有语音广播相关需求,可参照demo实例实现:

public interface GBSIPAgentAudioBroadcastListener {/**收到语音广播通知*/void ntsOnNotifyBroadcastCommand(String fromUserName, String fromUserNameAtDomain, String sn, String sourceID, String targetID);/**需要准备接受语音广播的SDP内容*/void ntsOnAudioBroadcast(String commandFromUserName, String commandFromUserNameAtDomain, String sourceID, String targetID);/**音频广播, 发送Invite请求异常*/void ntsOnInviteAudioBroadcastException(String sourceID, String targetID, String errorInfo);/**音频广播, 等待Invite响应超时*/void ntsOnInviteAudioBroadcastTimeout(String sourceID, String targetID);/**音频广播, 收到Invite消息最终响应*/void ntsOnInviteAudioBroadcastResponse(String sourceID, String targetID, int statusCode, SessionDescription sessionDescription);/** 音频广播, 收到BYE Message*/void ntsOnByeAudioBroadcast(String sourceID, String targetID);/** 不是在收到BYE Message情况下, 终止音频广播*/void ntsOnTerminateAudioBroadcast(String sourceID, String targetID);
}

GBSIPAgentDeviceControlListener主要系GB28181设备控制相关,比如远程启动、云台控制:

public interface GBSIPAgentDeviceControlListener {/** 收到远程启动控制命令*/void ntsOnDeviceControlTeleBootCommand(String deviceId, String teleBootValue);/** 云台控制*/void ntsOnDeviceControlPTZCmd(String deviceId, String typeValue);
}

GBSIPAgentQueryCommandListener主要系GB28181查询命令,如预置位查询:

public interface GBSIPAgentQueryCommandListener {/** 设备预置位查询*/void ntsOnDevicePresetQueryCommand(String fromUserName, String fromUserNameAtDomain, String sn, String deviceId);
}

GBSIPAgentTalkListener主要系GB28181语音对讲相关处理:

public interface GBSIPAgentTalkListener {/**收到s=Talk 语音对讲*/void ntsOnInviteTalk(String deviceId, SessionDescription sessionDescription);/**发送talk invite response 异常*/void ntsOnTalkInviteResponseException(String deviceId, int statusCode, String errorInfo);/** 收到CANCEL Talk INVITE请求*/void ntsOnCancelTalk(String deviceId);/** 收到Ack*/void ntsOnAckTalk(String deviceId);/** 收到Bye*/void ntsOnByeTalk(String deviceId);/** 不是在收到BYE Message情况下, 终止Talk*/void ntsOnTerminateTalk(String deviceId);/** Talk会话对应的对话终止, 一般不会出发这个回调,目前只有在响应了200K, 但在64*T1时间后还没收到ACK,才可能会出发收到这个, 请做相关清理处理*/void ntsOnTalkDialogTerminated(String deviceId);
}

媒体数据处理

RTP数据发送

RTP Sender(SmartPublisherJniV2.java)相关接口设计:

/** SmartPublisherJniV2.java* Author: https://daniusdk.com*/
/** 创建RTP Sender实例** @param reserve:保留参数传0** @return RTP Sender 句柄,0表示失败*/
public native long CreateRTPSender(int reserve);/***设置 RTP Sender传输协议** @param rtp_sender_handle, CreateRTPSender返回值* @param transport_protocol, 0:UDP, 1:TCP, 默认是UDP** @return {0} if successful*/
public native int SetRTPSenderTransportProtocol(long rtp_sender_handle, int transport_protocol);/***设置 RTP Sender IP地址类型** @param rtp_sender_handle, CreateRTPSender返回值* @param ip_address_type, 0:IPV4, 1:IPV6, 默认是IPV4, 当前仅支持IPV4** @return {0} if successful*/
public native int SetRTPSenderIPAddressType(long rtp_sender_handle, int ip_address_type);/***设置 RTP Sender RTP Socket本地端口** @param rtp_sender_handle, CreateRTPSender返回值* @param port, 必须是偶数,设置0的话SDK会自动分配, 默认值是0** @return {0} if successful*/
public native int SetRTPSenderLocalPort(long rtp_sender_handle, int port);/***设置 RTP Sender SSRC** @param rtp_sender_handle, CreateRTPSender返回值* @param ssrc, 如果设置的话,这个字符串要能转换成uint32类型, 否则设置失败** @return {0} if successful*/
public native int SetRTPSenderSSRC(long rtp_sender_handle, String ssrc);/***设置 RTP Sender RTP socket 发送Buffer大小** @param rtp_sender_handle, CreateRTPSender返回值* @param buffer_size, 必须大于0, 默认是512*1024, 当前仅对UDP socket有效, 根据视频码率考虑设置合适的值** @return {0} if successful*/
public native int SetRTPSenderSocketSendBuffer(long rtp_sender_handle, int buffer_size);/***设置 RTP Sender RTP时间戳时钟频率** @param rtp_sender_handle, CreateRTPSender返回值* @param clock_rate, 必须大于0, 对于GB28181 PS规定是90kHz, 也就是90000** @return {0} if successful*/
public native int SetRTPSenderClockRate(long rtp_sender_handle, int clock_rate);/***设置 RTP Sender 目的IP地址, 注意当前用在GB2818推送上,只设置一个地址,将来扩展如果用在其他地方,可能要设置多个目的地址,到时候接口可能会调整** @param rtp_sender_handle, CreateRTPSender返回值* @param address, IP地址* @param port, 端口** @return {0} if successful*/
public native int SetRTPSenderDestination(long rtp_sender_handle, String address, int port);/*** 设置是否开启 RTP Receiver* @param rtp_sender_handle, CreateRTPSender返回值* @param is_enable, 0表示不收RTP包, 1表示收RTP包, SDK默认值为0.* @return*/
public native int EnableRTPSenderReceive(long rtp_sender_handle, int is_enable);/***设置RTP Receiver SSRC** @param rtp_sender_handle, CreateRTPSender返回值* @param ssrc, 如果设置的话,这个字符串要能转换成uint32类型, 否则设置失败** @return {0} if successful*/
public native int SetRTPSenderReceiveSSRC(long rtp_sender_handle, String ssrc);/***设置RTP Receiver Payload 相关信息** @param rtp_sender_handle, CreateRTPSender返回值** @param payload_type, 请参考 RFC 3551** @param encoding_name, 编码名, 请参考 RFC 3551, 如果payload_type不是动态的, 可能传null就好** @param media_type, 媒体类型, 请参考 RFC 3551, 1 是视频, 2是音频** @param clock_rate, 请参考 RFC 3551** @return {0} if successful*/
public native int SetRTPSenderReceivePayloadType(long rtp_sender_handle, int payload_type, String encoding_name, int media_type, int clock_rate);/***设置RTP Receiver PS的pts和dts clock frequency** @param rtp_sender_handle, CreateRTPSender返回值** @param ps_clock_frequency, 默认是90000, 一些特殊场景需要设置** @return {0} if successful*/
public native int SetRTPSenderReceivePSClockFrequency(long rtp_sender_handle, int ps_clock_frequency);/***设置 RTP Receiver 音频采样率** @param rtp_sender_handle, CreateRTPSender返回值* @param sampling_rate, 音频采样率** @return {0} if successful*/
public native int SetRTPSenderReceiveAudioSamplingRate(long rtp_sender_handle, int sampling_rate);/***设置 RTP Receiver 音频通道数** @param rtp_sender_handle, CreateRTPSender返回值* @param channels, 音频通道数** @return {0} if successful*/
public native int SetRTPSenderReceiveAudioChannels(long rtp_sender_handle, int channels);/***初始化RTP Sender, 初始化之前先调用上面的接口配置相关参数** @param rtp_sender_handle, CreateRTPSender返回值** @return {0} if successful*/
public native int InitRTPSender(long rtp_sender_handle);/***获取RTP Sender RTP Socket本地端口** @param rtp_sender_handle, CreateRTPSender返回值** @return 失败返回0, 成功的话返回响应的端口, 请在InitRTPSender返回成功之后调用*/
public native int GetRTPSenderLocalPort(long rtp_sender_handle);/*** UnInit RTP Sender** @param rtp_sender_handle, CreateRTPSender返回值** @return {0} if successful*/
public native int UnInitRTPSender(long rtp_sender_handle);/*** 释放RTP Sender, 释放之后rtp_sender_handle就无效了,请不要再使用** @param rtp_sender_handle, CreateRTPSender返回值** @return {0} if successful*/
public native int DestoryRTPSender(long rtp_sender_handle);

RTP数据接收

对应RTP Receiver(SmartPlayerJniV2.java)相关接口设计,如无语音广播或语音对讲相关技术需求,这部分可忽略:

/** SmartPlayerJniV2.java* Author: https://daniusdk.com*/
/** 创建RTP Receiver** @param reserve:保留参数传0** @return RTP Receiver 句柄,0表示失败*/
public native long CreateRTPReceiver(int reserve);/***设置 RTP Receiver传输协议** @param rtp_receiver_handle, CreateRTPReceiver* @param transport_protocol, 0:UDP, 1:TCP, 默认是UDP** @return {0} if successful*/
public native int SetRTPReceiverTransportProtocol(long rtp_receiver_handle, int transport_protocol);/***设置 RTP Receiver IP地址类型** @param rtp_receiver_handle, CreateRTPReceiver* @param ip_address_type, 0:IPV4, 1:IPV6, 默认是IPV4** @return {0} if successful*/
public native int SetRTPReceiverIPAddressType(long rtp_receiver_handle, int ip_address_type);/***设置 RTP Receiver RTP Socket本地端口** @param rtp_receiver_handle, CreateRTPReceiver* @param port, 必须是偶数,设置0的话SDK会自动分配, 默认值是0** @return {0} if successful*/
public native int SetRTPReceiverLocalPort(long rtp_receiver_handle, int port);/***设置 RTP Receiver SSRC** @param rtp_receiver_handle, CreateRTPReceiver* @param ssrc, 如果设置的话,这个字符串要能转换成uint32类型, 否则设置失败** @return {0} if successful*/
public native int SetRTPReceiverSSRC(long rtp_receiver_handle, String ssrc);/***创建 RTP Receiver 会话** @param rtp_receiver_handle, CreateRTPReceiver* @param reserve, 保留值,目前传0** @return {0} if successful*/
public native int CreateRTPReceiverSession(long rtp_receiver_handle, int reserve);/***获取 RTP Receiver RTP Socket本地端口** @param rtp_receiver_handle, CreateRTPReceiver** @return 失败返回0, 成功的话返回响应的端口, 请在CreateRTPReceiverSession返回成功之后调用*/
public native int GetRTPReceiverLocalPort(long rtp_receiver_handle);/***设置 RTP Receiver Payload 相关信息** @param rtp_receiver_handle, CreateRTPReceiver** @param payload_type, 请参考 RFC 3551** @param encoding_name, 编码名, 请参考 RFC 3551, 如果payload_type不是动态的, 可能传null就好** @param media_type, 媒体类型, 请参考 RFC 3551, 1 是视频, 2是音频** @param clock_rate, 请参考 RFC 3551** @return {0} if successful*/
public native int SetRTPReceiverPayloadType(long rtp_receiver_handle, int payload_type, String encoding_name, int media_type, int clock_rate);/***设置 RTP Receiver 音频采样率** @param rtp_receiver_handle, CreateRTPReceiver* @param sampling_rate, 音频采样率** @return {0} if successful*/
public native int SetRTPReceiverAudioSamplingRate(long rtp_receiver_handle, int sampling_rate);/***设置 RTP Receiver 音频通道数** @param rtp_receiver_handle, CreateRTPReceiver* @param channels, 音频通道数** @return {0} if successful*/
public native int SetRTPReceiverAudioChannels(long rtp_receiver_handle, int channels);/***设置 RTP Receiver 远端地址** @param rtp_receiver_handle, CreateRTPReceiver* @param address, IP地址* @param port, 端口** @return {0} if successful*/
public native int SetRTPReceiverRemoteAddress(long rtp_receiver_handle, String address, int port);/***初始化 RTP Receiver** @param rtp_receiver_handle, CreateRTPReceiver** @return {0} if successful*/
public native int InitRTPReceiver(long rtp_receiver_handle);/***UnInit RTP Receiver** @param rtp_receiver_handle, CreateRTPReceiver** @return {0} if successful*/
public native int UnInitRTPReceiver(long rtp_receiver_handle);/***Destory RTP Receiver Session** @param rtp_receiver_handle, CreateRTPReceiver** @return {0} if successful*/
public native int DestoryRTPReceiverSession(long rtp_receiver_handle);/***Destory RTP Receiver** @param rtp_receiver_handle, CreateRTPReceiver** @return {0} if successful*/
public native int DestoryRTPReceiver(long rtp_receiver_handle);

PostAudioPacket(SmartPlayerJniV2.java),投递音频包给外部Live source,目前仅于语音对讲使用:

/** SmartPlayerJniV2.java* Author: https://daniusdk.com*/
/*** 投递音频包给外部Live source, 注意ByteBuffer对象必须是DirectBuffer** @param handle: return value from SmartPlayerOpen()** @return {0} if successful*/
public native int PostAudioPacket(long handle, int codec_id,java.nio.ByteBuffer packet, int offset, int size, long pts, boolean is_pts_discontinuity,java.nio.ByteBuffer extra_data, int extra_data_offset, int extra_data_size, int sample_rate, int channels);

GB28181接口调用

对应GB28181相关接口调用相关设计如下:

/** SmartPublisherJniV2.java* Author: https://daniusdk.com*/
/*** 设置GB28181 RTP Sender** @param rtp_sender_handle, CreateRTPSender返回值* @param rtp_payload_type, 对于GB28181 PS, 协议定义是96, 具体以SDP为准,  RFC 3551有定义* @param encoding_name, 编码名, 请参考 RFC 3551, 当前仅支持: "PS", 其他值返回失败* @return {0} if successful*/
public native int SetGB28181RTPSender(long handle, long rtp_sender_handle, int rtp_payload_type, String encoding_name);/*** 设置GB28181 RTP 收到的音频包回调* @param handle* @param audio_packet_callback* @return*/
public native int SetGB28181ReceiveAudioPacketCallback(long handle, NTAudioPacketCallback audio_packet_callback);/*** 启动 GB28181 媒体流** @return {0} if successful*/
public native int StartGB28181MediaStream(long handle);/*** 停止 GB28181 媒体流** @return {0} if successful*/
public native int StopGB28181MediaStream(long handle);

总结

以上是大牛直播SDK发布的Android平台GB28181设备接入模块的相关说明,除了上述接口设计外,模块还可以扩展实现实时静音、实时快照、按需录像、实时音量调节等,可扩展性非常好。

Android平台GB28181接入模块技术接入说明相关推荐

  1. 如何实现Android平台GB28181前端设备接入

    技术背景 在实现Android平台GB28181前端设备接入之前,我们几年前就有了非常成熟的RTMP推送.RTSP推送和轻量级RTSP服务等模块,特别是RTMP推送,行业内应用非常广泛,好多开发者可能 ...

  2. Android平台GB28181设备接入端如何支持跨网段语音对讲

    技术背景 如果你是音视频开发者亦或寻求这块技术方案的公司,在探讨这个问题之前,你可能网上看了太多关于语音广播和语音对讲相关的资料,大多文章认为语音对讲和语音广播无本质区别,实现思路也大同小异. 今天我 ...

  3. Android平台GB28181设备接入端语音广播支持PS格式

    技术背景 对接Android平台GB28181设备接入端语音广播的时候,我们有遇到过INVITE SDP需要PCMA格式的audio,对方同时回了PS和PCMA两种,然后,发数据的时候,直接发了PS的 ...

  4. Android平台GB28181接入端如何对接UVC摄像头?

    我们在对接Android平台GB28181接入的时候,有公司提出这样的需求,除了采集执法记录仪摄像头自带的数据外,还想通过执法记录仪采集外接UVC摄像头. 实际上,这块对我们来说有点炒冷饭了,不算新的 ...

  5. 【ARCore】Android ARCore 简介 ( AR 增强现实技术简介 | Android 平台常用的 AR 技术 | ARCore 相关资料收集 )

    文章目录 一.AR 增强现实技术简介 二.Android 平台常用的 AR 技术 三.ARCore 相关资料收集 一.AR 增强现实技术简介 AR 全称 Augmented Reality , 增强现 ...

  6. Android平台GB28181设备接入模块之球机/云台控制探究

    技术背景 好多开发者在做GB28181设备接入的时候,问云台控制是否可以处理(亦或拉取外部RTSP摄像头,通过命令中转的方式,控制摄像头),实际上云台控制命令相对来说还是比较好处理的.协议规范有明确说 ...

  7. android智能识别技术,基于Android平台的OCR识别技术研究与实现

    摘要: 随着智能手机市场的迅猛发展和普及,Android成为所占市场份额最高的手机操作系统,与此同时,人们希望在手机终端享受更丰富舒适的应用功能.将OCR和Android智能终端相结合,依托光学字符识 ...

  8. android平台应用技术特点,Android平台应用安全关键技术研究

    摘要: 最近几年来,随着智能手机的普及和移动互联网技术的发展,手机成了人们日常生活中不可缺少的一部分.在众多的智能手机操作系统里面,Android系统以其开源,自由,免费等特点占有着很大的市场占有率. ...

  9. android 人脸识别 方法研究,基于Android平台的人脸识别技术研究

    摘要: 在计算机视觉与模式识别领域中,人脸检测与识别技术是一个非常热门的研究课题,同时也具备非常广阔的商业价值.在诸多的目标检测算法中,基于AdaBoost算法的目标检测方法具有检测速度快,检测效果好 ...

最新文章

  1. findclass java_Java Context.findClass方法代码示例
  2. python数据笔记分析_利用 Python 进行数据分析学习笔记(一)
  3. e2fsprogs制作嵌入式 mkfs.ext2 mkfs.ext3 mkfs.ext4
  4. 模拟登录QQ判断是否需要验证码
  5. springaop事务逻辑原理_搞懂Spring AOP,这一篇就够了
  6. 计算机入门模拟试题abcd,计算机一级计算机基础及WPSOffice应用考前模拟试题及答案(7)...
  7. 打印容器_3D打印:增材点阵结构在压力容器优化设计中的应用
  8. 服务器即将维护完成,新一轮大服务器即将开启:3月26日维护8小时
  9. element ui el-dialog 居中,并且内容多的时候内部可以滚动
  10. 代码创建按钮,文本输入框
  11. ydisk安卓版本_Y Disk HD
  12. 武田收到CHMP同意ALUNBRIG® (brigatinib)用于ALK+非小细胞肺癌一线治疗的肯定意见
  13. 光量子计算机技术突破,真正突破光刻机封锁的技术诞生了!可编程光量子计算芯片是什么?...
  14. 国家集训队论文分类整理
  15. RTOS成功取代Linux成为天猫精灵OS的关键 -- AliOS Things 维测专题
  16. 6.3.1广度优先搜索
  17. Transfer Learning 迁移学习的相关知识
  18. 新闻主题分类任务NLP
  19. Kafka不丢失数据与不重复消费数据
  20. 基于java web 的企业员工信息管理系统的设计与实现

热门文章

  1. 展望2022:Android开发技术动向
  2. python:实现计算电阻Calculate resistance(附完整源码)
  3. pdf文档添加书签的三种方式
  4. CSDN待审核文章测试
  5. [附源码]计算机毕业设计JAVA校园快递管理系统
  6. 计算机中cmos设置程序,计算机CMOS设置详解.doc
  7. java的绝对布局_2.2.6 AbsoluteLayout(绝对布局)
  8. 商用计算机可信系统,可信计算机系统安全评价标准.ppt
  9. 冰河远程控制软件使用
  10. php三年级英语,三年级英语拼词大赛