| | |
| | | |
| | | import com.alibaba.fastjson2.JSON; |
| | | |
| | | import com.ard.vtdu.config.MediamtxSixHeConfig; |
| | | import com.ard.vtdu.domain.ArdVtdu; |
| | | import com.ard.work.component.websocket.utils.WebSocketUtil; |
| | | import com.ard.work.domain.message.BaseMessage; |
| | |
| | | |
| | | @Resource |
| | | private ITyService tyService; |
| | | @Resource |
| | | private MediamtxSixHeConfig mediamtxSixHeConfig; |
| | | |
| | | // 盒子拉流地址缓存 key:boxSn value: webrtcUrl |
| | | public static final ConcurrentMap<String, String> BOX_STREAM_PULL_MAP = new ConcurrentHashMap<>(); |
| | |
| | | public void subscribe(String boxSn, Long userId) { |
| | | |
| | | STREAM_USER_MAP.computeIfAbsent(boxSn, k -> ConcurrentHashMap.newKeySet()).add(userId); |
| | | String webrtcUrl = getWebrtcUrl(boxSn); |
| | | BoxStreamUrlReceiver streamReceiver = getWebrtcUrl(boxSn); |
| | | String webrtcUrl = streamReceiver.getRtc(); |
| | | if (Objects.equals(webrtcUrl, "")) { |
| | | log.warn("{}{}{}", STREAM_LOG_PREFIX, STREAM_NOT_FOUND_MSG, boxSn); |
| | | BaseMessage<String> baseMessage = new BaseMessage<>("stream", STREAM_NOT_FOUND_MSG + boxSn); |
| | | sendMessageToUser(userId, JSON.toJSONString(baseMessage)); |
| | | } |
| | | BOX_STREAM_PULL_MAP.put(boxSn, webrtcUrl); |
| | | BaseMessage<String> baseMessage = new BaseMessage<>("stream", webrtcUrl); |
| | | BaseMessage<BoxStreamUrlReceiver> baseMessage = new BaseMessage<>("stream", streamReceiver); |
| | | sendMessageToUser(userId, JSON.toJSONString(baseMessage)); |
| | | } |
| | | |
| | |
| | | * @param boxSn 盒子编号 |
| | | * @return String webrtcUrl |
| | | */ |
| | | private String getWebrtcUrl(String boxSn) { |
| | | try { |
| | | BoxStreamUrlReceiver boxLiveUrl = tyService.getBoxLiveUrl(boxSn); |
| | | if (boxLiveUrl != null) { |
| | | return boxLiveUrl.getRtc(); |
| | | } |
| | | } catch (Exception e) { |
| | | log.error("获取媒体地址异常:{}", e.getMessage()); |
| | | private BoxStreamUrlReceiver getWebrtcUrl(String boxSn) { |
| | | BoxStreamUrlReceiver boxLiveUrl = tyService.getBoxLiveUrl(boxSn); |
| | | if (boxLiveUrl == null) { |
| | | throw new RuntimeException("未获取到盒子直播地址:" + boxSn); |
| | | } |
| | | return ""; |
| | | // 2. 获取原始 URL 字符串 |
| | | String originalUrl = boxLiveUrl.getRtc(); |
| | | if (mediamtxSixHeConfig.getEnable() && originalUrl != null && !originalUrl.isEmpty()) { |
| | | // --- 开始替换逻辑 --- |
| | | // 配置你的外网地址 |
| | | String targetHost = mediamtxSixHeConfig.getPlayHost() + ":" + mediamtxSixHeConfig.getWebrtcPort(); |
| | | // 正则解释: |
| | | // (^https?://) -> 捕获组1:匹配 http:// 或 https:// |
| | | // ([^/:]+) -> 捕获组2:匹配 IP 地址或域名 (非 / 和 : 的字符) |
| | | // (:\d+)? -> 捕获组3:匹配 :端口号 (可选) |
| | | // (/.*) -> 捕获组4:匹配后面的路径参数 |
| | | String regex = "(^https?://)([^/:]+)(:\\d+)?(/.*)"; |
| | | // 替换为:协议 + 外网IP:端口 + 路径 |
| | | // $1 代表协议, $4 代表路径 |
| | | String newUrl = originalUrl.replaceAll(regex, "$1" + targetHost + "$4"); |
| | | // 将新 URL 设置回去 |
| | | boxLiveUrl.setRtc(newUrl); |
| | | } |
| | | boxLiveUrl.setBoxSn(boxSn); |
| | | return boxLiveUrl; |
| | | } |
| | | } |