Commit c1b3f2beb4b76e89d4938d2f7d5b31ff0f10220d

Authored by panlinlin
1 parent 9d19f6b9

国标级联--点播-未完成

src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java
@@ -10,6 +10,7 @@ import javax.sip.message.Request; @@ -10,6 +10,7 @@ import javax.sip.message.Request;
10 import javax.sip.message.Response; 10 import javax.sip.message.Response;
11 11
12 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; 12 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
  13 +import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
13 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 14 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
14 import com.alibaba.fastjson.JSON; 15 import com.alibaba.fastjson.JSON;
15 import com.genersoft.iot.vmp.gb28181.transmit.response.impl.*; 16 import com.genersoft.iot.vmp.gb28181.transmit.response.impl.*;
@@ -107,6 +108,9 @@ public class SIPProcessorFactory { @@ -107,6 +108,9 @@ public class SIPProcessorFactory {
107 @Autowired 108 @Autowired
108 private IPlayService playService; 109 private IPlayService playService;
109 110
  111 + @Autowired
  112 + private ZLMRTPServerFactory zlmrtpServerFactory;
  113 +
110 114
111 // 注:这里使用注解会导致循环依赖注入,暂用springBean 115 // 注:这里使用注解会导致循环依赖注入,暂用springBean
112 private SipProvider tcpSipProvider; 116 private SipProvider tcpSipProvider;
@@ -128,6 +132,7 @@ public class SIPProcessorFactory { @@ -128,6 +132,7 @@ public class SIPProcessorFactory {
128 processor.setCmderFroPlatform(cmderFroPlatform); 132 processor.setCmderFroPlatform(cmderFroPlatform);
129 processor.setPlayService(playService); 133 processor.setPlayService(playService);
130 processor.setStorager(storager); 134 processor.setStorager(storager);
  135 + processor.setZlmrtpServerFactory(zlmrtpServerFactory);
131 return processor; 136 return processor;
132 } else if (Request.REGISTER.equals(method)) { 137 } else if (Request.REGISTER.equals(method)) {
133 RegisterRequestProcessor processor = new RegisterRequestProcessor(); 138 RegisterRequestProcessor processor = new RegisterRequestProcessor();
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/InviteRequestProcessor.java
1 package com.genersoft.iot.vmp.gb28181.transmit.request.impl; 1 package com.genersoft.iot.vmp.gb28181.transmit.request.impl;
2 2
  3 +import javax.sdp.*;
3 import javax.sip.InvalidArgumentException; 4 import javax.sip.InvalidArgumentException;
4 import javax.sip.RequestEvent; 5 import javax.sip.RequestEvent;
5 import javax.sip.SipException; 6 import javax.sip.SipException;
@@ -11,20 +12,18 @@ import javax.sip.message.Request; @@ -11,20 +12,18 @@ import javax.sip.message.Request;
11 import javax.sip.message.Response; 12 import javax.sip.message.Response;
12 13
13 import com.alibaba.fastjson.JSONObject; 14 import com.alibaba.fastjson.JSONObject;
  15 +import com.genersoft.iot.vmp.conf.MediaServerConfig;
14 import com.genersoft.iot.vmp.gb28181.bean.Device; 16 import com.genersoft.iot.vmp.gb28181.bean.Device;
15 import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; 17 import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
16 -import com.genersoft.iot.vmp.gb28181.sdp.Codec;  
17 -import com.genersoft.iot.vmp.gb28181.sdp.MediaDescription;  
18 -import com.genersoft.iot.vmp.gb28181.sdp.SdpParser;  
19 -import com.genersoft.iot.vmp.gb28181.sdp.SessionDescription;  
20 -import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;  
21 -import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;  
22 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; 18 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
23 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; 19 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
24 import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor; 20 import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor;
  21 +import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
  22 +import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
25 import com.genersoft.iot.vmp.storager.IVideoManagerStorager; 23 import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
26 import com.genersoft.iot.vmp.vmanager.play.bean.PlayResult; 24 import com.genersoft.iot.vmp.vmanager.play.bean.PlayResult;
27 import com.genersoft.iot.vmp.vmanager.service.IPlayService; 25 import com.genersoft.iot.vmp.vmanager.service.IPlayService;
  26 +import gov.nist.javax.sdp.fields.SDPFormat;
28 import gov.nist.javax.sip.address.AddressImpl; 27 import gov.nist.javax.sip.address.AddressImpl;
29 import gov.nist.javax.sip.address.SipUri; 28 import gov.nist.javax.sip.address.SipUri;
30 import org.slf4j.Logger; 29 import org.slf4j.Logger;
@@ -34,6 +33,8 @@ import org.springframework.beans.factory.annotation.Autowired; @@ -34,6 +33,8 @@ import org.springframework.beans.factory.annotation.Autowired;
34 import java.io.IOException; 33 import java.io.IOException;
35 import java.text.ParseException; 34 import java.text.ParseException;
36 import java.util.List; 35 import java.util.List;
  36 +import java.util.UUID;
  37 +import java.util.Vector;
37 38
38 /** 39 /**
39 * @Description:处理INVITE请求 40 * @Description:处理INVITE请求
@@ -48,10 +49,22 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor { @@ -48,10 +49,22 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor {
48 49
49 private IVideoManagerStorager storager; 50 private IVideoManagerStorager storager;
50 51
  52 + private IRedisCatchStorage redisCatchStorage;
  53 +
51 private SIPCommander cmder; 54 private SIPCommander cmder;
52 55
53 private IPlayService playService; 56 private IPlayService playService;
54 57
  58 + private ZLMRTPServerFactory zlmrtpServerFactory;
  59 +
  60 + public ZLMRTPServerFactory getZlmrtpServerFactory() {
  61 + return zlmrtpServerFactory;
  62 + }
  63 +
  64 + public void setZlmrtpServerFactory(ZLMRTPServerFactory zlmrtpServerFactory) {
  65 + this.zlmrtpServerFactory = zlmrtpServerFactory;
  66 + }
  67 +
55 /** 68 /**
56 * 处理invite请求 69 * 处理invite请求
57 * 70 *
@@ -98,64 +111,105 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor { @@ -98,64 +111,105 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor {
98 }else { 111 }else {
99 response100Ack(evt); // 通道存在,发100,trying 112 response100Ack(evt); // 通道存在,发100,trying
100 } 113 }
101 - // 解析sdp消息  
102 - SessionDescription sdp = new SdpParser().parse(request.getRawContent()); 114 + // 解析sdp消息, 使用jainsip 自带的sdp解析方式
  115 + String contentString = new String(request.getRawContent());
  116 + SessionDescription sdp = SdpFactory.getInstance().createSessionDescription(contentString);
  117 +
  118 + // TODO 区分TCP发流还是udp, 当前默认udp
103 // 获取支持的格式 119 // 获取支持的格式
104 - List<MediaDescription> mediaDescriptions = sdp.getMediaDescriptions(); 120 + Vector mediaDescriptions = sdp.getMediaDescriptions(true);
105 // 查看是否支持PS 负载96 121 // 查看是否支持PS 负载96
106 String ip = null; 122 String ip = null;
107 int port = -1; 123 int port = -1;
108 - for (MediaDescription mediaDescription : mediaDescriptions) {  
109 -  
110 - List<Codec> codecs = mediaDescription.getCodecs();  
111 - for (Codec codec : codecs) {  
112 - if("96".equals(codec.getPayloadType()) || "PS".equals(codec.getName()) || "ps".equals(codec.getName())) {  
113 - ip = mediaDescription.getIpAddress().getHostName();  
114 - port = mediaDescription.getPort();  
115 - break;  
116 - }  
117 - }  
118 - }  
119 - if (ip == null || port == -1) { // TODO 没有合适的视频流格式, 可配置是否使用第一个media信息  
120 - if (mediaDescriptions.size() > 0) {  
121 - ip = mediaDescriptions.get(0).getIpAddress().getHostName();  
122 - port = mediaDescriptions.get(0).getPort();  
123 - } 124 + for (int i = 0; i < mediaDescriptions.size(); i++) {
  125 + MediaDescription mediaDescription = (MediaDescription)mediaDescriptions.get(i);
  126 + Media media = mediaDescription.getMedia();
  127 + port = media.getMediaPort();
124 } 128 }
125 -  
126 - if (ip == null || port == -1) {  
127 - response488Ack(evt);  
128 - return;  
129 - }  
130 -  
131 -  
132 - String ssrc = sdp.getSsrc();  
133 -  
134 - Device device = storager.queryVideoDeviceByPlatformIdAndChannelId(platformId, channelId);  
135 - if (device == null) {  
136 - logger.warn("点播平台{}的通道{}时未找到设备信息", platformId, channel);  
137 - response500Ack(evt);  
138 - return;  
139 - }  
140 -  
141 - // 通知下级推流,  
142 - PlayResult playResult = playService.play(device.getDeviceId(), channelId, (response)->{  
143 - // 收到推流, 回复200OK  
144 -  
145 - },(event -> {  
146 - // 未知错误。直接转发设备点播的错误  
147 - Response response = null;  
148 - try {  
149 - response = getMessageFactory().createResponse(event.getResponse().getStatusCode(), evt.getRequest());  
150 - getServerTransaction(evt).sendResponse(response);  
151 -  
152 - } catch (ParseException | SipException | InvalidArgumentException e) {  
153 - e.printStackTrace();  
154 - }  
155 - }));  
156 - playResult.getResult(); 129 +// for (MediaDescription mediaDescription : mediaDescriptions) {
  130 +//
  131 +// List<Codec> codecs = mediaDescription.getCodecs();
  132 +// for (Codec codec : codecs) {
  133 +// if("96".equals(codec.getPayloadType()) || "PS".equals(codec.getName()) || "ps".equals(codec.getName())) {
  134 +// // TODO 这里很慢
  135 +// ip = mediaDescription.getIpAddress().getHostName();
  136 +// port = mediaDescription.getPort();
  137 +// break;
  138 +// }
  139 +// }
  140 +// }
  141 +// if (ip == null || port == -1) { // TODO 没有合适的视频流格式, 可配置是否使用第一个media信息
  142 +// if (mediaDescriptions.size() > 0) {
  143 +// ip = mediaDescriptions.get(0).getIpAddress().getHostName();
  144 +// port = mediaDescriptions.get(0).getPort();
  145 +// }
  146 +// }
  147 +//
  148 +// if (ip == null || port == -1) {
  149 +// response488Ack(evt);
  150 +// return;
  151 +// }
  152 +//
  153 +//
  154 +// String ssrc = sdp.getSsrc();
  155 +//
  156 +// Device device = storager.queryVideoDeviceByPlatformIdAndChannelId(platformId, channelId);
  157 +// if (device == null) {
  158 +// logger.warn("点播平台{}的通道{}时未找到设备信息", platformId, channel);
  159 +// response500Ack(evt);
  160 +// return;
  161 +// }
  162 +//
  163 +// // 通知下级推流,
  164 +// PlayResult playResult = playService.play(device.getDeviceId(), channelId, (responseJSON)->{
  165 +// // 收到推流, 回复200OK
  166 +// UUID uuid = UUID.randomUUID();
  167 +// int rtpServer = zlmrtpServerFactory.createRTPServer(uuid.toString());
  168 +// if (rtpServer == -1) {
  169 +// logger.error("为获取到可用端口");
  170 +// return;
  171 +// }else {
  172 +// zlmrtpServerFactory.closeRTPServer(uuid.toString());
  173 +// }
  174 +// // TODO 添加对tcp的支持
  175 +// MediaServerConfig mediaInfo = redisCatchStorage.getMediaInfo();
  176 +// StringBuffer content = new StringBuffer(200);
  177 +// content.append("v=0\r\n");
  178 +// content.append("o="+"00000"+" 0 0 IN IP4 "+mediaInfo.getWanIp()+"\r\n");
  179 +// content.append("s=Play\r\n");
  180 +// content.append("c=IN IP4 "+mediaInfo.getWanIp()+"\r\n");
  181 +// content.append("t=0 0\r\n");
  182 +// content.append("m=video "+ rtpServer+" RTP/AVP 96\r\n");
  183 +// content.append("a=sendonly\r\n");
  184 +// content.append("a=rtpmap:96 PS/90000\r\n");
  185 +// content.append("y="+ ssrc + "\r\n");
  186 +// content.append("f=\r\n");
  187 +//
  188 +// try {
  189 +// responseAck(evt, content.toString());
  190 +// } catch (SipException e) {
  191 +// e.printStackTrace();
  192 +// } catch (InvalidArgumentException e) {
  193 +// e.printStackTrace();
  194 +// } catch (ParseException e) {
  195 +// e.printStackTrace();
  196 +// }
  197 +//
  198 +// // 写入redis, 超时时回复
  199 +//// redisCatchStorage.waiteAck()
  200 +// },(event -> {
  201 +// // 未知错误。直接转发设备点播的错误
  202 +// Response response = null;
  203 +// try {
  204 +// response = getMessageFactory().createResponse(event.getResponse().getStatusCode(), evt.getRequest());
  205 +// getServerTransaction(evt).sendResponse(response);
  206 +//
  207 +// } catch (ParseException | SipException | InvalidArgumentException e) {
  208 +// e.printStackTrace();
  209 +// }
  210 +// }));
  211 +// playResult.getResult();
157 // 查找合适的端口推流, 212 // 查找合适的端口推流,
158 - // 发送 200ok  
159 // 收到ack后调用推流接口 213 // 收到ack后调用推流接口
160 214
161 215
@@ -163,9 +217,12 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor { @@ -163,9 +217,12 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor {
163 217
164 } catch (SipException | InvalidArgumentException | ParseException e) { 218 } catch (SipException | InvalidArgumentException | ParseException e) {
165 e.printStackTrace(); 219 e.printStackTrace();
166 - } catch (IOException e) {  
167 logger.warn("sdp解析错误"); 220 logger.warn("sdp解析错误");
168 e.printStackTrace(); 221 e.printStackTrace();
  222 + } catch (SdpParseException e) {
  223 + e.printStackTrace();
  224 + } catch (SdpException e) {
  225 + e.printStackTrace();
169 } 226 }
170 227
171 } 228 }
src/main/java/com/genersoft/iot/vmp/storager/dao/PatformChannelMapper.java
1 package com.genersoft.iot.vmp.storager.dao; 1 package com.genersoft.iot.vmp.storager.dao;
2 2
  3 +import com.genersoft.iot.vmp.gb28181.bean.Device;
3 import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; 4 import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
4 import com.genersoft.iot.vmp.vmanager.platform.bean.ChannelReduce; 5 import com.genersoft.iot.vmp.vmanager.platform.bean.ChannelReduce;
5 import org.apache.ibatis.annotations.Delete; 6 import org.apache.ibatis.annotations.Delete;
@@ -45,4 +46,7 @@ public interface PatformChannelMapper { @@ -45,4 +46,7 @@ public interface PatformChannelMapper {
45 @Select("SELECT * FROM device_channel WHERE deviceId = (SELECT deviceId FROM platform_gb_channel WHERE " + 46 @Select("SELECT * FROM device_channel WHERE deviceId = (SELECT deviceId FROM platform_gb_channel WHERE " +
46 "platformId='${platformId}' AND channelId='${channelId}' ) AND channelId='${channelId}'") 47 "platformId='${platformId}' AND channelId='${channelId}' ) AND channelId='${channelId}'")
47 DeviceChannel queryChannelInParentPlatform(String platformId, String channelId); 48 DeviceChannel queryChannelInParentPlatform(String platformId, String channelId);
  49 +
  50 + @Select("SELECT * FROM device WHERE deviceId = (SELECT deviceId FROM platform_gb_channel WHERE platformId='${platformId}' AND channelId='${channelId}')")
  51 + Device queryVideoDeviceByPlatformIdAndChannelId(String platformId, String channelId);
48 } 52 }
src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java
@@ -338,6 +338,7 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager { @@ -338,6 +338,7 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
338 338
339 @Override 339 @Override
340 public Device queryVideoDeviceByPlatformIdAndChannelId(String platformId, String channelId) { 340 public Device queryVideoDeviceByPlatformIdAndChannelId(String platformId, String channelId) {
341 - return null; 341 + Device device = patformChannelMapper.queryVideoDeviceByPlatformIdAndChannelId(platformId, channelId);
  342 + return device;
342 } 343 }
343 } 344 }
web_src/.postcssrc.js
@@ -7,7 +7,7 @@ module.exports = { @@ -7,7 +7,7 @@ module.exports = {
7 // to edit target browsers: use "browserslist" field in package.json 7 // to edit target browsers: use "browserslist" field in package.json
8 "autoprefixer": {}, 8 "autoprefixer": {},
9 'postcss-pxtorem': { 9 'postcss-pxtorem': {
10 - rootValue: 24, 10 + rootValue: 16,
11 propList: ['font-size'] // 只转化font-size 11 propList: ['font-size'] // 只转化font-size
12 } 12 }
13 } 13 }