package com.fzzy.igds.camera.impl;
|
|
import com.alibaba.fastjson.JSONObject;
|
import com.fzzy.igds.camera.AbstractApiCameraService;
|
import com.fzzy.igds.camera.data.*;
|
import com.fzzy.igds.camera.data.ydqly.YdQlyCamera;
|
import com.fzzy.igds.camera.data.ydqly.YdQlyDto;
|
import com.fzzy.igds.camera.data.ydqly.YdQlyResp;
|
import com.fzzy.igds.constant.CameraPlayType;
|
import com.fzzy.igds.constant.Constant;
|
import com.fzzy.igds.constant.RedisConst;
|
import com.fzzy.igds.domain.Camera;
|
import com.fzzy.igds.domain.CameraMedia;
|
import com.fzzy.igds.service.CameraMediaService;
|
import com.fzzy.igds.service.SecCameraService;
|
import com.fzzy.igds.utils.ContextUtil;
|
import com.fzzy.igds.utils.HttpUtils;
|
import com.ruoyi.common.core.redis.RedisCache;
|
import com.ruoyi.common.utils.StringUtils;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.stereotype.Component;
|
import javax.annotation.Resource;
|
import java.util.*;
|
import java.util.concurrent.TimeUnit;
|
import org.apache.commons.codec.binary.Hex;
|
import org.apache.commons.codec.digest.DigestUtils;
|
import java.security.*;
|
import java.security.spec.PKCS8EncodedKeySpec;
|
|
/**
|
* @Desc 移动千里眼播放
|
* @Author CZT
|
* @Date 2026/01/04 16:09
|
*/
|
@Slf4j
|
@Component
|
public class ApiPlayYdQlyService extends AbstractApiCameraService {
|
|
/**
|
* 获取accessToken接口路径
|
*/
|
private static final String URL_ACCESS_TOKEN = "https://open.qly.cmviot.cn/v3/open/api/token";
|
private static final String URL_PLAY_LIVE = "https://open.qly.cmviot.cn/v3/open/api/websdk/live";
|
|
private static final String URL_CAMERA_LIST = "https://open.qly.cmviot.cn/v3/open/api/node/tree";
|
|
@Resource
|
private CameraMediaService cameraMediaService;
|
@Resource
|
private SecCameraService cameraService;
|
@Resource
|
private RedisCache redisCache;
|
|
@Override
|
public String getType() {
|
return CameraPlayType.PLAY_TYPE_YD_QLY.getCode();
|
}
|
|
@Override
|
public ApiCameraResp getPlayAddr(ApiCameraData apiCameraDto) {
|
|
if (StringUtils.isBlank(apiCameraDto.getCameraId())) {
|
log.error("获取摄像头信息失败,监控ID为空!");
|
return null;
|
}
|
|
if (StringUtils.isBlank(apiCameraDto.getDeptId())) {
|
log.error("获取摄像头信息失败,库区编码为空!");
|
return null;
|
}
|
|
//查询库区流媒体配置,获取库区节点
|
CameraMedia cameraMedia = cameraMediaService.getByDeptId(apiCameraDto.getDeptId(), apiCameraDto.getCompanyId());
|
if(null == cameraMedia || StringUtils.isBlank(cameraMedia.getYdStoreId())){
|
log.error("获取摄像头信息失败,库区节点未配置!");
|
return null;
|
}
|
|
//接口获取播放地址
|
YdQlyResp resp = getPlayUrl(cameraMedia, apiCameraDto.getCameraId());
|
|
if(!"000000".equals(resp.getResultCode())){
|
return new ApiCameraResp(ApiCameraResp.CODE_ERROR, resp.getResultMsg());
|
}
|
YdQlyDto dto = JSONObject.parseObject(resp.getData(), YdQlyDto.class);
|
if (null == dto || StringUtils.isBlank(dto.getUrl())) {
|
return new ApiCameraResp(ApiCameraResp.CODE_ERROR, "未获取到摄像头播放地址!");
|
}
|
|
return new ApiCameraResp(dto.getUrl());
|
}
|
|
@Override
|
public List<Camera> searchCamera(ApiCameraData apiCameraDto) {
|
|
if (StringUtils.isEmpty(apiCameraDto.getDeptId())) {
|
log.error("获取摄像头信息失败,库区编码为空!");
|
return null;
|
}
|
|
//查询库区流媒体配置,获取库区节点
|
CameraMedia cameraMedia = cameraMediaService.getByDeptId(apiCameraDto.getDeptId(), apiCameraDto.getCompanyId());
|
if(null == cameraMedia || StringUtils.isEmpty(cameraMedia.getYdStoreId())){
|
log.error("获取摄像头信息失败,库区节点未配置!");
|
return null;
|
}
|
|
String str = getCameraList(cameraMedia);
|
if(null== str){
|
log.error("获取摄像头信息失败,库区节点未配置!");
|
return null;
|
}
|
|
YdQlyDto ydQlyDto = JSONObject.parseObject(str, YdQlyDto.class);
|
|
if(null== ydQlyDto || null == ydQlyDto.getDevice()){
|
log.error("获取摄像头信息失败,库区节点未配置!");
|
return null;
|
}
|
|
//持久化
|
List<Camera> listCamera = new ArrayList<>();
|
Camera camera;
|
for (YdQlyCamera dto : ydQlyDto.getDevice()) {
|
camera = new Camera();
|
camera.setId(dto.getDeviceId());
|
camera.setCompanyId(cameraMedia.getCompanyId());
|
camera.setDeptId(cameraMedia.getDeptId());
|
camera.setSn(dto.getDeviceId());
|
camera.setName(dto.getDeviceName());
|
camera.setType("01");
|
camera.setPlayType(CameraPlayType.PLAY_TYPE_YD_QLY.getCode());
|
cameraService.pullUpdateCamera(camera);
|
}
|
return listCamera;
|
}
|
|
|
/**
|
* 获取accessToken
|
*
|
* @param cameraMedia
|
* @return
|
*/
|
private String getAccessToken(CameraMedia cameraMedia) {
|
//默认先从缓存获取
|
String key = RedisConst.buildKey(ContextUtil.getCompanyId(), Constant.KEY_ACCESS_TOKEN_YD_QLY);
|
String accessToken = (String) redisCache.getCacheObject(key);
|
|
//若缓存获取为空,则通过接口请求获取
|
if (null == accessToken) {
|
String result = getAccessTokenApi(cameraMedia);
|
|
YdQlyDto dto = JSONObject.parseObject(result, YdQlyDto.class);
|
if (null == dto) {
|
return null;
|
}
|
accessToken = dto.getToken();
|
Integer expiresIn = dto.getExpires_in();
|
|
//将token存入缓存,默认7天
|
redisCache.setCacheObject(key, accessToken, 7*60*24, TimeUnit.MINUTES);
|
}
|
|
return accessToken;
|
}
|
|
/**
|
* 接口获取授权accessToken
|
* @param cameraMedia
|
* @return
|
*/
|
private String getAccessTokenApi(CameraMedia cameraMedia) {
|
try {
|
String timestamp = String.valueOf(System.currentTimeMillis());
|
String sig = Hex.encodeHexString(MessageDigest.getInstance("MD5").digest(StringUtils.getBytes(cameraMedia.getYdAppKey()+cameraMedia.getYdAppSecret(),"UTF-8")));
|
JSONObject requestBody = new JSONObject();
|
requestBody.put("operatorType", 1);
|
requestBody.put("sig", sig);
|
String requestBodyStr = requestBody.toString();
|
|
// 2. 计算请求体MD5
|
String md5 = DigestUtils.md5Hex(String.valueOf(requestBody));
|
|
// 3. 构建签名字符串
|
LinkedHashMap<String, String> herderParams = new LinkedHashMap<>();
|
herderParams.put("appid", cameraMedia.getYdAppKey());
|
herderParams.put("md5", md5);
|
herderParams.put("timestamp", timestamp);
|
herderParams.put("version", "1.0.0");
|
String jsonString = JSONObject.toJSONString(herderParams);
|
|
// 4. RSA签名
|
byte[] keyBytes = Base64.getDecoder().decode(cameraMedia.getYdRsa());
|
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
|
PrivateKey priKey = KeyFactory.getInstance("RSA").generatePrivate(keySpec);
|
|
Signature signature = Signature.getInstance("SHA1WithRSA");
|
signature.initSign(priKey);
|
signature.update(jsonString.getBytes("UTF-8"));
|
String signatureString = Base64.getEncoder().encodeToString(signature.sign());
|
|
herderParams.put("signature", signatureString);
|
herderParams.put("content-type", "application/json");
|
|
// 5. 发送请求
|
String response = HttpUtils.doPost(URL_ACCESS_TOKEN, herderParams, requestBodyStr);
|
|
YdQlyResp ydQlyResp = JSONObject.parseObject(response, YdQlyResp.class);
|
if(!"000000".equals(ydQlyResp.getResultCode())){
|
return null;
|
}
|
return ydQlyResp.getData();
|
} catch (Exception e) {
|
log.error("-----获取身份认证异常-----,原因={}", e.toString());
|
return null;
|
}
|
}
|
|
/**
|
* 接口获取播放地址
|
* @param cameraMedia
|
* @param cameraId
|
* @return
|
*/
|
private YdQlyResp getPlayUrl(CameraMedia cameraMedia, String cameraId) {
|
try {
|
|
String timestamp = String.valueOf(System.currentTimeMillis());
|
|
JSONObject requestBody = new JSONObject();
|
requestBody.put("deviceId", cameraId);
|
|
String requestBodyStr = requestBody.toString();
|
|
// 2. 计算请求体MD5
|
String md5 = DigestUtils.md5Hex(String.valueOf(requestBody));
|
|
// 3. 构建签名字符串
|
LinkedHashMap<String, String> herderParams = new LinkedHashMap<>();
|
|
herderParams.put("appid", cameraMedia.getYdAppKey());
|
herderParams.put("md5", md5);
|
herderParams.put("timestamp", timestamp);
|
herderParams.put("token", getAccessToken(cameraMedia));
|
herderParams.put("version", "1.0.0");
|
String jsonString = JSONObject.toJSONString(herderParams);
|
|
// 4. RSA签名
|
byte[] keyBytes = Base64.getDecoder().decode(PRIVATE_KEY);
|
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
|
PrivateKey priKey = KeyFactory.getInstance("RSA").generatePrivate(keySpec);
|
|
Signature signature = Signature.getInstance("SHA1WithRSA");
|
signature.initSign(priKey);
|
signature.update(jsonString.getBytes("UTF-8"));
|
String signatureString = Base64.getEncoder().encodeToString(signature.sign());
|
|
herderParams.put("signature", signatureString);
|
herderParams.put("content-type", "application/json");
|
|
// 5. 发送请求
|
String response = HttpUtils.doPost(URL_PLAY_LIVE, herderParams, requestBodyStr);
|
|
YdQlyResp ydQlyResp = JSONObject.parseObject(response, YdQlyResp.class);
|
|
return ydQlyResp;
|
} catch (Exception e) {
|
return null;
|
}
|
}
|
|
/**
|
* 接口获取播放地址
|
* @param cameraMedia
|
* @return
|
*/
|
private String getCameraList(CameraMedia cameraMedia) {
|
try {
|
|
String timestamp = String.valueOf(System.currentTimeMillis());
|
|
JSONObject requestBody = new JSONObject();
|
requestBody.put("queryType", 0);
|
requestBody.put("page", 1);
|
requestBody.put("pageSize", 100);
|
requestBody.put("nodeId", cameraMedia.getYdStoreId());
|
|
String requestBodyStr = requestBody.toString();
|
|
// 2. 计算请求体MD5
|
String md5 = DigestUtils.md5Hex(String.valueOf(requestBody));
|
|
// 3. 构建签名字符串
|
LinkedHashMap<String, String> herderParams = new LinkedHashMap<>();
|
|
herderParams.put("appid", cameraMedia.getYdAppKey());
|
herderParams.put("md5", md5);
|
herderParams.put("timestamp", timestamp);
|
herderParams.put("token", getAccessToken(cameraMedia));
|
herderParams.put("version", "1.0.0");
|
String jsonString = JSONObject.toJSONString(herderParams);
|
|
// 4. RSA签名
|
byte[] keyBytes = Base64.getDecoder().decode(PRIVATE_KEY);
|
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
|
PrivateKey priKey = KeyFactory.getInstance("RSA").generatePrivate(keySpec);
|
|
Signature signature = Signature.getInstance("SHA1WithRSA");
|
signature.initSign(priKey);
|
signature.update(jsonString.getBytes("UTF-8"));
|
String signatureString = Base64.getEncoder().encodeToString(signature.sign());
|
|
herderParams.put("signature", signatureString);
|
herderParams.put("content-type", "application/json");
|
|
// 5. 发送请求
|
String response = HttpUtils.doPost(URL_CAMERA_LIST, herderParams, requestBodyStr);
|
|
YdQlyResp ydQlyResp = JSONObject.parseObject(response, YdQlyResp.class);
|
if(!"000000".equals(ydQlyResp.getResultCode())){
|
return null;
|
}
|
return ydQlyResp.getData();
|
} catch (Exception e) {
|
return null;
|
}
|
}
|
|
|
private static final String TOKEN = "eyJhbGciOiJIUzI1NiJ9.eyJwcm9mZXNzaW9uIjoxLCJhcHBpZCI6ImUwYTFhNDIwZjU1YTRmOWRiYTBkNjM4MmRmNTlkYjY2Iiwib3BlcmF0b3JUeXBlIjoxLCJvcGVyYXRvciI6ImUwYTFhNDIwZjU1YTRmOWRiYTBkNjM4MmRmNTlkYjY2IiwianRpIjoiMjE4Nzk0MzMzMTE4NDM1NzM4NyIsImlhdCI6MTc2NzYxMDM3Mywic3ViIjoiZTBhMWE0MjBmNTVhNGY5ZGJhMGQ2MzgyZGY1OWRiNjYiLCJleHAiOjE3NjgyMTUxNzN9.Tot-yYsNLbY9YH2AYgV_Fggb7PCNrUR0PDi0Ear1s5w";
|
private static final String APP_ID = "e0a1a420f55a4f9dba0d6382df59db66";
|
private static final String SECRET = "OuLsvFL9nqxeeltu";
|
private static final String URL = "https://open.qly.cmviot.cn/v3/open/api/token";
|
private static final String URL_PLAY = "https://open.qly.cmviot.cn/v3/open/api/websdk/live";
|
private static final String URL_LIST = "https://open.qly.cmviot.cn/v3/open/api/node/tree";
|
private static final String PRIVATE_KEY = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAI7iA0WASV8pekjHVcsYV3ycZR2/+XK7O6BZpybAw/cauEzHRKsrDknErFxdNFca1OlVbPljBOfXjIrhS1CpAWez3Ff2+XaAaFE3fFer9LTxQ5GMXJSIAGQ4ntq/7y57ucwdVjL9+4B4WT8Yfea1DLa/fv+I0Gm7haVQj75JVYhBAgMBAAECgYAfvBs16JRjSncaiwuHHFTyHFppDSZ+UQ+hQchaVx4vWAPvKaMa0WlPARu3OAxT/GWlnY+ipFeGlt1kSz3LIH5rERYd5sNPOFmK7Nzih1VK6r/y1XobM4cLqLrP2UW2c3V36A77xz1xpaa9CP5l6gFjYAdZ1vnGS7HyjolWvzjUAQJBAMB6OTwrHcxOUJiLRJSK697LMIziBi1p5cR4NdSoQjQ4/enUqzAalwi6ZODuGSYai5VKhH9xkxFASWMT8waTOxECQQC+CbWK4Igx8Uh5qPpBIiFuA6ReAuFoRDMvKlzPUi8FGFkvF/CDx5IUFvYUd7FFX4l6Wtu5vf+VF3OydmzFr5oxAkB96Xa3nZ0IodKnd7ONWLOkM1e3UcSowLXGKL1OOCPW9dFkvfKerUZQN172pctd2c+mAfFbTXjfuCZJ4isBCh+BAkA8+ZiKaujIPYbnolRJuc3IItsGXx47+kYCCDGnQ9NaaymSdrfxUIOKdqOWhaEXhUPzQlvmCRSMne29gUn9VA7BAkBLvhtfSuANFSDt942GAY0Q25bJBM01yrRjtTEVCnGDxztexksPKaWGnJxk0Zk0xp4PkJCZvVuxFZ1Dw7F9yg6X";
|
|
public static void main(String[] args) {
|
// String accessToken = getAccessTokenTest();
|
// System.out.println("accessToken: " + accessToken);
|
|
// String playUrl = getPlayUrlTest();
|
// System.out.println("playUrl: " + playUrl);
|
|
String cameraList = getCameraListTest();
|
System.out.println("cameraList: " + cameraList);
|
}
|
|
private static String getCameraListTest() {
|
try {
|
|
String timestamp = String.valueOf(System.currentTimeMillis());
|
|
JSONObject requestBody = new JSONObject();
|
requestBody.put("queryType", 0);
|
requestBody.put("nodeId", "1346024619493187584");
|
|
String requestBodyStr = requestBody.toString();
|
|
// 2. 计算请求体MD5
|
String md5 = DigestUtils.md5Hex(String.valueOf(requestBody));
|
|
// 3. 构建签名字符串
|
Map signParams = new LinkedHashMap();
|
signParams.put("appid", APP_ID);
|
signParams.put("md5", md5);
|
signParams.put("timestamp", timestamp);
|
signParams.put("token", TOKEN);
|
signParams.put("version", "1.0.0");
|
String jsonString = JSONObject.toJSONString(signParams);
|
|
// 4. RSA签名
|
byte[] keyBytes = Base64.getDecoder().decode(PRIVATE_KEY);
|
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
|
PrivateKey priKey = KeyFactory.getInstance("RSA").generatePrivate(keySpec);
|
|
Signature signature = Signature.getInstance("SHA1WithRSA");
|
signature.initSign(priKey);
|
signature.update(jsonString.getBytes("UTF-8"));
|
String signatureString = Base64.getEncoder().encodeToString(signature.sign());
|
|
LinkedHashMap<String, String> herderParams = new LinkedHashMap<>();
|
|
herderParams.put("content-type", "application/json");
|
herderParams.put("appid", APP_ID);
|
herderParams.put("md5", md5);
|
herderParams.put("timestamp", timestamp);
|
herderParams.put("token", TOKEN);
|
herderParams.put("version", "1.0.0");
|
herderParams.put("signature", signatureString);
|
|
// 5. 发送请求
|
String response = HttpUtils.doPost(URL_LIST, herderParams, requestBodyStr);
|
|
return response;
|
} catch (Exception e) {
|
e.printStackTrace();
|
return null;
|
}
|
}
|
|
private static String getPlayUrlTest() {
|
try {
|
|
String timestamp = String.valueOf(System.currentTimeMillis());
|
|
JSONObject requestBody = new JSONObject();
|
requestBody.put("deviceId", "gb_26236371771319266195");
|
|
String requestBodyStr = requestBody.toString();
|
|
// 2. 计算请求体MD5
|
String md5 = DigestUtils.md5Hex(String.valueOf(requestBody));
|
|
// 3. 构建签名字符串
|
Map signParams = new LinkedHashMap();
|
signParams.put("appid", APP_ID);
|
signParams.put("md5", md5);
|
signParams.put("timestamp", timestamp);
|
signParams.put("token", TOKEN);
|
signParams.put("version", "1.0.0");
|
String jsonString = JSONObject.toJSONString(signParams);
|
|
// 4. RSA签名
|
byte[] keyBytes = Base64.getDecoder().decode(PRIVATE_KEY);
|
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
|
PrivateKey priKey = KeyFactory.getInstance("RSA").generatePrivate(keySpec);
|
|
Signature signature = Signature.getInstance("SHA1WithRSA");
|
signature.initSign(priKey);
|
signature.update(jsonString.getBytes("UTF-8"));
|
String signatureString = Base64.getEncoder().encodeToString(signature.sign());
|
|
LinkedHashMap<String, String> herderParams = new LinkedHashMap<>();
|
|
herderParams.put("content-type", "application/json");
|
herderParams.put("appid", APP_ID);
|
herderParams.put("md5", md5);
|
herderParams.put("timestamp", timestamp);
|
herderParams.put("token", TOKEN);
|
herderParams.put("version", "1.0.0");
|
herderParams.put("signature", signatureString);
|
|
// 5. 发送请求
|
String response = HttpUtils.doPost(URL_PLAY, herderParams, requestBodyStr);
|
|
return response;
|
} catch (Exception e) {
|
e.printStackTrace();
|
return null;
|
}
|
}
|
|
private static String getAccessTokenTest() {
|
try {
|
|
String timestamp = String.valueOf(System.currentTimeMillis());
|
|
String sig = Hex.encodeHexString(MessageDigest.getInstance("MD5").digest(StringUtils.getBytes(APP_ID+SECRET,"UTF-8")));
|
|
JSONObject requestBody = new JSONObject();
|
requestBody.put("operatorType", 1);
|
requestBody.put("sig", sig);
|
String requestBodyStr = requestBody.toString();
|
|
// 2. 计算请求体MD5
|
String md5 = DigestUtils.md5Hex(String.valueOf(requestBody));
|
|
// 3. 构建签名字符串
|
Map signParams = new LinkedHashMap();
|
signParams.put("appid", APP_ID);
|
signParams.put("md5", md5);
|
signParams.put("timestamp", timestamp);
|
signParams.put("version", "1.0.0");
|
String jsonString = JSONObject.toJSONString(signParams);
|
|
// 4. RSA签名
|
byte[] keyBytes = Base64.getDecoder().decode(PRIVATE_KEY);
|
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
|
PrivateKey priKey = KeyFactory.getInstance("RSA").generatePrivate(keySpec);
|
|
Signature signature = Signature.getInstance("SHA1WithRSA");
|
signature.initSign(priKey);
|
signature.update(jsonString.getBytes("UTF-8"));
|
String signatureString = Base64.getEncoder().encodeToString(signature.sign());
|
|
LinkedHashMap<String, String> herderParams = new LinkedHashMap<>();
|
|
herderParams.put("content-type", "application/json");
|
herderParams.put("appid", APP_ID);
|
herderParams.put("md5", md5);
|
herderParams.put("timestamp", timestamp);
|
herderParams.put("version", "1.0.0");
|
|
herderParams.put("signature", signatureString);
|
|
// 5. 发送请求
|
String response = HttpUtils.doPost(URL, herderParams, requestBodyStr);
|
|
return response;
|
} catch (Exception e) {
|
e.printStackTrace();
|
return null;
|
}
|
}
|
}
|