Commit f2279859b367fda6108a5ea22c572d38d89d338d
1 parent
17f4fe25
增加对水星IPC的兼容
增加对SIP错误的订阅,刷新通道或点播或回放出现sip错误时及时返回给页面 优化UI,增加按钮loading
Showing
13 changed files
with
176 additions
and
46 deletions
src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java
| @@ -8,8 +8,10 @@ import java.util.concurrent.ThreadPoolExecutor; | @@ -8,8 +8,10 @@ import java.util.concurrent.ThreadPoolExecutor; | ||
| 8 | import java.util.concurrent.TimeUnit; | 8 | import java.util.concurrent.TimeUnit; |
| 9 | 9 | ||
| 10 | import javax.sip.*; | 10 | import javax.sip.*; |
| 11 | +import javax.sip.header.CallIdHeader; | ||
| 11 | import javax.sip.message.Response; | 12 | import javax.sip.message.Response; |
| 12 | 13 | ||
| 14 | +import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; | ||
| 13 | import org.slf4j.Logger; | 15 | import org.slf4j.Logger; |
| 14 | import org.slf4j.LoggerFactory; | 16 | import org.slf4j.LoggerFactory; |
| 15 | import org.springframework.beans.factory.annotation.Autowired; | 17 | import org.springframework.beans.factory.annotation.Autowired; |
| @@ -34,6 +36,9 @@ public class SipLayer implements SipListener { | @@ -34,6 +36,9 @@ public class SipLayer implements SipListener { | ||
| 34 | @Autowired | 36 | @Autowired |
| 35 | private SIPProcessorFactory processorFactory; | 37 | private SIPProcessorFactory processorFactory; |
| 36 | 38 | ||
| 39 | + @Autowired | ||
| 40 | + private SipSubscribe sipSubscribe; | ||
| 41 | + | ||
| 37 | private SipStack sipStack; | 42 | private SipStack sipStack; |
| 38 | 43 | ||
| 39 | private SipFactory sipFactory; | 44 | private SipFactory sipFactory; |
| @@ -139,11 +144,19 @@ public class SipLayer implements SipListener { | @@ -139,11 +144,19 @@ public class SipLayer implements SipListener { | ||
| 139 | // 增加其它无需回复的响应,如101、180等 | 144 | // 增加其它无需回复的响应,如101、180等 |
| 140 | } else { | 145 | } else { |
| 141 | logger.warn("接收到失败的response响应!status:" + status + ",message:" + response.getReasonPhrase()/* .getContent().toString()*/); | 146 | logger.warn("接收到失败的response响应!status:" + status + ",message:" + response.getReasonPhrase()/* .getContent().toString()*/); |
| 147 | + if (evt.getResponse() != null && sipSubscribe.getSize() > 0 ) { | ||
| 148 | + CallIdHeader callIdHeader = (CallIdHeader)evt.getResponse().getHeader(CallIdHeader.NAME); | ||
| 149 | + if (callIdHeader != null) { | ||
| 150 | + SipSubscribe.Event subscribe = sipSubscribe.getSubscribe(callIdHeader.getCallId()); | ||
| 151 | + if (subscribe != null) { | ||
| 152 | + subscribe.response(evt); | ||
| 153 | + } | ||
| 154 | + } | ||
| 155 | + } | ||
| 142 | } | 156 | } |
| 143 | - // trying不会回复 | ||
| 144 | - // if (status == Response.TRYING) { | ||
| 145 | 157 | ||
| 146 | - // } | 158 | + |
| 159 | + | ||
| 147 | } | 160 | } |
| 148 | 161 | ||
| 149 | /** | 162 | /** |
src/main/java/com/genersoft/iot/vmp/gb28181/auth/RegisterLogicHandler.java
| @@ -21,6 +21,6 @@ public class RegisterLogicHandler { | @@ -21,6 +21,6 @@ public class RegisterLogicHandler { | ||
| 21 | // TODO 后续处理,只有第一次注册时调用查询设备信息,如需更新调用更新API接口 | 21 | // TODO 后续处理,只有第一次注册时调用查询设备信息,如需更新调用更新API接口 |
| 22 | cmder.deviceInfoQuery(device); | 22 | cmder.deviceInfoQuery(device); |
| 23 | 23 | ||
| 24 | - cmder.catalogQuery(device); | 24 | + cmder.catalogQuery(device, null); |
| 25 | } | 25 | } |
| 26 | } | 26 | } |
src/main/java/com/genersoft/iot/vmp/gb28181/event/SipSubscribe.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.gb28181.event; | ||
| 2 | + | ||
| 3 | +import com.alibaba.fastjson.JSONObject; | ||
| 4 | +import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; | ||
| 5 | +import org.slf4j.Logger; | ||
| 6 | +import org.slf4j.LoggerFactory; | ||
| 7 | +import org.springframework.stereotype.Component; | ||
| 8 | + | ||
| 9 | +import javax.sip.ResponseEvent; | ||
| 10 | +import javax.sip.message.Request; | ||
| 11 | +import java.util.EventObject; | ||
| 12 | +import java.util.Map; | ||
| 13 | +import java.util.concurrent.ConcurrentHashMap; | ||
| 14 | + | ||
| 15 | +@Component | ||
| 16 | +public class SipSubscribe { | ||
| 17 | + | ||
| 18 | + private final static Logger logger = LoggerFactory.getLogger(SipSubscribe.class); | ||
| 19 | + | ||
| 20 | + private Map<String, SipSubscribe.Event> allSubscribes = new ConcurrentHashMap<>(); | ||
| 21 | + | ||
| 22 | + public interface Event { | ||
| 23 | + void response(ResponseEvent event); | ||
| 24 | + } | ||
| 25 | + | ||
| 26 | + public void addSubscribe(String key, SipSubscribe.Event event) { | ||
| 27 | + allSubscribes.put(key, event); | ||
| 28 | + } | ||
| 29 | + | ||
| 30 | + public SipSubscribe.Event getSubscribe(String key) { | ||
| 31 | + return allSubscribes.get(key); | ||
| 32 | + } | ||
| 33 | + | ||
| 34 | + public int getSize(){ | ||
| 35 | + return allSubscribes.size(); | ||
| 36 | + } | ||
| 37 | +} |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java
| @@ -4,10 +4,13 @@ import javax.sip.RequestEvent; | @@ -4,10 +4,13 @@ import javax.sip.RequestEvent; | ||
| 4 | import javax.sip.ResponseEvent; | 4 | import javax.sip.ResponseEvent; |
| 5 | import javax.sip.SipProvider; | 5 | import javax.sip.SipProvider; |
| 6 | import javax.sip.header.CSeqHeader; | 6 | import javax.sip.header.CSeqHeader; |
| 7 | +import javax.sip.header.CallIdHeader; | ||
| 8 | +import javax.sip.header.Header; | ||
| 7 | import javax.sip.message.Request; | 9 | import javax.sip.message.Request; |
| 8 | import javax.sip.message.Response; | 10 | import javax.sip.message.Response; |
| 9 | 11 | ||
| 10 | import com.alibaba.fastjson.JSON; | 12 | import com.alibaba.fastjson.JSON; |
| 13 | +import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; | ||
| 11 | import org.slf4j.Logger; | 14 | import org.slf4j.Logger; |
| 12 | import org.slf4j.LoggerFactory; | 15 | import org.slf4j.LoggerFactory; |
| 13 | import org.springframework.beans.factory.annotation.Autowired; | 16 | import org.springframework.beans.factory.annotation.Autowired; |
| @@ -83,7 +86,8 @@ public class SIPProcessorFactory { | @@ -83,7 +86,8 @@ public class SIPProcessorFactory { | ||
| 83 | 86 | ||
| 84 | @Autowired | 87 | @Autowired |
| 85 | private OtherResponseProcessor otherResponseProcessor; | 88 | private OtherResponseProcessor otherResponseProcessor; |
| 86 | - | 89 | + |
| 90 | + | ||
| 87 | // 注:这里使用注解会导致循环依赖注入,暂用springBean | 91 | // 注:这里使用注解会导致循环依赖注入,暂用springBean |
| 88 | private SipProvider tcpSipProvider; | 92 | private SipProvider tcpSipProvider; |
| 89 | 93 | ||
| @@ -94,6 +98,7 @@ public class SIPProcessorFactory { | @@ -94,6 +98,7 @@ public class SIPProcessorFactory { | ||
| 94 | Request request = evt.getRequest(); | 98 | Request request = evt.getRequest(); |
| 95 | String method = request.getMethod(); | 99 | String method = request.getMethod(); |
| 96 | // logger.info("接收到消息:"+request.getMethod()); | 100 | // logger.info("接收到消息:"+request.getMethod()); |
| 101 | +// sipSubscribe.getSubscribe(evt.getServerTransaction().getBranchId()).response(evt); | ||
| 97 | if (Request.INVITE.equals(method)) { | 102 | if (Request.INVITE.equals(method)) { |
| 98 | InviteRequestProcessor processor = new InviteRequestProcessor(); | 103 | InviteRequestProcessor processor = new InviteRequestProcessor(); |
| 99 | processor.setRequestEvent(evt); | 104 | processor.setRequestEvent(evt); |
| @@ -145,6 +150,7 @@ public class SIPProcessorFactory { | @@ -145,6 +150,7 @@ public class SIPProcessorFactory { | ||
| 145 | } | 150 | } |
| 146 | 151 | ||
| 147 | public ISIPResponseProcessor createResponseProcessor(ResponseEvent evt) { | 152 | public ISIPResponseProcessor createResponseProcessor(ResponseEvent evt) { |
| 153 | + | ||
| 148 | Response response = evt.getResponse(); | 154 | Response response = evt.getResponse(); |
| 149 | CSeqHeader cseqHeader = (CSeqHeader) response.getHeader(CSeqHeader.NAME); | 155 | CSeqHeader cseqHeader = (CSeqHeader) response.getHeader(CSeqHeader.NAME); |
| 150 | String method = cseqHeader.getMethod(); | 156 | String method = cseqHeader.getMethod(); |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java
| @@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.gb28181.transmit.cmd; | @@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.gb28181.transmit.cmd; | ||
| 2 | 2 | ||
| 3 | import com.genersoft.iot.vmp.common.StreamInfo; | 3 | import com.genersoft.iot.vmp.common.StreamInfo; |
| 4 | import com.genersoft.iot.vmp.gb28181.bean.Device; | 4 | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| 5 | +import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; | ||
| 5 | import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; | 6 | import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; |
| 6 | 7 | ||
| 7 | /** | 8 | /** |
| @@ -83,7 +84,7 @@ public interface ISIPCommander { | @@ -83,7 +84,7 @@ public interface ISIPCommander { | ||
| 83 | * @param device 视频设备 | 84 | * @param device 视频设备 |
| 84 | * @param channelId 预览通道 | 85 | * @param channelId 预览通道 |
| 85 | */ | 86 | */ |
| 86 | - void playStreamCmd(Device device, String channelId, ZLMHttpHookSubscribe.Event event); | 87 | + void playStreamCmd(Device device, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent); |
| 87 | 88 | ||
| 88 | /** | 89 | /** |
| 89 | * 请求回放视频流 | 90 | * 请求回放视频流 |
| @@ -93,7 +94,7 @@ public interface ISIPCommander { | @@ -93,7 +94,7 @@ public interface ISIPCommander { | ||
| 93 | * @param startTime 开始时间,格式要求:yyyy-MM-dd HH:mm:ss | 94 | * @param startTime 开始时间,格式要求:yyyy-MM-dd HH:mm:ss |
| 94 | * @param endTime 结束时间,格式要求:yyyy-MM-dd HH:mm:ss | 95 | * @param endTime 结束时间,格式要求:yyyy-MM-dd HH:mm:ss |
| 95 | */ | 96 | */ |
| 96 | - void playbackStreamCmd(Device device, String channelId, String startTime, String endTime, ZLMHttpHookSubscribe.Event event); | 97 | + void playbackStreamCmd(Device device, String channelId, String startTime, String endTime, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent); |
| 97 | 98 | ||
| 98 | /** | 99 | /** |
| 99 | * 视频流停止 | 100 | * 视频流停止 |
| @@ -175,7 +176,7 @@ public interface ISIPCommander { | @@ -175,7 +176,7 @@ public interface ISIPCommander { | ||
| 175 | * | 176 | * |
| 176 | * @param device 视频设备 | 177 | * @param device 视频设备 |
| 177 | */ | 178 | */ |
| 178 | - boolean catalogQuery(Device device); | 179 | + boolean catalogQuery(Device device, SipSubscribe.Event errorEvent); |
| 179 | 180 | ||
| 180 | /** | 181 | /** |
| 181 | * 查询录像信息 | 182 | * 查询录像信息 |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
| @@ -4,22 +4,22 @@ import java.text.ParseException; | @@ -4,22 +4,22 @@ import java.text.ParseException; | ||
| 4 | import java.util.regex.Matcher; | 4 | import java.util.regex.Matcher; |
| 5 | import java.util.regex.Pattern; | 5 | import java.util.regex.Pattern; |
| 6 | 6 | ||
| 7 | -import javax.sip.ClientTransaction; | ||
| 8 | -import javax.sip.Dialog; | ||
| 9 | -import javax.sip.InvalidArgumentException; | ||
| 10 | -import javax.sip.SipException; | ||
| 11 | -import javax.sip.SipProvider; | ||
| 12 | -import javax.sip.TransactionDoesNotExistException; | 7 | +import javax.sip.*; |
| 13 | import javax.sip.address.SipURI; | 8 | import javax.sip.address.SipURI; |
| 9 | +import javax.sip.header.CallIdHeader; | ||
| 10 | +import javax.sip.header.Header; | ||
| 14 | import javax.sip.header.ViaHeader; | 11 | import javax.sip.header.ViaHeader; |
| 15 | import javax.sip.message.Request; | 12 | import javax.sip.message.Request; |
| 16 | 13 | ||
| 17 | import com.alibaba.fastjson.JSONObject; | 14 | import com.alibaba.fastjson.JSONObject; |
| 18 | import com.genersoft.iot.vmp.conf.MediaServerConfig; | 15 | import com.genersoft.iot.vmp.conf.MediaServerConfig; |
| 19 | import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; | 16 | import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; |
| 17 | +import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; | ||
| 20 | import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; | 18 | import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; |
| 21 | import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; | 19 | import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; |
| 22 | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; | 20 | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
| 21 | +import org.slf4j.Logger; | ||
| 22 | +import org.slf4j.LoggerFactory; | ||
| 23 | import org.springframework.beans.factory.annotation.Autowired; | 23 | import org.springframework.beans.factory.annotation.Autowired; |
| 24 | import org.springframework.beans.factory.annotation.Qualifier; | 24 | import org.springframework.beans.factory.annotation.Qualifier; |
| 25 | import org.springframework.beans.factory.annotation.Value; | 25 | import org.springframework.beans.factory.annotation.Value; |
| @@ -39,6 +39,8 @@ import com.genersoft.iot.vmp.gb28181.utils.DateUtil; | @@ -39,6 +39,8 @@ import com.genersoft.iot.vmp.gb28181.utils.DateUtil; | ||
| 39 | */ | 39 | */ |
| 40 | @Component | 40 | @Component |
| 41 | public class SIPCommander implements ISIPCommander { | 41 | public class SIPCommander implements ISIPCommander { |
| 42 | + | ||
| 43 | + private final Logger logger = LoggerFactory.getLogger(SIPCommander.class); | ||
| 42 | 44 | ||
| 43 | @Autowired | 45 | @Autowired |
| 44 | private SipConfig sipConfig; | 46 | private SipConfig sipConfig; |
| @@ -69,6 +71,9 @@ public class SIPCommander implements ISIPCommander { | @@ -69,6 +71,9 @@ public class SIPCommander implements ISIPCommander { | ||
| 69 | @Autowired | 71 | @Autowired |
| 70 | private ZLMHttpHookSubscribe subscribe; | 72 | private ZLMHttpHookSubscribe subscribe; |
| 71 | 73 | ||
| 74 | + @Autowired | ||
| 75 | + private SipSubscribe sipSubscribe; | ||
| 76 | + | ||
| 72 | 77 | ||
| 73 | 78 | ||
| 74 | /** | 79 | /** |
| @@ -221,7 +226,7 @@ public class SIPCommander implements ISIPCommander { | @@ -221,7 +226,7 @@ public class SIPCommander implements ISIPCommander { | ||
| 221 | 226 | ||
| 222 | Request request = headerProvider.createMessageRequest(device, ptzXml.toString(), "ViaPtzBranch", "FromPtzTag", "ToPtzTag"); | 227 | Request request = headerProvider.createMessageRequest(device, ptzXml.toString(), "ViaPtzBranch", "FromPtzTag", "ToPtzTag"); |
| 223 | 228 | ||
| 224 | - transmitRequest(device, request); | 229 | + transmitRequest(device, request, null); |
| 225 | return true; | 230 | return true; |
| 226 | } catch (SipException | ParseException | InvalidArgumentException e) { | 231 | } catch (SipException | ParseException | InvalidArgumentException e) { |
| 227 | e.printStackTrace(); | 232 | e.printStackTrace(); |
| @@ -256,22 +261,23 @@ public class SIPCommander implements ISIPCommander { | @@ -256,22 +261,23 @@ public class SIPCommander implements ISIPCommander { | ||
| 256 | ptzXml.append("</Control>\r\n"); | 261 | ptzXml.append("</Control>\r\n"); |
| 257 | 262 | ||
| 258 | Request request = headerProvider.createMessageRequest(device, ptzXml.toString(), "ViaPtzBranch", "FromPtzTag", "ToPtzTag"); | 263 | Request request = headerProvider.createMessageRequest(device, ptzXml.toString(), "ViaPtzBranch", "FromPtzTag", "ToPtzTag"); |
| 259 | - | ||
| 260 | - transmitRequest(device, request); | 264 | + transmitRequest(device, request, null); |
| 261 | return true; | 265 | return true; |
| 262 | } catch (SipException | ParseException | InvalidArgumentException e) { | 266 | } catch (SipException | ParseException | InvalidArgumentException e) { |
| 263 | e.printStackTrace(); | 267 | e.printStackTrace(); |
| 264 | } | 268 | } |
| 265 | return false; | 269 | return false; |
| 266 | } | 270 | } |
| 271 | + | ||
| 267 | /** | 272 | /** |
| 268 | - * 请求预览视频流 | ||
| 269 | - * | 273 | + * 请求预览视频流 |
| 270 | * @param device 视频设备 | 274 | * @param device 视频设备 |
| 271 | * @param channelId 预览通道 | 275 | * @param channelId 预览通道 |
| 276 | + * @param event hook订阅 | ||
| 277 | + * @param errorEvent sip错误订阅 | ||
| 272 | */ | 278 | */ |
| 273 | @Override | 279 | @Override |
| 274 | - public void playStreamCmd(Device device, String channelId, ZLMHttpHookSubscribe.Event event) { | 280 | + public void playStreamCmd(Device device, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent) { |
| 275 | try { | 281 | try { |
| 276 | 282 | ||
| 277 | String ssrc = streamSession.createPlaySsrc(); | 283 | String ssrc = streamSession.createPlaySsrc(); |
| @@ -300,7 +306,8 @@ public class SIPCommander implements ISIPCommander { | @@ -300,7 +306,8 @@ public class SIPCommander implements ISIPCommander { | ||
| 300 | // | 306 | // |
| 301 | StringBuffer content = new StringBuffer(200); | 307 | StringBuffer content = new StringBuffer(200); |
| 302 | content.append("v=0\r\n"); | 308 | content.append("v=0\r\n"); |
| 303 | - content.append("o="+channelId+" 0 0 IN IP4 "+mediaInfo.getWanIp()+"\r\n"); | 309 | +// content.append("o="+channelId+" 0 0 IN IP4 "+mediaInfo.getWanIp()+"\r\n"); |
| 310 | + content.append("o="+"00000"+" 0 0 IN IP4 "+mediaInfo.getWanIp()+"\r\n"); | ||
| 304 | content.append("s=Play\r\n"); | 311 | content.append("s=Play\r\n"); |
| 305 | content.append("c=IN IP4 "+mediaInfo.getWanIp()+"\r\n"); | 312 | content.append("c=IN IP4 "+mediaInfo.getWanIp()+"\r\n"); |
| 306 | content.append("t=0 0\r\n"); | 313 | content.append("t=0 0\r\n"); |
| @@ -332,7 +339,7 @@ public class SIPCommander implements ISIPCommander { | @@ -332,7 +339,7 @@ public class SIPCommander implements ISIPCommander { | ||
| 332 | 339 | ||
| 333 | Request request = headerProvider.createInviteRequest(device, channelId, content.toString(), null, "live", null, ssrc); | 340 | Request request = headerProvider.createInviteRequest(device, channelId, content.toString(), null, "live", null, ssrc); |
| 334 | 341 | ||
| 335 | - ClientTransaction transaction = transmitRequest(device, request); | 342 | + ClientTransaction transaction = transmitRequest(device, request, errorEvent); |
| 336 | streamSession.put(streamId, transaction); | 343 | streamSession.put(streamId, transaction); |
| 337 | DeviceChannel deviceChannel = storager.queryChannel(device.getDeviceId(), channelId); | 344 | DeviceChannel deviceChannel = storager.queryChannel(device.getDeviceId(), channelId); |
| 338 | if (deviceChannel != null) { | 345 | if (deviceChannel != null) { |
| @@ -357,7 +364,8 @@ public class SIPCommander implements ISIPCommander { | @@ -357,7 +364,8 @@ public class SIPCommander implements ISIPCommander { | ||
| 357 | * @param endTime 结束时间,格式要求:yyyy-MM-dd HH:mm:ss | 364 | * @param endTime 结束时间,格式要求:yyyy-MM-dd HH:mm:ss |
| 358 | */ | 365 | */ |
| 359 | @Override | 366 | @Override |
| 360 | - public void playbackStreamCmd(Device device, String channelId, String startTime, String endTime, ZLMHttpHookSubscribe.Event event) { | 367 | + public void playbackStreamCmd(Device device, String channelId, String startTime, String endTime, ZLMHttpHookSubscribe.Event event |
| 368 | + , SipSubscribe.Event errorEvent) { | ||
| 361 | try { | 369 | try { |
| 362 | MediaServerConfig mediaInfo = storager.getMediaInfo(); | 370 | MediaServerConfig mediaInfo = storager.getMediaInfo(); |
| 363 | String ssrc = streamSession.createPlayBackSsrc(); | 371 | String ssrc = streamSession.createPlayBackSsrc(); |
| @@ -413,8 +421,8 @@ public class SIPCommander implements ISIPCommander { | @@ -413,8 +421,8 @@ public class SIPCommander implements ISIPCommander { | ||
| 413 | content.append("y="+ssrc+"\r\n");//ssrc | 421 | content.append("y="+ssrc+"\r\n");//ssrc |
| 414 | 422 | ||
| 415 | Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, "playback", null); | 423 | Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, "playback", null); |
| 416 | - | ||
| 417 | - ClientTransaction transaction = transmitRequest(device, request); | 424 | + |
| 425 | + ClientTransaction transaction = transmitRequest(device, request, errorEvent); | ||
| 418 | streamSession.put(streamId, transaction); | 426 | streamSession.put(streamId, transaction); |
| 419 | 427 | ||
| 420 | } catch ( SipException | ParseException | InvalidArgumentException e) { | 428 | } catch ( SipException | ParseException | InvalidArgumentException e) { |
| @@ -575,7 +583,8 @@ public class SIPCommander implements ISIPCommander { | @@ -575,7 +583,8 @@ public class SIPCommander implements ISIPCommander { | ||
| 575 | catalogXml.append("</Query>\r\n"); | 583 | catalogXml.append("</Query>\r\n"); |
| 576 | 584 | ||
| 577 | Request request = headerProvider.createMessageRequest(device, catalogXml.toString(), "ViaDeviceInfoBranch", "FromDeviceInfoTag", "ToDeviceInfoTag"); | 585 | Request request = headerProvider.createMessageRequest(device, catalogXml.toString(), "ViaDeviceInfoBranch", "FromDeviceInfoTag", "ToDeviceInfoTag"); |
| 578 | - transmitRequest(device, request); | 586 | + |
| 587 | + transmitRequest(device, request, null); | ||
| 579 | 588 | ||
| 580 | } catch (SipException | ParseException | InvalidArgumentException e) { | 589 | } catch (SipException | ParseException | InvalidArgumentException e) { |
| 581 | e.printStackTrace(); | 590 | e.printStackTrace(); |
| @@ -590,7 +599,7 @@ public class SIPCommander implements ISIPCommander { | @@ -590,7 +599,7 @@ public class SIPCommander implements ISIPCommander { | ||
| 590 | * @param device 视频设备 | 599 | * @param device 视频设备 |
| 591 | */ | 600 | */ |
| 592 | @Override | 601 | @Override |
| 593 | - public boolean catalogQuery(Device device) { | 602 | + public boolean catalogQuery(Device device, SipSubscribe.Event errorEvent) { |
| 594 | // 清空通道 | 603 | // 清空通道 |
| 595 | storager.cleanChannelsForDevice(device.getDeviceId()); | 604 | storager.cleanChannelsForDevice(device.getDeviceId()); |
| 596 | try { | 605 | try { |
| @@ -602,8 +611,9 @@ public class SIPCommander implements ISIPCommander { | @@ -602,8 +611,9 @@ public class SIPCommander implements ISIPCommander { | ||
| 602 | catalogXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n"); | 611 | catalogXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n"); |
| 603 | catalogXml.append("</Query>\r\n"); | 612 | catalogXml.append("</Query>\r\n"); |
| 604 | 613 | ||
| 605 | - Request request = headerProvider.createMessageRequest(device, catalogXml.toString(), "ViaCatalogBranch", "FromCatalogTag", "ToCatalogTag"); | ||
| 606 | - transmitRequest(device, request); | 614 | + Request request = headerProvider.createMessageRequest(device, catalogXml.toString(), "ViaCatalogBranch", "FromCatalogTag", null); |
| 615 | + | ||
| 616 | + transmitRequest(device, request, errorEvent); | ||
| 607 | } catch (SipException | ParseException | InvalidArgumentException e) { | 617 | } catch (SipException | ParseException | InvalidArgumentException e) { |
| 608 | e.printStackTrace(); | 618 | e.printStackTrace(); |
| 609 | return false; | 619 | return false; |
| @@ -636,7 +646,9 @@ public class SIPCommander implements ISIPCommander { | @@ -636,7 +646,9 @@ public class SIPCommander implements ISIPCommander { | ||
| 636 | recordInfoXml.append("</Query>\r\n"); | 646 | recordInfoXml.append("</Query>\r\n"); |
| 637 | 647 | ||
| 638 | Request request = headerProvider.createMessageRequest(device, recordInfoXml.toString(), "ViaRecordInfoBranch", "FromRecordInfoTag", "ToRecordInfoTag"); | 648 | Request request = headerProvider.createMessageRequest(device, recordInfoXml.toString(), "ViaRecordInfoBranch", "FromRecordInfoTag", "ToRecordInfoTag"); |
| 639 | - transmitRequest(device, request); | 649 | + |
| 650 | + | ||
| 651 | + transmitRequest(device, request, null); | ||
| 640 | } catch (SipException | ParseException | InvalidArgumentException e) { | 652 | } catch (SipException | ParseException | InvalidArgumentException e) { |
| 641 | e.printStackTrace(); | 653 | e.printStackTrace(); |
| 642 | return false; | 654 | return false; |
| @@ -688,13 +700,20 @@ public class SIPCommander implements ISIPCommander { | @@ -688,13 +700,20 @@ public class SIPCommander implements ISIPCommander { | ||
| 688 | return false; | 700 | return false; |
| 689 | } | 701 | } |
| 690 | 702 | ||
| 691 | - private ClientTransaction transmitRequest(Device device, Request request) throws SipException { | 703 | + private ClientTransaction transmitRequest(Device device, Request request, SipSubscribe.Event errorEvent) throws SipException { |
| 692 | ClientTransaction clientTransaction = null; | 704 | ClientTransaction clientTransaction = null; |
| 693 | if("TCP".equals(device.getTransport())) { | 705 | if("TCP".equals(device.getTransport())) { |
| 694 | clientTransaction = tcpSipProvider.getNewClientTransaction(request); | 706 | clientTransaction = tcpSipProvider.getNewClientTransaction(request); |
| 695 | } else if("UDP".equals(device.getTransport())) { | 707 | } else if("UDP".equals(device.getTransport())) { |
| 696 | clientTransaction = udpSipProvider.getNewClientTransaction(request); | 708 | clientTransaction = udpSipProvider.getNewClientTransaction(request); |
| 697 | } | 709 | } |
| 710 | + | ||
| 711 | + // 添加订阅 | ||
| 712 | + if (errorEvent != null) { | ||
| 713 | + CallIdHeader callIdHeader = (CallIdHeader)request.getHeader(CallIdHeader.NAME); | ||
| 714 | + sipSubscribe.addSubscribe(callIdHeader.getCallId(), errorEvent); | ||
| 715 | + } | ||
| 716 | + | ||
| 698 | clientTransaction.sendRequest(); | 717 | clientTransaction.sendRequest(); |
| 699 | return clientTransaction; | 718 | return clientTransaction; |
| 700 | } | 719 | } |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java
| @@ -294,7 +294,7 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor { | @@ -294,7 +294,7 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor { | ||
| 294 | device.setStreamMode("UDP"); | 294 | device.setStreamMode("UDP"); |
| 295 | } | 295 | } |
| 296 | storager.updateDevice(device); | 296 | storager.updateDevice(device); |
| 297 | - cmder.catalogQuery(device); | 297 | + cmder.catalogQuery(device, null); |
| 298 | // 回复200 OK | 298 | // 回复200 OK |
| 299 | responseAck(evt); | 299 | responseAck(evt); |
| 300 | if (offLineDetector.isOnline(deviceId)) { | 300 | if (offLineDetector.isOnline(deviceId)) { |
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
| @@ -323,7 +323,7 @@ public class ZLMHttpHookListener { | @@ -323,7 +323,7 @@ public class ZLMHttpHookListener { | ||
| 323 | cmder.playStreamCmd(device, channelId, (JSONObject response) -> { | 323 | cmder.playStreamCmd(device, channelId, (JSONObject response) -> { |
| 324 | logger.info("收到订阅消息: " + response.toJSONString()); | 324 | logger.info("收到订阅消息: " + response.toJSONString()); |
| 325 | playService.onPublishHandlerForPlay(response, deviceId, channelId, uuid.toString()); | 325 | playService.onPublishHandlerForPlay(response, deviceId, channelId, uuid.toString()); |
| 326 | - }); | 326 | + }, null); |
| 327 | } | 327 | } |
| 328 | 328 | ||
| 329 | } | 329 | } |
src/main/java/com/genersoft/iot/vmp/utils/SpringBeanFactory.java
| @@ -34,6 +34,7 @@ public class SpringBeanFactory implements ApplicationContextAware { | @@ -34,6 +34,7 @@ public class SpringBeanFactory implements ApplicationContextAware { | ||
| 34 | * 获取对象 这里重写了bean方法,起主要作用 | 34 | * 获取对象 这里重写了bean方法,起主要作用 |
| 35 | */ | 35 | */ |
| 36 | public static Object getBean(String beanId) throws BeansException { | 36 | public static Object getBean(String beanId) throws BeansException { |
| 37 | + if (applicationContext == null) return null; | ||
| 37 | return applicationContext.getBean(beanId); | 38 | return applicationContext.getBean(beanId); |
| 38 | } | 39 | } |
| 39 | 40 |
src/main/java/com/genersoft/iot/vmp/vmanager/device/DeviceController.java
| @@ -4,6 +4,7 @@ import java.util.List; | @@ -4,6 +4,7 @@ import java.util.List; | ||
| 4 | 4 | ||
| 5 | import com.genersoft.iot.vmp.common.PageResult; | 5 | import com.genersoft.iot.vmp.common.PageResult; |
| 6 | import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; | 6 | import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; |
| 7 | +import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; | ||
| 7 | import org.slf4j.Logger; | 8 | import org.slf4j.Logger; |
| 8 | import org.slf4j.LoggerFactory; | 9 | import org.slf4j.LoggerFactory; |
| 9 | import org.springframework.beans.factory.annotation.Autowired; | 10 | import org.springframework.beans.factory.annotation.Autowired; |
| @@ -19,6 +20,8 @@ import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; | @@ -19,6 +20,8 @@ import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; | ||
| 19 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; | 20 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; |
| 20 | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; | 21 | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
| 21 | 22 | ||
| 23 | +import javax.sip.message.Response; | ||
| 24 | + | ||
| 22 | @CrossOrigin | 25 | @CrossOrigin |
| 23 | @RestController | 26 | @RestController |
| 24 | @RequestMapping("/api") | 27 | @RequestMapping("/api") |
| @@ -86,11 +89,25 @@ public class DeviceController { | @@ -86,11 +89,25 @@ public class DeviceController { | ||
| 86 | 89 | ||
| 87 | if (logger.isDebugEnabled()) { | 90 | if (logger.isDebugEnabled()) { |
| 88 | } | 91 | } |
| 89 | - logger.debug("设备信息同步API调用,deviceId:" + deviceId); | 92 | + logger.debug("设备通道信息同步API调用,deviceId:" + deviceId); |
| 90 | 93 | ||
| 91 | Device device = storager.queryVideoDevice(deviceId); | 94 | Device device = storager.queryVideoDevice(deviceId); |
| 92 | - cmder.catalogQuery(device); | ||
| 93 | - DeferredResult<ResponseEntity<Device>> result = new DeferredResult<ResponseEntity<Device>>(); | 95 | + cmder.catalogQuery(device, event -> { |
| 96 | + Response response = event.getResponse(); | ||
| 97 | + RequestMessage msg = new RequestMessage(); | ||
| 98 | + msg.setId(DeferredResultHolder.CALLBACK_CMD_CATALOG+deviceId); | ||
| 99 | + msg.setData(String.format("同步通道失败,错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase())); | ||
| 100 | + resultHolder.invokeResult(msg); | ||
| 101 | + }); | ||
| 102 | + DeferredResult<ResponseEntity<Device>> result = new DeferredResult<ResponseEntity<Device>>(2*1000L); | ||
| 103 | + result.onTimeout(()->{ | ||
| 104 | + logger.warn(String.format("设备通道信息同步超时")); | ||
| 105 | + // 释放rtpserver | ||
| 106 | + RequestMessage msg = new RequestMessage(); | ||
| 107 | + msg.setId(DeferredResultHolder.CALLBACK_CMD_CATALOG+deviceId); | ||
| 108 | + msg.setData("Timeout"); | ||
| 109 | + resultHolder.invokeResult(msg); | ||
| 110 | + }); | ||
| 94 | resultHolder.put(DeferredResultHolder.CALLBACK_CMD_CATALOG+deviceId, result); | 111 | resultHolder.put(DeferredResultHolder.CALLBACK_CMD_CATALOG+deviceId, result); |
| 95 | return result; | 112 | return result; |
| 96 | } | 113 | } |
src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java
| @@ -28,6 +28,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; | @@ -28,6 +28,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; | ||
| 28 | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; | 28 | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
| 29 | import org.springframework.web.context.request.async.DeferredResult; | 29 | import org.springframework.web.context.request.async.DeferredResult; |
| 30 | 30 | ||
| 31 | +import javax.sip.message.Response; | ||
| 31 | import java.text.DecimalFormat; | 32 | import java.text.DecimalFormat; |
| 32 | import java.util.UUID; | 33 | import java.util.UUID; |
| 33 | 34 | ||
| @@ -72,6 +73,12 @@ public class PlayController { | @@ -72,6 +73,12 @@ public class PlayController { | ||
| 72 | cmder.playStreamCmd(device, channelId, (JSONObject response) -> { | 73 | cmder.playStreamCmd(device, channelId, (JSONObject response) -> { |
| 73 | logger.info("收到订阅消息: " + response.toJSONString()); | 74 | logger.info("收到订阅消息: " + response.toJSONString()); |
| 74 | playService.onPublishHandlerForPlay(response, deviceId, channelId, uuid.toString()); | 75 | playService.onPublishHandlerForPlay(response, deviceId, channelId, uuid.toString()); |
| 76 | + }, event -> { | ||
| 77 | + RequestMessage msg = new RequestMessage(); | ||
| 78 | + msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid); | ||
| 79 | + Response response = event.getResponse(); | ||
| 80 | + msg.setData(String.format("点播失败, 错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase())); | ||
| 81 | + resultHolder.invokeResult(msg); | ||
| 75 | }); | 82 | }); |
| 76 | } else { | 83 | } else { |
| 77 | String streamId = streamInfo.getStreamId(); | 84 | String streamId = streamInfo.getStreamId(); |
| @@ -86,6 +93,12 @@ public class PlayController { | @@ -86,6 +93,12 @@ public class PlayController { | ||
| 86 | cmder.playStreamCmd(device, channelId, (JSONObject response) -> { | 93 | cmder.playStreamCmd(device, channelId, (JSONObject response) -> { |
| 87 | logger.info("收到订阅消息: " + response.toJSONString()); | 94 | logger.info("收到订阅消息: " + response.toJSONString()); |
| 88 | playService.onPublishHandlerForPlay(response, deviceId, channelId, uuid.toString()); | 95 | playService.onPublishHandlerForPlay(response, deviceId, channelId, uuid.toString()); |
| 96 | + }, event -> { | ||
| 97 | + RequestMessage msg = new RequestMessage(); | ||
| 98 | + msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid); | ||
| 99 | + Response response = event.getResponse(); | ||
| 100 | + msg.setData(String.format("点播失败, 错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase())); | ||
| 101 | + resultHolder.invokeResult(msg); | ||
| 89 | }); | 102 | }); |
| 90 | } | 103 | } |
| 91 | } | 104 | } |
src/main/java/com/genersoft/iot/vmp/vmanager/playback/PlaybackController.java
| @@ -27,6 +27,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; | @@ -27,6 +27,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; | ||
| 27 | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; | 27 | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
| 28 | import org.springframework.web.context.request.async.DeferredResult; | 28 | import org.springframework.web.context.request.async.DeferredResult; |
| 29 | 29 | ||
| 30 | +import javax.sip.message.Response; | ||
| 30 | import java.util.UUID; | 31 | import java.util.UUID; |
| 31 | 32 | ||
| 32 | @CrossOrigin | 33 | @CrossOrigin |
| @@ -78,6 +79,12 @@ public class PlaybackController { | @@ -78,6 +79,12 @@ public class PlaybackController { | ||
| 78 | cmder.playbackStreamCmd(device, channelId, startTime, endTime, (JSONObject response) -> { | 79 | cmder.playbackStreamCmd(device, channelId, startTime, endTime, (JSONObject response) -> { |
| 79 | logger.info("收到订阅消息: " + response.toJSONString()); | 80 | logger.info("收到订阅消息: " + response.toJSONString()); |
| 80 | playService.onPublishHandlerForPlayBack(response, deviceId, channelId, uuid.toString()); | 81 | playService.onPublishHandlerForPlayBack(response, deviceId, channelId, uuid.toString()); |
| 82 | + }, event -> { | ||
| 83 | + Response response = event.getResponse(); | ||
| 84 | + RequestMessage msg = new RequestMessage(); | ||
| 85 | + msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid); | ||
| 86 | + msg.setData(String.format("回放失败, 错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase())); | ||
| 87 | + resultHolder.invokeResult(msg); | ||
| 81 | }); | 88 | }); |
| 82 | 89 | ||
| 83 | return result; | 90 | return result; |
web_src/src/components/videoList.vue
| @@ -8,7 +8,7 @@ | @@ -8,7 +8,7 @@ | ||
| 8 | <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;"> | 8 | <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;"> |
| 9 | <span style="font-size: 1rem; font-weight: bold;">设备列表</span> | 9 | <span style="font-size: 1rem; font-weight: bold;">设备列表</span> |
| 10 | <div style="position: absolute; right: 1rem; top: 0.3rem;"> | 10 | <div style="position: absolute; right: 1rem; top: 0.3rem;"> |
| 11 | - <el-button icon="el-icon-refresh-right" circle size="mini" @click="getDeviceList()"></el-button> | 11 | + <el-button icon="el-icon-refresh-right" circle size="mini" :loading="getDeviceListLoading" @click="getDeviceList()"></el-button> |
| 12 | </div> | 12 | </div> |
| 13 | </div> | 13 | </div> |
| 14 | <devicePlayer ref="devicePlayer"></devicePlayer> | 14 | <devicePlayer ref="devicePlayer"></devicePlayer> |
| @@ -51,7 +51,7 @@ | @@ -51,7 +51,7 @@ | ||
| 51 | 51 | ||
| 52 | <el-table-column label="操作" width="240" align="center" fixed="right"> | 52 | <el-table-column label="操作" width="240" align="center" fixed="right"> |
| 53 | <template slot-scope="scope"> | 53 | <template slot-scope="scope"> |
| 54 | - <el-button size="mini" icon="el-icon-refresh" @click="refDevice(scope.row)">刷新通道</el-button> | 54 | + <el-button size="mini" :ref="scope.row.deviceId + 'refbtn' " icon="el-icon-refresh" @click="refDevice(scope.row)">刷新通道</el-button> |
| 55 | <el-button size="mini" icon="el-icon-s-open" type="primary" @click="showChannelList(scope.row)">查看通道</el-button> | 55 | <el-button size="mini" icon="el-icon-s-open" type="primary" @click="showChannelList(scope.row)">查看通道</el-button> |
| 56 | </template> | 56 | </template> |
| 57 | </el-table-column> | 57 | </el-table-column> |
| @@ -90,7 +90,8 @@ | @@ -90,7 +90,8 @@ | ||
| 90 | winHeight: window.innerHeight - 200, | 90 | winHeight: window.innerHeight - 200, |
| 91 | currentPage:1, | 91 | currentPage:1, |
| 92 | count:15, | 92 | count:15, |
| 93 | - total:0 | 93 | + total:0, |
| 94 | + getDeviceListLoading: false | ||
| 94 | }; | 95 | }; |
| 95 | }, | 96 | }, |
| 96 | computed: { | 97 | computed: { |
| @@ -130,7 +131,7 @@ | @@ -130,7 +131,7 @@ | ||
| 130 | }, | 131 | }, |
| 131 | getDeviceList: function() { | 132 | getDeviceList: function() { |
| 132 | let that = this; | 133 | let that = this; |
| 133 | - | 134 | + this.getDeviceListLoading = true; |
| 134 | this.$axios.get(`/api/devices`,{ | 135 | this.$axios.get(`/api/devices`,{ |
| 135 | params: { | 136 | params: { |
| 136 | page: that.currentPage - 1, | 137 | page: that.currentPage - 1, |
| @@ -141,9 +142,11 @@ | @@ -141,9 +142,11 @@ | ||
| 141 | console.log(res); | 142 | console.log(res); |
| 142 | that.total = res.data.total; | 143 | that.total = res.data.total; |
| 143 | that.deviceList = res.data.data; | 144 | that.deviceList = res.data.data; |
| 145 | + that.getDeviceListLoading = false; | ||
| 144 | }) | 146 | }) |
| 145 | .catch(function (error) { | 147 | .catch(function (error) { |
| 146 | console.log(error); | 148 | console.log(error); |
| 149 | + that.getDeviceListLoading = false; | ||
| 147 | }); | 150 | }); |
| 148 | 151 | ||
| 149 | }, | 152 | }, |
| @@ -158,17 +161,30 @@ | @@ -158,17 +161,30 @@ | ||
| 158 | refDevice: function(itemData) { | 161 | refDevice: function(itemData) { |
| 159 | ///api/devices/{deviceId}/sync | 162 | ///api/devices/{deviceId}/sync |
| 160 | console.log("刷新对应设备:" + itemData.deviceId); | 163 | console.log("刷新对应设备:" + itemData.deviceId); |
| 164 | + var that = this; | ||
| 165 | + that.$refs[itemData.deviceId + 'refbtn' ].loading = true; | ||
| 161 | this.$axios({ | 166 | this.$axios({ |
| 162 | method: 'post', | 167 | method: 'post', |
| 163 | url: '/api/devices/' + itemData.deviceId + '/sync' | 168 | url: '/api/devices/' + itemData.deviceId + '/sync' |
| 164 | }).then(function(res) { | 169 | }).then(function(res) { |
| 165 | - // console.log("刷新设备结果:"+JSON.stringify(res)); | 170 | + console.log("刷新设备结果:"+JSON.stringify(res)); |
| 171 | + if (!res.data.deviceId) { | ||
| 172 | + that.$message({ | ||
| 173 | + showClose: true, | ||
| 174 | + message: res.data, | ||
| 175 | + type: 'error' | ||
| 176 | + }); | ||
| 177 | + }else{ | ||
| 178 | + that.$message({ | ||
| 179 | + showClose: true, | ||
| 180 | + message: '请求成功', | ||
| 181 | + type: 'success' | ||
| 182 | + }); | ||
| 183 | + } | ||
| 184 | + that.$refs[itemData.deviceId + 'refbtn' ].loading = false; | ||
| 166 | }).catch(function(e) { | 185 | }).catch(function(e) { |
| 167 | - that.$message({ | ||
| 168 | - showClose: true, | ||
| 169 | - message: '请求成功', | ||
| 170 | - type: 'success' | ||
| 171 | - }); | 186 | + console.error(e) |
| 187 | + that.$refs[itemData.deviceId + 'refbtn' ].loading = false; | ||
| 172 | });; | 188 | });; |
| 173 | }, | 189 | }, |
| 174 | //通知设备上传媒体流 | 190 | //通知设备上传媒体流 |