搜索
简帛阁>技术文章>海康威视4G球机对接萤石云平台实现实时预览、云台控制 ----- java完整demo

海康威视4G球机对接萤石云平台实现实时预览、云台控制 ----- java完整demo

前言:上一篇博文已经分享了如何获取直播列表,本篇博文是在上一篇博文的基础上做了完善,实现了实时预览和云台控制。因此,部分代码会有重复。

步骤一:在 萤石云开发平台 注册开发者并添加球机设备


步骤二:获取accessToken和直播列表请参考上一篇博文 海康威视4G球机对接萤石云平台获取直播视频列表

步骤三:云台控制

后端代码:action类

package com.jk.action;


import com.jk.comm.action.BaseAction;
import com.jiankong.util.HttpRequest;
import com.jiankong.util.TokenThread;

public class JianKongAction extends BaseAction{<!-- -->
	
	private String device; //设备序列号,存在英文字母的设备序列号,字母需为大写
	private Integer channelNo; //通道号
	private Integer direction;  //操作命令:0-上,1-下,2-左,3-右,4-左上,5-左下,6-右上,7-右下,8-放大,9-缩小,10-近焦距,11-远焦距
	private Integer speed;  //云台速度:0-慢,1-适中,2-快,海康设备参数不可为0
	
	public String getDevice() {<!-- -->
		return device;
	}

	public void setDevice(String device) {<!-- -->
		this.device = device;
	}

	public Integer getChannelNo() {<!-- -->
		return channelNo;
	}

	public void setChannelNo(Integer channelNo) {<!-- -->
		this.channelNo = channelNo;
	}

	public Integer getDirection() {<!-- -->
		return direction;
	}

	public void setDirection(Integer direction) {<!-- -->
		this.direction = direction;
	}

	public Integer getSpeed() {<!-- -->
		return speed;
	}

	public void setSpeed(Integer speed) {<!-- -->
		this.speed = speed;
	}

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	/**
	 * 获取直播列表
	 */
	public void getList(){<!-- -->
		String accessToken = MyHttpRequest.getAccessToken("https://open.ys7.com/api/lapp/token/get?appKey=xxxxxxxxxxxxxxxx&appSecret=xxxxxxxxxxxxxxxxx");
		//获取直播列表
		String list = HttpRequest.getList("https://open.ys7.com/api/lapp/live/video/list?accessToken="+accessToken+"&pageStart=0&pageSize=3");
		printJsonString(list);
	}
	/**
	 * 云台控制
	 * 开始云台控制之后必须先调用停止云台控制接口才能进行其他操作,包括其他方向的云台转动
	 */
	public void setCloudControl(){<!-- -->
		String accessToken = MyHttpRequest.getAccessToken("https://open.ys7.com/api/lapp/token/get?appKey=xxxxxxxxxxxxxxxx&appSecret=xxxxxxxxxxxxxxxxx");
		String start = "accessToken="+accessToken+"&deviceSerial="+device+"&channelNo="+channelNo+"&direction="+direction+"&speed="+speed;
		String stop =  "accessToken="+accessToken+"&deviceSerial="+device+"&channelNo="+channelNo+"&direction="+direction;
		jsonMsg = HttpRequest.setStartCloudControl("https://open.ys7.com/api/lapp/device/ptz/start?"+start);
		if(jsonMsg.equals("开始云台控制成功")){<!-- -->
			HttpRequest.setStopCloudControl("https://open.ys7.com/api/lapp/device/ptz/stop?"+stop);
		}
		printJsonString(jsonMsg);
	}
	
}

action父类:

public class BaseAction extends ActionSupport  {<!-- -->
    
    protected int             page             = 1;             //当前第几页
    protected int             rows         	   = 10;            // 每页数量
    protected String		  jsonMsg		   = "";

	/**
     * 打印Json字符串返回给客户
     * @param jsonString
     * @Description:
     */
    protected void printJsonString ( String jsonString ) {<!-- -->
        PrintWriter out = null;
        try {<!-- -->
        	HttpServletResponse response = getResponse();
        	response.setCharacterEncoding ( "UTF-8" );
            response.setContentType("text/html;charset=UTF-8");             
            out = response.getWriter ();
            out.print ( jsonString );
        }
        catch (IOException e) {<!-- -->
            e.printStackTrace ();
        }
        finally {<!-- -->
            out.close ();
        }
    }
}

util类

package com.jiankong.util;

import java.util.HashMap;
import java.util.Map;

import net.sf.json.JSONObject;

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.params.ClientPNames;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;


public class HttpRequest {<!-- -->
	/**
	 * 获取监控应用的 accessToken
	 * @param url
	 * @return
	 */
	public static String getAccessToken(String url) {<!-- -->
		DefaultHttpClient client = new DefaultHttpClient();
		client.getParams().setParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS,true);
		HttpPost httpost = getPostMethod(url);
		String accessToken = "";
		try {<!-- -->
			try {<!-- -->
				
				HttpResponse response = client.execute(httpost);
				String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8");
				System.out.println("jsonStr:"+jsonStr);
				JSONObject jsStr = JSONObject.fromObject(jsonStr);
				System.out.println("jsStr:"+jsStr);
				String code = String.valueOf(jsStr.get("code"));
				if(code.equals("200")){<!-- -->
					String data = jsStr.getString("data");
					JSONObject dataJson = JSONObject.fromObject(data);
					accessToken = dataJson.getString("accessToken");
					return accessToken;
				}
			} catch (Exception e) {<!-- -->
				e.printStackTrace();
			}
		} catch (Exception e) {<!-- -->
			e.printStackTrace();
		} finally {<!-- -->
			if(!httpost.isAborted()){<!-- -->
				httpost.abort();
			}
			client.getConnectionManager().shutdown();
		}
		return accessToken;
	}
	
	/**
	 * 获取直播视频列表
	 * @param url
	 * @return
	 */
	public static String getList(String url) {<!-- -->
		DefaultHttpClient client = new DefaultHttpClient();
		client.getParams().setParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS,true);
		HttpPost httpost = getPostMethod(url);
		String list = "";
		try {<!-- -->
			try {<!-- -->
				
				HttpResponse response = client.execute(httpost);
				String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8");
				System.out.println("jsonStr:"+jsonStr);
				JSONObject jsStr = JSONObject.fromObject(jsonStr);
				String code = jsStr.getString("code");
				if(code.equals("200")){<!-- -->
					list = jsStr.getString("data");
					return list;
				}else if(code.equals("10002")){<!-- -->  //accessToken过期或异常
					
				}
			} catch (Exception e) {<!-- -->
				e.printStackTrace();
			}
		} catch (Exception e) {<!-- -->
			e.printStackTrace();
		} finally {<!-- -->
			if(!httpost.isAborted()){<!-- -->
				httpost.abort();
			}
			client.getConnectionManager().shutdown();
		}
		return list;
	}
	
	
	public static String setStartCloudControl(String url){<!-- -->

		DefaultHttpClient client = new DefaultHttpClient();
		client.getParams().setParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS,true);
		HttpPost httpost = getPostMethod(url);
		String msg = "";
		try {<!-- -->
			try {<!-- -->
				
				HttpResponse response = client.execute(httpost);
				String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8");
				System.out.println("jsonStr:"+jsonStr);
				JSONObject jsStr = JSONObject.fromObject(jsonStr);
				String code = jsStr.getString("code");
				if(code.equals("200")){<!-- -->
					msg = "开始云台控制成功";
				}else{<!-- -->
					msg = "开始云台控制失败";
				}
			} catch (Exception e) {<!-- -->
				e.printStackTrace();
			}
		} catch (Exception e) {<!-- -->
			e.printStackTrace();
		} finally {<!-- -->
			if(!httpost.isAborted()){<!-- -->
				httpost.abort();
			}
			client.getConnectionManager().shutdown();
		}
		return msg;
	
	}
	
	
	public static String setStopCloudControl(String url){<!-- -->

		DefaultHttpClient client = new DefaultHttpClient();
		client.getParams().setParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS,true);
		HttpPost httpost = getPostMethod(url);
		String msg = "";
		try {<!-- -->
			try {<!-- -->
				
				HttpResponse response = client.execute(httpost);
				String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8");
				System.out.println("jsonStr:"+jsonStr);
				JSONObject jsStr = JSONObject.fromObject(jsonStr);
				String code = jsStr.getString("code");
				if(code.equals("200")){<!-- -->
					msg = "停止云台控制成功";
				}else{<!-- -->
					msg = "停止云台控制失败";
				}
			} catch (Exception e) {<!-- -->
				e.printStackTrace();
			}
		} catch (Exception e) {<!-- -->
			e.printStackTrace();
		} finally {<!-- -->
			if(!httpost.isAborted()){<!-- -->
				httpost.abort();
			}
			client.getConnectionManager().shutdown();
		}
		return msg;
	
	}
	/**
	 * 模拟浏览器post提交
	 * 
	 * @param url
	 * @return
	 */
	public static HttpPost getPostMethod(String url) {<!-- -->
		HttpPost pmethod = new HttpPost(url); // 设置响应头信息
		pmethod.addHeader("Connection", "keep-alive");
		pmethod.addHeader("Accept", "*/*");
		pmethod.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
		pmethod.addHeader("Host", "open.ys7.com");
		pmethod.addHeader("X-Requested-With", "XMLHttpRequest");
		pmethod.addHeader("Cache-Control", "max-age=0");
		pmethod.addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ");
		return pmethod;
	}
}

前端页面:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>监控网点</title>
    
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<link href="${basePath}static/css/jiankong.css" rel="stylesheet" type="text/css"/>
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->
	<style type="text/css">
		body{<!-- -->margin:0;}
        #myPlayer{max-width: 600px;width: 100%;display: inline;}
        #myPlayer1{max-width: 600px;width: 100%;display: inline;}
        #myPlayer2{max-width: 600px;width: 100%;display: inline;}
        .num{<!-- -->
        	max-width: 600px;
        	display: inline;
        }
        .head{<!-- -->
        	display: inline-grid;
        	width: 600px;
        }
	</style>
	<script src="${basePath}static/js/hontek/jiankong/ezuikit.js" type="text/javascript"></script>
	<script src="${basePath}static/js/jquery/jquery-1.8.0.min.js" type="text/javascript"></script>
	<script src="${basePath}static/js/layer/layer.js" type="text/javascript"></script>
  </head>
   
 <body>
 	<div class="head">
	 	<div class="num">1号监控点</div>
	   <video id="myPlayer" controls playsInline webkit-playsinline autoplay>
	    	<source id="playVideo0" src="" type="rtmp/flv" />
	   </video>
   </div>
   <div class="head">
	   <div class="num">2号监控点</div>
	   <video id="myPlayer1" controls playsInline webkit-playsinline autoplay>
	    	<source id="playVideo1" src="" type="rtmp/flv" />
	   </video>
   </div>
   <div class="head">
	   <div class="num">3号监控点</div>
	   <video id="myPlayer2" controls playsInline webkit-playsinline autoplay>
	    	<source id="playVideo2" src="" type="rtmp/flv" />
	   </video>
   </div>
   <div class="head">
   		<fieldset class="ptz" style="position: absolute;margin-top: 80px;margin-left: 60px;">
        <legend>云台控制</legend>
        <table cellpadding="0" cellspacing="3" border="0" class="left">
            <tr>
                <td>
                    <input type="button" class="btn" value="左上" onclick="cloudControl(4)" />
                    <input type="button" class="btn" value="上" onclick="cloudControl(0)"/>
                    <input type="button" class="btn" value="右上" onclick="cloudControl(6)" />
                </td>
            </tr>
            <tr>
                <td>
                    <input type="button" class="btn" value="左" onclick="cloudControl(2)"/>
                    <input type="button" class="btn" value="自动" onclick="" style="display:none"/>
                    <input type="button" class="btn" value="右" onclick="cloudControl(3)" style="position: unset;margin-left: 49px;"/>
                </td>
            </tr>
            <tr>
                <td>
                    <input type="button" class="btn" value="左下" onclick="cloudControl(5)" />
                    <input type="button" class="btn" value="下" onclick="cloudControl(1)"/>
                    <input type="button" class="btn" value="右下" onclick="cloudControl(7)"/>
                </td>
            </tr>
        </table>
        <table cellpadding="0" cellspacing="3" border="0" class="left">
            <tr>
                <td class="tt">云台速度</td>
                <td>
                    <select id="ptzspeed" class="sel">
                        <option value="1" >适中</option>
                        <option value="2">快</option>

                    </select>
                </td>
            </tr>
            <tr>
                <td class="tt">监控点</td>
                <td id="jkd">
                	
                </td>
            </tr>
           
        </table>
        <table cellpadding="0" cellspacing="3" border="0" class="left">
            <tr>
                <td class="tt"><input type="button" class="btn2" value="变倍+" onclick="cloudControl(8)"></td>
                <td><input type="button" class="btn2" value="变倍-" onclick="cloudControl(9)"></td>
            </tr>
            
            <tr style="position: absolute;margin-top: 20px;margin-left: -2px;">
                <td class="tt"><input type="button" class="btn2" value="变焦+" onclick="cloudControl(10)"></td>
                <td><input type="button" class="btn2" value="变焦-" onclick="cloudControl(11)"></td>
            </tr>
            
        </table>
    </fieldset>
   </div>
<script>
	
  $.post('jiankong_getList.action','',function(res){<!-- -->
      if(res.length>0){<!-- -->
    	  var myJkd = "<select id='direction' class='sel'>";
    	  for(var i=0;i<res.length;i++){<!-- -->
    		  var rtmp = res[i].rtmp;
    		  $("#playVideo"+i).attr('src',rtmp);
    		  myJkd+="<option value='"+res[i].deviceSerial+"'>"+(i+1)+"号监控点</option>";
    	  }
    	  myJkd+=" </select>";
    	  $("#jkd").html(myJkd);
    	  var player = new EZuikit.EZUIPlayer('myPlayer');
    	  var player1 = new EZuikit.EZUIPlayer('myPlayer1');
      }else{<!-- -->
          alert("获取失败");
      }
  },'json');
  
  function cloudControl(direction){<!-- -->
	  layer.load(2);
	  var jkd = $("#jkd option:selected").val();//选中的值
	  var speed = $("#ptzspeed option:selected").val();//选中的值
	  var data ={<!-- -->
			"device":jkd,
			"channelNo":1,
			"direction":direction,
			"speed":speed
	  };
	  $.post('jiankong_setCloudControl.action',data,function(res){<!-- -->
		  layer.closeAll('loading'); 
	  },'text');
  }
</script>

</body>
</html>

jiankong.css文件

@charset "utf-8";
* 
{<!-- -->
    margin:0;
    padding:0;
}
html
{<!-- -->
    width:100%;
    height:100%;
    font-size:12px;
    font-family:Arial, Helvetica, sans-serif;
    -webkit-text-size-adjust:none;
    background:#FFFFFF;
}
body
{<!-- -->
    padding:5px;
}
select
{<!-- -->
    height:20px;
    line-height:20px;
}
.left
{<!-- -->
    float:left;
}
.freeze
{<!-- -->
    position:absolute;
    text-align:center;
    background:#343434;
    color:#FFFFFF;
    font-size:26px;
    font-weight:bold;
    filter:alpha(opacity=60);
    opacity:0.6;
}
.vtop
{<!-- -->
    vertical-align:middle;
    margin-top:-1px;
}
/*插件*/
.plugin
{<!-- -->
    width:800px;
    height:600px;
    top:10px;
}
 object
{<!-- -->
    width:800px !important ;
    height:600px !important;
}
fieldset
{<!-- -->
    display:block;
}
/*本地配置*/
.localconfig
{<!-- -->
    width:480px;
    padding:10px;
    border:1px solid #7F9DB9;
}
.localconfig .tt
{<!-- -->
    width:125px;
}
.localconfig .txt
{<!-- -->
    width:310px;
}
.localconfig .txt2
{<!-- -->
    width:300px;
}
.localconfig .btn
{<!-- -->
    width:45px;
    height:22px;
    line-height:18px;
}
.localconfig .sel
{<!-- -->
    width:120px;
}
/*登录*/
.login
{<!-- -->
    width:480px;
    padding:10px;
    border:1px solid #7F9DB9;
}
.login .tt
{<!-- -->
    width:100px;
}
.login .txt
{<!-- -->
    width:130px;
}
.login .btn
{<!-- -->
    width:45px;
    height:22px;
    line-height:18px;
}
.login .btn2
{<!-- -->
    width:100px;
    height:22px;
    line-height:18px;
}
.login .sel
{<!-- -->
    width:130px;
}
.login .sel2
{<!-- -->
    width:65px;
}
/*数字通道*/
.ipchannel
{<!-- -->
    width:480px;
    padding:10px;
    border:1px solid #7F9DB9;
}
.ipchannel .btn
{<!-- -->
    width:130px;
    height:22px;
    line-height:18px;
}
.ipchannel .digitaltdiv
{<!-- -->
    height:100px;
    overflow:hidden;
    overflow-y:auto;
    border:1px solid #7F9DB9;
    font-size:11px;
}
.ipchannel .digitalchannellist th, .ipchannel .digitalchannellist td
{<!-- -->
    padding:2px;
    border:1px solid #7F9DB9;
    border-collapse:collapse;
    white-space:nowrap;
}
/*预览*/
.preview
{<!-- -->
    width:450px;
    padding:10px;
    padding-top:0;
    margin-left:10px;
    border:1px solid #7F9DB9;
}
.preview .tt
{<!-- -->
    width:60px;
}
.preview .txt
{<!-- -->
    width:30px;
}
.preview .btn
{<!-- -->
    width:70px;
    height:22px;
    line-height:18px;
}
.preview .btn2
{<!-- -->
    width:90px;
    height:22px;
    line-height:18px;
}
.preview .sel
{<!-- -->
    width:105px;
}
/*云台*/
.ptz
{<!-- -->
    width:450px;
    padding:10px;
    margin-left:10px;
    border:1px solid #7F9DB9;
}
.ptz .tt
{<!-- -->
    width:60px;
}
.ptz .txt
{<!-- -->
    width:60px;
}
.ptz .btn
{<!-- -->
    width:45px;
    height:22px;
    line-height:18px;
}
.ptz .btn2
{<!-- -->
    width:60px;
    height:22px;
    line-height:18px;
}
.ptz .sel
{<!-- -->
    width:100px;
}
/*视频参数*/
.videoparam
{<!-- -->
    width:450px;
    padding:10px;
    margin-left:10px;
    border:1px solid #7F9DB9;
}
.videoparam .tt
{<!-- -->
    width:60px;
}
.videoparam .txt
{<!-- -->
    width:60px;
}
.videoparam .btn
{<!-- -->
    width:45px;
    height:22px;
    line-height:18px;
}
.videoparam .sel
{<!-- -->
    width:65px;
}
/*回放*/
.playback
{<!-- -->
    width:450px;
    padding:10px;
    margin-left:10px;
    border:1px solid #7F9DB9;
}
.playback .tt
{<!-- -->
    width:60px;
}
.playback .txt
{<!-- -->
    width:140px;
}
.playback .btn
{<!-- -->
    width:45px;
    height:22px;
    line-height:18px;
}
.playback .btn2
{<!-- -->
    width:70px;
    height:22px;
    line-height:18px;
}
.playback .sel
{<!-- -->
    width:142px;
}
.playback .searchdiv
{<!-- -->
    height:100px;
    overflow:hidden;
    overflow-y:auto;
    border:1px solid #7F9DB9;
    font-size:11px;
}
.playback .searchlist th, .playback .searchlist td
{<!-- -->
    padding:2px;
    border:1px solid #7F9DB9;
    border-collapse:collapse;
    white-space:nowrap;
}
/*系统维护*/
.maintain
{<!-- -->
    width:450px;
    padding:10px;
    margin-left:10px;
    border:1px solid #7F9DB9;
}
.maintain .tt
{<!-- -->
    width:60px;
}
.maintain .txt
{<!-- -->
    width:280px;
}
.maintain .btn
{<!-- -->
    width:45px;
    height:22px;
    line-height:18px;
}
.maintain .btn2
{<!-- -->
    width:100px;
    height:22px;
    line-height:18px;
}
.maintain .sel
{<!-- -->
    width:65px;
}
/*操作信息*/
.operate
{<!-- -->
    width:450px;
    padding:10px;
    margin-left:10px;
    border:1px solid #7F9DB9;
}
.operate .opinfo
{<!-- -->
    height:150px;
    border:1px solid #7F9DB9;
    overflow:auto;
}
/*事件回调*/
.callback
{<!-- -->
    width:450px;
    padding:10px;
    margin-left:10px;
    border:1px solid #7F9DB9;
}
.callback .cbinfo
{<!-- -->
    height:114px;
    border:1px solid #7F9DB9;
    overflow:auto;
}
/*IP解析*/
.ipparse
{<!-- -->
    width:450px;
    padding:10px;
    margin-left:10px;
    border:1px solid #7F9DB9;
}
.ipparse .tt
{<!-- -->
    width:85px;
}
.ipparse .txt
{<!-- -->
    width:130px;
}
.ipparse .btn
{<!-- -->
    width:90px;
    height:22px;
    line-height:18px;
}
.ipparse .sel
{<!-- -->
    width:130px;
}
/*绘图*/
.draw
{<!-- -->
    width:450px;
    padding:10px;
    padding-top:0;
    margin-left:10px;
    border:1px solid #7F9DB9;
}
.draw .tt
{<!-- -->
    width:60px;
}
.draw .txt
{<!-- -->
    width:140px;
}
.draw .btn
{<!-- -->
    width:70px;
    height:22px;
    line-height:18px;
}
.draw .btn2
{<!-- -->
    width:100px;
    height:22px;
    line-height:18px;
}
.draw .sel
{<!-- -->
    width:105px;
}

注:ezuikit.js文件可在萤石云开发平台下载

最终效果如下:

有两台设备,不过此时只一台设备接通了电源。

智哪儿获悉,12月13日晚间,上交所受理杭州萤石网络股份有限公司(简称“萤石网络”)科创板上市申请,公司拟募资3739亿元,用于萤石智能制造重庆基地项目、新一代物联网平台项目、智能家居核心关键技术研
题描述整网有一部分裸金属服务器,连接至几台华为交换机上,需要使用浪潮平台管理裸金属服务器,因此需放开交换机的管理权限给平台管理组件。平台管理端接管华为交换机后,在对华为交换机进行远程配置并重启
杭州康威一面技术面(视频):20min​1、自我介绍​2、哪个项目成长最大,讲一讲​3、imu几轴的?用到那些数据?​我说6轴,偏航角和加速度(加速度判断撞墙)​小车启动加速度也会突变,怎么解决的
签名授权publicstaticTTecentDoPostJsonV3(Stringurl,Stringkey,StringsecretId,TecentPublicParamsheader,Stri
本文主要是博主使用海康SDK进行人流量统计的摸索过程,在这里简单记录一下。查询文档,能实现人流量统计大概有两种方式,报警或者监听,这边我选择了监听方式,NET_DVR_StartListen_V30这
实现一个流控程序。控制客户端每秒调用某个远程服务不超过N次,客户端是会多线程并发调用,需要一个轻量简洁的实现,大家看看下面的一个实现,然后可以自己写一个实现。importjavautilDate;im
整理|王启隆透过「历史上的今天」,从过去看未来,从现在亦可以改变未来。今天是2022年1月6日,在1838年的今天,美国发明家摩尔斯发明电报机。欧洲的科学家在十八世纪开始逐渐发现电的各种特质,同时开始
项目总结25:康威SDKJava二次开发客流量分析前言本来一个很简单的SDK接口对接,折腾了好久;总结下原因有:康的SDK底层使用C++写的,我不熟悉C++;海康Java源码示例写的是一个Sw
G将军有一支训练有素的军队,这个军队除开G将军外,每名士兵都有一个直接上级(可能是其他士兵,也可能是G将军)。现在G将军将接受一个特别的任务,需要派遣一部分士兵(至少一个)组成一个敢死队,为了增加队员
一、功能目标用户输入一个类似12*((6030+(40/5)*(92*5/3+7/3*99/4*2998+10*568/14))(4*3)/(163*2))这样的表达式,假设表达式里面除了包含空格、'