package com.newfiber.api.pc.camera.service; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjectUtil; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import com.newfiber.api.core.commons.CustomException; import com.newfiber.api.pc.camera.dto.Result; import com.newfiber.api.pc.camera.dto.Stream; import com.newfiber.api.pc.camera.util.CONST; import com.newfiber.api.pc.camera.util.HttpSend; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; /** * @program: OpenJavaDemo * @description: 登录接口 * @author: djt * @create: 2020-12-10 14:51 **/ @Slf4j @Service public class CameraService { @Autowired private HttpSend httpSend; /** * 请i去 * * @param paramsMap * @param methodUrl * @param token * @return java.lang.String * @author djt * @creed: Talk is cheap,show me the code * @date 2020/12/12 8:45 * @description: ${description} */ private String rpc(Map<String, Object> paramsMap, String methodUrl, String token) { String url = String.format(CONST.URL, methodUrl); log.info("获取调用的URL:{}",CONST.URL); Map<String, Object> map = httpSend.buildSystemParams(); paramsMap.put("token", token); map.put("params", paramsMap); Optional<String> optional = httpSend.doPost(url, map); return optional.orElseThrow(() -> new RuntimeException("通讯失败,返回数据为空")); } /** * 请求 * * @param paramsMap * @param methodUrl * @return java.lang.String * @author djt * @creed: Talk is cheap,show me the code * @date 2020/12/12 8:46 * @description: ${description} */ public String rpc(Map<String, Object> paramsMap, String methodUrl) { // checkToken(); String rpcString = rpc(paramsMap, methodUrl, CONST.token); JSONObject result = JSONObject.parseObject(rpcString).getJSONObject("result"); if (StringUtils.equalsIgnoreCase(result.getString("code"), "TK1002")) { doLogin(0); return rpc(paramsMap, methodUrl, CONST.token); } return rpcString; } /** * 检查tooken是否存在 。。可改成redis? todo * * @param * @return void * @author djt * @creed: Talk is cheap,show me the code * @date 2020/12/12 8:44 * @description: ${description} */ private void checkToken() { doLogin(0); } /** * 登录,请求得到token * * @param retry 重试次数 * @return void * @author djt * @creed: Talk is cheap,show me the code * @date 2020/12/12 8:45 * @description: ${description} */ private void doLogin(int retry) { if (retry >= 3) { throw new CustomException(500,"登录失败,超过登录最大重试次数,停止重试"); } String json = rpc(Maps.newHashMap(), CONST.ACCESSTOKEN_V2, null); if (!loginParse(json)) { retry++; doLogin(retry); } } /** * 解析登录 * * @param jsonObject * @return boolean * "expireTime":259176, * "accessToken":"At_00006ac6e32d123141238f60147de7ec" * @author djt * @creed: Talk is cheap,show me the code * @date 2020/12/11 13:45 * @description: ${description} */ private boolean loginParse(String jsonObject) { JSONObject result = JSONObject.parseObject(jsonObject).getJSONObject("result"); if (StringUtils.equalsIgnoreCase(result.getString("code"), "0")) { CONST.token = result.getJSONObject("data").getString("accessToken"); return true; } return false; } /** * 检查设备是否创建过直播,若创建过。。直接返回播放地址,若没有,则去创建播放。。在返回地址 * * @param * @return boolean * @author djt * @creed: Talk is cheap,show me the code * @date 2020/12/11 14:31 * @description: ${description} */ public String checkCameraPlaying(String deviceId,String channelId) { Map<String, Object> map = Maps.newHashMap(); map.put("deviceId", deviceId); map.put("channelId", channelId); map.put("streamId",1); String json = rpc(map, CONST.GETLIVESTREAMINFO_V2); //String json = rpc(map, CONST.BINDDEVICELIVE_V2); Optional<String> url = parseDeviceUrl(json); return url.orElseGet(() -> play(deviceId,channelId)); } /** * 根据deviceid播放 创建直播 * * @param deviceId * @return java.lang.String * @author djt * @creed: Talk is cheap,show me the code * @date 2020/12/12 8:43 * @description: ${description} */ private String play(String deviceId,String channelId) { Map<String, Object> map = Maps.newHashMap(); map.put("streamId", 1); map.put("deviceId", deviceId); map.put("channelId", channelId); String json = rpc(map, CONST.BINDDEVICELIVE_V2); return playParse(json); } /** * 根据设备id,获取直播地址 * * @param json * @return java.lang.String * @author djt * @creed: Talk is cheap,show me the code * @date 2020/12/11 16:57 * @description: ${description} */ private Optional<String> parseDeviceUrl(String json) { Result<JSONObject> result = JSONObject.parseObject(json).getObject("result", Result.class); //若没有则返回null if (StringUtils.equalsIgnoreCase("LV1002", result.getCode())) { return Optional.empty(); } //若是其他状态码。。直接返回前端 if (!StringUtils.equalsIgnoreCase("0", result.getCode())) { throw new CustomException(500,result.getMsg()); } //返回直播地址 JSONArray jsonArray = result.getData().getJSONArray("streams"); if (ObjectUtil.isNotNull(jsonArray)&&jsonArray.size()>1) { Stream stream = jsonArray.getObject(0, Stream.class); return Optional.of(stream.getHls()); } return Optional.empty(); } /** * 解析添加直播的回复,添加错误,抛出异常。添加成功返回直播地址(入口为检查视频是否播放中) * * @param jsonObject * @return void * @author djt * @creed: Talk is cheap,show me the code * @date 2020/12/11 17:24 * @description: ${description} */ private String playParse(String jsonObject) { Result<JSONObject> result = JSONObject.parseObject(jsonObject).getObject("result", Result.class); if (StringUtils.equalsIgnoreCase(result.getCode(), "0")) { return result.getData().getJSONArray("streams").getJSONObject(0).getString("hls"); // Stream stream = (Stream) result.getData().getJSONArray("streams").get(0); // return stream.getHls(); } throw new CustomException(500,result.getMsg()); } /** * 只需要,知道是否成功 * * @param json * @return boolean * @author djt * @creed: Talk is cheap,show me the code * @date 2020/12/11 17:54 * @description: ${description} */ private boolean parseJson(String json) { Result<JSONObject> result = JSONObject.parseObject(json).getObject("result", Result.class); if (StringUtils.equalsIgnoreCase(result.getCode(), "0")) { return true; } throw new CustomException(500,result.getMsg()); } // public static void main(String[] args) { // CameraService service = new CameraService(); // service.checkCameraPlaying("6F00BA1PAZ57D9C"); // service.ptz("6F00BA1PAZ57D9C", "1"); // Map<String, Object> map = new HashMap<String, Object>(5); // map.put("limit", "128"); // map.put("type", "bind"); // map.put("bindId", "-1"); // map.put("needApInfo", "true"); // service.rpc(map, CONST.DEVICEOPENLIST_V2, token); // service.checkCameraPlaying("6F00BA1PAZ57D9C"); // service.play("6F00BA1PAZ57D9C"); // map.put("streamId", 1); // map.put("deviceId", "6F00BA1PAZ57D9C"); // map.put("channelId", "0"); // service.rpc(map,CONST.PLAY_V2,token); // service.doPlay(map); // map.put("type","All"); // map.put("queryRange","1-10"); // map.put("beginTime","2020-05-19 00:00:00"); // map.put("endTime","2020-12-11 23:59:59"); // map.put("channelId","0"); // map.put("deviceId","6F00BA1PAZ57D9C"); // service.rpc(map,CONST.QUERYLOCALRECORDS_V2,token); // map.put("deviceId", "6F00BA1PAZ57D9C"); // map.put("channelId", "0"); // // 0-上,1-下,2-左,3-右,4-左上,5-左下,6-右上,7-右下,8-放大,9-缩小,10-停止 // map.put("operation", "0"); // map.put("duration", "1000"); // service.rpc(map, CONST.CONTROLMOVEPTZ_V2, token); // } /** * 云台控制, * * @param deviceId 设备id,设备唯一标识,并不是自己生成的id,而是 * @param instruct 云台控制指令 * @return boolean * @author djt * @creed: Talk is cheap,show me the code * @date 2020/12/12 8:42 * @description: ${description} */ public boolean ptz(String deviceId, String instruct,String channelId) { if (INSTRUCTS.contains(instruct)) { Map<String, Object> map = Maps.newHashMap(); map.put("deviceId", deviceId); map.put("channelId", channelId); // 0-上,1-下,2-左,3-右,4-左上,5-左下,6-右上,7-右下,8-放大,9-缩小,10-停止 map.put("operation", instruct); map.put("duration", "1000"); String json = rpc(map, CONST.CONTROLMOVEPTZ_V2); return parseJson(json); } throw new CustomException(500,"其他未知指令,请输入正确指令"); } /** * 根据设备的序列号。。查询设备的信息 * * @param deviceIds 查询设备的集合 * @return java.lang.String * @author djt * @creed: Talk is cheap,show me the code * @date 2020/12/12 11:07 * @description: ${description} 最多8个设备 */ public String list(List<String> deviceIds) { if (CollUtil.isEmpty(deviceIds)) { throw new CustomException(500,"查询参数不能为空"); } Map<String, Object> map = Maps.newHashMap(); List<Map<String, Object>> json = Lists.newArrayList(); deviceIds.forEach(i -> { json.add(ImmutableMap.of("deviceId", i)); }); map.put("deviceList", json); rpc(map, CONST.DEVICE_OPENDETAIL_LIST_V2); return null; } /** * 绑定设备 * * @param deviceId 设备序列号 * @param code 设备验证码 admin123 * @return void * @author djt * @creed: Talk is cheap,show me the code * @date 2020/12/12 11:13 * @description: ${description} */ public boolean bindDevice(String deviceId, String code) { Map<String, Object> map = Maps.newHashMap(); map.put("deviceId", deviceId); map.put("code", code); String json = rpc(map, CONST.BIND_DEVICE_V2); return parseJson(json); } /** * 解绑设备 * * @param deviceId 设备序列号 * @return boolean * @author djt * @creed: Talk is cheap,show me the code * @date 2020/12/12 11:12 * @description: ${description} */ public boolean unBindDevice(String deviceId) { Map<String, Object> map = Maps.newHashMap(); map.put("deviceId", deviceId); String json = rpc(map, CONST.UNBINDDEVICE_V2); return parseJson(json); } public Result<JSONObject> selectDeviceBindByDeviceCode(String deviceCode){ Map<String, Object> map = Maps.newHashMap(); map.put("deviceId", deviceCode); String json = rpc(map, CONST.CHECKDEVICEBINDORNOT_V2); return JSONObject.parseObject(json).getObject("result", Result.class); } /** * * @param deviceCode 设备序列号 * @return boolean * @author djt * @creed: Talk is cheap,show me the code * @date 2020/12/15 9:43 * @description: ${description} */ public boolean selectCameraStatus(String deviceCode) { Map<String, Object> map = Maps.newHashMap(); map.put("deviceId", deviceCode); try{ String json = rpc(map, CONST.DEVICEONLINE_V2); Result<JSONObject> result = JSONObject.parseObject(json).getObject("result", Result.class); if (StringUtils.equalsIgnoreCase(result.getCode(), "0")) { String status = result.getData().getString("onLine"); return StringUtils.equalsIgnoreCase("1", status); } }catch (Exception e){ log.error("同步摄像头的在线状态错误,错误信息:{},摄像头信息:{}",e.getLocalizedMessage(),deviceCode); return false; } return false; } private static final Set<String> INSTRUCTS = Sets.newHashSet("0","1", "2", "3", "4", "5", "6", "7", "8", "9", "10"); }