Browse Source

1.流媒体接口协议 http https按照请求协议自动切换
2.直播画面质量设置

S0025136190 1 year ago
parent
commit
62168cd8a3

+ 34 - 27
Backend/sample/src/main/java/com/dji/sample/common/smsp/CallSmsp.java

@@ -1,7 +1,5 @@
 package com.dji.sample.common.smsp;
 
-import cn.hutool.crypto.digest.MD5;
-import cn.hutool.json.JSONArray;
 import cn.hutool.json.JSONObject;
 import com.dji.sample.configuration.CustomConfiguration;
 import com.dji.sample.manage.model.dto.ManageDeviceLivestreamUrlDTO;
@@ -14,7 +12,6 @@ import org.apache.http.impl.client.CloseableHttpClient;
 import org.apache.http.impl.client.HttpClients;
 import org.apache.http.util.EntityUtils;
 
-import java.time.Instant;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -23,18 +20,30 @@ import java.util.Map;
 
 @Slf4j
 public class CallSmsp {
-    public static Map<String,String> getSmspToken(String username,String password) {
-//        String pass = MD5.create().digestHex(password);
-//        Instant now = Instant.now();
-//        long currentTimeMillis = now.toEpochMilli();
-        String url = CustomConfiguration.smspTokenUrl+"?username="+username+"&password="+password;
+
+    private static final String NODE_DATA = "data";
+    private static final String NODE_EASYDARWIN = "EasyDarwin";
+    private static final String NODE_BODY = "Body";
+    private static final String NODE_TOKEN = "Token";
+    private static final String NODE_DEVICE_NAME = "DeviceName";
+    private static final String NODE_CHILDREN = "Children";
+    private static final String NODE_RTMPPUSH = "RTMPPUSH";
+    private static final String NODE_WEBRTC = "WEBRTC";
+    private static final String NODE_CHANNELID = "ChannelID";
+    private static final String HTTPS = "https";
+
+
+
+    public static Map<String,String> getSmspToken(String username,String password,String protocal) {
+        String tokenUrl = HTTPS.equals(protocal) ? CustomConfiguration.smspTokenUrl2 : CustomConfiguration.smspTokenUrl;
+        String url = tokenUrl+"?username="+username+"&password="+password;
         try {
             Map<String,String> response = sendGetRequest(url);
-            log.debug("Response from API: " + response);
-            if(response.get("data") != null) {
-                JSONObject json = new JSONObject(response.get("data"));
-                JSONObject body = json.getJSONObject("EasyDarwin").getJSONObject("Body");
-                response.put("Token",body.getStr("Token"));
+            log.info("Response from  getSmspToken API: " + response);
+            if(response.get(NODE_DATA) != null) {
+                JSONObject json = new JSONObject(response.get(NODE_DATA));
+                JSONObject body = json.getJSONObject(NODE_EASYDARWIN).getJSONObject(NODE_BODY);
+                response.put(NODE_TOKEN,body.getStr(NODE_TOKEN));
             }
 
             return response;
@@ -44,32 +53,33 @@ public class CallSmsp {
         }
     }
 
-    public static List<ManageDeviceLivestreamUrlDTO> getRtmp(String token, String deviceSn, String payload) {
+    public static List<ManageDeviceLivestreamUrlDTO> getRtmp(String token, String deviceSn, String protocal) {
         List<ManageDeviceLivestreamUrlDTO> resultList = new ArrayList<>();
         if(token == null) {
             return resultList;
         }
-        String url = CustomConfiguration.smspRtmpUrl+"?token="+token;
+        String rUrl = HTTPS.equals(protocal) ? CustomConfiguration.smspRtmpUrl2 : CustomConfiguration.smspRtmpUrl;
+        String url = rUrl+"?token="+token;
         ObjectMapper objectMapper = new ObjectMapper();
         try {
             Map<String,String> response = sendGetRequest(url);
-            log.debug("Response from API: " + response);
-            if(response.get("data") != null ){
-                JsonNode rootNode = objectMapper.readTree(response.get("data"));
+            log.info("============Response from getSmspRtmpUrl API: " + response);
+            if(response.get(NODE_DATA) != null ){
+                JsonNode rootNode = objectMapper.readTree(response.get(NODE_DATA));
                 // 遍历顶层的设备列表
-                for (JsonNode deviceNode : rootNode.get("data")) {
-                    String deviceName = deviceNode.get("DeviceName").asText();
+                for (JsonNode deviceNode : rootNode.get(NODE_DATA)) {
+                    String deviceName = deviceNode.get(NODE_DEVICE_NAME).asText();
                     // 查找特定设备名
                     if (deviceSn.equals(deviceName)) {
                         // 获取该设备的子节点
-                        JsonNode childrenNode = deviceNode.get("Children");
+                        JsonNode childrenNode = deviceNode.get(NODE_CHILDREN);
                         // 遍历子节点
                         for (JsonNode childNode : childrenNode) {
                             ManageDeviceLivestreamUrlDTO livestreamUrlDTO = new ManageDeviceLivestreamUrlDTO();
                             // 获取RTMP和WEBRTC数据
-                            String rtmpUrl = childNode.get("RTMP").asText();
-                            String webRtcUrl = childNode.get("WEBRTC").asText();
-                            Integer channelID = childNode.get("ChannelID").asInt();
+                            String rtmpUrl = childNode.get(NODE_RTMPPUSH).asText();
+                            String webRtcUrl = childNode.get(NODE_WEBRTC).asText();
+                            Integer channelID = childNode.get(NODE_CHANNELID).asInt();
                             livestreamUrlDTO.setChannelId(channelID);
                             livestreamUrlDTO.setRtmpUrl(rtmpUrl);
                             livestreamUrlDTO.setWebRtcUrl(webRtcUrl);
@@ -79,9 +89,6 @@ public class CallSmsp {
                     }
                 }
             }
-//            if(response.get("message") != null) {
-//                resultList
-//            }
             return resultList;
         } catch (Exception e) {
             e.printStackTrace();

+ 20 - 0
Backend/sample/src/main/java/com/dji/sample/configuration/CustomConfiguration.java

@@ -43,6 +43,18 @@ public class CustomConfiguration {
      */
     public static String smspRtmpUrl;
 
+    /**
+     * 获取token地址
+     * @param smspTokenUrl
+     */
+    public static String smspTokenUrl2;
+
+    /**
+     * 获取URL地址
+     * @param smspRtmpUrl
+     */
+    public static String smspRtmpUrl2;
+
 
     /**
      * 获取clientId
@@ -70,6 +82,14 @@ public class CustomConfiguration {
         CustomConfiguration.smspRtmpUrl = smspRtmpUrl;
     }
 
+    public void setSmspTokenUrl2(String smspTokenUrl) {
+        CustomConfiguration.smspTokenUrl2 = smspTokenUrl;
+    }
+
+    public void setSmspRtmpUrl2(String smspRtmpUrl) {
+        CustomConfiguration.smspRtmpUrl2 = smspRtmpUrl;
+    }
+
     public void setClientId(String clientId) {
         CustomConfiguration.clientId = clientId;
     }

+ 11 - 2
Backend/sample/src/main/java/com/dji/sample/manage/controller/LiveStreamController.java

@@ -11,6 +11,8 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.http.HttpServletRequest;
+import java.net.MalformedURLException;
+import java.net.URL;
 import java.util.List;
 
 import static com.dji.sample.component.AuthInterceptor.TOKEN_CLAIM;
@@ -53,8 +55,15 @@ public class LiveStreamController {
      * @return
      */
     @PostMapping("/streams/start")
-    public HttpResultResponse liveStart(@RequestBody LiveTypeDTO liveParam) {
-        return liveStreamService.liveStart(liveParam);
+    public HttpResultResponse liveStart(HttpServletRequest request,@RequestBody LiveTypeDTO liveParam)  {
+        URL requestURL = null;
+        try {
+            requestURL = new URL(request.getRequestURL().toString());
+        } catch (MalformedURLException e) {
+            e.printStackTrace();
+        }
+        String protocol = requestURL.getProtocol();
+        return liveStreamService.liveStart(protocol,liveParam);
     }
 
     /**

+ 1 - 1
Backend/sample/src/main/java/com/dji/sample/manage/service/ILiveStreamService.java

@@ -26,7 +26,7 @@ public interface ILiveStreamService {
      * @param liveParam Parameters needed for on-demand.
      * @return
      */
-    HttpResultResponse liveStart(LiveTypeDTO liveParam);
+    HttpResultResponse liveStart(String protocol,LiveTypeDTO liveParam);
 
     /**
      * Stop the live streaming by publishing mqtt message.

+ 1 - 1
Backend/sample/src/main/java/com/dji/sample/manage/service/IManageDeviceLivestreamUrlService.java

@@ -13,5 +13,5 @@ public interface IManageDeviceLivestreamUrlService {
      * 通过接口获取RTMP
      * @return
      */
-    ManageDeviceLivestreamUrlDTO getUrl(ManageDeviceLivestreamUrlDTO deviceLivestreamUrlDTO);
+    ManageDeviceLivestreamUrlDTO getUrl(ManageDeviceLivestreamUrlDTO deviceLivestreamUrlDTO,String protocol);
 }

+ 32 - 22
Backend/sample/src/main/java/com/dji/sample/manage/service/impl/LiveStreamServiceImpl.java

@@ -74,7 +74,7 @@ public class LiveStreamServiceImpl implements ILiveStreamService {
     }
 
     @Override
-    public HttpResultResponse liveStart(LiveTypeDTO liveParam) {
+    public HttpResultResponse liveStart(String protocol, LiveTypeDTO liveParam) {
         // Check if this lens is available live.
         HttpResultResponse<DeviceDTO> responseResult = this.checkBeforeLive(liveParam.getVideoId());
         if (HttpResultResponse.CODE_SUCCESS != responseResult.getCode()) {
@@ -89,14 +89,17 @@ public class LiveStreamServiceImpl implements ILiveStreamService {
         livestreamUrlDTO.setPayload(getDeviceNameByModelKey(liveParam.getVideoId().getPayloadIndex()));
         livestreamUrlDTO.setPayloadIndex(liveParam.getVideoId().getPayloadIndex().toString());
         livestreamUrlDTO.setDeviceSn(liveParam.getVideoId().getDroneSn());
-        livestreamUrlDTO = deviceLivestreamUrlService.getUrl(livestreamUrlDTO);
+        livestreamUrlDTO = deviceLivestreamUrlService.getUrl(livestreamUrlDTO,protocol);
 
-        ILivestreamUrl url = LiveStreamProperty.get(liveParam.getUrlType());
+//        ILivestreamUrl url = LiveStreamProperty.get(liveParam.getUrlType());
 
         LivestreamRtmpUrl rtmpUrl = new LivestreamRtmpUrl();
         rtmpUrl.setUrl(livestreamUrlDTO.getRtmpUrl());
         //url = setExt(liveParam.getUrlType(), url, liveParam.getVideoId());
 
+
+
+
         TopicServicesResponse<ServicesReplyData<String>> response = abstractLivestreamService.liveStartPush(
                 SDKManager.getDeviceSDK(responseResult.getData().getDeviceSn()),
                 new LiveStartPushRequest()
@@ -107,7 +110,14 @@ public class LiveStreamServiceImpl implements ILiveStreamService {
 
         if (!response.getData().getResult().isSuccess()) {
             throw new RuntimeException(response.getData().getResult().getMessage());
-            //return HttpResultResponse.error(response.getData().getResult());
+        }
+
+        TopicServicesResponse<ServicesReplyData> qResponse = abstractLivestreamService.liveSetQuality(
+                SDKManager.getDeviceSDK(responseResult.getData().getDeviceSn()), new LiveSetQualityRequest()
+                        .setVideoQuality(liveParam.getVideoQuality())
+                        .setVideoId(liveParam.getVideoId()));
+        if (!qResponse.getData().getResult().isSuccess()) {
+            throw new RuntimeException(qResponse.getData().getResult().getMessage());
         }
 
         LiveDTO live = new LiveDTO();
@@ -117,28 +127,28 @@ public class LiveStreamServiceImpl implements ILiveStreamService {
                 break;
             case RTMP:
 //                live.setUrl("http://smsp.jkec.info:4443/flv/live/stream_27.flv");
-                //live.setUrl("webrtc://smsp.jkec.info:18000/rtc/stream_27");
+//                live.setUrl("webrtc://smsp.jkec.info:18000/rtc/stream_27");
                 live.setUrl(livestreamUrlDTO.getWebRtcUrl());
                 //live.setUrl("webrtcs://smsp.jkec.info:4443/rtc/stream_27");
 //                live.setUrl(url.toString().replace("rtmp", "webrtc"));
                 break;
-            case GB28181:
-                LivestreamGb28181Url gb28181 = (LivestreamGb28181Url) url;
-                live.setUrl(new StringBuilder()
-                        .append("webrtc://")
-                        .append(gb28181.getServerIP())
-                        .append("/live/")
-                        .append(gb28181.getAgentID())
-                        .append("@")
-                        .append(gb28181.getChannel())
-                        .toString());
-                break;
-            case RTSP:
-                live.setUrl(response.getData().getOutput());
-                break;
-            case WHIP:
-                live.setUrl(url.toString().replace("whip", "whep"));
-                break;
+//            case GB28181:
+//                LivestreamGb28181Url gb28181 = (LivestreamGb28181Url) url;
+//                live.setUrl(new StringBuilder()
+//                        .append("webrtc://")
+//                        .append(gb28181.getServerIP())
+//                        .append("/live/")
+//                        .append(gb28181.getAgentID())
+//                        .append("@")
+//                        .append(gb28181.getChannel())
+//                        .toString());
+//                break;
+//            case RTSP:
+//                live.setUrl(response.getData().getOutput());
+//                break;
+//            case WHIP:
+//                live.setUrl(url.toString().replace("whip", "whep"));
+//                break;
             default:
                 return HttpResultResponse.error(LiveErrorCodeEnum.URL_TYPE_NOT_SUPPORTED);
         }

+ 34 - 27
Backend/sample/src/main/java/com/dji/sample/manage/service/impl/ManageDeviceLivestreamUrlServiceImpl.java

@@ -42,46 +42,48 @@ public class ManageDeviceLivestreamUrlServiceImpl implements IManageDeviceLivest
 
 
     @Override
-    public ManageDeviceLivestreamUrlDTO getUrl(ManageDeviceLivestreamUrlDTO deviceLivestreamUrlDTO) {
+    public ManageDeviceLivestreamUrlDTO getUrl(ManageDeviceLivestreamUrlDTO deviceLivestreamUrlDTO,String protocal) {
 
 
         QueryWrapper<UserEntity> userWrapper = new QueryWrapper<>();
         userWrapper.lambda().eq(UserEntity::getUserType, UserTypeEnum.API.getVal()).eq(UserEntity::getClientId, CustomConfiguration.clientId);
         UserEntity userEntity = userMapper.selectOne(userWrapper);
         if (userEntity == null) {
-            log.debug("The user is null.");
-            throw new RuntimeException ("The user is null.");
+            log.info("接口用户不存在,ClientId:" + CustomConfiguration.clientId);
+            throw new RuntimeException ("接口用户不存在,无法获取流媒体地址信息");
         }
         //密码解密
         String password = DesUtil.getDecryptData(userEntity.getPassword(),userEntity.getSalt());
         //获取token
-        Map<String,String> tokenMap = CallSmsp.getSmspToken(userEntity.getUsername(),password);
+        Map<String,String> tokenMap = CallSmsp.getSmspToken(userEntity.getUsername(),password,protocal);
         if(tokenMap.get("Token") == null) {
-            log.debug("The smsp token is null.");
+            log.info("调用流媒体服务,获取token失败");
         }
 
         //获取rtmp地址
-        List<ManageDeviceLivestreamUrlDTO> rtmpList = CallSmsp.getRtmp(tokenMap.get("Token"),deviceLivestreamUrlDTO.getDeviceSn(),deviceLivestreamUrlDTO.getPayload());
+        List<ManageDeviceLivestreamUrlDTO> rtmpList = CallSmsp.getRtmp(tokenMap.get("Token"),deviceLivestreamUrlDTO.getDeviceSn(),protocal);
         ManageDeviceLivestreamUrlDTO rtmpDto = new ManageDeviceLivestreamUrlDTO();
 
         //获取数据库中deviceSn对应的url信息
         QueryWrapper<ManageDeviceLivestreamUrlEntity> wrapper = new QueryWrapper<>();
         wrapper.lambda().eq(ManageDeviceLivestreamUrlEntity::getDeviceSn,deviceLivestreamUrlDTO.getDeviceSn())
                 .eq(ManageDeviceLivestreamUrlEntity::getWorkspaceId,deviceLivestreamUrlDTO.getWorkspaceId());
-        List<ManageDeviceLivestreamUrlEntity> urlList = mapper.selectList(wrapper);
-        if(urlList.size() <= 0 && rtmpList.size() <= 0 ){
-            log.debug("The result is null.");
+        List<ManageDeviceLivestreamUrlEntity> urlListFromDB = mapper.selectList(wrapper);
+        if(urlListFromDB.size() <= 0 && rtmpList.size() <= 0 ){
+            log.info("调用流媒体服务,没有获取到流媒体推流拉流地址");
             throw new RuntimeException (tokenMap.get("message"));
         }
-        List<Integer> urlL = urlList.stream()
+        List<Integer> urlL = urlListFromDB.stream()
                 .map(ManageDeviceLivestreamUrlEntity::getChannelId)
                 .collect(Collectors.toList());
-        //过滤payloadIndex
-        List<ManageDeviceLivestreamUrlEntity> filterIndexList = urlList.stream().filter(channelData -> deviceLivestreamUrlDTO.getPayloadIndex().equals(channelData.getPayloadIndex()))
+        //筛选数据库中payloadIndex相同的记录
+        List<ManageDeviceLivestreamUrlEntity> filterIndexList =
+                urlListFromDB.stream().filter(channelData -> deviceLivestreamUrlDTO.getPayloadIndex().equals(channelData.getPayloadIndex()))
                 .collect(Collectors.toList());
         if (filterIndexList.size() > 0) {
-            //过滤channelId
-            List<ManageDeviceLivestreamUrlDTO> channelList = rtmpList.stream().filter(channelData -> filterIndexList.get(0).getChannelId().equals(channelData.getChannelId()))
+            //筛选数据库中channelId相同的记录
+            List<ManageDeviceLivestreamUrlDTO> channelList =
+                    rtmpList.stream().filter(channelData -> filterIndexList.get(0).getChannelId().equals(channelData.getChannelId()))
                     .collect(Collectors.toList());
             if (channelList.size() > 0) {
                 update(filterIndexList,channelList);
@@ -89,7 +91,7 @@ public class ManageDeviceLivestreamUrlServiceImpl implements IManageDeviceLivest
                 rtmpDto.setWebRtcUrl(channelList.get(0).getWebRtcUrl());
             } else {
                 if(rtmpList.size() > 0) {
-                    //过滤channelId
+                    //筛选数据库中不存在的记录
                     channelList = rtmpList.stream().filter(channelData -> !urlL.contains(channelData.getChannelId()))
                             .collect(Collectors.toList());
                     update(filterIndexList,channelList);
@@ -106,17 +108,16 @@ public class ManageDeviceLivestreamUrlServiceImpl implements IManageDeviceLivest
                 }
             }
         } else {
-            //过滤channelId
-            List<ManageDeviceLivestreamUrlDTO> channelList = rtmpList;
-
-            if(urlList.size() > 0) {
-                channelList = rtmpList.stream().filter(channelData -> !urlL.contains(channelData.getChannelId()))
-                        .collect(Collectors.toList());
-            }
+            //数据库中不存在
+            List<ManageDeviceLivestreamUrlDTO> channelList =
+                    rtmpList.stream().filter(channelData -> !urlL.contains(channelData.getChannelId()))
+                            .collect(Collectors.toList());
             ManageDeviceLivestreamUrlEntity urlEntity = new ManageDeviceLivestreamUrlEntity();
             if(channelList.size() > 0) {
-                //dto转entity
-                BeanUtils.copyProperties(deviceLivestreamUrlDTO,urlEntity);
+                urlEntity.setDeviceSn(deviceLivestreamUrlDTO.getDeviceSn());
+                urlEntity.setWorkspaceId(deviceLivestreamUrlDTO.getWorkspaceId());
+                urlEntity.setPayload(deviceLivestreamUrlDTO.getPayload());
+                urlEntity.setPayloadIndex(deviceLivestreamUrlDTO.getPayloadIndex());
                 //存库Rtmp
                 urlEntity.setSubType(DeviceSubTypeEnum.ONE.getSubType());
                 urlEntity.setUrlType(LiveUrlTypeEnum.RTMP.getVal());
@@ -140,11 +141,17 @@ public class ManageDeviceLivestreamUrlServiceImpl implements IManageDeviceLivest
 
     private void update(List<ManageDeviceLivestreamUrlEntity> entitys,List<ManageDeviceLivestreamUrlDTO> dtos) {
         for(ManageDeviceLivestreamUrlEntity url : entitys) {
-            url.setChannelId(dtos.get(0).getChannelId());
-            if (url.getUrlType().equals(LiveUrlTypeEnum.RTMP.getVal())) {
+            Integer channelId = dtos.get(0).getChannelId();
+            if (url.getUrlType().equals(LiveUrlTypeEnum.RTMP.getVal())
+            && (!url.getChannelId().equals(channelId)
+            || !url.getUrl().equals(dtos.get(0).getRtmpUrl()))) {
+                url.setChannelId(channelId);
                 url.setUrl(dtos.get(0).getRtmpUrl());
                 mapper.updateById(url);
-            } else if(url.getUrlType().equals(LiveUrlTypeEnum.WEBRTC.getVal())) {
+            } else if(url.getUrlType().equals(LiveUrlTypeEnum.WEBRTC.getVal())
+                    && (!url.getChannelId().equals(channelId)
+                    || !url.getUrl().equals(dtos.get(0).getWebRtcUrl()))) {
+                url.setChannelId(channelId);
                 url.setUrl(dtos.get(0).getWebRtcUrl());
                 mapper.updateById(url);
             }

+ 4 - 2
Backend/sample/src/main/resources/application.yml

@@ -183,6 +183,8 @@ custom-config:
   frequency: 3
   key: b1uruk98vuk40cdego6jw5yv9tygjm3s
   signKey: 7e92430eb1f949e9a750fadf68777c44
-  smspTokenUrl: https://smsp.jkec.info:4443/api/v1/login
-  smspRtmpUrl: https://smsp.jkec.info:4443/api/v1/channelstream/all
+  smspTokenUrl: http://smsp.jkec.info:18000/api/v1/login
+  smspRtmpUrl: http://smsp.jkec.info:18000/api/v1/channelstream/all
+  smspTokenUrl2: https://smsp.jkec.info:4443/api/v1/login
+  smspRtmpUrl2: https://smsp.jkec.info:4443/api/v1/channelstream/all
   clientId: e534550a85d94faba73e8040e76514bc