Commit d4ae8194eb87271423aba24bab0f0d815d5ffdc1
1 parent
c6e959eb
离在线状态样式修改
修复未回复200ok导致catalog一直发送的bug 修改点播接口未收到视频后回复
Showing
12 changed files
with
179 additions
and
80 deletions
src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java
| @@ -3,11 +3,13 @@ package com.genersoft.iot.vmp.common; | @@ -3,11 +3,13 @@ package com.genersoft.iot.vmp.common; | ||
| 3 | public class StreamInfo { | 3 | public class StreamInfo { |
| 4 | 4 | ||
| 5 | private String ssrc; | 5 | private String ssrc; |
| 6 | + private String deviceID; | ||
| 7 | + private String cahnnelId; | ||
| 6 | private String flv; | 8 | private String flv; |
| 7 | - private String WS_FLV; | ||
| 8 | - private String RTMP; | ||
| 9 | - private String HLS; | ||
| 10 | - private String RTSP; | 9 | + private String ws_flv; |
| 10 | + private String rtmp; | ||
| 11 | + private String hls; | ||
| 12 | + private String rtsp; | ||
| 11 | 13 | ||
| 12 | public String getSsrc() { | 14 | public String getSsrc() { |
| 13 | return ssrc; | 15 | return ssrc; |
| @@ -25,35 +27,51 @@ public class StreamInfo { | @@ -25,35 +27,51 @@ public class StreamInfo { | ||
| 25 | this.flv = flv; | 27 | this.flv = flv; |
| 26 | } | 28 | } |
| 27 | 29 | ||
| 28 | - public String getWS_FLV() { | ||
| 29 | - return WS_FLV; | 30 | + public String getWs_flv() { |
| 31 | + return ws_flv; | ||
| 30 | } | 32 | } |
| 31 | 33 | ||
| 32 | - public void setWS_FLV(String WS_FLV) { | ||
| 33 | - this.WS_FLV = WS_FLV; | 34 | + public void setWs_flv(String ws_flv) { |
| 35 | + this.ws_flv = ws_flv; | ||
| 34 | } | 36 | } |
| 35 | 37 | ||
| 36 | - public String getRTMP() { | ||
| 37 | - return RTMP; | 38 | + public String getRtmp() { |
| 39 | + return rtmp; | ||
| 38 | } | 40 | } |
| 39 | 41 | ||
| 40 | - public void setRTMP(String RTMP) { | ||
| 41 | - this.RTMP = RTMP; | 42 | + public void setRtmp(String rtmp) { |
| 43 | + this.rtmp = rtmp; | ||
| 42 | } | 44 | } |
| 43 | 45 | ||
| 44 | - public String getHLS() { | ||
| 45 | - return HLS; | 46 | + public String getHls() { |
| 47 | + return hls; | ||
| 46 | } | 48 | } |
| 47 | 49 | ||
| 48 | - public void setHLS(String HLS) { | ||
| 49 | - this.HLS = HLS; | 50 | + public void setHls(String hls) { |
| 51 | + this.hls = hls; | ||
| 50 | } | 52 | } |
| 51 | 53 | ||
| 52 | - public String getRTSP() { | ||
| 53 | - return RTSP; | 54 | + public String getRtsp() { |
| 55 | + return rtsp; | ||
| 54 | } | 56 | } |
| 55 | 57 | ||
| 56 | - public void setRTSP(String RTSP) { | ||
| 57 | - this.RTSP = RTSP; | 58 | + public void setRtsp(String rtsp) { |
| 59 | + this.rtsp = rtsp; | ||
| 60 | + } | ||
| 61 | + | ||
| 62 | + public String getDeviceID() { | ||
| 63 | + return deviceID; | ||
| 64 | + } | ||
| 65 | + | ||
| 66 | + public void setDeviceID(String deviceID) { | ||
| 67 | + this.deviceID = deviceID; | ||
| 68 | + } | ||
| 69 | + | ||
| 70 | + public String getCahnnelId() { | ||
| 71 | + return cahnnelId; | ||
| 72 | + } | ||
| 73 | + | ||
| 74 | + public void setCahnnelId(String cahnnelId) { | ||
| 75 | + this.cahnnelId = cahnnelId; | ||
| 58 | } | 76 | } |
| 59 | } | 77 | } |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
| @@ -242,14 +242,15 @@ public class SIPCommander implements ISIPCommander { | @@ -242,14 +242,15 @@ public class SIPCommander implements ISIPCommander { | ||
| 242 | StreamInfo streamInfo = new StreamInfo(); | 242 | StreamInfo streamInfo = new StreamInfo(); |
| 243 | streamInfo.setSsrc(ssrc); | 243 | streamInfo.setSsrc(ssrc); |
| 244 | // String streamId = Integer.toHexString(Integer.parseInt(streamInfo.getSsrc())); | 244 | // String streamId = Integer.toHexString(Integer.parseInt(streamInfo.getSsrc())); |
| 245 | - String streamId = String.format("%08x", Integer.parseInt(streamInfo.getSsrc())).toUpperCase(); // ZLM 要求大写且首位补零 | ||
| 246 | - streamInfo.setFlv(String.format("http://%s:%s/rtp/%s.flv", mediaInfo.getLocalIP(), mediaInfo.getHttpPort(), streamId)); | ||
| 247 | - streamInfo.setWS_FLV(String.format("ws://%s:%s/rtp/%s.flv", mediaInfo.getLocalIP(), mediaInfo.getHttpPort(), streamId)); | ||
| 248 | - streamInfo.setRTMP(String.format("rtmp://%s:%s/rtp/%s", mediaInfo.getLocalIP(), mediaInfo.getRtmpPort(), streamId)); | ||
| 249 | - streamInfo.setHLS(String.format("http://%s:%s/rtp/%s/hls.m3u8", mediaInfo.getLocalIP(), mediaInfo.getHttpPort(), streamId)); | ||
| 250 | - streamInfo.setRTSP(String.format("rtsp://%s:%s/rtp/%s", mediaInfo.getLocalIP(), mediaInfo.getRtspPort(), streamId)); | ||
| 251 | - | ||
| 252 | - storager.startPlay(device.getDeviceId(), channelId, streamInfo); | 245 | +// String streamId = String.format("%08x", Integer.parseInt(streamInfo.getSsrc())).toUpperCase(); // ZLM 要求大写且首位补零 |
| 246 | +// streamInfo.setFlv(String.format("http://%s:%s/rtp/%s.flv", mediaInfo.getLocalIP(), mediaInfo.getHttpPort(), streamId)); | ||
| 247 | +// streamInfo.setWS_FLV(String.format("ws://%s:%s/rtp/%s.flv", mediaInfo.getLocalIP(), mediaInfo.getHttpPort(), streamId)); | ||
| 248 | +// streamInfo.setRTMP(String.format("rtmp://%s:%s/rtp/%s", mediaInfo.getLocalIP(), mediaInfo.getRtmpPort(), streamId)); | ||
| 249 | +// streamInfo.setHLS(String.format("http://%s:%s/rtp/%s/hls.m3u8", mediaInfo.getLocalIP(), mediaInfo.getHttpPort(), streamId)); | ||
| 250 | +// streamInfo.setRTSP(String.format("rtsp://%s:%s/rtp/%s", mediaInfo.getLocalIP(), mediaInfo.getRtspPort(), streamId)); | ||
| 251 | + streamInfo.setCahnnelId(channelId); | ||
| 252 | + streamInfo.setDeviceID(device.getDeviceId()); | ||
| 253 | + storager.startPlay(streamInfo); | ||
| 253 | return streamInfo; | 254 | return streamInfo; |
| 254 | } catch ( SipException | ParseException | InvalidArgumentException e) { | 255 | } catch ( SipException | ParseException | InvalidArgumentException e) { |
| 255 | e.printStackTrace(); | 256 | e.printStackTrace(); |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java
| @@ -210,8 +210,11 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor { | @@ -210,8 +210,11 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor { | ||
| 210 | msg.setType(DeferredResultHolder.CALLBACK_CMD_CATALOG); | 210 | msg.setType(DeferredResultHolder.CALLBACK_CMD_CATALOG); |
| 211 | msg.setData(device); | 211 | msg.setData(device); |
| 212 | deferredResultHolder.invokeResult(msg); | 212 | deferredResultHolder.invokeResult(msg); |
| 213 | + | ||
| 214 | + // 回复200 | ||
| 215 | + responseAck(evt); | ||
| 213 | } | 216 | } |
| 214 | - } catch (DocumentException e) { | 217 | + } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) { |
| 215 | e.printStackTrace(); | 218 | e.printStackTrace(); |
| 216 | } | 219 | } |
| 217 | } | 220 | } |
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
| 1 | package com.genersoft.iot.vmp.media.zlm; | 1 | package com.genersoft.iot.vmp.media.zlm; |
| 2 | 2 | ||
| 3 | import java.math.BigInteger; | 3 | import java.math.BigInteger; |
| 4 | +import java.text.DecimalFormat; | ||
| 4 | import java.util.ArrayList; | 5 | import java.util.ArrayList; |
| 5 | import java.util.List; | 6 | import java.util.List; |
| 6 | 7 | ||
| 7 | import com.alibaba.fastjson.JSON; | 8 | import com.alibaba.fastjson.JSON; |
| 8 | import com.alibaba.fastjson.JSONArray; | 9 | import com.alibaba.fastjson.JSONArray; |
| 10 | +import com.genersoft.iot.vmp.common.StreamInfo; | ||
| 9 | import com.genersoft.iot.vmp.conf.MediaServerConfig; | 11 | import com.genersoft.iot.vmp.conf.MediaServerConfig; |
| 10 | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; | 12 | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
| 11 | import com.genersoft.iot.vmp.utils.IpUtil; | 13 | import com.genersoft.iot.vmp.utils.IpUtil; |
| @@ -35,7 +37,8 @@ import javax.servlet.http.HttpServletRequest; | @@ -35,7 +37,8 @@ import javax.servlet.http.HttpServletRequest; | ||
| 35 | public class ZLMHttpHookListener { | 37 | public class ZLMHttpHookListener { |
| 36 | 38 | ||
| 37 | private final static Logger logger = LoggerFactory.getLogger(ZLMHttpHookListener.class); | 39 | private final static Logger logger = LoggerFactory.getLogger(ZLMHttpHookListener.class); |
| 38 | - | 40 | + |
| 41 | + | ||
| 39 | @Autowired | 42 | @Autowired |
| 40 | private SIPCommander cmder; | 43 | private SIPCommander cmder; |
| 41 | 44 | ||
| @@ -54,7 +57,7 @@ public class ZLMHttpHookListener { | @@ -54,7 +57,7 @@ public class ZLMHttpHookListener { | ||
| 54 | logger.debug("ZLM HOOK on_flow_report API调用,参数:" + json.toString()); | 57 | logger.debug("ZLM HOOK on_flow_report API调用,参数:" + json.toString()); |
| 55 | } | 58 | } |
| 56 | // TODO Auto-generated method stub | 59 | // TODO Auto-generated method stub |
| 57 | - | 60 | + |
| 58 | 61 | ||
| 59 | JSONObject ret = new JSONObject(); | 62 | JSONObject ret = new JSONObject(); |
| 60 | ret.put("code", 0); | 63 | ret.put("code", 0); |
| @@ -113,6 +116,21 @@ public class ZLMHttpHookListener { | @@ -113,6 +116,21 @@ public class ZLMHttpHookListener { | ||
| 113 | if (logger.isDebugEnabled()) { | 116 | if (logger.isDebugEnabled()) { |
| 114 | logger.debug("ZLM HOOK on_publish API调用,参数:" + json.toString()); | 117 | logger.debug("ZLM HOOK on_publish API调用,参数:" + json.toString()); |
| 115 | } | 118 | } |
| 119 | + String app = json.getString("app"); | ||
| 120 | + String streamId = json.getString("id"); | ||
| 121 | +// String ssrc = String.format("%10d", Integer.parseInt(streamId, 16)); // ZLM 要求大写且首位补零 | ||
| 122 | + String ssrc = new DecimalFormat("0000000000").format(Integer.parseInt(streamId, 16)); | ||
| 123 | + StreamInfo streamInfo = storager.queryPlayBySSRC(ssrc); | ||
| 124 | + if ("rtp".equals(app) && streamInfo != null ) { | ||
| 125 | + MediaServerConfig mediaInfo = storager.getMediaInfo(); | ||
| 126 | + streamInfo.setFlv(String.format("http://%s:%s/rtp/%s.flv", mediaInfo.getLocalIP(), mediaInfo.getHttpPort(), streamId)); | ||
| 127 | + streamInfo.setWs_flv(String.format("ws://%s:%s/rtp/%s.flv", mediaInfo.getLocalIP(), mediaInfo.getHttpPort(), streamId)); | ||
| 128 | + streamInfo.setRtmp(String.format("rtmp://%s:%s/rtp/%s", mediaInfo.getLocalIP(), mediaInfo.getRtmpPort(), streamId)); | ||
| 129 | + streamInfo.setHls(String.format("http://%s:%s/rtp/%s/hls.m3u8", mediaInfo.getLocalIP(), mediaInfo.getHttpPort(), streamId)); | ||
| 130 | + streamInfo.setRtsp(String.format("rtsp://%s:%s/rtp/%s", mediaInfo.getLocalIP(), mediaInfo.getRtspPort(), streamId)); | ||
| 131 | + storager.startPlay(streamInfo); | ||
| 132 | + } | ||
| 133 | + | ||
| 116 | // TODO Auto-generated method stub | 134 | // TODO Auto-generated method stub |
| 117 | 135 | ||
| 118 | JSONObject ret = new JSONObject(); | 136 | JSONObject ret = new JSONObject(); |
| @@ -213,8 +231,18 @@ public class ZLMHttpHookListener { | @@ -213,8 +231,18 @@ public class ZLMHttpHookListener { | ||
| 213 | if (logger.isDebugEnabled()) { | 231 | if (logger.isDebugEnabled()) { |
| 214 | logger.debug("ZLM HOOK on_stream_changed API调用,参数:" + json.toString()); | 232 | logger.debug("ZLM HOOK on_stream_changed API调用,参数:" + json.toString()); |
| 215 | } | 233 | } |
| 216 | - // TODO Auto-generated method stub | ||
| 217 | - | 234 | + // 流消失移除redis play |
| 235 | + String app = json.getString("app"); | ||
| 236 | + String streamId = json.getString("stream"); | ||
| 237 | + boolean regist = json.getBoolean("regist"); | ||
| 238 | +// String ssrc = String.format("%10d", Integer.parseInt(streamId, 16)); // ZLM 要求大写且首位补零 | ||
| 239 | + String ssrc = new DecimalFormat("0000000000").format(Integer.parseInt(streamId, 16)); | ||
| 240 | + StreamInfo streamInfo = storager.queryPlayBySSRC(ssrc); | ||
| 241 | + if ("rtp".equals(app) && !regist ) { | ||
| 242 | + storager.stopPlay(streamInfo); | ||
| 243 | + } | ||
| 244 | + | ||
| 245 | + | ||
| 218 | JSONObject ret = new JSONObject(); | 246 | JSONObject ret = new JSONObject(); |
| 219 | ret.put("code", 0); | 247 | ret.put("code", 0); |
| 220 | ret.put("msg", "success"); | 248 | ret.put("msg", "success"); |
src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java
| @@ -136,30 +136,24 @@ public interface IVideoManagerStorager { | @@ -136,30 +136,24 @@ public interface IVideoManagerStorager { | ||
| 136 | /** | 136 | /** |
| 137 | * 开始播放时将流存入 | 137 | * 开始播放时将流存入 |
| 138 | * | 138 | * |
| 139 | - * @param deviceId 设备ID | ||
| 140 | - * @param channelId 通道ID | ||
| 141 | * @param stream 流信息 | 139 | * @param stream 流信息 |
| 142 | * @return | 140 | * @return |
| 143 | */ | 141 | */ |
| 144 | - public boolean startPlay(String deviceId, String channelId, StreamInfo stream); | 142 | + public boolean startPlay(StreamInfo stream); |
| 145 | 143 | ||
| 146 | /** | 144 | /** |
| 147 | * 停止播放时删除 | 145 | * 停止播放时删除 |
| 148 | * | 146 | * |
| 149 | - * @param deviceId 设备ID | ||
| 150 | - * @param channelId 通道ID | ||
| 151 | * @return | 147 | * @return |
| 152 | */ | 148 | */ |
| 153 | - public boolean stopPlay(String deviceId, String channelId); | 149 | + public boolean stopPlay(StreamInfo streamInfo); |
| 154 | 150 | ||
| 155 | /** | 151 | /** |
| 156 | * 查找视频流 | 152 | * 查找视频流 |
| 157 | * | 153 | * |
| 158 | - * @param deviceId 设备ID | ||
| 159 | - * @param channelId 通道ID | ||
| 160 | * @return | 154 | * @return |
| 161 | */ | 155 | */ |
| 162 | - public StreamInfo queryPlay(String deviceId, String channelId); | 156 | + public StreamInfo queryPlay(StreamInfo streamInfo); |
| 163 | 157 | ||
| 164 | /** | 158 | /** |
| 165 | * 查询子设备 | 159 | * 查询子设备 |
| @@ -182,4 +176,8 @@ public interface IVideoManagerStorager { | @@ -182,4 +176,8 @@ public interface IVideoManagerStorager { | ||
| 182 | * @param deviceId | 176 | * @param deviceId |
| 183 | */ | 177 | */ |
| 184 | void cleanChannelsForDevice(String deviceId); | 178 | void cleanChannelsForDevice(String deviceId); |
| 179 | + | ||
| 180 | + StreamInfo queryPlayBySSRC(String ssrc); | ||
| 181 | + | ||
| 182 | + StreamInfo queryPlayByDevice(String deviceId, String code); | ||
| 185 | } | 183 | } |
src/main/java/com/genersoft/iot/vmp/storager/jdbc/VideoManagerJdbcStoragerImpl.java
| @@ -148,17 +148,12 @@ public class VideoManagerJdbcStoragerImpl implements IVideoManagerStorager { | @@ -148,17 +148,12 @@ public class VideoManagerJdbcStoragerImpl implements IVideoManagerStorager { | ||
| 148 | } | 148 | } |
| 149 | 149 | ||
| 150 | @Override | 150 | @Override |
| 151 | - public boolean startPlay(String deviceId, String channelId, StreamInfo stream) { | 151 | + public boolean stopPlay(StreamInfo streamInfo) { |
| 152 | return false; | 152 | return false; |
| 153 | } | 153 | } |
| 154 | 154 | ||
| 155 | @Override | 155 | @Override |
| 156 | - public boolean stopPlay(String deviceId, String channelId) { | ||
| 157 | - return false; | ||
| 158 | - } | ||
| 159 | - | ||
| 160 | - @Override | ||
| 161 | - public StreamInfo queryPlay(String deviceId, String channelId) { | 156 | + public StreamInfo queryPlay(StreamInfo streamInfo) { |
| 162 | return null; | 157 | return null; |
| 163 | } | 158 | } |
| 164 | 159 | ||
| @@ -176,4 +171,19 @@ public class VideoManagerJdbcStoragerImpl implements IVideoManagerStorager { | @@ -176,4 +171,19 @@ public class VideoManagerJdbcStoragerImpl implements IVideoManagerStorager { | ||
| 176 | public void cleanChannelsForDevice(String deviceId) { | 171 | public void cleanChannelsForDevice(String deviceId) { |
| 177 | 172 | ||
| 178 | } | 173 | } |
| 174 | + | ||
| 175 | + @Override | ||
| 176 | + public boolean startPlay(StreamInfo stream) { | ||
| 177 | + return false; | ||
| 178 | + } | ||
| 179 | + | ||
| 180 | + @Override | ||
| 181 | + public StreamInfo queryPlayBySSRC(String ssrc) { | ||
| 182 | + return null; | ||
| 183 | + } | ||
| 184 | + | ||
| 185 | + @Override | ||
| 186 | + public StreamInfo queryPlayByDevice(String deviceId, String code) { | ||
| 187 | + return null; | ||
| 188 | + } | ||
| 179 | } | 189 | } |
src/main/java/com/genersoft/iot/vmp/storager/redis/VideoManagerRedisStoragerImpl.java
| @@ -329,40 +329,53 @@ public class VideoManagerRedisStoragerImpl implements IVideoManagerStorager { | @@ -329,40 +329,53 @@ public class VideoManagerRedisStoragerImpl implements IVideoManagerStorager { | ||
| 329 | /** | 329 | /** |
| 330 | * 开始播放时将流存入redis | 330 | * 开始播放时将流存入redis |
| 331 | * | 331 | * |
| 332 | - * @param deviceId 设备ID | ||
| 333 | - * @param channelId 通道ID | ||
| 334 | * @return | 332 | * @return |
| 335 | */ | 333 | */ |
| 336 | @Override | 334 | @Override |
| 337 | - public boolean startPlay(String deviceId, String channelId, StreamInfo stream) { | ||
| 338 | - return redis.set(String.format("%S_%s_%s", VideoManagerConstants.PLAYER_PREFIX, deviceId, channelId), | 335 | + public boolean startPlay(StreamInfo stream) { |
| 336 | + return redis.set(String.format("%S_%s_%s_%s", VideoManagerConstants.PLAYER_PREFIX, stream.getSsrc(),stream.getDeviceID(), stream.getCahnnelId()), | ||
| 339 | stream); | 337 | stream); |
| 340 | } | 338 | } |
| 341 | 339 | ||
| 342 | /** | 340 | /** |
| 343 | * 停止播放时从redis删除 | 341 | * 停止播放时从redis删除 |
| 344 | * | 342 | * |
| 345 | - * @param deviceId 设备ID | ||
| 346 | - * @param channelId 通道ID | ||
| 347 | * @return | 343 | * @return |
| 348 | */ | 344 | */ |
| 349 | @Override | 345 | @Override |
| 350 | - public boolean stopPlay(String deviceId, String channelId) { | ||
| 351 | - return redis.del(String.format("%S_%s_%s", VideoManagerConstants.PLAYER_PREFIX, deviceId, channelId)); | 346 | + public boolean stopPlay(StreamInfo streamInfo) { |
| 347 | + return redis.del(String.format("%S_%s_%s_%s", VideoManagerConstants.PLAYER_PREFIX, | ||
| 348 | + streamInfo.getSsrc(), | ||
| 349 | + streamInfo.getDeviceID(), | ||
| 350 | + streamInfo.getCahnnelId())); | ||
| 352 | } | 351 | } |
| 353 | 352 | ||
| 354 | /** | 353 | /** |
| 355 | * 查询播放列表 | 354 | * 查询播放列表 |
| 356 | - * @param deviceId 设备ID | ||
| 357 | - * @param channelId 通道ID | ||
| 358 | * @return | 355 | * @return |
| 359 | */ | 356 | */ |
| 360 | @Override | 357 | @Override |
| 361 | - public StreamInfo queryPlay(String deviceId, String channelId) { | ||
| 362 | - return (StreamInfo)redis.get(String.format("%S_%s_%s", VideoManagerConstants.PLAYER_PREFIX, deviceId, channelId)); | 358 | + public StreamInfo queryPlay(StreamInfo streamInfo) { |
| 359 | + return (StreamInfo)redis.get(String.format("%S_%s_%s_%s", | ||
| 360 | + VideoManagerConstants.PLAYER_PREFIX, | ||
| 361 | + streamInfo.getSsrc(), | ||
| 362 | + streamInfo.getDeviceID(), | ||
| 363 | + streamInfo.getCahnnelId())); | ||
| 364 | + } | ||
| 365 | + @Override | ||
| 366 | + public StreamInfo queryPlayBySSRC(String ssrc) { | ||
| 367 | + List<Object> playLeys = redis.keys(String.format("%S_%s_*", VideoManagerConstants.PLAYER_PREFIX, ssrc)); | ||
| 368 | + if (playLeys.size() == 0) return null; | ||
| 369 | + return (StreamInfo)redis.get(playLeys.get(0).toString()); | ||
| 363 | } | 370 | } |
| 364 | 371 | ||
| 365 | - | 372 | + @Override |
| 373 | + public StreamInfo queryPlayByDevice(String deviceId, String code) { | ||
| 374 | + List<Object> playLeys = redis.keys(String.format("%S_*_%s_%s", VideoManagerConstants.PLAYER_PREFIX, | ||
| 375 | + deviceId, | ||
| 376 | + code)); | ||
| 377 | + return (StreamInfo)redis.get(playLeys.get(0).toString()); | ||
| 378 | + } | ||
| 366 | 379 | ||
| 367 | /** | 380 | /** |
| 368 | * 更新流媒体信息 | 381 | * 更新流媒体信息 |
| @@ -423,4 +436,7 @@ public class VideoManagerRedisStoragerImpl implements IVideoManagerStorager { | @@ -423,4 +436,7 @@ public class VideoManagerRedisStoragerImpl implements IVideoManagerStorager { | ||
| 423 | } | 436 | } |
| 424 | } | 437 | } |
| 425 | } | 438 | } |
| 439 | + | ||
| 440 | + | ||
| 441 | + | ||
| 426 | } | 442 | } |
src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java
| @@ -37,7 +37,18 @@ public class PlayController { | @@ -37,7 +37,18 @@ public class PlayController { | ||
| 37 | 37 | ||
| 38 | Device device = storager.queryVideoDevice(deviceId); | 38 | Device device = storager.queryVideoDevice(deviceId); |
| 39 | StreamInfo streamInfo = cmder.playStreamCmd(device, channelId); | 39 | StreamInfo streamInfo = cmder.playStreamCmd(device, channelId); |
| 40 | - | 40 | + // 等待推流, TODO 默认超时15s |
| 41 | + | ||
| 42 | + long startTime = System.currentTimeMillis(); | ||
| 43 | + while (storager.queryPlay(streamInfo) == null || storager.queryPlay(streamInfo).getFlv() == null) { | ||
| 44 | + try { | ||
| 45 | + if (System.currentTimeMillis() - startTime > 15 * 1000) | ||
| 46 | + Thread.sleep(200); | ||
| 47 | + } catch (InterruptedException e) { | ||
| 48 | + e.printStackTrace(); | ||
| 49 | + } | ||
| 50 | + } | ||
| 51 | + streamInfo = storager.queryPlay(streamInfo); | ||
| 41 | if (logger.isDebugEnabled()) { | 52 | if (logger.isDebugEnabled()) { |
| 42 | logger.debug(String.format("设备预览 API调用,deviceId:%s ,channelId:%s",deviceId, channelId)); | 53 | logger.debug(String.format("设备预览 API调用,deviceId:%s ,channelId:%s",deviceId, channelId)); |
| 43 | logger.debug("设备预览 API调用,ssrc:"+streamInfo.getSsrc()+",ZLMedia streamId:"+Integer.toHexString(Integer.parseInt(streamInfo.getSsrc()))); | 54 | logger.debug("设备预览 API调用,ssrc:"+streamInfo.getSsrc()+",ZLMedia streamId:"+Integer.toHexString(Integer.parseInt(streamInfo.getSsrc()))); |
| @@ -55,7 +66,8 @@ public class PlayController { | @@ -55,7 +66,8 @@ public class PlayController { | ||
| 55 | public ResponseEntity<String> playStop(@PathVariable String ssrc){ | 66 | public ResponseEntity<String> playStop(@PathVariable String ssrc){ |
| 56 | 67 | ||
| 57 | cmder.streamByeCmd(ssrc); | 68 | cmder.streamByeCmd(ssrc); |
| 58 | - | 69 | + StreamInfo streamInfo = storager.queryPlayBySSRC(ssrc); |
| 70 | + storager.stopPlay(streamInfo); | ||
| 59 | if (logger.isDebugEnabled()) { | 71 | if (logger.isDebugEnabled()) { |
| 60 | logger.debug(String.format("设备预览停止API调用,ssrc:%s", ssrc)); | 72 | logger.debug(String.format("设备预览停止API调用,ssrc:%s", ssrc)); |
| 61 | } | 73 | } |
src/main/java/com/genersoft/iot/vmp/web/ApiStreamController.java
| @@ -70,7 +70,7 @@ public class ApiStreamController { | @@ -70,7 +70,7 @@ public class ApiStreamController { | ||
| 70 | return result; | 70 | return result; |
| 71 | } | 71 | } |
| 72 | // 查询是否已经在播放 | 72 | // 查询是否已经在播放 |
| 73 | - StreamInfo streamInfo = storager.queryPlay(device.getDeviceId(), code); | 73 | + StreamInfo streamInfo = storager.queryPlayByDevice(device.getDeviceId(), code); |
| 74 | if (streamInfo == null) streamInfo = cmder.playStreamCmd(device, code); | 74 | if (streamInfo == null) streamInfo = cmder.playStreamCmd(device, code); |
| 75 | 75 | ||
| 76 | if (logger.isDebugEnabled()) { | 76 | if (logger.isDebugEnabled()) { |
| @@ -86,10 +86,10 @@ public class ApiStreamController { | @@ -86,10 +86,10 @@ public class ApiStreamController { | ||
| 86 | result.put("ChannelName", deviceChannel.getName()); | 86 | result.put("ChannelName", deviceChannel.getName()); |
| 87 | result.put("ChannelCustomName ", ""); | 87 | result.put("ChannelCustomName ", ""); |
| 88 | result.put("FLV ", streamInfo.getFlv()); | 88 | result.put("FLV ", streamInfo.getFlv()); |
| 89 | - result.put("WS_FLV ", streamInfo.getWS_FLV()); | ||
| 90 | - result.put("RTMP", streamInfo.getRTMP()); | ||
| 91 | - result.put("HLS", streamInfo.getHLS()); | ||
| 92 | - result.put("RTSP", streamInfo.getRTSP()); | 89 | + result.put("WS_FLV ", streamInfo.getWs_flv()); |
| 90 | + result.put("RTMP", streamInfo.getRtmp()); | ||
| 91 | + result.put("HLS", streamInfo.getHls()); | ||
| 92 | + result.put("RTSP", streamInfo.getRtsp()); | ||
| 93 | result.put("CDN", ""); | 93 | result.put("CDN", ""); |
| 94 | result.put("SnapURL", ""); | 94 | result.put("SnapURL", ""); |
| 95 | result.put("Transport", device.getTransport()); | 95 | result.put("Transport", device.getTransport()); |
| @@ -135,14 +135,14 @@ public class ApiStreamController { | @@ -135,14 +135,14 @@ public class ApiStreamController { | ||
| 135 | @RequestParam(required = false)String check_outputs | 135 | @RequestParam(required = false)String check_outputs |
| 136 | 136 | ||
| 137 | ){ | 137 | ){ |
| 138 | - StreamInfo streamInfo = storager.queryPlay(serial, code); | 138 | + StreamInfo streamInfo = storager.queryPlayByDevice(serial, code); |
| 139 | if (streamInfo == null) { | 139 | if (streamInfo == null) { |
| 140 | JSONObject result = new JSONObject(); | 140 | JSONObject result = new JSONObject(); |
| 141 | result.put("error","未找到流信息"); | 141 | result.put("error","未找到流信息"); |
| 142 | return result; | 142 | return result; |
| 143 | } | 143 | } |
| 144 | cmder.streamByeCmd(streamInfo.getSsrc()); | 144 | cmder.streamByeCmd(streamInfo.getSsrc()); |
| 145 | - storager.stopPlay(serial, code); | 145 | + storager.stopPlay(streamInfo); |
| 146 | return null; | 146 | return null; |
| 147 | } | 147 | } |
| 148 | 148 | ||
| @@ -151,7 +151,6 @@ public class ApiStreamController { | @@ -151,7 +151,6 @@ public class ApiStreamController { | ||
| 151 | * @param serial 设备编号 | 151 | * @param serial 设备编号 |
| 152 | * @param channel 通道序号 | 152 | * @param channel 通道序号 |
| 153 | * @param code 通道国标编号 | 153 | * @param code 通道国标编号 |
| 154 | - * @param check_outputs | ||
| 155 | * @return | 154 | * @return |
| 156 | */ | 155 | */ |
| 157 | @RequestMapping(value = "/touch") | 156 | @RequestMapping(value = "/touch") |
web_src/src/components/channelList.vue
| @@ -35,8 +35,16 @@ | @@ -35,8 +35,16 @@ | ||
| 35 | </el-table-column> | 35 | </el-table-column> |
| 36 | <el-table-column prop="subCount" label="子节点数"> | 36 | <el-table-column prop="subCount" label="子节点数"> |
| 37 | </el-table-column> | 37 | </el-table-column> |
| 38 | - <el-table-column prop="ptztypeText" label="云台类型"> | ||
| 39 | - </el-table-column> | 38 | + <el-table-column label="状态" width="180" align="center"> |
| 39 | + <template slot-scope="scope"> | ||
| 40 | + <div slot="reference" class="name-wrapper"> | ||
| 41 | + <el-tag size="medium" v-if="scope.row.status == 1">在线</el-tag> | ||
| 42 | + <el-tag size="medium" type="info" v-if="scope.row.status == 0">离线</el-tag> | ||
| 43 | + </div> | ||
| 44 | + </template> | ||
| 45 | + </el-table-column> | ||
| 46 | + <el-table-column prop="ptztypeText" label="云台类型"> | ||
| 47 | + </el-table-column> | ||
| 40 | <el-table-column label="操作" width="240" align="center" fixed="right"> | 48 | <el-table-column label="操作" width="240" align="center" fixed="right"> |
| 41 | <template slot-scope="scope"> | 49 | <template slot-scope="scope"> |
| 42 | <el-button size="mini" icon="el-icon-video-play" v-if="scope.row.parental == 0" @click="sendDevicePush(scope.row)">预览视频</el-button> | 50 | <el-button size="mini" icon="el-icon-video-play" v-if="scope.row.parental == 0" @click="sendDevicePush(scope.row)">预览视频</el-button> |
| @@ -58,17 +66,20 @@ | @@ -58,17 +66,20 @@ | ||
| 58 | 66 | ||
| 59 | </el-main> | 67 | </el-main> |
| 60 | </el-container> | 68 | </el-container> |
| 69 | + <Loading v-if="isLoging" marginTop="-50%"></Loading> | ||
| 61 | </div> | 70 | </div> |
| 62 | </template> | 71 | </template> |
| 63 | 72 | ||
| 64 | <script> | 73 | <script> |
| 65 | import devicePlayer from './gb28181/devicePlayer.vue' | 74 | import devicePlayer from './gb28181/devicePlayer.vue' |
| 66 | import uiHeader from './UiHeader.vue' | 75 | import uiHeader from './UiHeader.vue' |
| 76 | + import Loading from './Loading.vue' | ||
| 67 | export default { | 77 | export default { |
| 68 | name: 'channelList', | 78 | name: 'channelList', |
| 69 | components: { | 79 | components: { |
| 70 | devicePlayer, | 80 | devicePlayer, |
| 71 | - uiHeader | 81 | + uiHeader, |
| 82 | + Loading | ||
| 72 | }, | 83 | }, |
| 73 | data() { | 84 | data() { |
| 74 | return { | 85 | return { |
| @@ -85,7 +96,8 @@ | @@ -85,7 +96,8 @@ | ||
| 85 | currentPage: parseInt(this.$route.params.page), | 96 | currentPage: parseInt(this.$route.params.page), |
| 86 | count: parseInt(this.$route.params.count), | 97 | count: parseInt(this.$route.params.count), |
| 87 | total:0, | 98 | total:0, |
| 88 | - beforeUrl:"/videoList" | 99 | + beforeUrl:"/videoList", |
| 100 | + isLoging: false | ||
| 89 | }; | 101 | }; |
| 90 | }, | 102 | }, |
| 91 | 103 | ||
| @@ -182,7 +194,7 @@ | @@ -182,7 +194,7 @@ | ||
| 182 | //通知设备上传媒体流 | 194 | //通知设备上传媒体流 |
| 183 | sendDevicePush: function(itemData) { | 195 | sendDevicePush: function(itemData) { |
| 184 | let deviceId = this.deviceId; | 196 | let deviceId = this.deviceId; |
| 185 | - | 197 | + this.isLoging = true; |
| 186 | let channelId = itemData.channelId; | 198 | let channelId = itemData.channelId; |
| 187 | console.log("通知设备推流1:" + deviceId + " : " + channelId); | 199 | console.log("通知设备推流1:" + deviceId + " : " + channelId); |
| 188 | let that = this; | 200 | let that = this; |
| @@ -191,6 +203,7 @@ | @@ -191,6 +203,7 @@ | ||
| 191 | url: '/api/play/' + deviceId + '/' + channelId | 203 | url: '/api/play/' + deviceId + '/' + channelId |
| 192 | }).then(function(res) { | 204 | }).then(function(res) { |
| 193 | let ssrc = res.data.ssrc; | 205 | let ssrc = res.data.ssrc; |
| 206 | + that.isLoging = false | ||
| 194 | that.$refs.devicePlayer.play(res.data,deviceId,channelId); | 207 | that.$refs.devicePlayer.play(res.data,deviceId,channelId); |
| 195 | }).catch(function(e) { | 208 | }).catch(function(e) { |
| 196 | }); | 209 | }); |
web_src/src/components/gb28181/devicePlayer.vue
web_src/src/components/videoList.vue
| 1 | <template> | 1 | <template> |
| 2 | <div id="app"> | 2 | <div id="app"> |
| 3 | <el-container> | 3 | <el-container> |
| 4 | - | ||
| 5 | <el-header> | 4 | <el-header> |
| 6 | <uiHeader></uiHeader> | 5 | <uiHeader></uiHeader> |
| 7 | </el-header> | 6 | </el-header> |
| @@ -37,14 +36,15 @@ | @@ -37,14 +36,15 @@ | ||
| 37 | <el-table-column label="状态" width="180" align="center"> | 36 | <el-table-column label="状态" width="180" align="center"> |
| 38 | <template slot-scope="scope"> | 37 | <template slot-scope="scope"> |
| 39 | <div slot="reference" class="name-wrapper"> | 38 | <div slot="reference" class="name-wrapper"> |
| 40 | - <el-tag size="medium">{{ scope.row.online==1?'在线' :'离线'}}</el-tag> | 39 | + <el-tag size="medium" v-if="scope.row.online == 1">在线</el-tag> |
| 40 | + <el-tag size="medium" type="info" v-if="scope.row.online == 0">离线</el-tag> | ||
| 41 | </div> | 41 | </div> |
| 42 | </template> | 42 | </template> |
| 43 | </el-table-column> | 43 | </el-table-column> |
| 44 | 44 | ||
| 45 | <el-table-column label="操作" width="240" align="center" fixed="right"> | 45 | <el-table-column label="操作" width="240" align="center" fixed="right"> |
| 46 | <template slot-scope="scope"> | 46 | <template slot-scope="scope"> |
| 47 | - <el-button size="mini" icon="el-icon-refresh" @click="refDevice(scope.row)">刷新</el-button> | 47 | + <el-button size="mini" icon="el-icon-refresh" @click="refDevice(scope.row)">刷新通道</el-button> |
| 48 | <el-button size="mini" icon="el-icon-s-open" type="primary" @click="showChannelList(scope.row)">查看通道</el-button> | 48 | <el-button size="mini" icon="el-icon-s-open" type="primary" @click="showChannelList(scope.row)">查看通道</el-button> |
| 49 | </template> | 49 | </template> |
| 50 | </el-table-column> | 50 | </el-table-column> |