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 10 import javax.sip.message.Response;
11 11  
12 12 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
  13 +import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
13 14 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
14 15 import com.alibaba.fastjson.JSON;
15 16 import com.genersoft.iot.vmp.gb28181.transmit.response.impl.*;
... ... @@ -107,6 +108,9 @@ public class SIPProcessorFactory {
107 108 @Autowired
108 109 private IPlayService playService;
109 110  
  111 + @Autowired
  112 + private ZLMRTPServerFactory zlmrtpServerFactory;
  113 +
110 114  
111 115 // 注:这里使用注解会导致循环依赖注入,暂用springBean
112 116 private SipProvider tcpSipProvider;
... ... @@ -128,6 +132,7 @@ public class SIPProcessorFactory {
128 132 processor.setCmderFroPlatform(cmderFroPlatform);
129 133 processor.setPlayService(playService);
130 134 processor.setStorager(storager);
  135 + processor.setZlmrtpServerFactory(zlmrtpServerFactory);
131 136 return processor;
132 137 } else if (Request.REGISTER.equals(method)) {
133 138 RegisterRequestProcessor processor = new RegisterRequestProcessor();
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/InviteRequestProcessor.java
1 1 package com.genersoft.iot.vmp.gb28181.transmit.request.impl;
2 2  
  3 +import javax.sdp.*;
3 4 import javax.sip.InvalidArgumentException;
4 5 import javax.sip.RequestEvent;
5 6 import javax.sip.SipException;
... ... @@ -11,20 +12,18 @@ import javax.sip.message.Request;
11 12 import javax.sip.message.Response;
12 13  
13 14 import com.alibaba.fastjson.JSONObject;
  15 +import com.genersoft.iot.vmp.conf.MediaServerConfig;
14 16 import com.genersoft.iot.vmp.gb28181.bean.Device;
15 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 18 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
23 19 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
24 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 23 import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
26 24 import com.genersoft.iot.vmp.vmanager.play.bean.PlayResult;
27 25 import com.genersoft.iot.vmp.vmanager.service.IPlayService;
  26 +import gov.nist.javax.sdp.fields.SDPFormat;
28 27 import gov.nist.javax.sip.address.AddressImpl;
29 28 import gov.nist.javax.sip.address.SipUri;
30 29 import org.slf4j.Logger;
... ... @@ -34,6 +33,8 @@ import org.springframework.beans.factory.annotation.Autowired;
34 33 import java.io.IOException;
35 34 import java.text.ParseException;
36 35 import java.util.List;
  36 +import java.util.UUID;
  37 +import java.util.Vector;
37 38  
38 39 /**
39 40 * @Description:处理INVITE请求
... ... @@ -48,10 +49,22 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor {
48 49  
49 50 private IVideoManagerStorager storager;
50 51  
  52 + private IRedisCatchStorage redisCatchStorage;
  53 +
51 54 private SIPCommander cmder;
52 55  
53 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 69 * 处理invite请求
57 70 *
... ... @@ -98,64 +111,105 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor {
98 111 }else {
99 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 121 // 查看是否支持PS 负载96
106 122 String ip = null;
107 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 213 // 收到ack后调用推流接口
160 214  
161 215  
... ... @@ -163,9 +217,12 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor {
163 217  
164 218 } catch (SipException | InvalidArgumentException | ParseException e) {
165 219 e.printStackTrace();
166   - } catch (IOException e) {
167 220 logger.warn("sdp解析错误");
168 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 1 package com.genersoft.iot.vmp.storager.dao;
2 2  
  3 +import com.genersoft.iot.vmp.gb28181.bean.Device;
3 4 import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
4 5 import com.genersoft.iot.vmp.vmanager.platform.bean.ChannelReduce;
5 6 import org.apache.ibatis.annotations.Delete;
... ... @@ -45,4 +46,7 @@ public interface PatformChannelMapper {
45 46 @Select("SELECT * FROM device_channel WHERE deviceId = (SELECT deviceId FROM platform_gb_channel WHERE " +
46 47 "platformId='${platformId}' AND channelId='${channelId}' ) AND channelId='${channelId}'")
47 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 338  
339 339 @Override
340 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 // to edit target browsers: use "browserslist" field in package.json
8 8 "autoprefixer": {},
9 9 'postcss-pxtorem': {
10   - rootValue: 24,
  10 + rootValue: 16,
11 11 propList: ['font-size'] // 只转化font-size
12 12 }
13 13 }
... ...