liusuyi
2025-03-03 6531e781105e073a55a23529e2b7b31e85110951
优化流媒体同步
5 files modified
97 ■■■■■ changed files
ard-admin/src/main/resources/application-dev.yml 2 ●●●●● patch | view | raw | blame | history
ard-work/src/main/java/com/ard/tianyu/controller/UavManualFlyController.java 2 ●●●●● patch | view | raw | blame | history
ard-work/src/main/java/com/ard/tianyu/model/dto/wayline/PlanLineData.java 26 ●●●●● patch | view | raw | blame | history
ard-work/src/main/java/com/ard/tianyu/service/impl/UavStreamManager.java 66 ●●●●● patch | view | raw | blame | history
ard-work/src/main/java/com/ard/vtdu/client/MediaClient.java 1 ●●●●● patch | view | raw | blame | history
ard-admin/src/main/resources/application-dev.yml
@@ -42,7 +42,7 @@
 accesskeysecret: 9c9f139f63b343b0a9ef42e05ed29b0b
 # 天宇tcp服务器地址
 tcpserver: 59.110.237.99
 tcpport: 8124
 tcpport: 8125
#流媒体配置
mediamtx:
  # 流媒体服务器地址
ard-work/src/main/java/com/ard/tianyu/controller/UavManualFlyController.java
@@ -72,7 +72,7 @@
        return AjaxResult.success();
    }
    @ApiOperation("强制降落")
    @ApiOperation(value = "强制降落",notes = "强制无人机在当前位置降落,不理会蔽障信息,调用此指令时需人工确定降落地点安全")
    @ApiOperationSupport(order = 7)
    @PostMapping("/landForced")
    public AjaxResult landForced(@RequestBody LandForcedDTO landForcedDTO) {
ard-work/src/main/java/com/ard/tianyu/model/dto/wayline/PlanLineData.java
@@ -18,17 +18,17 @@
@AllArgsConstructor
@NoArgsConstructor
public class PlanLineData {
    private int finishedAction; // 结束航线后动作
    private float maxSpeed; // 最大飞行速度(单位:米/秒)
    private float autoSpeed; // 自动飞行速度(单位:米/秒)
    private List<PointData> points; // 坐标点数组
    private int loseAction; // 网络失联后动作
    private int homeHeight; // 返航高度
    private int isSaveEnergyMode; // 是否开启节能模式
    private HangarPoint takePoint; // 起飞点机库信息
    private HangarPoint landPoint; // 降落点机库信息
    private List<PointData> interests; // 兴趣点数组
    private NormalModel normalModel; // 普通建模
    private SurroundModel surroundModel; // 环绕建模
    private PointData takeOffPoint; // 起飞点
    private int finishedAction;     // 结束航线后动作(必填)
    private float maxSpeed;         // 最大飞行速度(单位:米/秒)
    private float autoSpeed;        // 自动飞行速度(单位:米/秒)
    private List<PointData> points; // 坐标点数组(必填)
    private int loseAction;         // 网络失联后动作(必填)
    private int homeHeight;         // 返航高度(必填)
    private int isSaveEnergyMode;   // 是否开启节能模式
    private HangarPoint takePoint;  // 起飞点机库信息
    private HangarPoint landPoint;  // 降落点机库信息
    private List<PointData> interests;      // 兴趣点数组
    private NormalModel normalModel;        // 普通建模
    private SurroundModel surroundModel;    // 环绕建模
    private PointData takeOffPoint;         // 起飞点
}
ard-work/src/main/java/com/ard/tianyu/service/impl/UavStreamManager.java
@@ -4,11 +4,14 @@
import com.ard.tianyu.service.ITyService;
import com.ard.tianyu.websocket.utils.WebSocketUtil;
import com.ard.vtdu.domain.ArdVtdu;
import com.ard.vtdu.domain.Conf;
import com.ard.vtdu.service.IMediaService;
import com.dtflys.forest.exceptions.ForestNetworkException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@@ -39,39 +42,21 @@
     * @param userId 用户ID
     */
    public void startPullStream(String boxSn, String userId) {
        String webrtcUrl = "";
        STREAM_USER_MAP.computeIfAbsent(boxSn, k -> ConcurrentHashMap.newKeySet()).add(userId);
        String webrtcUrl = BOX_STREAM_PULL_MAP.get(boxSn);
        if (webrtcUrl != null) {
            log.info("{}Already pulled stream: {}", STREAM_LOG_PREFIX, webrtcUrl);
            sendMessageToUser(userId, webrtcUrl);
            return;
        }
        try {
            BoxStreamUrlReceiver boxLiveUrl = tyService.getBoxLiveUrl(boxSn);
            if (boxLiveUrl == null) {
        //不管谁拉流都判断流媒体中是否存在
        boolean exist = mediaService.checkNameExist(boxSn);
        if (!exist) {
            webrtcUrl = addVtdu(boxSn);
            if (Objects.equals(webrtcUrl, "")) {
                log.warn("{}{}{}", STREAM_LOG_PREFIX, STREAM_NOT_FOUND_MSG, boxSn);
                sendMessageToUser(userId, STREAM_NOT_FOUND_MSG + boxSn);
                return;
            }
            ArdVtdu vtdu = ArdVtdu.builder()
                    .name(boxSn)
                    .mode(0)
                    .isCode(0)
                    .rtspSource(boxLiveUrl.getRtsp())
                    .build();
            ArdVtdu ardVtdu = mediaService.addPath(vtdu);
            webrtcUrl = ardVtdu.getWebrtcUrl();
            BOX_STREAM_PULL_MAP.put(boxSn, webrtcUrl);
            log.info("{}First pulled stream: {}", STREAM_LOG_PREFIX, webrtcUrl);
            sendMessageToUser(userId, webrtcUrl);
        } catch (Exception e) {
            log.error("{}Failed to start pull stream for box: {}", STREAM_LOG_PREFIX, boxSn, e);
            sendMessageToUser(userId, "Failed to start pull stream due to an internal error.");
        } else {
            webrtcUrl = BOX_STREAM_PULL_MAP.get(boxSn);
        }
        sendMessageToUser(userId, webrtcUrl);
    }
    /**
@@ -102,6 +87,7 @@
            }
        }
    }
    /**
     * 停止拉流
     *
@@ -126,4 +112,30 @@
            log.error("{}Failed to send message to user: {}", STREAM_LOG_PREFIX, userId, e);
        }
    }
    /**
     * 通过盒子编号获取rtsp加入流媒体中获取webrtc地址
     *
     * @param boxSn 盒子编号
     * @return String webrtcUrl
     */
    private String addVtdu(String boxSn) {
        try {
            BoxStreamUrlReceiver boxLiveUrl = tyService.getBoxLiveUrl(boxSn);
            if (boxLiveUrl != null) {
                ArdVtdu vtdu = ArdVtdu.builder()
                        .name(boxSn)
                        .mode(0)
                        .isCode(0)
                        .rtspSource(boxLiveUrl.getRtsp())
                        .build();
                ArdVtdu ardVtdu = mediaService.addPath(vtdu);
                return ardVtdu.getWebrtcUrl();
            }
        } catch (Exception e) {
            log.error("获取媒体地址异常:{}", e.getMessage());
        }
        return "";
    }
}
ard-work/src/main/java/com/ard/vtdu/client/MediaClient.java
@@ -2,6 +2,7 @@
import com.ard.vtdu.domain.*;
import com.dtflys.forest.annotation.*;
import org.springframework.scheduling.annotation.Async;
/**
 * @Description: mediamtx流媒体客户端