This commit is contained in:
tangzh 2025-06-16 17:01:07 +08:00
parent b2571b44d6
commit 08709311bc
11 changed files with 92 additions and 54 deletions

View File

@ -9,10 +9,7 @@ import me.zhengjie.annotation.Log;
import me.zhengjie.annotation.rest.AnonymousGetMapping;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@ -24,7 +21,7 @@ import java.io.UnsupportedEncodingException;
* @author gc.x
*/
@Slf4j
@RestController("api/front/flv")
@RequestMapping("api/front/flv")
@Api(tags = "微信:拉流播放")
public class FLVController {
@ -36,7 +33,6 @@ public class FLVController {
@Log("拉流播放")
@ApiOperation(value = "打开视频流")
// @GetMapping(value = "/get/stream")
@AnonymousGetMapping(value = "/get/stream")
public void open(String url, HttpServletResponse response, HttpServletRequest request) throws UnsupportedEncodingException {
if (!StringUtils.isEmpty(url)) {

View File

@ -1,30 +1,30 @@
//package com.gc.easy.flv.controller;
//
//import com.gc.easy.flv.config.FlvConfig;
//import me.zhengjie.annotation.rest.AnonymousGetMapping;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.stereotype.Controller;
//import org.springframework.ui.Model;
//
//import java.io.UnsupportedEncodingException;
//
///**
// * FLV流转换
// *
// * @author gc.x
// */
//@Controller
//public class FLVPlayController {
// @Autowired
// private FlvConfig flvConfig;
//
// @AnonymousGetMapping(value = "/flv/hls/stream")
// public String getAppHtml1(String url, Model model) throws UnsupportedEncodingException {
// String decodedUrl = java.net.URLDecoder.decode(url, "UTF-8");
// String videoPath="/api/front/flv/get/stream?url="+decodedUrl;
// model.addAttribute("videoPath", videoPath);
// model.addAttribute("wight", flvConfig.getWight());
// model.addAttribute("height", flvConfig.getHeight());
// return "video";
// }
//}
package com.gc.easy.flv.controller;
import com.gc.easy.flv.config.FlvConfig;
import me.zhengjie.annotation.rest.AnonymousGetMapping;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import java.io.UnsupportedEncodingException;
/**
* FLV流转换
*
* @author gc.x
*/
@Controller
public class FLVPlayController {
@Autowired
private FlvConfig flvConfig;
@AnonymousGetMapping(value = "/api/front/flv/hls/stream")
public String getAppHtml1(String url, Model model) throws UnsupportedEncodingException {
String decodedUrl = java.net.URLDecoder.decode(url, "UTF-8");
String videoPath="/api/front/flv/get/stream?url="+decodedUrl;
model.addAttribute("videoPath", videoPath);
model.addAttribute("wight", flvConfig.getWight());
model.addAttribute("height", flvConfig.getHeight());
return "video";
}
}

View File

@ -94,6 +94,8 @@ public class SpringSecurityConfig {
"/**/*.js",
"/webSocket/**"
).permitAll()
// 视频播放
.antMatchers("/api/front/flv/**").permitAll()
// swagger 文档
.antMatchers("/swagger-ui.html").permitAll()
.antMatchers("/swagger-resources/**").permitAll()

View File

@ -3,6 +3,7 @@ package me.zhengjie.modules.security.config.enums;
public enum CapabilitieEnum {
REFRESH, // 刷新
PAUSE, // 暂停
CONTINUE, // 继续
EXIT, // 退出

View File

@ -6,9 +6,7 @@ import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.websocket.Session;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
@Component
@ -27,6 +25,8 @@ public class WebSocketService {
// 存储设备号
public static List<String> deviceList = new ArrayList<>();
// 观看视频的用户
public static Set<String> videoUser = new LinkedHashSet<>();
// 存储连接的客户端
public String channel;

View File

@ -1,4 +1,4 @@
package me.zhengjie.modules.system.service.impl;//package me.zhengjie.modules.system.service.webstocket;
package me.zhengjie.modules.system.service.impl;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
@ -70,8 +70,11 @@ public class WebSocketSdcpServiceImpl extends WebSocketService {
public void onMessage(Session session, String message) {
WebSocketService collect = getSocket(WebSocketConfig.TOPIC_PREFIX);
if (null == collect) { return; }
long time = System.currentTimeMillis();
log.info("【SDCP服务端】收到消息channel={}message={}", collect.channel, message);
log.info("" + time + "+++++++++++++++++++++++++++++】");
serviceMessageHandle(session, message);
log.info("" + time + "+++++++++++++++++++++++++++++】");
}
// 连接关闭状态刷新
@ -91,7 +94,7 @@ public class WebSocketSdcpServiceImpl extends WebSocketService {
reqDTO.setTopic(WebSocketConfig.TOPIC_PREFIX + "/" + MethodEnum.request.name() + "/" + deviceSn);
WebSocketReqData data = new WebSocketReqData();
data.setCmd(0);
data.setData(new Object());
data.setData(new HashMap());
data.setRequestID(currentTimeLong + "");
data.setMainboardID(deviceSn);
data.setTimeStamp(currentTimeLong);
@ -122,7 +125,6 @@ public class WebSocketSdcpServiceImpl extends WebSocketService {
log.info("<<< 请求类型有误,忽略");
return;
}
log.info(">>> 方式 {}", method);
String deviceSn = param.getMainboardID();
// 只关心已有的设备
if (!deviceList.contains(deviceSn)) {

View File

@ -5,11 +5,14 @@ import lombok.extern.slf4j.Slf4j;
import me.zhengjie.modules.security.config.WebSocketConfig;
import me.zhengjie.modules.security.config.enums.CapabilitieEnum;
import me.zhengjie.modules.security.config.enums.MethodEnum;
import me.zhengjie.modules.security.service.dto.JwtUserDto;
import me.zhengjie.modules.system.domain.BusDevice;
import me.zhengjie.modules.system.domain.User;
import me.zhengjie.modules.system.domain.dto.BusDeviceQueryCriteria;
import me.zhengjie.modules.system.service.WebSocketService;
import me.zhengjie.modules.system.service.webstocket.req.WebSocketReqDTO;
import me.zhengjie.modules.system.service.webstocket.req.WebSocketReqData;
import me.zhengjie.utils.SecurityUtils;
import me.zhengjie.utils.StringUtils;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@ -86,8 +89,11 @@ public class WebSocketVueServiceImpl extends WebSocketService {
public void onMessage(Session session, String message) {
WebSocketService collect = getSocket(session.getId());
if (null == collect) { return; }
long time = System.currentTimeMillis();
log.info("【VUE服务端】收到消息channel={}message={}", collect.channel, message);
log.info("" + time + "-----------------------------】");
serviceMessageHandle(message);
log.info("" + time + "-----------------------------】");
}
private void serviceMessageHandle(String message) {
@ -104,7 +110,6 @@ public class WebSocketVueServiceImpl extends WebSocketService {
log.info("<<< 请求类型有误,忽略");
return;
}
log.info(">>> 方式 {}", method);
String deviceSn = param.getMainboardID();
// 只关心已有的设备
if (!deviceList.contains(deviceSn)) {
@ -112,14 +117,28 @@ public class WebSocketVueServiceImpl extends WebSocketService {
return;
}
String command = param.getCommand();
if (null == command) {
log.info("<<< 命令类型未找到,忽略");
if (StringUtils.isEmpty(command)) {
log.info("<<< 命令为空,忽略");
return;
}
String commandStr = null;
long sysTimeLong = System.currentTimeMillis();
// 刷新
if (command.equals(CapabilitieEnum.REFRESH.name())) {
WebSocketReqData data = new WebSocketReqData();
data.setCmd(0);
data.setData(new HashMap());
data.setType(0);
data.setRequestID(sysTimeLong + "");
data.setMainboardID(deviceSn);
data.setTimeStamp(sysTimeLong);
WebSocketReqDTO req = new WebSocketReqDTO();
req.setTopic(WebSocketConfig.TOPIC_PREFIX + "/" + MethodEnum.request + "/" + deviceSn);
req.setData(data);
commandStr = JSON.toJSONString(req);
}
// 暂停
if (command.equals(CapabilitieEnum.PAUSE.name())) {
else if (command.equals(CapabilitieEnum.PAUSE.name())) {
}
// 继续
@ -132,7 +151,7 @@ public class WebSocketVueServiceImpl extends WebSocketService {
}
// 图片
else if (command.equals(CapabilitieEnum.IMAGE.name())) {
Map<String, Object> dataParam = new HashMap<>();
Map<String, Integer> dataParam = new HashMap<>();
dataParam.put("Type", 0);
WebSocketReqData data = new WebSocketReqData();
data.setCmd(385);
@ -145,10 +164,12 @@ public class WebSocketVueServiceImpl extends WebSocketService {
req.setData(data);
commandStr = JSON.toJSONString(req);
}
// 打开视频
// 视频
else if (command.equals(CapabilitieEnum.OPEN_VIDEO.name()) || command.equals(CapabilitieEnum.CLOSE_VIDEO.name())) {
int uIndex = (videoUser.contains(session.getId())) ? new ArrayList<>(videoUser).indexOf(session.getId()) : videoUser.size();
Map<String, Object> dataParam = new HashMap<>();
dataParam.put("Enable", command.equals(CapabilitieEnum.OPEN_VIDEO.name()) ? 1 : 0);
dataParam.put("UserId", uIndex);
WebSocketReqData data = new WebSocketReqData();
data.setCmd(386);
data.setData(dataParam);
@ -159,6 +180,12 @@ public class WebSocketVueServiceImpl extends WebSocketService {
req.setTopic(WebSocketConfig.TOPIC_PREFIX + "/" + MethodEnum.request + "/" + deviceSn);
req.setData(data);
commandStr = JSON.toJSONString(req);
// 记录用户打开视频
if (command.equals(CapabilitieEnum.OPEN_VIDEO.name()))
videoUser.add(session.getId());
// 移除用户记录
else
videoUser.remove(session.getId());
}
else {
log.info("<<< 命令类型未找到,忽略");

View File

@ -1,5 +1,6 @@
package me.zhengjie.modules.system.service.webstocket;
import com.alibaba.fastjson.annotation.JSONField;
import jodd.util.StringUtil;
import lombok.Data;
import me.zhengjie.modules.security.config.enums.MethodEnum;
@ -16,9 +17,11 @@ import me.zhengjie.modules.security.config.enums.MethodEnum;
public class WebSocketParam {
// 消息topic
@JSONField(name = "Topic")
private String Topic;
// 设备ID
@JSONField(name = "MainboardID")
private String MainboardID;
// 消息类型

View File

@ -1,5 +1,6 @@
package me.zhengjie.modules.system.service.webstocket.req;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
import me.zhengjie.modules.system.service.webstocket.WebSocketParam;
@ -9,6 +10,7 @@ import java.io.Serializable;
public class WebSocketReqDTO extends WebSocketParam implements Serializable {
// 消息参数
@JSONField(name = "Data")
private WebSocketReqData Data;
// 机器品牌标识32位UUID

View File

@ -1,27 +1,38 @@
package me.zhengjie.modules.system.service.webstocket.req;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
import java.io.Serializable;
import java.util.Map;
@Data
public class WebSocketReqData implements Serializable {
// 请求命令
@JSONField(name = "Cmd")
private Integer Cmd;
private Object Data;
@JSONField(name = "Data")
private Map Data;
@JSONField(name = "Type")
private Integer Type;
// 请求ID
@JSONField(name = "RequestID")
private String RequestID;
// 主板ID
@JSONField(name = "MainboardID")
private String MainboardID;
// 时间戳
@JSONField(name = "TimeStamp")
private Long TimeStamp;
// 标识命令来源
@JSONField(name = "From")
private Integer From;
}

View File

@ -107,12 +107,6 @@ weChat:
appId: wx583d0c321ef43dfe
secret: 1b5eca11a1058361b0f14c5933ef6bd6
# socket
thirdParty:
socket:
init: false
url: ws://127.0.0.1:8000/webSocket
# 文件存储路径
file:
mac: