
34 changed files with 4400 additions and 3707 deletions
@ -1,225 +1,220 @@ |
|||
<?xml version="1.0"?> |
|||
<project |
|||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" |
|||
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> |
|||
<modelVersion>4.0.0</modelVersion> |
|||
<parent> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-starter-parent</artifactId> |
|||
<version>2.3.5.RELEASE</version> |
|||
</parent> |
|||
|
|||
<groupId>com.genersoft</groupId> |
|||
<artifactId>wvp</artifactId> |
|||
<name>web video platform</name> |
|||
|
|||
<properties> |
|||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
|||
<!-- 依赖版本 --> |
|||
<mybatis-spring-boot-starter-version>2.1.4</mybatis-spring-boot-starter-version> |
|||
<druid-version>1.2.3</druid-version> |
|||
<mysql-connector-java-version>8.0.22</mysql-connector-java-version> |
|||
<sqlite-jdbc-version>3.32.3.2</sqlite-jdbc-version> |
|||
<jedis-version>3.1.0</jedis-version> |
|||
<pagehelper-spring-boot-starter-version>1.2.10</pagehelper-spring-boot-starter-version> |
|||
<springfox-swagger2-version>2.9.2</springfox-swagger2-version> |
|||
<springfox-swagger-ui-version>2.6.1</springfox-swagger-ui-version> |
|||
<jain-sip-ri-version>1.3.0-91</jain-sip-ri-version> |
|||
<log4j-version>1.2.17</log4j-version> |
|||
<dom4j-version>2.1.3</dom4j-version> |
|||
<fastjson-version>1.2.73</fastjson-version> |
|||
<guava-version>30.0-jre</guava-version> |
|||
<lombok-version>1.18.12</lombok-version> |
|||
<commons-lang3-version>3.7</commons-lang3-version> |
|||
<commons-io-version>2.6</commons-io-version> |
|||
<okhttp-version>4.9.0</okhttp-version> |
|||
|
|||
<snippetsDirectory>${project.build.directory}/generated-snippets</snippetsDirectory> |
|||
<asciidoctor.input.directory>${project.basedir}/docs/asciidoc</asciidoctor.input.directory> |
|||
<generated.asciidoc.directory>${project.build.directory}/asciidoc</generated.asciidoc.directory> |
|||
<asciidoctor.html.output.directory>${project.build.directory}/asciidoc/html</asciidoctor.html.output.directory> |
|||
<asciidoctor.pdf.output.directory>${project.build.directory}/asciidoc/pdf</asciidoctor.pdf.output.directory> |
|||
</properties> |
|||
|
|||
<repositories> |
|||
<repository> |
|||
<id>nexus-aliyun</id> |
|||
<name>Nexus aliyun</name> |
|||
<url>https://maven.aliyun.com/repository/public</url> |
|||
<layout>default</layout> |
|||
<snapshots> |
|||
<enabled>false</enabled> |
|||
</snapshots> |
|||
<releases> |
|||
<enabled>true</enabled> |
|||
</releases> |
|||
</repository> |
|||
</repositories> |
|||
<pluginRepositories> |
|||
<pluginRepository> |
|||
<id>nexus-aliyun</id> |
|||
<name>Nexus aliyun</name> |
|||
<url>https://maven.aliyun.com/repository/public</url> |
|||
<snapshots> |
|||
<enabled>false</enabled> |
|||
</snapshots> |
|||
<releases> |
|||
<enabled>true</enabled> |
|||
</releases> |
|||
</pluginRepository> |
|||
</pluginRepositories> |
|||
|
|||
|
|||
<dependencies> |
|||
<dependency> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-starter-data-redis</artifactId> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-starter-web</artifactId> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.mybatis.spring.boot</groupId> |
|||
<artifactId>mybatis-spring-boot-starter</artifactId> |
|||
<version>${mybatis-spring-boot-starter-version}</version> |
|||
</dependency> |
|||
|
|||
<!-- druid数据库连接池 --> |
|||
<dependency> |
|||
<groupId>com.alibaba</groupId> |
|||
<artifactId>druid</artifactId> |
|||
<version>${druid-version}</version> |
|||
</dependency> |
|||
|
|||
<!-- mysql数据库 --> |
|||
<dependency> |
|||
<groupId>mysql</groupId> |
|||
<artifactId>mysql-connector-java</artifactId> |
|||
<version>${mysql-connector-java-version}</version> |
|||
</dependency> |
|||
|
|||
<!-- 添加sqlite-jdbc数据库驱动 --> |
|||
<dependency> |
|||
<groupId>org.xerial</groupId> |
|||
<artifactId>sqlite-jdbc</artifactId> |
|||
<version>${sqlite-jdbc-version}</version> |
|||
</dependency> |
|||
|
|||
<!--Mybatis分页插件 --> |
|||
<dependency> |
|||
<groupId>com.github.pagehelper</groupId> |
|||
<artifactId>pagehelper-spring-boot-starter</artifactId> |
|||
<version>${pagehelper-spring-boot-starter-version}</version> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>redis.clients</groupId> |
|||
<artifactId>jedis</artifactId> |
|||
<version>${jedis-version}</version> |
|||
</dependency> |
|||
|
|||
<!--Swagger2 --> |
|||
<!--在线文档 --> |
|||
<dependency> |
|||
<groupId>io.springfox</groupId> |
|||
<artifactId>springfox-swagger2</artifactId> |
|||
<version>${springfox-swagger2-version}</version> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>io.springfox</groupId> |
|||
<artifactId>springfox-swagger-ui</artifactId> |
|||
<version>${springfox-swagger-ui-version}</version> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>javax.validation</groupId> |
|||
<artifactId>validation-api</artifactId> |
|||
</dependency> |
|||
|
|||
<!-- 日志相关 --> |
|||
<dependency> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-starter-aop</artifactId> |
|||
</dependency> |
|||
|
|||
<!-- sip协议栈 --> |
|||
<dependency> |
|||
<groupId>javax.sip</groupId> |
|||
<artifactId>jain-sip-ri</artifactId> |
|||
<version>${jain-sip-ri-version}</version> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>log4j</groupId> |
|||
<artifactId>log4j</artifactId> |
|||
<version>${log4j-version}</version> |
|||
</dependency> |
|||
|
|||
<!-- xml解析库 --> |
|||
<dependency> |
|||
<groupId>org.dom4j</groupId> |
|||
<artifactId>dom4j</artifactId> |
|||
<version>${dom4j-version}</version> |
|||
</dependency> |
|||
|
|||
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson --> |
|||
<dependency> |
|||
<groupId>com.alibaba</groupId> |
|||
<artifactId>fastjson</artifactId> |
|||
<version>${fastjson-version}</version> |
|||
</dependency> |
|||
|
|||
<!--Guava是一种基于开源的Java库--> |
|||
<dependency> |
|||
<groupId>com.google.guava</groupId> |
|||
<artifactId>guava</artifactId> |
|||
<version>${guava-version}</version> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.projectlombok</groupId> |
|||
<artifactId>lombok</artifactId> |
|||
<version>${lombok-version}</version> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.apache.commons</groupId> |
|||
<artifactId>commons-lang3</artifactId> |
|||
<version>${commons-lang3-version}</version> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>commons-io</groupId> |
|||
<artifactId>commons-io</artifactId> |
|||
<version>${commons-io-version}</version> |
|||
</dependency> |
|||
|
|||
<!-- okhttp --> |
|||
<dependency> |
|||
<groupId>com.squareup.okhttp3</groupId> |
|||
<artifactId>okhttp</artifactId> |
|||
<version>${okhttp-version}</version> |
|||
</dependency> |
|||
<project |
|||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" |
|||
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> |
|||
<modelVersion>4.0.0</modelVersion> |
|||
<parent> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-starter-parent</artifactId> |
|||
<version>2.3.5.RELEASE</version> |
|||
</parent> |
|||
|
|||
<groupId>com.genersoft</groupId> |
|||
<artifactId>wvp</artifactId> |
|||
<name>web video platform</name> |
|||
|
|||
<properties> |
|||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
|||
<!-- 依赖版本 --> |
|||
<mybatis-spring-boot-starter-version>2.1.4</mybatis-spring-boot-starter-version> |
|||
<druid-version>1.2.3</druid-version> |
|||
<mysql-connector-java-version>8.0.22</mysql-connector-java-version> |
|||
<sqlite-jdbc-version>3.32.3.2</sqlite-jdbc-version> |
|||
<jedis-version>3.1.0</jedis-version> |
|||
<pagehelper-spring-boot-starter-version>1.2.10</pagehelper-spring-boot-starter-version> |
|||
<springfox-swagger2-version>2.9.2</springfox-swagger2-version> |
|||
<springfox-swagger-ui-version>2.6.1</springfox-swagger-ui-version> |
|||
<jain-sip-ri-version>1.3.0-91</jain-sip-ri-version> |
|||
<log4j-version>1.2.17</log4j-version> |
|||
<dom4j-version>2.1.3</dom4j-version> |
|||
<fastjson-version>1.2.73</fastjson-version> |
|||
<guava-version>30.0-jre</guava-version> |
|||
<lombok-version>1.18.12</lombok-version> |
|||
<commons-lang3-version>3.7</commons-lang3-version> |
|||
<commons-io-version>2.6</commons-io-version> |
|||
<okhttp-version>4.9.0</okhttp-version> |
|||
|
|||
<snippetsDirectory>${project.build.directory}/generated-snippets</snippetsDirectory> |
|||
<asciidoctor.input.directory>${project.basedir}/docs/asciidoc</asciidoctor.input.directory> |
|||
<generated.asciidoc.directory>${project.build.directory}/asciidoc</generated.asciidoc.directory> |
|||
<asciidoctor.html.output.directory>${project.build.directory}/asciidoc/html</asciidoctor.html.output.directory> |
|||
<asciidoctor.pdf.output.directory>${project.build.directory}/asciidoc/pdf</asciidoctor.pdf.output.directory> |
|||
</properties> |
|||
|
|||
<repositories> |
|||
<repository> |
|||
<id>nexus-aliyun</id> |
|||
<name>Nexus aliyun</name> |
|||
<url>https://maven.aliyun.com/repository/public</url> |
|||
<layout>default</layout> |
|||
<snapshots> |
|||
<enabled>false</enabled> |
|||
</snapshots> |
|||
<releases> |
|||
<enabled>true</enabled> |
|||
</releases> |
|||
</repository> |
|||
</repositories> |
|||
<pluginRepositories> |
|||
<pluginRepository> |
|||
<id>nexus-aliyun</id> |
|||
<name>Nexus aliyun</name> |
|||
<url>https://maven.aliyun.com/repository/public</url> |
|||
<snapshots> |
|||
<enabled>false</enabled> |
|||
</snapshots> |
|||
<releases> |
|||
<enabled>true</enabled> |
|||
</releases> |
|||
</pluginRepository> |
|||
</pluginRepositories> |
|||
|
|||
|
|||
<dependencies> |
|||
<dependency> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-starter-data-redis</artifactId> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-starter-web</artifactId> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.mybatis.spring.boot</groupId> |
|||
<artifactId>mybatis-spring-boot-starter</artifactId> |
|||
<version>${mybatis-spring-boot-starter-version}</version> |
|||
</dependency> |
|||
|
|||
<!-- druid数据库连接池 --> |
|||
<dependency> |
|||
<groupId>com.alibaba</groupId> |
|||
<artifactId>druid</artifactId> |
|||
<version>${druid-version}</version> |
|||
</dependency> |
|||
|
|||
<!-- mysql数据库 --> |
|||
<dependency> |
|||
<groupId>mysql</groupId> |
|||
<artifactId>mysql-connector-java</artifactId> |
|||
<version>${mysql-connector-java-version}</version> |
|||
</dependency> |
|||
|
|||
<!-- 添加sqlite-jdbc数据库驱动 --> |
|||
<dependency> |
|||
<groupId>org.xerial</groupId> |
|||
<artifactId>sqlite-jdbc</artifactId> |
|||
<version>${sqlite-jdbc-version}</version> |
|||
</dependency> |
|||
|
|||
<!--Mybatis分页插件 --> |
|||
<dependency> |
|||
<groupId>com.github.pagehelper</groupId> |
|||
<artifactId>pagehelper-spring-boot-starter</artifactId> |
|||
<version>${pagehelper-spring-boot-starter-version}</version> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>redis.clients</groupId> |
|||
<artifactId>jedis</artifactId> |
|||
<version>${jedis-version}</version> |
|||
</dependency> |
|||
|
|||
<!--Swagger2 --> |
|||
<!--在线文档 --> |
|||
<dependency> |
|||
<groupId>io.springfox</groupId> |
|||
<artifactId>springfox-swagger2</artifactId> |
|||
<version>${springfox-swagger2-version}</version> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>io.springfox</groupId> |
|||
<artifactId>springfox-swagger-ui</artifactId> |
|||
<version>${springfox-swagger-ui-version}</version> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>javax.validation</groupId> |
|||
<artifactId>validation-api</artifactId> |
|||
</dependency> |
|||
|
|||
<!-- 日志相关 --> |
|||
<dependency> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-starter-aop</artifactId> |
|||
</dependency> |
|||
|
|||
<!-- sip协议栈 --> |
|||
<dependency> |
|||
<groupId>javax.sip</groupId> |
|||
<artifactId>jain-sip-ri</artifactId> |
|||
<version>${jain-sip-ri-version}</version> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>log4j</groupId> |
|||
<artifactId>log4j</artifactId> |
|||
<version>${log4j-version}</version> |
|||
</dependency> |
|||
|
|||
<!-- xml解析库 --> |
|||
<dependency> |
|||
<groupId>org.dom4j</groupId> |
|||
<artifactId>dom4j</artifactId> |
|||
<version>${dom4j-version}</version> |
|||
</dependency> |
|||
|
|||
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson --> |
|||
<dependency> |
|||
<groupId>com.alibaba</groupId> |
|||
<artifactId>fastjson</artifactId> |
|||
<version>${fastjson-version}</version> |
|||
</dependency> |
|||
|
|||
<!--Guava是一种基于开源的Java库--> |
|||
<dependency> |
|||
<groupId>com.google.guava</groupId> |
|||
<artifactId>guava</artifactId> |
|||
<version>${guava-version}</version> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.apache.commons</groupId> |
|||
<artifactId>commons-lang3</artifactId> |
|||
<version>${commons-lang3-version}</version> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>commons-io</groupId> |
|||
<artifactId>commons-io</artifactId> |
|||
<version>${commons-io-version}</version> |
|||
</dependency> |
|||
|
|||
<!-- okhttp --> |
|||
<dependency> |
|||
<groupId>com.squareup.okhttp3</groupId> |
|||
<artifactId>okhttp</artifactId> |
|||
<version>${okhttp-version}</version> |
|||
</dependency> |
|||
</dependencies> |
|||
|
|||
<build> |
|||
<finalName>wvp-2.5.8</finalName> |
|||
<plugins> |
|||
<plugin> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-maven-plugin</artifactId> |
|||
</plugin> |
|||
<plugin> |
|||
<groupId>org.apache.maven.plugins</groupId> |
|||
<artifactId>maven-compiler-plugin</artifactId> |
|||
<configuration> |
|||
<source>1.8</source> |
|||
<target>1.8</target> |
|||
</configuration> |
|||
</plugin> |
|||
|
|||
<plugin> |
|||
<groupId>org.apache.maven.plugins</groupId> |
|||
<artifactId>maven-surefire-plugin</artifactId> |
|||
</plugin> |
|||
|
|||
</plugins> |
|||
</build> |
|||
|
|||
<build> |
|||
<finalName>wvp-2.5.8</finalName> |
|||
<plugins> |
|||
<plugin> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-maven-plugin</artifactId> |
|||
</plugin> |
|||
<plugin> |
|||
<groupId>org.apache.maven.plugins</groupId> |
|||
<artifactId>maven-compiler-plugin</artifactId> |
|||
<configuration> |
|||
<source>1.8</source> |
|||
<target>1.8</target> |
|||
</configuration> |
|||
</plugin> |
|||
|
|||
<plugin> |
|||
<groupId>org.apache.maven.plugins</groupId> |
|||
<artifactId>maven-surefire-plugin</artifactId> |
|||
</plugin> |
|||
|
|||
</plugins> |
|||
</build> |
|||
</project> |
|||
|
@ -1,231 +1,219 @@ |
|||
package com.genersoft.iot.vmp.gb28181.transmit; |
|||
|
|||
import javax.sip.RequestEvent; |
|||
import javax.sip.ResponseEvent; |
|||
import javax.sip.SipProvider; |
|||
import javax.sip.header.CSeqHeader; |
|||
import javax.sip.message.Request; |
|||
import javax.sip.message.Response; |
|||
|
|||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; |
|||
import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; |
|||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
|||
import com.genersoft.iot.vmp.gb28181.transmit.response.impl.*; |
|||
import com.genersoft.iot.vmp.vmanager.service.IPlayService; |
|||
// import org.slf4j.Logger;
|
|||
// import org.slf4j.LoggerFactory;
|
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.context.annotation.Lazy; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
import com.genersoft.iot.vmp.conf.SipConfig; |
|||
import com.genersoft.iot.vmp.gb28181.auth.RegisterLogicHandler; |
|||
import com.genersoft.iot.vmp.gb28181.event.DeviceOffLineDetector; |
|||
import com.genersoft.iot.vmp.gb28181.event.EventPublisher; |
|||
import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; |
|||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; |
|||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; |
|||
import com.genersoft.iot.vmp.gb28181.transmit.request.ISIPRequestProcessor; |
|||
import com.genersoft.iot.vmp.gb28181.transmit.request.impl.AckRequestProcessor; |
|||
import com.genersoft.iot.vmp.gb28181.transmit.request.impl.ByeRequestProcessor; |
|||
import com.genersoft.iot.vmp.gb28181.transmit.request.impl.CancelRequestProcessor; |
|||
import com.genersoft.iot.vmp.gb28181.transmit.request.impl.InviteRequestProcessor; |
|||
import com.genersoft.iot.vmp.gb28181.transmit.request.impl.MessageRequestProcessor; |
|||
import com.genersoft.iot.vmp.gb28181.transmit.request.impl.NotifyRequestProcessor; |
|||
import com.genersoft.iot.vmp.gb28181.transmit.request.impl.OtherRequestProcessor; |
|||
import com.genersoft.iot.vmp.gb28181.transmit.request.impl.RegisterRequestProcessor; |
|||
import com.genersoft.iot.vmp.gb28181.transmit.request.impl.SubscribeRequestProcessor; |
|||
import com.genersoft.iot.vmp.gb28181.transmit.request.impl.*; |
|||
import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor; |
|||
import com.genersoft.iot.vmp.gb28181.transmit.response.impl.ByeResponseProcessor; |
|||
import com.genersoft.iot.vmp.gb28181.transmit.response.impl.CancelResponseProcessor; |
|||
import com.genersoft.iot.vmp.gb28181.transmit.response.impl.InviteResponseProcessor; |
|||
import com.genersoft.iot.vmp.gb28181.transmit.response.impl.OtherResponseProcessor; |
|||
import com.genersoft.iot.vmp.gb28181.transmit.response.impl.*; |
|||
import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; |
|||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
|||
import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
|||
import com.genersoft.iot.vmp.utils.SpringBeanFactory; |
|||
import com.genersoft.iot.vmp.utils.redis.RedisUtil; |
|||
import com.genersoft.iot.vmp.vmanager.service.IPlayService; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.context.annotation.Lazy; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
import javax.sip.RequestEvent; |
|||
import javax.sip.ResponseEvent; |
|||
import javax.sip.SipProvider; |
|||
import javax.sip.header.CSeqHeader; |
|||
import javax.sip.message.Request; |
|||
import javax.sip.message.Response; |
|||
|
|||
/** |
|||
// import org.slf4j.Logger;
|
|||
// import org.slf4j.LoggerFactory;
|
|||
|
|||
/** |
|||
* @Description: SIP信令处理分配 |
|||
* @author: swwheihei |
|||
* @date: 2020年5月3日 下午4:24:37 |
|||
* @date: 2020年5月3日 下午4:24:37 |
|||
*/ |
|||
@Component |
|||
public class SIPProcessorFactory { |
|||
|
|||
// private final static Logger logger = LoggerFactory.getLogger(SIPProcessorFactory.class);
|
|||
|
|||
@Autowired |
|||
private SipConfig sipConfig; |
|||
|
|||
@Autowired |
|||
private RegisterLogicHandler handler; |
|||
|
|||
@Autowired |
|||
private IVideoManagerStorager storager; |
|||
|
|||
@Autowired |
|||
private IRedisCatchStorage redisCatchStorage; |
|||
// private final static Logger logger = LoggerFactory.getLogger(SIPProcessorFactory.class);
|
|||
|
|||
@Autowired |
|||
private SipConfig sipConfig; |
|||
|
|||
@Autowired |
|||
private RegisterLogicHandler handler; |
|||
|
|||
@Autowired |
|||
private EventPublisher publisher; |
|||
@Autowired |
|||
private IVideoManagerStorager storager; |
|||
|
|||
@Autowired |
|||
private SIPCommander cmder; |
|||
@Autowired |
|||
private IRedisCatchStorage redisCatchStorage; |
|||
|
|||
@Autowired |
|||
private SIPCommanderFroPlatform cmderFroPlatform; |
|||
@Autowired |
|||
private EventPublisher publisher; |
|||
|
|||
@Autowired |
|||
private RedisUtil redis; |
|||
@Autowired |
|||
private SIPCommander cmder; |
|||
|
|||
@Autowired |
|||
private DeferredResultHolder deferredResultHolder; |
|||
@Autowired |
|||
private SIPCommanderFroPlatform cmderFroPlatform; |
|||
|
|||
@Autowired |
|||
private DeviceOffLineDetector offLineDetector; |
|||
@Autowired |
|||
private RedisUtil redis; |
|||
|
|||
@Autowired |
|||
private InviteResponseProcessor inviteResponseProcessor; |
|||
@Autowired |
|||
private DeferredResultHolder deferredResultHolder; |
|||
|
|||
@Autowired |
|||
private ByeResponseProcessor byeResponseProcessor; |
|||
@Autowired |
|||
private DeviceOffLineDetector offLineDetector; |
|||
|
|||
@Autowired |
|||
private CancelResponseProcessor cancelResponseProcessor; |
|||
@Autowired |
|||
private InviteResponseProcessor inviteResponseProcessor; |
|||
|
|||
@Autowired |
|||
@Lazy |
|||
private RegisterResponseProcessor registerResponseProcessor; |
|||
@Autowired |
|||
private ByeResponseProcessor byeResponseProcessor; |
|||
|
|||
@Autowired |
|||
private CancelResponseProcessor cancelResponseProcessor; |
|||
|
|||
@Autowired |
|||
private OtherResponseProcessor otherResponseProcessor; |
|||
@Autowired |
|||
@Lazy |
|||
private RegisterResponseProcessor registerResponseProcessor; |
|||
|
|||
@Autowired |
|||
private IPlayService playService; |
|||
|
|||
@Autowired |
|||
private ZLMRTPServerFactory zlmrtpServerFactory; |
|||
@Autowired |
|||
private OtherResponseProcessor otherResponseProcessor; |
|||
|
|||
@Autowired |
|||
private IPlayService playService; |
|||
|
|||
// 注:这里使用注解会导致循环依赖注入,暂用springBean
|
|||
private SipProvider tcpSipProvider; |
|||
|
|||
// 注:这里使用注解会导致循环依赖注入,暂用springBean
|
|||
private SipProvider udpSipProvider; |
|||
|
|||
public ISIPRequestProcessor createRequestProcessor(RequestEvent evt) { |
|||
Request request = evt.getRequest(); |
|||
String method = request.getMethod(); |
|||
@Autowired |
|||
private ZLMRTPServerFactory zlmrtpServerFactory; |
|||
|
|||
|
|||
// 注:这里使用注解会导致循环依赖注入,暂用springBean
|
|||
private SipProvider tcpSipProvider; |
|||
|
|||
// 注:这里使用注解会导致循环依赖注入,暂用springBean
|
|||
private SipProvider udpSipProvider; |
|||
|
|||
public ISIPRequestProcessor createRequestProcessor(RequestEvent evt) { |
|||
Request request = evt.getRequest(); |
|||
String method = request.getMethod(); |
|||
// logger.info("接收到消息:"+request.getMethod());
|
|||
// sipSubscribe.getSubscribe(evt.getServerTransaction().getBranchId()).response(evt);
|
|||
if (Request.INVITE.equals(method)) { |
|||
InviteRequestProcessor processor = new InviteRequestProcessor(); |
|||
processor.setRequestEvent(evt); |
|||
processor.setTcpSipProvider(getTcpSipProvider()); |
|||
processor.setUdpSipProvider(getUdpSipProvider()); |
|||
|
|||
processor.setCmder(cmder); |
|||
processor.setCmderFroPlatform(cmderFroPlatform); |
|||
processor.setPlayService(playService); |
|||
processor.setStorager(storager); |
|||
processor.setRedisCatchStorage(redisCatchStorage); |
|||
processor.setZlmrtpServerFactory(zlmrtpServerFactory); |
|||
return processor; |
|||
} else if (Request.REGISTER.equals(method)) { |
|||
RegisterRequestProcessor processor = new RegisterRequestProcessor(); |
|||
processor.setRequestEvent(evt); |
|||
processor.setTcpSipProvider(getTcpSipProvider()); |
|||
processor.setUdpSipProvider(getUdpSipProvider()); |
|||
processor.setHandler(handler); |
|||
processor.setPublisher(publisher); |
|||
processor.setSipConfig(sipConfig); |
|||
processor.setVideoManagerStorager(storager); |
|||
return processor; |
|||
} else if (Request.SUBSCRIBE.equals(method)) { |
|||
SubscribeRequestProcessor processor = new SubscribeRequestProcessor(); |
|||
processor.setRequestEvent(evt); |
|||
return processor; |
|||
} else if (Request.ACK.equals(method)) { |
|||
AckRequestProcessor processor = new AckRequestProcessor(); |
|||
processor.setRequestEvent(evt); |
|||
processor.setRedisCatchStorage(redisCatchStorage); |
|||
processor.setZlmrtpServerFactory(zlmrtpServerFactory); |
|||
return processor; |
|||
} else if (Request.BYE.equals(method)) { |
|||
ByeRequestProcessor processor = new ByeRequestProcessor(); |
|||
processor.setRequestEvent(evt); |
|||
processor.setRedisCatchStorage(redisCatchStorage); |
|||
processor.setZlmrtpServerFactory(zlmrtpServerFactory); |
|||
processor.setSIPCommander(cmder); |
|||
return processor; |
|||
} else if (Request.CANCEL.equals(method)) { |
|||
CancelRequestProcessor processor = new CancelRequestProcessor(); |
|||
processor.setRequestEvent(evt); |
|||
return processor; |
|||
} else if (Request.MESSAGE.equals(method)) { |
|||
MessageRequestProcessor processor = new MessageRequestProcessor(); |
|||
processor.setRequestEvent(evt); |
|||
processor.setTcpSipProvider(getTcpSipProvider()); |
|||
processor.setUdpSipProvider(getUdpSipProvider()); |
|||
processor.setPublisher(publisher); |
|||
processor.setRedis(redis); |
|||
processor.setDeferredResultHolder(deferredResultHolder); |
|||
processor.setOffLineDetector(offLineDetector); |
|||
processor.setCmder(cmder); |
|||
processor.setCmderFroPlatform(cmderFroPlatform); |
|||
processor.setStorager(storager); |
|||
processor.setRedisCatchStorage(redisCatchStorage); |
|||
return processor; |
|||
} else if (Request.NOTIFY.equalsIgnoreCase(method)) { |
|||
NotifyRequestProcessor processor = new NotifyRequestProcessor(); |
|||
processor.setRequestEvent(evt); |
|||
processor.setTcpSipProvider(getTcpSipProvider()); |
|||
processor.setUdpSipProvider(getUdpSipProvider()); |
|||
processor.setPublisher(publisher); |
|||
processor.setRedis(redis); |
|||
processor.setDeferredResultHolder(deferredResultHolder); |
|||
processor.setOffLineDetector(offLineDetector); |
|||
processor.setCmder(cmder); |
|||
processor.setStorager(storager); |
|||
processor.setRedisCatchStorage(redisCatchStorage); |
|||
return processor; |
|||
} else { |
|||
OtherRequestProcessor processor = new OtherRequestProcessor(); |
|||
processor.setRequestEvent(evt); |
|||
return processor; |
|||
} |
|||
} |
|||
|
|||
public ISIPResponseProcessor createResponseProcessor(ResponseEvent evt) { |
|||
|
|||
Response response = evt.getResponse(); |
|||
CSeqHeader cseqHeader = (CSeqHeader) response.getHeader(CSeqHeader.NAME); |
|||
String method = cseqHeader.getMethod(); |
|||
if(Request.INVITE.equals(method)){ |
|||
return inviteResponseProcessor; |
|||
} else if (Request.BYE.equals(method)) { |
|||
return byeResponseProcessor; |
|||
} else if (Request.CANCEL.equals(method)) { |
|||
return cancelResponseProcessor; |
|||
}else if (Request.REGISTER.equals(method)) { |
|||
return registerResponseProcessor; |
|||
} else { |
|||
return otherResponseProcessor; |
|||
} |
|||
} |
|||
|
|||
private SipProvider getTcpSipProvider() { |
|||
if (tcpSipProvider == null) { |
|||
tcpSipProvider = (SipProvider) SpringBeanFactory.getBean("tcpSipProvider"); |
|||
} |
|||
return tcpSipProvider; |
|||
} |
|||
|
|||
private SipProvider getUdpSipProvider() { |
|||
if (udpSipProvider == null) { |
|||
udpSipProvider = (SipProvider) SpringBeanFactory.getBean("udpSipProvider"); |
|||
} |
|||
return udpSipProvider; |
|||
} |
|||
|
|||
if (Request.INVITE.equals(method)) { |
|||
InviteRequestProcessor processor = new InviteRequestProcessor(); |
|||
processor.setRequestEvent(evt); |
|||
processor.setTcpSipProvider(getTcpSipProvider()); |
|||
processor.setUdpSipProvider(getUdpSipProvider()); |
|||
|
|||
processor.setCmder(cmder); |
|||
processor.setCmderFroPlatform(cmderFroPlatform); |
|||
processor.setPlayService(playService); |
|||
processor.setStorager(storager); |
|||
processor.setRedisCatchStorage(redisCatchStorage); |
|||
processor.setZlmrtpServerFactory(zlmrtpServerFactory); |
|||
return processor; |
|||
} else if (Request.REGISTER.equals(method)) { |
|||
RegisterRequestProcessor processor = new RegisterRequestProcessor(); |
|||
processor.setRequestEvent(evt); |
|||
processor.setTcpSipProvider(getTcpSipProvider()); |
|||
processor.setUdpSipProvider(getUdpSipProvider()); |
|||
processor.setHandler(handler); |
|||
processor.setPublisher(publisher); |
|||
processor.setSipConfig(sipConfig); |
|||
processor.setVideoManagerStorager(storager); |
|||
return processor; |
|||
} else if (Request.SUBSCRIBE.equals(method)) { |
|||
SubscribeRequestProcessor processor = new SubscribeRequestProcessor(); |
|||
processor.setRequestEvent(evt); |
|||
return processor; |
|||
} else if (Request.ACK.equals(method)) { |
|||
AckRequestProcessor processor = new AckRequestProcessor(); |
|||
processor.setRequestEvent(evt); |
|||
processor.setRedisCatchStorage(redisCatchStorage); |
|||
processor.setZlmrtpServerFactory(zlmrtpServerFactory); |
|||
return processor; |
|||
} else if (Request.BYE.equals(method)) { |
|||
ByeRequestProcessor processor = new ByeRequestProcessor(); |
|||
processor.setRequestEvent(evt); |
|||
processor.setRedisCatchStorage(redisCatchStorage); |
|||
processor.setZlmrtpServerFactory(zlmrtpServerFactory); |
|||
processor.setSIPCommander(cmder); |
|||
return processor; |
|||
} else if (Request.CANCEL.equals(method)) { |
|||
CancelRequestProcessor processor = new CancelRequestProcessor(); |
|||
processor.setRequestEvent(evt); |
|||
return processor; |
|||
} else if (Request.MESSAGE.equals(method)) { |
|||
MessageRequestProcessor processor = new MessageRequestProcessor(); |
|||
processor.setRequestEvent(evt); |
|||
processor.setTcpSipProvider(getTcpSipProvider()); |
|||
processor.setUdpSipProvider(getUdpSipProvider()); |
|||
processor.setPublisher(publisher); |
|||
processor.setRedis(redis); |
|||
processor.setDeferredResultHolder(deferredResultHolder); |
|||
processor.setOffLineDetector(offLineDetector); |
|||
processor.setCmder(cmder); |
|||
processor.setCmderFroPlatform(cmderFroPlatform); |
|||
processor.setStorager(storager); |
|||
processor.setRedisCatchStorage(redisCatchStorage); |
|||
return processor; |
|||
} else if (Request.NOTIFY.equalsIgnoreCase(method)) { |
|||
NotifyRequestProcessor processor = new NotifyRequestProcessor(); |
|||
processor.setRequestEvent(evt); |
|||
processor.setTcpSipProvider(getTcpSipProvider()); |
|||
processor.setUdpSipProvider(getUdpSipProvider()); |
|||
processor.setPublisher(publisher); |
|||
processor.setRedis(redis); |
|||
processor.setDeferredResultHolder(deferredResultHolder); |
|||
processor.setOffLineDetector(offLineDetector); |
|||
processor.setCmder(cmder); |
|||
processor.setStorager(storager); |
|||
processor.setRedisCatchStorage(redisCatchStorage); |
|||
return processor; |
|||
} else { |
|||
OtherRequestProcessor processor = new OtherRequestProcessor(); |
|||
processor.setRequestEvent(evt); |
|||
return processor; |
|||
} |
|||
} |
|||
|
|||
public ISIPResponseProcessor createResponseProcessor(ResponseEvent evt) { |
|||
|
|||
Response response = evt.getResponse(); |
|||
CSeqHeader cseqHeader = (CSeqHeader) response.getHeader(CSeqHeader.NAME); |
|||
String method = cseqHeader.getMethod(); |
|||
if (Request.INVITE.equals(method)) { |
|||
return inviteResponseProcessor; |
|||
} else if (Request.BYE.equals(method)) { |
|||
return byeResponseProcessor; |
|||
} else if (Request.CANCEL.equals(method)) { |
|||
return cancelResponseProcessor; |
|||
} else if (Request.REGISTER.equals(method)) { |
|||
return registerResponseProcessor; |
|||
} else { |
|||
return otherResponseProcessor; |
|||
} |
|||
} |
|||
|
|||
private SipProvider getTcpSipProvider() { |
|||
if (tcpSipProvider == null) { |
|||
tcpSipProvider = (SipProvider) SpringBeanFactory.getBean("tcpSipProvider"); |
|||
} |
|||
return tcpSipProvider; |
|||
} |
|||
|
|||
private SipProvider getUdpSipProvider() { |
|||
if (udpSipProvider == null) { |
|||
udpSipProvider = (SipProvider) SpringBeanFactory.getBean("udpSipProvider"); |
|||
} |
|||
return udpSipProvider; |
|||
} |
|||
|
|||
} |
|||
|
@ -1,60 +1,60 @@ |
|||
package com.genersoft.iot.vmp.gb28181.transmit.callback; |
|||
|
|||
import java.util.Map; |
|||
import java.util.concurrent.ConcurrentHashMap; |
|||
|
|||
import org.springframework.http.HttpStatus; |
|||
import org.springframework.http.ResponseEntity; |
|||
import org.springframework.stereotype.Component; |
|||
import org.springframework.web.context.request.async.DeferredResult; |
|||
|
|||
/** |
|||
import java.util.Map; |
|||
import java.util.concurrent.ConcurrentHashMap; |
|||
|
|||
/** |
|||
* @Description: 异步请求处理 |
|||
* @author: swwheihei |
|||
* @date: 2020年5月8日 下午7:59:05 |
|||
* @date: 2020年5月8日 下午7:59:05 |
|||
*/ |
|||
@Component |
|||
public class DeferredResultHolder { |
|||
|
|||
public static final String CALLBACK_CMD_DEVICESTATUS = "CALLBACK_DEVICESTATUS"; |
|||
|
|||
public static final String CALLBACK_CMD_DEVICEINFO = "CALLBACK_DEVICEINFO"; |
|||
|
|||
public static final String CALLBACK_CMD_DEVICECONTROL = "CALLBACK_DEVICECONTROL"; |
|||
|
|||
public static final String CALLBACK_CMD_DEVICECONFIG = "CALLBACK_DEVICECONFIG"; |
|||
|
|||
public static final String CALLBACK_CMD_CONFIGDOWNLOAD = "CALLBACK_CONFIGDOWNLOAD"; |
|||
|
|||
public static final String CALLBACK_CMD_CATALOG = "CALLBACK_CATALOG"; |
|||
|
|||
public static final String CALLBACK_CMD_RECORDINFO = "CALLBACK_RECORDINFO"; |
|||
public static final String CALLBACK_CMD_DEVICESTATUS = "CALLBACK_DEVICESTATUS"; |
|||
|
|||
public static final String CALLBACK_CMD_DEVICEINFO = "CALLBACK_DEVICEINFO"; |
|||
|
|||
public static final String CALLBACK_CMD_DEVICECONTROL = "CALLBACK_DEVICECONTROL"; |
|||
|
|||
public static final String CALLBACK_CMD_DEVICECONFIG = "CALLBACK_DEVICECONFIG"; |
|||
|
|||
public static final String CALLBACK_CMD_CONFIGDOWNLOAD = "CALLBACK_CONFIGDOWNLOAD"; |
|||
|
|||
public static final String CALLBACK_CMD_CATALOG = "CALLBACK_CATALOG"; |
|||
|
|||
public static final String CALLBACK_CMD_RECORDINFO = "CALLBACK_RECORDINFO"; |
|||
|
|||
public static final String CALLBACK_CMD_PlAY = "CALLBACK_PLAY"; |
|||
public static final String CALLBACK_CMD_PlAY = "CALLBACK_PLAY"; |
|||
|
|||
public static final String CALLBACK_CMD_STOP = "CALLBACK_STOP"; |
|||
public static final String CALLBACK_CMD_STOP = "CALLBACK_STOP"; |
|||
|
|||
public static final String CALLBACK_CMD_MOBILEPOSITION = "CALLBACK_MOBILEPOSITION"; |
|||
public static final String CALLBACK_CMD_MOBILEPOSITION = "CALLBACK_MOBILEPOSITION"; |
|||
|
|||
public static final String CALLBACK_CMD_PRESETQUERY = "CALLBACK_PRESETQUERY"; |
|||
public static final String CALLBACK_CMD_PRESETQUERY = "CALLBACK_PRESETQUERY"; |
|||
|
|||
public static final String CALLBACK_CMD_ALARM = "CALLBACK_ALARM"; |
|||
public static final String CALLBACK_CMD_ALARM = "CALLBACK_ALARM"; |
|||
|
|||
public static final String CALLBACK_CMD_BROADCAST = "CALLBACK_BROADCAST"; |
|||
public static final String CALLBACK_CMD_BROADCAST = "CALLBACK_BROADCAST"; |
|||
|
|||
private Map<String, DeferredResult> map = new ConcurrentHashMap<String, DeferredResult>(); |
|||
private Map<String, DeferredResult> map = new ConcurrentHashMap<String, DeferredResult>(); |
|||
|
|||
public void put(String key, DeferredResult result) { |
|||
map.put(key, result); |
|||
} |
|||
public void put(String key, DeferredResult result) { |
|||
map.put(key, result); |
|||
} |
|||
|
|||
public void invokeResult(RequestMessage msg) { |
|||
public void invokeResult(RequestMessage msg) { |
|||
// DeferredResult result = map.get(msg.getId());
|
|||
// 获取并移除
|
|||
DeferredResult result = map.remove(msg.getId()); |
|||
if (result == null) { |
|||
return; |
|||
} |
|||
result.setResult(new ResponseEntity<>(msg.getData(),HttpStatus.OK)); |
|||
} |
|||
// 获取并移除
|
|||
DeferredResult result = map.remove(msg.getId()); |
|||
if (result == null) { |
|||
return; |
|||
} |
|||
result.setResult(new ResponseEntity<>(msg.getData(), HttpStatus.OK)); |
|||
} |
|||
} |
|||
|
File diff suppressed because it is too large
@ -1,113 +1,120 @@ |
|||
package com.genersoft.iot.vmp.gb28181.transmit.request.impl; |
|||
|
|||
import java.util.HashMap; |
|||
import java.util.Map; |
|||
|
|||
import javax.sip.*; |
|||
import javax.sip.address.SipURI; |
|||
import javax.sip.header.FromHeader; |
|||
import javax.sip.header.HeaderAddress; |
|||
import javax.sip.header.ToHeader; |
|||
|
|||
import com.genersoft.iot.vmp.common.StreamInfo; |
|||
import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; |
|||
import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor; |
|||
import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; |
|||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
|||
|
|||
/** |
|||
* @Description:ACK请求处理器 |
|||
* @author: swwheihei |
|||
* @date: 2020年5月3日 下午5:31:45 |
|||
*/ |
|||
public class AckRequestProcessor extends SIPRequestAbstractProcessor { |
|||
|
|||
private IRedisCatchStorage redisCatchStorage; |
|||
|
|||
private ZLMRTPServerFactory zlmrtpServerFactory; |
|||
|
|||
/** |
|||
* 处理 ACK请求 |
|||
* |
|||
* @param evt |
|||
*/ |
|||
@Override |
|||
public void process(RequestEvent evt) { |
|||
//Request request = evt.getRequest();
|
|||
Dialog dialog = evt.getDialog(); |
|||
if (dialog == null) return; |
|||
//DialogState state = dialog.getState();
|
|||
if (/*request.getMecodewwthod().equals(Request.INVITE) &&*/ dialog.getState()== DialogState.CONFIRMED) { |
|||
String platformGbId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(FromHeader.NAME)).getAddress().getURI()).getUser(); |
|||
String channelId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser(); |
|||
SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(platformGbId, channelId); |
|||
String is_Udp = sendRtpItem.isTcp() ? "0" : "1"; |
|||
String deviceId = sendRtpItem.getDeviceId(); |
|||
StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId); |
|||
sendRtpItem.setStreamId(streamInfo.getStreamId()); |
|||
redisCatchStorage.updateSendRTPSever(sendRtpItem); |
|||
System.out.println(platformGbId); |
|||
System.out.println(channelId); |
|||
Map<String, Object> param = new HashMap<>(); |
|||
param.put("vhost","__defaultVhost__"); |
|||
param.put("app","rtp"); |
|||
param.put("stream",streamInfo.getStreamId()); |
|||
param.put("ssrc", sendRtpItem.getSsrc()); |
|||
param.put("dst_url",sendRtpItem.getIp()); |
|||
param.put("dst_port", sendRtpItem.getPort()); |
|||
param.put("is_udp", is_Udp); |
|||
//param.put ("src_port", sendRtpItem.getLocalPort());
|
|||
// 设备推流查询,成功后才能转推
|
|||
boolean rtpPushed = false; |
|||
long startTime = System.currentTimeMillis(); |
|||
while (!rtpPushed) { |
|||
try { |
|||
if (System.currentTimeMillis() - startTime < 30 * 1000) { |
|||
if (zlmrtpServerFactory.isRtpReady(streamInfo.getStreamId())) { |
|||
rtpPushed = true; |
|||
System.out.println("已获取设备推流,开始向上级推流"); |
|||
zlmrtpServerFactory.startSendRtpStream(param); |
|||
} else { |
|||
System.out.println("等待设备推流......."); |
|||
Thread.sleep(2000); |
|||
continue; |
|||
} |
|||
} else { |
|||
rtpPushed = true; |
|||
System.out.println("设备推流超时,终止向上级推流"); |
|||
} |
|||
} catch (InterruptedException e) { |
|||
e.printStackTrace(); |
|||
} |
|||
} |
|||
} |
|||
// try {
|
|||
// Request ackRequest = null;
|
|||
// CSeq csReq = (CSeq) request.getHeader(CSeq.NAME);
|
|||
// ackRequest = dialog.createAck(csReq.getSeqNumber());
|
|||
// dialog.sendAck(ackRequest);
|
|||
// System.out.println("send ack to callee:" + ackRequest.toString());
|
|||
// } catch (SipException e) {
|
|||
// e.printStackTrace();
|
|||
// } catch (InvalidArgumentException e) {
|
|||
// e.printStackTrace();
|
|||
// }
|
|||
|
|||
} |
|||
|
|||
public IRedisCatchStorage getRedisCatchStorage() { |
|||
return redisCatchStorage; |
|||
} |
|||
|
|||
public void setRedisCatchStorage(IRedisCatchStorage redisCatchStorage) { |
|||
this.redisCatchStorage = redisCatchStorage; |
|||
} |
|||
|
|||
public ZLMRTPServerFactory getZlmrtpServerFactory() { |
|||
return zlmrtpServerFactory; |
|||
} |
|||
|
|||
public void setZlmrtpServerFactory(ZLMRTPServerFactory zlmrtpServerFactory) { |
|||
this.zlmrtpServerFactory = zlmrtpServerFactory; |
|||
} |
|||
} |
|||
package com.genersoft.iot.vmp.gb28181.transmit.request.impl; |
|||
|
|||
import java.util.HashMap; |
|||
import java.util.Map; |
|||
|
|||
import javax.sip.*; |
|||
import javax.sip.address.SipURI; |
|||
import javax.sip.header.FromHeader; |
|||
import javax.sip.header.HeaderAddress; |
|||
import javax.sip.header.ToHeader; |
|||
|
|||
import com.genersoft.iot.vmp.common.StreamInfo; |
|||
import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; |
|||
import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; |
|||
import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor; |
|||
import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; |
|||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
|
|||
/** |
|||
* @Description:ACK请求处理器 |
|||
* @author: swwheihei |
|||
* @date: 2020年5月3日 下午5:31:45 |
|||
*/ |
|||
public class AckRequestProcessor extends SIPRequestAbstractProcessor { |
|||
|
|||
private IRedisCatchStorage redisCatchStorage; |
|||
|
|||
private ZLMRTPServerFactory zlmrtpServerFactory; |
|||
|
|||
@Autowired |
|||
private VideoStreamSessionManager streamSession; |
|||
|
|||
/** |
|||
* 处理 ACK请求 |
|||
* |
|||
* @param evt |
|||
*/ |
|||
@Override |
|||
public void process(RequestEvent evt) { |
|||
//Request request = evt.getRequest();
|
|||
Dialog dialog = evt.getDialog(); |
|||
if (dialog == null) { |
|||
return; |
|||
} |
|||
//DialogState state = dialog.getState();
|
|||
if (/*request.getMecodewwthod().equals(Request.INVITE) &&*/ dialog.getState()== DialogState.CONFIRMED) { |
|||
String platformGbId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(FromHeader.NAME)).getAddress().getURI()).getUser(); |
|||
String channelId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser(); |
|||
SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(platformGbId, channelId); |
|||
String is_Udp = sendRtpItem.isTcp() ? "0" : "1"; |
|||
String deviceId = sendRtpItem.getDeviceId(); |
|||
StreamInfo streamInfo = redisCatchStorage.queryPlayByChannel(channelId); |
|||
sendRtpItem.setStreamId(streamInfo.getStreamId()); |
|||
redisCatchStorage.updateSendRTPSever(sendRtpItem); |
|||
System.out.println(platformGbId); |
|||
System.out.println(channelId); |
|||
Map<String, Object> param = new HashMap<>(); |
|||
param.put("vhost","__defaultVhost__"); |
|||
param.put("app","rtp"); |
|||
param.put("stream",streamInfo.getStreamId()); |
|||
param.put("ssrc", sendRtpItem.getSsrc()); |
|||
param.put("dst_url",sendRtpItem.getIp()); |
|||
param.put("dst_port", sendRtpItem.getPort()); |
|||
param.put("is_udp", is_Udp); |
|||
//param.put ("src_port", sendRtpItem.getLocalPort());
|
|||
// 设备推流查询,成功后才能转推
|
|||
boolean rtpPushed = false; |
|||
long startTime = System.currentTimeMillis(); |
|||
while (!rtpPushed) { |
|||
try { |
|||
if (System.currentTimeMillis() - startTime < 30 * 1000) { |
|||
if (zlmrtpServerFactory.isRtpReady(streamInfo.getStreamId())) { |
|||
rtpPushed = true; |
|||
System.out.println("已获取设备推流,开始向上级推流"); |
|||
zlmrtpServerFactory.startSendRtpStream(param); |
|||
} else { |
|||
System.out.println("等待设备推流......."); |
|||
Thread.sleep(2000); |
|||
continue; |
|||
} |
|||
} else { |
|||
rtpPushed = true; |
|||
System.out.println("设备推流超时,终止向上级推流"); |
|||
} |
|||
} catch (InterruptedException e) { |
|||
e.printStackTrace(); |
|||
} |
|||
} |
|||
} |
|||
// try {
|
|||
// Request ackRequest = null;
|
|||
// CSeq csReq = (CSeq) request.getHeader(CSeq.NAME);
|
|||
// ackRequest = dialog.createAck(csReq.getSeqNumber());
|
|||
// dialog.sendAck(ackRequest);
|
|||
// System.out.println("send ack to callee:" + ackRequest.toString());
|
|||
// } catch (SipException e) {
|
|||
// e.printStackTrace();
|
|||
// } catch (InvalidArgumentException e) {
|
|||
// e.printStackTrace();
|
|||
// }
|
|||
|
|||
} |
|||
|
|||
public IRedisCatchStorage getRedisCatchStorage() { |
|||
return redisCatchStorage; |
|||
} |
|||
|
|||
public void setRedisCatchStorage(IRedisCatchStorage redisCatchStorage) { |
|||
this.redisCatchStorage = redisCatchStorage; |
|||
} |
|||
|
|||
public ZLMRTPServerFactory getZlmrtpServerFactory() { |
|||
return zlmrtpServerFactory; |
|||
} |
|||
|
|||
public void setZlmrtpServerFactory(ZLMRTPServerFactory zlmrtpServerFactory) { |
|||
this.zlmrtpServerFactory = zlmrtpServerFactory; |
|||
} |
|||
} |
|||
|
@ -1,109 +1,116 @@ |
|||
package com.genersoft.iot.vmp.gb28181.transmit.request.impl; |
|||
|
|||
import javax.sip.address.SipURI; |
|||
import javax.sip.Dialog; |
|||
import javax.sip.DialogState; |
|||
import javax.sip.InvalidArgumentException; |
|||
import javax.sip.RequestEvent; |
|||
import javax.sip.SipException; |
|||
import javax.sip.header.FromHeader; |
|||
import javax.sip.header.HeaderAddress; |
|||
import javax.sip.header.ToHeader; |
|||
import javax.sip.message.Response; |
|||
|
|||
import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; |
|||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; |
|||
import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor; |
|||
import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; |
|||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
|||
|
|||
import java.text.ParseException; |
|||
import java.util.HashMap; |
|||
import java.util.Map; |
|||
|
|||
/** |
|||
* @Description: BYE请求处理器 |
|||
* @author: lawrencehj |
|||
* @date: 2021年3月9日 |
|||
*/ |
|||
public class ByeRequestProcessor extends SIPRequestAbstractProcessor { |
|||
|
|||
private ISIPCommander cmder; |
|||
|
|||
private IRedisCatchStorage redisCatchStorage; |
|||
|
|||
private ZLMRTPServerFactory zlmrtpServerFactory; |
|||
|
|||
/** |
|||
* 处理BYE请求 |
|||
* @param evt |
|||
*/ |
|||
@Override |
|||
public void process(RequestEvent evt) { |
|||
try { |
|||
responseAck(evt); |
|||
Dialog dialog = evt.getDialog(); |
|||
if (dialog == null) return; |
|||
if (dialog.getState().equals(DialogState.TERMINATED)) { |
|||
String platformGbId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(FromHeader.NAME)).getAddress().getURI()).getUser(); |
|||
String channelId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser(); |
|||
SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(platformGbId, channelId); |
|||
String streamId = sendRtpItem.getStreamId(); |
|||
Map<String, Object> param = new HashMap<>(); |
|||
param.put("vhost","__defaultVhost__"); |
|||
param.put("app","rtp"); |
|||
param.put("stream",streamId); |
|||
System.out.println("停止向上级推流:" + streamId); |
|||
zlmrtpServerFactory.stopSendRtpStream(param); |
|||
redisCatchStorage.deleteSendRTPServer(platformGbId, channelId); |
|||
if (zlmrtpServerFactory.totalReaderCount(streamId) == 0) { |
|||
System.out.println(streamId + "无其它观看者,通知设备停止推流"); |
|||
cmder.streamByeCmd(streamId); |
|||
} |
|||
} |
|||
} catch (SipException e) { |
|||
e.printStackTrace(); |
|||
} catch (InvalidArgumentException e) { |
|||
e.printStackTrace(); |
|||
} catch (ParseException e) { |
|||
e.printStackTrace(); |
|||
} |
|||
} |
|||
|
|||
/*** |
|||
* 回复200 OK |
|||
* @param evt |
|||
* @throws SipException |
|||
* @throws InvalidArgumentException |
|||
* @throws ParseException |
|||
*/ |
|||
private void responseAck(RequestEvent evt) throws SipException, InvalidArgumentException, ParseException { |
|||
Response response = getMessageFactory().createResponse(Response.OK, evt.getRequest()); |
|||
getServerTransaction(evt).sendResponse(response); |
|||
} |
|||
|
|||
public IRedisCatchStorage getRedisCatchStorage() { |
|||
return redisCatchStorage; |
|||
} |
|||
|
|||
public void setRedisCatchStorage(IRedisCatchStorage redisCatchStorage) { |
|||
this.redisCatchStorage = redisCatchStorage; |
|||
} |
|||
|
|||
public ZLMRTPServerFactory getZlmrtpServerFactory() { |
|||
return zlmrtpServerFactory; |
|||
} |
|||
|
|||
public void setZlmrtpServerFactory(ZLMRTPServerFactory zlmrtpServerFactory) { |
|||
this.zlmrtpServerFactory = zlmrtpServerFactory; |
|||
} |
|||
|
|||
public ISIPCommander getSIPCommander() { |
|||
return cmder; |
|||
} |
|||
|
|||
public void setSIPCommander(ISIPCommander cmder) { |
|||
this.cmder = cmder; |
|||
} |
|||
|
|||
} |
|||
package com.genersoft.iot.vmp.gb28181.transmit.request.impl; |
|||
|
|||
import javax.sip.address.SipURI; |
|||
import javax.sip.Dialog; |
|||
import javax.sip.DialogState; |
|||
import javax.sip.InvalidArgumentException; |
|||
import javax.sip.RequestEvent; |
|||
import javax.sip.SipException; |
|||
import javax.sip.header.FromHeader; |
|||
import javax.sip.header.HeaderAddress; |
|||
import javax.sip.header.ToHeader; |
|||
import javax.sip.message.Response; |
|||
|
|||
import com.genersoft.iot.vmp.common.StreamInfo; |
|||
import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; |
|||
import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; |
|||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; |
|||
import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor; |
|||
import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; |
|||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
|
|||
import java.text.ParseException; |
|||
import java.util.HashMap; |
|||
import java.util.Map; |
|||
|
|||
/** |
|||
* @Description: BYE请求处理器 |
|||
* @author: lawrencehj |
|||
* @date: 2021年3月9日 |
|||
*/ |
|||
public class ByeRequestProcessor extends SIPRequestAbstractProcessor { |
|||
|
|||
private ISIPCommander cmder; |
|||
|
|||
private IRedisCatchStorage redisCatchStorage; |
|||
|
|||
private ZLMRTPServerFactory zlmrtpServerFactory; |
|||
|
|||
@Autowired |
|||
private VideoStreamSessionManager streamSession; |
|||
|
|||
/** |
|||
* 处理BYE请求 |
|||
* @param evt |
|||
*/ |
|||
@Override |
|||
public void process(RequestEvent evt) { |
|||
try { |
|||
responseAck(evt); |
|||
Dialog dialog = evt.getDialog(); |
|||
if (dialog == null) return; |
|||
if (dialog.getState().equals(DialogState.TERMINATED)) { |
|||
String platformGbId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(FromHeader.NAME)).getAddress().getURI()).getUser(); |
|||
String channelId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser(); |
|||
SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(platformGbId, channelId); |
|||
String streamId = sendRtpItem.getStreamId(); |
|||
Map<String, Object> param = new HashMap<>(); |
|||
param.put("vhost","__defaultVhost__"); |
|||
param.put("app","rtp"); |
|||
param.put("stream",streamId); |
|||
System.out.println("停止向上级推流:" + streamId); |
|||
StreamInfo streamInfo = streamSession.getStreamInfo(channelId, streamId); |
|||
zlmrtpServerFactory.stopSendRtpStream(param); |
|||
redisCatchStorage.deleteSendRTPServer(platformGbId, channelId); |
|||
if (zlmrtpServerFactory.totalReaderCount(streamId) == 0) { |
|||
System.out.println(streamId + "无其它观看者,通知设备停止推流"); |
|||
cmder.stopStreamByeCmd(streamInfo, null); |
|||
} |
|||
} |
|||
} catch (SipException e) { |
|||
e.printStackTrace(); |
|||
} catch (InvalidArgumentException e) { |
|||
e.printStackTrace(); |
|||
} catch (ParseException e) { |
|||
e.printStackTrace(); |
|||
} |
|||
} |
|||
|
|||
/*** |
|||
* 回复200 OK |
|||
* @param evt |
|||
* @throws SipException |
|||
* @throws InvalidArgumentException |
|||
* @throws ParseException |
|||
*/ |
|||
private void responseAck(RequestEvent evt) throws SipException, InvalidArgumentException, ParseException { |
|||
Response response = getMessageFactory().createResponse(Response.OK, evt.getRequest()); |
|||
getServerTransaction(evt).sendResponse(response); |
|||
} |
|||
|
|||
public IRedisCatchStorage getRedisCatchStorage() { |
|||
return redisCatchStorage; |
|||
} |
|||
|
|||
public void setRedisCatchStorage(IRedisCatchStorage redisCatchStorage) { |
|||
this.redisCatchStorage = redisCatchStorage; |
|||
} |
|||
|
|||
public ZLMRTPServerFactory getZlmrtpServerFactory() { |
|||
return zlmrtpServerFactory; |
|||
} |
|||
|
|||
public void setZlmrtpServerFactory(ZLMRTPServerFactory zlmrtpServerFactory) { |
|||
this.zlmrtpServerFactory = zlmrtpServerFactory; |
|||
} |
|||
|
|||
public ISIPCommander getSIPCommander() { |
|||
return cmder; |
|||
} |
|||
|
|||
public void setSIPCommander(ISIPCommander cmder) { |
|||
this.cmder = cmder; |
|||
} |
|||
|
|||
} |
|||
|
@ -1,384 +1,377 @@ |
|||
package com.genersoft.iot.vmp.gb28181.transmit.request.impl; |
|||
|
|||
import javax.sdp.*; |
|||
import javax.sip.InvalidArgumentException; |
|||
import javax.sip.RequestEvent; |
|||
import javax.sip.SipException; |
|||
import javax.sip.SipFactory; |
|||
import javax.sip.address.Address; |
|||
import javax.sip.address.SipURI; |
|||
import javax.sip.header.*; |
|||
import javax.sip.message.Request; |
|||
import javax.sip.message.Response; |
|||
|
|||
import com.genersoft.iot.vmp.conf.MediaServerConfig; |
|||
import com.genersoft.iot.vmp.gb28181.bean.Device; |
|||
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; |
|||
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; |
|||
import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; |
|||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; |
|||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; |
|||
import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor; |
|||
import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; |
|||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
|||
import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
|||
import com.genersoft.iot.vmp.vmanager.play.bean.PlayResult; |
|||
import com.genersoft.iot.vmp.vmanager.service.IPlayService; |
|||
import gov.nist.javax.sip.address.AddressImpl; |
|||
import gov.nist.javax.sip.address.SipUri; |
|||
import org.slf4j.Logger; |
|||
import org.slf4j.LoggerFactory; |
|||
|
|||
import java.text.ParseException; |
|||
import java.util.Vector; |
|||
|
|||
/** |
|||
* @Description:处理INVITE请求 |
|||
* @author: panll |
|||
* @date: 2021年1月14日 |
|||
*/ |
|||
@SuppressWarnings("rawtypes") |
|||
public class InviteRequestProcessor extends SIPRequestAbstractProcessor { |
|||
|
|||
private final static Logger logger = LoggerFactory.getLogger(MessageRequestProcessor.class); |
|||
|
|||
private SIPCommanderFroPlatform cmderFroPlatform; |
|||
|
|||
private IVideoManagerStorager storager; |
|||
|
|||
private IRedisCatchStorage redisCatchStorage; |
|||
|
|||
private SIPCommander cmder; |
|||
|
|||
private IPlayService playService; |
|||
|
|||
private ZLMRTPServerFactory zlmrtpServerFactory; |
|||
|
|||
public ZLMRTPServerFactory getZlmrtpServerFactory() { |
|||
return zlmrtpServerFactory; |
|||
} |
|||
|
|||
public void setZlmrtpServerFactory(ZLMRTPServerFactory zlmrtpServerFactory) { |
|||
this.zlmrtpServerFactory = zlmrtpServerFactory; |
|||
} |
|||
|
|||
/** |
|||
* 处理invite请求 |
|||
* |
|||
* @param evt |
|||
* 请求消息 |
|||
*/ |
|||
@Override |
|||
public void process(RequestEvent evt) { |
|||
// Invite Request消息实现,此消息一般为级联消息,上级给下级发送请求视频指令
|
|||
try { |
|||
Request request = evt.getRequest(); |
|||
SipURI sipURI = (SipURI) request.getRequestURI(); |
|||
String channelId = sipURI.getUser(); |
|||
String requesterId = null; |
|||
|
|||
FromHeader fromHeader = (FromHeader)request.getHeader(FromHeader.NAME); |
|||
AddressImpl address = (AddressImpl) fromHeader.getAddress(); |
|||
SipUri uri = (SipUri) address.getURI(); |
|||
requesterId = uri.getUser(); |
|||
|
|||
if (requesterId == null || channelId == null) { |
|||
logger.info("无法从FromHeader的Address中获取到平台id,返回400"); |
|||
responseAck(evt, Response.BAD_REQUEST); // 参数不全, 发400,请求错误
|
|||
return; |
|||
} |
|||
|
|||
// 查询请求方是否上级平台
|
|||
ParentPlatform platform = storager.queryParentPlatById(requesterId); |
|||
if (platform != null) { |
|||
// 查询平台下是否有该通道
|
|||
DeviceChannel channel = storager.queryChannelInParentPlatform(requesterId, channelId); |
|||
if (channel == null) { |
|||
logger.info("通道不存在,返回404"); |
|||
responseAck(evt, Response.NOT_FOUND); // 通道不存在,发404,资源不存在
|
|||
return; |
|||
}else { |
|||
responseAck(evt, Response.CALL_IS_BEING_FORWARDED); // 通道存在,发181,呼叫转接中
|
|||
} |
|||
// 解析sdp消息, 使用jainsip 自带的sdp解析方式
|
|||
String contentString = new String(request.getRawContent()); |
|||
|
|||
// jainSip不支持y=字段, 移除移除以解析。
|
|||
int ssrcIndex = contentString.indexOf("y="); |
|||
//ssrc规定长度为10字节,不取余下长度以避免后续还有“f=”字段
|
|||
String ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12); |
|||
String substring = contentString.substring(0, contentString.indexOf("y=")); |
|||
SessionDescription sdp = SdpFactory.getInstance().createSessionDescription(substring); |
|||
|
|||
// 获取支持的格式
|
|||
Vector mediaDescriptions = sdp.getMediaDescriptions(true); |
|||
// 查看是否支持PS 负载96
|
|||
//String ip = null;
|
|||
int port = -1; |
|||
//boolean recvonly = false;
|
|||
boolean mediaTransmissionTCP = false; |
|||
Boolean tcpActive = null; |
|||
for (int i = 0; i < mediaDescriptions.size(); i++) { |
|||
MediaDescription mediaDescription = (MediaDescription)mediaDescriptions.get(i); |
|||
Media media = mediaDescription.getMedia(); |
|||
|
|||
Vector mediaFormats = media.getMediaFormats(false); |
|||
if (mediaFormats.contains("96")) { |
|||
port = media.getMediaPort(); |
|||
//String mediaType = media.getMediaType();
|
|||
String protocol = media.getProtocol(); |
|||
|
|||
// 区分TCP发流还是udp, 当前默认udp
|
|||
if ("TCP/RTP/AVP".equals(protocol)) { |
|||
String setup = mediaDescription.getAttribute("setup"); |
|||
if (setup != null) { |
|||
mediaTransmissionTCP = true; |
|||
if ("active".equals(setup)) { |
|||
tcpActive = true; |
|||
}else if ("passive".equals(setup)) { |
|||
tcpActive = false; |
|||
} |
|||
} |
|||
} |
|||
break; |
|||
} |
|||
} |
|||
if (port == -1) { |
|||
logger.info("不支持的媒体格式,返回415"); |
|||
// 回复不支持的格式
|
|||
responseAck(evt, Response.UNSUPPORTED_MEDIA_TYPE); // 不支持的格式,发415
|
|||
return; |
|||
} |
|||
String username = sdp.getOrigin().getUsername(); |
|||
String addressStr = sdp.getOrigin().getAddress(); |
|||
//String sessionName = sdp.getSessionName().getValue();
|
|||
logger.info("[上级点播]用户:{}, 地址:{}:{}, ssrc:{}", username, addressStr, port, ssrc); |
|||
|
|||
Device device = storager.queryVideoDeviceByPlatformIdAndChannelId(requesterId, channelId); |
|||
if (device == null) { |
|||
logger.warn("点播平台{}的通道{}时未找到设备信息", requesterId, channel); |
|||
responseAck(evt, Response.SERVER_INTERNAL_ERROR); |
|||
return; |
|||
} |
|||
SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(addressStr, port, ssrc, requesterId, device.getDeviceId(), channelId, |
|||
mediaTransmissionTCP); |
|||
if (tcpActive != null) { |
|||
sendRtpItem.setTcpActive(tcpActive); |
|||
} |
|||
if (sendRtpItem == null) { |
|||
logger.warn("服务器端口资源不足"); |
|||
responseAck(evt, Response.BUSY_HERE); |
|||
return; |
|||
} |
|||
|
|||
// 写入redis, 超时时回复
|
|||
redisCatchStorage.updateSendRTPSever(sendRtpItem); |
|||
// 通知下级推流,
|
|||
PlayResult playResult = playService.play(device.getDeviceId(), channelId, (responseJSON)->{ |
|||
// 收到推流, 回复200OK, 等待ack
|
|||
sendRtpItem.setStatus(1); |
|||
redisCatchStorage.updateSendRTPSever(sendRtpItem); |
|||
// TODO 添加对tcp的支持
|
|||
MediaServerConfig mediaInfo = redisCatchStorage.getMediaInfo(); |
|||
StringBuffer content = new StringBuffer(200); |
|||
content.append("v=0\r\n"); |
|||
content.append("o="+"00000"+" 0 0 IN IP4 "+mediaInfo.getWanIp()+"\r\n"); |
|||
content.append("s=Play\r\n"); |
|||
content.append("c=IN IP4 "+mediaInfo.getWanIp()+"\r\n"); |
|||
content.append("t=0 0\r\n"); |
|||
content.append("m=video "+ sendRtpItem.getLocalPort()+" RTP/AVP 96\r\n"); |
|||
content.append("a=sendonly\r\n"); |
|||
content.append("a=rtpmap:96 PS/90000\r\n"); |
|||
content.append("y="+ ssrc + "\r\n"); |
|||
content.append("f=\r\n"); |
|||
|
|||
try { |
|||
responseAck(evt, content.toString()); |
|||
} catch (SipException e) { |
|||
e.printStackTrace(); |
|||
} catch (InvalidArgumentException e) { |
|||
e.printStackTrace(); |
|||
} catch (ParseException e) { |
|||
e.printStackTrace(); |
|||
} |
|||
},(event -> { |
|||
// 未知错误。直接转发设备点播的错误
|
|||
Response response = null; |
|||
try { |
|||
response = getMessageFactory().createResponse(event.getResponse().getStatusCode(), evt.getRequest()); |
|||
getServerTransaction(evt).sendResponse(response); |
|||
} catch (ParseException | SipException | InvalidArgumentException e) { |
|||
e.printStackTrace(); |
|||
} |
|||
})); |
|||
if (logger.isDebugEnabled()) { |
|||
logger.debug(playResult.getResult().toString()); |
|||
} |
|||
} else { |
|||
// 非上级平台请求,查询是否设备请求(通常为接收语音广播的设备)
|
|||
Device device = storager.queryVideoDevice(requesterId); |
|||
if (device != null) { |
|||
logger.info("收到设备" + requesterId + "的语音广播Invite请求"); |
|||
responseAck(evt, Response.TRYING); |
|||
|
|||
String contentString = new String(request.getRawContent()); |
|||
// jainSip不支持y=字段, 移除移除以解析。
|
|||
String substring = contentString; |
|||
String ssrc = "0000000404"; |
|||
int ssrcIndex = contentString.indexOf("y="); |
|||
if (ssrcIndex > 0) { |
|||
substring = contentString.substring(0, ssrcIndex); |
|||
ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12); |
|||
} |
|||
ssrcIndex = substring.indexOf("f="); |
|||
if (ssrcIndex > 0) { |
|||
substring = contentString.substring(0, ssrcIndex); |
|||
} |
|||
SessionDescription sdp = SdpFactory.getInstance().createSessionDescription(substring); |
|||
|
|||
// 获取支持的格式
|
|||
Vector mediaDescriptions = sdp.getMediaDescriptions(true); |
|||
// 查看是否支持PS 负载96
|
|||
int port = -1; |
|||
//boolean recvonly = false;
|
|||
boolean mediaTransmissionTCP = false; |
|||
Boolean tcpActive = null; |
|||
for (int i = 0; i < mediaDescriptions.size(); i++) { |
|||
MediaDescription mediaDescription = (MediaDescription)mediaDescriptions.get(i); |
|||
Media media = mediaDescription.getMedia(); |
|||
|
|||
Vector mediaFormats = media.getMediaFormats(false); |
|||
if (mediaFormats.contains("8")) { |
|||
port = media.getMediaPort(); |
|||
String protocol = media.getProtocol(); |
|||
// 区分TCP发流还是udp, 当前默认udp
|
|||
if ("TCP/RTP/AVP".equals(protocol)) { |
|||
String setup = mediaDescription.getAttribute("setup"); |
|||
if (setup != null) { |
|||
mediaTransmissionTCP = true; |
|||
if ("active".equals(setup)) { |
|||
tcpActive = true; |
|||
} else if ("passive".equals(setup)) { |
|||
tcpActive = false; |
|||
} |
|||
} |
|||
} |
|||
break; |
|||
} |
|||
} |
|||
if (port == -1) { |
|||
logger.info("不支持的媒体格式,返回415"); |
|||
// 回复不支持的格式
|
|||
responseAck(evt, Response.UNSUPPORTED_MEDIA_TYPE); // 不支持的格式,发415
|
|||
return; |
|||
} |
|||
String username = sdp.getOrigin().getUsername(); |
|||
String addressStr = sdp.getOrigin().getAddress(); |
|||
logger.info("设备{}请求语音流,地址:{}:{},ssrc:{}", username, addressStr, port, ssrc); |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
} else { |
|||
logger.warn("来自无效设备/平台的请求"); |
|||
responseAck(evt, Response.BAD_REQUEST); |
|||
} |
|||
} |
|||
|
|||
} catch (SipException | InvalidArgumentException | ParseException e) { |
|||
e.printStackTrace(); |
|||
logger.warn("sdp解析错误"); |
|||
e.printStackTrace(); |
|||
} catch (SdpParseException e) { |
|||
e.printStackTrace(); |
|||
} catch (SdpException e) { |
|||
e.printStackTrace(); |
|||
} |
|||
} |
|||
|
|||
/*** |
|||
* 回复状态码 |
|||
* 100 trying |
|||
* 200 OK |
|||
* 400 |
|||
* 404 |
|||
* @param evt |
|||
* @throws SipException |
|||
* @throws InvalidArgumentException |
|||
* @throws ParseException |
|||
*/ |
|||
private void responseAck(RequestEvent evt, int statusCode) throws SipException, InvalidArgumentException, ParseException { |
|||
Response response = getMessageFactory().createResponse(statusCode, evt.getRequest()); |
|||
getServerTransaction(evt).sendResponse(response); |
|||
} |
|||
|
|||
/** |
|||
* 回复带sdp的200 |
|||
* @param evt |
|||
* @param sdp |
|||
* @throws SipException |
|||
* @throws InvalidArgumentException |
|||
* @throws ParseException |
|||
*/ |
|||
private void responseAck(RequestEvent evt, String sdp) throws SipException, InvalidArgumentException, ParseException { |
|||
Response response = getMessageFactory().createResponse(Response.OK, evt.getRequest()); |
|||
SipFactory sipFactory = SipFactory.getInstance(); |
|||
ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("APPLICATION", "SDP"); |
|||
response.setContent(sdp, contentTypeHeader); |
|||
|
|||
SipURI sipURI = (SipURI)evt.getRequest().getRequestURI(); |
|||
|
|||
Address concatAddress = sipFactory.createAddressFactory().createAddress( |
|||
sipFactory.createAddressFactory().createSipURI(sipURI.getUser(), sipURI.getHost()+":"+sipURI.getPort() |
|||
)); |
|||
response.addHeader(sipFactory.createHeaderFactory().createContactHeader(concatAddress)); |
|||
getServerTransaction(evt).sendResponse(response); |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
public SIPCommanderFroPlatform getCmderFroPlatform() { |
|||
return cmderFroPlatform; |
|||
} |
|||
|
|||
public void setCmderFroPlatform(SIPCommanderFroPlatform cmderFroPlatform) { |
|||
this.cmderFroPlatform = cmderFroPlatform; |
|||
} |
|||
|
|||
public IVideoManagerStorager getStorager() { |
|||
return storager; |
|||
} |
|||
|
|||
public void setStorager(IVideoManagerStorager storager) { |
|||
this.storager = storager; |
|||
} |
|||
|
|||
public SIPCommander getCmder() { |
|||
return cmder; |
|||
} |
|||
|
|||
public void setCmder(SIPCommander cmder) { |
|||
this.cmder = cmder; |
|||
} |
|||
|
|||
public IPlayService getPlayService() { |
|||
return playService; |
|||
} |
|||
|
|||
public void setPlayService(IPlayService playService) { |
|||
this.playService = playService; |
|||
} |
|||
|
|||
public IRedisCatchStorage getRedisCatchStorage() { |
|||
return redisCatchStorage; |
|||
} |
|||
|
|||
public void setRedisCatchStorage(IRedisCatchStorage redisCatchStorage) { |
|||
this.redisCatchStorage = redisCatchStorage; |
|||
} |
|||
} |
|||
package com.genersoft.iot.vmp.gb28181.transmit.request.impl; |
|||
|
|||
import com.genersoft.iot.vmp.conf.MediaServerConfig; |
|||
import com.genersoft.iot.vmp.gb28181.bean.Device; |
|||
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; |
|||
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; |
|||
import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; |
|||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; |
|||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; |
|||
import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor; |
|||
import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; |
|||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
|||
import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
|||
import com.genersoft.iot.vmp.vmanager.service.IPlayService; |
|||
import gov.nist.javax.sip.address.AddressImpl; |
|||
import gov.nist.javax.sip.address.SipUri; |
|||
import org.slf4j.Logger; |
|||
import org.slf4j.LoggerFactory; |
|||
import org.springframework.http.ResponseEntity; |
|||
import org.springframework.web.context.request.async.DeferredResult; |
|||
|
|||
import javax.sdp.*; |
|||
import javax.sip.InvalidArgumentException; |
|||
import javax.sip.RequestEvent; |
|||
import javax.sip.SipException; |
|||
import javax.sip.SipFactory; |
|||
import javax.sip.address.Address; |
|||
import javax.sip.address.SipURI; |
|||
import javax.sip.header.ContentTypeHeader; |
|||
import javax.sip.header.FromHeader; |
|||
import javax.sip.message.Request; |
|||
import javax.sip.message.Response; |
|||
import java.text.ParseException; |
|||
import java.util.Vector; |
|||
|
|||
/** |
|||
* @Description:处理INVITE请求 |
|||
* @author: panll |
|||
* @date: 2021年1月14日 |
|||
*/ |
|||
@SuppressWarnings("rawtypes") |
|||
public class InviteRequestProcessor extends SIPRequestAbstractProcessor { |
|||
|
|||
private final static Logger logger = LoggerFactory.getLogger(MessageRequestProcessor.class); |
|||
|
|||
private SIPCommanderFroPlatform cmderFroPlatform; |
|||
|
|||
private IVideoManagerStorager storager; |
|||
|
|||
private IRedisCatchStorage redisCatchStorage; |
|||
|
|||
private SIPCommander cmder; |
|||
|
|||
private IPlayService playService; |
|||
|
|||
private ZLMRTPServerFactory zlmrtpServerFactory; |
|||
|
|||
public ZLMRTPServerFactory getZlmrtpServerFactory() { |
|||
return zlmrtpServerFactory; |
|||
} |
|||
|
|||
public void setZlmrtpServerFactory(ZLMRTPServerFactory zlmrtpServerFactory) { |
|||
this.zlmrtpServerFactory = zlmrtpServerFactory; |
|||
} |
|||
|
|||
/** |
|||
* 处理invite请求 |
|||
* |
|||
* @param evt 请求消息 |
|||
*/ |
|||
@Override |
|||
public void process(RequestEvent evt) { |
|||
// Invite Request消息实现,此消息一般为级联消息,上级给下级发送请求视频指令
|
|||
try { |
|||
Request request = evt.getRequest(); |
|||
SipURI sipURI = (SipURI) request.getRequestURI(); |
|||
String channelId = sipURI.getUser(); |
|||
String requesterId = null; |
|||
|
|||
FromHeader fromHeader = (FromHeader) request.getHeader(FromHeader.NAME); |
|||
AddressImpl address = (AddressImpl) fromHeader.getAddress(); |
|||
SipUri uri = (SipUri) address.getURI(); |
|||
requesterId = uri.getUser(); |
|||
|
|||
if (requesterId == null || channelId == null) { |
|||
logger.info("无法从FromHeader的Address中获取到平台id,返回400"); |
|||
responseAck(evt, Response.BAD_REQUEST); // 参数不全, 发400,请求错误
|
|||
return; |
|||
} |
|||
|
|||
// 查询请求方是否上级平台
|
|||
ParentPlatform platform = storager.queryParentPlatById(requesterId); |
|||
if (platform != null) { |
|||
// 查询平台下是否有该通道
|
|||
DeviceChannel channel = storager.queryChannelInParentPlatform(requesterId, channelId); |
|||
if (channel == null) { |
|||
logger.info("通道不存在,返回404"); |
|||
responseAck(evt, Response.NOT_FOUND); // 通道不存在,发404,资源不存在
|
|||
return; |
|||
} else { |
|||
responseAck(evt, Response.CALL_IS_BEING_FORWARDED); // 通道存在,发181,呼叫转接中
|
|||
} |
|||
// 解析sdp消息, 使用jainsip 自带的sdp解析方式
|
|||
String contentString = new String(request.getRawContent()); |
|||
|
|||
// jainSip不支持y=字段, 移除移除以解析。
|
|||
int ssrcIndex = contentString.indexOf("y="); |
|||
//ssrc规定长度为10字节,不取余下长度以避免后续还有“f=”字段
|
|||
String ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12); |
|||
String substring = contentString.substring(0, contentString.indexOf("y=")); |
|||
SessionDescription sdp = SdpFactory.getInstance().createSessionDescription(substring); |
|||
|
|||
// 获取支持的格式
|
|||
Vector mediaDescriptions = sdp.getMediaDescriptions(true); |
|||
// 查看是否支持PS 负载96
|
|||
//String ip = null;
|
|||
int port = -1; |
|||
//boolean recvonly = false;
|
|||
boolean mediaTransmissionTCP = false; |
|||
Boolean tcpActive = null; |
|||
for (int i = 0; i < mediaDescriptions.size(); i++) { |
|||
MediaDescription mediaDescription = (MediaDescription) mediaDescriptions.get(i); |
|||
Media media = mediaDescription.getMedia(); |
|||
|
|||
Vector mediaFormats = media.getMediaFormats(false); |
|||
if (mediaFormats.contains("96")) { |
|||
port = media.getMediaPort(); |
|||
//String mediaType = media.getMediaType();
|
|||
String protocol = media.getProtocol(); |
|||
|
|||
// 区分TCP发流还是udp, 当前默认udp
|
|||
if ("TCP/RTP/AVP".equals(protocol)) { |
|||
String setup = mediaDescription.getAttribute("setup"); |
|||
if (setup != null) { |
|||
mediaTransmissionTCP = true; |
|||
if ("active".equals(setup)) { |
|||
tcpActive = true; |
|||
} else if ("passive".equals(setup)) { |
|||
tcpActive = false; |
|||
} |
|||
} |
|||
} |
|||
break; |
|||
} |
|||
} |
|||
if (port == -1) { |
|||
logger.info("不支持的媒体格式,返回415"); |
|||
// 回复不支持的格式
|
|||
responseAck(evt, Response.UNSUPPORTED_MEDIA_TYPE); // 不支持的格式,发415
|
|||
return; |
|||
} |
|||
String username = sdp.getOrigin().getUsername(); |
|||
String addressStr = sdp.getOrigin().getAddress(); |
|||
//String sessionName = sdp.getSessionName().getValue();
|
|||
logger.info("[上级点播]用户:{}, 地址:{}:{}, ssrc:{}", username, addressStr, port, ssrc); |
|||
|
|||
Device device = storager.queryVideoDeviceByPlatformIdAndChannelId(requesterId, channelId); |
|||
if (device == null) { |
|||
logger.warn("点播平台{}的通道{}时未找到设备信息", requesterId, channel); |
|||
responseAck(evt, Response.SERVER_INTERNAL_ERROR); |
|||
return; |
|||
} |
|||
SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(addressStr, port, ssrc, requesterId, device, channelId, |
|||
mediaTransmissionTCP); |
|||
if (tcpActive != null) { |
|||
sendRtpItem.setTcpActive(tcpActive); |
|||
} |
|||
if (sendRtpItem == null) { |
|||
logger.warn("服务器端口资源不足"); |
|||
responseAck(evt, Response.BUSY_HERE); |
|||
return; |
|||
} |
|||
|
|||
// 写入redis, 超时时回复
|
|||
redisCatchStorage.updateSendRTPSever(sendRtpItem); |
|||
// 通知下级推流,
|
|||
DeferredResult<ResponseEntity<String>> playResult = playService.play(device.getDeviceId(), channelId, (responseJSON) -> { |
|||
// 收到推流, 回复200OK, 等待ack
|
|||
sendRtpItem.setStatus(1); |
|||
redisCatchStorage.updateSendRTPSever(sendRtpItem); |
|||
// TODO 添加对tcp的支持
|
|||
MediaServerConfig mediaInfo = redisCatchStorage.getMediaInfo(); |
|||
StringBuffer content = new StringBuffer(200); |
|||
content.append("v=0\r\n"); |
|||
content.append("o=" + "00000" + " 0 0 IN IP4 " + mediaInfo.getWanIp() + "\r\n"); |
|||
content.append("s=Play\r\n"); |
|||
content.append("c=IN IP4 " + mediaInfo.getWanIp() + "\r\n"); |
|||
content.append("t=0 0\r\n"); |
|||
content.append("m=video " + sendRtpItem.getLocalPort() + " RTP/AVP 96\r\n"); |
|||
content.append("a=sendonly\r\n"); |
|||
content.append("a=rtpmap:96 PS/90000\r\n"); |
|||
content.append("y=" + ssrc + "\r\n"); |
|||
content.append("f=\r\n"); |
|||
|
|||
try { |
|||
responseAck(evt, content.toString()); |
|||
} catch (SipException e) { |
|||
e.printStackTrace(); |
|||
} catch (InvalidArgumentException e) { |
|||
e.printStackTrace(); |
|||
} catch (ParseException e) { |
|||
e.printStackTrace(); |
|||
} |
|||
}, (event -> { |
|||
// 未知错误。直接转发设备点播的错误
|
|||
Response response = null; |
|||
try { |
|||
response = getMessageFactory().createResponse(event.getResponse().getStatusCode(), evt.getRequest()); |
|||
getServerTransaction(evt).sendResponse(response); |
|||
} catch (ParseException | SipException | InvalidArgumentException e) { |
|||
e.printStackTrace(); |
|||
} |
|||
})); |
|||
if (logger.isDebugEnabled()) { |
|||
logger.debug(playResult.getResult().toString()); |
|||
} |
|||
} else { |
|||
// 非上级平台请求,查询是否设备请求(通常为接收语音广播的设备)
|
|||
Device device = storager.queryVideoDevice(requesterId); |
|||
if (device != null) { |
|||
logger.info("收到设备" + requesterId + "的语音广播Invite请求"); |
|||
responseAck(evt, Response.TRYING); |
|||
|
|||
String contentString = new String(request.getRawContent()); |
|||
// jainSip不支持y=字段, 移除移除以解析。
|
|||
String substring = contentString; |
|||
String ssrc = "0000000404"; |
|||
int ssrcIndex = contentString.indexOf("y="); |
|||
if (ssrcIndex > 0) { |
|||
substring = contentString.substring(0, ssrcIndex); |
|||
ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12); |
|||
} |
|||
ssrcIndex = substring.indexOf("f="); |
|||
if (ssrcIndex > 0) { |
|||
substring = contentString.substring(0, ssrcIndex); |
|||
} |
|||
SessionDescription sdp = SdpFactory.getInstance().createSessionDescription(substring); |
|||
|
|||
// 获取支持的格式
|
|||
Vector mediaDescriptions = sdp.getMediaDescriptions(true); |
|||
// 查看是否支持PS 负载96
|
|||
int port = -1; |
|||
//boolean recvonly = false;
|
|||
boolean mediaTransmissionTCP = false; |
|||
Boolean tcpActive = null; |
|||
for (int i = 0; i < mediaDescriptions.size(); i++) { |
|||
MediaDescription mediaDescription = (MediaDescription) mediaDescriptions.get(i); |
|||
Media media = mediaDescription.getMedia(); |
|||
|
|||
Vector mediaFormats = media.getMediaFormats(false); |
|||
if (mediaFormats.contains("8")) { |
|||
port = media.getMediaPort(); |
|||
String protocol = media.getProtocol(); |
|||
// 区分TCP发流还是udp, 当前默认udp
|
|||
if ("TCP/RTP/AVP".equals(protocol)) { |
|||
String setup = mediaDescription.getAttribute("setup"); |
|||
if (setup != null) { |
|||
mediaTransmissionTCP = true; |
|||
if ("active".equals(setup)) { |
|||
tcpActive = true; |
|||
} else if ("passive".equals(setup)) { |
|||
tcpActive = false; |
|||
} |
|||
} |
|||
} |
|||
break; |
|||
} |
|||
} |
|||
if (port == -1) { |
|||
logger.info("不支持的媒体格式,返回415"); |
|||
// 回复不支持的格式
|
|||
responseAck(evt, Response.UNSUPPORTED_MEDIA_TYPE); // 不支持的格式,发415
|
|||
return; |
|||
} |
|||
String username = sdp.getOrigin().getUsername(); |
|||
String addressStr = sdp.getOrigin().getAddress(); |
|||
logger.info("设备{}请求语音流,地址:{}:{},ssrc:{}", username, addressStr, port, ssrc); |
|||
|
|||
|
|||
} else { |
|||
logger.warn("来自无效设备/平台的请求"); |
|||
responseAck(evt, Response.BAD_REQUEST); |
|||
} |
|||
} |
|||
|
|||
} catch (SipException | InvalidArgumentException | ParseException e) { |
|||
e.printStackTrace(); |
|||
logger.warn("sdp解析错误"); |
|||
e.printStackTrace(); |
|||
} catch (SdpParseException e) { |
|||
e.printStackTrace(); |
|||
} catch (SdpException e) { |
|||
e.printStackTrace(); |
|||
} |
|||
} |
|||
|
|||
/*** |
|||
* 回复状态码 |
|||
* 100 trying |
|||
* 200 OK |
|||
* 400 |
|||
* 404 |
|||
* @param evt |
|||
* @throws SipException |
|||
* @throws InvalidArgumentException |
|||
* @throws ParseException |
|||
*/ |
|||
private void responseAck(RequestEvent evt, int statusCode) throws SipException, InvalidArgumentException, ParseException { |
|||
Response response = getMessageFactory().createResponse(statusCode, evt.getRequest()); |
|||
getServerTransaction(evt).sendResponse(response); |
|||
} |
|||
|
|||
/** |
|||
* 回复带sdp的200 |
|||
* |
|||
* @param evt |
|||
* @param sdp |
|||
* @throws SipException |
|||
* @throws InvalidArgumentException |
|||
* @throws ParseException |
|||
*/ |
|||
private void responseAck(RequestEvent evt, String sdp) throws SipException, InvalidArgumentException, ParseException { |
|||
Response response = getMessageFactory().createResponse(Response.OK, evt.getRequest()); |
|||
SipFactory sipFactory = SipFactory.getInstance(); |
|||
ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("APPLICATION", "SDP"); |
|||
response.setContent(sdp, contentTypeHeader); |
|||
|
|||
SipURI sipURI = (SipURI) evt.getRequest().getRequestURI(); |
|||
|
|||
Address concatAddress = sipFactory.createAddressFactory().createAddress( |
|||
sipFactory.createAddressFactory().createSipURI(sipURI.getUser(), sipURI.getHost() + ":" + sipURI.getPort() |
|||
)); |
|||
response.addHeader(sipFactory.createHeaderFactory().createContactHeader(concatAddress)); |
|||
getServerTransaction(evt).sendResponse(response); |
|||
} |
|||
|
|||
|
|||
public SIPCommanderFroPlatform getCmderFroPlatform() { |
|||
return cmderFroPlatform; |
|||
} |
|||
|
|||
public void setCmderFroPlatform(SIPCommanderFroPlatform cmderFroPlatform) { |
|||
this.cmderFroPlatform = cmderFroPlatform; |
|||
} |
|||
|
|||
public IVideoManagerStorager getStorager() { |
|||
return storager; |
|||
} |
|||
|
|||
public void setStorager(IVideoManagerStorager storager) { |
|||
this.storager = storager; |
|||
} |
|||
|
|||
public SIPCommander getCmder() { |
|||
return cmder; |
|||
} |
|||
|
|||
public void setCmder(SIPCommander cmder) { |
|||
this.cmder = cmder; |
|||
} |
|||
|
|||
public IPlayService getPlayService() { |
|||
return playService; |
|||
} |
|||
|
|||
public void setPlayService(IPlayService playService) { |
|||
this.playService = playService; |
|||
} |
|||
|
|||
public IRedisCatchStorage getRedisCatchStorage() { |
|||
return redisCatchStorage; |
|||
} |
|||
|
|||
public void setRedisCatchStorage(IRedisCatchStorage redisCatchStorage) { |
|||
this.redisCatchStorage = redisCatchStorage; |
|||
} |
|||
} |
|||
|
@ -1,391 +1,388 @@ |
|||
package com.genersoft.iot.vmp.storager.impl; |
|||
|
|||
import java.util.*; |
|||
|
|||
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; |
|||
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; |
|||
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch; |
|||
import com.genersoft.iot.vmp.gb28181.bean.*; |
|||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
|||
import com.genersoft.iot.vmp.gb28181.bean.MobilePosition; |
|||
import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper; |
|||
import com.genersoft.iot.vmp.storager.dao.DeviceMapper; |
|||
import com.genersoft.iot.vmp.storager.dao.ParentPlatformMapper; |
|||
import com.genersoft.iot.vmp.storager.dao.PatformChannelMapper; |
|||
import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
|||
import com.genersoft.iot.vmp.storager.dao.*; |
|||
import com.genersoft.iot.vmp.vmanager.platform.bean.ChannelReduce; |
|||
import com.genersoft.iot.vmp.storager.dao.DeviceMobilePositionMapper; |
|||
import com.github.pagehelper.PageHelper; |
|||
import com.github.pagehelper.PageInfo; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
import com.genersoft.iot.vmp.gb28181.bean.Device; |
|||
import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
|||
import org.springframework.transaction.annotation.Transactional; |
|||
|
|||
/** |
|||
import java.util.ArrayList; |
|||
import java.util.HashMap; |
|||
import java.util.List; |
|||
import java.util.Map; |
|||
|
|||
/** |
|||
* @Description:视频设备数据存储-jdbc实现 |
|||
* @author: swwheihei |
|||
* @date: 2020年5月6日 下午2:31:42 |
|||
* @date: 2020年5月6日 下午2:31:42 |
|||
*/ |
|||
@SuppressWarnings("rawtypes") |
|||
@Component |
|||
public class VideoManagerStoragerImpl implements IVideoManagerStorager { |
|||
|
|||
@Autowired |
|||
@Autowired |
|||
private DeviceMapper deviceMapper; |
|||
|
|||
@Autowired |
|||
private DeviceChannelMapper deviceChannelMapper; |
|||
@Autowired |
|||
private DeviceChannelMapper deviceChannelMapper; |
|||
|
|||
@Autowired |
|||
private DeviceMobilePositionMapper deviceMobilePositionMapper; |
|||
@Autowired |
|||
private DeviceMobilePositionMapper deviceMobilePositionMapper; |
|||
|
|||
@Autowired |
|||
@Autowired |
|||
private ParentPlatformMapper platformMapper; |
|||
|
|||
@Autowired |
|||
@Autowired |
|||
private IRedisCatchStorage redisCatchStorage; |
|||
|
|||
@Autowired |
|||
@Autowired |
|||
private PatformChannelMapper patformChannelMapper; |
|||
|
|||
|
|||
|
|||
|
|||
/** |
|||
* 根据设备ID判断设备是否存在 |
|||
* |
|||
* @param deviceId 设备ID |
|||
* @return true:存在 false:不存在 |
|||
*/ |
|||
@Override |
|||
public boolean exists(String deviceId) { |
|||
return deviceMapper.getDeviceByDeviceId(deviceId) != null; |
|||
} |
|||
|
|||
/** |
|||
* 视频设备创建 |
|||
* |
|||
* @param device 设备对象 |
|||
* @return true:创建成功 false:创建失败 |
|||
*/ |
|||
@Override |
|||
public synchronized boolean create(Device device) { |
|||
return deviceMapper.add(device) > 0; |
|||
} |
|||
|
|||
|
|||
|
|||
/** |
|||
* 视频设备更新 |
|||
* |
|||
* @param device 设备对象 |
|||
* @return true:更新成功 false:更新失败 |
|||
*/ |
|||
@Override |
|||
public synchronized boolean updateDevice(Device device) { |
|||
Device deviceByDeviceId = deviceMapper.getDeviceByDeviceId(device.getDeviceId()); |
|||
if (deviceByDeviceId == null) { |
|||
return deviceMapper.add(device) > 0; |
|||
}else { |
|||
return deviceMapper.update(device) > 0; |
|||
} |
|||
|
|||
} |
|||
|
|||
@Override |
|||
public synchronized void updateChannel(String deviceId, DeviceChannel channel) { |
|||
String channelId = channel.getChannelId(); |
|||
channel.setDeviceId(deviceId); |
|||
DeviceChannel deviceChannel = deviceChannelMapper.queryChannel(deviceId, channelId); |
|||
if (deviceChannel == null) { |
|||
deviceChannelMapper.add(channel); |
|||
}else { |
|||
deviceChannelMapper.update(channel); |
|||
} |
|||
} |
|||
|
|||
@Override |
|||
public void startPlay(String deviceId, String channelId, String streamId) { |
|||
deviceChannelMapper.startPlay(deviceId, channelId, streamId); |
|||
} |
|||
|
|||
@Override |
|||
public void stopPlay(String deviceId, String channelId) { |
|||
deviceChannelMapper.stopPlay(deviceId, channelId); |
|||
} |
|||
|
|||
/** |
|||
* 获取设备 |
|||
* |
|||
* @param deviceId 设备ID |
|||
* @return Device 设备对象 |
|||
*/ |
|||
@Override |
|||
public Device queryVideoDevice(String deviceId) { |
|||
return deviceMapper.getDeviceByDeviceId(deviceId); |
|||
} |
|||
|
|||
@Override |
|||
public PageInfo queryChannelsByDeviceId(String deviceId, String query, Boolean hasSubChannel, Boolean online, int page, int count) { |
|||
// 获取到所有正在播放的流
|
|||
PageHelper.startPage(page, count); |
|||
List<DeviceChannel> all = deviceChannelMapper.queryChannelsByDeviceId(deviceId, null, query, hasSubChannel, online); |
|||
return new PageInfo<>(all); |
|||
} |
|||
|
|||
@Override |
|||
public List<DeviceChannel> queryChannelsByDeviceId(String deviceId) { |
|||
return deviceChannelMapper.queryChannelsByDeviceId(deviceId, null,null, null, null); |
|||
} |
|||
|
|||
@Override |
|||
public PageInfo<DeviceChannel> querySubChannels(String deviceId, String parentChannelId, String query, Boolean hasSubChannel, String online, int page, int count) { |
|||
PageHelper.startPage(page, count); |
|||
List<DeviceChannel> all = deviceChannelMapper.queryChannelsByDeviceId(deviceId, parentChannelId, null, null, null); |
|||
return new PageInfo<>(all); |
|||
} |
|||
|
|||
@Override |
|||
public DeviceChannel queryChannel(String deviceId, String channelId) { |
|||
return deviceChannelMapper.queryChannel(deviceId, channelId); |
|||
} |
|||
|
|||
|
|||
/** |
|||
* 获取多个设备 |
|||
* |
|||
* @param page 当前页数 |
|||
* @param count 每页数量 |
|||
* @return PageInfo<Device> 分页设备对象数组 |
|||
*/ |
|||
@Override |
|||
public PageInfo<Device> queryVideoDeviceList(int page, int count) { |
|||
PageHelper.startPage(page, count); |
|||
List<Device> all = deviceMapper.getDevices(); |
|||
return new PageInfo<>(all); |
|||
} |
|||
|
|||
/** |
|||
* 获取多个设备 |
|||
* |
|||
* @return List<Device> 设备对象数组 |
|||
*/ |
|||
@Override |
|||
public List<Device> queryVideoDeviceList() { |
|||
|
|||
List<Device> deviceList = deviceMapper.getDevices(); |
|||
return deviceList; |
|||
} |
|||
|
|||
/** |
|||
* 删除设备 |
|||
* |
|||
* @param deviceId 设备ID |
|||
* @return true:删除成功 false:删除失败 |
|||
*/ |
|||
@Override |
|||
public boolean delete(String deviceId) { |
|||
int result = deviceMapper.del(deviceId); |
|||
|
|||
return result > 0; |
|||
} |
|||
|
|||
/** |
|||
* 更新设备在线 |
|||
* |
|||
* @param deviceId 设备ID |
|||
* @return true:更新成功 false:更新失败 |
|||
*/ |
|||
@Override |
|||
public synchronized boolean online(String deviceId) { |
|||
Device device = deviceMapper.getDeviceByDeviceId(deviceId); |
|||
if (device == null) { |
|||
return false; |
|||
} |
|||
device.setOnline(1); |
|||
System.out.println("更新设备在线"); |
|||
return deviceMapper.update(device) > 0; |
|||
} |
|||
|
|||
/** |
|||
* 更新设备离线 |
|||
* |
|||
* @param deviceId 设备ID |
|||
* @return true:更新成功 false:更新失败 |
|||
*/ |
|||
@Override |
|||
public synchronized boolean outline(String deviceId) { |
|||
Device device = deviceMapper.getDeviceByDeviceId(deviceId); |
|||
device.setOnline(0); |
|||
System.out.println("更新设备离线"); |
|||
return deviceMapper.update(device) > 0; |
|||
} |
|||
|
|||
/** |
|||
* 清空通道 |
|||
* @param deviceId |
|||
*/ |
|||
@Override |
|||
public void cleanChannelsForDevice(String deviceId) { |
|||
deviceChannelMapper.cleanChannelsByDeviceId(deviceId); |
|||
} |
|||
|
|||
/** |
|||
* 添加Mobile Position设备移动位置 |
|||
* @param MobilePosition |
|||
*/ |
|||
@Override |
|||
public synchronized boolean insertMobilePosition(MobilePosition mobilePosition) { |
|||
return deviceMobilePositionMapper.insertNewPosition(mobilePosition) > 0; |
|||
} |
|||
|
|||
/** |
|||
* 查询移动位置轨迹 |
|||
* @param deviceId |
|||
* @param startTime |
|||
* @param endTime |
|||
*/ |
|||
@Override |
|||
public synchronized List<MobilePosition> queryMobilePositions(String deviceId, String startTime, String endTime) { |
|||
return deviceMobilePositionMapper.queryPositionByDeviceIdAndTime(deviceId, startTime, endTime); |
|||
} |
|||
|
|||
@Override |
|||
public boolean addParentPlatform(ParentPlatform parentPlatform) { |
|||
int result = platformMapper.addParentPlatform(parentPlatform); |
|||
return result > 0; |
|||
} |
|||
|
|||
@Override |
|||
public boolean updateParentPlatform(ParentPlatform parentPlatform) { |
|||
int result = 0; |
|||
ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(parentPlatform.getServerGBId()); // .getDeviceGBId());
|
|||
if ( platformMapper.getParentPlatById(parentPlatform.getServerGBId()) == null) { |
|||
result = platformMapper.addParentPlatform(parentPlatform); |
|||
|
|||
if (parentPlatformCatch == null) { |
|||
parentPlatformCatch = new ParentPlatformCatch(); |
|||
parentPlatformCatch.setParentPlatform(parentPlatform); |
|||
parentPlatformCatch.setId(parentPlatform.getServerGBId()); |
|||
} |
|||
}else { |
|||
result = platformMapper.updateParentPlatform(parentPlatform); |
|||
} |
|||
// 更新缓存
|
|||
parentPlatformCatch.setParentPlatform(parentPlatform); |
|||
redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch); |
|||
return result > 0; |
|||
} |
|||
|
|||
@Transactional |
|||
@Override |
|||
public boolean deleteParentPlatform(ParentPlatform parentPlatform) { |
|||
int result = platformMapper.delParentPlatform(parentPlatform); |
|||
// 删除关联的通道
|
|||
patformChannelMapper.cleanChannelForGB(parentPlatform.getServerGBId()); |
|||
return result > 0; |
|||
} |
|||
|
|||
@Override |
|||
public PageInfo<ParentPlatform> queryParentPlatformList(int page, int count) { |
|||
PageHelper.startPage(page, count); |
|||
List<ParentPlatform> all = platformMapper.getParentPlatformList(); |
|||
return new PageInfo<>(all); |
|||
} |
|||
|
|||
@Override |
|||
public ParentPlatform queryParentPlatById(String platformGbId) { |
|||
return platformMapper.getParentPlatById(platformGbId); |
|||
} |
|||
|
|||
@Override |
|||
public List<ParentPlatform> queryEnableParentPlatformList(boolean enable) { |
|||
return platformMapper.getEnableParentPlatformList(enable); |
|||
} |
|||
|
|||
@Override |
|||
public void outlineForAllParentPlatform() { |
|||
platformMapper.outlineForAllParentPlatform(); |
|||
} |
|||
|
|||
|
|||
@Override |
|||
public PageInfo<ChannelReduce> queryAllChannelList(int page, int count, String query, Boolean online, |
|||
Boolean channelType, String platformId, Boolean inPlatform) { |
|||
PageHelper.startPage(page, count); |
|||
List<ChannelReduce> all = deviceChannelMapper.queryChannelListInAll(query, online, channelType, platformId, inPlatform); |
|||
return new PageInfo<>(all); |
|||
} |
|||
|
|||
@Override |
|||
public List<ChannelReduce> queryChannelListInParentPlatform(String platformId) { |
|||
|
|||
return deviceChannelMapper.queryChannelListInAll(null, null, null, platformId, true); |
|||
} |
|||
|
|||
@Override |
|||
public int updateChannelForGB(String platformId, List<ChannelReduce> channelReduces) { |
|||
|
|||
Map<String, ChannelReduce> deviceAndChannels = new HashMap<>(); |
|||
for (ChannelReduce channelReduce : channelReduces) { |
|||
deviceAndChannels.put(channelReduce.getDeviceId() + "_" + channelReduce.getChannelId(), channelReduce); |
|||
} |
|||
List<String> deviceAndChannelList = new ArrayList<>(deviceAndChannels.keySet()); |
|||
// 查询当前已经存在的
|
|||
List<String> relatedPlatformchannels = patformChannelMapper.findChannelRelatedPlatform(platformId, deviceAndChannelList); |
|||
if (relatedPlatformchannels != null) { |
|||
deviceAndChannelList.removeAll(relatedPlatformchannels); |
|||
} |
|||
for (String relatedPlatformchannel : relatedPlatformchannels) { |
|||
deviceAndChannels.remove(relatedPlatformchannel); |
|||
} |
|||
List<ChannelReduce> channelReducesToAdd = new ArrayList<>(deviceAndChannels.values()); |
|||
// 对剩下的数据进行存储
|
|||
int result = 0; |
|||
if (channelReducesToAdd.size() > 0) { |
|||
result = patformChannelMapper.addChannels(platformId, channelReducesToAdd); |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
|
|||
|
|||
@Override |
|||
public int delChannelForGB(String platformId, List<ChannelReduce> channelReduces) { |
|||
|
|||
int result = patformChannelMapper.delChannelForGB(platformId, channelReduces); |
|||
|
|||
return result; |
|||
} |
|||
|
|||
@Override |
|||
public DeviceChannel queryChannelInParentPlatform(String platformId, String channelId) { |
|||
DeviceChannel channel = patformChannelMapper.queryChannelInParentPlatform(platformId, channelId); |
|||
return channel; |
|||
} |
|||
|
|||
@Override |
|||
public Device queryVideoDeviceByPlatformIdAndChannelId(String platformId, String channelId) { |
|||
Device device = patformChannelMapper.queryVideoDeviceByPlatformIdAndChannelId(platformId, channelId); |
|||
return device; |
|||
} |
|||
|
|||
/** |
|||
* 查询最新移动位置 |
|||
* @param deviceId |
|||
*/ |
|||
@Override |
|||
public MobilePosition queryLatestPosition(String deviceId) { |
|||
return deviceMobilePositionMapper.queryLatestPositionByDevice(deviceId); |
|||
} |
|||
|
|||
/** |
|||
* 删除指定设备的所有移动位置 |
|||
* @param deviceId |
|||
*/ |
|||
public int clearMobilePositionsByDeviceId(String deviceId) { |
|||
return deviceMobilePositionMapper.clearMobilePositionsByDeviceId(deviceId); |
|||
} |
|||
/** |
|||
* 根据设备ID判断设备是否存在 |
|||
* |
|||
* @param deviceId 设备ID |
|||
* @return true:存在 false:不存在 |
|||
*/ |
|||
@Override |
|||
public boolean exists(String deviceId) { |
|||
return deviceMapper.getDeviceByDeviceId(deviceId) != null; |
|||
} |
|||
|
|||
/** |
|||
* 视频设备创建 |
|||
* |
|||
* @param device 设备对象 |
|||
* @return true:创建成功 false:创建失败 |
|||
*/ |
|||
@Override |
|||
public synchronized boolean create(Device device) { |
|||
return deviceMapper.add(device) > 0; |
|||
} |
|||
|
|||
|
|||
/** |
|||
* 视频设备更新 |
|||
* |
|||
* @param device 设备对象 |
|||
* @return true:更新成功 false:更新失败 |
|||
*/ |
|||
@Override |
|||
public synchronized boolean updateDevice(Device device) { |
|||
Device deviceByDeviceId = deviceMapper.getDeviceByDeviceId(device.getDeviceId()); |
|||
if (deviceByDeviceId == null) { |
|||
return deviceMapper.add(device) > 0; |
|||
} else { |
|||
return deviceMapper.update(device) > 0; |
|||
} |
|||
|
|||
} |
|||
|
|||
@Override |
|||
public synchronized void updateChannel(String deviceId, DeviceChannel channel) { |
|||
String channelId = channel.getChannelId(); |
|||
channel.setDeviceId(deviceId); |
|||
DeviceChannel deviceChannel = deviceChannelMapper.queryChannel(deviceId, channelId); |
|||
if (deviceChannel == null) { |
|||
deviceChannelMapper.add(channel); |
|||
} else { |
|||
deviceChannelMapper.update(channel); |
|||
} |
|||
} |
|||
|
|||
@Override |
|||
public void startPlay(String deviceId, String channelId, String streamId) { |
|||
deviceChannelMapper.startPlay(deviceId, channelId, streamId); |
|||
} |
|||
|
|||
@Override |
|||
public void stopPlay(String deviceId, String channelId) { |
|||
deviceChannelMapper.stopPlay(deviceId, channelId); |
|||
} |
|||
|
|||
/** |
|||
* 获取设备 |
|||
* |
|||
* @param deviceId 设备ID |
|||
* @return Device 设备对象 |
|||
*/ |
|||
@Override |
|||
public Device queryVideoDevice(String deviceId) { |
|||
return deviceMapper.getDeviceByDeviceId(deviceId); |
|||
} |
|||
|
|||
@Override |
|||
public PageInfo queryChannelsByDeviceId(String deviceId, String query, Boolean hasSubChannel, Boolean online, int page, int count) { |
|||
// 获取到所有正在播放的流
|
|||
PageHelper.startPage(page, count); |
|||
List<DeviceChannel> all = deviceChannelMapper.queryChannelsByDeviceId(deviceId, null, query, hasSubChannel, online); |
|||
return new PageInfo<>(all); |
|||
} |
|||
|
|||
@Override |
|||
public List<DeviceChannel> queryChannelsByDeviceId(String deviceId) { |
|||
return deviceChannelMapper.queryChannelsByDeviceId(deviceId, null, null, null, null); |
|||
} |
|||
|
|||
@Override |
|||
public PageInfo<DeviceChannel> querySubChannels(String deviceId, String parentChannelId, String query, Boolean hasSubChannel, String online, int page, int count) { |
|||
PageHelper.startPage(page, count); |
|||
List<DeviceChannel> all = deviceChannelMapper.queryChannelsByDeviceId(deviceId, parentChannelId, null, null, null); |
|||
return new PageInfo<>(all); |
|||
} |
|||
|
|||
@Override |
|||
public DeviceChannel queryChannel(String deviceId, String channelId) { |
|||
return deviceChannelMapper.queryChannel(deviceId, channelId); |
|||
} |
|||
|
|||
|
|||
/** |
|||
* 获取多个设备 |
|||
* |
|||
* @param page 当前页数 |
|||
* @param count 每页数量 |
|||
* @return PageInfo<Device> 分页设备对象数组 |
|||
*/ |
|||
@Override |
|||
public PageInfo<Device> queryVideoDeviceList(int page, int count) { |
|||
PageHelper.startPage(page, count); |
|||
List<Device> all = deviceMapper.getDevices(); |
|||
return new PageInfo<>(all); |
|||
} |
|||
|
|||
/** |
|||
* 获取多个设备 |
|||
* |
|||
* @return List<Device> 设备对象数组 |
|||
*/ |
|||
@Override |
|||
public List<Device> queryVideoDeviceList() { |
|||
|
|||
List<Device> deviceList = deviceMapper.getDevices(); |
|||
return deviceList; |
|||
} |
|||
|
|||
/** |
|||
* 删除设备 |
|||
* |
|||
* @param deviceId 设备ID |
|||
* @return true:删除成功 false:删除失败 |
|||
*/ |
|||
@Override |
|||
public boolean delete(String deviceId) { |
|||
int result = deviceMapper.del(deviceId); |
|||
|
|||
return result > 0; |
|||
} |
|||
|
|||
/** |
|||
* 更新设备在线 |
|||
* |
|||
* @param deviceId 设备ID |
|||
* @return true:更新成功 false:更新失败 |
|||
*/ |
|||
@Override |
|||
public synchronized boolean online(String deviceId) { |
|||
Device device = deviceMapper.getDeviceByDeviceId(deviceId); |
|||
if (device == null) { |
|||
return false; |
|||
} |
|||
device.setOnline(1); |
|||
System.out.println("更新设备在线"); |
|||
return deviceMapper.update(device) > 0; |
|||
} |
|||
|
|||
/** |
|||
* 更新设备离线 |
|||
* |
|||
* @param deviceId 设备ID |
|||
* @return true:更新成功 false:更新失败 |
|||
*/ |
|||
@Override |
|||
public synchronized boolean outline(String deviceId) { |
|||
Device device = deviceMapper.getDeviceByDeviceId(deviceId); |
|||
device.setOnline(0); |
|||
System.out.println("更新设备离线"); |
|||
return deviceMapper.update(device) > 0; |
|||
} |
|||
|
|||
/** |
|||
* 清空通道 |
|||
* |
|||
* @param deviceId |
|||
*/ |
|||
@Override |
|||
public void cleanChannelsForDevice(String deviceId) { |
|||
deviceChannelMapper.cleanChannelsByDeviceId(deviceId); |
|||
} |
|||
|
|||
/** |
|||
* 添加Mobile Position设备移动位置 |
|||
* |
|||
* @param mobilePosition |
|||
*/ |
|||
@Override |
|||
public synchronized boolean insertMobilePosition(MobilePosition mobilePosition) { |
|||
return deviceMobilePositionMapper.insertNewPosition(mobilePosition) > 0; |
|||
} |
|||
|
|||
/** |
|||
* 查询移动位置轨迹 |
|||
* |
|||
* @param deviceId |
|||
* @param startTime |
|||
* @param endTime |
|||
*/ |
|||
@Override |
|||
public synchronized List<MobilePosition> queryMobilePositions(String deviceId, String startTime, String endTime) { |
|||
return deviceMobilePositionMapper.queryPositionByDeviceIdAndTime(deviceId, startTime, endTime); |
|||
} |
|||
|
|||
@Override |
|||
public boolean addParentPlatform(ParentPlatform parentPlatform) { |
|||
int result = platformMapper.addParentPlatform(parentPlatform); |
|||
return result > 0; |
|||
} |
|||
|
|||
@Override |
|||
public boolean updateParentPlatform(ParentPlatform parentPlatform) { |
|||
int result = 0; |
|||
ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(parentPlatform.getServerGBId()); // .getDeviceGBId());
|
|||
if (platformMapper.getParentPlatById(parentPlatform.getServerGBId()) == null) { |
|||
result = platformMapper.addParentPlatform(parentPlatform); |
|||
|
|||
if (parentPlatformCatch == null) { |
|||
parentPlatformCatch = new ParentPlatformCatch(); |
|||
parentPlatformCatch.setParentPlatform(parentPlatform); |
|||
parentPlatformCatch.setId(parentPlatform.getServerGBId()); |
|||
} |
|||
} else { |
|||
result = platformMapper.updateParentPlatform(parentPlatform); |
|||
} |
|||
// 更新缓存
|
|||
parentPlatformCatch.setParentPlatform(parentPlatform); |
|||
redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch); |
|||
return result > 0; |
|||
} |
|||
|
|||
@Transactional |
|||
@Override |
|||
public boolean deleteParentPlatform(ParentPlatform parentPlatform) { |
|||
int result = platformMapper.delParentPlatform(parentPlatform); |
|||
// 删除关联的通道
|
|||
patformChannelMapper.cleanChannelForGB(parentPlatform.getServerGBId()); |
|||
return result > 0; |
|||
} |
|||
|
|||
@Override |
|||
public PageInfo<ParentPlatform> queryParentPlatformList(int page, int count) { |
|||
PageHelper.startPage(page, count); |
|||
List<ParentPlatform> all = platformMapper.getParentPlatformList(); |
|||
return new PageInfo<>(all); |
|||
} |
|||
|
|||
@Override |
|||
public ParentPlatform queryParentPlatById(String platformGbId) { |
|||
return platformMapper.getParentPlatById(platformGbId); |
|||
} |
|||
|
|||
@Override |
|||
public List<ParentPlatform> queryEnableParentPlatformList(boolean enable) { |
|||
return platformMapper.getEnableParentPlatformList(enable); |
|||
} |
|||
|
|||
@Override |
|||
public void outlineForAllParentPlatform() { |
|||
platformMapper.outlineForAllParentPlatform(); |
|||
} |
|||
|
|||
|
|||
@Override |
|||
public PageInfo<ChannelReduce> queryAllChannelList(int page, int count, String query, Boolean online, |
|||
Boolean channelType, String platformId, Boolean inPlatform) { |
|||
PageHelper.startPage(page, count); |
|||
List<ChannelReduce> all = deviceChannelMapper.queryChannelListInAll(query, online, channelType, platformId, inPlatform); |
|||
return new PageInfo<>(all); |
|||
} |
|||
|
|||
@Override |
|||
public List<ChannelReduce> queryChannelListInParentPlatform(String platformId) { |
|||
|
|||
return deviceChannelMapper.queryChannelListInAll(null, null, null, platformId, true); |
|||
} |
|||
|
|||
@Override |
|||
public int updateChannelForGB(String platformId, List<ChannelReduce> channelReduces) { |
|||
|
|||
Map<String, ChannelReduce> deviceAndChannels = new HashMap<>(); |
|||
for (ChannelReduce channelReduce : channelReduces) { |
|||
deviceAndChannels.put(channelReduce.getDeviceId() + "_" + channelReduce.getChannelId(), channelReduce); |
|||
} |
|||
List<String> deviceAndChannelList = new ArrayList<>(deviceAndChannels.keySet()); |
|||
// 查询当前已经存在的
|
|||
List<String> relatedPlatformchannels = patformChannelMapper.findChannelRelatedPlatform(platformId, deviceAndChannelList); |
|||
if (relatedPlatformchannels != null) { |
|||
deviceAndChannelList.removeAll(relatedPlatformchannels); |
|||
} |
|||
for (String relatedPlatformchannel : relatedPlatformchannels) { |
|||
deviceAndChannels.remove(relatedPlatformchannel); |
|||
} |
|||
List<ChannelReduce> channelReducesToAdd = new ArrayList<>(deviceAndChannels.values()); |
|||
// 对剩下的数据进行存储
|
|||
int result = 0; |
|||
if (channelReducesToAdd.size() > 0) { |
|||
result = patformChannelMapper.addChannels(platformId, channelReducesToAdd); |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
|
|||
|
|||
@Override |
|||
public int delChannelForGB(String platformId, List<ChannelReduce> channelReduces) { |
|||
|
|||
int result = patformChannelMapper.delChannelForGB(platformId, channelReduces); |
|||
|
|||
return result; |
|||
} |
|||
|
|||
@Override |
|||
public DeviceChannel queryChannelInParentPlatform(String platformId, String channelId) { |
|||
DeviceChannel channel = patformChannelMapper.queryChannelInParentPlatform(platformId, channelId); |
|||
return channel; |
|||
} |
|||
|
|||
@Override |
|||
public Device queryVideoDeviceByPlatformIdAndChannelId(String platformId, String channelId) { |
|||
Device device = patformChannelMapper.queryVideoDeviceByPlatformIdAndChannelId(platformId, channelId); |
|||
return device; |
|||
} |
|||
|
|||
/** |
|||
* 查询最新移动位置 |
|||
* |
|||
* @param deviceId |
|||
*/ |
|||
@Override |
|||
public MobilePosition queryLatestPosition(String deviceId) { |
|||
return deviceMobilePositionMapper.queryLatestPositionByDevice(deviceId); |
|||
} |
|||
|
|||
/** |
|||
* 删除指定设备的所有移动位置 |
|||
* |
|||
* @param deviceId |
|||
*/ |
|||
@Override |
|||
public int clearMobilePositionsByDeviceId(String deviceId) { |
|||
return deviceMobilePositionMapper.clearMobilePositionsByDeviceId(deviceId); |
|||
} |
|||
|
|||
} |
|||
|
@ -1,37 +0,0 @@ |
|||
package com.genersoft.iot.vmp.vmanager.play.bean; |
|||
|
|||
import com.genersoft.iot.vmp.gb28181.bean.Device; |
|||
import org.springframework.http.ResponseEntity; |
|||
import org.springframework.web.context.request.async.DeferredResult; |
|||
|
|||
public class PlayResult { |
|||
|
|||
private DeferredResult<ResponseEntity<String>> result; |
|||
private String uuid; |
|||
|
|||
private Device device; |
|||
|
|||
public DeferredResult<ResponseEntity<String>> getResult() { |
|||
return result; |
|||
} |
|||
|
|||
public void setResult(DeferredResult<ResponseEntity<String>> result) { |
|||
this.result = result; |
|||
} |
|||
|
|||
public String getUuid() { |
|||
return uuid; |
|||
} |
|||
|
|||
public void setUuid(String uuid) { |
|||
this.uuid = uuid; |
|||
} |
|||
|
|||
public Device getDevice() { |
|||
return device; |
|||
} |
|||
|
|||
public void setDevice(Device device) { |
|||
this.device = device; |
|||
} |
|||
} |
@ -1,102 +1,102 @@ |
|||
spring: |
|||
# REDIS数据库配置 |
|||
redis: |
|||
# [必须修改] Redis服务器IP, REDIS安装在本机的,使用127.0.0.1 |
|||
host: 127.0.0.1 |
|||
# [必须修改] 端口号 |
|||
port: 6379 |
|||
# [可选] 数据库 DB |
|||
database: 6 |
|||
# [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接 |
|||
password: |
|||
# [可选] 超时时间 |
|||
timeout: 10000 |
|||
poolMaxTotal: 1000 |
|||
poolMaxIdle: 50 |
|||
poolMaxWait: 500 |
|||
# [可选] jdbc数据库配置, 项目使用sqlite作为数据库,一般不需要配置 |
|||
datasource: |
|||
# name: eiot |
|||
# url: jdbc:mysql://127.0.0.1:3306/eiot?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true |
|||
# username: |
|||
# password: |
|||
# type: com.alibaba.druid.pool.DruidDataSource |
|||
# driver-class-name: com.mysql.jdbc.Driver |
|||
name: eiot |
|||
url: jdbc:sqlite::resource:wvp.sqlite |
|||
username: |
|||
password: |
|||
type: com.alibaba.druid.pool.DruidDataSource |
|||
driver-class-name: org.sqlite.JDBC |
|||
max-active: 1 |
|||
min-idle: 1 |
|||
# REDIS数据库配置 |
|||
redis: |
|||
# [必须修改] Redis服务器IP, REDIS安装在本机的,使用127.0.0.1 |
|||
host: 127.0.0.1 |
|||
# [必须修改] 端口号 |
|||
port: 6379 |
|||
# [可选] 数据库 DB |
|||
database: 6 |
|||
# [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接 |
|||
password: 111111 |
|||
# [可选] 超时时间 |
|||
timeout: 10000 |
|||
poolMaxTotal: 1000 |
|||
poolMaxIdle: 50 |
|||
poolMaxWait: 500 |
|||
# [可选] jdbc数据库配置, 项目使用sqlite作为数据库,一般不需要配置 |
|||
datasource: |
|||
# name: eiot |
|||
# url: jdbc:mysql://127.0.0.1:3306/eiot?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true |
|||
# username: |
|||
# password: |
|||
# type: com.alibaba.druid.pool.DruidDataSource |
|||
# driver-class-name: com.mysql.jdbc.Driver |
|||
name: eiot |
|||
url: jdbc:sqlite::resource:wvp.sqlite |
|||
username: |
|||
password: |
|||
type: com.alibaba.druid.pool.DruidDataSource |
|||
driver-class-name: org.sqlite.JDBC |
|||
max-active: 1 |
|||
min-idle: 1 |
|||
|
|||
# [可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口 |
|||
server: |
|||
port: 18080 |
|||
port: 18080 |
|||
|
|||
# 作为28181服务器的配置 |
|||
sip: |
|||
# [必须修改] 本机的内网IP, 必须是网卡上的IP |
|||
ip: 192.168.0.100 |
|||
# [可选] 28181服务监听的端口 |
|||
port: 5060 |
|||
# 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) |
|||
# 后两位为行业编码,定义参照附录D.3 |
|||
# 3701020049标识山东济南历下区 信息行业接入 |
|||
# [可选] |
|||
domain: 4401020049 |
|||
# [可选] |
|||
id: 44010200492000000001 |
|||
# [可选] 默认设备认证密码,后续扩展使用设备单独密码 |
|||
password: admin123 |
|||
# [必须修改] 本机的内网IP, 必须是网卡上的IP |
|||
ip: 192.168.1.105 |
|||
# [可选] 28181服务监听的端口 |
|||
port: 5060 |
|||
# 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) |
|||
# 后两位为行业编码,定义参照附录D.3 |
|||
# 3701020049标识山东济南历下区 信息行业接入 |
|||
# [可选] |
|||
domain: 4401020049 |
|||
# [可选] |
|||
id: 44010200492000000001 |
|||
# [可选] 默认设备认证密码,后续扩展使用设备单独密码 |
|||
password: admin123 |
|||
|
|||
# 登陆的用户名密码 |
|||
auth: |
|||
# [可选] 用户名 |
|||
username: admin |
|||
# [可选] 密码, 默认为admin |
|||
password: 21232f297a57a5a743894a0e4a801fc3 |
|||
# [可选] 用户名 |
|||
username: admin |
|||
# [可选] 密码, 默认为admin |
|||
password: 21232f297a57a5a743894a0e4a801fc3 |
|||
|
|||
#zlm服务器配置 |
|||
media: |
|||
# [必须修改] zlm服务器的IP(内网公网IP均可),配置多台时IP用逗号隔开 |
|||
ip: 192.168.0.100 |
|||
# [可选] zlm服务器的公网IP, 内网部署置空即可 |
|||
wanIp: |
|||
# [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip |
|||
hookIp: |
|||
# [必须修改] zlm服务器的http.port |
|||
port: 80 |
|||
# [可选] 是否自动配置ZLM, 如果希望手动配置ZLM, 可以设为false, 不建议新接触的用户修改 |
|||
autoConfig: true |
|||
# [可选] zlm服务器的hook.admin_params=secret |
|||
secret: 035c73f7-bb6b-4889-a715-d9eb2d1925cc |
|||
# [可选] zlm服务器的general.streamNoneReaderDelayMS |
|||
streamNoneReaderDelayMS: 18000 # 无人观看多久自动关闭流, -1表示永不自动关闭,即 关闭按需拉流 |
|||
# [可选] 自动点播, 使用固定流地址进行播放时,如果未点播则自动进行点播, 需要rtp.enable=true |
|||
autoApplyPlay: false |
|||
# [可选] 部分设备需要扩展SDP,需要打开此设置 |
|||
seniorSdp: false |
|||
# 启用udp多端口模式 |
|||
rtp: |
|||
# [可选] 是否启用udp多端口模式, 开启后会在udpPortRange范围内选择端口用于媒体流传输 |
|||
enable: true |
|||
# [可选] 在此范围内选择端口用于媒体流传输, 不只是udp, 使用TCP被动传输模式时,也是从这个范围内选择端口 |
|||
udpPortRange: 30000,30500 # 端口范围 |
|||
# [必须修改] zlm服务器的IP(内网公网IP均可),配置多台时IP用逗号隔开 |
|||
ip: 192.168.1.105 |
|||
# [可选] zlm服务器的公网IP, 内网部署置空即可 |
|||
wanIp: |
|||
# [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip |
|||
hookIp: |
|||
# [必须修改] zlm服务器的http.port |
|||
port: 80 |
|||
# [可选] 是否自动配置ZLM, 如果希望手动配置ZLM, 可以设为false, 不建议新接触的用户修改 |
|||
autoConfig: true |
|||
# [可选] zlm服务器的hook.admin_params=secret |
|||
secret: 035c73f7-bb6b-4889-a715-d9eb2d1925cc |
|||
# [可选] zlm服务器的general.streamNoneReaderDelayMS |
|||
streamNoneReaderDelayMS: 18000 # 无人观看多久自动关闭流, -1表示永不自动关闭,即 关闭按需拉流 |
|||
# [可选] 自动点播, 使用固定流地址进行播放时,如果未点播则自动进行点播, 需要rtp.enable=true |
|||
autoApplyPlay: false |
|||
# [可选] 部分设备需要扩展SDP,需要打开此设置 |
|||
seniorSdp: false |
|||
# 启用udp多端口模式 |
|||
rtp: |
|||
# [可选] 是否启用udp多端口模式, 开启后会在udpPortRange范围内选择端口用于媒体流传输 |
|||
enable: true |
|||
# [可选] 在此范围内选择端口用于媒体流传输, 不只是udp, 使用TCP被动传输模式时,也是从这个范围内选择端口 |
|||
udpPortRange: 30000,30500 # 端口范围 |
|||
|
|||
# [可选] 日志配置, 一般不需要改 |
|||
logging: |
|||
file: |
|||
name: logs/wvp.log |
|||
max-history: 30 |
|||
max-size: 10MB |
|||
total-size-cap: 300MB |
|||
level: |
|||
com: |
|||
genersoft: |
|||
iot: debug |
|||
file: |
|||
name: logs/wvp.log |
|||
max-history: 30 |
|||
max-size: 10MB |
|||
total-size-cap: 300MB |
|||
level: |
|||
com: |
|||
genersoft: |
|||
iot: debug |
|||
# [根据业务需求配置] |
|||
userSettings: |
|||
# 保存移动位置历史轨迹:true:保留历史数据,false:仅保留最后的位置(默认) |
|||
savePositionHistory: false |
|||
# 保存移动位置历史轨迹:true:保留历史数据,false:仅保留最后的位置(默认) |
|||
savePositionHistory: false |
@ -1,3 +1,3 @@ |
|||
spring: |
|||
profiles: |
|||
active: local |
|||
active: dev |
Loading…
Reference in new issue