From b0080159d98cd441175ddaf90a77d30b8264003d Mon Sep 17 00:00:00 2001 From: panlinlin <648540858@qq.com> Date: Sat, 19 Dec 2020 21:52:20 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8E=BB=E9=99=A4ssrc=E4=BD=9C=E4=B8=BA?= =?UTF-8?q?=E6=B5=81ID=E4=BC=A0=E9=80=92=EF=BC=8Cssrc=E5=8F=AA=E4=BD=9C?= =?UTF-8?q?=E4=B8=BAsdp=E6=B6=88=E6=81=AF=E4=BD=BF=E7=94=A8=E3=80=82?= =?UTF-8?q?=E5=8A=A8=E6=80=81=E7=AB=AF=E5=8F=A3=E7=9A=84=E6=83=85=E5=86=B5?= =?UTF-8?q?=E4=B8=8B=E6=94=AF=E6=8C=81=E5=9B=BA=E5=AE=9A=E6=B5=81=E5=9C=B0?= =?UTF-8?q?=E5=9D=80=EF=BC=8C=E5=90=8C=E6=97=B6=E6=94=AF=E6=8C=81=E6=9C=AA?= =?UTF-8?q?=E7=82=B9=E6=92=AD=E6=97=B6=E7=9B=B4=E6=8E=A5=E6=92=AD=E6=94=BE?= =?UTF-8?q?=E6=B5=81=E5=9C=B0=E5=9D=80=EF=BC=8C=E4=BB=A3=E7=A0=81=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E5=8F=91=E8=B5=B7=E7=82=B9=E6=92=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../genersoft/iot/vmp/common/StreamInfo.java | 9 --- .../iot/vmp/gb28181/bean/DeviceChannel.java | 18 ++--- .../transmit/cmd/impl/SIPCommander.java | 23 +++--- .../request/impl/MessageRequestProcessor.java | 2 +- .../vmp/media/zlm/ZLMHttpHookListener.java | 80 +++++++++---------- .../genersoft/iot/vmp/media/zlm/ZLMUtils.java | 6 +- .../vmp/storager/IVideoManagerStorager.java | 4 +- .../jdbc/VideoManagerJdbcStoragerImpl.java | 11 +-- .../redis/VideoManagerRedisStoragerImpl.java | 27 +++---- .../iot/vmp/vmanager/play/PlayController.java | 27 +++---- .../vmanager/playback/PlaybackController.java | 2 +- .../service/impl/PlayServiceImpl.java | 2 - .../iot/vmp/web/ApiDeviceController.java | 2 +- .../iot/vmp/web/ApiStreamController.java | 10 +-- src/main/resources/application-dev.yml | 2 + web_src/src/components/channelList.vue | 6 +- .../src/components/gb28181/devicePlayer.vue | 13 ++- 17 files changed, 117 insertions(+), 127 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java b/src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java index 53bda91a..0fb76b93 100644 --- a/src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java +++ b/src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java @@ -4,7 +4,6 @@ import com.alibaba.fastjson.JSONArray; public class StreamInfo { - private String ssrc; private String streamId; private String deviceID; private String cahnnelId; @@ -20,14 +19,6 @@ public class StreamInfo { private String rtsp; private JSONArray tracks; - public String getSsrc() { - return ssrc; - } - - public void setSsrc(String ssrc) { - this.ssrc = ssrc; - } - public String getDeviceID() { return deviceID; } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceChannel.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceChannel.java index 810feabd..19e9eda9 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceChannel.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceChannel.java @@ -141,7 +141,7 @@ public class DeviceChannel { /** * 流唯一编号,存在表示正在直播 */ - private String ssrc; + private String streamId; /** * 是否含有音频 @@ -379,14 +379,6 @@ public class DeviceChannel { this.subCount = subCount; } - public String getSsrc() { - return ssrc; - } - - public void setSsrc(String ssrc) { - this.ssrc = ssrc; - } - public boolean isHasAudio() { return hasAudio; } @@ -402,4 +394,12 @@ public class DeviceChannel { public void setPlay(boolean play) { this.play = play; } + + public String getStreamId() { + return streamId; + } + + public void setStreamId(String streamId) { + this.streamId = streamId; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java index 3d5aaccf..097d2b70 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java @@ -277,17 +277,22 @@ public class SIPCommander implements ISIPCommander { try { String ssrc = streamSession.createPlaySsrc(); + String streamId = null; + if (rtpEnable) { + streamId = String.format("gb_play_%s_%s", device.getDeviceId(), channelId); + }else { + streamId = String.format("%08x", Integer.parseInt(ssrc)).toUpperCase(); + } String streamMode = device.getStreamMode().toUpperCase(); MediaServerConfig mediaInfo = storager.getMediaInfo(); String mediaPort = null; // 使用动态udp端口 if (rtpEnable) { - mediaPort = zlmUtils.getNewRTPPort(ssrc) + ""; + mediaPort = zlmUtils.getNewRTPPort(streamId) + ""; }else { mediaPort = mediaInfo.getRtpProxyPort(); } - String streamId = String.format("%08x", Integer.parseInt(ssrc)).toUpperCase(); // 添加订阅 JSONObject subscribeKey = new JSONObject(); subscribeKey.put("app", "rtp"); @@ -330,10 +335,10 @@ public class SIPCommander implements ISIPCommander { Request request = headerProvider.createInviteRequest(device, channelId, content.toString(), null, "live", null, ssrc); ClientTransaction transaction = transmitRequest(device, request); - streamSession.put(ssrc, transaction); + streamSession.put(streamId, transaction); DeviceChannel deviceChannel = storager.queryChannel(device.getDeviceId(), channelId); if (deviceChannel != null) { - deviceChannel.setSsrc(ssrc); + deviceChannel.setStreamId(streamId); storager.updateChannel(device.getDeviceId(), deviceChannel); } @@ -378,7 +383,7 @@ public class SIPCommander implements ISIPCommander { String mediaPort = null; // 使用动态udp端口 if (rtpEnable) { - mediaPort = zlmUtils.getNewRTPPort(ssrc) + ""; + mediaPort = zlmUtils.getNewRTPPort(streamId) + ""; }else { mediaPort = mediaInfo.getRtpProxyPort(); } @@ -412,7 +417,7 @@ public class SIPCommander implements ISIPCommander { Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, "playback", null); ClientTransaction transaction = transmitRequest(device, request); - streamSession.put(ssrc, transaction); + streamSession.put(streamId, transaction); } catch ( SipException | ParseException | InvalidArgumentException e) { e.printStackTrace(); @@ -424,10 +429,10 @@ public class SIPCommander implements ISIPCommander { * */ @Override - public void streamByeCmd(String ssrc) { + public void streamByeCmd(String streamId) { try { - ClientTransaction transaction = streamSession.get(ssrc); + ClientTransaction transaction = streamSession.get(streamId); if (transaction == null) { return; } @@ -453,7 +458,7 @@ public class SIPCommander implements ISIPCommander { clientTransaction = udpSipProvider.getNewClientTransaction(byeRequest); } dialog.sendRequest(clientTransaction); - streamSession.remove(ssrc); + streamSession.remove(streamId); } catch (TransactionDoesNotExistException e) { e.printStackTrace(); } catch (SipException e) { diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java index c987f5ee..3c90e8ea 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java @@ -450,7 +450,7 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor { StreamInfo streamInfo = storager.queryPlaybackByDevice(deviceId, "*"); if (streamInfo != null) { storager.stopPlayback(streamInfo); - cmder.streamByeCmd(streamInfo.getSsrc()); + cmder.streamByeCmd(streamInfo.getStreamId()); } } } catch (ParseException | SipException | InvalidArgumentException | DocumentException e) { diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java index 99da6243..03031f04 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java @@ -4,13 +4,16 @@ import java.math.BigInteger; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.List; +import java.util.UUID; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.conf.MediaServerConfig; +import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.storager.IVideoManagerStorager; import com.genersoft.iot.vmp.utils.IpUtil; +import com.genersoft.iot.vmp.vmanager.service.IPlayService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -43,6 +46,9 @@ public class ZLMHttpHookListener { @Autowired private SIPCommander cmder; + @Autowired + private IPlayService playService; + @Autowired private IVideoManagerStorager storager; @@ -52,6 +58,9 @@ public class ZLMHttpHookListener { @Autowired private ZLMHttpHookSubscribe subscribe; + @Value("${media.autoApplyPlay}") + private boolean autoApplyPlay; + @Value("${media.ip}") private String mediaIp; @@ -135,34 +144,6 @@ public class ZLMHttpHookListener { ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_publish, json); if (subscribe != null) subscribe.response(json); -// if ("rtp".equals(app)) { -// String ssrc = new DecimalFormat("0000000000").format(Integer.parseInt(streamId, 16)); -// StreamInfo streamInfoForPlay = storager.queryPlayBySSRC(ssrc); -// if ("rtp".equals(app) && streamInfoForPlay != null ) { -// MediaServerConfig mediaInfo = storager.getMediaInfo(); -// streamInfoForPlay.setFlv(String.format("http://%s:%s/rtp/%s.flv", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), streamId)); -// streamInfoForPlay.setWs_flv(String.format("ws://%s:%s/rtp/%s.flv", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), streamId)); -// streamInfoForPlay.setFmp4(String.format("http://%s:%s/rtp/%s.live.mp4", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), streamId)); -// streamInfoForPlay.setWs_fmp4(String.format("ws://%s:%s/rtp/%s.live.mp4", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), streamId)); -// streamInfoForPlay.setRtmp(String.format("rtmp://%s:%s/rtp/%s", mediaInfo.getWanIp(), mediaInfo.getRtmpPort(), streamId)); -// streamInfoForPlay.setHls(String.format("http://%s:%s/rtp/%s/hls.m3u8", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), streamId)); -// streamInfoForPlay.setRtsp(String.format("rtsp://%s:%s/rtp/%s", mediaInfo.getWanIp(), mediaInfo.getRtspPort(), streamId)); -// storager.startPlay(streamInfoForPlay); -// } -// -// StreamInfo streamInfoForPlayBack = storager.queryPlaybackBySSRC(ssrc); -// if ("rtp".equals(app) && streamInfoForPlayBack != null ) { -// MediaServerConfig mediaInfo = storager.getMediaInfo(); -// streamInfoForPlayBack.setFlv(String.format("http://%s:%s/rtp/%s.flv", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), streamId)); -// streamInfoForPlayBack.setWs_flv(String.format("ws://%s:%s/rtp/%s.flv", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), streamId)); -// streamInfoForPlayBack.setFmp4(String.format("http://%s:%s/rtp/%s.live.mp4", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), streamId)); -// streamInfoForPlayBack.setWs_fmp4(String.format("ws://%s:%s/rtp/%s.live.mp4", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), streamId)); -// streamInfoForPlayBack.setRtmp(String.format("rtmp://%s:%s/rtp/%s", mediaInfo.getWanIp(), mediaInfo.getRtmpPort(), streamId)); -// streamInfoForPlayBack.setHls(String.format("http://%s:%s/rtp/%s/hls.m3u8", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), streamId)); -// streamInfoForPlayBack.setRtsp(String.format("rtsp://%s:%s/rtp/%s", mediaInfo.getWanIp(), mediaInfo.getRtspPort(), streamId)); -// storager.startPlayback(streamInfoForPlayBack); -// } -// } // TODO Auto-generated method stub @@ -268,14 +249,12 @@ public class ZLMHttpHookListener { String app = json.getString("app"); String streamId = json.getString("stream"); boolean regist = json.getBoolean("regist"); -// String ssrc = String.format("%10d", Integer.parseInt(streamId, 16)); // ZLM 要求大写且首位补零 - String ssrc = new DecimalFormat("0000000000").format(Integer.parseInt(streamId, 16)); - StreamInfo streamInfo = storager.queryPlayBySSRC(ssrc); + StreamInfo streamInfo = storager.queryPlayByStreamId(streamId); if ("rtp".equals(app) && !regist ) { if (streamInfo!=null){ storager.stopPlay(streamInfo); }else{ - streamInfo = storager.queryPlaybackBySSRC(ssrc); + streamInfo = storager.queryPlaybackByStreamId(streamId); storager.stopPlayback(streamInfo); } } @@ -299,16 +278,14 @@ public class ZLMHttpHookListener { logger.debug("ZLM HOOK on_stream_none_reader API调用,参数:" + json.toString()); } - BigInteger bigint=new BigInteger(json.getString("stream"), 16); - int numb=bigint.intValue(); - String ssrc = String.format("%010d", numb); - - cmder.streamByeCmd(ssrc); - StreamInfo streamInfo = storager.queryPlayBySSRC(ssrc); + String streamId = json.getString("stream"); + + cmder.streamByeCmd(streamId); + StreamInfo streamInfo = storager.queryPlayByStreamId(streamId); if (streamInfo!=null){ storager.stopPlay(streamInfo); }else{ - streamInfo = storager.queryPlaybackBySSRC(ssrc); + streamInfo = storager.queryPlaybackByStreamId(streamId); storager.stopPlayback(streamInfo); } @@ -330,7 +307,30 @@ public class ZLMHttpHookListener { logger.debug("ZLM HOOK on_stream_not_found API调用,参数:" + json.toString()); } // TODO Auto-generated method stub - + + if (autoApplyPlay) { + String app = json.getString("app"); + String streamId = json.getString("stream"); + if ("rtp".equals(app) && streamId.indexOf("gb_play") > -1) { + String[] s = streamId.split("_"); + if (s.length == 4) { + String deviceId = s[2]; + String channelId = s[3]; + Device device = storager.queryVideoDevice(deviceId); + if (device != null) { + UUID uuid = UUID.randomUUID(); + cmder.playStreamCmd(device, channelId, (JSONObject response) -> { + logger.info("收到订阅消息: " + response.toJSONString()); + playService.onPublishHandlerForPlay(response, deviceId, channelId, uuid.toString()); + }); + } + + } + + } + + } + JSONObject ret = new JSONObject(); ret.put("code", 0); ret.put("msg", "success"); diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMUtils.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMUtils.java index 8195b656..132e1e17 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMUtils.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMUtils.java @@ -21,8 +21,8 @@ public class ZLMUtils { private int currentPort = 0; - public int getNewRTPPort(String ssrc) { - String streamId = String.format("%08x", Integer.parseInt(ssrc)).toUpperCase(); + public int getNewRTPPort(String streamId) { +// String streamId = String.format("%08x", Integer.parseInt(ssrc)).toUpperCase(); Map param = new HashMap<>(); int newPort = getPortFromUdpPortRange(); param.put("port", newPort); @@ -32,7 +32,7 @@ public class ZLMUtils { if (jsonObject != null && jsonObject.getInteger("code") == 0) { return newPort; } else { - return getNewRTPPort(ssrc); + return getNewRTPPort(streamId); } } diff --git a/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java b/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java index fdf4bc33..f427e5e5 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java @@ -178,7 +178,7 @@ public interface IVideoManagerStorager { */ void cleanChannelsForDevice(String deviceId); - StreamInfo queryPlayBySSRC(String ssrc); + StreamInfo queryPlayByStreamId(String streamId); StreamInfo queryPlayByDevice(String deviceId, String code); @@ -190,5 +190,5 @@ public interface IVideoManagerStorager { StreamInfo queryPlaybackByDevice(String deviceId, String channelId); - StreamInfo queryPlaybackBySSRC(String ssrc); + StreamInfo queryPlaybackByStreamId(String streamId); } diff --git a/src/main/java/com/genersoft/iot/vmp/storager/jdbc/VideoManagerJdbcStoragerImpl.java b/src/main/java/com/genersoft/iot/vmp/storager/jdbc/VideoManagerJdbcStoragerImpl.java index 75b9c929..3302aa35 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/jdbc/VideoManagerJdbcStoragerImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/jdbc/VideoManagerJdbcStoragerImpl.java @@ -178,10 +178,6 @@ public class VideoManagerJdbcStoragerImpl implements IVideoManagerStorager { return false; } - @Override - public StreamInfo queryPlayBySSRC(String ssrc) { - return null; - } @Override public StreamInfo queryPlayByDevice(String deviceId, String code) { @@ -210,7 +206,12 @@ public class VideoManagerJdbcStoragerImpl implements IVideoManagerStorager { } @Override - public StreamInfo queryPlaybackBySSRC(String ssrc) { + public StreamInfo queryPlayByStreamId(String streamId) { + return null; + } + + @Override + public StreamInfo queryPlaybackByStreamId(String streamId) { return null; } } diff --git a/src/main/java/com/genersoft/iot/vmp/storager/redis/VideoManagerRedisStoragerImpl.java b/src/main/java/com/genersoft/iot/vmp/storager/redis/VideoManagerRedisStoragerImpl.java index fe7b8e68..00d41fc4 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/redis/VideoManagerRedisStoragerImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/redis/VideoManagerRedisStoragerImpl.java @@ -151,7 +151,6 @@ public class VideoManagerRedisStoragerImpl implements IVideoManagerStorager { "_" + queryOnline + // 搜索是否在线 "_" + queryHasSubChannel + // 搜索是否含有子节点 "_" + "*"; -// List deviceChannelList = redis.keys(queryStr); List deviceChannelList = redis.scan(queryStr); //对查询结果排序,避免出现通道排列顺序乱序的情况 Collections.sort(deviceChannelList,new Comparator(){ @@ -169,7 +168,7 @@ public class VideoManagerRedisStoragerImpl implements IVideoManagerStorager { DeviceChannel deviceChannel = (DeviceChannel)redis.get((String)deviceChannelList.get(i)); StreamInfo streamInfo = stringStreamInfoMap.get(deviceId + "_" + deviceChannel.getChannelId()); deviceChannel.setPlay(streamInfo != null); - if (streamInfo != null) deviceChannel.setSsrc(streamInfo.getSsrc()); + if (streamInfo != null) deviceChannel.setStreamId(streamInfo.getStreamId()); result.add(deviceChannel); } pageResult.setData(result); @@ -384,7 +383,7 @@ public class VideoManagerRedisStoragerImpl implements IVideoManagerStorager { */ @Override public boolean startPlay(StreamInfo stream) { - return redis.set(String.format("%S_%s_%s_%s", VideoManagerConstants.PLAYER_PREFIX, stream.getSsrc(),stream.getDeviceID(), stream.getCahnnelId()), + return redis.set(String.format("%S_%s_%s_%s", VideoManagerConstants.PLAYER_PREFIX, stream.getStreamId(),stream.getDeviceID(), stream.getCahnnelId()), stream); } @@ -398,12 +397,12 @@ public class VideoManagerRedisStoragerImpl implements IVideoManagerStorager { if (streamInfo == null) return false; DeviceChannel deviceChannel = queryChannel(streamInfo.getDeviceID(), streamInfo.getCahnnelId()); if (deviceChannel != null) { - deviceChannel.setSsrc(null); + deviceChannel.setStreamId(null); deviceChannel.setPlay(false); updateChannel(streamInfo.getDeviceID(), deviceChannel); } return redis.del(String.format("%S_%s_%s_%s", VideoManagerConstants.PLAYER_PREFIX, - streamInfo.getSsrc(), + streamInfo.getStreamId(), streamInfo.getDeviceID(), streamInfo.getCahnnelId())); } @@ -416,22 +415,20 @@ public class VideoManagerRedisStoragerImpl implements IVideoManagerStorager { public StreamInfo queryPlay(StreamInfo streamInfo) { return (StreamInfo)redis.get(String.format("%S_%s_%s_%s", VideoManagerConstants.PLAYER_PREFIX, - streamInfo.getSsrc(), + streamInfo.getStreamId(), streamInfo.getDeviceID(), streamInfo.getCahnnelId())); } @Override - public StreamInfo queryPlayBySSRC(String ssrc) { -// List playLeys = redis.keys(String.format("%S_%s_*", VideoManagerConstants.PLAYER_PREFIX, ssrc)); - List playLeys = redis.scan(String.format("%S_%s_*", VideoManagerConstants.PLAYER_PREFIX, ssrc)); + public StreamInfo queryPlayByStreamId(String steamId) { + List playLeys = redis.scan(String.format("%S_%s_*", VideoManagerConstants.PLAYER_PREFIX, steamId)); if (playLeys == null || playLeys.size() == 0) return null; return (StreamInfo)redis.get(playLeys.get(0).toString()); } @Override - public StreamInfo queryPlaybackBySSRC(String ssrc) { -// List playLeys = redis.keys(String.format("%S_%s_*", VideoManagerConstants.PLAYER_PREFIX, ssrc)); - List playLeys = redis.scan(String.format("%S_%s_*", VideoManagerConstants.PLAY_BLACK_PREFIX, ssrc)); + public StreamInfo queryPlaybackByStreamId(String steamId) { + List playLeys = redis.scan(String.format("%S_%s_*", VideoManagerConstants.PLAY_BLACK_PREFIX, steamId)); if (playLeys == null || playLeys.size() == 0) return null; return (StreamInfo)redis.get(playLeys.get(0).toString()); } @@ -526,7 +523,7 @@ public class VideoManagerRedisStoragerImpl implements IVideoManagerStorager { @Override public boolean startPlayback(StreamInfo stream) { - return redis.set(String.format("%S_%s_%s_%s", VideoManagerConstants.PLAY_BLACK_PREFIX, stream.getSsrc(),stream.getDeviceID(), stream.getCahnnelId()), + return redis.set(String.format("%S_%s_%s_%s", VideoManagerConstants.PLAY_BLACK_PREFIX, stream.getStreamId(),stream.getDeviceID(), stream.getCahnnelId()), stream); } @@ -536,12 +533,12 @@ public class VideoManagerRedisStoragerImpl implements IVideoManagerStorager { if (streamInfo == null) return false; DeviceChannel deviceChannel = queryChannel(streamInfo.getDeviceID(), streamInfo.getCahnnelId()); if (deviceChannel != null) { - deviceChannel.setSsrc(null); + deviceChannel.setStreamId(null); deviceChannel.setPlay(false); updateChannel(streamInfo.getDeviceID(), deviceChannel); } return redis.del(String.format("%S_%s_%s_%s", VideoManagerConstants.PLAY_BLACK_PREFIX, - streamInfo.getSsrc(), + streamInfo.getStreamId(), streamInfo.getDeviceID(), streamInfo.getCahnnelId())); } diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java index e741b5af..3da666aa 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java @@ -80,7 +80,7 @@ public class PlayController { playService.onPublishHandlerForPlay(response, deviceId, channelId, uuid.toString()); }); } else { - String streamId = String.format("%08x", Integer.parseInt(streamInfo.getSsrc())).toUpperCase(); + String streamId = streamInfo.getStreamId(); JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(streamId); if (rtpInfo.getBoolean("exist")) { RequestMessage msg = new RequestMessage(); @@ -99,21 +99,21 @@ public class PlayController { return result; } - @PostMapping("/play/{ssrc}/stop") - public ResponseEntity playStop(@PathVariable String ssrc) { + @PostMapping("/play/{streamId}/stop") + public ResponseEntity playStop(@PathVariable String streamId) { - cmder.streamByeCmd(ssrc); - StreamInfo streamInfo = storager.queryPlayBySSRC(ssrc); + cmder.streamByeCmd(streamId); + StreamInfo streamInfo = storager.queryPlayByStreamId(streamId); if (streamInfo == null) - return new ResponseEntity("ssrc not found", HttpStatus.OK); + return new ResponseEntity("streamId not found", HttpStatus.OK); storager.stopPlay(streamInfo); if (logger.isDebugEnabled()) { - logger.debug(String.format("设备预览停止API调用,ssrc:%s", ssrc)); + logger.debug(String.format("设备预览停止API调用,streamId:%s", streamId)); } - if (ssrc != null) { + if (streamId != null) { JSONObject json = new JSONObject(); - json.put("ssrc", ssrc); + json.put("streamId", streamId); return new ResponseEntity(json.toString(), HttpStatus.OK); } else { logger.warn("设备预览停止API调用失败!"); @@ -123,17 +123,16 @@ public class PlayController { /** * 将不是h264的视频通过ffmpeg 转码为h264 + aac - * @param ssrc + * @param streamId 流ID * @return */ - @PostMapping("/play/{ssrc}/convert") - public ResponseEntity playConvert(@PathVariable String ssrc) { - StreamInfo streamInfo = storager.queryPlayBySSRC(ssrc); + @PostMapping("/play/{streamId}/convert") + public ResponseEntity playConvert(@PathVariable String streamId) { + StreamInfo streamInfo = storager.queryPlayByStreamId(streamId); if (streamInfo == null) { logger.warn("视频转码API调用失败!, 视频流已经停止!"); return new ResponseEntity("未找到视频流信息, 视频流可能已经停止", HttpStatus.OK); } - String streamId = String.format("%08x", Integer.parseInt(ssrc)).toUpperCase(); JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(streamId); if (!rtpInfo.getBoolean("exist")) { logger.warn("视频转码API调用失败!, 视频流已停止推流!"); diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/playback/PlaybackController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/playback/PlaybackController.java index 2e32b1bb..5fbaabfe 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/playback/PlaybackController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/playback/PlaybackController.java @@ -72,7 +72,7 @@ public class PlaybackController { StreamInfo streamInfo = storager.queryPlaybackByDevice(deviceId, channelId); if (streamInfo != null) { // 停止之前的回放 - cmder.streamByeCmd(streamInfo.getSsrc()); + cmder.streamByeCmd(streamInfo.getStreamId()); } resultHolder.put(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid, result); cmder.playbackStreamCmd(device, channelId, startTime, endTime, (JSONObject response) -> { diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/service/impl/PlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/vmanager/service/impl/PlayServiceImpl.java index e9528d1d..2800882a 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/service/impl/PlayServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/service/impl/PlayServiceImpl.java @@ -61,9 +61,7 @@ public class PlayServiceImpl implements IPlayService { public StreamInfo onPublishHandler(JSONObject resonse, String deviceId, String channelId, String uuid) { String streamId = resonse.getString("id"); - String ssrc = new DecimalFormat("0000000000").format(Integer.parseInt(streamId, 16)); StreamInfo streamInfo = new StreamInfo(); - streamInfo.setSsrc(ssrc); streamInfo.setStreamId(streamId); streamInfo.setDeviceID(deviceId); streamInfo.setCahnnelId(channelId); diff --git a/src/main/java/com/genersoft/iot/vmp/web/ApiDeviceController.java b/src/main/java/com/genersoft/iot/vmp/web/ApiDeviceController.java index ce3b7ec8..fdb67781 100644 --- a/src/main/java/com/genersoft/iot/vmp/web/ApiDeviceController.java +++ b/src/main/java/com/genersoft/iot/vmp/web/ApiDeviceController.java @@ -159,7 +159,7 @@ public class ApiDeviceController { deviceJOSNChannel.put("PTZType ", deviceChannel.getPTZType()); // 云台类型, 0 - 未知, 1 - 球机, 2 - 半球, // 3 - 固定枪机, 4 - 遥控枪机 deviceJOSNChannel.put("CustomPTZType", ""); - deviceJOSNChannel.put("StreamID", deviceChannel.getSsrc()); // StreamID 直播流ID, 有值表示正在直播 + deviceJOSNChannel.put("StreamID", deviceChannel.getStreamId()); // StreamID 直播流ID, 有值表示正在直播 deviceJOSNChannel.put("NumOutputs ", -1); // 直播在线人数 channleJSONList.add(deviceJOSNChannel); } diff --git a/src/main/java/com/genersoft/iot/vmp/web/ApiStreamController.java b/src/main/java/com/genersoft/iot/vmp/web/ApiStreamController.java index 6180fbb6..b3fc2473 100644 --- a/src/main/java/com/genersoft/iot/vmp/web/ApiStreamController.java +++ b/src/main/java/com/genersoft/iot/vmp/web/ApiStreamController.java @@ -96,12 +96,12 @@ public class ApiStreamController { // streamInfo = cmder.playStreamCmd(device, code); }else { logger.debug("streamInfo 不等于null, 向流媒体查询是否正在推流"); - String streamId = String.format("%08x", Integer.parseInt(streamInfo.getSsrc())).toUpperCase(); + String streamId = streamInfo.getStreamId(); JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(streamId); if (rtpInfo.getBoolean("exist")) { logger.debug("向流媒体查询正在推流, 直接返回: " + streamInfo.getRtsp()); JSONObject result = new JSONObject(); - result.put("StreamID", streamInfo.getSsrc()); + result.put("StreamID", streamInfo.getStreamId()); result.put("DeviceID", device.getDeviceId()); result.put("ChannelID", code); result.put("ChannelName", deviceChannel.getName()); @@ -141,7 +141,7 @@ public class ApiStreamController { if (logger.isDebugEnabled()) { logger.debug(String.format("设备预览 API调用,deviceId:%s ,channelId:%s",serial, code)); - logger.debug("设备预览 API调用,ssrc:"+streamInfo.getSsrc()+",ZLMedia streamId:"+Integer.toHexString(Integer.parseInt(streamInfo.getSsrc()))); + logger.debug("设备预览 API调用,streamId:"+streamInfo.getStreamId()); } boolean lockFlag = true; long startTime = System.currentTimeMillis(); @@ -173,7 +173,7 @@ public class ApiStreamController { } if(streamInfo!=null) { JSONObject result = new JSONObject(); - result.put("StreamID", streamInfo.getSsrc()); + result.put("StreamID", streamInfo.getStreamId()); result.put("DeviceID", device.getDeviceId()); result.put("ChannelID", code); result.put("ChannelName", deviceChannel.getName()); @@ -234,7 +234,7 @@ public class ApiStreamController { result.put("error","未找到流信息"); return result; } - cmder.streamByeCmd(streamInfo.getSsrc()); + cmder.streamByeCmd(streamInfo.getStreamId()); storager.stopPlay(streamInfo); return null; } diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index b58c0636..868298a6 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -74,6 +74,8 @@ media: # 设为false可以获得更好的兼容性,保证返回后流就可以播放, # 设为true可以快速打开播放窗口,可以获得更好的体验 closeWaitRTPInfo: false + # [可选] 自动点播, 使用固定流地址进行播放时,如果未点播则自动进行点播 + autoApplyPlay: true # 启用udp多端口模式, 详细解释参考: https://github.com/xia-chu/ZLMediaKit/wiki/GB28181%E6%8E%A8%E6%B5%81 下的高阶使用 rtp: # [可选] 是否启用udp多端口模式, 开启后会在udpPortRange范围内选择端口用于媒体流传输 diff --git a/web_src/src/components/channelList.vue b/web_src/src/components/channelList.vue index 4c39a3f8..738012d2 100644 --- a/web_src/src/components/channelList.vue +++ b/web_src/src/components/channelList.vue @@ -187,9 +187,9 @@ export default { url: '/api/play/' + deviceId + '/' + channelId + '?getEncoding=' + getEncoding }).then(function (res) { console.log(res.data) - let ssrc = res.data.ssrc; + let streamId = res.data.streamId; that.isLoging = false; - if (!!ssrc) { + if (!!streamId) { // that.$refs.devicePlayer.play(res.data, deviceId, channelId, itemData.hasAudio); that.$refs.devicePlayer.openDialog("media", deviceId, channelId, { streamInfo: res.data, @@ -212,7 +212,7 @@ export default { var that = this; this.$axios({ method: 'post', - url: '/api/play/' + itemData.ssrc + '/stop' + url: '/api/play/' + itemData.streamId + '/stop' }).then(function (res) { console.log(JSON.stringify(res)); that.initData(); diff --git a/web_src/src/components/gb28181/devicePlayer.vue b/web_src/src/components/gb28181/devicePlayer.vue index 8442a82f..ed8464af 100644 --- a/web_src/src/components/gb28181/devicePlayer.vue +++ b/web_src/src/components/gb28181/devicePlayer.vue @@ -158,7 +158,6 @@ export default { searchHistoryResult: [] //媒体流历史记录搜索结果 }, showVideoDialog: false, - ssrc: '', streamId: '', convertKey: '', deviceId: '', @@ -210,7 +209,6 @@ export default { this.tabActiveName = tab; this.channelId = channelId; this.deviceId = deviceId; - this.ssrc = ""; this.streamId = ""; this.videoUrl = "" if (!!this.$refs.videoPlayer) { @@ -238,7 +236,6 @@ export default { this.hasaudio = hasAudio; this.isLoging = false; this.videoUrl = streamInfo.ws_flv; - this.ssrc = streamInfo.ssrc; this.streamId = streamInfo.streamId; this.playFromStreamInfo(false, streamInfo) }, @@ -248,7 +245,7 @@ export default { this.$refs.videoPlayer.pause() that.$axios({ method: 'post', - url: '/api/play/' + that.ssrc + '/convert' + url: '/api/play/' + that.streamId + '/convert' }).then(function (res) { if (res.data.code == 0) { that.convertKey = res.data.key; @@ -368,9 +365,9 @@ export default { }, playRecord: function (row) { let that = this; - if (that.ssrc != "") { + if (that.streamId != "") { that.stopPlayRecord(function () { - that.ssrc = "", + that.streamId = "", that.playRecord(row); }) } else { @@ -380,7 +377,7 @@ export default { row.endTime }).then(function (res) { var streamInfo = res.data; - that.ssrc = streamInfo.ssrc; + that.streamId = streamInfo.streamId; that.videoUrl = streamInfo.ws_flv; }); } @@ -390,7 +387,7 @@ export default { this.videoUrl = ''; this.$axios({ method: 'get', - url: '/api/playback/' + this.ssrc + '/stop' + url: '/api/playback/' + this.streamId + '/stop' }).then(function (res) { if (callback) callback() });