Commit 5077713ed944a02a971c941bb1827fa45de454b0

Authored by 王鑫
1 parent d76da120

修改

Showing 150 changed files with 3703 additions and 5457 deletions
@@ -104,7 +104,16 @@ @@ -104,7 +104,16 @@
104 <artifactId>netty-all</artifactId> 104 <artifactId>netty-all</artifactId>
105 <version>4.1.42.Final</version> 105 <version>4.1.42.Final</version>
106 </dependency> 106 </dependency>
107 - 107 + <!-- forrest工具 -->
  108 + <dependency>
  109 + <groupId>com.dtflys.forest</groupId>
  110 + <artifactId>forest-spring-boot-starter</artifactId>
  111 + <version>1.5.36</version>
  112 + </dependency>
  113 + <dependency>
  114 + <groupId>org.projectlombok</groupId>
  115 + <artifactId>lombok</artifactId>
  116 + </dependency>
108 <dependency> 117 <dependency>
109 <groupId>de.sciss</groupId> 118 <groupId>de.sciss</groupId>
110 <artifactId>jump3r</artifactId> 119 <artifactId>jump3r</artifactId>
@@ -402,43 +411,43 @@ @@ -402,43 +411,43 @@
402 </configuration> 411 </configuration>
403 </plugin> 412 </plugin>
404 413
405 -<!-- <plugin>-->  
406 -<!-- <groupId>org.apache.maven.plugins</groupId>-->  
407 -<!-- <artifactId>maven-jar-plugin</artifactId>-->  
408 -<!-- <version>3.3.0</version>-->  
409 -<!-- <configuration>-->  
410 -<!-- <excludes>-->  
411 -<!-- <exclude>**/all-application.yml</exclude>-->  
412 -<!-- <exclude>**/application.yml</exclude>-->  
413 -<!-- <exclude>**/application-*.yml</exclude>-->  
414 -<!-- <exclude>**/local.jks</exclude>-->  
415 -<!-- </excludes>-->  
416 -<!-- </configuration>-->  
417 -<!-- </plugin>-->  
418 -<!-- <plugin>-->  
419 -<!-- <artifactId>maven-resources-plugin</artifactId>-->  
420 -<!-- <executions>-->  
421 -<!-- <execution> &lt;!&ndash; 复制配置文件 &ndash;&gt;-->  
422 -<!-- <id>copy-resources</id>-->  
423 -<!-- <phase>package</phase>-->  
424 -<!-- <goals>-->  
425 -<!-- <goal>copy-resources</goal>-->  
426 -<!-- </goals>-->  
427 -<!-- <configuration>-->  
428 -<!-- <resources>-->  
429 -<!-- <resource>-->  
430 -<!-- <directory>src/main/resources</directory>-->  
431 -<!-- <includes>-->  
432 -<!-- <include>application.yml</include>-->  
433 -<!-- <include>application-*.yml</include>-->  
434 -<!-- </includes>-->  
435 -<!-- </resource>-->  
436 -<!-- </resources>-->  
437 -<!-- <outputDirectory>${project.build.directory}</outputDirectory>-->  
438 -<!-- </configuration>-->  
439 -<!-- </execution>-->  
440 -<!-- </executions>-->  
441 -<!-- </plugin>--> 414 + <!-- <plugin>-->
  415 + <!-- <groupId>org.apache.maven.plugins</groupId>-->
  416 + <!-- <artifactId>maven-jar-plugin</artifactId>-->
  417 + <!-- <version>3.3.0</version>-->
  418 + <!-- <configuration>-->
  419 + <!-- <excludes>-->
  420 + <!-- <exclude>**/all-application.yml</exclude>-->
  421 + <!-- <exclude>**/application.yml</exclude>-->
  422 + <!-- <exclude>**/application-*.yml</exclude>-->
  423 + <!-- <exclude>**/local.jks</exclude>-->
  424 + <!-- </excludes>-->
  425 + <!-- </configuration>-->
  426 + <!-- </plugin>-->
  427 + <!-- <plugin>-->
  428 + <!-- <artifactId>maven-resources-plugin</artifactId>-->
  429 + <!-- <executions>-->
  430 + <!-- <execution> &lt;!&ndash; 复制配置文件 &ndash;&gt;-->
  431 + <!-- <id>copy-resources</id>-->
  432 + <!-- <phase>package</phase>-->
  433 + <!-- <goals>-->
  434 + <!-- <goal>copy-resources</goal>-->
  435 + <!-- </goals>-->
  436 + <!-- <configuration>-->
  437 + <!-- <resources>-->
  438 + <!-- <resource>-->
  439 + <!-- <directory>src/main/resources</directory>-->
  440 + <!-- <includes>-->
  441 + <!-- <include>application.yml</include>-->
  442 + <!-- <include>application-*.yml</include>-->
  443 + <!-- </includes>-->
  444 + <!-- </resource>-->
  445 + <!-- </resources>-->
  446 + <!-- <outputDirectory>${project.build.directory}</outputDirectory>-->
  447 + <!-- </configuration>-->
  448 + <!-- </execution>-->
  449 + <!-- </executions>-->
  450 + <!-- </plugin>-->
442 </plugins> 451 </plugins>
443 <resources> 452 <resources>
444 <resource> 453 <resource>
src/main/java/com/genersoft/iot/vmp/LengthCalculator.java 0 → 100644
  1 +package com.genersoft.iot.vmp;
  2 +
  3 +import java.io.IOException;
  4 +import java.io.InputStream;
  5 +import java.io.OutputStream;
  6 +import java.net.Socket;
  7 +
  8 +public class LengthCalculator extends Thread{
  9 + //socket为成员变量,来接收服务端socket实例
  10 + private Socket socket;
  11 +
  12 + public LengthCalculator(Socket socket){
  13 + this.socket = socket;
  14 + }
  15 +
  16 + // run()保存了所有的业务逻辑
  17 + public void run(){
  18 + try {
  19 + //获取socket的输出流
  20 + OutputStream os = socket.getOutputStream();
  21 + //获取socket的输入流
  22 + InputStream is = socket.getInputStream();
  23 + int ch = 0;
  24 + //buff用来读取输入的内容,存成byte数组,ch用来获取读取数组的字节数
  25 + byte[] buff = new byte[1024];
  26 + ch = is.read(buff);
  27 + //将接收流的byte数组转换成字符串,这里获取的内容是客户端发送过来的字节数组
  28 + String content = new String(buff,0,ch);
  29 + System.out.println(content);
  30 + //往输出流里写入获得的字符串的长度,回发给客户端
  31 + os.write(String.valueOf(content.length()).getBytes());
  32 + //一定要关闭输入输出流以及socket
  33 + is.close();
  34 + os.close();
  35 + socket.close();
  36 + } catch (IOException e) {
  37 + throw new RuntimeException(e);
  38 + }
  39 + }
  40 +}
src/main/java/com/genersoft/iot/vmp/TCPClient.java 0 → 100644
  1 +package com.genersoft.iot.vmp;
  2 +
  3 +import java.io.InputStream;
  4 +import java.io.OutputStream;
  5 +import java.net.Socket;
  6 +
  7 +public class TCPClient {
  8 + public static void main(String[] args) throws Exception{
  9 + //创建socket,并指定连接的是本机的端口号为65000的服务器socket
  10 + Socket socket = new Socket("118.113.164.50",3333);
  11 + //获取输出流
  12 + OutputStream os = socket.getOutputStream();
  13 + //获取输入流
  14 + InputStream is = socket.getInputStream();
  15 + // 将要传递给server的字符串参数转换称byte数组,并将数组写入到输出流中
  16 + os.write(new String("hello world").getBytes());
  17 + int ch = 0;
  18 + byte[] buff = new byte[1024];
  19 + // buff主要用来读取输入的内容,存成byte数组,ch主要用来获取读取数组的长度(与服务端作用相同)
  20 + ch = is.read(buff);
  21 + //将接收流的byte数组转换成字符串,这里是从服务端回发的字符串参数的长度
  22 + String content = new String(buff,0,ch);
  23 + System.out.println(content);
  24 + //一定要关闭输入输出流及socket
  25 + is.close();
  26 + os.close();
  27 + socket.close();
  28 + }
  29 +}
src/main/java/com/genersoft/iot/vmp/TCPServer.java 0 → 100644
  1 +package com.genersoft.iot.vmp;
  2 +
  3 +import java.net.ServerSocket;
  4 +import java.net.Socket;
  5 +
  6 +public class TCPServer {
  7 + public static void main(String[] args) throws Exception{
  8 + //创建socket,并将socket绑定到65000端口
  9 + ServerSocket ss = new ServerSocket(30020);
  10 + //死循环,使得socket一直等待并处理客户端发送过来的请求
  11 + while(true){
  12 + //监听65000端口,直到客户端返回连接信息后才返回
  13 + Socket socket = ss.accept();
  14 + //获取客户端的请求信息后,启动一个新线程执行相关业务逻辑
  15 + new LengthCalculator(socket).start();
  16 + }
  17 + }
  18 +}
src/main/java/com/genersoft/iot/vmp/VManageBootstrap.java
1 package com.genersoft.iot.vmp; 1 package com.genersoft.iot.vmp;
2 2
  3 +import com.dtflys.forest.springboot.annotation.ForestScan;
  4 +import com.genersoft.iot.vmp.jtt1078.app.VideoServerApp;
3 import com.genersoft.iot.vmp.utils.GitUtil; 5 import com.genersoft.iot.vmp.utils.GitUtil;
4 import com.genersoft.iot.vmp.utils.SpringBeanFactory; 6 import com.genersoft.iot.vmp.utils.SpringBeanFactory;
5 import org.slf4j.Logger; 7 import org.slf4j.Logger;
@@ -9,7 +11,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; @@ -9,7 +11,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
9 import org.springframework.boot.builder.SpringApplicationBuilder; 11 import org.springframework.boot.builder.SpringApplicationBuilder;
10 import org.springframework.boot.web.servlet.ServletComponentScan; 12 import org.springframework.boot.web.servlet.ServletComponentScan;
11 import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; 13 import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
12 -import org.springframework.context.ConfigurableApplicationContext; 14 +import org.springframework.context.ApplicationContext;
13 import org.springframework.scheduling.annotation.EnableScheduling; 15 import org.springframework.scheduling.annotation.EnableScheduling;
14 16
15 import javax.servlet.ServletContext; 17 import javax.servlet.ServletContext;
@@ -25,25 +27,27 @@ import java.util.Objects; @@ -25,25 +27,27 @@ import java.util.Objects;
25 @ServletComponentScan("com.genersoft.iot.vmp.conf") 27 @ServletComponentScan("com.genersoft.iot.vmp.conf")
26 @SpringBootApplication 28 @SpringBootApplication
27 @EnableScheduling 29 @EnableScheduling
  30 +@ForestScan(basePackages = "com.genersoft.iot.vmp.vmanager.jt1078.platform.remote")
28 public class VManageBootstrap extends SpringBootServletInitializer { 31 public class VManageBootstrap extends SpringBootServletInitializer {
29 32
30 private final static Logger logger = LoggerFactory.getLogger(VManageBootstrap.class); 33 private final static Logger logger = LoggerFactory.getLogger(VManageBootstrap.class);
31 34
32 private static String[] args; 35 private static String[] args;
33 - private static ConfigurableApplicationContext context; 36 + private static ApplicationContext context;
34 public static void main(String[] args) { 37 public static void main(String[] args) {
35 VManageBootstrap.args = args; 38 VManageBootstrap.args = args;
36 VManageBootstrap.context = SpringApplication.run(VManageBootstrap.class, args); 39 VManageBootstrap.context = SpringApplication.run(VManageBootstrap.class, args);
37 - GitUtil gitUtil1 = SpringBeanFactory.getBean("gitUtil"); 40 + VideoServerApp videoServerApp = context.getBean(VideoServerApp.class);
  41 + try {
  42 + videoServerApp.run(args);
  43 + } catch (Exception e) {
  44 + throw new RuntimeException(e);
  45 + }
  46 + GitUtil gitUtil1 = SpringBeanFactory.getBean("gitUtil");
38 logger.info("构建版本: {}", gitUtil1.getBuildVersion()); 47 logger.info("构建版本: {}", gitUtil1.getBuildVersion());
39 logger.info("构建时间: {}", gitUtil1.getBuildDate()); 48 logger.info("构建时间: {}", gitUtil1.getBuildDate());
40 logger.info("GIT最后提交时间: {}", gitUtil1.getCommitTime()); 49 logger.info("GIT最后提交时间: {}", gitUtil1.getCommitTime());
41 } 50 }
42 - // 项目重启  
43 - public static void restart() {  
44 - context.close();  
45 - VManageBootstrap.context = SpringApplication.run(VManageBootstrap.class, args);  
46 - }  
47 51
48 @Override 52 @Override
49 protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { 53 protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
src/main/java/com/genersoft/iot/vmp/conf/ApiAccessFilter.java
1 package com.genersoft.iot.vmp.conf; 1 package com.genersoft.iot.vmp.conf;
2 2
3 import com.genersoft.iot.vmp.common.ApiSaveConstant; 3 import com.genersoft.iot.vmp.common.ApiSaveConstant;
  4 +import com.genersoft.iot.vmp.conf.security.IpWhitelistFilter;
4 import com.genersoft.iot.vmp.conf.security.SecurityUtils; 5 import com.genersoft.iot.vmp.conf.security.SecurityUtils;
  6 +import com.genersoft.iot.vmp.conf.security.WebSecurityConfig;
5 import com.genersoft.iot.vmp.service.ILogService; 7 import com.genersoft.iot.vmp.service.ILogService;
6 import com.genersoft.iot.vmp.storager.dao.dto.LogDto; 8 import com.genersoft.iot.vmp.storager.dao.dto.LogDto;
7 import com.genersoft.iot.vmp.utils.DateUtil; 9 import com.genersoft.iot.vmp.utils.DateUtil;
@@ -21,6 +23,8 @@ import javax.servlet.http.HttpServletRequest; @@ -21,6 +23,8 @@ import javax.servlet.http.HttpServletRequest;
21 import javax.servlet.http.HttpServletResponse; 23 import javax.servlet.http.HttpServletResponse;
22 import java.io.IOException; 24 import java.io.IOException;
23 25
  26 +import static com.genersoft.iot.vmp.conf.security.IpWhitelistFilter.verifyIpAndPath;
  27 +
24 /** 28 /**
25 * @author lin 29 * @author lin
26 */ 30 */
@@ -40,6 +44,10 @@ public class ApiAccessFilter extends OncePerRequestFilter { @@ -40,6 +44,10 @@ public class ApiAccessFilter extends OncePerRequestFilter {
40 44
41 @Override 45 @Override
42 protected void doFilterInternal(HttpServletRequest servletRequest, HttpServletResponse servletResponse, FilterChain filterChain) throws ServletException, IOException { 46 protected void doFilterInternal(HttpServletRequest servletRequest, HttpServletResponse servletResponse, FilterChain filterChain) throws ServletException, IOException {
  47 + if (verifyIpAndPath(servletRequest)){
  48 + filterChain.doFilter(servletRequest, servletResponse);
  49 + return;
  50 + }
43 String username = null; 51 String username = null;
44 if (SecurityUtils.getUserInfo() == null) { 52 if (SecurityUtils.getUserInfo() == null) {
45 username = servletRequest.getParameter("username"); 53 username = servletRequest.getParameter("username");
@@ -66,8 +74,6 @@ public class ApiAccessFilter extends OncePerRequestFilter { @@ -66,8 +74,6 @@ public class ApiAccessFilter extends OncePerRequestFilter {
66 logDto.setUri(servletRequest.getRequestURI()); 74 logDto.setUri(servletRequest.getRequestURI());
67 logDto.setCreateTime(DateUtil.getNow()); 75 logDto.setCreateTime(DateUtil.getNow());
68 logService.add(logDto); 76 logService.add(logDto);
69 -  
70 -  
71 } 77 }
72 } 78 }
73 79
src/main/java/com/genersoft/iot/vmp/conf/DynamicTask.java
1 package com.genersoft.iot.vmp.conf; 1 package com.genersoft.iot.vmp.conf;
2 2
  3 +import org.apache.commons.collections4.CollectionUtils;
3 import org.apache.commons.lang3.ObjectUtils; 4 import org.apache.commons.lang3.ObjectUtils;
  5 +import org.ehcache.core.util.CollectionUtil;
4 import org.slf4j.Logger; 6 import org.slf4j.Logger;
5 import org.slf4j.LoggerFactory; 7 import org.slf4j.LoggerFactory;
  8 +import org.springframework.data.redis.cache.RedisCache;
  9 +import org.springframework.data.redis.core.RedisTemplate;
6 import org.springframework.scheduling.annotation.Scheduled; 10 import org.springframework.scheduling.annotation.Scheduled;
7 import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; 11 import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
8 import org.springframework.stereotype.Component; 12 import org.springframework.stereotype.Component;
9 13
10 import javax.annotation.PostConstruct; 14 import javax.annotation.PostConstruct;
  15 +import javax.annotation.Resource;
11 import java.time.Instant; 16 import java.time.Instant;
12 import java.util.Date; 17 import java.util.Date;
13 import java.util.Map; 18 import java.util.Map;
@@ -18,6 +23,7 @@ import java.util.concurrent.TimeUnit; @@ -18,6 +23,7 @@ import java.util.concurrent.TimeUnit;
18 23
19 /** 24 /**
20 * 动态定时任务 25 * 动态定时任务
  26 + *
21 * @author lin 27 * @author lin
22 */ 28 */
23 @Component 29 @Component
@@ -30,6 +36,9 @@ public class DynamicTask { @@ -30,6 +36,9 @@ public class DynamicTask {
30 private final Map<String, ScheduledFuture<?>> futureMap = new ConcurrentHashMap<>(); 36 private final Map<String, ScheduledFuture<?>> futureMap = new ConcurrentHashMap<>();
31 private final Map<String, Runnable> runnableMap = new ConcurrentHashMap<>(); 37 private final Map<String, Runnable> runnableMap = new ConcurrentHashMap<>();
32 38
  39 + @Resource
  40 + private RedisTemplate<String, String> redisTemplate;
  41 +
33 @PostConstruct 42 @PostConstruct
34 public void DynamicTask() { 43 public void DynamicTask() {
35 threadPoolTaskScheduler = new ThreadPoolTaskScheduler(); 44 threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
@@ -37,17 +46,23 @@ public class DynamicTask { @@ -37,17 +46,23 @@ public class DynamicTask {
37 threadPoolTaskScheduler.setWaitForTasksToCompleteOnShutdown(true); 46 threadPoolTaskScheduler.setWaitForTasksToCompleteOnShutdown(true);
38 threadPoolTaskScheduler.setAwaitTerminationSeconds(10); 47 threadPoolTaskScheduler.setAwaitTerminationSeconds(10);
39 threadPoolTaskScheduler.initialize(); 48 threadPoolTaskScheduler.initialize();
  49 + Set<String> keys = redisTemplate.keys("jt1078:server:port:*");
  50 + if (CollectionUtils.isNotEmpty(keys)) {
  51 + redisTemplate.delete(keys);
  52 + }
  53 +
40 } 54 }
41 55
42 /** 56 /**
43 * 循环执行的任务 57 * 循环执行的任务
44 - * @param key 任务ID  
45 - * @param task 任务 58 + *
  59 + * @param key 任务ID
  60 + * @param task 任务
46 * @param cycleForCatalog 间隔 毫秒 61 * @param cycleForCatalog 间隔 毫秒
47 * @return 62 * @return
48 */ 63 */
49 public void startCron(String key, Runnable task, int cycleForCatalog) { 64 public void startCron(String key, Runnable task, int cycleForCatalog) {
50 - if(ObjectUtils.isEmpty(key)) { 65 + if (ObjectUtils.isEmpty(key)) {
51 return; 66 return;
52 } 67 }
53 ScheduledFuture<?> future = futureMap.get(key); 68 ScheduledFuture<?> future = futureMap.get(key);
@@ -62,24 +77,25 @@ public class DynamicTask { @@ -62,24 +77,25 @@ public class DynamicTask {
62 // scheduleWithFixedDelay 必须等待上一个任务结束才开始计时period, cycleForCatalog表示执行的间隔 77 // scheduleWithFixedDelay 必须等待上一个任务结束才开始计时period, cycleForCatalog表示执行的间隔
63 78
64 future = threadPoolTaskScheduler.scheduleAtFixedRate(task, new Date(System.currentTimeMillis() + cycleForCatalog), cycleForCatalog); 79 future = threadPoolTaskScheduler.scheduleAtFixedRate(task, new Date(System.currentTimeMillis() + cycleForCatalog), cycleForCatalog);
65 - if (future != null){ 80 + if (future != null) {
66 futureMap.put(key, future); 81 futureMap.put(key, future);
67 runnableMap.put(key, task); 82 runnableMap.put(key, task);
68 logger.debug("任务【{}】启动成功!!!", key); 83 logger.debug("任务【{}】启动成功!!!", key);
69 - }else { 84 + } else {
70 logger.debug("任务【{}】启动失败!!!", key); 85 logger.debug("任务【{}】启动失败!!!", key);
71 } 86 }
72 } 87 }
73 88
74 /** 89 /**
75 * 延时任务 90 * 延时任务
76 - * @param key 任务ID  
77 - * @param task 任务 91 + *
  92 + * @param key 任务ID
  93 + * @param task 任务
78 * @param delay 延时 /毫秒 94 * @param delay 延时 /毫秒
79 * @return 95 * @return
80 */ 96 */
81 public void startDelay(String key, Runnable task, int delay) { 97 public void startDelay(String key, Runnable task, int delay) {
82 - if(ObjectUtils.isEmpty(key)) { 98 + if (ObjectUtils.isEmpty(key)) {
83 return; 99 return;
84 } 100 }
85 stop(key); 101 stop(key);
@@ -98,17 +114,17 @@ public class DynamicTask { @@ -98,17 +114,17 @@ public class DynamicTask {
98 } 114 }
99 // scheduleWithFixedDelay 必须等待上一个任务结束才开始计时period, cycleForCatalog表示执行的间隔 115 // scheduleWithFixedDelay 必须等待上一个任务结束才开始计时period, cycleForCatalog表示执行的间隔
100 future = threadPoolTaskScheduler.schedule(task, startInstant); 116 future = threadPoolTaskScheduler.schedule(task, startInstant);
101 - if (future != null){ 117 + if (future != null) {
102 futureMap.put(key, future); 118 futureMap.put(key, future);
103 runnableMap.put(key, task); 119 runnableMap.put(key, task);
104 logger.debug("任务【{}】启动成功!!!", key); 120 logger.debug("任务【{}】启动成功!!!", key);
105 - }else { 121 + } else {
106 logger.debug("任务【{}】启动失败!!!", key); 122 logger.debug("任务【{}】启动失败!!!", key);
107 } 123 }
108 } 124 }
109 125
110 public boolean stop(String key) { 126 public boolean stop(String key) {
111 - if(ObjectUtils.isEmpty(key)) { 127 + if (ObjectUtils.isEmpty(key)) {
112 return false; 128 return false;
113 } 129 }
114 boolean result = false; 130 boolean result = false;
@@ -121,7 +137,7 @@ public class DynamicTask { @@ -121,7 +137,7 @@ public class DynamicTask {
121 } 137 }
122 138
123 public boolean contains(String key) { 139 public boolean contains(String key) {
124 - if(ObjectUtils.isEmpty(key)) { 140 + if (ObjectUtils.isEmpty(key)) {
125 return false; 141 return false;
126 } 142 }
127 return futureMap.get(key) != null; 143 return futureMap.get(key) != null;
@@ -132,7 +148,7 @@ public class DynamicTask { @@ -132,7 +148,7 @@ public class DynamicTask {
132 } 148 }
133 149
134 public Runnable get(String key) { 150 public Runnable get(String key) {
135 - if(ObjectUtils.isEmpty(key)) { 151 + if (ObjectUtils.isEmpty(key)) {
136 return null; 152 return null;
137 } 153 }
138 return runnableMap.get(key); 154 return runnableMap.get(key);
@@ -141,8 +157,8 @@ public class DynamicTask { @@ -141,8 +157,8 @@ public class DynamicTask {
141 /** 157 /**
142 * 每五分钟检查失效的任务,并移除 158 * 每五分钟检查失效的任务,并移除
143 */ 159 */
144 - @Scheduled(cron="0 0/5 * * * ?")  
145 - public void execute(){ 160 + @Scheduled(cron = "0 0/5 * * * ?")
  161 + public void execute() {
146 if (futureMap.size() > 0) { 162 if (futureMap.size() > 0) {
147 for (String key : futureMap.keySet()) { 163 for (String key : futureMap.keySet()) {
148 ScheduledFuture<?> future = futureMap.get(key); 164 ScheduledFuture<?> future = futureMap.get(key);
src/main/java/com/genersoft/iot/vmp/conf/security/IpWhitelistFilter.java 0 → 100644
  1 +package com.genersoft.iot.vmp.conf.security;
  2 +
  3 +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
  4 +import org.springframework.security.core.context.SecurityContextHolder;
  5 +import org.springframework.web.filter.OncePerRequestFilter;
  6 +
  7 +import javax.servlet.FilterChain;
  8 +import javax.servlet.ServletException;
  9 +import javax.servlet.http.HttpServletRequest;
  10 +import javax.servlet.http.HttpServletResponse;
  11 +import java.io.IOException;
  12 +import java.util.Arrays;
  13 +import java.util.Collections;
  14 +import java.util.List;
  15 +
  16 +public class IpWhitelistFilter extends OncePerRequestFilter {
  17 +
  18 + public static final List<String> PATH_ARRAY = Arrays.asList("/api/jt1078/query/send/request/getPlay");
  19 +
  20 + @Override
  21 + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
  22 + throws ServletException, IOException {
  23 + if (verifyIpAndPath(request)) {
  24 + // 如果IP在白名单中,则直接设置用户为已认证状态并放行请求
  25 + UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
  26 + "whitelisted-ip", null, Collections.emptyList());
  27 + SecurityContextHolder.getContext().setAuthentication(authentication);
  28 +
  29 + // 直接返回,不再继续执行链中的其他过滤器
  30 + chain.doFilter(request, response);
  31 + return;
  32 + }
  33 +
  34 + // 对于非白名单IP,继续执行链中的下一个过滤器
  35 + chain.doFilter(request, response);
  36 + }
  37 +
  38 + private boolean isAllowedIp(String ip) {
  39 + return WebSecurityConfig.ALLOWED_IPS.contains(ip);
  40 + }
  41 +
  42 + private boolean isAllowedPath(String path) {
  43 + return PATH_ARRAY.contains(path);
  44 + }
  45 +
  46 + public static String getClientIp(HttpServletRequest request) {
  47 + String xfHeader = request.getHeader("X-Forwarded-For");
  48 + if (xfHeader == null) {
  49 + return request.getRemoteAddr();
  50 + }
  51 + return xfHeader.split(",")[0];
  52 + }
  53 +
  54 + public static Boolean verifyIpAndPath(HttpServletRequest request) throws ServletException, IOException {
  55 + String requestURI = request.getRequestURI();
  56 + String clientIp = IpWhitelistFilter.getClientIp(request);
  57 + String header = request.getHeader("access-token");
  58 + return (WebSecurityConfig.ALLOWED_IPS.contains(clientIp) && IpWhitelistFilter.PATH_ARRAY.contains(requestURI)) || JwtUtils.token.equals(header);
  59 + }
  60 +}
src/main/java/com/genersoft/iot/vmp/conf/security/JwtUtils.java
@@ -34,6 +34,8 @@ public class JwtUtils implements InitializingBean { @@ -34,6 +34,8 @@ public class JwtUtils implements InitializingBean {
34 34
35 private static final String keyId = "3e79646c4dbc408383a9eed09f2b85ae"; 35 private static final String keyId = "3e79646c4dbc408383a9eed09f2b85ae";
36 36
  37 + public static final String token = "interior-api-eyJhbGciOiJSUzI1NiIsImtpZCI6IjNlNzk2NDZjNGRiYzQwODM4M2E5ZWVkMDlmMmI4NWFlIn0.eyJqdGkiOiJHUThFUFhtdGtJd01yVTNES3F3bnN3IiwiaWF0IjoxNzM2ODM2Mjk";
  38 +
37 /** 39 /**
38 * token过期时间(分钟) 40 * token过期时间(分钟)
39 */ 41 */
src/main/java/com/genersoft/iot/vmp/conf/security/SecurityUtils.java
@@ -54,7 +54,6 @@ public class SecurityUtils { @@ -54,7 +54,6 @@ public class SecurityUtils {
54 if(authentication!=null){ 54 if(authentication!=null){
55 Object principal = authentication.getPrincipal(); 55 Object principal = authentication.getPrincipal();
56 if(principal!=null && !"anonymousUser".equals(principal.toString())){ 56 if(principal!=null && !"anonymousUser".equals(principal.toString())){
57 -  
58 User user = (User) principal; 57 User user = (User) principal;
59 return new LoginUser(user, LocalDateTime.now()); 58 return new LoginUser(user, LocalDateTime.now());
60 } 59 }
src/main/java/com/genersoft/iot/vmp/conf/security/WebSecurityConfig.java
@@ -18,6 +18,7 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur @@ -18,6 +18,7 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur
18 import org.springframework.security.config.http.SessionCreationPolicy; 18 import org.springframework.security.config.http.SessionCreationPolicy;
19 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 19 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
20 import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; 20 import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
  21 +import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
21 import org.springframework.web.cors.CorsConfiguration; 22 import org.springframework.web.cors.CorsConfiguration;
22 import org.springframework.web.cors.CorsConfigurationSource; 23 import org.springframework.web.cors.CorsConfigurationSource;
23 import org.springframework.web.cors.CorsUtils; 24 import org.springframework.web.cors.CorsUtils;
@@ -26,6 +27,7 @@ import org.springframework.web.cors.UrlBasedCorsConfigurationSource; @@ -26,6 +27,7 @@ import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
26 import java.util.ArrayList; 27 import java.util.ArrayList;
27 import java.util.Arrays; 28 import java.util.Arrays;
28 import java.util.Collections; 29 import java.util.Collections;
  30 +import java.util.List;
29 31
30 /** 32 /**
31 * 配置Spring Security 33 * 配置Spring Security
@@ -58,6 +60,8 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @@ -58,6 +60,8 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
58 @Autowired 60 @Autowired
59 private JwtAuthenticationFilter jwtAuthenticationFilter; 61 private JwtAuthenticationFilter jwtAuthenticationFilter;
60 62
  63 + public static final List<String> ALLOWED_IPS = Arrays.asList("192.169.1.88", "127.0.0.1");
  64 +
61 65
62 /** 66 /**
63 * 描述: 静态资源放行,这里的放行,是不走 Spring Security 过滤器链 67 * 描述: 静态资源放行,这里的放行,是不走 Spring Security 过滤器链
@@ -88,6 +92,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @@ -88,6 +92,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
88 } 92 }
89 } 93 }
90 94
  95 +
91 /** 96 /**
92 * 配置认证方式 97 * 配置认证方式
93 * 98 *
@@ -113,21 +118,20 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @@ -113,21 +118,20 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
113 .and().csrf().disable() 118 .and().csrf().disable()
114 .sessionManagement() 119 .sessionManagement()
115 .sessionCreationPolicy(SessionCreationPolicy.STATELESS) 120 .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
116 -  
117 - // 配置拦截规则  
118 .and() 121 .and()
  122 + // 配置拦截规则
119 .authorizeRequests() 123 .authorizeRequests()
120 .requestMatchers(CorsUtils::isPreFlightRequest).permitAll() 124 .requestMatchers(CorsUtils::isPreFlightRequest).permitAll()
121 .antMatchers(userSetting.getInterfaceAuthenticationExcludes().toArray(new String[0])).permitAll() 125 .antMatchers(userSetting.getInterfaceAuthenticationExcludes().toArray(new String[0])).permitAll()
122 .antMatchers("/api/user/login", "/index/hook/**", "/swagger-ui/**", "/doc.html").permitAll() 126 .antMatchers("/api/user/login", "/index/hook/**", "/swagger-ui/**", "/doc.html").permitAll()
123 .anyRequest().authenticated() 127 .anyRequest().authenticated()
124 - // 异常处理器  
125 .and() 128 .and()
  129 + .addFilterBefore(new IpWhitelistFilter(), BasicAuthenticationFilter.class)
  130 + // 异常处理器
126 .exceptionHandling() 131 .exceptionHandling()
127 .authenticationEntryPoint(anonymousAuthenticationEntryPoint) 132 .authenticationEntryPoint(anonymousAuthenticationEntryPoint)
128 .and().logout().logoutUrl("/api/user/logout").permitAll() 133 .and().logout().logoutUrl("/api/user/logout").permitAll()
129 - .logoutSuccessHandler(logoutHandler)  
130 - ; 134 + .logoutSuccessHandler(logoutHandler);
131 http.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); 135 http.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
132 136
133 } 137 }
src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java
@@ -37,6 +37,10 @@ public class SipLayer implements CommandLineRunner { @@ -37,6 +37,10 @@ public class SipLayer implements CommandLineRunner {
37 private final Map<String, SipProviderImpl> tcpSipProviderMap = new ConcurrentHashMap<>(); 37 private final Map<String, SipProviderImpl> tcpSipProviderMap = new ConcurrentHashMap<>();
38 private final Map<String, SipProviderImpl> udpSipProviderMap = new ConcurrentHashMap<>(); 38 private final Map<String, SipProviderImpl> udpSipProviderMap = new ConcurrentHashMap<>();
39 39
  40 + /**
  41 + * 获取监听的IP
  42 + * @param args
  43 + */
40 @Override 44 @Override
41 public void run(String... args) { 45 public void run(String... args) {
42 List<String> monitorIps = new ArrayList<>(); 46 List<String> monitorIps = new ArrayList<>();
src/main/java/com/genersoft/iot/vmp/jt1078/annotation/MsgId.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.jt1078.annotation;  
2 -  
3 -import java.lang.annotation.*;  
4 -  
5 -/**  
6 - * @author QingtaiJiang  
7 - * @date 2023/4/27 18:31  
8 - * @email qingtaij@163.com  
9 - */  
10 -@Target(ElementType.TYPE)  
11 -@Retention(RetentionPolicy.RUNTIME)  
12 -@Documented  
13 -public @interface MsgId {  
14 - String id();  
15 -}  
src/main/java/com/genersoft/iot/vmp/jt1078/app/CacheMapUtil.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.jt1078.app;  
2 -  
3 -import io.netty.channel.Channel;  
4 -  
5 -import java.util.HashMap;  
6 -import java.util.Map;  
7 -  
8 -public class CacheMapUtil {  
9 - public Map<Integer, VideoServerApp.VideoServer> videoServerMap = new HashMap();  
10 - public Map<Integer, Channel> portChannel = new HashMap();  
11 -  
12 - private static CacheMapUtil cacheMapUtil;  
13 -  
14 - public static CacheMapUtil getCacheMapUtil() {  
15 - if (null == cacheMapUtil) {  
16 - cacheMapUtil = new CacheMapUtil();  
17 - }  
18 - return cacheMapUtil;  
19 - }  
20 -  
21 - private CacheMapUtil() {  
22 -  
23 - }  
24 -  
25 -  
26 -}  
src/main/java/com/genersoft/iot/vmp/jt1078/app/VideoServerApp.java deleted 100644 → 0
1 -//  
2 -// Source code recreated from a .class file by IntelliJ IDEA  
3 -// (powered by FernFlower decompiler)  
4 -//  
5 -  
6 -package com.genersoft.iot.vmp.jt1078.app;  
7 -  
8 -import com.genersoft.iot.vmp.jt1078.http.GeneralResponseWriter;  
9 -import com.genersoft.iot.vmp.jt1078.http.NettyHttpServerHandler;  
10 -import com.genersoft.iot.vmp.jt1078.publisher.PublishManager;  
11 -import com.genersoft.iot.vmp.jt1078.server.Jtt1078Handler;  
12 -import com.genersoft.iot.vmp.jt1078.server.Jtt1078MessageDecoder;  
13 -import com.genersoft.iot.vmp.jt1078.util.Configs;  
14 -import io.netty.bootstrap.ServerBootstrap;  
15 -import io.netty.channel.Channel;  
16 -import io.netty.channel.ChannelFuture;  
17 -import io.netty.channel.ChannelHandler;  
18 -import io.netty.channel.ChannelInitializer;  
19 -import io.netty.channel.ChannelOption;  
20 -import io.netty.channel.ChannelPipeline;  
21 -import io.netty.channel.EventLoopGroup;  
22 -import io.netty.channel.nio.NioEventLoopGroup;  
23 -import io.netty.channel.socket.SocketChannel;  
24 -import io.netty.channel.socket.nio.NioServerSocketChannel;  
25 -  
26 -import java.net.InetAddress;  
27 -import java.util.Date;  
28 -import java.util.HashMap;  
29 -import java.util.Map;  
30 -import java.util.Objects;  
31 -  
32 -import io.netty.handler.codec.http.HttpObjectAggregator;  
33 -import io.netty.handler.codec.http.HttpRequestDecoder;  
34 -import io.netty.handler.codec.http.HttpResponseEncoder;  
35 -import org.apache.commons.collections4.MapUtils;  
36 -import org.slf4j.Logger;  
37 -import org.slf4j.LoggerFactory;  
38 -import sun.misc.Signal;  
39 -import sun.misc.SignalHandler;  
40 -  
41 -public class VideoServerApp {  
42 - private static Logger logger = LoggerFactory.getLogger(VideoServerApp.class);  
43 -  
44 - public VideoServerApp() {  
45 - }  
46 -  
47 - public void createListenter() throws Exception {  
48 - Configs.init("/app.properties");  
49 - PublishManager.init();  
50 - String tagMapping = null;  
51 - final VideoServer videoServer = new VideoServer();  
52 - final HttpServer httpServer = new HttpServer();  
53 - Signal.handle(new Signal("TERM"), new SignalHandler() {  
54 - public void handle(Signal signal) {  
55 - videoServer.shutdown();  
56 - HttpServer var10000 = httpServer;  
57 - VideoServerApp.HttpServer.shutdown();  
58 - }  
59 - });  
60 - VideoServerApp.VideoServer.getInstance().start(11078, (String) tagMapping, 3333);  
61 - VideoServerApp.HttpServer.start((String) tagMapping, 3333);  
62 - }  
63 -  
64 - public void newVideoServer(final String key, int port, final int httpPort) throws Exception {  
65 - VideoServer videoServer = new VideoServer();  
66 - HttpServer httpServer = null;  
67 - boolean videoFlag = false;  
68 - boolean httpFlag = false;  
69 - long nw = (new Date()).getTime();  
70 - VideoServer sourceVideoServer = (VideoServer) CacheMapUtil.getCacheMapUtil().videoServerMap.get(port);  
71 - if (Objects.isNull(sourceVideoServer)) {  
72 - videoServer = new VideoServer();  
73 - videoFlag = true;  
74 - CacheMapUtil.getCacheMapUtil().videoServerMap.put(port, videoServer);  
75 - }  
76 - if (videoFlag) {  
77 - videoServer.start(port, key, httpPort);  
78 - }  
79 - }  
80 -  
81 - public static void stopServer(int port, Integer httpPort) {  
82 - stopVideoServer(port);  
83 -// stopHttpServer(httpPort);  
84 -// channelMappingMap.remove(httpPort);  
85 - }  
86 -  
87 - public void stopServer2(int port, int httpPort) {  
88 - stopVideoServer(port);  
89 -// stopHttpServer(httpPort);  
90 -// channelMappingMap.remove(httpPort);  
91 - }  
92 -  
93 -  
94 - private static void stopVideoServer(Integer port) {  
95 - VideoServer videoServer = (VideoServer) CacheMapUtil.getCacheMapUtil().videoServerMap.get(port);  
96 - if (Objects.nonNull(videoServer)) {  
97 - videoServer.shutdown();  
98 - CacheMapUtil.getCacheMapUtil().videoServerMap.remove(port);  
99 - }  
100 -  
101 - }  
102 -  
103 - private static void stopHttpServer(Integer port) {  
104 -  
105 -  
106 - }  
107 -  
108 - static class HttpServer {  
109 - private static ServerBootstrap serverBootstrap;  
110 - private static EventLoopGroup bossGroup;  
111 - private static EventLoopGroup workerGroup;  
112 - private static Integer httpPort;  
113 -  
114 - HttpServer() {  
115 - }  
116 -  
117 - private static void start(final String tagMapping, final int port) throws Exception {  
118 - bossGroup = new NioEventLoopGroup();  
119 - workerGroup = new NioEventLoopGroup(Runtime.getRuntime().availableProcessors());  
120 - httpPort = port;  
121 - ServerBootstrap bootstrap = new ServerBootstrap();  
122 - ((ServerBootstrap) ((ServerBootstrap) bootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)).childHandler(new ChannelInitializer<SocketChannel>() {  
123 - public void initChannel(SocketChannel ch) throws Exception {  
124 - ch.pipeline().addLast(new ChannelHandler[]{new GeneralResponseWriter(), new HttpResponseEncoder(), new HttpRequestDecoder(), new HttpObjectAggregator(65536), new NettyHttpServerHandler(tagMapping, port)});  
125 - }  
126 - }).option(ChannelOption.SO_BACKLOG, 1024)).childOption(ChannelOption.SO_KEEPALIVE, true);  
127 -  
128 - try {  
129 - InterruptedException e;  
130 - try {  
131 - ChannelFuture f = bootstrap.bind(InetAddress.getByName("0.0.0.0"), port).sync();  
132 - VideoServerApp.logger.info("HTTP Server started at: {}", port);  
133 -  
134 - f.channel().closeFuture().sync();  
135 - e = null;  
136 - } catch (InterruptedException var7) {  
137 - e = var7;  
138 - VideoServerApp.logger.error("http server error", e);  
139 - }  
140 - } finally {  
141 - shutdown();  
142 - }  
143 -  
144 - }  
145 -  
146 - private static void shutdown() {  
147 -  
148 - try {  
149 - bossGroup.shutdownGracefully();  
150 - } catch (Exception e) {  
151 - e.printStackTrace();  
152 - }  
153 -  
154 - bossGroup = null;  
155 -  
156 - try {  
157 - workerGroup.shutdownGracefully();  
158 - } catch (Exception e) {  
159 - e.printStackTrace();  
160 - }  
161 -  
162 - workerGroup = null;  
163 - }  
164 - }  
165 -  
166 - static class VideoServer {  
167 - private ServerBootstrap serverBootstrap;  
168 - private EventLoopGroup bossGroup;  
169 - private EventLoopGroup workerGroup;  
170 - private static Integer port;  
171 -  
172 - public void start(int port, final String tagMapping, final Integer httpPort) throws Exception {  
173 - VideoServerApp.VideoServer.port = port;  
174 - serverBootstrap = new ServerBootstrap();  
175 - serverBootstrap.option(ChannelOption.SO_BACKLOG, Configs.getInt("server.backlog", 102400));  
176 - bossGroup = new NioEventLoopGroup(Configs.getInt("server.worker-count", Runtime.getRuntime().availableProcessors()));  
177 - workerGroup = new NioEventLoopGroup();  
178 - serverBootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class);  
179 - serverBootstrap.childHandler(new ChannelInitializer<SocketChannel>() {  
180 - protected void initChannel(SocketChannel channel) throws Exception {  
181 - ChannelPipeline p = channel.pipeline();  
182 - p.addLast(new ChannelHandler[]{new Jtt1078MessageDecoder()});  
183 - p.addLast(new ChannelHandler[]{new Jtt1078Handler(tagMapping, httpPort)});  
184 - }  
185 - });  
186 - Channel ch = serverBootstrap.bind(InetAddress.getByName("0.0.0.0"), port).sync().channel();  
187 - CacheMapUtil.getCacheMapUtil().portChannel.put(port, ch);  
188 - VideoServerApp.logger.info("Video Server started at: {}", port);  
189 - ch.closeFuture();  
190 - ch = null;  
191 - CacheMapUtil.getCacheMapUtil().portChannel.remove(port);  
192 - }  
193 -  
194 - public void shutdown() {  
195 - Channel channel = (Channel) CacheMapUtil.getCacheMapUtil().portChannel.get(port);  
196 - Exception e;  
197 - if (Objects.nonNull(channel)) {  
198 - try {  
199 - channel.closeFuture();  
200 - } catch (Exception var5) {  
201 - e = var5;  
202 - e.printStackTrace();  
203 - }  
204 -  
205 - channel = null;  
206 - CacheMapUtil.getCacheMapUtil().portChannel.remove(port);  
207 - }  
208 -  
209 - try {  
210 - bossGroup.shutdownGracefully();  
211 - } catch (Exception var4) {  
212 - e = var4;  
213 - e.printStackTrace();  
214 - }  
215 -  
216 - try {  
217 - workerGroup.shutdownGracefully();  
218 - } catch (Exception var3) {  
219 - e = var3;  
220 - e.printStackTrace();  
221 - }  
222 -  
223 - }  
224 -  
225 - public static VideoServer getInstance() {  
226 - return new VideoServer();  
227 - }  
228 - }  
229 -}  
src/main/java/com/genersoft/iot/vmp/jt1078/cmd/JT1078Template.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.jt1078.cmd;  
2 -  
3 -import com.genersoft.iot.vmp.jt1078.proc.entity.Cmd;  
4 -import com.genersoft.iot.vmp.jt1078.proc.response.*;  
5 -import com.genersoft.iot.vmp.jt1078.session.SessionManager;  
6 -  
7 -import java.util.Random;  
8 -  
9 -/**  
10 - * @author QingtaiJiang  
11 - * @date 2023/4/27 18:58  
12 - * @email qingtaij@163.com  
13 - */  
14 -public class JT1078Template {  
15 -  
16 - private final Random random = new Random();  
17 -  
18 - private static final String H9101 = "9101";  
19 - private static final String H9102 = "9102";  
20 - private static final String H9201 = "9201";  
21 - private static final String H9202 = "9202";  
22 - private static final String H9205 = "9205";  
23 -  
24 - private static final String H0001 = "0001";  
25 - private static final String H1205 = "1205";  
26 -  
27 - /**  
28 - * 开启直播视频  
29 - *  
30 - * @param devId 设备号  
31 - * @param j9101 开启视频参数  
32 - */  
33 - public String startLive(String devId, J9101 j9101, Integer timeOut) {  
34 - Cmd cmd = new Cmd.Builder()  
35 - .setDevId(devId)  
36 - .setPackageNo(randomInt())  
37 - .setMsgId(H9101)  
38 - .setRespId(H0001)  
39 - .setRs(j9101)  
40 - .build();  
41 - return SessionManager.INSTANCE.request(cmd, timeOut);  
42 - }  
43 -  
44 - /**  
45 - * 关闭直播视频  
46 - *  
47 - * @param devId 设备号  
48 - * @param j9102 关闭视频参数  
49 - */  
50 - public String stopLive(String devId, J9102 j9102, Integer timeOut) {  
51 - Cmd cmd = new Cmd.Builder()  
52 - .setDevId(devId)  
53 - .setPackageNo(randomInt())  
54 - .setMsgId(H9102)  
55 - .setRespId(H0001)  
56 - .setRs(j9102)  
57 - .build();  
58 - return SessionManager.INSTANCE.request(cmd, timeOut);  
59 - }  
60 -  
61 - /**  
62 - * 查询音视频列表  
63 - *  
64 - * @param devId 设备号  
65 - * @param j9205 查询音视频列表  
66 - */  
67 - public String queryBackTime(String devId, J9205 j9205, Integer timeOut) {  
68 - Cmd cmd = new Cmd.Builder()  
69 - .setDevId(devId)  
70 - .setPackageNo(randomInt())  
71 - .setMsgId(H9205)  
72 - .setRespId(H1205)  
73 - .setRs(j9205)  
74 - .build();  
75 - return SessionManager.INSTANCE.request(cmd, timeOut);  
76 - }  
77 -  
78 - /**  
79 - * 开启视频回放  
80 - *  
81 - * @param devId 设备号  
82 - * @param j9201 视频回放参数  
83 - */  
84 - public String startBackLive(String devId, J9201 j9201, Integer timeOut) {  
85 - Cmd cmd = new Cmd.Builder()  
86 - .setDevId(devId)  
87 - .setPackageNo(randomInt())  
88 - .setMsgId(H9201)  
89 - .setRespId(H1205)  
90 - .setRs(j9201)  
91 - .build();  
92 - return SessionManager.INSTANCE.request(cmd, timeOut);  
93 - }  
94 -  
95 - /**  
96 - * 视频回放控制  
97 - *  
98 - * @param devId 设备号  
99 - * @param j9202 控制视频回放参数  
100 - */  
101 - public String controlBackLive(String devId, J9202 j9202, Integer timeOut) {  
102 - Cmd cmd = new Cmd.Builder()  
103 - .setDevId(devId)  
104 - .setPackageNo(randomInt())  
105 - .setMsgId(H9202)  
106 - .setRespId(H0001)  
107 - .setRs(j9202)  
108 - .build();  
109 - return SessionManager.INSTANCE.request(cmd, timeOut);  
110 - }  
111 -  
112 - private Long randomInt() {  
113 - return (long) random.nextInt(1000) + 1;  
114 - }  
115 -}  
src/main/java/com/genersoft/iot/vmp/jt1078/codec/decode/Jt808Decoder.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.jt1078.codec.decode;  
2 -  
3 -import com.genersoft.iot.vmp.jt1078.proc.Header;  
4 -import com.genersoft.iot.vmp.jt1078.proc.factory.CodecFactory;  
5 -import com.genersoft.iot.vmp.jt1078.proc.request.Re;  
6 -import com.genersoft.iot.vmp.jt1078.proc.response.Rs;  
7 -import com.genersoft.iot.vmp.jt1078.session.Session;  
8 -import io.netty.buffer.ByteBuf;  
9 -import io.netty.buffer.ByteBufUtil;  
10 -import io.netty.buffer.CompositeByteBuf;  
11 -import io.netty.buffer.UnpooledByteBufAllocator;  
12 -import io.netty.channel.ChannelHandlerContext;  
13 -import io.netty.handler.codec.ByteToMessageDecoder;  
14 -import org.slf4j.Logger;  
15 -import org.slf4j.LoggerFactory;  
16 -  
17 -import java.util.ArrayList;  
18 -import java.util.List;  
19 -  
20 -/**  
21 - * @author QingtaiJiang  
22 - * @date 2023/4/27 18:10  
23 - * @email qingtaij@163.com  
24 - */  
25 -public class Jt808Decoder extends ByteToMessageDecoder {  
26 - private final static Logger log = LoggerFactory.getLogger(Jt808Decoder.class);  
27 -  
28 - @Override  
29 - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {  
30 - Session session = ctx.channel().attr(Session.KEY).get();  
31 - log.info("> {} hex:{}", session, ByteBufUtil.hexDump(in));  
32 -  
33 - try {  
34 - ByteBuf buf = unEscapeAndCheck(in);  
35 -  
36 - Header header = new Header();  
37 - header.setMsgId(ByteBufUtil.hexDump(buf.readSlice(2)));  
38 - header.setMsgPro(buf.readUnsignedShort());  
39 - if (header.is2019Version()) {  
40 - header.setVersion(buf.readUnsignedByte());  
41 - String devId = ByteBufUtil.hexDump(buf.readSlice(10));  
42 - header.setDevId(devId.replaceFirst("^0*", ""));  
43 - } else {  
44 - header.setDevId(ByteBufUtil.hexDump(buf.readSlice(6)).replaceFirst("^0*", ""));  
45 - }  
46 - header.setSn(buf.readUnsignedShort());  
47 -  
48 - Re handler = CodecFactory.getHandler(header.getMsgId());  
49 - if (handler == null) {  
50 - log.error("get msgId is null {}", header.getMsgId());  
51 - return;  
52 - }  
53 - Rs decode = handler.decode(buf, header, session);  
54 - if (decode != null) {  
55 - out.add(decode);  
56 - }  
57 - } finally {  
58 - in.skipBytes(in.readableBytes());  
59 - }  
60 -  
61 -  
62 - }  
63 -  
64 -  
65 - /**  
66 - * 转义与验证校验码  
67 - *  
68 - * @param byteBuf 转义Buf  
69 - * @return 转义好的数据  
70 - */  
71 - public ByteBuf unEscapeAndCheck(ByteBuf byteBuf) throws Exception {  
72 - int low = byteBuf.readerIndex();  
73 - int high = byteBuf.writerIndex();  
74 - byte checkSum = 0;  
75 - int calculationCheckSum = 0;  
76 -  
77 - byte aByte = byteBuf.getByte(high - 2);  
78 - byte protocolEscapeFlag7d = 0x7d;  
79 - //0x7d转义  
80 - byte protocolEscapeFlag01 = 0x01;  
81 - //0x7e转义  
82 - byte protocolEscapeFlag02 = 0x02;  
83 - if (aByte == protocolEscapeFlag7d) {  
84 - byte b2 = byteBuf.getByte(high - 1);  
85 - if (b2 == protocolEscapeFlag01) {  
86 - checkSum = protocolEscapeFlag7d;  
87 - } else if (b2 == protocolEscapeFlag02) {  
88 - checkSum = 0x7e;  
89 - } else {  
90 - log.error("转义1异常:{}", ByteBufUtil.hexDump(byteBuf));  
91 - throw new Exception("转义错误");  
92 - }  
93 - high = high - 2;  
94 - } else {  
95 - high = high - 1;  
96 - checkSum = byteBuf.getByte(high);  
97 - }  
98 - List<ByteBuf> bufList = new ArrayList<>();  
99 - int index = low;  
100 - while (index < high) {  
101 - byte b = byteBuf.getByte(index);  
102 - if (b == protocolEscapeFlag7d) {  
103 - byte c = byteBuf.getByte(index + 1);  
104 - if (c == protocolEscapeFlag01) {  
105 - ByteBuf slice = slice0x01(byteBuf, low, index);  
106 - bufList.add(slice);  
107 - b = protocolEscapeFlag7d;  
108 - } else if (c == protocolEscapeFlag02) {  
109 - ByteBuf slice = slice0x02(byteBuf, low, index);  
110 - bufList.add(slice);  
111 - b = 0x7e;  
112 - } else {  
113 - log.error("转义2异常:{}", ByteBufUtil.hexDump(byteBuf));  
114 - throw new Exception("转义错误");  
115 - }  
116 - index += 2;  
117 - low = index;  
118 - } else {  
119 - index += 1;  
120 - }  
121 - calculationCheckSum = calculationCheckSum ^ b;  
122 - }  
123 -  
124 - if (calculationCheckSum == checkSum) {  
125 - if (bufList.size() == 0) {  
126 - return byteBuf.slice(low, high);  
127 - } else {  
128 - bufList.add(byteBuf.slice(low, high - low));  
129 - return new CompositeByteBuf(UnpooledByteBufAllocator.DEFAULT, false, bufList.size(), bufList);  
130 - }  
131 - } else {  
132 - log.info("{} 解析校验码:{}--计算校验码:{}", ByteBufUtil.hexDump(byteBuf), checkSum, calculationCheckSum);  
133 - throw new Exception("校验码错误!");  
134 - }  
135 - }  
136 -  
137 -  
138 - private ByteBuf slice0x01(ByteBuf buf, int low, int sign) {  
139 - return buf.slice(low, sign - low + 1);  
140 - }  
141 -  
142 - private ByteBuf slice0x02(ByteBuf buf, int low, int sign) {  
143 - buf.setByte(sign, 0x7e);  
144 - return buf.slice(low, sign - low + 1);  
145 - }  
146 -}  
src/main/java/com/genersoft/iot/vmp/jt1078/codec/encode/Jt808Encoder.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.jt1078.codec.encode;  
2 -  
3 -  
4 -import com.genersoft.iot.vmp.jt1078.proc.response.Rs;  
5 -import com.genersoft.iot.vmp.jt1078.session.Session;  
6 -import io.netty.buffer.ByteBuf;  
7 -import io.netty.buffer.ByteBufUtil;  
8 -import io.netty.channel.ChannelHandlerContext;  
9 -import io.netty.handler.codec.MessageToByteEncoder;  
10 -import org.slf4j.Logger;  
11 -import org.slf4j.LoggerFactory;  
12 -  
13 -/**  
14 - * @author QingtaiJiang  
15 - * @date 2023/4/27 18:10  
16 - * @email qingtaij@163.com  
17 - */  
18 -public class Jt808Encoder extends MessageToByteEncoder<Rs> {  
19 - private final static Logger log = LoggerFactory.getLogger(Jt808Encoder.class);  
20 -  
21 - @Override  
22 - protected void encode(ChannelHandlerContext ctx, Rs msg, ByteBuf out) throws Exception {  
23 - Session session = ctx.channel().attr(Session.KEY).get();  
24 -  
25 - ByteBuf encode = Jt808EncoderCmd.encode(msg, session, session.nextSerialNo());  
26 - if(encode!=null){  
27 - log.info("< {} hex:{}", session, ByteBufUtil.hexDump(encode));  
28 - out.writeBytes(encode);  
29 - }  
30 - }  
31 -  
32 -  
33 -}  
src/main/java/com/genersoft/iot/vmp/jt1078/codec/encode/Jt808EncoderCmd.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.jt1078.codec.encode;  
2 -  
3 -import com.genersoft.iot.vmp.jt1078.annotation.MsgId;  
4 -import com.genersoft.iot.vmp.jt1078.proc.Header;  
5 -import com.genersoft.iot.vmp.jt1078.proc.entity.Cmd;  
6 -import com.genersoft.iot.vmp.jt1078.proc.response.Rs;  
7 -import com.genersoft.iot.vmp.jt1078.session.Session;  
8 -import com.genersoft.iot.vmp.jt1078.util.Bin;  
9 -import io.netty.buffer.ByteBuf;  
10 -import io.netty.buffer.ByteBufUtil;  
11 -import io.netty.buffer.CompositeByteBuf;  
12 -import io.netty.buffer.Unpooled;  
13 -import io.netty.channel.ChannelHandlerContext;  
14 -import io.netty.handler.codec.MessageToByteEncoder;  
15 -import io.netty.util.ByteProcessor;  
16 -import org.slf4j.Logger;  
17 -import org.slf4j.LoggerFactory;  
18 -import org.springframework.util.StringUtils;  
19 -  
20 -import java.util.LinkedList;  
21 -  
22 -/**  
23 - * @author QingtaiJiang  
24 - * @date 2023/4/27 18:25  
25 - * @email qingtaij@163.com  
26 - */  
27 -public class Jt808EncoderCmd extends MessageToByteEncoder<Cmd> {  
28 - private final static Logger log = LoggerFactory.getLogger(Jt808EncoderCmd.class);  
29 -  
30 - @Override  
31 - protected void encode(ChannelHandlerContext ctx, Cmd cmd, ByteBuf out) throws Exception {  
32 - Session session = ctx.channel().attr(Session.KEY).get();  
33 - Rs msg = cmd.getRs();  
34 - ByteBuf encode = encode(msg, session, cmd.getPackageNo().intValue());  
35 - if (encode != null) {  
36 - log.info("< {} hex:{}", session, ByteBufUtil.hexDump(encode));  
37 - out.writeBytes(encode);  
38 - }  
39 - }  
40 -  
41 -  
42 - public static ByteBuf encode(Rs msg, Session session, Integer packageNo) {  
43 - String id = msg.getClass().getAnnotation(MsgId.class).id();  
44 - if (!StringUtils.hasLength(id)) {  
45 - log.error("Not find msgId");  
46 - return null;  
47 - }  
48 -  
49 - ByteBuf byteBuf = Unpooled.buffer();  
50 -  
51 - byteBuf.writeBytes(ByteBufUtil.decodeHexDump(id));  
52 -  
53 - ByteBuf encode = msg.encode();  
54 -  
55 - Header header = msg.getHeader();  
56 - if (header == null) {  
57 - header = session.getHeader();  
58 - }  
59 -  
60 - if (header.is2019Version()) {  
61 - // 消息体属性  
62 - byteBuf.writeShort(encode.readableBytes() | 1 << 14);  
63 -  
64 - // 版本号  
65 - byteBuf.writeByte(header.getVersion());  
66 -  
67 - // 终端手机号  
68 - byteBuf.writeBytes(ByteBufUtil.decodeHexDump(Bin.strHexPaddingLeft(header.getDevId(), 20)));  
69 - } else {  
70 - // 消息体属性  
71 - byteBuf.writeShort(encode.readableBytes());  
72 -  
73 - byteBuf.writeBytes(ByteBufUtil.decodeHexDump(Bin.strHexPaddingLeft(header.getDevId(), 12)));  
74 - }  
75 -  
76 - // 消息体流水号  
77 - byteBuf.writeShort(packageNo);  
78 -  
79 - // 写入消息体  
80 - byteBuf.writeBytes(encode);  
81 -  
82 - // 计算校验码,并反转义  
83 - byteBuf = escapeAndCheck0(byteBuf);  
84 - return byteBuf;  
85 - }  
86 -  
87 -  
88 - private static final ByteProcessor searcher = value -> !(value == 0x7d || value == 0x7e);  
89 -  
90 - //转义与校验  
91 - public static ByteBuf escapeAndCheck0(ByteBuf source) {  
92 -  
93 - sign(source);  
94 -  
95 - int low = source.readerIndex();  
96 - int high = source.writerIndex();  
97 -  
98 - LinkedList<ByteBuf> bufList = new LinkedList<>();  
99 - int mark, len;  
100 - while ((mark = source.forEachByte(low, high - low, searcher)) > 0) {  
101 -  
102 - len = mark + 1 - low;  
103 - ByteBuf[] slice = slice(source, low, len);  
104 - bufList.add(slice[0]);  
105 - bufList.add(slice[1]);  
106 - low += len;  
107 - }  
108 -  
109 - if (bufList.size() > 0) {  
110 - bufList.add(source.slice(low, high - low));  
111 - } else {  
112 - bufList.add(source);  
113 - }  
114 -  
115 - ByteBuf delimiter = Unpooled.buffer(1, 1).writeByte(0x7e).retain();  
116 - bufList.addFirst(delimiter);  
117 - bufList.addLast(delimiter);  
118 -  
119 - CompositeByteBuf byteBufLs = Unpooled.compositeBuffer(bufList.size());  
120 - byteBufLs.addComponents(true, bufList);  
121 - return byteBufLs;  
122 - }  
123 -  
124 - public static void sign(ByteBuf buf) {  
125 - byte checkCode = bcc(buf);  
126 - buf.writeByte(checkCode);  
127 - }  
128 -  
129 - public static byte bcc(ByteBuf byteBuf) {  
130 - byte cs = 0;  
131 - while (byteBuf.isReadable())  
132 - cs ^= byteBuf.readByte();  
133 - byteBuf.resetReaderIndex();  
134 - return cs;  
135 - }  
136 -  
137 - protected static ByteBuf[] slice(ByteBuf byteBuf, int index, int length) {  
138 - byte first = byteBuf.getByte(index + length - 1);  
139 -  
140 - ByteBuf[] byteBufList = new ByteBuf[2];  
141 - byteBufList[0] = byteBuf.retainedSlice(index, length);  
142 -  
143 - if (first == 0x7d) {  
144 - byteBufList[1] = Unpooled.buffer(1, 1).writeByte(0x01);  
145 - } else {  
146 - byteBuf.setByte(index + length - 1, 0x7d);  
147 - byteBufList[1] = Unpooled.buffer(1, 1).writeByte(0x02);  
148 - }  
149 - return byteBufList;  
150 - }  
151 -}  
src/main/java/com/genersoft/iot/vmp/jt1078/codec/netty/Jt808Handler.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.jt1078.codec.netty;  
2 -  
3 -import com.genersoft.iot.vmp.jt1078.proc.response.Rs;  
4 -import com.genersoft.iot.vmp.jt1078.session.Session;  
5 -import com.genersoft.iot.vmp.jt1078.session.SessionManager;  
6 -import io.netty.channel.Channel;  
7 -import io.netty.channel.ChannelHandlerContext;  
8 -import io.netty.channel.ChannelInboundHandlerAdapter;  
9 -import io.netty.handler.timeout.IdleState;  
10 -import io.netty.handler.timeout.IdleStateEvent;  
11 -import org.slf4j.Logger;  
12 -import org.slf4j.LoggerFactory;  
13 -  
14 -/**  
15 - * @author QingtaiJiang  
16 - * @date 2023/4/27 18:14  
17 - * @email qingtaij@163.com  
18 - */  
19 -public class Jt808Handler extends ChannelInboundHandlerAdapter {  
20 -  
21 - private final static Logger log = LoggerFactory.getLogger(Jt808Handler.class);  
22 -  
23 - @Override  
24 - public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {  
25 - if (msg instanceof Rs) {  
26 - ctx.writeAndFlush(msg);  
27 - } else {  
28 - ctx.fireChannelRead(msg);  
29 - }  
30 - }  
31 -  
32 - @Override  
33 - public void channelActive(ChannelHandlerContext ctx) {  
34 - Channel channel = ctx.channel();  
35 - Session session = SessionManager.INSTANCE.newSession(channel);  
36 - channel.attr(Session.KEY).set(session);  
37 - log.info("> Tcp connect {}", session);  
38 - }  
39 -  
40 - @Override  
41 - public void channelInactive(ChannelHandlerContext ctx) {  
42 - Session session = ctx.channel().attr(Session.KEY).get();  
43 - log.info("< Tcp disconnect {}", session);  
44 - ctx.close();  
45 - }  
46 -  
47 - @Override  
48 - public void exceptionCaught(ChannelHandlerContext ctx, Throwable e) {  
49 - Session session = ctx.channel().attr(Session.KEY).get();  
50 - String message = e.getMessage();  
51 - if (message.toLowerCase().contains("Connection reset by peer".toLowerCase())) {  
52 - log.info("< exception{} {}", session, e.getMessage());  
53 - } else {  
54 - log.info("< exception{} {}", session, e.getMessage(), e);  
55 - }  
56 -  
57 - }  
58 -  
59 - @Override  
60 - public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {  
61 - if (evt instanceof IdleStateEvent) {  
62 - IdleStateEvent event = (IdleStateEvent) evt;  
63 - IdleState state = event.state();  
64 - if (state == IdleState.READER_IDLE || state == IdleState.WRITER_IDLE) {  
65 - Session session = ctx.channel().attr(Session.KEY).get();  
66 - log.warn("< Proactively disconnect{}", session);  
67 - ctx.close();  
68 - }  
69 - }  
70 - }  
71 -  
72 -}  
src/main/java/com/genersoft/iot/vmp/jt1078/codec/netty/TcpServer.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.jt1078.codec.netty;  
2 -  
3 -import com.genersoft.iot.vmp.jt1078.codec.decode.Jt808Decoder;  
4 -import com.genersoft.iot.vmp.jt1078.codec.encode.Jt808Encoder;  
5 -import com.genersoft.iot.vmp.jt1078.codec.encode.Jt808EncoderCmd;  
6 -import com.genersoft.iot.vmp.jt1078.proc.factory.CodecFactory;  
7 -import io.netty.bootstrap.ServerBootstrap;  
8 -import io.netty.buffer.ByteBuf;  
9 -import io.netty.buffer.Unpooled;  
10 -import io.netty.channel.ChannelFuture;  
11 -import io.netty.channel.ChannelInitializer;  
12 -import io.netty.channel.EventLoopGroup;  
13 -import io.netty.channel.nio.NioEventLoopGroup;  
14 -import io.netty.channel.socket.nio.NioChannelOption;  
15 -import io.netty.channel.socket.nio.NioServerSocketChannel;  
16 -import io.netty.channel.socket.nio.NioSocketChannel;  
17 -import io.netty.handler.codec.DelimiterBasedFrameDecoder;  
18 -import io.netty.handler.timeout.IdleStateHandler;  
19 -import io.netty.util.concurrent.Future;  
20 -import org.slf4j.Logger;  
21 -import org.slf4j.LoggerFactory;  
22 -  
23 -import java.util.concurrent.TimeUnit;  
24 -  
25 -/**  
26 - * @author QingtaiJiang  
27 - * @date 2023/4/27 18:01  
28 - * @email qingtaij@163.com  
29 - */  
30 -  
31 -public class TcpServer {  
32 - private final static Logger log = LoggerFactory.getLogger(TcpServer.class);  
33 -  
34 - private final Integer port;  
35 - private boolean isRunning = false;  
36 - private EventLoopGroup bossGroup = null;  
37 - private EventLoopGroup workerGroup = null;  
38 -  
39 - private final ByteBuf DECODER_JT808 = Unpooled.wrappedBuffer(new byte[]{0x7e});  
40 -  
41 - public TcpServer(Integer port) {  
42 - this.port = port;  
43 - }  
44 -  
45 - private void startTcpServer() {  
46 - try {  
47 - CodecFactory.init();  
48 - this.bossGroup = new NioEventLoopGroup();  
49 - this.workerGroup = new NioEventLoopGroup();  
50 - ServerBootstrap bootstrap = new ServerBootstrap();  
51 - bootstrap.channel(NioServerSocketChannel.class);  
52 - bootstrap.group(bossGroup, workerGroup);  
53 -  
54 - bootstrap.option(NioChannelOption.SO_BACKLOG, 1024)  
55 - .option(NioChannelOption.SO_REUSEADDR, true)  
56 - .childOption(NioChannelOption.TCP_NODELAY, true)  
57 - .childHandler(new ChannelInitializer<NioSocketChannel>() {  
58 - @Override  
59 - public void initChannel(NioSocketChannel channel) {  
60 - channel.pipeline()  
61 - .addLast(new IdleStateHandler(10, 0, 0, TimeUnit.MINUTES))  
62 - .addLast(new DelimiterBasedFrameDecoder(1024 * 2, DECODER_JT808))  
63 - .addLast(new Jt808Decoder())  
64 - .addLast(new Jt808Encoder())  
65 - .addLast(new Jt808EncoderCmd())  
66 - .addLast(new Jt808Handler());  
67 - }  
68 - });  
69 - ChannelFuture channelFuture = bootstrap.bind(port).sync();  
70 - // 监听设备TCP端口是否启动成功  
71 - channelFuture.addListener(future -> {  
72 - if (!future.isSuccess()) {  
73 - log.error("Binding port:{} fail! cause: {}", port, future.cause().getCause(), future.cause());  
74 - }  
75 - });  
76 - log.info("服务:JT808 Server 启动成功, port:{}", port);  
77 - channelFuture.channel().closeFuture().sync();  
78 - } catch (Exception e) {  
79 - log.warn("服务:JT808 Server 启动异常, port:{},{}", port, e.getMessage(), e);  
80 - } finally {  
81 - stop();  
82 - }  
83 - }  
84 -  
85 - /**  
86 - * 开启一个新的线程,拉起来Netty  
87 - */  
88 - public synchronized void start() {  
89 - if (this.isRunning) {  
90 - log.warn("服务:JT808 Server 已经启动, port:{}", port);  
91 - return;  
92 - }  
93 - this.isRunning = true;  
94 - new Thread(this::startTcpServer).start();  
95 - }  
96 -  
97 - public synchronized void stop() {  
98 - if (!this.isRunning) {  
99 - log.warn("服务:JT808 Server 已经停止, port:{}", port);  
100 - }  
101 - this.isRunning = false;  
102 - Future<?> future = this.bossGroup.shutdownGracefully();  
103 - if (!future.isSuccess()) {  
104 - log.warn("bossGroup 无法正常停止", future.cause());  
105 - }  
106 - future = this.workerGroup.shutdownGracefully();  
107 - if (!future.isSuccess()) {  
108 - log.warn("workerGroup 无法正常停止", future.cause());  
109 - }  
110 - log.warn("服务:JT808 Server 已经停止, port:{}", port);  
111 - }  
112 -}  
src/main/java/com/genersoft/iot/vmp/jt1078/config/JT1078AutoConfiguration.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.jt1078.config;  
2 -  
3 -import com.genersoft.iot.vmp.jt1078.app.VideoServerApp;  
4 -import com.genersoft.iot.vmp.jt1078.cmd.JT1078Template;  
5 -import com.genersoft.iot.vmp.jt1078.codec.netty.TcpServer;  
6 -import org.springframework.beans.factory.annotation.Value;  
7 -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;  
8 -import org.springframework.context.annotation.Bean;  
9 -import org.springframework.context.annotation.Configuration;  
10 -import org.springframework.core.annotation.Order;  
11 -  
12 -/**  
13 - * @author QingtaiJiang  
14 - * @date 2023/4/27 19:35  
15 - * @email qingtaij@163.com  
16 - */  
17 -@Order(Integer.MIN_VALUE)  
18 -@Configuration  
19 -@ConditionalOnProperty(value = "jt1078.enable", havingValue = "true")  
20 -public class JT1078AutoConfiguration {  
21 -  
22 -// @Bean(initMethod = "start", destroyMethod = "stop")  
23 -// public TcpServer jt1078Server(@Value("${jt1078.port}") Integer port) {  
24 -// return new TcpServer(port);  
25 -// }  
26 -  
27 -// @Bean(initMethod = "start", destroyMethod = "stop")  
28 - @Bean  
29 - public VideoServerApp jt1078VideoServerApp(@Value("${jt1078.port}") Integer port) {  
30 - VideoServerApp videoServerApp = new VideoServerApp();  
31 - new Thread(new Runnable() {  
32 - @Override  
33 - public void run() {  
34 - try {  
35 - videoServerApp.createListenter();  
36 - } catch (Exception e) {  
37 - throw new RuntimeException(e);  
38 - }  
39 - }  
40 - }).start();  
41 -  
42 - return videoServerApp;  
43 - }  
44 - @Bean  
45 - public JT1078Template jt1078Template() {  
46 - return new JT1078Template();  
47 - }  
48 -}  
src/main/java/com/genersoft/iot/vmp/jt1078/config/JT1078Controller.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.jt1078.config;  
2 -  
3 -import com.genersoft.iot.vmp.jt1078.cmd.JT1078Template;  
4 -import com.genersoft.iot.vmp.jt1078.proc.response.*;  
5 -import com.genersoft.iot.vmp.vmanager.bean.WVPResult;  
6 -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;  
7 -import org.springframework.web.bind.annotation.GetMapping;  
8 -import org.springframework.web.bind.annotation.PathVariable;  
9 -import org.springframework.web.bind.annotation.RequestMapping;  
10 -import org.springframework.web.bind.annotation.RestController;  
11 -  
12 -import javax.annotation.Resource;  
13 -  
14 -/**  
15 - * curl http://localhost:18080/api/jt1078/start/live/18864197066/1  
16 - *  
17 - * @author QingtaiJiang  
18 - * @date 2023/4/27 18:12  
19 - * @email qingtaij@163.com  
20 - */  
21 -@ConditionalOnProperty(value = "jt1078.enable", havingValue = "true")  
22 -@RestController  
23 -@RequestMapping("/api/jt1078")  
24 -public class JT1078Controller {  
25 -  
26 - @Resource  
27 - JT1078Template jt1078Template;  
28 -  
29 - /**  
30 - * jt1078Template 调用示例  
31 - */  
32 - @GetMapping("/start/live/{deviceId}/{channelId}")  
33 - public WVPResult<?> startLive(@PathVariable String deviceId, @PathVariable String channelId) {  
34 - J9101 j9101 = new J9101();  
35 - j9101.setChannel(Integer.valueOf(channelId));  
36 - j9101.setIp("192.168.169.100");  
37 - j9101.setRate(1);  
38 - j9101.setTcpPort(7618);  
39 - j9101.setUdpPort(7618);  
40 - j9101.setType(0);  
41 - // TODO 分配ZLM,获取IP、端口  
42 - String s = jt1078Template.startLive(deviceId, j9101, 6);  
43 - // TODO 设备响应成功后,封装拉流结果集  
44 - WVPResult<String> wvpResult = new WVPResult<>();  
45 - wvpResult.setCode(200);  
46 - wvpResult.setData(String.format("http://192.168.169.100/rtp/%s_%s.live.mp4", deviceId, channelId));  
47 - return wvpResult;  
48 - }  
49 -  
50 -}  
51 -  
src/main/java/com/genersoft/iot/vmp/jt1078/http/NettyHttpServerHandler.java deleted 100644 → 0
1 -//  
2 -// Source code recreated from a .class file by IntelliJ IDEA  
3 -// (powered by FernFlower decompiler)  
4 -//  
5 -  
6 -package com.genersoft.iot.vmp.jt1078.http;  
7 -  
8 -import com.genersoft.iot.vmp.jt1078.app.VideoServerApp;  
9 -import com.genersoft.iot.vmp.jt1078.entity.Media.Type;  
10 -import com.genersoft.iot.vmp.jt1078.publisher.PublishManager;  
11 -import com.genersoft.iot.vmp.jt1078.server.Jtt1078Handler;  
12 -import com.genersoft.iot.vmp.jt1078.server.Session;  
13 -import com.genersoft.iot.vmp.jt1078.util.FileUtils;  
14 -import com.genersoft.iot.vmp.jt1078.util.Packet;  
15 -import io.netty.buffer.ByteBuf;  
16 -import io.netty.buffer.Unpooled;  
17 -import io.netty.channel.ChannelHandlerContext;  
18 -import io.netty.channel.ChannelInboundHandlerAdapter;  
19 -import io.netty.handler.codec.http.DefaultFullHttpResponse;  
20 -import io.netty.handler.codec.http.FullHttpRequest;  
21 -import io.netty.handler.codec.http.FullHttpResponse;  
22 -import io.netty.handler.codec.http.HttpResponseStatus;  
23 -import io.netty.handler.codec.http.HttpVersion;  
24 -import io.netty.util.Attribute;  
25 -import io.netty.util.AttributeKey;  
26 -import org.apache.commons.lang3.StringUtils;  
27 -import org.slf4j.Logger;  
28 -import org.slf4j.LoggerFactory;  
29 -  
30 -import java.io.IOException;  
31 -import java.net.URISyntaxException;  
32 -import java.util.Objects;  
33 -  
34 -public class NettyHttpServerHandler extends ChannelInboundHandlerAdapter {  
35 - private String tagMapping;  
36 - private Integer httpPort;  
37 - static Logger logger = LoggerFactory.getLogger(NettyHttpServerHandler.class);  
38 - static final byte[] HTTP_403_DATA = "<h1>403 Forbidden</h1><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding-->".getBytes();  
39 - static final byte[] SUCCESS = "{code:0}".getBytes();  
40 - static final String HEADER_ENCODING = "ISO-8859-1";  
41 - private static final AttributeKey<Session> SESSION_KEY = AttributeKey.valueOf("session");  
42 -  
43 - public NettyHttpServerHandler(String tagMapping, Integer httpPort) {  
44 - this.tagMapping = tagMapping;  
45 - this.httpPort = httpPort;  
46 - }  
47 -  
48 - public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {  
49 - FullHttpRequest fhr = (FullHttpRequest) msg;  
50 - String uri = fhr.uri();  
51 - Packet resp = Packet.create(1024);  
52 - String tagMapping;  
53 - long wid;  
54 - if (uri.startsWith("/video/")) {  
55 - tagMapping = uri.substring("/video/".length());  
56 - resp.addBytes("HTTP/1.1 200 OK\r\n".getBytes("ISO-8859-1"));  
57 - resp.addBytes("Connection: keep-alive\r\n".getBytes("ISO-8859-1"));  
58 - resp.addBytes("Content-Type: video/x-flv\r\n".getBytes("ISO-8859-1"));  
59 - resp.addBytes("Transfer-Encoding: chunked\r\n".getBytes("ISO-8859-1"));  
60 - resp.addBytes("Cache-Control: no-cache\r\n".getBytes("ISO-8859-1"));  
61 - resp.addBytes("Access-Control-Allow-Origin: *\r\n".getBytes("ISO-8859-1"));  
62 - resp.addBytes("Access-Control-Allow-Credentials: true\r\n".getBytes("ISO-8859-1"));  
63 - resp.addBytes("\r\n".getBytes("ISO-8859-1"));  
64 - ctx.writeAndFlush(resp.getBytes()).await();  
65 - logger.info("Thread id:[{}]", Thread.currentThread().getId());  
66 - if (StringUtils.isEmpty(this.tagMapping)) {  
67 - this.tagMapping = tagMapping;  
68 - }  
69 -  
70 -  
71 - wid = PublishManager.getInstance().subscribe(this.tagMapping, Type.Video, ctx, this.httpPort).getId();  
72 - this.setSession(ctx, (new Session()).set("subscriber-id", wid).set("tag", this.tagMapping));  
73 -// if (wid == 0) {  
74 -  
75 - try {  
76 - Jtt1078Handler.createStreamProxy(this.tagMapping, httpPort);  
77 - } catch (URISyntaxException e) {  
78 - throw new RuntimeException(e);  
79 - } catch (IOException e) {  
80 - throw new RuntimeException(e);  
81 - }  
82 -  
83 -// }  
84 - } else if (uri.equals("/test/multimedia")) {  
85 - this.responseHTMLFile("/multimedia.html", ctx);  
86 - } else {  
87 - String httpPort;  
88 - if (uri.startsWith("/stop/channel/")) {  
89 - resp.addBytes("HTTP/1.1 200 OK\r\n".getBytes("ISO-8859-1"));  
90 - resp.addBytes("Connection: keep-alive\r\n".getBytes("ISO-8859-1"));  
91 - resp.addBytes("Content-Type: video/x-flv\r\n".getBytes("ISO-8859-1"));  
92 - resp.addBytes("Transfer-Encoding: chunked\r\n".getBytes("ISO-8859-1"));  
93 - resp.addBytes("Cache-Control: no-cache\r\n".getBytes("ISO-8859-1"));  
94 - resp.addBytes("Access-Control-Allow-Origin: *\r\n".getBytes("ISO-8859-1"));  
95 - resp.addBytes("Access-Control-Allow-Credentials: true\r\n".getBytes("ISO-8859-1"));  
96 - tagMapping = uri.substring("/stop/channel/".length());  
97 - String str = uri.substring("/stop/channel/".length());  
98 - int endIndex = StringUtils.indexOf(str, "/");  
99 - StringUtils.substring(str, 0, endIndex);  
100 - Integer startIndex = endIndex + 1;  
101 - endIndex = StringUtils.indexOf(str, "/", startIndex);  
102 - httpPort = StringUtils.substring(str, startIndex, endIndex);  
103 - startIndex = endIndex + 1;  
104 - httpPort = StringUtils.substring(str, startIndex, str.length());  
105 - PublishManager publishManager = PublishManager.getInstance();  
106 - publishManager.unsubscribeAndClose(tagMapping);  
107 - VideoServerApp.stopServer(Integer.parseInt(httpPort), Integer.parseInt(httpPort));  
108 - logger.info("{}停流", tagMapping);  
109 - ByteBuf body = Unpooled.buffer(SUCCESS.length);  
110 - body.writeBytes(SUCCESS);  
111 - FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.valueOf(200), body);  
112 - response.headers().add("Content-Length", SUCCESS.length);  
113 - ctx.writeAndFlush(response).await();  
114 - ctx.flush();  
115 - } else if (uri.startsWith("/new/server/")) {  
116 - resp.addBytes("HTTP/1.1 200 OK\r\n".getBytes("ISO-8859-1"));  
117 - resp.addBytes("Connection: keep-alive\r\n".getBytes("ISO-8859-1"));  
118 - resp.addBytes("Content-Type: video/x-flv\r\n".getBytes("ISO-8859-1"));  
119 - resp.addBytes("Transfer-Encoding: chunked\r\n".getBytes("ISO-8859-1"));  
120 - resp.addBytes("Cache-Control: no-cache\r\n".getBytes("ISO-8859-1"));  
121 - resp.addBytes("Access-Control-Allow-Origin: *\r\n".getBytes("ISO-8859-1"));  
122 - resp.addBytes("Access-Control-Allow-Credentials: true\r\n".getBytes("ISO-8859-1"));  
123 - tagMapping = uri.substring("/new/server/".length());  
124 - int endIndex = StringUtils.indexOf(tagMapping, "/");  
125 - String key = StringUtils.substring(tagMapping, 0, endIndex);  
126 - Integer startIndex = endIndex + 1;  
127 - endIndex = StringUtils.indexOf(tagMapping, "/", startIndex);  
128 - String port = StringUtils.substring(tagMapping, startIndex, endIndex);  
129 - startIndex = endIndex + 1;  
130 - httpPort = StringUtils.substring(tagMapping, startIndex, tagMapping.length());  
131 -  
132 - ByteBuf body = Unpooled.buffer(SUCCESS.length);  
133 - body.writeBytes(SUCCESS);  
134 - FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.valueOf(200), body);  
135 - response.headers().add("Content-Length", SUCCESS.length);  
136 - ctx.writeAndFlush(response).await();  
137 - ctx.flush();  
138 - } else if (uri.startsWith("/play/history/")) {  
139 - tagMapping = uri.substring("/play/history/".length());  
140 - resp.addBytes("HTTP/1.1 200 OK\r\n".getBytes("ISO-8859-1"));  
141 - resp.addBytes("Connection: keep-alive\r\n".getBytes("ISO-8859-1"));  
142 - resp.addBytes("Content-Type: video/x-flv\r\n".getBytes("ISO-8859-1"));  
143 - resp.addBytes("Transfer-Encoding: chunked\r\n".getBytes("ISO-8859-1"));  
144 - resp.addBytes("Cache-Control: no-cache\r\n".getBytes("ISO-8859-1"));  
145 - resp.addBytes("Access-Control-Allow-Origin: *\r\n".getBytes("ISO-8859-1"));  
146 - resp.addBytes("Access-Control-Allow-Credentials: true\r\n".getBytes("ISO-8859-1"));  
147 - resp.addBytes("\r\n".getBytes("ISO-8859-1"));  
148 - ctx.writeAndFlush(resp.getBytes()).await();  
149 - logger.info("Thread id:[{}]", Thread.currentThread().getId());  
150 - wid = PublishManager.getInstance().subscribe(tagMapping, Type.Video, ctx, this.httpPort).getId();  
151 - this.setSession(ctx, (new Session()).set("subscriber-id", wid).set("tag", tagMapping));  
152 - } else {  
153 - ByteBuf body = Unpooled.buffer(HTTP_403_DATA.length);  
154 - body.writeBytes(HTTP_403_DATA);  
155 - FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.valueOf(403), body);  
156 - response.headers().add("Content-Length", HTTP_403_DATA.length);  
157 - ctx.writeAndFlush(response).await();  
158 - ctx.flush();  
159 - }  
160 - }  
161 -  
162 - }  
163 -  
164 - public void channelInactive(ChannelHandlerContext ctx) throws Exception {  
165 - super.channelInactive(ctx);  
166 - Session session = this.getSession(ctx);  
167 - if (session != null && session.has("subscriber-id") && session.has("tag")) {  
168 - String tag = (String) session.get("tag");  
169 - Long wid = (Long) session.get("subscriber-id");  
170 - PublishManager.getInstance().unsubscribe(tag, wid);  
171 - }  
172 -  
173 - }  
174 -  
175 - private void responseHTMLFile(String htmlFilePath, ChannelHandlerContext ctx) {  
176 - byte[] fileData = FileUtils.read(NettyHttpServerHandler.class.getResourceAsStream(htmlFilePath));  
177 - ByteBuf body = Unpooled.buffer(fileData.length);  
178 - body.writeBytes(fileData);  
179 - FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.valueOf(200), body);  
180 - response.headers().add("Content-Length", fileData.length);  
181 - ctx.write(response);  
182 - ctx.flush();  
183 - }  
184 -  
185 - public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {  
186 - ctx.flush();  
187 - }  
188 -  
189 - public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {  
190 - ctx.close();  
191 - cause.printStackTrace();  
192 - }  
193 -  
194 - public final void setSession(ChannelHandlerContext context, Session session) {  
195 - context.channel().attr(SESSION_KEY).set(session);  
196 - }  
197 -  
198 - public final Session getSession(ChannelHandlerContext context) {  
199 - Attribute<Session> attr = context.channel().attr(SESSION_KEY);  
200 - return null == attr ? null : (Session) attr.get();  
201 - }  
202 -}  
src/main/java/com/genersoft/iot/vmp/jt1078/proc/Header.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.jt1078.proc;  
2 -  
3 -import com.genersoft.iot.vmp.jt1078.util.Bin;  
4 -  
5 -/**  
6 - * @author QingtaiJiang  
7 - * @date 2023/4/27 18:22  
8 - * @email qingtaij@163.com  
9 - */  
10 -public class Header {  
11 - // 消息ID  
12 - String msgId;  
13 -  
14 - // 消息体属性  
15 - Integer msgPro;  
16 -  
17 - // 标识  
18 - String devId;  
19 -  
20 - // 消息体流水号  
21 - Integer sn;  
22 -  
23 - // 协议版本号  
24 - Short version = -1;  
25 -  
26 -  
27 - public String getMsgId() {  
28 - return msgId;  
29 - }  
30 -  
31 - public void setMsgId(String msgId) {  
32 - this.msgId = msgId;  
33 - }  
34 -  
35 - public Integer getMsgPro() {  
36 - return msgPro;  
37 - }  
38 -  
39 - public void setMsgPro(Integer msgPro) {  
40 - this.msgPro = msgPro;  
41 - }  
42 -  
43 - public String getDevId() {  
44 - return devId;  
45 - }  
46 -  
47 - public void setDevId(String devId) {  
48 - this.devId = devId;  
49 - }  
50 -  
51 - public Integer getSn() {  
52 - return sn;  
53 - }  
54 -  
55 - public void setSn(Integer sn) {  
56 - this.sn = sn;  
57 - }  
58 -  
59 - public Short getVersion() {  
60 - return version;  
61 - }  
62 -  
63 - public void setVersion(Short version) {  
64 - this.version = version;  
65 - }  
66 -  
67 - /**  
68 - * 判断是否是2019的版本  
69 - *  
70 - * @return true 2019后的版本。false 2013  
71 - */  
72 - public boolean is2019Version() {  
73 - return Bin.get(msgPro, 14);  
74 - }  
75 -  
76 -}  
src/main/java/com/genersoft/iot/vmp/jt1078/proc/entity/Cmd.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.jt1078.proc.entity;  
2 -  
3 -import com.genersoft.iot.vmp.jt1078.proc.response.Rs;  
4 -  
5 -/**  
6 - * @author QingtaiJiang  
7 - * @date 2023/4/27 18:23  
8 - * @email qingtaij@163.com  
9 - */  
10 -public class Cmd {  
11 - String devId;  
12 - Long packageNo;  
13 - String msgId;  
14 - String respId;  
15 - Rs rs;  
16 -  
17 - public Cmd() {  
18 - }  
19 -  
20 - public Cmd(Builder builder) {  
21 - this.devId = builder.devId;  
22 - this.packageNo = builder.packageNo;  
23 - this.msgId = builder.msgId;  
24 - this.respId = builder.respId;  
25 - this.rs = builder.rs;  
26 - }  
27 -  
28 - public String getDevId() {  
29 - return devId;  
30 - }  
31 -  
32 - public void setDevId(String devId) {  
33 - this.devId = devId;  
34 - }  
35 -  
36 - public Long getPackageNo() {  
37 - return packageNo;  
38 - }  
39 -  
40 - public void setPackageNo(Long packageNo) {  
41 - this.packageNo = packageNo;  
42 - }  
43 -  
44 - public String getMsgId() {  
45 - return msgId;  
46 - }  
47 -  
48 - public void setMsgId(String msgId) {  
49 - this.msgId = msgId;  
50 - }  
51 -  
52 - public String getRespId() {  
53 - return respId;  
54 - }  
55 -  
56 - public void setRespId(String respId) {  
57 - this.respId = respId;  
58 - }  
59 -  
60 - public Rs getRs() {  
61 - return rs;  
62 - }  
63 -  
64 - public void setRs(Rs rs) {  
65 - this.rs = rs;  
66 - }  
67 -  
68 - public static class Builder {  
69 - String devId;  
70 - Long packageNo;  
71 - String msgId;  
72 - String respId;  
73 - Rs rs;  
74 -  
75 - public Builder setDevId(String devId) {  
76 - this.devId = devId.replaceFirst("^0*", "");  
77 - return this;  
78 - }  
79 -  
80 - public Builder setPackageNo(Long packageNo) {  
81 - this.packageNo = packageNo;  
82 - return this;  
83 - }  
84 -  
85 - public Builder setMsgId(String msgId) {  
86 - this.msgId = msgId;  
87 - return this;  
88 - }  
89 -  
90 - public Builder setRespId(String respId) {  
91 - this.respId = respId;  
92 - return this;  
93 - }  
94 -  
95 - public Builder setRs(Rs re) {  
96 - this.rs = re;  
97 - return this;  
98 - }  
99 -  
100 - public Cmd build() {  
101 - return new Cmd(this);  
102 - }  
103 - }  
104 -  
105 -  
106 - @Override  
107 - public String toString() {  
108 - return "Cmd{" +  
109 - "devId='" + devId + '\'' +  
110 - ", packageNo=" + packageNo +  
111 - ", msgId='" + msgId + '\'' +  
112 - ", respId='" + respId + '\'' +  
113 - ", rs=" + rs +  
114 - '}';  
115 - }  
116 -}  
src/main/java/com/genersoft/iot/vmp/jt1078/proc/factory/CodecFactory.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.jt1078.proc.factory;  
2 -  
3 -import com.genersoft.iot.vmp.jt1078.annotation.MsgId;  
4 -import com.genersoft.iot.vmp.jt1078.proc.request.Re;  
5 -import com.genersoft.iot.vmp.jt1078.util.ClassUtil;  
6 -import org.slf4j.Logger;  
7 -import org.slf4j.LoggerFactory;  
8 -  
9 -import java.util.HashMap;  
10 -import java.util.List;  
11 -import java.util.Map;  
12 -  
13 -/**  
14 - * @author QingtaiJiang  
15 - * @date 2023/4/27 18:29  
16 - * @email qingtaij@163.com  
17 - */  
18 -  
19 -public class CodecFactory {  
20 - private final static Logger log = LoggerFactory.getLogger(CodecFactory.class);  
21 -  
22 - private static Map<String, Class<?>> protocolHash;  
23 -  
24 - public static void init() {  
25 - protocolHash = new HashMap<>();  
26 - List<Class<?>> classList = ClassUtil.getClassList("com.genersoft.iot.vmp.jt1078.proc", MsgId.class);  
27 - for (Class<?> handlerClass : classList) {  
28 - String id = handlerClass.getAnnotation(MsgId.class).id();  
29 - protocolHash.put(id, handlerClass);  
30 - }  
31 - if (log.isDebugEnabled()) {  
32 - log.debug("消息ID缓存表 protocolHash:{}", protocolHash);  
33 - }  
34 - }  
35 -  
36 - public static Re getHandler(String msgId) {  
37 - Class<?> aClass = protocolHash.get(msgId);  
38 - Object bean = ClassUtil.getBean(aClass);  
39 - if (bean instanceof Re) {  
40 - return (Re) bean;  
41 - }  
42 - return null;  
43 - }  
44 -}  
src/main/java/com/genersoft/iot/vmp/jt1078/proc/request/J0001.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.jt1078.proc.request;  
2 -  
3 -import com.alibaba.fastjson2.JSON;  
4 -import com.genersoft.iot.vmp.jt1078.annotation.MsgId;  
5 -import com.genersoft.iot.vmp.jt1078.proc.Header;  
6 -import com.genersoft.iot.vmp.jt1078.proc.response.Rs;  
7 -import com.genersoft.iot.vmp.jt1078.session.Session;  
8 -import com.genersoft.iot.vmp.jt1078.session.SessionManager;  
9 -import io.netty.buffer.ByteBuf;  
10 -import io.netty.buffer.ByteBufUtil;  
11 -  
12 -/**  
13 - * 终端通用应答  
14 - *  
15 - * @author QingtaiJiang  
16 - * @date 2023/4/27 18:04  
17 - * @email qingtaij@163.com  
18 - */  
19 -@MsgId(id = "0001")  
20 -public class J0001 extends Re {  
21 - int respNo;  
22 - String respId;  
23 - int result;  
24 -  
25 - @Override  
26 - protected Rs decode0(ByteBuf buf, Header header, Session session) {  
27 - respNo = buf.readUnsignedShort();  
28 - respId = ByteBufUtil.hexDump(buf.readSlice(2));  
29 - result = buf.readUnsignedByte();  
30 - return null;  
31 - }  
32 -  
33 - @Override  
34 - protected Rs handler(Header header, Session session) {  
35 - SessionManager.INSTANCE.response(header.getDevId(), "0001", (long) respNo, JSON.toJSONString(this));  
36 - return null;  
37 - }  
38 -  
39 - public int getRespNo() {  
40 - return respNo;  
41 - }  
42 -  
43 - public String getRespId() {  
44 - return respId;  
45 - }  
46 -  
47 - public int getResult() {  
48 - return result;  
49 - }  
50 -}  
src/main/java/com/genersoft/iot/vmp/jt1078/proc/request/J0002.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.jt1078.proc.request;  
2 -  
3 -import com.genersoft.iot.vmp.jt1078.annotation.MsgId;  
4 -import com.genersoft.iot.vmp.jt1078.proc.Header;  
5 -import com.genersoft.iot.vmp.jt1078.proc.response.J8001;  
6 -import com.genersoft.iot.vmp.jt1078.proc.response.Rs;  
7 -import com.genersoft.iot.vmp.jt1078.session.Session;  
8 -import io.netty.buffer.ByteBuf;  
9 -  
10 -/**  
11 - * 终端心跳  
12 - *  
13 - * @author QingtaiJiang  
14 - * @date 2023/4/27 18:04  
15 - * @email qingtaij@163.com  
16 - */  
17 -@MsgId(id = "0002")  
18 -public class J0002 extends Re {  
19 - @Override  
20 - protected Rs decode0(ByteBuf buf, Header header, Session session) {  
21 - return null;  
22 - }  
23 -  
24 - @Override  
25 - protected Rs handler(Header header, Session session) {  
26 - J8001 j8001 = new J8001();  
27 - j8001.setRespNo(header.getSn());  
28 - j8001.setRespId(header.getMsgId());  
29 - j8001.setResult(J8001.SUCCESS);  
30 - return j8001;  
31 - }  
32 -}  
src/main/java/com/genersoft/iot/vmp/jt1078/proc/request/J0004.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.jt1078.proc.request;  
2 -  
3 -import com.genersoft.iot.vmp.jt1078.annotation.MsgId;  
4 -import com.genersoft.iot.vmp.jt1078.proc.Header;  
5 -import com.genersoft.iot.vmp.jt1078.proc.response.Rs;  
6 -import com.genersoft.iot.vmp.jt1078.session.Session;  
7 -import io.netty.buffer.ByteBuf;  
8 -  
9 -/**  
10 - * 查询服务器时间  
11 - *  
12 - * @author QingtaiJiang  
13 - * @date 2023/4/27 18:06  
14 - * @email qingtaij@163.com  
15 - */  
16 -@MsgId(id = "0004")  
17 -public class J0004 extends Re {  
18 - @Override  
19 - protected Rs decode0(ByteBuf buf, Header header, Session session) {  
20 - return null;  
21 - }  
22 -  
23 - @Override  
24 - protected Rs handler(Header header, Session session) {  
25 - return null;  
26 - }  
27 -}  
src/main/java/com/genersoft/iot/vmp/jt1078/proc/request/J0100.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.jt1078.proc.request;  
2 -  
3 -import com.genersoft.iot.vmp.jt1078.annotation.MsgId;  
4 -import com.genersoft.iot.vmp.jt1078.proc.Header;  
5 -import com.genersoft.iot.vmp.jt1078.proc.response.J8100;  
6 -import com.genersoft.iot.vmp.jt1078.proc.response.Rs;  
7 -import com.genersoft.iot.vmp.jt1078.session.Session;  
8 -import io.netty.buffer.ByteBuf;  
9 -  
10 -/**  
11 - * 终端注册  
12 - *  
13 - * @author QingtaiJiang  
14 - * @date 2023/4/27 18:06  
15 - * @email qingtaij@163.com  
16 - */  
17 -@MsgId(id = "0100")  
18 -public class J0100 extends Re {  
19 -  
20 - private int provinceId;  
21 -  
22 - private int cityId;  
23 -  
24 - private String makerId;  
25 -  
26 - private String deviceModel;  
27 -  
28 - private String deviceId;  
29 -  
30 - private int plateColor;  
31 -  
32 - private String plateNo;  
33 -  
34 - @Override  
35 - protected Rs decode0(ByteBuf buf, Header header, Session session) {  
36 - Short version = header.getVersion();  
37 - provinceId = buf.readUnsignedShort();  
38 - if (version > 1) {  
39 - cityId = buf.readUnsignedShort();  
40 - // decode as 2019  
41 - } else {  
42 - int i = buf.readUnsignedShort();  
43 - // decode as 2013  
44 - }  
45 - return null;  
46 - }  
47 -  
48 - @Override  
49 - protected Rs handler(Header header, Session session) {  
50 - J8100 j8100 = new J8100();  
51 - j8100.setRespNo(header.getSn());  
52 - j8100.setResult(J8100.SUCCESS);  
53 - j8100.setCode("WVP_YYDS");  
54 - return j8100;  
55 - }  
56 -}  
src/main/java/com/genersoft/iot/vmp/jt1078/proc/request/J0102.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.jt1078.proc.request;  
2 -  
3 -import com.genersoft.iot.vmp.jt1078.annotation.MsgId;  
4 -import com.genersoft.iot.vmp.jt1078.proc.Header;  
5 -import com.genersoft.iot.vmp.jt1078.proc.response.J8001;  
6 -import com.genersoft.iot.vmp.jt1078.proc.response.Rs;  
7 -import com.genersoft.iot.vmp.jt1078.session.Session;  
8 -import io.netty.buffer.ByteBuf;  
9 -  
10 -/**  
11 - * 终端鉴权  
12 - *  
13 - * @author QingtaiJiang  
14 - * @date 2023/4/27 18:06  
15 - * @email qingtaij@163.com  
16 - */  
17 -@MsgId(id = "0102")  
18 -public class J0102 extends Re {  
19 - @Override  
20 - protected Rs decode0(ByteBuf buf, Header header, Session session) {  
21 - int lenCode = buf.readUnsignedByte();  
22 -// String code = buf.readCharSequence(lenCode, CharsetUtil.UTF_8).toString();  
23 - // if 2019 to decode next  
24 - return null;  
25 - }  
26 -  
27 - @Override  
28 - protected Rs handler(Header header, Session session) {  
29 - J8001 j8001 = new J8001();  
30 - j8001.setRespNo(header.getSn());  
31 - j8001.setRespId(header.getMsgId());  
32 - j8001.setResult(J8001.SUCCESS);  
33 - return j8001;  
34 - }  
35 -  
36 -}  
src/main/java/com/genersoft/iot/vmp/jt1078/proc/request/J0200.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.jt1078.proc.request;  
2 -  
3 -import com.genersoft.iot.vmp.jt1078.annotation.MsgId;  
4 -import com.genersoft.iot.vmp.jt1078.proc.Header;  
5 -import com.genersoft.iot.vmp.jt1078.proc.response.J8001;  
6 -import com.genersoft.iot.vmp.jt1078.proc.response.Rs;  
7 -import com.genersoft.iot.vmp.jt1078.session.Session;  
8 -import io.netty.buffer.ByteBuf;  
9 -  
10 -/**  
11 - * 实时消息上报  
12 - *  
13 - * @author QingtaiJiang  
14 - * @date 2023/4/27 18:06  
15 - * @email qingtaij@163.com  
16 - */  
17 -@MsgId(id = "0200")  
18 -public class J0200 extends Re {  
19 - @Override  
20 - protected Rs decode0(ByteBuf buf, Header header, Session session) {  
21 - return null;  
22 - }  
23 -  
24 - @Override  
25 - protected Rs handler(Header header, Session session) {  
26 - J8001 j8001 = new J8001();  
27 - j8001.setRespNo(header.getSn());  
28 - j8001.setRespId(header.getMsgId());  
29 - j8001.setResult(J8001.SUCCESS);  
30 - return j8001;  
31 - }  
32 -}  
src/main/java/com/genersoft/iot/vmp/jt1078/proc/request/J1205.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.jt1078.proc.request;  
2 -  
3 -import com.alibaba.fastjson2.JSON;  
4 -import com.genersoft.iot.vmp.jt1078.annotation.MsgId;  
5 -import com.genersoft.iot.vmp.jt1078.proc.Header;  
6 -import com.genersoft.iot.vmp.jt1078.proc.response.J8001;  
7 -import com.genersoft.iot.vmp.jt1078.proc.response.Rs;  
8 -import com.genersoft.iot.vmp.jt1078.session.Session;  
9 -import com.genersoft.iot.vmp.jt1078.session.SessionManager;  
10 -import io.netty.buffer.ByteBuf;  
11 -import io.netty.buffer.ByteBufUtil;  
12 -  
13 -import java.util.ArrayList;  
14 -import java.util.List;  
15 -  
16 -/**  
17 - * 终端上传音视频资源列表  
18 - *  
19 - * @author QingtaiJiang  
20 - * @date 2023/4/28 10:36  
21 - * @email qingtaij@163.com  
22 - */  
23 -@MsgId(id = "1205")  
24 -public class J1205 extends Re {  
25 - Integer respNo;  
26 -  
27 - private List<JRecordItem> recordList = new ArrayList<JRecordItem>();  
28 -  
29 - @Override  
30 - protected Rs decode0(ByteBuf buf, Header header, Session session) {  
31 - respNo = buf.readUnsignedShort();  
32 - long size = buf.readUnsignedInt();  
33 -  
34 - for (int i = 0; i < size; i++) {  
35 - JRecordItem item = new JRecordItem();  
36 - item.setChannelId(buf.readUnsignedByte());  
37 - item.setStartTime(ByteBufUtil.hexDump(buf.readSlice(6)));  
38 - item.setEndTime(ByteBufUtil.hexDump(buf.readSlice(6)));  
39 - item.setWarn(buf.readLong());  
40 - item.setMediaType(buf.readUnsignedByte());  
41 - item.setStreamType(buf.readUnsignedByte());  
42 - item.setStorageType(buf.readUnsignedByte());  
43 - item.setSize(buf.readUnsignedInt());  
44 - recordList.add(item);  
45 - }  
46 -  
47 - return null;  
48 - }  
49 -  
50 - @Override  
51 - protected Rs handler(Header header, Session session) {  
52 - SessionManager.INSTANCE.response(header.getDevId(), "1205", (long) respNo, JSON.toJSONString(this));  
53 -  
54 - J8001 j8001 = new J8001();  
55 - j8001.setRespNo(header.getSn());  
56 - j8001.setRespId(header.getMsgId());  
57 - j8001.setResult(J8001.SUCCESS);  
58 - return j8001;  
59 - }  
60 -  
61 -  
62 - public Integer getRespNo() {  
63 - return respNo;  
64 - }  
65 -  
66 - public void setRespNo(Integer respNo) {  
67 - this.respNo = respNo;  
68 - }  
69 -  
70 - public List<JRecordItem> getRecordList() {  
71 - return recordList;  
72 - }  
73 -  
74 - public void setRecordList(List<JRecordItem> recordList) {  
75 - this.recordList = recordList;  
76 - }  
77 -  
78 - public static class JRecordItem {  
79 -  
80 - // 逻辑通道号  
81 - private int channelId;  
82 -  
83 - // 开始时间  
84 - private String startTime;  
85 -  
86 - // 结束时间  
87 - private String endTime;  
88 -  
89 - // 报警标志  
90 - private long warn;  
91 -  
92 - // 音视频资源类型  
93 - private int mediaType;  
94 -  
95 - // 码流类型  
96 - private int streamType = 1;  
97 -  
98 - // 存储器类型  
99 - private int storageType;  
100 -  
101 - // 文件大小  
102 - private long size;  
103 -  
104 - public int getChannelId() {  
105 - return channelId;  
106 - }  
107 -  
108 - public void setChannelId(int channelId) {  
109 - this.channelId = channelId;  
110 - }  
111 -  
112 - public String getStartTime() {  
113 - return startTime;  
114 - }  
115 -  
116 - public void setStartTime(String startTime) {  
117 - this.startTime = startTime;  
118 - }  
119 -  
120 - public String getEndTime() {  
121 - return endTime;  
122 - }  
123 -  
124 - public void setEndTime(String endTime) {  
125 - this.endTime = endTime;  
126 - }  
127 -  
128 - public long getWarn() {  
129 - return warn;  
130 - }  
131 -  
132 - public void setWarn(long warn) {  
133 - this.warn = warn;  
134 - }  
135 -  
136 - public int getMediaType() {  
137 - return mediaType;  
138 - }  
139 -  
140 - public void setMediaType(int mediaType) {  
141 - this.mediaType = mediaType;  
142 - }  
143 -  
144 - public int getStreamType() {  
145 - return streamType;  
146 - }  
147 -  
148 - public void setStreamType(int streamType) {  
149 - this.streamType = streamType;  
150 - }  
151 -  
152 - public int getStorageType() {  
153 - return storageType;  
154 - }  
155 -  
156 - public void setStorageType(int storageType) {  
157 - this.storageType = storageType;  
158 - }  
159 -  
160 - public long getSize() {  
161 - return size;  
162 - }  
163 -  
164 - public void setSize(long size) {  
165 - this.size = size;  
166 - }  
167 -  
168 - @Override  
169 - public String toString() {  
170 - return "JRecordItem{" +  
171 - "channelId=" + channelId +  
172 - ", startTime='" + startTime + '\'' +  
173 - ", endTime='" + endTime + '\'' +  
174 - ", warn=" + warn +  
175 - ", mediaType=" + mediaType +  
176 - ", streamType=" + streamType +  
177 - ", storageType=" + storageType +  
178 - ", size=" + size +  
179 - '}';  
180 - }  
181 - }  
182 -  
183 - @Override  
184 - public String toString() {  
185 - return "J1205{" +  
186 - "respNo=" + respNo +  
187 - ", recordList=" + recordList +  
188 - '}';  
189 - }  
190 -}  
src/main/java/com/genersoft/iot/vmp/jt1078/proc/request/Re.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.jt1078.proc.request;  
2 -  
3 -import com.genersoft.iot.vmp.jt1078.proc.Header;  
4 -import com.genersoft.iot.vmp.jt1078.proc.response.Rs;  
5 -import com.genersoft.iot.vmp.jt1078.session.Session;  
6 -import io.netty.buffer.ByteBuf;  
7 -import org.slf4j.Logger;  
8 -import org.slf4j.LoggerFactory;  
9 -import org.springframework.util.StringUtils;  
10 -  
11 -/**  
12 - * @author QingtaiJiang  
13 - * @date 2023/4/27 18:50  
14 - * @email qingtaij@163.com  
15 - */  
16 -public abstract class Re {  
17 - private final static Logger log = LoggerFactory.getLogger(Re.class);  
18 -  
19 - protected abstract Rs decode0(ByteBuf buf, Header header, Session session);  
20 -  
21 - protected abstract Rs handler(Header header, Session session);  
22 -  
23 - public Rs decode(ByteBuf buf, Header header, Session session) {  
24 - if (session != null && !StringUtils.hasLength(session.getDevId())) {  
25 - session.register(header.getDevId(), (int) header.getVersion(), header);  
26 - }  
27 - Rs rs = decode0(buf, header, session);  
28 - Rs rsHand = handler(header, session);  
29 - if (rs == null && rsHand != null) {  
30 - rs = rsHand;  
31 - } else if (rs != null && rsHand != null) {  
32 - log.warn("decode0:{} 与 handler:{} 返回值冲突,采用decode0返回值", rs, rsHand);  
33 - }  
34 - if (rs != null) {  
35 - rs.setHeader(header);  
36 - }  
37 -  
38 - return rs;  
39 - }  
40 -}  
src/main/java/com/genersoft/iot/vmp/jt1078/proc/response/J8001.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.jt1078.proc.response;  
2 -  
3 -import com.genersoft.iot.vmp.jt1078.annotation.MsgId;  
4 -import io.netty.buffer.ByteBuf;  
5 -import io.netty.buffer.ByteBufUtil;  
6 -import io.netty.buffer.Unpooled;  
7 -  
8 -/**  
9 - * @author QingtaiJiang  
10 - * @date 2023/4/27 18:48  
11 - * @email qingtaij@163.com  
12 - */  
13 -@MsgId(id = "8001")  
14 -public class J8001 extends Rs {  
15 - public static final Integer SUCCESS = 0;  
16 -  
17 - Integer respNo;  
18 - String respId;  
19 - Integer result;  
20 -  
21 - @Override  
22 - public ByteBuf encode() {  
23 - ByteBuf buffer = Unpooled.buffer();  
24 - buffer.writeShort(respNo);  
25 - buffer.writeBytes(ByteBufUtil.decodeHexDump(respId));  
26 - buffer.writeByte(result);  
27 -  
28 - return buffer;  
29 - }  
30 -  
31 -  
32 - public void setRespNo(Integer respNo) {  
33 - this.respNo = respNo;  
34 - }  
35 -  
36 - public void setRespId(String respId) {  
37 - this.respId = respId;  
38 - }  
39 -  
40 - public void setResult(Integer result) {  
41 - this.result = result;  
42 - }  
43 -}  
src/main/java/com/genersoft/iot/vmp/jt1078/proc/response/J8100.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.jt1078.proc.response;  
2 -  
3 -import com.genersoft.iot.vmp.jt1078.annotation.MsgId;  
4 -import io.netty.buffer.ByteBuf;  
5 -import io.netty.buffer.Unpooled;  
6 -import io.netty.util.CharsetUtil;  
7 -  
8 -/**  
9 - * @author QingtaiJiang  
10 - * @date 2023/4/27 18:40  
11 - * @email qingtaij@163.com  
12 - */  
13 -@MsgId(id = "8100")  
14 -public class J8100 extends Rs {  
15 - public static final Integer SUCCESS = 0;  
16 -  
17 - Integer respNo;  
18 - Integer result;  
19 - String code;  
20 -  
21 - @Override  
22 - public ByteBuf encode() {  
23 - ByteBuf buffer = Unpooled.buffer();  
24 - buffer.writeShort(respNo);  
25 - buffer.writeByte(result);  
26 - buffer.writeCharSequence(code, CharsetUtil.UTF_8);  
27 - return buffer;  
28 - }  
29 -  
30 - public void setRespNo(Integer respNo) {  
31 - this.respNo = respNo;  
32 - }  
33 -  
34 - public void setResult(Integer result) {  
35 - this.result = result;  
36 - }  
37 -  
38 - public void setCode(String code) {  
39 - this.code = code;  
40 - }  
41 -}  
src/main/java/com/genersoft/iot/vmp/jt1078/proc/response/J9101.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.jt1078.proc.response;  
2 -  
3 -import com.genersoft.iot.vmp.jt1078.annotation.MsgId;  
4 -import io.netty.buffer.ByteBuf;  
5 -import io.netty.buffer.Unpooled;  
6 -import io.netty.util.CharsetUtil;  
7 -  
8 -/**  
9 - * 实时音视频传输请求  
10 - *  
11 - * @author QingtaiJiang  
12 - * @date 2023/4/27 18:25  
13 - * @email qingtaij@163.com  
14 - */  
15 -@MsgId(id = "9101")  
16 -public class J9101 extends Rs {  
17 - String ip;  
18 -  
19 - // TCP端口  
20 - Integer tcpPort;  
21 -  
22 - // UDP端口  
23 - Integer udpPort;  
24 -  
25 - // 逻辑通道号  
26 - Integer channel;  
27 -  
28 - // 数据类型  
29 - /**  
30 - * 0:音视频,1:视频,2:双向对讲,3:监听,4:中心广播,5:透传  
31 - */  
32 - Integer type;  
33 -  
34 - // 码流类型  
35 - /**  
36 - * 0:主码流,1:子码流  
37 - */  
38 - Integer rate;  
39 -  
40 - @Override  
41 - public ByteBuf encode() {  
42 - ByteBuf buffer = Unpooled.buffer();  
43 - buffer.writeByte(ip.getBytes().length);  
44 - buffer.writeCharSequence(ip, CharsetUtil.UTF_8);  
45 - buffer.writeShort(tcpPort);  
46 - buffer.writeShort(udpPort);  
47 - buffer.writeByte(channel);  
48 - buffer.writeByte(type);  
49 - buffer.writeByte(rate);  
50 - return buffer;  
51 - }  
52 -  
53 - public String getIp() {  
54 - return ip;  
55 - }  
56 -  
57 - public void setIp(String ip) {  
58 - this.ip = ip;  
59 - }  
60 -  
61 - public Integer getTcpPort() {  
62 - return tcpPort;  
63 - }  
64 -  
65 - public void setTcpPort(Integer tcpPort) {  
66 - this.tcpPort = tcpPort;  
67 - }  
68 -  
69 - public Integer getUdpPort() {  
70 - return udpPort;  
71 - }  
72 -  
73 - public void setUdpPort(Integer udpPort) {  
74 - this.udpPort = udpPort;  
75 - }  
76 -  
77 - public Integer getChannel() {  
78 - return channel;  
79 - }  
80 -  
81 - public void setChannel(Integer channel) {  
82 - this.channel = channel;  
83 - }  
84 -  
85 - public Integer getType() {  
86 - return type;  
87 - }  
88 -  
89 - public void setType(Integer type) {  
90 - this.type = type;  
91 - }  
92 -  
93 - public Integer getRate() {  
94 - return rate;  
95 - }  
96 -  
97 - public void setRate(Integer rate) {  
98 - this.rate = rate;  
99 - }  
100 -  
101 - @Override  
102 - public String toString() {  
103 - return "J9101{" +  
104 - "ip='" + ip + '\'' +  
105 - ", tcpPort=" + tcpPort +  
106 - ", udpPort=" + udpPort +  
107 - ", channel=" + channel +  
108 - ", type=" + type +  
109 - ", rate=" + rate +  
110 - '}';  
111 - }  
112 -}  
src/main/java/com/genersoft/iot/vmp/jt1078/proc/response/J9102.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.jt1078.proc.response;  
2 -  
3 -import com.genersoft.iot.vmp.jt1078.annotation.MsgId;  
4 -import io.netty.buffer.ByteBuf;  
5 -import io.netty.buffer.Unpooled;  
6 -  
7 -/**  
8 - * 音视频实时传输控制  
9 - *  
10 - * @author QingtaiJiang  
11 - * @date 2023/4/27 18:49  
12 - * @email qingtaij@163.com  
13 - */  
14 -@MsgId(id = "9102")  
15 -public class J9102 extends Rs {  
16 -  
17 - // 通道号  
18 - Integer channel;  
19 -  
20 - // 控制指令  
21 - /**  
22 - * 0:关闭音视频传输指令;  
23 - * 1:切换码流(增加暂停和继续);  
24 - * 2:暂停该通道所有流的发送;  
25 - * 3:恢复暂停前流的发送,与暂停前的流类型一致;  
26 - * 4:关闭双向对讲  
27 - */  
28 - Integer command;  
29 -  
30 - // 数据类型  
31 - /**  
32 - * 0:关闭该通道有关的音视频数据;  
33 - * 1:只关闭该通道有关的音频,保留该通道  
34 - * 有关的视频;  
35 - * 2:只关闭该通道有关的视频,保留该通道  
36 - * 有关的音频  
37 - */  
38 - Integer closeType;  
39 -  
40 - // 数据类型  
41 - /**  
42 - * 0:主码流;  
43 - * 1:子码流  
44 - */  
45 - Integer streamType;  
46 -  
47 - @Override  
48 - public ByteBuf encode() {  
49 - ByteBuf buffer = Unpooled.buffer();  
50 - buffer.writeByte(channel);  
51 - buffer.writeByte(command);  
52 - buffer.writeByte(closeType);  
53 - buffer.writeByte(streamType);  
54 - return buffer;  
55 - }  
56 -  
57 -  
58 - public Integer getChannel() {  
59 - return channel;  
60 - }  
61 -  
62 - public void setChannel(Integer channel) {  
63 - this.channel = channel;  
64 - }  
65 -  
66 - public Integer getCommand() {  
67 - return command;  
68 - }  
69 -  
70 - public void setCommand(Integer command) {  
71 - this.command = command;  
72 - }  
73 -  
74 - public Integer getCloseType() {  
75 - return closeType;  
76 - }  
77 -  
78 - public void setCloseType(Integer closeType) {  
79 - this.closeType = closeType;  
80 - }  
81 -  
82 - public Integer getStreamType() {  
83 - return streamType;  
84 - }  
85 -  
86 - public void setStreamType(Integer streamType) {  
87 - this.streamType = streamType;  
88 - }  
89 -  
90 - @Override  
91 - public String toString() {  
92 - return "J9102{" +  
93 - "channel=" + channel +  
94 - ", command=" + command +  
95 - ", closeType=" + closeType +  
96 - ", streamType=" + streamType +  
97 - '}';  
98 - }  
99 -}  
src/main/java/com/genersoft/iot/vmp/jt1078/proc/response/J9201.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.jt1078.proc.response;  
2 -  
3 -import com.genersoft.iot.vmp.jt1078.annotation.MsgId;  
4 -import io.netty.buffer.ByteBuf;  
5 -import io.netty.buffer.ByteBufUtil;  
6 -import io.netty.buffer.Unpooled;  
7 -import io.netty.util.CharsetUtil;  
8 -  
9 -/**  
10 - * 回放请求  
11 - *  
12 - * @author QingtaiJiang  
13 - * @date 2023/4/28 10:37  
14 - * @email qingtaij@163.com  
15 - */  
16 -@MsgId(id = "9201")  
17 -public class J9201 extends Rs {  
18 - // 服务器IP地址  
19 - private String ip;  
20 -  
21 - // 实时视频服务器TCP端口号  
22 - private int tcpPort;  
23 -  
24 - // 实时视频服务器UDP端口号  
25 - private int udpPort;  
26 -  
27 - // 逻辑通道号  
28 - private int channel;  
29 -  
30 - // 音视频资源类型:0.音视频 1.音频 2.视频 3.视频或音视频  
31 - private int type;  
32 -  
33 - // 码流类型:0.所有码流 1.主码流 2.子码流(如果此通道只传输音频,此字段置0)  
34 - private int rate;  
35 -  
36 - // 存储器类型:0.所有存储器 1.主存储器 2.灾备存储器"  
37 - private int storageType;  
38 -  
39 - // 回放方式:0.正常回放 1.快进回放 2.关键帧快退回放 3.关键帧播放 4.单帧上传  
40 - private int playbackType;  
41 -  
42 - // 快进或快退倍数:0.无效 1.1倍 2.2倍 3.4倍 4.8倍 5.16倍 (回放控制为1和2时,此字段内容有效,否则置0)  
43 - private int playbackSpeed;  
44 -  
45 - // 开始时间YYMMDDHHMMSS,回放方式为4时,该字段表示单帧上传时间  
46 - private String startTime;  
47 -  
48 - // 结束时间YYMMDDHHMMSS,回放方式为4时,该字段无效,为0表示一直回放  
49 - private String endTime;  
50 -  
51 - @Override  
52 - public ByteBuf encode() {  
53 - ByteBuf buffer = Unpooled.buffer();  
54 - buffer.writeByte(ip.getBytes().length);  
55 - buffer.writeCharSequence(ip, CharsetUtil.UTF_8);  
56 - buffer.writeShort(tcpPort);  
57 - buffer.writeShort(udpPort);  
58 - buffer.writeByte(channel);  
59 - buffer.writeByte(type);  
60 - buffer.writeByte(rate);  
61 - buffer.writeByte(storageType);  
62 - buffer.writeByte(playbackType);  
63 - buffer.writeByte(playbackSpeed);  
64 - buffer.writeBytes(ByteBufUtil.decodeHexDump(startTime));  
65 - buffer.writeBytes(ByteBufUtil.decodeHexDump(endTime));  
66 - return buffer;  
67 - }  
68 -  
69 - public String getIp() {  
70 - return ip;  
71 - }  
72 -  
73 - public void setIp(String ip) {  
74 - this.ip = ip;  
75 - }  
76 -  
77 - public int getTcpPort() {  
78 - return tcpPort;  
79 - }  
80 -  
81 - public void setTcpPort(int tcpPort) {  
82 - this.tcpPort = tcpPort;  
83 - }  
84 -  
85 - public int getUdpPort() {  
86 - return udpPort;  
87 - }  
88 -  
89 - public void setUdpPort(int udpPort) {  
90 - this.udpPort = udpPort;  
91 - }  
92 -  
93 - public int getChannel() {  
94 - return channel;  
95 - }  
96 -  
97 - public void setChannel(int channel) {  
98 - this.channel = channel;  
99 - }  
100 -  
101 - public int getType() {  
102 - return type;  
103 - }  
104 -  
105 - public void setType(int type) {  
106 - this.type = type;  
107 - }  
108 -  
109 - public int getRate() {  
110 - return rate;  
111 - }  
112 -  
113 - public void setRate(int rate) {  
114 - this.rate = rate;  
115 - }  
116 -  
117 - public int getStorageType() {  
118 - return storageType;  
119 - }  
120 -  
121 - public void setStorageType(int storageType) {  
122 - this.storageType = storageType;  
123 - }  
124 -  
125 - public int getPlaybackType() {  
126 - return playbackType;  
127 - }  
128 -  
129 - public void setPlaybackType(int playbackType) {  
130 - this.playbackType = playbackType;  
131 - }  
132 -  
133 - public int getPlaybackSpeed() {  
134 - return playbackSpeed;  
135 - }  
136 -  
137 - public void setPlaybackSpeed(int playbackSpeed) {  
138 - this.playbackSpeed = playbackSpeed;  
139 - }  
140 -  
141 - public String getStartTime() {  
142 - return startTime;  
143 - }  
144 -  
145 - public void setStartTime(String startTime) {  
146 - this.startTime = startTime;  
147 - }  
148 -  
149 - public String getEndTime() {  
150 - return endTime;  
151 - }  
152 -  
153 - public void setEndTime(String endTime) {  
154 - this.endTime = endTime;  
155 - }  
156 -  
157 - @Override  
158 - public String toString() {  
159 - return "J9201{" +  
160 - "ip='" + ip + '\'' +  
161 - ", tcpPort=" + tcpPort +  
162 - ", udpPort=" + udpPort +  
163 - ", channel=" + channel +  
164 - ", type=" + type +  
165 - ", rate=" + rate +  
166 - ", storageType=" + storageType +  
167 - ", playbackType=" + playbackType +  
168 - ", playbackSpeed=" + playbackSpeed +  
169 - ", startTime='" + startTime + '\'' +  
170 - ", endTime='" + endTime + '\'' +  
171 - '}';  
172 - }  
173 -}  
src/main/java/com/genersoft/iot/vmp/jt1078/proc/response/J9202.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.jt1078.proc.response;  
2 -  
3 -import com.genersoft.iot.vmp.jt1078.annotation.MsgId;  
4 -import io.netty.buffer.ByteBuf;  
5 -import io.netty.buffer.ByteBufUtil;  
6 -import io.netty.buffer.Unpooled;  
7 -  
8 -/**  
9 - * 平台下发远程录像回放控制  
10 - *  
11 - * @author QingtaiJiang  
12 - * @date 2023/4/28 10:37  
13 - * @email qingtaij@163.com  
14 - */  
15 -@MsgId(id = "9202")  
16 -public class J9202 extends Rs {  
17 - // 逻辑通道号  
18 - private int channel;  
19 -  
20 - // 回放控制:0.开始回放 1.暂停回放 2.结束回放 3.快进回放 4.关键帧快退回放 5.拖动回放 6.关键帧播放  
21 - private int playbackType;  
22 -  
23 - // 快进或快退倍数:0.无效 1.1倍 2.2倍 3.4倍 4.8倍 5.16倍 (回放控制为3和4时,此字段内容有效,否则置0)  
24 - private int playbackSpeed;  
25 -  
26 - // 拖动回放位置(YYMMDDHHMMSS,回放控制为5时,此字段有效)  
27 - private String playbackTime;  
28 -  
29 - @Override  
30 - public ByteBuf encode() {  
31 - ByteBuf buffer = Unpooled.buffer();  
32 - buffer.writeByte(channel);  
33 - buffer.writeByte(playbackType);  
34 - buffer.writeByte(playbackSpeed);  
35 - buffer.writeBytes(ByteBufUtil.decodeHexDump(playbackTime));  
36 - return buffer;  
37 - }  
38 -  
39 - public int getChannel() {  
40 - return channel;  
41 - }  
42 -  
43 - public void setChannel(int channel) {  
44 - this.channel = channel;  
45 - }  
46 -  
47 - public int getPlaybackType() {  
48 - return playbackType;  
49 - }  
50 -  
51 - public void setPlaybackType(int playbackType) {  
52 - this.playbackType = playbackType;  
53 - }  
54 -  
55 - public int getPlaybackSpeed() {  
56 - return playbackSpeed;  
57 - }  
58 -  
59 - public void setPlaybackSpeed(int playbackSpeed) {  
60 - this.playbackSpeed = playbackSpeed;  
61 - }  
62 -  
63 - public String getPlaybackTime() {  
64 - return playbackTime;  
65 - }  
66 -  
67 - public void setPlaybackTime(String playbackTime) {  
68 - this.playbackTime = playbackTime;  
69 - }  
70 -  
71 - @Override  
72 - public String toString() {  
73 - return "J9202{" +  
74 - "channel=" + channel +  
75 - ", playbackType=" + playbackType +  
76 - ", playbackSpeed=" + playbackSpeed +  
77 - ", playbackTime='" + playbackTime + '\'' +  
78 - '}';  
79 - }  
80 -}  
src/main/java/com/genersoft/iot/vmp/jt1078/proc/response/J9205.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.jt1078.proc.response;  
2 -  
3 -import com.genersoft.iot.vmp.jt1078.annotation.MsgId;  
4 -import io.netty.buffer.ByteBuf;  
5 -import io.netty.buffer.ByteBufUtil;  
6 -import io.netty.buffer.Unpooled;  
7 -  
8 -/**  
9 - * 查询资源列表  
10 - *  
11 - * @author QingtaiJiang  
12 - * @date 2023/4/28 10:36  
13 - * @email qingtaij@163.com  
14 - */  
15 -@MsgId(id = "9205")  
16 -public class J9205 extends Rs {  
17 - // 逻辑通道号  
18 - private int channelId;  
19 -  
20 - // 开始时间YYMMDDHHMMSS,全0表示无起始时间  
21 - private String startTime;  
22 -  
23 - // 结束时间YYMMDDHHMMSS,全0表示无终止时间  
24 - private String endTime;  
25 -  
26 - // 报警标志  
27 - private final int warnType = 0;  
28 -  
29 - // 音视频资源类型:0.音视频 1.音频 2.视频 3.视频或音视频  
30 - private int mediaType;  
31 -  
32 - // 码流类型:0.所有码流 1.主码流 2.子码流  
33 - private int streamType = 0;  
34 -  
35 - // 存储器类型:0.所有存储器 1.主存储器 2.灾备存储器  
36 - private int storageType = 0;  
37 -  
38 - @Override  
39 - public ByteBuf encode() {  
40 - ByteBuf buffer = Unpooled.buffer();  
41 -  
42 - buffer.writeByte(channelId);  
43 - buffer.writeBytes(ByteBufUtil.decodeHexDump(startTime));  
44 - buffer.writeBytes(ByteBufUtil.decodeHexDump(endTime));  
45 - buffer.writeLong(warnType);  
46 - buffer.writeByte(mediaType);  
47 - buffer.writeByte(streamType);  
48 - buffer.writeByte(storageType);  
49 -  
50 - return buffer;  
51 - }  
52 -  
53 -  
54 - public void setChannelId(int channelId) {  
55 - this.channelId = channelId;  
56 - }  
57 -  
58 - public void setStartTime(String startTime) {  
59 - this.startTime = startTime;  
60 - }  
61 -  
62 - public void setEndTime(String endTime) {  
63 - this.endTime = endTime;  
64 - }  
65 -  
66 - public void setMediaType(int mediaType) {  
67 - this.mediaType = mediaType;  
68 - }  
69 -  
70 - public void setStreamType(int streamType) {  
71 - this.streamType = streamType;  
72 - }  
73 -  
74 - public void setStorageType(int storageType) {  
75 - this.storageType = storageType;  
76 - }  
77 -  
78 - public int getWarnType() {  
79 - return warnType;  
80 - }  
81 -  
82 - @Override  
83 - public String toString() {  
84 - return "J9205{" +  
85 - "channelId=" + channelId +  
86 - ", startTime='" + startTime + '\'' +  
87 - ", endTime='" + endTime + '\'' +  
88 - ", warnType=" + warnType +  
89 - ", mediaType=" + mediaType +  
90 - ", streamType=" + streamType +  
91 - ", storageType=" + storageType +  
92 - '}';  
93 - }  
94 -}  
src/main/java/com/genersoft/iot/vmp/jt1078/proc/response/Rs.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.jt1078.proc.response;  
2 -  
3 -  
4 -import com.genersoft.iot.vmp.jt1078.proc.Header;  
5 -import io.netty.buffer.ByteBuf;  
6 -  
7 -  
8 -/**  
9 - * @author QingtaiJiang  
10 - * @date 2021/8/30 18:54  
11 - * @email qingtaij@163.com  
12 - */  
13 -  
14 -public abstract class Rs {  
15 - private Header header;  
16 -  
17 - public abstract ByteBuf encode();  
18 -  
19 -  
20 - public Header getHeader() {  
21 - return header;  
22 - }  
23 -  
24 - public void setHeader(Header header) {  
25 - this.header = header;  
26 - }  
27 -}  
src/main/java/com/genersoft/iot/vmp/jt1078/publisher/Channel.java deleted 100644 → 0
1 -//  
2 -// Source code recreated from a .class file by IntelliJ IDEA  
3 -// (powered by FernFlower decompiler)  
4 -//  
5 -  
6 -package com.genersoft.iot.vmp.jt1078.publisher;  
7 -  
8 -import com.genersoft.iot.vmp.jt1078.codec.AudioCodec;  
9 -import com.genersoft.iot.vmp.jt1078.entity.MediaEncoding;  
10 -import com.genersoft.iot.vmp.jt1078.entity.Media.Type;  
11 -import com.genersoft.iot.vmp.jt1078.flv.FlvEncoder;  
12 -import com.genersoft.iot.vmp.jt1078.server.Jtt1078Handler;  
13 -import com.genersoft.iot.vmp.jt1078.subscriber.RTMPPublisher;  
14 -import com.genersoft.iot.vmp.jt1078.subscriber.Subscriber;  
15 -import com.genersoft.iot.vmp.jt1078.subscriber.VideoSubscriber;  
16 -import com.genersoft.iot.vmp.jt1078.util.ByteHolder;  
17 -import com.genersoft.iot.vmp.jt1078.util.Configs;  
18 -import io.netty.channel.ChannelHandlerContext;  
19 -  
20 -import java.io.IOException;  
21 -import java.net.URISyntaxException;  
22 -import java.util.Iterator;  
23 -import java.util.concurrent.ConcurrentLinkedQueue;  
24 -  
25 -import org.apache.commons.lang3.StringUtils;  
26 -import org.slf4j.Logger;  
27 -import org.slf4j.LoggerFactory;  
28 -  
29 -public class Channel {  
30 - static Logger logger = LoggerFactory.getLogger(Channel.class);  
31 - ConcurrentLinkedQueue<Subscriber> subscribers;  
32 - RTMPPublisher rtmpPublisher;  
33 - String tag;  
34 - boolean publishing;  
35 - ByteHolder buffer;  
36 - AudioCodec audioCodec;  
37 - FlvEncoder flvEncoder;  
38 - private long firstTimestamp = -1L;  
39 - private Integer httpPort;  
40 - private boolean flag = true;  
41 -  
42 - public Channel(String tag, Integer httpPort) {  
43 -  
44 - this.tag = tag;  
45 - this.subscribers = new ConcurrentLinkedQueue();  
46 - this.flvEncoder = new FlvEncoder(true, true);  
47 - this.buffer = new ByteHolder(204800);  
48 - this.httpPort = httpPort;  
49 - if (!StringUtils.isEmpty(Configs.get("rtmp.url"))) {  
50 - this.rtmpPublisher = new RTMPPublisher(tag, httpPort);  
51 - this.rtmpPublisher.start();  
52 - }  
53 -  
54 - }  
55 -  
56 - public boolean isPublishing() {  
57 - return this.publishing;  
58 - }  
59 -  
60 - public Subscriber subscribe(ChannelHandlerContext ctx) {  
61 - logger.info("channel: {} -> {}, subscriber: {}", new Object[]{Long.toHexString((long)this.hashCode() & 4294967295L), this.tag, ctx.channel().remoteAddress().toString()});  
62 - Subscriber subscriber = new VideoSubscriber(this.tag, ctx);  
63 - this.subscribers.add(subscriber);  
64 -  
65 -  
66 - return subscriber;  
67 - }  
68 -  
69 - public void writeAudio(long timestamp, int pt, byte[] data) {  
70 - if (this.audioCodec == null) {  
71 - this.audioCodec = AudioCodec.getCodec(pt);  
72 - logger.info("audio codec: {}", MediaEncoding.getEncoding(Type.Audio, pt));  
73 - }  
74 -  
75 - this.broadcastAudio(timestamp, this.audioCodec.toPCM(data));  
76 - }  
77 -  
78 - public void writeVideo(long sequence, long timeoffset, int payloadType, byte[] h264) {  
79 - if (this.firstTimestamp == -1L) {  
80 - this.firstTimestamp = timeoffset;  
81 - }  
82 -  
83 - this.publishing = true;  
84 - this.buffer.write(h264);  
85 -  
86 - while(true) {  
87 - byte[] nalu = this.readNalu();  
88 - if (nalu == null) {  
89 - return;  
90 - }  
91 -  
92 - if (nalu.length >= 4) {  
93 - byte[] flvTag = this.flvEncoder.write(nalu, (int)(timeoffset - this.firstTimestamp));  
94 - if (flvTag != null) {  
95 - this.broadcastVideo(timeoffset, flvTag);  
96 - }  
97 - }  
98 - }  
99 - }  
100 -  
101 - public void broadcastVideo(long timeoffset, byte[] flvTag) {  
102 - Iterator var4 = this.subscribers.iterator();  
103 -  
104 - while(var4.hasNext()) {  
105 - Subscriber subscriber = (Subscriber)var4.next();  
106 - subscriber.onVideoData(timeoffset, flvTag, this.flvEncoder);  
107 - }  
108 -  
109 - }  
110 -  
111 - public void broadcastAudio(long timeoffset, byte[] flvTag) {  
112 - Iterator var4 = this.subscribers.iterator();  
113 -  
114 - while(var4.hasNext()) {  
115 - Subscriber subscriber = (Subscriber)var4.next();  
116 - subscriber.onAudioData(timeoffset, flvTag, this.flvEncoder);  
117 - }  
118 -  
119 - }  
120 -  
121 - public void unsubscribe(long watcherId) {  
122 - Iterator<Subscriber> itr = this.subscribers.iterator();  
123 -  
124 - Subscriber subscriber;  
125 - do {  
126 - if (!itr.hasNext()) {  
127 - return;  
128 - }  
129 -  
130 - subscriber = (Subscriber)itr.next();  
131 - } while(subscriber.getId() != watcherId);  
132 -  
133 - itr.remove();  
134 - subscriber.close();  
135 - }  
136 -  
137 - public long getWatcherId(String tag) {  
138 - Iterator<Subscriber> itr = this.subscribers.iterator();  
139 -  
140 - Subscriber subscriber;  
141 - do {  
142 - if (!itr.hasNext()) {  
143 - return -1100L;  
144 - }  
145 -  
146 - subscriber = (Subscriber)itr.next();  
147 - } while(!StringUtils.equals(tag, subscriber.getTag()));  
148 -  
149 - return subscriber.getId();  
150 - }  
151 -  
152 - public void close() {  
153 - Iterator<Subscriber> itr = this.subscribers.iterator();  
154 -  
155 - while(itr.hasNext()) {  
156 - Subscriber subscriber = (Subscriber)itr.next();  
157 - subscriber.close();  
158 - itr.remove();  
159 - }  
160 -  
161 - if (this.rtmpPublisher != null) {  
162 - this.rtmpPublisher.close();  
163 - }  
164 -  
165 - }  
166 -  
167 - private byte[] readNalu() {  
168 - for(int i = 0; i < this.buffer.size(); ++i) {  
169 - int a = this.buffer.get(i + 0) & 255;  
170 - int b = this.buffer.get(i + 1) & 255;  
171 - int c = this.buffer.get(i + 2) & 255;  
172 - int d = this.buffer.get(i + 3) & 255;  
173 - if (a == 0 && b == 0 && c == 0 && d == 1 && i != 0) {  
174 - byte[] nalu = new byte[i];  
175 - this.buffer.sliceInto(nalu, i);  
176 - return nalu;  
177 - }  
178 - }  
179 -  
180 - return null;  
181 - }  
182 -}  
src/main/java/com/genersoft/iot/vmp/jt1078/publisher/PublishManager.java deleted 100644 → 0
1 -//  
2 -// Source code recreated from a .class file by IntelliJ IDEA  
3 -// (powered by FernFlower decompiler)  
4 -//  
5 -  
6 -package com.genersoft.iot.vmp.jt1078.publisher;  
7 -  
8 -import com.genersoft.iot.vmp.jt1078.entity.Media;  
9 -import com.genersoft.iot.vmp.jt1078.entity.Media.Type;  
10 -import com.genersoft.iot.vmp.jt1078.server.Jtt1078Handler;  
11 -import com.genersoft.iot.vmp.jt1078.subscriber.Subscriber;  
12 -import io.netty.channel.ChannelHandlerContext;  
13 -  
14 -import java.io.IOException;  
15 -import java.net.URISyntaxException;  
16 -import java.util.Objects;  
17 -import java.util.concurrent.ConcurrentHashMap;  
18 -import org.slf4j.Logger;  
19 -import org.slf4j.LoggerFactory;  
20 -  
21 -public final class PublishManager {  
22 - static Logger logger = LoggerFactory.getLogger(PublishManager.class);  
23 - ConcurrentHashMap<String, Channel> channels = new ConcurrentHashMap();  
24 - static final PublishManager instance = new PublishManager();  
25 - private Integer httpPort;  
26 -  
27 - private PublishManager() {  
28 - }  
29 -  
30 - public Subscriber subscribe(String tag, Media.Type type, ChannelHandlerContext ctx, Integer httpPort) {  
31 - Channel chl = (Channel)this.channels.get(tag);  
32 - if (chl == null) {  
33 - chl = new Channel(tag, httpPort);  
34 - this.channels.put(tag, chl);  
35 - }  
36 - this.httpPort = httpPort;  
37 -  
38 - Subscriber subscriber = null;  
39 - if (type.equals(Type.Video)) {  
40 - subscriber = chl.subscribe(ctx);  
41 - subscriber.setName("subscriber-" + tag + "-" + subscriber.getId());  
42 - subscriber.start();  
43 - return subscriber;  
44 - } else {  
45 - throw new RuntimeException("unknown media type: " + type);  
46 - }  
47 - }  
48 -  
49 - public void publishAudio(String tag, int sequence, long timestamp, int payloadType, byte[] data) {  
50 - Channel chl = (Channel)this.channels.get(tag);  
51 - if (chl != null) {  
52 - chl.writeAudio(timestamp, payloadType, data);  
53 - }  
54 -  
55 - }  
56 -  
57 - public void publishVideo(String tag, int sequence, long timestamp, int payloadType, byte[] data) {  
58 - int length = data.length;  
59 - StringBuilder builder = new StringBuilder();  
60 -  
61 - for(int i = 0; i < length; ++i) {  
62 - builder.append(this.valu(data, i));  
63 - }  
64 -  
65 - Channel chl = (Channel)this.channels.get(tag);  
66 - if (chl != null) {  
67 - chl.writeVideo((long)sequence, timestamp, payloadType, data);  
68 - }  
69 -  
70 - }  
71 -  
72 - public String valu(byte[] data, int index) {  
73 - byte val = data[index++];  
74 - int ch1 = val >> 4 & 15;  
75 - int ch2 = val & 15;  
76 - return ch1 + "" + ch2;  
77 - }  
78 -  
79 - public Channel open(String tag, Integer httpPort) {  
80 - Channel chl = (Channel)this.channels.get(tag);  
81 - if (chl == null) {  
82 - chl = new Channel(tag, httpPort);  
83 - this.channels.put(tag, chl);  
84 - }  
85 -  
86 - logger.info("Thread id:[{}]", Thread.currentThread().getId());  
87 - if (chl.isPublishing()) {  
88 - throw new RuntimeException("channel already publishing");  
89 - } else {  
90 - return chl;  
91 - }  
92 - }  
93 -  
94 - public void close(String tag) {  
95 - Channel chl = (Channel)this.channels.remove(tag);  
96 - if (chl != null) {  
97 - chl.close();  
98 - }  
99 -  
100 - }  
101 -  
102 - public void unsubscribe(String tag, long watcherId) {  
103 - Channel chl = (Channel)this.channels.get(tag);  
104 - if (chl != null) {  
105 - chl.unsubscribe(watcherId);  
106 - }  
107 -  
108 -  
109 - logger.info("unsubscribe: {} - {}", tag, watcherId);  
110 - }  
111 -  
112 - public void unsubscribeAndClose(String tag) {  
113 - try {  
114 - Channel chl = (Channel)this.channels.get(tag);  
115 - if (chl != null) {  
116 - long watcherId = chl.getWatcherId(tag);  
117 - this.unsubscribe(tag, watcherId);  
118 - }  
119 - } catch (Exception var6) {  
120 - logger.error("unsubscribeAndClose unsubscribe error;[{}]", tag);  
121 - }  
122 -  
123 - try {  
124 - this.close(tag);  
125 - } catch (Exception var5) {  
126 - logger.error("unsubscribeAndClose close error;[{}]", tag);  
127 - }  
128 -  
129 - }  
130 -  
131 - public static void init() {  
132 - }  
133 -  
134 - public static PublishManager getInstance() {  
135 - return instance;  
136 - }  
137 -  
138 - private void createChannel(String tag, String tagMapping) {  
139 - Channel chl = (Channel)this.channels.get(tag);  
140 - }  
141 -}  
src/main/java/com/genersoft/iot/vmp/jt1078/rtp/H264Packeter.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.jt1078.rtp;  
2 -  
3 -import java.nio.ByteBuffer;  
4 -import java.util.ArrayList;  
5 -import java.util.Arrays;  
6 -import java.util.List;  
7 -  
8 -public class H264Packeter {  
9 -  
10 - private final int MAX_PACKAGE_SIZE = 1400;  
11 -  
12 - private byte[] buffer;  
13 -  
14 - private long firstTimestamp = 0;  
15 -  
16 - private int seq = 0;  
17 -  
18 - private int lastPosition = 0;  
19 -  
20 - public List<byte[]> packet(byte[] h264, long timestamp) {  
21 - List<byte[]> streams = new ArrayList<>();  
22 - if (buffer == null) {  
23 - buffer = Arrays.copyOf(h264, h264.length);  
24 - } else {  
25 - byte[] nbuffer = new byte[buffer.length - lastPosition + h264.length];  
26 - System.arraycopy(buffer, lastPosition, nbuffer, 0, buffer.length - lastPosition);  
27 - //System.out.println(toHex(nbuffer));  
28 - System.arraycopy(h264, 0, nbuffer, buffer.length - lastPosition, h264.length);  
29 - //System.out.println(toHex(nbuffer));  
30 - buffer = nbuffer;  
31 - }  
32 - lastPosition = 0;  
33 - //System.out.println(buffer.length);  
34 - if (firstTimestamp == 0) {  
35 - firstTimestamp = timestamp;  
36 - }  
37 - while (lastPosition < buffer.length - 4) {  
38 - byte[] nalu = readNalu();  
39 - if (nalu == null) {  
40 - break;  
41 - }  
42 - ByteBuffer buffer = null;  
43 - byte[] header = new byte[14];  
44 - header[0] = (byte) (header[0] | 0x80);  
45 - header[1] = (byte) (header[1] | 96);  
46 - header[11] = 15;  
47 - if (nalu.length <= MAX_PACKAGE_SIZE) {  
48 - buffer = ByteBuffer.allocate(16 + nalu.length);  
49 - header[1] = (byte) (header[1] | 0x80);  
50 - buffer.put((byte) 0x24);  
51 - buffer.put((byte) 0);  
52 - buffer.putShort((short) (12 + nalu.length));  
53 - buffer.put(header, 0, 2);  
54 - buffer.putShort((short) ++seq);  
55 - buffer.putInt((int) (timestamp - firstTimestamp));  
56 - buffer.put(header, 8, 4);  
57 - buffer.put(nalu);  
58 - //System.out.println("完整: " + toHex(buffer.array()));  
59 - streams.add(buffer.array());  
60 - } else {  
61 - int tail = nalu.length % MAX_PACKAGE_SIZE, group = nalu.length / MAX_PACKAGE_SIZE + (tail > 0 ? 1 : 0);  
62 - for (int i = 0; i < group; i++) {  
63 - buffer = ByteBuffer.allocate(18 + MAX_PACKAGE_SIZE);  
64 - if (i == 0) {  
65 - buffer = ByteBuffer.allocate(17 + MAX_PACKAGE_SIZE);  
66 - header[1] = (byte) (header[1] & 0x7F);  
67 - header[12] = (byte) (header[12] | ((byte) (nalu[0] & 0x80)) << 7);  
68 - header[12] = (byte) (header[12] | ((byte) ((nalu[0] & 0x60) >> 5)) << 5);  
69 - header[12] = (byte) (header[12] | ((byte) 28));  
70 - header[13] = (byte) (header[13] & 0xBF);  
71 - header[13] = (byte) (header[13] & 0xDF);  
72 - header[13] = (byte) (header[13] | 0x80);  
73 - header[13] = (byte) (header[13] | ((byte) (nalu[0] & 0x1F)));  
74 - buffer.put((byte) 0x24);  
75 - buffer.put((byte) 0);  
76 - buffer.putShort((short) (13 + MAX_PACKAGE_SIZE));  
77 - buffer.put(header, 0, 2);  
78 - buffer.putShort((short) ++seq);  
79 - buffer.putInt((int) (timestamp - firstTimestamp));  
80 - buffer.put(header, 8, 6);  
81 - buffer.put(nalu, i * MAX_PACKAGE_SIZE + 1, MAX_PACKAGE_SIZE - 1);  
82 - //System.out.println(String.format("Nalu header:%02X", nalu[0]));  
83 - //System.out.println("第一分片: " + toHex(buffer.array()));  
84 - } else if (i == group - 1) {  
85 - buffer = ByteBuffer.allocate(18 + tail);  
86 - header[1] = (byte) (header[1] | 0x80);  
87 - header[12] = (byte) (header[12] | ((byte) (nalu[0] & 0x80)) << 7);  
88 - header[12] = (byte) (header[12] | ((byte) ((nalu[0] & 0x60) >> 5)) << 5);  
89 - header[12] = (byte) (header[12] | ((byte) 28));  
90 - header[13] = (byte) (header[13] & 0xDF);  
91 - header[13] = (byte) (header[13] & 0x7F);  
92 - header[13] = (byte) (header[13] | 0x40);  
93 - header[13] = (byte) (header[13] | ((byte) (nalu[0] & 0x1F)));  
94 - buffer.put((byte) 0x24);  
95 - buffer.put((byte) 0);  
96 - buffer.putShort((short) (14 + tail));  
97 - buffer.put(header, 0, 2);  
98 - buffer.putShort((short) ++seq);  
99 - buffer.putInt((int) (timestamp - firstTimestamp));  
100 - buffer.put(header, 8, 6);  
101 - buffer.put(nalu, i * MAX_PACKAGE_SIZE, tail);  
102 - //System.out.println("最后分片: " + toHex(buffer.array()));  
103 - } else {  
104 - header[1] = (byte) (header[1] & 0x7F);  
105 - header[12] = (byte) (header[12] | ((byte) (nalu[0] & 0x80)) << 7);  
106 - header[12] = (byte) (header[12] | ((byte) ((nalu[0] & 0x60) >> 5)) << 5);  
107 - header[12] = (byte) (header[12] | ((byte) 28));  
108 - header[13] = (byte) (header[13] & 0xDF);  
109 - header[13] = (byte) (header[13] & 0x7F);  
110 - header[13] = (byte) (header[13] & 0xBF);  
111 - header[13] = (byte) (header[13] | ((byte) (nalu[0] & 0x1F)));  
112 - buffer.put((byte) 0x24);  
113 - buffer.put((byte) 0);  
114 - buffer.putShort((short) (14 + MAX_PACKAGE_SIZE));  
115 - buffer.put(header, 0, 2);  
116 - buffer.putShort((short) ++seq);  
117 - buffer.putInt((int) (timestamp - firstTimestamp));  
118 - buffer.put(header, 8, 6);  
119 - buffer.put(nalu, i * MAX_PACKAGE_SIZE, MAX_PACKAGE_SIZE);  
120 - //System.out.println("中间分片: " + toHex(buffer.array()));  
121 - }  
122 - streams.add(buffer.array());  
123 - }  
124 - }  
125 - }  
126 -  
127 - return streams;  
128 - }  
129 -  
130 - public byte[] readNalu() {  
131 - for (int i = (lastPosition == 0 ? 0 : lastPosition + 1); i < buffer.length - 3; i++) {  
132 - if (buffer[i] == 0 && buffer[i + 1] == 0 && buffer[i + 2] == 0 && buffer[i + 3] == 1) {  
133 - if (i != 0) {  
134 - byte[] nalu = new byte[i - lastPosition - 4];  
135 - System.arraycopy(buffer, lastPosition + 4, nalu, 0, i - lastPosition - 4);  
136 - lastPosition = i;  
137 - //System.out.println(toHex(nalu));  
138 -  
139 - return nalu;  
140 - }  
141 - }  
142 - }  
143 -  
144 - return null;  
145 - }  
146 -  
147 - public String toHex(byte[] bytes) {  
148 - StringBuilder sb = new StringBuilder();  
149 - for (byte b : bytes) {  
150 - sb.append(String.format("%02X ", b));  
151 - }  
152 -  
153 - return sb.toString();  
154 - }  
155 -  
156 - public static void main(String[] args) {  
157 - byte[] bytes = new byte[]{(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x01,(byte)0x67,(byte)0x4D,(byte)0x00,(byte)0x1F,(byte)0x96,(byte)0x35,(byte)0x41,(byte)0xE0,(byte)0x24,(byte)0xD3,(byte)0x70,(byte)0x50,(byte)0x10,(byte)0x50,(byte)0x20,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x01,(byte)0x68,(byte)0xEE,(byte)0x31,(byte)0xB2,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x01,(byte)0x06,(byte)0xE5,(byte)0x01,(byte)0x4A,(byte)0x80,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x01,(byte)0x65,(byte)0xB8,(byte)0x00,(byte)0x00,(byte)0x0C,(byte)0x16,(byte)0x90,(byte)0x00,(byte)0x00,(byte)0xBF,(byte)0xFE,(byte)0xD4,(byte)0xA7,(byte)0x99,(byte)0x63,(byte)0xE6,(byte)0xF9,(byte)0x5A,(byte)0x75,(byte)0xCE,(byte)0xDB,(byte)0x0C,(byte)0xD3,(byte)0xA6,(byte)0x31,(byte)0x05,(byte)0x66,(byte)0x6C,(byte)0x18,(byte)0x87,(byte)0xD0,(byte)0xF9,(byte)0xD0,(byte)0xCC,(byte)0xA3,(byte)0x57,(byte)0x07,(byte)0xDF,(byte)0x7C,(byte)0x6F,(byte)0x42,(byte)0xE9,(byte)0x8B,(byte)0x1B,(byte)0xA2,(byte)0x70,(byte)0x8C,(byte)0x80,(byte)0x00,(byte)0x00,(byte)0x1A,(byte)0xD6,(byte)0xEB,(byte)0x80,(byte)0xDE,(byte)0xE6,(byte)0xE2,(byte)0xF5,(byte)0xFF,(byte)0x33,(byte)0x98,(byte)0x97,(byte)0xCD,(byte)0xEB,(byte)0xEB,(byte)0xE5,(byte)0x60,(byte)0x00,(byte)0x00,(byte)0x0F,(byte)0xFB,(byte)0x49,(byte)0x08,(byte)0x9C,(byte)0x75,(byte)0xB4,(byte)0xDB,(byte)0xCE,(byte)0x58,(byte)0x08,(byte)0xB4,(byte)0x68,(byte)0x22,(byte)0x16,(byte)0x51,(byte)0x47,(byte)0xF3,(byte)0xD3,(byte)0x56,(byte)0xC2,(byte)0x4F,(byte)0x12,(byte)0xFD,(byte)0x2B,(byte)0xC9,(byte)0x45,(byte)0x80,(byte)0xDB,(byte)0xA4,(byte)0x62,(byte)0xEB,(byte)0xC3,(byte)0x6D,(byte)0xFE,(byte)0x36,(byte)0x20,(byte)0xAE,(byte)0xD9,(byte)0xD2,(byte)0x4C,(byte)0x9E,(byte)0x06,(byte)0xA0,(byte)0x8B,(byte)0x42,(byte)0x35,(byte)0xEC,(byte)0x64,(byte)0x03,(byte)0x22,(byte)0x29,(byte)0x26,(byte)0x19,(byte)0x70,(byte)0xCA,(byte)0x18,(byte)0xC0,(byte)0x7E,(byte)0x08,(byte)0x4F,(byte)0xEB,(byte)0xFD,(byte)0x5D,(byte)0x90,(byte)0x31,(byte)0x62,(byte)0x02,(byte)0x2E,(byte)0xBE,(byte)0x53,(byte)0xCF,(byte)0xC0,(byte)0xA8,(byte)0xAC,(byte)0xF3,(byte)0x92,(byte)0xC8,(byte)0x76,(byte)0x77,(byte)0x84,(byte)0x2F,(byte)0x76,(byte)0x45,(byte)0xF3,(byte)0xBF,(byte)0x07,(byte)0x1F,(byte)0x6D,(byte)0xC6,(byte)0x11,(byte)0xB9,(byte)0x83,(byte)0xF6,(byte)0xDF,(byte)0xA1,(byte)0x6D,(byte)0x56,(byte)0x6D,(byte)0xE0,(byte)0xFA,(byte)0xC1,(byte)0x7E,(byte)0xC5,(byte)0xC5,(byte)0x3C,(byte)0x69,(byte)0x57,(byte)0x61,(byte)0xCA,(byte)0x17,(byte)0x40,(byte)0x30,(byte)0xAE,(byte)0x4E,(byte)0x4C,(byte)0x61,(byte)0xC3,(byte)0xAF,(byte)0x6F,(byte)0xB4,(byte)0x48,(byte)0x33,(byte)0x4F,(byte)0x59,(byte)0x6D,(byte)0x88,(byte)0xA0,(byte)0x3B,(byte)0x9C,(byte)0x39,(byte)0x67,(byte)0xAD,(byte)0x0C,(byte)0xC0,(byte)0x64,(byte)0x8A,(byte)0xDB,(byte)0x95,(byte)0xB3,(byte)0xEF,(byte)0x6A,(byte)0xC0,(byte)0x9B,(byte)0xAF,(byte)0x44,(byte)0xBF,(byte)0x69,(byte)0x77,(byte)0x7D,(byte)0x2B,(byte)0xDB,(byte)0x47,(byte)0x78,(byte)0xD0,(byte)0x9C,(byte)0x79,(byte)0xA1,(byte)0xFE,(byte)0xC4,(byte)0xC4,(byte)0xAF,(byte)0x6A,(byte)0x2C,(byte)0x2D,(byte)0xF4,(byte)0xB6,(byte)0x27,(byte)0xC6,(byte)0x3C,(byte)0x71,(byte)0xC1,(byte)0x5E,(byte)0xB0,(byte)0x22,(byte)0x93,(byte)0x88,(byte)0x9C,(byte)0x98,(byte)0x3A,(byte)0x8D,(byte)0x7F,(byte)0x2E,(byte)0x48,(byte)0x53,(byte)0x2D,(byte)0xF5,(byte)0x7A,(byte)0xD0,(byte)0xC2,(byte)0x68,(byte)0xAF,(byte)0xB7,(byte)0x8C,(byte)0xF4,(byte)0xD4,(byte)0x99,(byte)0x96,(byte)0x24,(byte)0x47,(byte)0x2B,(byte)0x28,(byte)0x26,(byte)0xE4,(byte)0xBD,(byte)0xFA,(byte)0x65,(byte)0x7C,(byte)0xB3,(byte)0xA8,(byte)0x3E,(byte)0x43,(byte)0xF4,(byte)0x6D,(byte)0x50,(byte)0x7F,(byte)0xE3,(byte)0xF5,(byte)0x73,(byte)0xE6,(byte)0xF2,(byte)0x23,(byte)0x3A,(byte)0x22,(byte)0x74,(byte)0x7B,(byte)0x1E,(byte)0xDC,(byte)0xFB,(byte)0xF4,(byte)0xA8,(byte)0x97,(byte)0xB9,(byte)0x3A,(byte)0x73,(byte)0x8B,(byte)0x78,(byte)0x64,(byte)0x03,(byte)0x55,(byte)0x6E,(byte)0x52,(byte)0x7D,(byte)0x4C,(byte)0x28,(byte)0x00,(byte)0x43,(byte)0x72,(byte)0x84,(byte)0xF1,(byte)0x81,(byte)0x55,(byte)0x7B,(byte)0x8D,(byte)0x0F,(byte)0x7F,(byte)0xB4,(byte)0xEB,(byte)0xAB,(byte)0x69,(byte)0x65,(byte)0x7B,(byte)0x92,(byte)0xAC,(byte)0xB6,(byte)0xB4,(byte)0x33,(byte)0x5D,(byte)0x33,(byte)0x5D,(byte)0xC2,(byte)0xF8,(byte)0x25,(byte)0x7E,(byte)0x1D,(byte)0x1D,(byte)0xDB,(byte)0x1C,(byte)0xF8,(byte)0xBE,(byte)0x4B,(byte)0x25,(byte)0xA9,(byte)0xB5,(byte)0x8A,(byte)0x8D,(byte)0x67,(byte)0x61,(byte)0xFF,(byte)0xE3,(byte)0x18,(byte)0x1C,(byte)0x8F,(byte)0x7F,(byte)0xBA,(byte)0x50,(byte)0x47,(byte)0x10,(byte)0x5D,(byte)0xD5,(byte)0x97,(byte)0x62,(byte)0x06,(byte)0x09,(byte)0x52,(byte)0xC3,(byte)0x81,(byte)0x1A,(byte)0x58,(byte)0x87,(byte)0xFC,(byte)0x30,(byte)0x61,(byte)0x89,(byte)0xF5,(byte)0x2C,(byte)0x58,(byte)0x04,(byte)0x32,(byte)0x8B,(byte)0x3E,(byte)0x79,(byte)0xA3,(byte)0x10,(byte)0xFD,(byte)0x11,(byte)0x59,(byte)0xCA,(byte)0x08,(byte)0x48,(byte)0x24,(byte)0xDF,(byte)0x5F,(byte)0x02,(byte)0x12,(byte)0x2F,(byte)0x4C,(byte)0xDC,(byte)0xE9,(byte)0xFE,(byte)0xF0,(byte)0x21,(byte)0x5B,(byte)0xD3,(byte)0x0C,(byte)0xA7,(byte)0xF6,(byte)0xEF,(byte)0xFD,(byte)0xA4,(byte)0xB0,(byte)0xEF,(byte)0x47,(byte)0xC6,(byte)0x8F,(byte)0xB7,(byte)0x90,(byte)0xE3,(byte)0x03,(byte)0xBE,(byte)0x85,(byte)0x51,(byte)0x56,(byte)0x65,(byte)0xD3,(byte)0x6B,(byte)0xC4,(byte)0x8F,(byte)0x00,(byte)0x09,(byte)0xCC,(byte)0x0C,(byte)0x7C,(byte)0x69,(byte)0x42,(byte)0x68,(byte)0x05,(byte)0x97,(byte)0x5D,(byte)0xD8,(byte)0x66,(byte)0x8E,(byte)0x1D,(byte)0x2E,(byte)0x65,(byte)0x0B,(byte)0xCC,(byte)0x24,(byte)0x15,(byte)0xE4,(byte)0x10,(byte)0x23,(byte)0x4D,(byte)0xAE,(byte)0x01,(byte)0xCB,(byte)0xEB,(byte)0x16,(byte)0xAE,(byte)0x5A,(byte)0xA9,(byte)0xA0,(byte)0xFD,(byte)0xE8,(byte)0x62,(byte)0x57,(byte)0x8E,(byte)0x8F,(byte)0x57,(byte)0xA7,(byte)0xCC,(byte)0x6B,(byte)0xEB,(byte)0xDF,(byte)0xC1,(byte)0xBD,(byte)0xA6,(byte)0x40,(byte)0x40,(byte)0x07,(byte)0xAC,(byte)0x0A,(byte)0x40,(byte)0xD1,(byte)0xA7,(byte)0x9F,(byte)0x8D,(byte)0xE8,(byte)0x36,(byte)0xD8,(byte)0x53,(byte)0x54,(byte)0x66,(byte)0x14,(byte)0x5B,(byte)0x38,(byte)0x23,(byte)0xC5,(byte)0x72,(byte)0xA1,(byte)0x9D,(byte)0x3B,(byte)0xDD,(byte)0xD3,(byte)0xD6,(byte)0x46,(byte)0xE9,(byte)0x7D,(byte)0x0D,(byte)0xA7,(byte)0x22,(byte)0x00,(byte)0x87,(byte)0x7C,(byte)0x4E,(byte)0x4E,(byte)0x56,(byte)0xE1,(byte)0x03,(byte)0x99,(byte)0x4A,(byte)0xB5,(byte)0x09,(byte)0xD7,(byte)0xC1,(byte)0x0F,(byte)0xDD,(byte)0xB5,(byte)0x91,(byte)0xF8,(byte)0x3D,(byte)0x19,(byte)0x63,(byte)0xAD,(byte)0xC1,(byte)0x21,(byte)0x46,(byte)0x2F,(byte)0x2A,(byte)0xE8,(byte)0x11,(byte)0xFA,(byte)0x56,(byte)0xCD,(byte)0x16,(byte)0xB2,(byte)0x1C,(byte)0xA0,(byte)0xB1,(byte)0xBC,(byte)0xB4,(byte)0x99,(byte)0xBC,(byte)0xFB,(byte)0x60,(byte)0x48,(byte)0x45,(byte)0xFB,(byte)0x52,(byte)0x5A,(byte)0xE5,(byte)0x1A,(byte)0x43,(byte)0x6B,(byte)0x26,(byte)0xC3,(byte)0xD8,(byte)0xE6,(byte)0x1F,(byte)0x0F,(byte)0x1D,(byte)0x77,(byte)0x92,(byte)0xB7,(byte)0x05,(byte)0x15,(byte)0x8A,(byte)0xEE,(byte)0xB8,(byte)0x62,(byte)0x82,(byte)0x9D,(byte)0x98,(byte)0x94,(byte)0xA7,(byte)0xBA,(byte)0x7B,(byte)0x19,(byte)0x8B,(byte)0x8E,(byte)0x3F,(byte)0xB4,(byte)0x1B,(byte)0x9B,(byte)0x4D,(byte)0xD3,(byte)0xA2,(byte)0x28,(byte)0x05,(byte)0x99,(byte)0xC8,(byte)0xF7,(byte)0x2A,(byte)0x6F,(byte)0xB9,(byte)0xC9,(byte)0x96,(byte)0xF6,(byte)0x03,(byte)0xC6,(byte)0x10,(byte)0xBF,(byte)0xF2,(byte)0xD5,(byte)0xAE,(byte)0x7F,(byte)0x93,(byte)0xE4,(byte)0xB6,(byte)0x4D,(byte)0xE0,(byte)0xE5,(byte)0x06,(byte)0x4E,(byte)0x4C,(byte)0xC5,(byte)0xD5,(byte)0xD9,(byte)0xF8,(byte)0x1E,(byte)0x36,(byte)0x38,(byte)0x01,(byte)0x7C,(byte)0xBC,(byte)0x1C,(byte)0x71,(byte)0x46,(byte)0x2C,(byte)0xCE,(byte)0xBD,(byte)0x23,(byte)0x14,(byte)0x37,(byte)0xBB,(byte)0x70,(byte)0xC6,(byte)0x7A,(byte)0xF7,(byte)0x73,(byte)0xA8,(byte)0xA9,(byte)0xDC,(byte)0xC2,(byte)0xC0,(byte)0x7A,(byte)0xDA,(byte)0x74,(byte)0xFF,(byte)0x25,(byte)0x73,(byte)0x31,(byte)0xD8,(byte)0xF9,(byte)0x4D,(byte)0x66,(byte)0xD3,(byte)0x5E,(byte)0x98,(byte)0xC6,(byte)0xC4,(byte)0x55,(byte)0x0B,(byte)0xC4,(byte)0xB1,(byte)0xED,(byte)0x0F,(byte)0x74,(byte)0x5D,(byte)0x1B,(byte)0x7A,(byte)0x05,(byte)0xDB,(byte)0x7C,(byte)0x0D,(byte)0xDF,(byte)0xE2,(byte)0x6B,(byte)0xAF,(byte)0x22,(byte)0x3B,(byte)0x11,(byte)0x35,(byte)0xE3,(byte)0x51,(byte)0x13,(byte)0x07,(byte)0xD3,(byte)0x6E,(byte)0xAE,(byte)0x91,(byte)0xE2,(byte)0x98,(byte)0x02,(byte)0x6D,(byte)0xD9,(byte)0xD9,(byte)0xBD,(byte)0x7C,(byte)0x8E,(byte)0xBF,(byte)0xBE,(byte)0xB7,(byte)0x79,(byte)0xCA,(byte)0xC1,(byte)0x66,(byte)0x89,(byte)0x17,(byte)0x9B,(byte)0x77,(byte)0xBE,(byte)0xA7,(byte)0xED,(byte)0x3E,(byte)0xCC,(byte)0x86,(byte)0x44,(byte)0x42,(byte)0x38,(byte)0x50,(byte)0x8D,(byte)0xC3,(byte)0x58,(byte)0x07,(byte)0x42,(byte)0xBF,(byte)0x7C,(byte)0xC3,(byte)0x72,(byte)0x81,(byte)0x6E,(byte)0xFC,(byte)0xC8,(byte)0x63,(byte)0x8B,(byte)0x2E,(byte)0x63,(byte)0xA6,(byte)0x17,(byte)0x62,(byte)0x3C,(byte)0xED,(byte)0x29,(byte)0xFE,(byte)0xBC,(byte)0x4E,(byte)0x8B,(byte)0x94,(byte)0x4B,(byte)0x46,(byte)0xE6,(byte)0xC7,(byte)0x1A,(byte)0x32,(byte)0xE7,(byte)0xC8,(byte)0x44,(byte)0x47,(byte)0x1C,(byte)0xE8,(byte)0xC7,(byte)0x8C,(byte)0x1F,(byte)0x9E,(byte)0x16,(byte)0xED,(byte)0x12,(byte)0x8D,(byte)0x66,(byte)0x71,(byte)0xF4,(byte)0x1E,(byte)0x22,(byte)0xAB,(byte)0xD9,(byte)0xF5,(byte)0x22,(byte)0xC3,(byte)0x31,(byte)0x0B,(byte)0xD6,(byte)0x12,(byte)0x46,(byte)0x99,(byte)0x13,(byte)0xD2,(byte)0x02,(byte)0x34,(byte)0x7E,(byte)0x01,(byte)0x25,(byte)0xAC,(byte)0xB6,(byte)0xF1,(byte)0xF1,(byte)0x46,(byte)0xBE,(byte)0x90,(byte)0x79,(byte)0xBA,(byte)0x5B,(byte)0x36,(byte)0xF7,(byte)0x81,(byte)0x70,(byte)0x4A,(byte)0xDC,(byte)0xF1,(byte)0x24,(byte)0x9A,(byte)0x87,(byte)0x1E,(byte)0x59,(byte)0xE1,(byte)0x46,(byte)0xDC,(byte)0x0E,(byte)0x71,(byte)0xB4,(byte)0xE5,(byte)0x48,(byte)0x0E,(byte)0x11,(byte)0x87,(byte)0x99,(byte)0x2A,(byte)0x5C,(byte)0x61,(byte)0x75,(byte)0x3C,(byte)0x5B,(byte)0xF8,(byte)0xE6,(byte)0xE4,(byte)0x01,(byte)0xA2,(byte)0x01,(byte)0xE5,(byte)0x79,(byte)0x52,(byte)0x0B,(byte)0xC7,(byte)0xF7,(byte)0xED,(byte)0x0B,(byte)0x52,(byte)0x47,(byte)0x77,(byte)0xAD,(byte)0x45,(byte)0x72,(byte)0x21,(byte)0x0E,(byte)0xBE,(byte)0xA5,(byte)0x3D,(byte)0xEA,(byte)0xBF,(byte)0x44,(byte)0x7E,(byte)0x75,(byte)0x8C,(byte)0xF0,(byte)0x05,(byte)0xBB,(byte)0xDD,(byte)0xE3,(byte)0x53,(byte)0x4E,(byte)0x1B,(byte)0xB4,(byte)0x2F,(byte)0x65,(byte)0xCE,(byte)0x44,(byte)0x95,(byte)0x4F,(byte)0x44,(byte)0x1D,(byte)0x0D,(byte)0x54,(byte)0xF9,(byte)0xCD,(byte)0x30,(byte)0x00,(byte)0x81,(byte)0x2C,(byte)0x5C,(byte)0xFF,(byte)0xBE};  
158 - H264Packeter packeter = new H264Packeter();  
159 - packeter.packet(bytes, 0);  
160 - }  
161 -}  
src/main/java/com/genersoft/iot/vmp/jt1078/rtsp/RtspRequest.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.jt1078.rtsp;  
2 -  
3 -import io.netty.handler.codec.http.DefaultFullHttpRequest;  
4 -import io.netty.handler.codec.http.FullHttpRequest;  
5 -import io.netty.handler.codec.rtsp.RtspHeaderNames;  
6 -import io.netty.handler.codec.rtsp.RtspMethods;  
7 -import io.netty.handler.codec.rtsp.RtspVersions;  
8 -import io.netty.util.internal.StringUtil;  
9 -  
10 -/**  
11 - * Rtsp请求  
12 - */  
13 -public class RtspRequest {  
14 -  
15 - private final String CRLF = "\r\n";  
16 -  
17 - private final String VERSION = "RTSP/1.0";  
18 -  
19 - private int seq = 0;  
20 -  
21 - private String host;  
22 -  
23 - private int port;  
24 -  
25 - private String path;  
26 -  
27 - private String sessionID;  
28 -  
29 - public RtspRequest(String host, int port, String path) {  
30 - this.host = host;  
31 - this.port = port;  
32 - this.path = path;  
33 - }  
34 -  
35 - public String getHost() {  
36 - return host;  
37 - }  
38 -  
39 - public void setHost(String host) {  
40 - this.host = host;  
41 - }  
42 -  
43 - public int getPort() {  
44 - return port;  
45 - }  
46 -  
47 - public void setPort(int port) {  
48 - this.port = port;  
49 - }  
50 -  
51 - public String getPath() {  
52 - return path;  
53 - }  
54 -  
55 - public void setPath(String path) {  
56 - this.path = path;  
57 - }  
58 -  
59 - public String getSessionID() {  
60 - return sessionID;  
61 - }  
62 -  
63 - public void setSessionID(String sessionID) {  
64 - this.sessionID = sessionID;  
65 - }  
66 -  
67 - public FullHttpRequest option() {  
68 - FullHttpRequest request = new DefaultFullHttpRequest(RtspVersions.RTSP_1_0, RtspMethods.OPTIONS, String.format("rtsp://%s:%d%s", host, port, path));  
69 - request.headers().set(RtspHeaderNames.CSEQ, ++seq);  
70 -  
71 - return request;  
72 - }  
73 -  
74 - public FullHttpRequest announce() {  
75 - StringBuilder body = new StringBuilder();  
76 - FullHttpRequest request = new DefaultFullHttpRequest(RtspVersions.RTSP_1_0, RtspMethods.ANNOUNCE, String.format("rtsp://%s:%d%s", host, port, path));  
77 - request.headers().set(RtspHeaderNames.CSEQ, ++seq);  
78 - request.headers().set(RtspHeaderNames.CONTENT_TYPE, "application/sdp");  
79 -  
80 - body.append("v=0").append(CRLF)  
81 - .append("o=- 0 0 IN IP4 127.0.0.1").append(CRLF)  
82 - .append("s=No Name").append(CRLF)  
83 - .append("c=IN IP4 ").append(this.host).append(CRLF)  
84 - .append("t=0 0").append(CRLF)  
85 - .append("a=tool:libavformat 61.9.100").append(CRLF)  
86 - .append("m=video 0 RTP/AVP 96").append(CRLF)  
87 - .append("b=AS:3943").append(CRLF)  
88 - .append("a=rtpmap:96 H264/90000").append(CRLF)  
89 - .append("a=fmtp:96 packetization-mode=1; sprop-parameter-sets=Z00AKp2oHgCJ+WbgICAoAAADAAgAAAMBlCA=,aO48gA==; profile-level-id=4D002A").append(CRLF)  
90 - .append("a=control:streamid=0").append(CRLF);  
91 - request.content().writeBytes(body.toString().getBytes());  
92 - request.headers().set(RtspHeaderNames.CONTENT_LENGTH, body.toString().getBytes().length);  
93 -  
94 - return request;  
95 - }  
96 -  
97 - public FullHttpRequest setup() {  
98 - FullHttpRequest request = new DefaultFullHttpRequest(RtspVersions.RTSP_1_0, RtspMethods.SETUP, String.format("rtsp://%s:%d%s/streamid=0", host, port, path));  
99 - request.headers().set(RtspHeaderNames.CSEQ, ++seq);  
100 - request.headers().set(RtspHeaderNames.TRANSPORT, "RTP/AVP/TCP;unicast;interleaved=0-1;mode=record");  
101 - request.headers().set(RtspHeaderNames.SESSION, sessionID);  
102 -  
103 - return request;  
104 - }  
105 -  
106 - public FullHttpRequest record() {  
107 - FullHttpRequest request = new DefaultFullHttpRequest(RtspVersions.RTSP_1_0, RtspMethods.RECORD, String.format("rtsp://%s:%d%s/streamid=0", host, port, path));  
108 - request.headers().set(RtspHeaderNames.CSEQ, ++seq);  
109 - request.headers().set(RtspHeaderNames.RANGE, "npt=0.000-");  
110 - request.headers().set(RtspHeaderNames.SESSION, sessionID);  
111 -  
112 - return request;  
113 - }  
114 -  
115 - public String teardown() {  
116 - StringBuilder sb = new StringBuilder();  
117 -  
118 - return sb.toString();  
119 - }  
120 -  
121 - private String header(int length) {  
122 - StringBuilder sb = new StringBuilder();  
123 -  
124 - return sb.append("CSeq: ").append(++seq).append(CRLF)  
125 - .append("User-Agent: jt1078").append(CRLF)  
126 - .append("Content-Length: ").append(length).append(CRLF)  
127 - .append(StringUtil.isNullOrEmpty(sessionID) ? "" : "Session: ").append(StringUtil.isNullOrEmpty(sessionID) ? "" : sessionID).append(StringUtil.isNullOrEmpty(sessionID) ? "" : CRLF).append(CRLF).toString();  
128 - }  
129 -}  
src/main/java/com/genersoft/iot/vmp/jt1078/rtsp/RtspSessionManager.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.jt1078.rtsp;  
2 -  
3 -import io.netty.channel.Channel;  
4 -  
5 -import java.util.Map;  
6 -import java.util.concurrent.ConcurrentHashMap;  
7 -  
8 -/**  
9 - * Rtsp会话  
10 - */  
11 -public class RtspSessionManager {  
12 -  
13 - private static Map<String, Object> channel2register = new ConcurrentHashMap<>();  
14 -  
15 - private static Map<String, Channel> channel2push = new ConcurrentHashMap<>();  
16 -  
17 - public static void register(String channel) {  
18 - channel2register.put(channel, System.currentTimeMillis());  
19 - }  
20 -  
21 - public static void unregister(String channel) {  
22 - channel2register.remove(channel);  
23 - }  
24 -  
25 - public static boolean isRegistered(String channel) {  
26 - return channel2register.containsKey(channel);  
27 - }  
28 -  
29 - public static void setPush(String channel, Channel push) {  
30 - channel2push.put(channel, push);  
31 - }  
32 -  
33 - public static Channel getPush(String channel) {  
34 - return channel2push.get(channel);  
35 - }  
36 -}  
src/main/java/com/genersoft/iot/vmp/jt1078/server/Jtt1078Handler.java deleted 100644 → 0
1 -//  
2 -// Source code recreated from a .class file by IntelliJ IDEA  
3 -// (powered by FernFlower decompiler)  
4 -//  
5 -  
6 -package com.genersoft.iot.vmp.jt1078.server;  
7 -  
8 -import com.genersoft.iot.vmp.VManageBootstrap;  
9 -import com.genersoft.iot.vmp.conf.MediaConfig;  
10 -import com.genersoft.iot.vmp.jt1078.app.VideoServerApp;  
11 -import com.genersoft.iot.vmp.jt1078.publisher.Channel;  
12 -import com.genersoft.iot.vmp.jt1078.publisher.PublishManager;  
13 -import com.genersoft.iot.vmp.jt1078.util.Packet;  
14 -import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;  
15 -import com.genersoft.iot.vmp.service.IStreamProxyService;  
16 -import com.genersoft.iot.vmp.utils.SpringBeanFactory;  
17 -import com.genersoft.iot.vmp.vmanager.jt1078.platform.config.Jt1078ConfigBean;  
18 -import com.genersoft.iot.vmp.vmanager.streamProxy.StreamProxyController;  
19 -import io.lettuce.core.support.caching.RedisCache;  
20 -import io.netty.channel.ChannelHandlerContext;  
21 -import io.netty.channel.SimpleChannelInboundHandler;  
22 -import io.netty.util.Attribute;  
23 -import io.netty.util.AttributeKey;  
24 -  
25 -import java.io.IOException;  
26 -import java.net.URISyntaxException;  
27 -import java.util.Date;  
28 -import java.util.Iterator;  
29 -import java.util.Map;  
30 -import java.util.Objects;  
31 -import java.util.concurrent.TimeUnit;  
32 -  
33 -import org.apache.commons.lang3.StringUtils;  
34 -import org.slf4j.Logger;  
35 -import org.slf4j.LoggerFactory;  
36 -import org.springframework.data.redis.core.RedisTemplate;  
37 -import org.springframework.data.redis.core.StringRedisTemplate;  
38 -  
39 -public class Jtt1078Handler extends SimpleChannelInboundHandler<Packet> {  
40 - static Logger logger = LoggerFactory.getLogger(Jtt1078Handler.class);  
41 - private static final AttributeKey<Session> SESSION_KEY = AttributeKey.valueOf("session-key");  
42 - private ChannelHandlerContext context;  
43 - private String tagMapping;  
44 - private Integer httpPort;  
45 -  
46 - public Jtt1078Handler(String tagMapping, Integer httpPort) {  
47 - this.tagMapping = tagMapping;  
48 - this.httpPort = httpPort;  
49 - }  
50 -  
51 - protected void channelRead0(ChannelHandlerContext ctx, Packet packet) throws Exception {  
52 - this.context = ctx;  
53 - packet.seek(8);  
54 - String sim = packet.nextBCD() + packet.nextBCD() + packet.nextBCD() + packet.nextBCD() + packet.nextBCD() + packet.nextBCD();  
55 - int channel = packet.nextByte() & 255;  
56 - String tag = sim + "-" + channel;  
57 - if (StringUtils.isEmpty(this.tagMapping)) {  
58 - this.tagMapping = tag;  
59 - }  
60 -  
61 - if (!StringUtils.endsWith(this.tagMapping, ".flv")) {  
62 - endWithMapping(this.tagMapping);  
63 - }  
64 -  
65 -  
66 - Session session = this.getSession();  
67 - if (null == session) {  
68 - this.setSession(session = new Session());  
69 - Channel chl = PublishManager.getInstance().open(this.tagMapping, this.httpPort);  
70 - session.set("tag", this.tagMapping);  
71 - logger.info("start publishing: {} -> {}-{}", new Object[]{Long.toHexString((long) chl.hashCode() & 4294967295L), sim, channel});  
72 - }  
73 -  
74 - Integer sequence = (Integer) session.get("video-sequence");  
75 - if (sequence == null) {  
76 - sequence = 0;  
77 - }  
78 -  
79 - int lengthOffset = 28;  
80 - int dataType = packet.seek(15).nextByte() >> 4 & 15;  
81 - int pkType = packet.seek(15).nextByte() & 15;  
82 - if (dataType == 4) {  
83 - lengthOffset = 16;  
84 - } else if (dataType == 3) {  
85 - lengthOffset = 24;  
86 - }  
87 -  
88 - int pt = packet.seek(5).nextByte() & 127;  
89 - long timestamp;  
90 - if (dataType != 0 && dataType != 1 && dataType != 2) {  
91 - if (dataType == 3) {  
92 - timestamp = packet.seek(16).nextLong();  
93 - byte[] data = packet.seek(lengthOffset + 2).nextBytes();  
94 - PublishManager.getInstance().publishVideo(this.tagMapping, sequence, timestamp, pt, data);  
95 - }  
96 - } else {  
97 - if (pkType == 0 || pkType == 2) {  
98 - sequence = sequence + 1;  
99 - session.set("video-sequence", sequence);  
100 - }  
101 -  
102 - timestamp = packet.seek(16).nextLong();  
103 - PublishManager.getInstance().publishVideo(this.tagMapping, sequence, timestamp, pt, packet.seek(lengthOffset + 2).nextBytes());  
104 - }  
105 -  
106 - }  
107 -  
108 - private byte[] convert(String str) {  
109 - byte[] bytes = str.getBytes();  
110 - new StringBuilder();  
111 - int length = bytes.length;  
112 - byte[] bys = new byte[length];  
113 -  
114 - for (int i = 0; i < length; ++i) {  
115 - bys[i] = Byte.valueOf(Integer.toBinaryString(bytes[i]) + "");  
116 - }  
117 -  
118 - return bys;  
119 - }  
120 -  
121 - public final Session getSession() {  
122 - Attribute<Session> attr = this.context.channel().attr(SESSION_KEY);  
123 - return null == attr ? null : (Session) attr.get();  
124 - }  
125 -  
126 - public void channelInactive(ChannelHandlerContext ctx) throws Exception {  
127 - super.channelInactive(ctx);  
128 - this.release();  
129 - }  
130 -  
131 - public final void setSession(Session session) {  
132 - this.context.channel().attr(SESSION_KEY).set(session);  
133 - }  
134 -  
135 - public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {  
136 - cause.printStackTrace();  
137 - this.release();  
138 - ctx.close();  
139 - }  
140 -  
141 - private void release() {  
142 - String tag = (String) this.getSession().get("tag");  
143 - if (tag != null) {  
144 - logger.info("close netty channel: {}", tag);  
145 - PublishManager.getInstance().close(tag);  
146 - }  
147 -  
148 - }  
149 -  
150 - public static void createStreamProxy(String stream, Integer port) throws URISyntaxException, IOException {  
151 - Jt1078ConfigBean jt1078ConfigBean = VManageBootstrap.getBean(Jt1078ConfigBean.class);  
152 - MediaConfig mediaConfig = VManageBootstrap.getBean(MediaConfig.class);  
153 - StreamProxyController streamProxyController = VManageBootstrap.getBean(StreamProxyController.class);  
154 -  
155 - if (StringUtils.endsWith(stream, ".flv")) {  
156 - stream = StringUtils.substringBeforeLast(stream, ".flv");  
157 - }  
158 - if(Objects.isNull(jt1078ConfigBean)){  
159 - return;  
160 - }  
161 - String url = StringUtils.replace(jt1078ConfigBean.getGetURL(), "{stream}", stream);  
162 - url = StringUtils.replace(url, "{port}", port + "");  
163 - if (!StringUtils.endsWith(url, ".flv")) {  
164 - url = url + ".flv";  
165 - }  
166 - StreamProxyItem item = new StreamProxyItem();  
167 - item.setApp("schedule");  
168 - item.setEnable(true);  
169 - item.setEnableAudio(true);  
170 - item.setRtpType("default");  
171 - item.setStream(stream);  
172 - item.setMediaServerId(mediaConfig.getId());  
173 - item.setUrl(url);  
174 - item.setFfmpegCmdKey("ffmpeg.cmd");  
175 - item.setEnable(true);  
176 - item.setEnableAudio(true);  
177 - item.setEnableMp4(false);  
178 - item.setEnableRemoveNoneReader(false);  
179 - item.setEnableDisableNoneReader(false);  
180 - item.setName(stream);  
181 -  
182 - StringRedisTemplate redisTemplate = VManageBootstrap.getBean(StringRedisTemplate.class);  
183 - String key = "jtt1078:" + stream;  
184 - String closeKey = "jt1078:count:"+stream;  
185 - String timeoutKey = "timeout:"+stream;  
186 - Object timeOutVal = redisTemplate.opsForValue().get(timeoutKey);  
187 - if(Objects.equals("2",timeOutVal)){  
188 - IStreamProxyService streamProxyService = VManageBootstrap.getBean(IStreamProxyService.class);  
189 - streamProxyService.stop1("schedule",stream);  
190 - redisTemplate.delete(timeoutKey);  
191 - }  
192 -  
193 - if(redisTemplate.hasKey(closeKey)){  
194 - IStreamProxyService streamProxyService = VManageBootstrap.getBean(IStreamProxyService.class);  
195 - streamProxyService.del("schedule",stream);  
196 - }else if (redisTemplate.hasKey(key)) {  
197 - redisTemplate.opsForValue().set(key, "1", 300, TimeUnit.SECONDS);  
198 - } else {  
199 - try {  
200 - streamProxyController.save(item);  
201 - }catch (Exception e){  
202 - logger.error(e.getMessage());  
203 - }  
204 - timeOutVal = redisTemplate.opsForValue().get(timeoutKey);  
205 - if(Objects.equals("2",timeOutVal)) {  
206 - IStreamProxyService streamProxyService = VManageBootstrap.getBean(IStreamProxyService.class);  
207 - streamProxyService.stop1("schedule", stream);  
208 - redisTemplate.delete(timeoutKey);  
209 - }  
210 -  
211 - }  
212 - }  
213 -  
214 - private synchronized String endWithMapping(String tagMapping) throws URISyntaxException, IOException {  
215 - if (!StringUtils.endsWith(this.tagMapping, ".flv")) {  
216 - this.tagMapping = this.tagMapping + ".flv";  
217 - }  
218 - return this.tagMapping;  
219 - }  
220 -}  
src/main/java/com/genersoft/iot/vmp/jt1078/server/RTSPHandler.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.jt1078.server;  
2 -  
3 -import com.genersoft.iot.vmp.jt1078.rtsp.RtspRequest;  
4 -import com.genersoft.iot.vmp.jt1078.rtsp.RtspSessionManager;  
5 -import io.netty.bootstrap.Bootstrap;  
6 -import io.netty.buffer.ByteBuf;  
7 -import io.netty.channel.*;  
8 -import io.netty.channel.nio.NioEventLoopGroup;  
9 -import io.netty.channel.socket.SocketChannel;  
10 -import io.netty.channel.socket.nio.NioSocketChannel;  
11 -import io.netty.handler.codec.http.DefaultHttpContent;  
12 -import io.netty.handler.codec.http.DefaultHttpResponse;  
13 -import io.netty.handler.codec.http.HttpMethod;  
14 -import io.netty.handler.codec.rtsp.*;  
15 -import io.netty.util.internal.StringUtil;  
16 -import org.slf4j.Logger;  
17 -import org.slf4j.LoggerFactory;  
18 -  
19 -import java.net.InetSocketAddress;  
20 -import java.util.*;  
21 -  
22 -public class RTSPHandler extends ChannelInboundHandlerAdapter {  
23 -  
24 - private final static Logger log = LoggerFactory.getLogger(RTSPHandler.class);  
25 -  
26 - private String channelId = "122223333444-1";  
27 -  
28 - private HttpMethod currentMethod = RtspMethods.OPTIONS;  
29 -  
30 - private List<HttpMethod> methods = Arrays.asList(RtspMethods.OPTIONS, RtspMethods.ANNOUNCE, RtspMethods.SETUP, RtspMethods.RECORD, null);  
31 -  
32 - private RtspRequest rtspRequest = new RtspRequest("192.168.169.100", 9555, String.format("/schedule/%s?sign=41db35390ddad33f83944f44b8b75ded", channelId));  
33 -  
34 - /*  
35 - When notified that the channel is active, sends a message. A channel is active  
36 - when a connection has been established, so the method is invoked when the connections  
37 - is established.  
38 - */  
39 - @Override  
40 - public void channelActive(final ChannelHandlerContext ctx) {  
41 - log.debug("channelActive, connection established: {}", ctx);  
42 - log.debug("Sending request to the server");  
43 - ctx.writeAndFlush(rtspRequest.option());  
44 - }  
45 -  
46 - @Override  
47 - public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {  
48 - log.info("exceptionCaught: {}", cause);  
49 - ctx.close();  
50 - }  
51 -  
52 - @Override  
53 - public void channelRead(ChannelHandlerContext ctx, Object msg) {  
54 - log.info("Received from RTSP Server: {}", ctx);  
55 - log.info("Received from RTSP msg: {}", msg.toString());  
56 - log.debug("Received Class Type: {}", msg.getClass().getTypeName());  
57 - if (msg instanceof DefaultHttpResponse) {  
58 - DefaultHttpResponse res = (DefaultHttpResponse) msg;  
59 - if (RtspResponseStatuses.OK.equals(res.status())) {  
60 - log.debug("{}: {}", currentMethod, res.status());  
61 - if (res.headers().contains(RtspHeaderNames.SESSION)) {  
62 - rtspRequest.setSessionID(res.headers().get(RtspHeaderNames.SESSION));  
63 - }  
64 - nextMethod(ctx);  
65 - } else {  
66 - ctx.close();  
67 - }  
68 - } else if (msg instanceof DefaultHttpContent) {  
69 - DefaultHttpContent content = (DefaultHttpContent) msg;  
70 - log.info("Content: {}", content);  
71 -  
72 - ByteBuf byteBuf = content.content();  
73 - } else {  
74 - log.debug("dataType error: {}", msg.getClass().getTypeName());  
75 - }  
76 - }  
77 -  
78 - private void nextMethod(ChannelHandlerContext ctx) {  
79 - for (int i = 0;i < methods.size(); i++) {  
80 - if (methods.get(i).equals(currentMethod) && i < methods.size() - 1) {  
81 - currentMethod = methods.get(i + 1);  
82 - break;  
83 - }  
84 - }  
85 - if (currentMethod == null) {  
86 - RtspSessionManager.register(channelId);  
87 - return;  
88 - }  
89 - if (currentMethod == RtspMethods.ANNOUNCE) {  
90 - ctx.writeAndFlush(rtspRequest.announce());  
91 - }  
92 - if (currentMethod == RtspMethods.SETUP) {  
93 - ctx.writeAndFlush(rtspRequest.setup());  
94 - }  
95 - if (currentMethod == RtspMethods.RECORD) {  
96 - ctx.writeAndFlush(rtspRequest.record());  
97 - }  
98 - }  
99 -  
100 - private void parseSdp(String sdp) {  
101 - log.debug("Parsing SDP: {}", sdp);  
102 - Map<String, List<String>> mediaMap = new HashMap<>(10);  
103 - String[] array = sdp.split("\\n");  
104 - String mediaName = "";  
105 - for (int i = 0; i < array.length; i++) {  
106 - String line = array[i];  
107 - if (line.startsWith("m=")) {  
108 - mediaName = line.substring(line.indexOf("=") + 1, line.indexOf(" "));  
109 - if (mediaName.equals("video") || mediaName.equals("audio")) {  
110 - mediaMap.put(mediaName, new ArrayList<>());  
111 - } else {  
112 - mediaName = "";  
113 - }  
114 - } else if (!StringUtil.isNullOrEmpty(mediaName)) {  
115 - if (line.startsWith("b=") || line.startsWith("a=")) {  
116 - List<String> medialist = mediaMap.get(mediaName);  
117 - medialist.add(line);  
118 - }  
119 - }  
120 - }  
121 - for (String mediaKey : mediaMap.keySet()) {  
122 - StringBuilder stringBuilder = new StringBuilder();  
123 - List<String> mediaInfo = mediaMap.get(mediaKey);  
124 - mediaInfo.forEach((s) -> {  
125 - stringBuilder.append("\n");  
126 - stringBuilder.append(s);  
127 - });  
128 - log.info("[>>>>> {} <<<<<] {}", mediaKey, stringBuilder.toString());  
129 - }  
130 - }  
131 -  
132 - public static void main(String[] args) {  
133 - EventLoopGroup group = new NioEventLoopGroup();  
134 - try {  
135 - Bootstrap clientBootstrap = new Bootstrap();  
136 - clientBootstrap.group(group)  
137 - .option(ChannelOption.TCP_NODELAY, true)  
138 - .channel(NioSocketChannel.class)  
139 - .remoteAddress(new InetSocketAddress("192.168.169.100", 9555))  
140 - .handler(new ChannelInitializer<SocketChannel>() {  
141 - @Override  
142 - protected void initChannel(SocketChannel socketChannel) {  
143 - socketChannel.pipeline()  
144 - .addLast(new RtspEncoder())  
145 - .addLast(new RtspDecoder())  
146 - .addLast(new RTSPHandler());  
147 - }  
148 - });  
149 - ChannelFuture f = null;  
150 - while (true) {  
151 - log.info("Waiting for server connection");  
152 - f = clientBootstrap.connect();  
153 - f.awaitUninterruptibly();  
154 - if (f.isSuccess()) {  
155 - log.info("RTSP Connection success!");  
156 - break;  
157 - }  
158 - Thread.sleep(1000);  
159 - }  
160 -  
161 - // Wait for the server to close the connection.  
162 - f.channel().closeFuture().sync();  
163 - } catch (Exception e) {  
164 - log.error("Error ->", e);  
165 - log.error("<- Error");  
166 - } finally {  
167 - // Shut down executor threads to exit.Ahkk  
168 - try {  
169 - log.info("ShutdownGracefully the connection group");  
170 - group.shutdownGracefully().sync();  
171 - } catch (InterruptedException e) {  
172 - log.error("", e);  
173 - }  
174 - }  
175 - }  
176 -}  
177 \ No newline at end of file 0 \ No newline at end of file
src/main/java/com/genersoft/iot/vmp/jt1078/session/Session.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.jt1078.session;  
2 -  
3 -import com.genersoft.iot.vmp.jt1078.proc.Header;  
4 -import io.netty.channel.Channel;  
5 -import io.netty.util.AttributeKey;  
6 -import org.slf4j.Logger;  
7 -import org.slf4j.LoggerFactory;  
8 -  
9 -import java.util.concurrent.atomic.AtomicInteger;  
10 -  
11 -/**  
12 - * @author QingtaiJiang  
13 - * @date 2023/4/27 18:54  
14 - * @email qingtaij@163.com  
15 - */  
16 -public class Session {  
17 - private final static Logger log = LoggerFactory.getLogger(Session.class);  
18 -  
19 - public static final AttributeKey<Session> KEY = AttributeKey.newInstance(Session.class.getName());  
20 -  
21 - // Netty的channel  
22 - protected final Channel channel;  
23 -  
24 - // 原子类的自增ID  
25 - private final AtomicInteger serialNo = new AtomicInteger(0);  
26 -  
27 - // 是否注册成功  
28 - private boolean registered = false;  
29 -  
30 - // 设备ID  
31 - private String devId;  
32 -  
33 - // 创建时间  
34 - private final long creationTime;  
35 -  
36 - // 协议版本号  
37 - private Integer protocolVersion;  
38 -  
39 - private Header header;  
40 -  
41 - protected Session(Channel channel) {  
42 - this.channel = channel;  
43 - this.creationTime = System.currentTimeMillis();  
44 - }  
45 -  
46 - public void writeObject(Object message) {  
47 - log.info("<<<<<<<<<< cmd{},{}", this, message);  
48 - channel.writeAndFlush(message);  
49 - }  
50 -  
51 - /**  
52 - * 获得下一个流水号  
53 - *  
54 - * @return 流水号  
55 - */  
56 - public int nextSerialNo() {  
57 - int current;  
58 - int next;  
59 - do {  
60 - current = serialNo.get();  
61 - next = current > 0xffff ? 0 : current;  
62 - } while (!serialNo.compareAndSet(current, next + 1));  
63 - return next;  
64 - }  
65 -  
66 - /**  
67 - * 注册session  
68 - *  
69 - * @param devId 设备ID  
70 - */  
71 - public void register(String devId, Integer version, Header header) {  
72 - this.devId = devId;  
73 - this.registered = true;  
74 - this.protocolVersion = version;  
75 - this.header = header;  
76 - SessionManager.INSTANCE.put(devId, this);  
77 - }  
78 -  
79 - /**  
80 - * 获取设备号  
81 - *  
82 - * @return 设备号  
83 - */  
84 - public String getDevId() {  
85 - return devId;  
86 - }  
87 -  
88 -  
89 - public boolean isRegistered() {  
90 - return registered;  
91 - }  
92 -  
93 - public long getCreationTime() {  
94 - return creationTime;  
95 - }  
96 -  
97 - public Integer getProtocolVersion() {  
98 - return protocolVersion;  
99 - }  
100 -  
101 - public Header getHeader() {  
102 - return header;  
103 - }  
104 -  
105 - @Override  
106 - public String toString() {  
107 - return "[" +  
108 - "devId=" + devId +  
109 - ", reg=" + registered +  
110 - ", version=" + protocolVersion +  
111 - ",ip=" + channel.remoteAddress() +  
112 - ']';  
113 - }  
114 -}  
src/main/java/com/genersoft/iot/vmp/jt1078/session/SessionManager.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.jt1078.session;  
2 -  
3 -import com.genersoft.iot.vmp.jt1078.proc.entity.Cmd;  
4 -import io.netty.channel.Channel;  
5 -import org.slf4j.Logger;  
6 -import org.slf4j.LoggerFactory;  
7 -  
8 -import java.util.Map;  
9 -import java.util.concurrent.ConcurrentHashMap;  
10 -import java.util.concurrent.SynchronousQueue;  
11 -import java.util.concurrent.TimeUnit;  
12 -  
13 -  
14 -/**  
15 - * @author QingtaiJiang  
16 - * @date 2023/4/27 19:54  
17 - * @email qingtaij@163.com  
18 - */  
19 -public enum SessionManager {  
20 - INSTANCE;  
21 - private final static Logger log = LoggerFactory.getLogger(SessionManager.class);  
22 -  
23 - // 用与消息的缓存  
24 - private final Map<String, SynchronousQueue<String>> topicSubscribers = new ConcurrentHashMap<>();  
25 -  
26 - // session的缓存  
27 - private final Map<Object, Session> sessionMap;  
28 -  
29 - SessionManager() {  
30 - this.sessionMap = new ConcurrentHashMap<>();  
31 - }  
32 -  
33 - /**  
34 - * 创建新的Session  
35 - *  
36 - * @param channel netty通道  
37 - * @return 创建的session对象  
38 - */  
39 - public Session newSession(Channel channel) {  
40 - return new Session(channel);  
41 - }  
42 -  
43 -  
44 - /**  
45 - * 获取指定设备的Session  
46 - *  
47 - * @param clientId 设备Id  
48 - * @return Session  
49 - */  
50 - public Session get(Object clientId) {  
51 - return sessionMap.get(clientId);  
52 - }  
53 -  
54 - /**  
55 - * 放入新设备连接的session  
56 - *  
57 - * @param clientId 设备ID  
58 - * @param newSession session  
59 - */  
60 - protected void put(Object clientId, Session newSession) {  
61 - sessionMap.put(clientId, newSession);  
62 - }  
63 -  
64 -  
65 - /**  
66 - * 发送同步消息,接收响应  
67 - * 默认超时时间6秒  
68 - */  
69 - public String request(Cmd cmd) {  
70 - // 默认6秒  
71 - int timeOut = 6000;  
72 - return request(cmd, timeOut);  
73 - }  
74 -  
75 - public String request(Cmd cmd, Integer timeOut) {  
76 - Session session = this.get(cmd.getDevId());  
77 - if (session == null) {  
78 - log.error("DevId: {} not online!", cmd.getDevId());  
79 - return null;  
80 - }  
81 - String requestKey = requestKey(cmd.getDevId(), cmd.getRespId(), cmd.getPackageNo());  
82 - SynchronousQueue<String> subscribe = subscribe(requestKey);  
83 - if (subscribe == null) {  
84 - log.error("DevId: {} key:{} send repaid", cmd.getDevId(), requestKey);  
85 - return null;  
86 - }  
87 - session.writeObject(cmd);  
88 - try {  
89 - return subscribe.poll(timeOut, TimeUnit.SECONDS);  
90 - } catch (InterruptedException e) {  
91 - log.warn("<<<<<<<<<< timeout" + session, e);  
92 - } finally {  
93 - this.unsubscribe(requestKey);  
94 - }  
95 - return null;  
96 - }  
97 -  
98 - public Boolean response(String devId, String respId, Long responseNo, String data) {  
99 - String requestKey = requestKey(devId, respId, responseNo);  
100 - SynchronousQueue<String> queue = topicSubscribers.get(requestKey);  
101 - if (queue != null) {  
102 - try {  
103 - return queue.offer(data, 2, TimeUnit.SECONDS);  
104 - } catch (InterruptedException e) {  
105 - log.error("{}", e.getMessage(), e);  
106 - }  
107 - }  
108 - log.warn("Not find response,key:{} data:{} ", requestKey, data);  
109 - return false;  
110 - }  
111 -  
112 - private void unsubscribe(String key) {  
113 - topicSubscribers.remove(key);  
114 - }  
115 -  
116 - private SynchronousQueue<String> subscribe(String key) {  
117 - SynchronousQueue<String> queue = null;  
118 - if (!topicSubscribers.containsKey(key))  
119 - topicSubscribers.put(key, queue = new SynchronousQueue<String>());  
120 - return queue;  
121 - }  
122 -  
123 - private String requestKey(String devId, String respId, Long requestNo) {  
124 - return String.join("_", devId.replaceFirst("^0*", ""), respId, requestNo.toString());  
125 - }  
126 -  
127 -}  
src/main/java/com/genersoft/iot/vmp/jt1078/test/AudioTest.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.jt1078.test;  
2 -  
3 -import com.genersoft.iot.vmp.jt1078.codec.G711Codec;  
4 -import com.genersoft.iot.vmp.jt1078.server.Jtt1078Decoder;  
5 -import com.genersoft.iot.vmp.jt1078.util.ByteUtils;  
6 -import com.genersoft.iot.vmp.jt1078.util.Packet;  
7 -  
8 -import java.io.FileInputStream;  
9 -import java.io.FileOutputStream;  
10 -  
11 -/**  
12 - * Created by matrixy on 2019/12/21.  
13 - */  
14 -public class AudioTest  
15 -{  
16 - public static void main(String[] args) throws Exception  
17 - {  
18 - int len = -1;  
19 - byte[] block = new byte[1024];  
20 - FileInputStream fis = new FileInputStream("e:\\test\\streaming.hex");  
21 - Jtt1078Decoder decoder = new Jtt1078Decoder();  
22 - G711Codec codec = new G711Codec();  
23 - FileOutputStream fos = new FileOutputStream("e:\\test\\fuckfuckfuck1111.pcm");  
24 - while ((len = fis.read(block)) > -1)  
25 - {  
26 - decoder.write(block, 0, len);  
27 - while (true)  
28 - {  
29 - Packet p = decoder.decode();  
30 - if (p == null) break;  
31 -  
32 - int lengthOffset = 28;  
33 - int dataType = (p.seek(15).nextByte() >> 4) & 0x0f;  
34 - // 透传数据类型:0100,没有后面的时间以及Last I Frame Interval和Last Frame Interval字段  
35 - if (dataType == 0x04) lengthOffset = 28 - 8 - 2 - 2;  
36 - else if (dataType == 0x03) lengthOffset = 28 - 4;  
37 -  
38 - if (dataType == 0x03)  
39 - {  
40 - byte[] pcmData = codec.toPCM(p.seek(lengthOffset + 2).nextBytes());  
41 - fos.write(pcmData);  
42 - fos.flush();  
43 - }  
44 - }  
45 - }  
46 - fos.close();  
47 - fis.close();  
48 - }  
49 -}  
src/main/java/com/genersoft/iot/vmp/jt1078/test/ChannelTest.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.jt1078.test;  
2 -  
3 -import com.genersoft.iot.vmp.jt1078.util.ByteHolder;  
4 -import com.genersoft.iot.vmp.jt1078.util.ByteUtils;  
5 -  
6 -import java.io.ByteArrayOutputStream;  
7 -import java.io.IOException;  
8 -import java.nio.ByteBuffer;  
9 -import java.nio.channels.ByteChannel;  
10 -  
11 -/**  
12 - * Created by matrixy on 2020/1/9.  
13 - */  
14 -public class ChannelTest implements ByteChannel  
15 -{  
16 - byte[] temp = new byte[4];  
17 - ByteHolder buffer = new ByteHolder(1024);  
18 -  
19 - // 读出,存入dst  
20 - @Override  
21 - public int read(ByteBuffer dst) throws IOException  
22 - {  
23 - dst.flip();  
24 - int len = Math.min(4, buffer.size());  
25 - if (dst.remaining() > len)  
26 - {  
27 - buffer.sliceInto(temp, len);  
28 - dst.put(temp, 0, len);  
29 - }  
30 - else  
31 - {  
32 - // 丢掉???  
33 - }  
34 - dst.flip();  
35 - return len;  
36 - }  
37 -  
38 - // 从src读出,写入进来  
39 - @Override  
40 - public int write(ByteBuffer src) throws IOException  
41 - {  
42 - int len = -1;  
43 - // src.flip();  
44 - len = Math.min(4, src.limit());  
45 - src.get(temp, 0, len);  
46 - buffer.write(temp, 0, len);  
47 - // src.flip();  
48 - System.out.println("write: " + len);  
49 - return len;  
50 - }  
51 -  
52 - @Override  
53 - public boolean isOpen()  
54 - {  
55 - return true;  
56 - }  
57 -  
58 - @Override  
59 - public void close() throws IOException  
60 - {  
61 -  
62 - }  
63 -  
64 - public byte[] array()  
65 - {  
66 - return buffer.array();  
67 - }  
68 -  
69 - public static void main(String[] args) throws Exception  
70 - {  
71 - ChannelTest chl = new ChannelTest();  
72 - ByteBuffer buffer = ByteBuffer.allocate(4);  
73 - java.nio.ByteBuffer xx;  
74 - System.out.println(buffer.getClass().getName());  
75 - for (int i = 0; i < 4096; i++)  
76 - buffer.put((byte)'f');  
77 - /*  
78 - buffer.putLong(0x1122334455667788L);  
79 - buffer.flip();  
80 - // flip太迷惑了  
81 - buffer.isReadOnly();  
82 - int len = chl.write(buffer);  
83 - len = chl.write(buffer);  
84 - ByteUtils.dump(chl.array());  
85 - */  
86 - }  
87 -  
88 - static final class ByteBufferWrapper  
89 - {  
90 - boolean writeMode;  
91 - ByteBuffer buffer;  
92 -  
93 - private ByteBufferWrapper(int size)  
94 - {  
95 - this.buffer = ByteBuffer.allocate(size);  
96 - }  
97 -  
98 - // 控制写入,代理过来  
99 - public void write()  
100 - {  
101 -  
102 - }  
103 -  
104 - // 写出就无所谓了  
105 -  
106 - public static ByteBufferWrapper create(int size)  
107 - {  
108 - return new ByteBufferWrapper(size);  
109 - }  
110 - }  
111 -}  
src/main/java/com/genersoft/iot/vmp/jt1078/test/FuckTest.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.jt1078.test;  
2 -  
3 -import com.genersoft.iot.vmp.jt1078.util.ByteUtils;  
4 -import com.genersoft.iot.vmp.jt1078.util.Packet;  
5 -  
6 -import java.io.DataInputStream;  
7 -import java.io.FileInputStream;  
8 -  
9 -/**  
10 - * Created by matrixy on 2020/3/19.  
11 - */  
12 -public class FuckTest  
13 -{  
14 - public static void main(String[] args) throws Exception  
15 - {  
16 - String line;  
17 - DataInputStream dis = new DataInputStream(new FileInputStream("d:\\temp\\rtp.txt"));  
18 - while ((line = dis.readLine()) != null)  
19 - {  
20 - byte[] rtp = ByteUtils.parse(line);  
21 - Packet packet = Packet.create(rtp);  
22 -  
23 - int lengthOffset = 28;  
24 - int dataType = (packet.seek(15).nextByte() >> 4) & 0x0f;  
25 - int pkType = packet.seek(15).nextByte() & 0x0f;  
26 - // 透传数据类型:0100,没有后面的时间以及Last I Frame Interval和Last Frame Interval字段  
27 - if (dataType == 0x04) lengthOffset = 28 - 8 - 2 - 2;  
28 - else if (dataType == 0x03) lengthOffset = 28 - 4;  
29 -  
30 - if (dataType <= 0x02)  
31 - {  
32 - if (dataType == 0x00) System.out.println("I Frame---------------------------------");  
33 - if (dataType == 0x01) System.out.println("P Frame");  
34 - if (dataType == 0x02) System.out.println("B Frame");  
35 - }  
36 - }  
37 - }  
38 -}  
src/main/java/com/genersoft/iot/vmp/jt1078/test/G711ATest.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.jt1078.test;  
2 -  
3 -import com.genersoft.iot.vmp.jt1078.codec.G711Codec;  
4 -  
5 -import java.io.FileInputStream;  
6 -import java.io.FileOutputStream;  
7 -  
8 -/**  
9 - * Created by matrixy on 2019/12/21.  
10 - */  
11 -public class G711ATest  
12 -{  
13 - public static void main(String[] args) throws Exception  
14 - {  
15 - int len = -1;  
16 - byte[] block = new byte[1024];  
17 - FileInputStream fis = new FileInputStream("E:\\workspace\\enc_dec_audio\\g711\\encode_out.g711a");  
18 - FileOutputStream fos = new FileOutputStream("E:\\test\\fuckfuckfuck111.pcm");  
19 - G711Codec codec = new G711Codec();  
20 - while ((len = fis.read(block)) > -1)  
21 - {  
22 - byte[] pcmData = null;  
23 - if (len == 1024)  
24 - {  
25 - pcmData = codec.toPCM(block);  
26 - }  
27 - else  
28 - {  
29 - byte[] temp = new byte[len];  
30 - System.arraycopy(block, 0, temp, 0, len);  
31 - pcmData = codec.toPCM(temp);  
32 - }  
33 - fos.write(pcmData);  
34 - fos.flush();  
35 - }  
36 - fis.close();  
37 - fos.close();  
38 - }  
39 -}  
src/main/java/com/genersoft/iot/vmp/jt1078/test/MP3Test.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.jt1078.test;  
2 -  
3 -import de.sciss.jump3r.lowlevel.LameEncoder;  
4 -import de.sciss.jump3r.mp3.Lame;  
5 -  
6 -import javax.sound.sampled.AudioFormat;  
7 -import java.io.ByteArrayOutputStream;  
8 -import java.io.FileInputStream;  
9 -import java.io.FileOutputStream;  
10 -  
11 -/**  
12 - * Created by matrixy on 2020/4/27.  
13 - */  
14 -public class MP3Test  
15 -{  
16 - public static void main(String[] args) throws Exception  
17 - {  
18 - AudioFormat sourceFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 8000, 16, 1, 1 * 2, -1, false);  
19 - LameEncoder encoder = new LameEncoder(sourceFormat, 256, 3, Lame.MEDIUM, false);  
20 -  
21 - byte[] block = new byte[320];  
22 - int len = -1;  
23 - FileInputStream fis = new FileInputStream("d:\\temp\\hello.pcm");  
24 - ByteArrayOutputStream mp3 = new ByteArrayOutputStream(encoder.getOutputBufferSize());  
25 - byte[] buffer = new byte[encoder.getPCMBufferSize()];  
26 - int bytesToTransfer = 0;  
27 - int bytesWritten;  
28 - int currentPcmPosition = 0;  
29 -  
30 - FileOutputStream fos = new FileOutputStream("d:\\temp\\fuck.mp3");  
31 -  
32 - while ((len = fis.read(block)) > -1)  
33 - {  
34 - bytesToTransfer = len;  
35 - currentPcmPosition = 0;  
36 - while (0 < (bytesWritten = encoder.encodeBuffer(block, currentPcmPosition, bytesToTransfer, buffer)))  
37 - {  
38 - currentPcmPosition += bytesToTransfer;  
39 - bytesToTransfer = Math.min(buffer.length, len - currentPcmPosition);  
40 -  
41 - mp3.write(buffer, 0, bytesWritten);  
42 - fos.write(buffer, 0, bytesWritten);  
43 -  
44 - System.out.println(String.format("pcm data: %4d, written: %4d, pos: %4d", len, bytesWritten, currentPcmPosition));  
45 - }  
46 - System.out.println();  
47 - }  
48 -  
49 - fos.close();  
50 - fis.close();  
51 -  
52 - encoder.close();  
53 - }  
54 -}  
src/main/java/com/genersoft/iot/vmp/jt1078/test/RTPGenerate.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.jt1078.test;  
2 -  
3 -import com.genersoft.iot.vmp.jt1078.flv.FlvEncoder;  
4 -import com.genersoft.iot.vmp.jt1078.server.Jtt1078Decoder;  
5 -import com.genersoft.iot.vmp.jt1078.util.ByteHolder;  
6 -import com.genersoft.iot.vmp.jt1078.util.ByteUtils;  
7 -import com.genersoft.iot.vmp.jt1078.util.Packet;  
8 -  
9 -import java.io.FileInputStream;  
10 -import java.io.FileOutputStream;  
11 -import java.io.InputStream;  
12 -import java.io.OutputStream;  
13 -import java.util.LinkedList;  
14 -  
15 -/**  
16 - * Created by matrixy on 2019/12/16.  
17 - */  
18 -public class RTPGenerate  
19 -{  
20 - public static void main(String[] args) throws Exception  
21 - {  
22 - InputStream input = new FileInputStream("d:\\test\\1078\\streamax-20191209.bin");  
23 - LinkedList<Packet> packets = readPackets(input);  
24 -  
25 - for (int i = 0; i < 100; i++)  
26 - {  
27 - String sim = String.format("013800138%03d", i);  
28 - int channel = 1;  
29 -  
30 - try (OutputStream output = new FileOutputStream("d:\\test\\1078\\temp\\" + sim + "-" + channel + ".bin"))  
31 - {  
32 - for (Packet p : packets)  
33 - {  
34 - p.seek(8).putBytes(toBCD(sim));  
35 - p.seek(14).putByte((byte)channel);  
36 - output.write(p.getBytes());  
37 - }  
38 - System.out.println(String.format(" -> %s-%d generated...", sim, channel));  
39 - }  
40 - catch(Exception ex)  
41 - {  
42 - ex.printStackTrace();  
43 - System.out.println(ex);  
44 - }  
45 - }  
46 -  
47 - input.close();  
48 - }  
49 -  
50 - public static LinkedList<Packet> readPackets(InputStream input) throws Exception  
51 - {  
52 - int len = -1;  
53 - byte[] block = new byte[1024];  
54 - Jtt1078Decoder decoder = new Jtt1078Decoder();  
55 -  
56 - LinkedList<Packet> packets = new LinkedList();  
57 -  
58 - while ((len = input.read(block)) > -1)  
59 - {  
60 - decoder.write(block, 0, len);  
61 - while (true)  
62 - {  
63 - Packet p = decoder.decode();  
64 - if (p == null) break;  
65 -  
66 - packets.add(p);  
67 - }  
68 - }  
69 -  
70 - return packets;  
71 - }  
72 -  
73 - public static byte[] toBCD(String sim)  
74 - {  
75 - byte[] bcd = new byte[sim.length() / 2];  
76 - for (int i = 0, k = 0, l = sim.length(); i < l; i+=2)  
77 - {  
78 - char a = (char)(sim.charAt(i) - '0');  
79 - char b = (char)(sim.charAt(i + 1) - '0');  
80 - bcd[k++] = ((byte)(a << 4 | b));  
81 - }  
82 - return bcd;  
83 - }  
84 -}  
src/main/java/com/genersoft/iot/vmp/jt1078/test/UnPack.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.jt1078.test;  
2 -  
3 -import com.genersoft.iot.vmp.jt1078.server.Jtt1078Decoder;  
4 -import com.genersoft.iot.vmp.jt1078.util.Packet;  
5 -  
6 -import java.io.FileInputStream;  
7 -import java.io.FileOutputStream;  
8 -  
9 -public class UnPack  
10 -{  
11 - public static void main(String[] args) throws Exception  
12 - {  
13 - FileInputStream input = new FileInputStream("d:\\test\\1078\\d.bin");  
14 - FileOutputStream output = new FileOutputStream("d:\\test\\1078\\fuck.1078.xxx");  
15 -  
16 - int len = -1;  
17 - byte[] block = new byte[1024];  
18 - Jtt1078Decoder decoder = new Jtt1078Decoder();  
19 - while (true)  
20 - {  
21 - len = input.read(block);  
22 - if (len == -1) break;  
23 - decoder.write(block, 0, len);  
24 -  
25 - while (true)  
26 - {  
27 - Packet p = decoder.decode();  
28 - if (p == null) break;  
29 -  
30 - int lengthOffset = 28;  
31 - int dataType = (p.seek(15).nextByte() >> 4) & 0x0f;  
32 - // 透传数据类型:0100,没有后面的时间以及Last I Frame Interval和Last Frame Interval字段  
33 - if (dataType == 0x04) lengthOffset = 28 - 8 - 2 - 2;  
34 - else if (dataType == 0x03) lengthOffset = 28 - 4;  
35 -  
36 - // FFMpegManager.getInstance().feed(publisherId, packet.seek(lengthOffset + 2).nextBytes());  
37 - if (dataType == 0x00 || dataType == 0x01 || dataType == 0x02)  
38 - {  
39 - // 视频  
40 - // p.seek(lengthOffset + 2).nextBytes()  
41 - // output.write(p.seek(lengthOffset + 2).nextBytes());  
42 - System.out.println(p.seek(lengthOffset).nextShort());  
43 - }  
44 - else  
45 - {  
46 - // 音频  
47 - // p.seek(lengthOffset + 2).nextBytes()  
48 - }  
49 - }  
50 - }  
51 - output.flush();  
52 - output.close();  
53 - input.close();  
54 - }  
55 -}  
56 \ No newline at end of file 0 \ No newline at end of file
src/main/java/com/genersoft/iot/vmp/jt1078/test/VideoPushTest.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.jt1078.test;  
2 -  
3 -import java.io.FileInputStream;  
4 -import java.io.InputStream;  
5 -import java.io.OutputStream;  
6 -import java.net.Socket;  
7 -  
8 -/**  
9 - * Created by matrixy on 2019/4/10.  
10 - */  
11 -public class VideoPushTest  
12 -{  
13 - public static void main(String[] args) throws Exception  
14 - {  
15 - Socket conn = new Socket("localhost", 1078);  
16 - OutputStream os = conn.getOutputStream();  
17 -  
18 - // InputStream fis = new FileInputStream("e:\\workspace\\enc_dec_audio\\streamax.bin");  
19 - // InputStream fis = new FileInputStream("e:\\test\\streaming.hex");  
20 - InputStream fis = VideoPushTest.class.getResourceAsStream("/tcpdump.bin");  
21 - int len = -1;  
22 - byte[] block = new byte[512];  
23 - while ((len = fis.read(block)) > -1)  
24 - {  
25 - os.write(block, 0, len);  
26 - os.flush();  
27 - Thread.sleep(20);  
28 - System.out.println("sending...");  
29 - }  
30 - os.close();  
31 - fis.close();  
32 - conn.close();  
33 - }  
34 -}  
src/main/java/com/genersoft/iot/vmp/jt1078/test/VideoServer.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.jt1078.test;  
2 -  
3 -import com.genersoft.iot.vmp.jt1078.server.Jtt1078Decoder;  
4 -import com.genersoft.iot.vmp.jt1078.util.Packet;  
5 -  
6 -import java.io.FileOutputStream;  
7 -import java.io.InputStream;  
8 -import java.net.ServerSocket;  
9 -import java.net.Socket;  
10 -import java.util.LinkedList;  
11 -  
12 -/**  
13 - * Created by houcheng on 2019-12-10.  
14 - */  
15 -public class VideoServer  
16 -{  
17 - public static void main(String[] args) throws Exception  
18 - {  
19 - System.out.println("started...");  
20 -  
21 - String command = ("ffmpeg -f h264 -i /opt/test/xxoo.Video -f sln -ar 8000 -ac 1 -i /opt/test/xxoo.Audio -vcodec copy -acodec aac -map 0:v:0 -map 1:a:0 -probesize 512 -analyzeduration 100 -f flv rtmp://localhost/live/fuck");  
22 - Process process = Runtime.getRuntime().exec(command);  
23 - new Reader(process.getErrorStream()).start();  
24 -  
25 - Thread.sleep(2000);  
26 -  
27 - ServerSocket server = new ServerSocket(1078, 100);  
28 - Socket conn = server.accept();  
29 - System.out.println("Connected from: " + conn.getRemoteSocketAddress());  
30 - InputStream input = conn.getInputStream();  
31 -  
32 - Publisher videoPublisher = new VideoPublisher();  
33 - Publisher audioPublisher = new AudioPublisher();  
34 -  
35 - videoPublisher.start();  
36 - audioPublisher.start();  
37 -  
38 - int len = -1;  
39 - byte[] block = new byte[1024];  
40 - Jtt1078Decoder decoder = new Jtt1078Decoder();  
41 - while (true)  
42 - {  
43 - len = input.read(block);  
44 - if (len == -1) break;  
45 - decoder.write(block, 0, len);  
46 -  
47 - while (true)  
48 - {  
49 - Packet p = decoder.decode();  
50 - if (p == null) break;  
51 -  
52 - int lengthOffset = 28;  
53 - int dataType = (p.seek(15).nextByte() >> 4) & 0x0f;  
54 - // 透传数据类型:0100,没有后面的时间以及Last I Frame Interval和Last Frame Interval字段  
55 - if (dataType == 0x04) lengthOffset = 28 - 8 - 2 - 2;  
56 - else if (dataType == 0x03) lengthOffset = 28 - 4;  
57 -  
58 - // FFMpegManager.getInstance().feed(publisherId, packet.seek(lengthOffset + 2).nextBytes());  
59 - if (dataType == 0x00 || dataType == 0x01 || dataType == 0x02)  
60 - {  
61 - videoPublisher.publish(p.seek(lengthOffset + 2).nextBytes());  
62 - }  
63 - else  
64 - {  
65 - audioPublisher.publish(p.seek(lengthOffset + 2).nextBytes());  
66 - }  
67 - }  
68 - }  
69 -  
70 - System.in.read();  
71 - }  
72 -  
73 -  
74 -  
75 - static class Reader extends Thread  
76 - {  
77 - InputStream stdout = null;  
78 - public Reader(InputStream is)  
79 - {  
80 - this.stdout = is;  
81 - }  
82 -  
83 - public void run()  
84 - {  
85 - int len = -1;  
86 - byte[] block = new byte[512];  
87 - try  
88 - {  
89 - while ((len = stdout.read(block)) > -1)  
90 - {  
91 - System.out.print(new String(block, 0, len));  
92 - }  
93 - }  
94 - catch(Exception ex)  
95 - {  
96 - ex.printStackTrace();  
97 - }  
98 - }  
99 - }  
100 -  
101 - static class Publisher extends Thread  
102 - {  
103 - Object lock = new Object();  
104 - LinkedList<byte[]> messages = new LinkedList();  
105 -  
106 - public void publish(byte[] msg)  
107 - {  
108 - synchronized (lock)  
109 - {  
110 - messages.add(msg);  
111 - lock.notify();  
112 - }  
113 - }  
114 -  
115 - public byte[] peek()  
116 - {  
117 - byte[] msg = null;  
118 - synchronized (lock)  
119 - {  
120 - while (messages.size() == 0) try { lock.wait(); } catch(Exception e) { }  
121 - msg = messages.removeFirst();  
122 - }  
123 - return msg;  
124 - }  
125 -  
126 - public FileOutputStream open(String fname)  
127 - {  
128 - try  
129 - {  
130 - return new FileOutputStream(fname);  
131 - }  
132 - catch(Exception ex)  
133 - {  
134 - throw new RuntimeException(ex);  
135 - }  
136 - }  
137 - }  
138 -  
139 - static class VideoPublisher extends Publisher  
140 - {  
141 - public void run()  
142 - {  
143 - FileOutputStream fos = open("/opt/test/xxoo.Video");  
144 - while (!this.isInterrupted())  
145 - {  
146 - try  
147 - {  
148 - byte[] msg = peek();  
149 - fos.write(msg);  
150 - fos.flush();  
151 - }  
152 - catch(Exception ex)  
153 - {  
154 - ex.printStackTrace();  
155 - break;  
156 - }  
157 - }  
158 - }  
159 - }  
160 -  
161 - static class AudioPublisher extends Publisher  
162 - {  
163 - public void run()  
164 - {  
165 - FileOutputStream fos = open("/opt/test/xxoo.Audio");  
166 - while (!this.isInterrupted())  
167 - {  
168 - try  
169 - {  
170 - byte[] msg = peek();  
171 - fos.write(msg);  
172 - fos.flush();  
173 - }  
174 - catch(Exception ex)  
175 - {  
176 - ex.printStackTrace();  
177 - break;  
178 - }  
179 - }  
180 - }  
181 - }  
182 -}  
src/main/java/com/genersoft/iot/vmp/jt1078/test/WAVTest.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.jt1078.test;  
2 -  
3 -import com.genersoft.iot.vmp.jt1078.util.ByteUtils;  
4 -import com.genersoft.iot.vmp.jt1078.util.Packet;  
5 -  
6 -import java.io.FileInputStream;  
7 -import java.io.FileOutputStream;  
8 -  
9 -/**  
10 - * Created by matrixy on 2019/12/18.  
11 - */  
12 -public class WAVTest  
13 -{  
14 - public static void main(String[] args) throws Exception  
15 - {  
16 - int len;  
17 - byte[] block = new byte[1024 * 2048];  
18 - FileInputStream fis = new FileInputStream("d:\\temp\\xxoo.pcm");  
19 - Packet p = Packet.create(1024 * 2048);  
20 - while ((len = fis.read(block)) > -1)  
21 - {  
22 - p.reset();  
23 - p.addBytes("RIFF".getBytes())  
24 - .addBytes(ByteUtils.toLEBytes(len + 36))  
25 - .addBytes("WAVE".getBytes()) // wave type  
26 - .addBytes("fmt ".getBytes()) // fmt id  
27 - .addInt(0x10000000) // fmt chunk size  
28 - .addShort((short)0x0100) // format: 1 -> PCM  
29 - .addShort((short)0x0100) // channels: 1  
30 - .addBytes(ByteUtils.toLEBytes(8000)) // samples per second  
31 - .addBytes(ByteUtils.toLEBytes(1 * 8000 * 16 / 8)) // BPSecond  
32 - .addBytes(ByteUtils.toLEBytes((short)(1 * 16 / 8))) // BPSample  
33 - .addBytes(ByteUtils.toLEBytes((short)(1 * 16))) // bPSecond  
34 - .addBytes("data".getBytes()) // data id  
35 - .addBytes(ByteUtils.toLEBytes(len)); // data chunk size  
36 -  
37 - p.addBytes(block, len);  
38 -  
39 - FileOutputStream fos = new FileOutputStream("d:\\fuck.wav");  
40 - fos.write(p.getBytes());  
41 - fos.flush();  
42 - fos.close();  
43 - }  
44 - }  
45 -}  
src/main/java/com/genersoft/iot/vmp/jt1078/util/ClassUtil.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.jt1078.util;  
2 -  
3 -import org.slf4j.Logger;  
4 -import org.slf4j.LoggerFactory;  
5 -import org.springframework.core.io.Resource;  
6 -import org.springframework.core.io.support.PathMatchingResourcePatternResolver;  
7 -import org.springframework.core.io.support.ResourcePatternResolver;  
8 -  
9 -import java.lang.annotation.Annotation;  
10 -import java.util.LinkedList;  
11 -import java.util.List;  
12 -  
13 -public class ClassUtil {  
14 -  
15 - private static final Logger logger = LoggerFactory.getLogger(ClassUtil.class);  
16 -  
17 -  
18 - public static Object getBean(Class<?> clazz) {  
19 - if (clazz != null) {  
20 - try {  
21 - return clazz.getDeclaredConstructor().newInstance();  
22 - } catch (Exception ex) {  
23 - logger.error("ClassUtil:找不到指定的类", ex);  
24 - }  
25 - }  
26 - return null;  
27 - }  
28 -  
29 -  
30 - public static Object getBean(String className) {  
31 - Class<?> clazz = null;  
32 - try {  
33 - clazz = Class.forName(className);  
34 - } catch (Exception ex) {  
35 - logger.error("ClassUtil:找不到指定的类");  
36 - }  
37 - if (clazz != null) {  
38 - try {  
39 - //获取声明的构造器--》创建实例  
40 - return clazz.getDeclaredConstructor().newInstance();  
41 - } catch (Exception ex) {  
42 - logger.error("ClassUtil:找不到指定的类", ex);  
43 - }  
44 - }  
45 - return null;  
46 - }  
47 -  
48 -  
49 - /**  
50 - * 获取包下所有带注解的class  
51 - *  
52 - * @param packageName 包名  
53 - * @param annotationClass 注解类型  
54 - * @return list  
55 - */  
56 - public static List<Class<?>> getClassList(String packageName, Class<? extends Annotation> annotationClass) {  
57 - List<Class<?>> classList = getClassList(packageName);  
58 - classList.removeIf(next -> !next.isAnnotationPresent(annotationClass));  
59 - return classList;  
60 - }  
61 -  
62 - public static List<Class<?>> getClassList(String... packageName) {  
63 - List<Class<?>> classList = new LinkedList<>();  
64 - for (String s : packageName) {  
65 - List<Class<?>> c = getClassList(s);  
66 - classList.addAll(c);  
67 - }  
68 - return classList;  
69 - }  
70 -  
71 - public static List<Class<?>> getClassList(String packageName) {  
72 - List<Class<?>> classList = new LinkedList<>();  
73 - try {  
74 - ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();  
75 - Resource[] resources = resourcePatternResolver.getResources(packageName.replace(".", "/") + "/**/*.class");  
76 - for (Resource resource : resources) {  
77 - String url = resource.getURL().toString();  
78 -  
79 - String[] split = url.split(packageName.replace(".", "/"));  
80 - String s = split[split.length - 1];  
81 - String className = s.replace("/", ".");  
82 - className = className.substring(0, className.lastIndexOf("."));  
83 - doAddClass(classList, packageName + className);  
84 - }  
85 -  
86 - } catch (Exception e) {  
87 - throw new RuntimeException(e);  
88 - }  
89 - return classList;  
90 - }  
91 -  
92 - private static void doAddClass(List<Class<?>> classList, String className) {  
93 - Class<?> cls = loadClass(className, false);  
94 - classList.add(cls);  
95 - }  
96 -  
97 - public static Class<?> loadClass(String className, boolean isInitialized) {  
98 - Class<?> cls;  
99 - try {  
100 - cls = Class.forName(className, isInitialized, getClassLoader());  
101 - } catch (ClassNotFoundException e) {  
102 - throw new RuntimeException(e);  
103 - }  
104 - return cls;  
105 - }  
106 -  
107 -  
108 - public static ClassLoader getClassLoader() {  
109 - return Thread.currentThread().getContextClassLoader();  
110 - }  
111 -  
112 -}  
src/main/java/com/genersoft/iot/vmp/jtt1078/app/VideoServerApp.java 0 → 100644
  1 +package com.genersoft.iot.vmp.jtt1078.app;
  2 +
  3 +import com.genersoft.iot.vmp.jtt1078.http.GeneralResponseWriter;
  4 +import com.genersoft.iot.vmp.jtt1078.http.NettyHttpServerHandler;
  5 +import com.genersoft.iot.vmp.jtt1078.publisher.PublishManager;
  6 +import com.genersoft.iot.vmp.jtt1078.server.Jtt1078Handler;
  7 +import com.genersoft.iot.vmp.jtt1078.server.Jtt1078MessageDecoder;
  8 +import com.genersoft.iot.vmp.jtt1078.server.SessionManager;
  9 +import com.genersoft.iot.vmp.jtt1078.util.Configs;
  10 +import com.xiaoleilu.hutool.collection.ConcurrentHashSet;
  11 +import io.netty.bootstrap.ServerBootstrap;
  12 +import io.netty.channel.*;
  13 +import io.netty.channel.nio.NioEventLoopGroup;
  14 +import io.netty.channel.socket.SocketChannel;
  15 +import io.netty.channel.socket.nio.NioServerSocketChannel;
  16 +import io.netty.handler.codec.http.HttpObjectAggregator;
  17 +import io.netty.handler.codec.http.HttpRequestDecoder;
  18 +import io.netty.handler.codec.http.HttpResponseEncoder;
  19 +import org.slf4j.Logger;
  20 +import org.slf4j.LoggerFactory;
  21 +import org.springframework.beans.factory.annotation.Value;
  22 +import org.springframework.context.annotation.Configuration;
  23 +import sun.misc.Signal;
  24 +import sun.misc.SignalHandler;
  25 +
  26 +import java.net.InetAddress;
  27 +
  28 +
  29 +/**
  30 + * Created by matrixy on 2019/4/9.
  31 + */
  32 +@Configuration
  33 +public class VideoServerApp
  34 +{
  35 + private static Logger logger = LoggerFactory.getLogger(VideoServerApp.class);
  36 +
  37 + public static final ConcurrentHashSet<String> TAG_SET = new ConcurrentHashSet<>();
  38 +
  39 + @Value("${spring.profiles.active}")
  40 + private String activeProfile;
  41 +
  42 + public void run(String... args) throws Exception {
  43 + try {
  44 + String configProperties = null;
  45 + switch (activeProfile){
  46 + case "wx-local":
  47 + configProperties = "/app.properties";
  48 + break;
  49 + case "dev100":
  50 + configProperties = "/app-dev100.properties";
  51 + break;
  52 + case "dev103":
  53 + configProperties = "/app-dev103.properties";
  54 + break;
  55 + default:
  56 + break;
  57 + }
  58 + if (configProperties == null) {
  59 + throw new RuntimeException(String.format("推流配置文件错误 [ %s ]", activeProfile));
  60 + }
  61 + Configs.init(configProperties);
  62 + PublishManager.init();
  63 + SessionManager.init();
  64 + int port = Configs.getInt("server.port", 1078);
  65 + int historyPort = Configs.getInt("server.history.port", 1078);
  66 + VideoServer videoServer = new VideoServer(port);
  67 + HttpServer httpServer = new HttpServer();
  68 + VideoServer historyVideoServer = new VideoServer(historyPort);
  69 +
  70 + Signal.handle(new Signal("TERM"), new SignalHandler()
  71 + {
  72 + @Override
  73 + public void handle(Signal signal)
  74 + {
  75 + videoServer.shutdown();
  76 + httpServer.shutdown();
  77 + historyVideoServer.shutdown();
  78 + }
  79 + });
  80 +
  81 + videoServer.start();
  82 + httpServer.start();
  83 + historyVideoServer.historyStart();
  84 + } catch (Exception e) {
  85 + logger.error("端口监听异常 ===》 {}",e.getMessage(),e);
  86 + }
  87 + }
  88 +
  89 + public VideoServer getVideoServer(Integer port) {
  90 + return new VideoServer(port);
  91 + }
  92 +
  93 + public class VideoServer
  94 + {
  95 + private ServerBootstrap serverBootstrap;
  96 +
  97 + private EventLoopGroup bossGroup;
  98 + private EventLoopGroup workerGroup;
  99 + private final Integer port;
  100 +
  101 + public VideoServer(Integer port) {
  102 + this.port = port;
  103 + }
  104 +
  105 + private void start() throws Exception
  106 + {
  107 + serverBootstrap = new ServerBootstrap();
  108 + serverBootstrap.option(ChannelOption.SO_BACKLOG, Configs.getInt("server.backlog", 102400));
  109 + bossGroup = new NioEventLoopGroup(Configs.getInt("server.worker-count", Runtime.getRuntime().availableProcessors()));
  110 + workerGroup = new NioEventLoopGroup();
  111 + serverBootstrap.group(bossGroup, workerGroup)
  112 + .option(ChannelOption.SO_KEEPALIVE, true)
  113 + .channel(NioServerSocketChannel.class)
  114 + .childHandler(new ChannelInitializer<SocketChannel>() {
  115 + @Override
  116 + protected void initChannel(final SocketChannel channel) throws Exception {
  117 + ChannelPipeline p = channel.pipeline();
  118 + // p.addLast(new IdleStateHandler(10,0,0, TimeUnit.SECONDS));
  119 + p.addLast(new Jtt1078MessageDecoder());
  120 + // p.addLast(new Jtt808MessageEncoder());
  121 + // p.addLast(new JTT808Handler());
  122 + p.addLast(new Jtt1078Handler());
  123 + }
  124 + });
  125 +
  126 +// int historyPort = Configs.getInt("server.history.port", 30001);
  127 + Channel ch = serverBootstrap.bind(InetAddress.getByName("0.0.0.0"), port).sync().channel();
  128 +// Channel historyCh = serverBootstrap.bind(InetAddress.getByName("0.0.0.0"), historyPort).sync().channel();
  129 + logger.info("Video Server started at: {}", port);
  130 +// logger.info("Video history Server started at: {}", historyPort);
  131 + ch.closeFuture();
  132 +// historyCh.closeFuture();
  133 + }
  134 +
  135 + public void historyStart() throws Exception
  136 + {
  137 + serverBootstrap = new ServerBootstrap();
  138 + serverBootstrap.option(ChannelOption.SO_BACKLOG, Configs.getInt("server.backlog", 102400));
  139 + bossGroup = new NioEventLoopGroup(Configs.getInt("server.worker-count", Runtime.getRuntime().availableProcessors()));
  140 + workerGroup = new NioEventLoopGroup();
  141 + serverBootstrap.group(bossGroup, workerGroup)
  142 + .option(ChannelOption.SO_KEEPALIVE, true)
  143 + .channel(NioServerSocketChannel.class)
  144 + .childHandler(new ChannelInitializer<SocketChannel>() {
  145 + @Override
  146 + protected void initChannel(final SocketChannel channel) throws Exception {
  147 + ChannelPipeline p = channel.pipeline();
  148 + // p.addLast(new IdleStateHandler(10,0,0, TimeUnit.SECONDS));
  149 + p.addLast(new Jtt1078MessageDecoder());
  150 + // p.addLast(new Jtt808MessageEncoder());
  151 + // p.addLast(new JTT808Handler());
  152 + p.addLast(new Jtt1078Handler(port));
  153 + }
  154 + });
  155 + Channel ch = serverBootstrap.bind(InetAddress.getByName("0.0.0.0"), port).sync().channel();
  156 + logger.info("Video Server started at: {}", port);
  157 + ch.closeFuture();
  158 + }
  159 +
  160 + public void shutdown()
  161 + {
  162 + try
  163 + {
  164 + bossGroup.shutdownGracefully();
  165 + workerGroup.shutdownGracefully();
  166 + }
  167 + catch(Exception e)
  168 + {
  169 + e.printStackTrace();
  170 + }
  171 + }
  172 + }
  173 +
  174 + class HttpServer
  175 + {
  176 + private ServerBootstrap serverBootstrap;
  177 +
  178 + private EventLoopGroup bossGroup;
  179 + private EventLoopGroup workerGroup;
  180 +
  181 + private void start() throws Exception
  182 + {
  183 + bossGroup = new NioEventLoopGroup();
  184 + workerGroup = new NioEventLoopGroup(Runtime.getRuntime().availableProcessors());
  185 +
  186 + ServerBootstrap bootstrap = new ServerBootstrap();
  187 + bootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
  188 + .childHandler(new ChannelInitializer<SocketChannel>()
  189 + {
  190 + @Override
  191 + public void initChannel(SocketChannel ch) throws Exception
  192 + {
  193 + ch.pipeline().addLast(
  194 + new GeneralResponseWriter(),
  195 + new HttpResponseEncoder(),
  196 + new HttpRequestDecoder(),
  197 + new HttpObjectAggregator(1024 * 64),
  198 + new NettyHttpServerHandler()
  199 + );
  200 + }
  201 + }).option(ChannelOption.SO_BACKLOG, 1024)
  202 + .childOption(ChannelOption.SO_KEEPALIVE, true);
  203 + try
  204 + {
  205 + int port = Configs.getInt("server.http.port", 3333);
  206 +// int historyPort = Configs.getInt("server.history.http.port", 3334);
  207 + ChannelFuture f = bootstrap.bind(InetAddress.getByName("0.0.0.0"), port).sync();
  208 +// ChannelFuture historyF = bootstrap.bind(InetAddress.getByName("0.0.0.0"), historyPort).sync();
  209 + logger.info("HTTP Server started at: {}", port);
  210 +// logger.info("HTTP Server started at: {}", historyPort);
  211 + f.channel().closeFuture().sync();
  212 +// historyF.channel().closeFuture().sync();
  213 + }
  214 + catch (InterruptedException e)
  215 + {
  216 + logger.error("http server error", e);
  217 + }
  218 + finally
  219 + {
  220 + workerGroup.shutdownGracefully();
  221 + bossGroup.shutdownGracefully();
  222 + }
  223 + }
  224 +
  225 + private void shutdown()
  226 + {
  227 + try
  228 + {
  229 + bossGroup.shutdownGracefully();
  230 + workerGroup.shutdownGracefully();
  231 + }
  232 + catch(Exception e)
  233 + {
  234 + e.printStackTrace();
  235 + }
  236 + }
  237 + }
  238 +}
src/main/java/com/genersoft/iot/vmp/jt1078/codec/ADPCMCodec.java renamed to src/main/java/com/genersoft/iot/vmp/jtt1078/codec/ADPCMCodec.java
1 -package com.genersoft.iot.vmp.jt1078.codec; 1 +package com.genersoft.iot.vmp.jtt1078.codec;
2 2
3 -import com.genersoft.iot.vmp.jt1078.server.Jtt1078Decoder;  
4 -import com.genersoft.iot.vmp.jt1078.util.ByteHolder;  
5 -import com.genersoft.iot.vmp.jt1078.util.Packet; 3 +import com.genersoft.iot.vmp.jtt1078.server.Jtt1078Decoder;
  4 +import com.genersoft.iot.vmp.jtt1078.util.Packet;
6 5
7 import java.io.ByteArrayInputStream; 6 import java.io.ByteArrayInputStream;
8 import java.io.ByteArrayOutputStream; 7 import java.io.ByteArrayOutputStream;
9 import java.io.FileInputStream; 8 import java.io.FileInputStream;
10 import java.io.FileOutputStream; 9 import java.io.FileOutputStream;
11 -import java.util.Arrays;  
12 10
13 /** 11 /**
14 * Created by houcheng on 2019-12-05. 12 * Created by houcheng on 2019-12-05.
src/main/java/com/genersoft/iot/vmp/jt1078/codec/AudioCodec.java renamed to src/main/java/com/genersoft/iot/vmp/jtt1078/codec/AudioCodec.java
1 -package com.genersoft.iot.vmp.jt1078.codec; 1 +package com.genersoft.iot.vmp.jtt1078.codec;
2 2
3 -import com.genersoft.iot.vmp.jt1078.entity.MediaEncoding; 3 +
  4 +import com.genersoft.iot.vmp.jtt1078.entity.MediaEncoding;
4 5
5 /** 6 /**
6 * Created by houcheng on 2019-12-11. 7 * Created by houcheng on 2019-12-11.
src/main/java/com/genersoft/iot/vmp/jt1078/codec/G711Codec.java renamed to src/main/java/com/genersoft/iot/vmp/jtt1078/codec/G711Codec.java
1 -package com.genersoft.iot.vmp.jt1078.codec; 1 +package com.genersoft.iot.vmp.jtt1078.codec;
2 2
  3 +import com.genersoft.iot.vmp.jtt1078.codec.AudioCodec;
3 4
4 /** 5 /**
5 * 核心转换,PCM转G711 6 * 核心转换,PCM转G711
@@ -154,4 +155,4 @@ public class G711Codec extends AudioCodec @@ -154,4 +155,4 @@ public class G711Codec extends AudioCodec
154 public byte[] fromPCM(byte[] data) { 155 public byte[] fromPCM(byte[] data) {
155 return encode(data); 156 return encode(data);
156 } 157 }
157 -}  
158 \ No newline at end of file 158 \ No newline at end of file
  159 +}
src/main/java/com/genersoft/iot/vmp/jt1078/codec/G711UCodec.java renamed to src/main/java/com/genersoft/iot/vmp/jtt1078/codec/G711UCodec.java
1 -package com.genersoft.iot.vmp.jt1078.codec; 1 +package com.genersoft.iot.vmp.jtt1078.codec;
2 2
3 -import com.genersoft.iot.vmp.jt1078.util.ByteUtils; 3 +import com.genersoft.iot.vmp.jtt1078.util.ByteUtils;
4 4
5 import java.io.ByteArrayOutputStream; 5 import java.io.ByteArrayOutputStream;
6 import java.io.FileInputStream; 6 import java.io.FileInputStream;
src/main/java/com/genersoft/iot/vmp/jt1078/codec/G726Codec.java renamed to src/main/java/com/genersoft/iot/vmp/jtt1078/codec/G726Codec.java
1 -package com.genersoft.iot.vmp.jt1078.codec; 1 +package com.genersoft.iot.vmp.jtt1078.codec;
2 2
3 -  
4 -import com.genersoft.iot.vmp.jt1078.codec.g726.*; 3 +import com.genersoft.iot.vmp.jtt1078.codec.g726.*;
5 4
6 import java.io.FileInputStream; 5 import java.io.FileInputStream;
7 import java.io.FileOutputStream; 6 import java.io.FileOutputStream;
src/main/java/com/genersoft/iot/vmp/jt1078/codec/MP3Encoder.java renamed to src/main/java/com/genersoft/iot/vmp/jtt1078/codec/MP3Encoder.java
1 -package com.genersoft.iot.vmp.jt1078.codec; 1 +package com.genersoft.iot.vmp.jtt1078.codec;
2 2
3 import de.sciss.jump3r.lowlevel.LameEncoder; 3 import de.sciss.jump3r.lowlevel.LameEncoder;
4 import de.sciss.jump3r.mp3.Lame; 4 import de.sciss.jump3r.mp3.Lame;
src/main/java/com/genersoft/iot/vmp/jt1078/codec/SilenceCodec.java renamed to src/main/java/com/genersoft/iot/vmp/jtt1078/codec/SilenceCodec.java
1 -package com.genersoft.iot.vmp.jt1078.codec;  
2 -  
3 -import java.util.Arrays; 1 +package com.genersoft.iot.vmp.jtt1078.codec;
4 2
5 /** 3 /**
6 * Created by houcheng on 2019-12-11. 4 * Created by houcheng on 2019-12-11.
src/main/java/com/genersoft/iot/vmp/jt1078/codec/g726/G726.java renamed to src/main/java/com/genersoft/iot/vmp/jtt1078/codec/g726/G726.java
1 1
2 -package com.genersoft.iot.vmp.jt1078.codec.g726; 2 +package com.genersoft.iot.vmp.jtt1078.codec.g726;
3 3
4 4
5 -import com.genersoft.iot.vmp.jt1078.codec.G711Codec;  
6 -import com.genersoft.iot.vmp.jt1078.codec.G711UCodec; 5 +import com.genersoft.iot.vmp.jtt1078.codec.G711Codec;
  6 +import com.genersoft.iot.vmp.jtt1078.codec.G711UCodec;
7 7
8 /** Common routines for G.721 and G.723 conversions. 8 /** Common routines for G.721 and G.723 conversions.
9 * <p> 9 * <p>
@@ -15,7 +15,7 @@ import com.genersoft.iot.vmp.jt1078.codec.G711UCodec; @@ -15,7 +15,7 @@ import com.genersoft.iot.vmp.jt1078.codec.G711UCodec;
15 * ANSI-C source code to the public domain. 15 * ANSI-C source code to the public domain.
16 */ 16 */
17 public abstract class G726 { 17 public abstract class G726 {
18 - 18 +
19 // ##### C-to-Java conversion: ##### 19 // ##### C-to-Java conversion: #####
20 // short becomes int 20 // short becomes int
21 // char becomes int 21 // char becomes int
@@ -26,10 +26,10 @@ public abstract class G726 { @@ -26,10 +26,10 @@ public abstract class G726 {
26 26
27 /** ISDN u-law */ 27 /** ISDN u-law */
28 public static final int AUDIO_ENCODING_ULAW=1; 28 public static final int AUDIO_ENCODING_ULAW=1;
29 - 29 +
30 /** ISDN A-law */ 30 /** ISDN A-law */
31 public static final int AUDIO_ENCODING_ALAW=2; 31 public static final int AUDIO_ENCODING_ALAW=2;
32 - 32 +
33 /** PCM 2's-complement (0-center) */ 33 /** PCM 2's-complement (0-center) */
34 public static final int AUDIO_ENCODING_LINEAR=3; 34 public static final int AUDIO_ENCODING_LINEAR=3;
35 35
@@ -44,7 +44,7 @@ public abstract class G726 { @@ -44,7 +44,7 @@ public abstract class G726 {
44 * <p> 44 * <p>
45 * Using linear search for simple coding. */ 45 * Using linear search for simple coding. */
46 private static int quan(int val, /*short*/int[] table, int size) { 46 private static int quan(int val, /*short*/int[] table, int size) {
47 - 47 +
48 int i; 48 int i;
49 for (i=0; i<size; i++) if (val<table[i]) break; 49 for (i=0; i<size; i++) if (val<table[i]) break;
50 return i; 50 return i;
@@ -63,24 +63,24 @@ public abstract class G726 { @@ -63,24 +63,24 @@ public abstract class G726 {
63 * @param size - Table size of short integers 63 * @param size - Table size of short integers
64 */ 64 */
65 protected static int quantize(int d, int y, /*short*/int[] table, int size) { 65 protected static int quantize(int d, int y, /*short*/int[] table, int size) {
66 - 66 +
67 /* LOG 67 /* LOG
68 * Compute base 2 log of 'd', and store in 'dl'. 68 * Compute base 2 log of 'd', and store in 'dl'.
69 */ 69 */
70 /*short*/int dqm=Math.abs(d); /* Magnitude of 'd' */ 70 /*short*/int dqm=Math.abs(d); /* Magnitude of 'd' */
71 - 71 +
72 /*short*/int exp=quan(dqm>>1, power2, 15); /* Integer part of base 2 log of 'd' */ 72 /*short*/int exp=quan(dqm>>1, power2, 15); /* Integer part of base 2 log of 'd' */
73 - 73 +
74 /*short*/int mant=((dqm<<7)>>exp)&0x7F; /* Fractional part of base 2 log */ 74 /*short*/int mant=((dqm<<7)>>exp)&0x7F; /* Fractional part of base 2 log */
75 - 75 +
76 /*short*/int dl=(exp<<7)+mant; /* Log of magnitude of 'd' */ 76 /*short*/int dl=(exp<<7)+mant; /* Log of magnitude of 'd' */
77 - 77 +
78 /* SUBTB 78 /* SUBTB
79 * "Divide" by step size multiplier. 79 * "Divide" by step size multiplier.
80 */ 80 */
81 /* Step size scale factor normalized log */ 81 /* Step size scale factor normalized log */
82 /*short*/int dln=dl-(y>>2); 82 /*short*/int dln=dl-(y>>2);
83 - 83 +
84 /* QUAN 84 /* QUAN
85 * Obtain codword i for 'd'. 85 * Obtain codword i for 'd'.
86 */ 86 */
@@ -102,10 +102,10 @@ public abstract class G726 { @@ -102,10 +102,10 @@ public abstract class G726 {
102 * @param y - Step size multiplier 102 * @param y - Step size multiplier
103 */ 103 */
104 protected static int reconstruct(int sign, int dqln, int y) { 104 protected static int reconstruct(int sign, int dqln, int y) {
105 - 105 +
106 /* Log of 'dq' magnitude */ 106 /* Log of 'dq' magnitude */
107 /*short*/int dql=dqln+(y>>2); /* ADDA */ 107 /*short*/int dql=dqln+(y>>2); /* ADDA */
108 - 108 +
109 if (dql<0) { 109 if (dql<0) {
110 return ((sign!=0)? -0x8000 : 0); 110 return ((sign!=0)? -0x8000 : 0);
111 } 111 }
@@ -119,8 +119,8 @@ public abstract class G726 { @@ -119,8 +119,8 @@ public abstract class G726 {
119 return ((sign!=0)? (dq-0x8000) : dq); 119 return ((sign!=0)? (dq-0x8000) : dq);
120 } 120 }
121 } 121 }
122 -  
123 - 122 +
  123 +
124 /** updates the state variables for each output code 124 /** updates the state variables for each output code
125 * @param code_size - distinguish 723_40 with others 125 * @param code_size - distinguish 723_40 with others
126 * @param y - quantizer step size 126 * @param y - quantizer step size
@@ -132,7 +132,7 @@ public abstract class G726 { @@ -132,7 +132,7 @@ public abstract class G726 {
132 * @param state - coder state 132 * @param state - coder state
133 */ 133 */
134 protected static void update(int code_size, int y, int wi, int fi, int dq, int sr, int dqsez, G726State state) { 134 protected static void update(int code_size, int y, int wi, int fi, int dq, int sr, int dqsez, G726State state) {
135 - 135 +
136 int cnt; 136 int cnt;
137 /*short*/int mag, exp, mant; /* Adaptive predictor, FLOAT A */ 137 /*short*/int mag, exp, mant; /* Adaptive predictor, FLOAT A */
138 /*short*/int a2p; /* LIMC */ 138 /*short*/int a2p; /* LIMC */
@@ -144,13 +144,13 @@ public abstract class G726 { @@ -144,13 +144,13 @@ public abstract class G726 {
144 /*short*/int ylint, thr2, dqthr; 144 /*short*/int ylint, thr2, dqthr;
145 /*short*/int ylfrac, thr1; 145 /*short*/int ylfrac, thr1;
146 /*short*/int pk0; 146 /*short*/int pk0;
147 - 147 +
148 // ##### C-to-Java conversion: ##### 148 // ##### C-to-Java conversion: #####
149 // init a2p 149 // init a2p
150 - a2p=0;  
151 - 150 + a2p=0;
  151 +
152 pk0=(dqsez<0)? 1 : 0; /* needed in updating predictor poles */ 152 pk0=(dqsez<0)? 1 : 0; /* needed in updating predictor poles */
153 - 153 +
154 mag=dq&0x7FFF; /* prediction difference magnitude */ 154 mag=dq&0x7FFF; /* prediction difference magnitude */
155 /* TRANS */ 155 /* TRANS */
156 ylint=state.yl>>15; /* exponent part of yl */ 156 ylint=state.yl>>15; /* exponent part of yl */
@@ -165,24 +165,24 @@ public abstract class G726 { @@ -165,24 +165,24 @@ public abstract class G726 {
165 tr=0; /* treated as voice */ 165 tr=0; /* treated as voice */
166 else /* signal is data (modem) */ 166 else /* signal is data (modem) */
167 tr=1; 167 tr=1;
168 - 168 +
169 /* Quantizer scale factor adaptation. */ 169 /* Quantizer scale factor adaptation. */
170 - 170 +
171 /* FUNCTW&FILTD&DELAY */ 171 /* FUNCTW&FILTD&DELAY */
172 /* update non-steady state step size multiplier */ 172 /* update non-steady state step size multiplier */
173 state.yu=y+((wi-y)>>5); 173 state.yu=y+((wi-y)>>5);
174 - 174 +
175 /* LIMB */ 175 /* LIMB */
176 if (state.yu<544) /* 544<=yu<=5120 */ 176 if (state.yu<544) /* 544<=yu<=5120 */
177 state.yu=544; 177 state.yu=544;
178 else 178 else
179 if (state.yu>5120) 179 if (state.yu>5120)
180 state.yu=5120; 180 state.yu=5120;
181 - 181 +
182 /* FILTE&DELAY */ 182 /* FILTE&DELAY */
183 /* update steady state step size multiplier */ 183 /* update steady state step size multiplier */
184 state.yl+=state.yu+((-state.yl)>>6); 184 state.yl+=state.yu+((-state.yl)>>6);
185 - 185 +
186 /* 186 /*
187 * Adaptive predictor coefficients. 187 * Adaptive predictor coefficients.
188 */ 188 */
@@ -200,7 +200,7 @@ public abstract class G726 { @@ -200,7 +200,7 @@ public abstract class G726 {
200 else { 200 else {
201 /* update a's and b's */ 201 /* update a's and b's */
202 pks1=pk0^state.pk[0]; /* UPA2 */ 202 pks1=pk0^state.pk[0]; /* UPA2 */
203 - 203 +
204 /* update predictor pole a[1] */ 204 /* update predictor pole a[1] */
205 a2p=state.a[1]-(state.a[1]>>7); 205 a2p=state.a[1]-(state.a[1]>>7);
206 if (dqsez != 0) { 206 if (dqsez != 0) {
@@ -212,7 +212,7 @@ public abstract class G726 { @@ -212,7 +212,7 @@ public abstract class G726 {
212 a2p+=0xFF; 212 a2p+=0xFF;
213 else 213 else
214 a2p+=fa1>>5; 214 a2p+=fa1>>5;
215 - 215 +
216 if ((pk0^state.pk[1])!=0) { 216 if ((pk0^state.pk[1])!=0) {
217 /* LIMC */ 217 /* LIMC */
218 if (a2p<=-12160) 218 if (a2p<=-12160)
@@ -232,10 +232,10 @@ public abstract class G726 { @@ -232,10 +232,10 @@ public abstract class G726 {
232 else 232 else
233 a2p+=0x80; 233 a2p+=0x80;
234 } 234 }
235 - 235 +
236 /* TRIGB&DELAY */ 236 /* TRIGB&DELAY */
237 state.a[1]=a2p; 237 state.a[1]=a2p;
238 - 238 +
239 /* UPA1 */ 239 /* UPA1 */
240 /* update predictor pole a[0] */ 240 /* update predictor pole a[0] */
241 state.a[0] -= state.a[0]>>8; 241 state.a[0] -= state.a[0]>>8;
@@ -244,17 +244,17 @@ public abstract class G726 { @@ -244,17 +244,17 @@ public abstract class G726 {
244 state.a[0]+=192; 244 state.a[0]+=192;
245 else 245 else
246 state.a[0] -= 192; 246 state.a[0] -= 192;
247 - 247 +
248 /* LIMD */ 248 /* LIMD */
249 a1ul=15360-a2p; 249 a1ul=15360-a2p;
250 if (state.a[0]<-a1ul) 250 if (state.a[0]<-a1ul)
251 state.a[0]=-a1ul; 251 state.a[0]=-a1ul;
252 else if (state.a[0]>a1ul) 252 else if (state.a[0]>a1ul)
253 state.a[0]=a1ul; 253 state.a[0]=a1ul;
254 - 254 +
255 /* UPB : update predictor zeros b[6] */ 255 /* UPB : update predictor zeros b[6] */
256 for (cnt=0; cnt<6; cnt++) { 256 for (cnt=0; cnt<6; cnt++) {
257 - 257 +
258 if (code_size==5) /* for 40Kbps G.723 */ 258 if (code_size==5) /* for 40Kbps G.723 */
259 state.b[cnt]-=state.b[cnt]>>9; 259 state.b[cnt]-=state.b[cnt]>>9;
260 else /* for G.721 and 24Kbps G.723 */ 260 else /* for G.721 and 24Kbps G.723 */
@@ -268,7 +268,7 @@ public abstract class G726 { @@ -268,7 +268,7 @@ public abstract class G726 {
268 } 268 }
269 } 269 }
270 } 270 }
271 - 271 +
272 for (cnt=5; cnt>0; cnt--) state.dq[cnt]=state.dq[cnt-1]; 272 for (cnt=5; cnt>0; cnt--) state.dq[cnt]=state.dq[cnt-1];
273 /* FLOAT A : convert dq[0] to 4-bit exp, 6-bit mantissa f.p. */ 273 /* FLOAT A : convert dq[0] to 4-bit exp, 6-bit mantissa f.p. */
274 if (mag==0) { 274 if (mag==0) {
@@ -278,7 +278,7 @@ public abstract class G726 { @@ -278,7 +278,7 @@ public abstract class G726 {
278 exp=quan(mag, power2, 15); 278 exp=quan(mag, power2, 15);
279 state.dq[0]=(dq>=0) ? (exp<<6)+((mag<<6)>>exp) : (exp<<6)+((mag<<6)>>exp)-0x400; 279 state.dq[0]=(dq>=0) ? (exp<<6)+((mag<<6)>>exp) : (exp<<6)+((mag<<6)>>exp)-0x400;
280 } 280 }
281 - 281 +
282 state.sr[1]=state.sr[0]; 282 state.sr[1]=state.sr[0];
283 /* FLOAT B : convert sr to 4-bit exp., 6-bit mantissa f.p. */ 283 /* FLOAT B : convert sr to 4-bit exp., 6-bit mantissa f.p. */
284 if (sr==0) { 284 if (sr==0) {
@@ -297,11 +297,11 @@ public abstract class G726 { @@ -297,11 +297,11 @@ public abstract class G726 {
297 } 297 }
298 else 298 else
299 state.sr[0]=0xFC20; 299 state.sr[0]=0xFC20;
300 - 300 +
301 /* DELAY A */ 301 /* DELAY A */
302 state.pk[1]=state.pk[0]; 302 state.pk[1]=state.pk[0];
303 state.pk[0]=pk0; 303 state.pk[0]=pk0;
304 - 304 +
305 /* TONE */ 305 /* TONE */
306 if (tr==1) /* this sample has been treated as data */ 306 if (tr==1) /* this sample has been treated as data */
307 state.td=0; /* next one will be treated as voice */ 307 state.td=0; /* next one will be treated as voice */
@@ -310,13 +310,13 @@ public abstract class G726 { @@ -310,13 +310,13 @@ public abstract class G726 {
310 state.td=1; /* signal may be data */ 310 state.td=1; /* signal may be data */
311 else /* signal is voice */ 311 else /* signal is voice */
312 state.td=0; 312 state.td=0;
313 - 313 +
314 /* 314 /*
315 * Adaptation speed control. 315 * Adaptation speed control.
316 */ 316 */
317 state.dms+=(fi-state.dms)>>5; /* FILTA */ 317 state.dms+=(fi-state.dms)>>5; /* FILTA */
318 state.dml+=(((fi<<2)-state.dml)>>7); /* FILTB */ 318 state.dml+=(((fi<<2)-state.dml)>>7); /* FILTB */
319 - 319 +
320 if (tr==1) 320 if (tr==1)
321 state.ap=256; 321 state.ap=256;
322 else 322 else
@@ -331,7 +331,7 @@ public abstract class G726 { @@ -331,7 +331,7 @@ public abstract class G726 {
331 else 331 else
332 state.ap+=(-state.ap)>>4; 332 state.ap+=(-state.ap)>>4;
333 } 333 }
334 - 334 +
335 /** At the end of ADPCM decoding, it simulates an encoder which may be receiving 335 /** At the end of ADPCM decoding, it simulates an encoder which may be receiving
336 * the output of this decoder as a tandem process. If the output of the 336 * the output of this decoder as a tandem process. If the output of the
337 * simulated encoder differs from the input to this decoder, the decoder output 337 * simulated encoder differs from the input to this decoder, the decoder output
@@ -346,19 +346,19 @@ public abstract class G726 { @@ -346,19 +346,19 @@ public abstract class G726 {
346 * @return adjusted A-law or u-law compressed sample. 346 * @return adjusted A-law or u-law compressed sample.
347 */ 347 */
348 protected static int tandem_adjust_alaw(int sr, int se, int y, int i, int sign, /*short*/int[] qtab) { 348 protected static int tandem_adjust_alaw(int sr, int se, int y, int i, int sign, /*short*/int[] qtab) {
349 - 349 +
350 /*unsigned char*/int sp; /* A-law compressed 8-bit code */ 350 /*unsigned char*/int sp; /* A-law compressed 8-bit code */
351 /*short*/int dx; /* prediction error */ 351 /*short*/int dx; /* prediction error */
352 /*char*/int id; /* quantized prediction error */ 352 /*char*/int id; /* quantized prediction error */
353 int sd; /* adjusted A-law decoded sample value */ 353 int sd; /* adjusted A-law decoded sample value */
354 int im; /* biased magnitude of i */ 354 int im; /* biased magnitude of i */
355 int imx; /* biased magnitude of id */ 355 int imx; /* biased magnitude of id */
356 - 356 +
357 if (sr<=-32768) sr=-1; 357 if (sr<=-32768) sr=-1;
358 sp= G711Codec.linear2alaw((short)((sr>>1)<<3)); /* short to A-law compression */ 358 sp= G711Codec.linear2alaw((short)((sr>>1)<<3)); /* short to A-law compression */
359 dx=(G711Codec.alaw2linear((byte)sp)>>2)-se; /* 16-bit prediction error */ 359 dx=(G711Codec.alaw2linear((byte)sp)>>2)-se; /* 16-bit prediction error */
360 id=quantize(dx, y, qtab, sign-1); 360 id=quantize(dx, y, qtab, sign-1);
361 - 361 +
362 if (id==i) { 362 if (id==i) {
363 /* no adjustment on sp */ 363 /* no adjustment on sp */
364 return (sp); 364 return (sp);
@@ -368,12 +368,12 @@ public abstract class G726 { @@ -368,12 +368,12 @@ public abstract class G726 {
368 /* ADPCM codes : 8, 9, ... F, 0, 1, ... , 6, 7 */ 368 /* ADPCM codes : 8, 9, ... F, 0, 1, ... , 6, 7 */
369 im=i^sign; /* 2's complement to biased unsigned */ 369 im=i^sign; /* 2's complement to biased unsigned */
370 imx=id^sign; 370 imx=id^sign;
371 - 371 +
372 if (imx>im) { 372 if (imx>im) {
373 /* sp adjusted to next lower value */ 373 /* sp adjusted to next lower value */
374 if ((sp&0x80)!=0) { 374 if ((sp&0x80)!=0) {
375 sd=(sp==0xD5)? 0x55 : ((sp^0x55)-1)^0x55; 375 sd=(sp==0xD5)? 0x55 : ((sp^0x55)-1)^0x55;
376 - } 376 + }
377 else { 377 else {
378 sd=(sp==0x2A)? 0x2A : ((sp^0x55)+1)^0x55; 378 sd=(sp==0x2A)? 0x2A : ((sp^0x55)+1)^0x55;
379 } 379 }
@@ -388,7 +388,7 @@ public abstract class G726 { @@ -388,7 +388,7 @@ public abstract class G726 {
388 return (sd); 388 return (sd);
389 } 389 }
390 } 390 }
391 - 391 +
392 /** @param sr - decoder output linear PCM sample 392 /** @param sr - decoder output linear PCM sample
393 * @param se - predictor estimate sample 393 * @param se - predictor estimate sample
394 * @param y - quantizer step size 394 * @param y - quantizer step size
@@ -397,21 +397,21 @@ public abstract class G726 { @@ -397,21 +397,21 @@ public abstract class G726 {
397 * @param qtab 397 * @param qtab
398 */ 398 */
399 protected static int tandem_adjust_ulaw(int sr, int se, int y, int i, int sign, /*short*/int[] qtab) { 399 protected static int tandem_adjust_ulaw(int sr, int se, int y, int i, int sign, /*short*/int[] qtab) {
400 - 400 +
401 /*unsigned char*/int sp; /* u-law compressed 8-bit code */ 401 /*unsigned char*/int sp; /* u-law compressed 8-bit code */
402 /*short*/int dx; /* prediction error */ 402 /*short*/int dx; /* prediction error */
403 /*char*/int id; /* quantized prediction error */ 403 /*char*/int id; /* quantized prediction error */
404 int sd; /* adjusted u-law decoded sample value */ 404 int sd; /* adjusted u-law decoded sample value */
405 int im; /* biased magnitude of i */ 405 int im; /* biased magnitude of i */
406 int imx; /* biased magnitude of id */ 406 int imx; /* biased magnitude of id */
407 - 407 +
408 if (sr<=-32768) sr=0; 408 if (sr<=-32768) sr=0;
409 sp= G711UCodec.linear2ulaw((short)(sr<<2)); /* short to u-law compression */ 409 sp= G711UCodec.linear2ulaw((short)(sr<<2)); /* short to u-law compression */
410 dx=(G711UCodec.ulaw2linear((byte)sp)>>2)-se; /* 16-bit prediction error */ 410 dx=(G711UCodec.ulaw2linear((byte)sp)>>2)-se; /* 16-bit prediction error */
411 id=quantize(dx, y, qtab, sign-1); 411 id=quantize(dx, y, qtab, sign-1);
412 if (id==i) { 412 if (id==i) {
413 return (sp); 413 return (sp);
414 - } 414 + }
415 else { 415 else {
416 /* ADPCM codes : 8, 9, ... F, 0, 1, ... , 6, 7 */ 416 /* ADPCM codes : 8, 9, ... F, 0, 1, ... , 6, 7 */
417 im=i^sign; /* 2's complement to biased unsigned */ 417 im=i^sign; /* 2's complement to biased unsigned */
@@ -422,7 +422,7 @@ public abstract class G726 { @@ -422,7 +422,7 @@ public abstract class G726 {
422 sd=(sp==0xFF)? 0x7E : sp+1; 422 sd=(sp==0xFF)? 0x7E : sp+1;
423 else 423 else
424 sd=(sp==0)? 0 : sp-1; 424 sd=(sp==0)? 0 : sp-1;
425 - 425 +
426 } 426 }
427 else { 427 else {
428 /* sp adjusted to next higher value */ 428 /* sp adjusted to next higher value */
@@ -437,7 +437,7 @@ public abstract class G726 { @@ -437,7 +437,7 @@ public abstract class G726 {
437 437
438 438
439 // ##### C-to-Java conversion: ##### 439 // ##### C-to-Java conversion: #####
440 - 440 +
441 /** Converts a byte into an unsigned int. */ 441 /** Converts a byte into an unsigned int. */
442 protected static int unsignedInt(byte b) { 442 protected static int unsignedInt(byte b) {
443 return ((int)b+0x100)&0xFF; 443 return ((int)b+0x100)&0xFF;
@@ -477,7 +477,7 @@ public abstract class G726 { @@ -477,7 +477,7 @@ public abstract class G726 {
477 /** Encodes the input vale of linear PCM, A-law or u-law data sl and returns 477 /** Encodes the input vale of linear PCM, A-law or u-law data sl and returns
478 * the resulting code. -1 is returned for unknown input coding value. */ 478 * the resulting code. -1 is returned for unknown input coding value. */
479 public abstract int encode(int sl, int in_coding); 479 public abstract int encode(int sl, int in_coding);
480 - 480 +
481 481
482 /** Encodes the input chunk in_buff of linear PCM, A-law or u-law data and returns 482 /** Encodes the input chunk in_buff of linear PCM, A-law or u-law data and returns
483 * the G726 encoded chuck into out_buff. <br> 483 * the G726 encoded chuck into out_buff. <br>
@@ -498,4 +498,4 @@ public abstract class G726 { @@ -498,4 +498,4 @@ public abstract class G726 {
498 * out_coding value. */ 498 * out_coding value. */
499 public abstract int decode(byte[] in_buff, int in_offset, int in_len, int out_coding, byte[] out_buff, int out_offset); 499 public abstract int decode(byte[] in_buff, int in_offset, int in_len, int out_coding, byte[] out_buff, int out_offset);
500 500
501 -}  
502 \ No newline at end of file 501 \ No newline at end of file
  502 +}
src/main/java/com/genersoft/iot/vmp/jt1078/codec/g726/G726State.java renamed to src/main/java/com/genersoft/iot/vmp/jtt1078/codec/g726/G726State.java
1 -package com.genersoft.iot.vmp.jt1078.codec.g726; 1 +package com.genersoft.iot.vmp.jtt1078.codec.g726;
2 2
3 public class G726State { 3 public class G726State {
4 4
src/main/java/com/genersoft/iot/vmp/jt1078/codec/g726/G726_16.java renamed to src/main/java/com/genersoft/iot/vmp/jtt1078/codec/g726/G726_16.java
1 -package com.genersoft.iot.vmp.jt1078.codec.g726; 1 +package com.genersoft.iot.vmp.jtt1078.codec.g726;
2 2
3 -  
4 -import com.genersoft.iot.vmp.jt1078.codec.G711Codec;  
5 -import com.genersoft.iot.vmp.jt1078.codec.G711UCodec; 3 +import com.genersoft.iot.vmp.jtt1078.codec.G711Codec;
  4 +import com.genersoft.iot.vmp.jtt1078.codec.G711UCodec;
6 5
7 /** G726_16 encoder and decoder. 6 /** G726_16 encoder and decoder.
8 * <p> 7 * <p>
src/main/java/com/genersoft/iot/vmp/jt1078/codec/g726/G726_24.java renamed to src/main/java/com/genersoft/iot/vmp/jtt1078/codec/g726/G726_24.java
1 -package com.genersoft.iot.vmp.jt1078.codec.g726; 1 +package com.genersoft.iot.vmp.jtt1078.codec.g726;
2 2
3 -  
4 -import com.genersoft.iot.vmp.jt1078.codec.G711Codec;  
5 -import com.genersoft.iot.vmp.jt1078.codec.G711UCodec; 3 +import com.genersoft.iot.vmp.jtt1078.codec.G711Codec;
  4 +import com.genersoft.iot.vmp.jtt1078.codec.G711UCodec;
6 5
7 /** G726_24 encoder and decoder. 6 /** G726_24 encoder and decoder.
8 * <p> 7 * <p>
@@ -19,7 +18,7 @@ import com.genersoft.iot.vmp.jt1078.codec.G711UCodec; @@ -19,7 +18,7 @@ import com.genersoft.iot.vmp.jt1078.codec.G711UCodec;
19 * ANSI-C source code to the public domain. 18 * ANSI-C source code to the public domain.
20 */ 19 */
21 public class G726_24 extends G726 { 20 public class G726_24 extends G726 {
22 - 21 +
23 // ##### C-to-Java conversion: ##### 22 // ##### C-to-Java conversion: #####
24 // short becomes int 23 // short becomes int
25 // char becomes int 24 // char becomes int
@@ -33,30 +32,30 @@ public class G726_24 extends G726 { @@ -33,30 +32,30 @@ public class G726_24 extends G726 {
33 * magnitude values. 32 * magnitude values.
34 */ 33 */
35 static /*short*/int[] _dqlntab={-2048, 135, 273, 373, 373, 273, 135, -2048}; 34 static /*short*/int[] _dqlntab={-2048, 135, 273, 373, 373, 273, 135, -2048};
36 - 35 +
37 /* Maps G726_24 code word to log of scale factor multiplier. */ 36 /* Maps G726_24 code word to log of scale factor multiplier. */
38 static /*short*/int[] _witab={-128, 960, 4384, 18624, 18624, 4384, 960, -128}; 37 static /*short*/int[] _witab={-128, 960, 4384, 18624, 18624, 4384, 960, -128};
39 - 38 +
40 /* 39 /*
41 * Maps G726_24 code words to a set of values whose long and short 40 * Maps G726_24 code words to a set of values whose long and short
42 * term averages are computed and then compared to give an indication 41 * term averages are computed and then compared to give an indication
43 * how stationary (steady state) the signal is. 42 * how stationary (steady state) the signal is.
44 */ 43 */
45 static /*short*/int[] _fitab={0, 0x200, 0x400, 0xE00, 0xE00, 0x400, 0x200, 0}; 44 static /*short*/int[] _fitab={0, 0x200, 0x400, 0xE00, 0xE00, 0x400, 0x200, 0};
46 - 45 +
47 static /*short*/int[] qtab_723_24={8, 218, 331}; 46 static /*short*/int[] qtab_723_24={8, 218, 331};
48 - 47 +
49 /** Encodes a linear PCM, A-law or u-law input sample and returns its 3-bit code. 48 /** Encodes a linear PCM, A-law or u-law input sample and returns its 3-bit code.
50 * Returns -1 if invalid input coding value. */ 49 * Returns -1 if invalid input coding value. */
51 public static int encode(int sl, int in_coding, G726State state) { 50 public static int encode(int sl, int in_coding, G726State state) {
52 - 51 +
53 /*short*/int sei, sezi, se, sez; /* ACCUM */ 52 /*short*/int sei, sezi, se, sez; /* ACCUM */
54 /*short*/int d; /* SUBTA */ 53 /*short*/int d; /* SUBTA */
55 /*short*/int y; /* MIX */ 54 /*short*/int y; /* MIX */
56 /*short*/int sr; /* ADDB */ 55 /*short*/int sr; /* ADDB */
57 /*short*/int dqsez; /* ADDC */ 56 /*short*/int dqsez; /* ADDC */
58 /*short*/int dq, i; 57 /*short*/int dq, i;
59 - 58 +
60 switch (in_coding) { 59 switch (in_coding) {
61 /* linearize input sample to 14-bit PCM */ 60 /* linearize input sample to 14-bit PCM */
62 case AUDIO_ENCODING_ALAW: 61 case AUDIO_ENCODING_ALAW:
@@ -71,57 +70,57 @@ public class G726_24 extends G726 { @@ -71,57 +70,57 @@ public class G726_24 extends G726 {
71 default: 70 default:
72 return (-1); 71 return (-1);
73 } 72 }
74 - 73 +
75 sezi=state.predictor_zero(); 74 sezi=state.predictor_zero();
76 sez=sezi >> 1; 75 sez=sezi >> 1;
77 sei=sezi+state.predictor_pole(); 76 sei=sezi+state.predictor_pole();
78 se=sei >> 1; /* se=estimated signal */ 77 se=sei >> 1; /* se=estimated signal */
79 - 78 +
80 d=sl-se; /* d=estimation diff. */ 79 d=sl-se; /* d=estimation diff. */
81 - 80 +
82 /* quantize prediction difference d */ 81 /* quantize prediction difference d */
83 y=state.step_size(); /* quantizer step size */ 82 y=state.step_size(); /* quantizer step size */
84 i=quantize(d, y, qtab_723_24, 3); /* i=ADPCM code */ 83 i=quantize(d, y, qtab_723_24, 3); /* i=ADPCM code */
85 dq=reconstruct(i & 4, _dqlntab[i], y); /* quantized diff. */ 84 dq=reconstruct(i & 4, _dqlntab[i], y); /* quantized diff. */
86 - 85 +
87 sr=(dq<0)? se-(dq & 0x3FFF) : se+dq; /* reconstructed signal */ 86 sr=(dq<0)? se-(dq & 0x3FFF) : se+dq; /* reconstructed signal */
88 - 87 +
89 dqsez=sr+sez-se; /* pole prediction diff. */ 88 dqsez=sr+sez-se; /* pole prediction diff. */
90 - 89 +
91 update(3, y, _witab[i], _fitab[i], dq, sr, dqsez, state); 90 update(3, y, _witab[i], _fitab[i], dq, sr, dqsez, state);
92 - 91 +
93 return (i); 92 return (i);
94 } 93 }
95 - 94 +
96 95
97 /** Decodes a 3-bit CCITT G.726 24kbps ADPCM code and returns 96 /** Decodes a 3-bit CCITT G.726 24kbps ADPCM code and returns
98 * the resulting 16-bit linear PCM, A-law or u-law sample value. 97 * the resulting 16-bit linear PCM, A-law or u-law sample value.
99 * -1 is returned if the output coding is unknown. */ 98 * -1 is returned if the output coding is unknown. */
100 public static int decode(int i, int out_coding, G726State state) { 99 public static int decode(int i, int out_coding, G726State state) {
101 - 100 +
102 /*short*/int sezi, sei, sez, se; /* ACCUM */ 101 /*short*/int sezi, sei, sez, se; /* ACCUM */
103 /*short*/int y; /* MIX */ 102 /*short*/int y; /* MIX */
104 /*short*/int sr; /* ADDB */ 103 /*short*/int sr; /* ADDB */
105 /*short*/int dq; 104 /*short*/int dq;
106 /*short*/int dqsez; 105 /*short*/int dqsez;
107 - 106 +
108 i &= 0x07; /* mask to get proper bits */ 107 i &= 0x07; /* mask to get proper bits */
109 sezi=state.predictor_zero(); 108 sezi=state.predictor_zero();
110 sez=sezi >> 1; 109 sez=sezi >> 1;
111 sei=sezi+state.predictor_pole(); 110 sei=sezi+state.predictor_pole();
112 se=sei >> 1; /* se=estimated signal */ 111 se=sei >> 1; /* se=estimated signal */
113 - 112 +
114 y=state.step_size(); /* adaptive quantizer step size */ 113 y=state.step_size(); /* adaptive quantizer step size */
115 dq=reconstruct(i & 0x04, _dqlntab[i], y); /* unquantize pred diff */ 114 dq=reconstruct(i & 0x04, _dqlntab[i], y); /* unquantize pred diff */
116 - 115 +
117 sr=(dq<0)? (se-(dq & 0x3FFF)) : (se+dq); /* reconst. signal */ 116 sr=(dq<0)? (se-(dq & 0x3FFF)) : (se+dq); /* reconst. signal */
118 - 117 +
119 dqsez=sr-se+sez; /* pole prediction diff. */ 118 dqsez=sr-se+sez; /* pole prediction diff. */
120 - 119 +
121 update(3, y, _witab[i], _fitab[i], dq, sr, dqsez, state); 120 update(3, y, _witab[i], _fitab[i], dq, sr, dqsez, state);
122 - 121 +
123 switch (out_coding) { 122 switch (out_coding) {
124 - 123 +
125 case AUDIO_ENCODING_ALAW: 124 case AUDIO_ENCODING_ALAW:
126 return (tandem_adjust_alaw(sr, se, y, i, 4, qtab_723_24)); 125 return (tandem_adjust_alaw(sr, se, y, i, 4, qtab_723_24));
127 case AUDIO_ENCODING_ULAW: 126 case AUDIO_ENCODING_ULAW:
@@ -139,9 +138,9 @@ public class G726_24 extends G726 { @@ -139,9 +138,9 @@ public class G726_24 extends G726 {
139 * It returns the actual size of the output data, or -1 in case of unknown 138 * It returns the actual size of the output data, or -1 in case of unknown
140 * in_coding value. */ 139 * in_coding value. */
141 public static int encode(byte[] in_buff, int in_offset, int in_len, int in_coding, byte[] out_buff, int out_offset, G726State state) { 140 public static int encode(byte[] in_buff, int in_offset, int in_len, int in_coding, byte[] out_buff, int out_offset, G726State state) {
142 - 141 +
143 if (in_coding==AUDIO_ENCODING_ALAW || in_coding==AUDIO_ENCODING_ULAW) { 142 if (in_coding==AUDIO_ENCODING_ALAW || in_coding==AUDIO_ENCODING_ULAW) {
144 - 143 +
145 int len_div_8=in_len/8; 144 int len_div_8=in_len/8;
146 for (int i=0; i<len_div_8; i++) { 145 for (int i=0; i<len_div_8; i++) {
147 int value8=0; 146 int value8=0;
@@ -160,7 +159,7 @@ public class G726_24 extends G726 { @@ -160,7 +159,7 @@ public class G726_24 extends G726 {
160 } 159 }
161 else 160 else
162 if (in_coding==AUDIO_ENCODING_LINEAR) { 161 if (in_coding==AUDIO_ENCODING_LINEAR) {
163 - 162 +
164 int len_div_16=in_len/16; 163 int len_div_16=in_len/16;
165 for (int i=0; i<len_div_16; i++) { 164 for (int i=0; i<len_div_16; i++) {
166 int value16=0; 165 int value16=0;
@@ -188,9 +187,9 @@ public class G726_24 extends G726 { @@ -188,9 +187,9 @@ public class G726_24 extends G726 {
188 * It returns the actual size of the output data, or -1 in case of unknown 187 * It returns the actual size of the output data, or -1 in case of unknown
189 * out_coding value. */ 188 * out_coding value. */
190 public static int decode(byte[] in_buff, int in_offset, int in_len, int out_coding, byte[] out_buff, int out_offset, G726State state) { 189 public static int decode(byte[] in_buff, int in_offset, int in_len, int out_coding, byte[] out_buff, int out_offset, G726State state) {
191 - 190 +
192 if (out_coding==AUDIO_ENCODING_ALAW || out_coding==AUDIO_ENCODING_ULAW) { 191 if (out_coding==AUDIO_ENCODING_ALAW || out_coding==AUDIO_ENCODING_ULAW) {
193 - 192 +
194 int len_div_3=in_len/3; 193 int len_div_3=in_len/3;
195 for (int i=0; i<len_div_3; i++) { 194 for (int i=0; i<len_div_3; i++) {
196 int value8=0; 195 int value8=0;
@@ -209,7 +208,7 @@ public class G726_24 extends G726 { @@ -209,7 +208,7 @@ public class G726_24 extends G726 {
209 } 208 }
210 else 209 else
211 if (out_coding==AUDIO_ENCODING_LINEAR) { 210 if (out_coding==AUDIO_ENCODING_LINEAR) {
212 - 211 +
213 int len_div_3=in_len/3; 212 int len_div_3=in_len/3;
214 for (int i=0; i<len_div_3; i++) { 213 for (int i=0; i<len_div_3; i++) {
215 int value16=0; 214 int value16=0;
src/main/java/com/genersoft/iot/vmp/jt1078/codec/g726/G726_32.java renamed to src/main/java/com/genersoft/iot/vmp/jtt1078/codec/g726/G726_32.java
1 1
2 -package com.genersoft.iot.vmp.jt1078.codec.g726; 2 +package com.genersoft.iot.vmp.jtt1078.codec.g726;
3 3
4 -  
5 -import com.genersoft.iot.vmp.jt1078.codec.G711Codec;  
6 -import com.genersoft.iot.vmp.jt1078.codec.G711UCodec; 4 +import com.genersoft.iot.vmp.jtt1078.codec.G711Codec;
  5 +import com.genersoft.iot.vmp.jtt1078.codec.G711UCodec;
7 6
8 /** G726_32 encoder and decoder. 7 /** G726_32 encoder and decoder.
9 * <p> 8 * <p>
@@ -31,7 +30,7 @@ import com.genersoft.iot.vmp.jt1078.codec.G711UCodec; @@ -31,7 +30,7 @@ import com.genersoft.iot.vmp.jt1078.codec.G711UCodec;
31 * ANSI-C source code to the public domain. 30 * ANSI-C source code to the public domain.
32 */ 31 */
33 public class G726_32 extends G726 { 32 public class G726_32 extends G726 {
34 - 33 +
35 // ##### C-to-Java conversion: ##### 34 // ##### C-to-Java conversion: #####
36 // short becomes int 35 // short becomes int
37 // char becomes int 36 // char becomes int
@@ -46,7 +45,7 @@ public class G726_32 extends G726 { @@ -46,7 +45,7 @@ public class G726_32 extends G726 {
46 * magnitude values. 45 * magnitude values.
47 */ 46 */
48 static /*short*/int[] _dqlntab={-2048, 4, 135, 213, 273, 323, 373, 425, 425, 373, 323, 273, 213, 135, 4, -2048}; 47 static /*short*/int[] _dqlntab={-2048, 4, 135, 213, 273, 323, 373, 425, 425, 373, 323, 273, 213, 135, 4, -2048};
49 - 48 +
50 /* Maps G726_32 code word to log of scale factor multiplier. */ 49 /* Maps G726_32 code word to log of scale factor multiplier. */
51 static /*short*/int[] _witab={-12, 18, 41, 64, 112, 198, 355, 1122, 1122, 355, 198, 112, 64, 41, 18, -12}; 50 static /*short*/int[] _witab={-12, 18, 41, 64, 112, 198, 355, 1122, 1122, 355, 198, 112, 64, 41, 18, -12};
52 51
@@ -56,18 +55,18 @@ public class G726_32 extends G726 { @@ -56,18 +55,18 @@ public class G726_32 extends G726 {
56 * how stationary (steady state) the signal is. 55 * how stationary (steady state) the signal is.
57 */ 56 */
58 static /*short*/int[] _fitab={0, 0, 0, 0x200, 0x200, 0x200, 0x600, 0xE00, 0xE00, 0x600, 0x200, 0x200, 0x200, 0, 0, 0}; 57 static /*short*/int[] _fitab={0, 0, 0, 0x200, 0x200, 0x200, 0x600, 0xE00, 0xE00, 0x600, 0x200, 0x200, 0x200, 0, 0, 0};
59 - 58 +
60 /** Encodes the input vale of linear PCM, A-law or u-law data sl and returns 59 /** Encodes the input vale of linear PCM, A-law or u-law data sl and returns
61 * the resulting code. -1 is returned for unknown input coding value. */ 60 * the resulting code. -1 is returned for unknown input coding value. */
62 public static int encode(int sl, int in_coding, G726State state) { 61 public static int encode(int sl, int in_coding, G726State state) {
63 - 62 +
64 /*short*/int sezi, se, sez; /* ACCUM */ 63 /*short*/int sezi, se, sez; /* ACCUM */
65 /*short*/int d; /* SUBTA */ 64 /*short*/int d; /* SUBTA */
66 /*short*/int sr; /* ADDB */ 65 /*short*/int sr; /* ADDB */
67 /*short*/int y; /* MIX */ 66 /*short*/int y; /* MIX */
68 /*short*/int dqsez; /* ADDC */ 67 /*short*/int dqsez; /* ADDC */
69 /*short*/int dq, i; 68 /*short*/int dq, i;
70 - 69 +
71 switch (in_coding) { 70 switch (in_coding) {
72 /* linearize input sample to 14-bit PCM */ 71 /* linearize input sample to 14-bit PCM */
73 case AUDIO_ENCODING_ALAW: 72 case AUDIO_ENCODING_ALAW:
@@ -82,57 +81,57 @@ public class G726_32 extends G726 { @@ -82,57 +81,57 @@ public class G726_32 extends G726 {
82 default: 81 default:
83 return -1; 82 return -1;
84 } 83 }
85 - 84 +
86 sezi=state.predictor_zero(); 85 sezi=state.predictor_zero();
87 sez=sezi >> 1; 86 sez=sezi >> 1;
88 se=(sezi+state.predictor_pole()) >> 1; /* estimated signal */ 87 se=(sezi+state.predictor_pole()) >> 1; /* estimated signal */
89 - 88 +
90 d=sl-se; /* estimation difference */ 89 d=sl-se; /* estimation difference */
91 - 90 +
92 /* quantize the prediction difference */ 91 /* quantize the prediction difference */
93 y=state.step_size(); /* quantizer step size */ 92 y=state.step_size(); /* quantizer step size */
94 i=quantize(d, y, qtab_721, 7); /* i=ADPCM code */ 93 i=quantize(d, y, qtab_721, 7); /* i=ADPCM code */
95 - 94 +
96 dq=reconstruct(i & 8, _dqlntab[i], y); /* quantized est diff */ 95 dq=reconstruct(i & 8, _dqlntab[i], y); /* quantized est diff */
97 - 96 +
98 sr=(dq<0)? se-(dq & 0x3FFF) : se+dq; /* reconst. signal */ 97 sr=(dq<0)? se-(dq & 0x3FFF) : se+dq; /* reconst. signal */
99 - 98 +
100 dqsez=sr+sez-se; /* pole prediction diff. */ 99 dqsez=sr+sez-se; /* pole prediction diff. */
101 - 100 +
102 update(4, y, _witab[i] << 5, _fitab[i], dq, sr, dqsez, state); 101 update(4, y, _witab[i] << 5, _fitab[i], dq, sr, dqsez, state);
103 - 102 +
104 return i; 103 return i;
105 } 104 }
106 - 105 +
107 /** Decodes a 4-bit code of G726_32 encoded data of i and 106 /** Decodes a 4-bit code of G726_32 encoded data of i and
108 * returns the resulting linear PCM, A-law or u-law value. 107 * returns the resulting linear PCM, A-law or u-law value.
109 * return -1 for unknown out_coding value. */ 108 * return -1 for unknown out_coding value. */
110 public static int decode(int i, int out_coding, G726State state) { 109 public static int decode(int i, int out_coding, G726State state) {
111 - 110 +
112 /*short*/int sezi, sei, sez, se; /* ACCUM */ 111 /*short*/int sezi, sei, sez, se; /* ACCUM */
113 /*short*/int y; /* MIX */ 112 /*short*/int y; /* MIX */
114 /*short*/int sr; /* ADDB */ 113 /*short*/int sr; /* ADDB */
115 /*short*/int dq; 114 /*short*/int dq;
116 /*short*/int dqsez; 115 /*short*/int dqsez;
117 - 116 +
118 i &= 0x0f; /* mask to get proper bits */ 117 i &= 0x0f; /* mask to get proper bits */
119 sezi=state.predictor_zero(); 118 sezi=state.predictor_zero();
120 sez=sezi >> 1; 119 sez=sezi >> 1;
121 sei=sezi+state.predictor_pole(); 120 sei=sezi+state.predictor_pole();
122 se=sei >> 1; /* se=estimated signal */ 121 se=sei >> 1; /* se=estimated signal */
123 - 122 +
124 y=state.step_size(); /* dynamic quantizer step size */ 123 y=state.step_size(); /* dynamic quantizer step size */
125 - 124 +
126 dq=reconstruct(i & 0x08, _dqlntab[i], y); /* quantized diff. */ 125 dq=reconstruct(i & 0x08, _dqlntab[i], y); /* quantized diff. */
127 - 126 +
128 sr=(dq<0)? (se-(dq & 0x3FFF)) : se+dq; /* reconst. signal */ 127 sr=(dq<0)? (se-(dq & 0x3FFF)) : se+dq; /* reconst. signal */
129 - 128 +
130 dqsez=sr-se+sez; /* pole prediction diff. */ 129 dqsez=sr-se+sez; /* pole prediction diff. */
131 - 130 +
132 update(4, y, _witab[i] << 5, _fitab[i], dq, sr, dqsez, state); 131 update(4, y, _witab[i] << 5, _fitab[i], dq, sr, dqsez, state);
133 - 132 +
134 switch (out_coding) { 133 switch (out_coding) {
135 - 134 +
136 case AUDIO_ENCODING_ALAW: 135 case AUDIO_ENCODING_ALAW:
137 return (tandem_adjust_alaw(sr, se, y, i, 8, qtab_721)); 136 return (tandem_adjust_alaw(sr, se, y, i, 8, qtab_721));
138 case AUDIO_ENCODING_ULAW: 137 case AUDIO_ENCODING_ULAW:
@@ -150,9 +149,9 @@ public class G726_32 extends G726 { @@ -150,9 +149,9 @@ public class G726_32 extends G726 {
150 * It returns the actual size of the output data, or -1 in case of unknown 149 * It returns the actual size of the output data, or -1 in case of unknown
151 * in_coding value. */ 150 * in_coding value. */
152 public static int encode(byte[] in_buff, int in_offset, int in_len, int in_coding, byte[] out_buff, int out_offset, G726State state) { 151 public static int encode(byte[] in_buff, int in_offset, int in_len, int in_coding, byte[] out_buff, int out_offset, G726State state) {
153 - 152 +
154 if (in_coding==AUDIO_ENCODING_ALAW || in_coding==AUDIO_ENCODING_ULAW) { 153 if (in_coding==AUDIO_ENCODING_ALAW || in_coding==AUDIO_ENCODING_ULAW) {
155 - 154 +
156 /* 155 /*
157 for (int i=0; i<in_len; i++) { 156 for (int i=0; i<in_len; i++) {
158 int in_value=in_buff[in_offset+i]; 157 int in_value=in_buff[in_offset+i];
@@ -170,25 +169,25 @@ public class G726_32 extends G726 { @@ -170,25 +169,25 @@ public class G726_32 extends G726 {
170 int in_index=in_offset+i*2; 169 int in_index=in_offset+i*2;
171 int in_value1=in_buff[in_index]; 170 int in_value1=in_buff[in_index];
172 int in_value2=in_buff[in_index+1]; 171 int in_value2=in_buff[in_index+1];
173 - int out_value1=encode(in_value1,in_coding,state);  
174 - int out_value2=encode(in_value2,in_coding,state); 172 + int out_value1=encode(in_value1,in_coding,state);
  173 + int out_value2=encode(in_value2,in_coding,state);
175 out_buff[out_offset+i]=(byte)((out_value1<<4) + out_value2); 174 out_buff[out_offset+i]=(byte)((out_value1<<4) + out_value2);
176 } 175 }
177 return len_div_2; 176 return len_div_2;
178 } 177 }
179 else 178 else
180 if (in_coding==AUDIO_ENCODING_LINEAR) { 179 if (in_coding==AUDIO_ENCODING_LINEAR) {
181 - 180 +
182 int len_div_4=in_len/4; 181 int len_div_4=in_len/4;
183 for (int i=0; i<len_div_4; i++) { 182 for (int i=0; i<len_div_4; i++) {
184 int in_index=in_offset+i*4; 183 int in_index=in_offset+i*4;
185 int in_value1=signedIntLittleEndian(in_buff[in_index+1],in_buff[in_index+0]); 184 int in_value1=signedIntLittleEndian(in_buff[in_index+1],in_buff[in_index+0]);
186 int in_value2=signedIntLittleEndian(in_buff[in_index+3],in_buff[in_index+2]); 185 int in_value2=signedIntLittleEndian(in_buff[in_index+3],in_buff[in_index+2]);
187 186
188 - //int out_value1=encode(G711.linear2ulaw(in_value1),AUDIO_ENCODING_ULAW,state);  
189 - //int out_value2=encode(G711.linear2ulaw(in_value2),AUDIO_ENCODING_ULAW,state);  
190 - int out_value1=encode(in_value1,in_coding,state);  
191 - int out_value2=encode(in_value2,in_coding,state); 187 + //int out_value1=encode(G711.linear2ulaw(in_value1),AUDIO_ENCODING_ULAW,state);
  188 + //int out_value2=encode(G711.linear2ulaw(in_value2),AUDIO_ENCODING_ULAW,state);
  189 + int out_value1=encode(in_value1,in_coding,state);
  190 + int out_value2=encode(in_value2,in_coding,state);
192 out_buff[out_offset+i]=(byte)((out_value1<<4) + out_value2); 191 out_buff[out_offset+i]=(byte)((out_value1<<4) + out_value2);
193 } 192 }
194 return len_div_4; 193 return len_div_4;
@@ -202,24 +201,24 @@ public class G726_32 extends G726 { @@ -202,24 +201,24 @@ public class G726_32 extends G726 {
202 * It returns the actual size of the output data, or -1 in case of unknown 201 * It returns the actual size of the output data, or -1 in case of unknown
203 * out_coding value. */ 202 * out_coding value. */
204 public static int decode(byte[] in_buff, int in_offset, int in_len, int out_coding, byte[] out_buff, int out_offset, G726State state) { 203 public static int decode(byte[] in_buff, int in_offset, int in_len, int out_coding, byte[] out_buff, int out_offset, G726State state) {
205 - 204 +
206 if (out_coding==AUDIO_ENCODING_ALAW || out_coding==AUDIO_ENCODING_ULAW) { 205 if (out_coding==AUDIO_ENCODING_ALAW || out_coding==AUDIO_ENCODING_ULAW) {
207 - 206 +
208 /* 207 /*
209 for (int i=0; i<in_len*2; i++) { 208 for (int i=0; i<in_len*2; i++) {
210 int in_value=unsignedInt(in_buff[in_offset+i/2]); 209 int in_value=unsignedInt(in_buff[in_offset+i/2]);
211 if ((i/2)*2==i) 210 if ((i/2)*2==i)
212 in_value>>=4; 211 in_value>>=4;
213 else 212 else
214 - in_value%=0x10;  
215 - int out_value=decode(in_value,out_coding,state); 213 + in_value%=0x10;
  214 + int out_value=decode(in_value,out_coding,state);
216 out_buff[out_offset+i]=(byte)out_value; 215 out_buff[out_offset+i]=(byte)out_value;
217 } 216 }
218 return in_len*2; 217 return in_len*2;
219 */ 218 */
220 for (int i=0; i<in_len; i++) { 219 for (int i=0; i<in_len; i++) {
221 int in_value=unsignedInt(in_buff[in_offset+i]); 220 int in_value=unsignedInt(in_buff[in_offset+i]);
222 - int out_value1=decode(in_value>>4,out_coding,state); 221 + int out_value1=decode(in_value>>4,out_coding,state);
223 int out_value2=decode(in_value&0xF,out_coding,state); 222 int out_value2=decode(in_value&0xF,out_coding,state);
224 int out_index=out_offset+i*2; 223 int out_index=out_offset+i*2;
225 out_buff[out_index]=(byte)out_value1; 224 out_buff[out_index]=(byte)out_value1;
@@ -229,12 +228,12 @@ public class G726_32 extends G726 { @@ -229,12 +228,12 @@ public class G726_32 extends G726 {
229 } 228 }
230 else 229 else
231 if (out_coding==AUDIO_ENCODING_LINEAR) { 230 if (out_coding==AUDIO_ENCODING_LINEAR) {
232 - 231 +
233 for (int i=0; i<in_len; i++) { 232 for (int i=0; i<in_len; i++) {
234 int in_value=unsignedInt(in_buff[in_offset+i]); 233 int in_value=unsignedInt(in_buff[in_offset+i]);
235 - //int out_value1=G711.ulaw2linear(decode(in_value>>4,AUDIO_ENCODING_ULAW,state)); 234 + //int out_value1=G711.ulaw2linear(decode(in_value>>4,AUDIO_ENCODING_ULAW,state));
236 //int out_value2=G711.ulaw2linear(decode(in_value&0xF,AUDIO_ENCODING_ULAW,state)); 235 //int out_value2=G711.ulaw2linear(decode(in_value&0xF,AUDIO_ENCODING_ULAW,state));
237 - int out_value1=decode(in_value>>4,out_coding,state); 236 + int out_value1=decode(in_value>>4,out_coding,state);
238 int out_value2=decode(in_value&0xF,out_coding,state); 237 int out_value2=decode(in_value&0xF,out_coding,state);
239 int out_index=out_offset+i*4; 238 int out_index=out_offset+i*4;
240 out_buff[out_index]=(byte)(out_value1&0xFF); 239 out_buff[out_index]=(byte)(out_value1&0xFF);
src/main/java/com/genersoft/iot/vmp/jt1078/codec/g726/G726_40.java renamed to src/main/java/com/genersoft/iot/vmp/jtt1078/codec/g726/G726_40.java
1 -package com.genersoft.iot.vmp.jt1078.codec.g726; 1 +package com.genersoft.iot.vmp.jtt1078.codec.g726;
2 2
3 -  
4 -import com.genersoft.iot.vmp.jt1078.codec.G711Codec;  
5 -import com.genersoft.iot.vmp.jt1078.codec.G711UCodec; 3 +import com.genersoft.iot.vmp.jtt1078.codec.G711Codec;
  4 +import com.genersoft.iot.vmp.jtt1078.codec.G711UCodec;
6 5
7 /** G726_40 encoder and decoder. 6 /** G726_40 encoder and decoder.
8 * <p> 7 * <p>
@@ -27,12 +26,12 @@ import com.genersoft.iot.vmp.jt1078.codec.G711UCodec; @@ -27,12 +26,12 @@ import com.genersoft.iot.vmp.jt1078.codec.G711UCodec;
27 * ANSI-C source code to the public domain. 26 * ANSI-C source code to the public domain.
28 */ 27 */
29 public class G726_40 extends G726 { 28 public class G726_40 extends G726 {
30 - 29 +
31 // ##### C-to-Java conversion: ##### 30 // ##### C-to-Java conversion: #####
32 // short becomes int 31 // short becomes int
33 // char becomes int 32 // char becomes int
34 // unsigned char becomes int 33 // unsigned char becomes int
35 - 34 +
36 35
37 // *************************** STATIC *************************** 36 // *************************** STATIC ***************************
38 37
@@ -41,31 +40,31 @@ public class G726_40 extends G726 { @@ -41,31 +40,31 @@ public class G726_40 extends G726 {
41 * magnitude values. 40 * magnitude values.
42 */ 41 */
43 static /*short*/int[] _dqlntab={-2048, -66, 28, 104, 169, 224, 274, 318, 358, 395, 429, 459, 488, 514, 539, 566, 566, 539, 514, 488, 459, 429, 395, 358, 318, 274, 224, 169, 104, 28, -66, -2048}; 42 static /*short*/int[] _dqlntab={-2048, -66, 28, 104, 169, 224, 274, 318, 358, 395, 429, 459, 488, 514, 539, 566, 566, 539, 514, 488, 459, 429, 395, 358, 318, 274, 224, 169, 104, 28, -66, -2048};
44 - 43 +
45 /* Maps G723_40 code word to log of scale factor multiplier. */ 44 /* Maps G723_40 code word to log of scale factor multiplier. */
46 static /*short*/int[] _witab={448, 448, 768, 1248, 1280, 1312, 1856, 3200, 4512, 5728, 7008, 8960, 11456, 14080, 16928, 22272, 22272, 16928, 14080, 11456, 8960, 7008, 5728, 4512, 3200, 1856, 1312, 1280, 1248, 768, 448, 448}; 45 static /*short*/int[] _witab={448, 448, 768, 1248, 1280, 1312, 1856, 3200, 4512, 5728, 7008, 8960, 11456, 14080, 16928, 22272, 22272, 16928, 14080, 11456, 8960, 7008, 5728, 4512, 3200, 1856, 1312, 1280, 1248, 768, 448, 448};
47 - 46 +
48 /* 47 /*
49 * Maps G723_40 code words to a set of values whose long and short 48 * Maps G723_40 code words to a set of values whose long and short
50 * term averages are computed and then compared to give an indication 49 * term averages are computed and then compared to give an indication
51 * how stationary (steady state) the signal is. 50 * how stationary (steady state) the signal is.
52 */ 51 */
53 static /*short*/int[] _fitab={0, 0, 0, 0, 0, 0x200, 0x200, 0x200, 0x200, 0x200, 0x400, 0x600, 0x800, 0xA00, 0xC00, 0xC00, 0xC00, 0xC00, 0xA00, 0x800, 0x600, 0x400, 0x200, 0x200, 0x200, 0x200, 0x200, 0, 0, 0, 0, 0}; 52 static /*short*/int[] _fitab={0, 0, 0, 0, 0, 0x200, 0x200, 0x200, 0x200, 0x200, 0x400, 0x600, 0x800, 0xA00, 0xC00, 0xC00, 0xC00, 0xC00, 0xA00, 0x800, 0x600, 0x400, 0x200, 0x200, 0x200, 0x200, 0x200, 0, 0, 0, 0, 0};
54 - 53 +
55 static /*short*/int[] qtab_723_40={-122, -16, 68, 139, 198, 250, 298, 339, 378, 413, 445, 475, 502, 528, 553}; 54 static /*short*/int[] qtab_723_40={-122, -16, 68, 139, 198, 250, 298, 339, 378, 413, 445, 475, 502, 528, 553};
56 - 55 +
57 /** Encodes a 16-bit linear PCM, A-law or u-law input sample and retuens 56 /** Encodes a 16-bit linear PCM, A-law or u-law input sample and retuens
58 * the resulting 5-bit CCITT G726 40kbps code. 57 * the resulting 5-bit CCITT G726 40kbps code.
59 * Returns -1 if the input coding value is invalid. */ 58 * Returns -1 if the input coding value is invalid. */
60 public static int encode(int sl, int in_coding, G726State state) { 59 public static int encode(int sl, int in_coding, G726State state) {
61 - 60 +
62 /*short*/int sei, sezi, se, sez; /* ACCUM */ 61 /*short*/int sei, sezi, se, sez; /* ACCUM */
63 /*short*/int d; /* SUBTA */ 62 /*short*/int d; /* SUBTA */
64 /*short*/int y; /* MIX */ 63 /*short*/int y; /* MIX */
65 /*short*/int sr; /* ADDB */ 64 /*short*/int sr; /* ADDB */
66 /*short*/int dqsez; /* ADDC */ 65 /*short*/int dqsez; /* ADDC */
67 /*short*/int dq, i; 66 /*short*/int dq, i;
68 - 67 +
69 switch (in_coding) { 68 switch (in_coding) {
70 /* linearize input sample to 14-bit PCM */ 69 /* linearize input sample to 14-bit PCM */
71 case AUDIO_ENCODING_ALAW: 70 case AUDIO_ENCODING_ALAW:
@@ -80,58 +79,58 @@ public class G726_40 extends G726 { @@ -80,58 +79,58 @@ public class G726_40 extends G726 {
80 default: 79 default:
81 return (-1); 80 return (-1);
82 } 81 }
83 - 82 +
84 sezi=state.predictor_zero(); 83 sezi=state.predictor_zero();
85 sez=sezi >> 1; 84 sez=sezi >> 1;
86 sei=sezi+state.predictor_pole(); 85 sei=sezi+state.predictor_pole();
87 se=sei >> 1; /* se=estimated signal */ 86 se=sei >> 1; /* se=estimated signal */
88 - 87 +
89 d=sl-se; /* d=estimation difference */ 88 d=sl-se; /* d=estimation difference */
90 - 89 +
91 /* quantize prediction difference */ 90 /* quantize prediction difference */
92 y=state.step_size(); /* adaptive quantizer step size */ 91 y=state.step_size(); /* adaptive quantizer step size */
93 i=quantize(d, y, qtab_723_40, 15); /* i=ADPCM code */ 92 i=quantize(d, y, qtab_723_40, 15); /* i=ADPCM code */
94 - 93 +
95 dq=reconstruct(i & 0x10, _dqlntab[i], y); /* quantized diff */ 94 dq=reconstruct(i & 0x10, _dqlntab[i], y); /* quantized diff */
96 - 95 +
97 sr=(dq<0)? se-(dq & 0x7FFF) : se+dq; /* reconstructed signal */ 96 sr=(dq<0)? se-(dq & 0x7FFF) : se+dq; /* reconstructed signal */
98 - 97 +
99 dqsez=sr+sez-se; /* dqsez=pole prediction diff. */ 98 dqsez=sr+sez-se; /* dqsez=pole prediction diff. */
100 - 99 +
101 update(5, y, _witab[i], _fitab[i], dq, sr, dqsez, state); 100 update(5, y, _witab[i], _fitab[i], dq, sr, dqsez, state);
102 - 101 +
103 return (i); 102 return (i);
104 } 103 }
105 104
106 - 105 +
107 /** Decodes a 5-bit CCITT G.726 40kbps code and returns 106 /** Decodes a 5-bit CCITT G.726 40kbps code and returns
108 * the resulting 16-bit linear PCM, A-law or u-law sample value. 107 * the resulting 16-bit linear PCM, A-law or u-law sample value.
109 * -1 is returned if the output coding is unknown. */ 108 * -1 is returned if the output coding is unknown. */
110 public static int decode(int i, int out_coding, G726State state) { 109 public static int decode(int i, int out_coding, G726State state) {
111 - 110 +
112 /*short*/int sezi, sei, sez, se; /* ACCUM */ 111 /*short*/int sezi, sei, sez, se; /* ACCUM */
113 /*short*/int y, dif; /* MIX */ 112 /*short*/int y, dif; /* MIX */
114 /*short*/int sr; /* ADDB */ 113 /*short*/int sr; /* ADDB */
115 /*short*/int dq; 114 /*short*/int dq;
116 /*short*/int dqsez; 115 /*short*/int dqsez;
117 - 116 +
118 i &= 0x1f; /* mask to get proper bits */ 117 i &= 0x1f; /* mask to get proper bits */
119 sezi=state.predictor_zero(); 118 sezi=state.predictor_zero();
120 sez=sezi >> 1; 119 sez=sezi >> 1;
121 sei=sezi+state.predictor_pole(); 120 sei=sezi+state.predictor_pole();
122 se=sei >> 1; /* se=estimated signal */ 121 se=sei >> 1; /* se=estimated signal */
123 - 122 +
124 y=state.step_size(); /* adaptive quantizer step size */ 123 y=state.step_size(); /* adaptive quantizer step size */
125 dq=reconstruct(i & 0x10, _dqlntab[i], y); /* estimation diff. */ 124 dq=reconstruct(i & 0x10, _dqlntab[i], y); /* estimation diff. */
126 - 125 +
127 sr=(dq<0)? (se-(dq & 0x7FFF)) : (se+dq); /* reconst. signal */ 126 sr=(dq<0)? (se-(dq & 0x7FFF)) : (se+dq); /* reconst. signal */
128 - 127 +
129 dqsez=sr-se+sez; /* pole prediction diff. */ 128 dqsez=sr-se+sez; /* pole prediction diff. */
130 - 129 +
131 update(5, y, _witab[i], _fitab[i], dq, sr, dqsez, state); 130 update(5, y, _witab[i], _fitab[i], dq, sr, dqsez, state);
132 - 131 +
133 switch (out_coding) { 132 switch (out_coding) {
134 - 133 +
135 case AUDIO_ENCODING_ALAW: 134 case AUDIO_ENCODING_ALAW:
136 return (tandem_adjust_alaw(sr, se, y, i, 0x10, qtab_723_40)); 135 return (tandem_adjust_alaw(sr, se, y, i, 0x10, qtab_723_40));
137 case AUDIO_ENCODING_ULAW: 136 case AUDIO_ENCODING_ULAW:
@@ -149,9 +148,9 @@ public class G726_40 extends G726 { @@ -149,9 +148,9 @@ public class G726_40 extends G726 {
149 * It returns the actual size of the output data, or -1 in case of unknown 148 * It returns the actual size of the output data, or -1 in case of unknown
150 * in_coding value. */ 149 * in_coding value. */
151 public static int encode(byte[] in_buff, int in_offset, int in_len, int in_coding, byte[] out_buff, int out_offset, G726State state) { 150 public static int encode(byte[] in_buff, int in_offset, int in_len, int in_coding, byte[] out_buff, int out_offset, G726State state) {
152 - 151 +
153 if (in_coding==AUDIO_ENCODING_ALAW || in_coding==AUDIO_ENCODING_ULAW) { 152 if (in_coding==AUDIO_ENCODING_ALAW || in_coding==AUDIO_ENCODING_ULAW) {
154 - 153 +
155 int len_div_8=in_len/8; 154 int len_div_8=in_len/8;
156 for (int i=0; i<len_div_8; i++) { 155 for (int i=0; i<len_div_8; i++) {
157 long value8=0; 156 long value8=0;
@@ -170,7 +169,7 @@ public class G726_40 extends G726 { @@ -170,7 +169,7 @@ public class G726_40 extends G726 {
170 } 169 }
171 else 170 else
172 if (in_coding==AUDIO_ENCODING_LINEAR) { 171 if (in_coding==AUDIO_ENCODING_LINEAR) {
173 - 172 +
174 int len_div_16=in_len/16; 173 int len_div_16=in_len/16;
175 for (int i=0; i<len_div_16; i++) { 174 for (int i=0; i<len_div_16; i++) {
176 long value16=0; 175 long value16=0;
@@ -197,9 +196,9 @@ public class G726_40 extends G726 { @@ -197,9 +196,9 @@ public class G726_40 extends G726 {
197 * It returns the actual size of the output data, or -1 in case of unknown 196 * It returns the actual size of the output data, or -1 in case of unknown
198 * out_coding value. */ 197 * out_coding value. */
199 public static int decode(byte[] in_buff, int in_offset, int in_len, int out_coding, byte[] out_buff, int out_offset, G726State state) { 198 public static int decode(byte[] in_buff, int in_offset, int in_len, int out_coding, byte[] out_buff, int out_offset, G726State state) {
200 - 199 +
201 if (out_coding==AUDIO_ENCODING_ALAW || out_coding==AUDIO_ENCODING_ULAW) { 200 if (out_coding==AUDIO_ENCODING_ALAW || out_coding==AUDIO_ENCODING_ULAW) {
202 - 201 +
203 int len_div_5=in_len/5; 202 int len_div_5=in_len/5;
204 for (int i=0; i<len_div_5; i++) { 203 for (int i=0; i<len_div_5; i++) {
205 long value8=0; 204 long value8=0;
@@ -218,7 +217,7 @@ public class G726_40 extends G726 { @@ -218,7 +217,7 @@ public class G726_40 extends G726 {
218 } 217 }
219 else 218 else
220 if (out_coding==AUDIO_ENCODING_LINEAR) { 219 if (out_coding==AUDIO_ENCODING_LINEAR) {
221 - 220 +
222 int len_div_5=in_len/5; 221 int len_div_5=in_len/5;
223 for (int i=0; i<len_div_5; i++) { 222 for (int i=0; i<len_div_5; i++) {
224 long value16=0; 223 long value16=0;
src/main/java/com/genersoft/iot/vmp/jt1078/entity/Audio.java renamed to src/main/java/com/genersoft/iot/vmp/jtt1078/entity/Audio.java
1 -package com.genersoft.iot.vmp.jt1078.entity; 1 +package com.genersoft.iot.vmp.jtt1078.entity;
2 2
3 /** 3 /**
4 * Created by houcheng on 2019-12-11. 4 * Created by houcheng on 2019-12-11.
src/main/java/com/genersoft/iot/vmp/jt1078/entity/Media.java renamed to src/main/java/com/genersoft/iot/vmp/jtt1078/entity/Media.java
1 -package com.genersoft.iot.vmp.jt1078.entity; 1 +package com.genersoft.iot.vmp.jtt1078.entity;
2 2
3 /** 3 /**
4 * Created by houcheng on 2019-12-11. 4 * Created by houcheng on 2019-12-11.
src/main/java/com/genersoft/iot/vmp/jt1078/entity/MediaEncoding.java renamed to src/main/java/com/genersoft/iot/vmp/jtt1078/entity/MediaEncoding.java
1 -package com.genersoft.iot.vmp.jt1078.entity; 1 +package com.genersoft.iot.vmp.jtt1078.entity;
2 2
3 /** 3 /**
4 * Created by matrixy on 2019/12/20. 4 * Created by matrixy on 2019/12/20.
src/main/java/com/genersoft/iot/vmp/jt1078/entity/Video.java renamed to src/main/java/com/genersoft/iot/vmp/jtt1078/entity/Video.java
1 -package com.genersoft.iot.vmp.jt1078.entity; 1 +package com.genersoft.iot.vmp.jtt1078.entity;
2 2
3 /** 3 /**
4 * Created by houcheng on 2019-12-11. 4 * Created by houcheng on 2019-12-11.
5 */ 5 */
6 -public class Video extends Media {  
7 - public Video(long sequence, MediaEncoding.Encoding encoding, byte[] data) { 6 +public class Video extends Media
  7 +{
  8 + public Video(long sequence, MediaEncoding.Encoding encoding, byte[] data)
  9 + {
8 super(sequence, encoding, data); 10 super(sequence, encoding, data);
9 } 11 }
10 } 12 }
src/main/java/com/genersoft/iot/vmp/jt1078/flv/AudioTag.java renamed to src/main/java/com/genersoft/iot/vmp/jtt1078/flv/AudioTag.java
1 -package com.genersoft.iot.vmp.jt1078.flv; 1 +package com.genersoft.iot.vmp.jtt1078.flv;
2 2
3 /** 3 /**
4 * flv 音频封装 4 * flv 音频封装
src/main/java/com/genersoft/iot/vmp/jt1078/flv/FlvAudioTagEncoder.java renamed to src/main/java/com/genersoft/iot/vmp/jtt1078/flv/FlvAudioTagEncoder.java
1 -package com.genersoft.iot.vmp.jt1078.flv; 1 +package com.genersoft.iot.vmp.jtt1078.flv;
2 2
3 import io.netty.buffer.ByteBuf; 3 import io.netty.buffer.ByteBuf;
4 import io.netty.buffer.Unpooled; 4 import io.netty.buffer.Unpooled;
src/main/java/com/genersoft/iot/vmp/jt1078/flv/FlvEncoder.java renamed to src/main/java/com/genersoft/iot/vmp/jtt1078/flv/FlvEncoder.java
1 -package com.genersoft.iot.vmp.jt1078.flv; 1 +package com.genersoft.iot.vmp.jtt1078.flv;
2 2
3 -import com.genersoft.iot.vmp.jt1078.util.Packet; 3 +import com.genersoft.iot.vmp.jtt1078.util.Packet;
4 4
5 import java.io.ByteArrayOutputStream; 5 import java.io.ByteArrayOutputStream;
6 -import java.io.IOException;  
7 -import java.io.OutputStream;  
8 6
9 /** 7 /**
10 * Created by matrixy on 2020/1/3. 8 * Created by matrixy on 2020/1/3.
src/main/java/com/genersoft/iot/vmp/jt1078/flv/FlvTag.java renamed to src/main/java/com/genersoft/iot/vmp/jtt1078/flv/FlvTag.java
1 -package com.genersoft.iot.vmp.jt1078.flv; 1 +package com.genersoft.iot.vmp.jtt1078.flv;
2 2
3 //由于flv格式是header+body,而body是preTagSize+currentTagData.......循环形式,并且第一个的preTagSize始终为0, 3 //由于flv格式是header+body,而body是preTagSize+currentTagData.......循环形式,并且第一个的preTagSize始终为0,
4 // 与其这样不如采用(header+preTag0Size)+(currentTagData+currentTagSize),这样就避免每次都要记录以下上一个tag的数据大小。 4 // 与其这样不如采用(header+preTag0Size)+(currentTagData+currentTagSize),这样就避免每次都要记录以下上一个tag的数据大小。
src/main/java/com/genersoft/iot/vmp/jt1078/http/GeneralResponseWriter.java renamed to src/main/java/com/genersoft/iot/vmp/jtt1078/http/GeneralResponseWriter.java
1 -package com.genersoft.iot.vmp.jt1078.http; 1 +package com.genersoft.iot.vmp.jtt1078.http;
2 2
3 import io.netty.buffer.ByteBuf; 3 import io.netty.buffer.ByteBuf;
4 import io.netty.channel.ChannelHandlerContext; 4 import io.netty.channel.ChannelHandlerContext;
src/main/java/com/genersoft/iot/vmp/jtt1078/http/NettyHttpServerHandler.java 0 → 100644
  1 +package com.genersoft.iot.vmp.jtt1078.http;
  2 +
  3 +import com.genersoft.iot.vmp.jtt1078.entity.Media;
  4 +import com.genersoft.iot.vmp.jtt1078.publisher.PublishManager;
  5 +import com.genersoft.iot.vmp.jtt1078.server.Session;
  6 +import com.genersoft.iot.vmp.jtt1078.util.*;
  7 +import io.netty.buffer.ByteBuf;
  8 +import io.netty.buffer.Unpooled;
  9 +import io.netty.channel.ChannelHandlerContext;
  10 +import io.netty.channel.ChannelInboundHandlerAdapter;
  11 +import io.netty.handler.codec.http.*;
  12 +import io.netty.util.Attribute;
  13 +import io.netty.util.AttributeKey;
  14 +import org.slf4j.Logger;
  15 +import org.slf4j.LoggerFactory;
  16 +
  17 +/**
  18 + * Created by matrixy on 2019/8/13.
  19 + */
  20 +public class NettyHttpServerHandler extends ChannelInboundHandlerAdapter
  21 +{
  22 + static Logger logger = LoggerFactory.getLogger(NettyHttpServerHandler.class);
  23 + static final byte[] HTTP_403_DATA = "<h1>403 Forbidden</h1><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding--><!--padding-->".getBytes();
  24 + static final String HEADER_ENCODING = "ISO-8859-1";
  25 +
  26 + private static final AttributeKey<Session> SESSION_KEY = AttributeKey.valueOf("session");
  27 +
  28 + @Override
  29 + public void channelRead(final ChannelHandlerContext ctx, Object msg) throws Exception
  30 + {
  31 + FullHttpRequest fhr = (FullHttpRequest) msg;
  32 + String uri = fhr.uri();
  33 + Packet resp = Packet.create(1024);
  34 + // uri的第二段,就是通道标签
  35 + if (uri.startsWith("/video/"))
  36 + {
  37 + String tag = uri.substring("/video/".length());
  38 + resp.addBytes("HTTP/1.1 200 OK\r\n".getBytes(HEADER_ENCODING));
  39 + resp.addBytes("Connection: keep-alive\r\n".getBytes(HEADER_ENCODING));
  40 + resp.addBytes("Content-Type: video/x-flv\r\n".getBytes(HEADER_ENCODING));
  41 + resp.addBytes("Transfer-Encoding: chunked\r\n".getBytes(HEADER_ENCODING));
  42 + resp.addBytes("Cache-Control: no-cache\r\n".getBytes(HEADER_ENCODING));
  43 + resp.addBytes("Access-Control-Allow-Origin: *\r\n".getBytes(HEADER_ENCODING));
  44 + resp.addBytes("Access-Control-Allow-Credentials: true\r\n".getBytes(HEADER_ENCODING));
  45 + resp.addBytes("\r\n".getBytes(HEADER_ENCODING));
  46 +
  47 + ctx.writeAndFlush(resp.getBytes()).await();
  48 +
  49 + // 订阅视频数据
  50 + long wid = PublishManager.getInstance().subscribe(tag, Media.Type.Video, ctx).getId();
  51 + setSession(ctx, new Session().set("subscriber-id", wid).set("tag", tag));
  52 +
  53 + }
  54 + else if (uri.equals("/test/multimedia"))
  55 + {
  56 + responseHTMLFile("/multimedia.html", ctx);
  57 + }
  58 + else
  59 + {
  60 + ByteBuf body = Unpooled.buffer(HTTP_403_DATA.length);
  61 + body.writeBytes(HTTP_403_DATA);
  62 + FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.valueOf(403), body);
  63 + response.headers().add("Content-Length", HTTP_403_DATA.length);
  64 + ctx.writeAndFlush(response).await();
  65 + ctx.flush();
  66 + }
  67 + }
  68 +
  69 + @Override
  70 + public void channelInactive(ChannelHandlerContext ctx) throws Exception
  71 + {
  72 + super.channelInactive(ctx);
  73 + Session session = getSession(ctx);
  74 + if (session != null && session.has("subscriber-id") && session.has("tag"))
  75 + {
  76 + String tag = session.get("tag");
  77 + Long wid = session.get("subscriber-id");
  78 + PublishManager.getInstance().unsubscribe(tag, wid);
  79 + }
  80 + }
  81 +
  82 + // 响应静态文件内容
  83 + private void responseHTMLFile(String htmlFilePath, ChannelHandlerContext ctx)
  84 + {
  85 + byte[] fileData = FileUtils.read(NettyHttpServerHandler.class.getResourceAsStream(htmlFilePath));
  86 + ByteBuf body = Unpooled.buffer(fileData.length);
  87 + body.writeBytes(fileData);
  88 + FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.valueOf(200), body);
  89 + response.headers().add("Content-Length", fileData.length);
  90 + ctx.write(response);
  91 + ctx.flush();
  92 + }
  93 +
  94 + @Override
  95 + public void channelReadComplete(ChannelHandlerContext ctx) throws Exception
  96 + {
  97 + ctx.flush();
  98 + }
  99 +
  100 + @Override
  101 + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception
  102 + {
  103 + ctx.close();
  104 + cause.printStackTrace();
  105 + }
  106 +
  107 + public final void setSession(ChannelHandlerContext context, Session session)
  108 + {
  109 + context.channel().attr(SESSION_KEY).set(session);
  110 + }
  111 +
  112 + public final Session getSession(ChannelHandlerContext context)
  113 + {
  114 + Attribute<Session> attr = context.channel().attr(SESSION_KEY);
  115 + if (null == attr) return null;
  116 + else return attr.get();
  117 + }
  118 +}
  119 +
src/main/java/com/genersoft/iot/vmp/jtt1078/publisher/Channel.java 0 → 100644
  1 +package com.genersoft.iot.vmp.jtt1078.publisher;
  2 +
  3 +import com.genersoft.iot.vmp.jtt1078.app.VideoServerApp;
  4 +import com.genersoft.iot.vmp.jtt1078.codec.AudioCodec;
  5 +import com.genersoft.iot.vmp.jtt1078.entity.Media;
  6 +import com.genersoft.iot.vmp.jtt1078.entity.MediaEncoding;
  7 +import com.genersoft.iot.vmp.jtt1078.flv.FlvEncoder;
  8 +import com.genersoft.iot.vmp.jtt1078.subscriber.RTMPPublisher;
  9 +import com.genersoft.iot.vmp.jtt1078.subscriber.Subscriber;
  10 +import com.genersoft.iot.vmp.jtt1078.subscriber.VideoSubscriber;
  11 +import com.genersoft.iot.vmp.jtt1078.util.ByteHolder;
  12 +import com.genersoft.iot.vmp.jtt1078.util.Configs;
  13 +import io.netty.channel.ChannelHandlerContext;
  14 +import org.apache.commons.lang3.StringUtils;
  15 +import org.slf4j.Logger;
  16 +import org.slf4j.LoggerFactory;
  17 +
  18 +import java.util.Iterator;
  19 +import java.util.concurrent.ConcurrentLinkedQueue;
  20 +
  21 +/**
  22 + * Created by matrixy on 2020/1/11.
  23 + */
  24 +public class Channel
  25 +{
  26 + static Logger logger = LoggerFactory.getLogger(Channel.class);
  27 +
  28 + ConcurrentLinkedQueue<Subscriber> subscribers;
  29 + RTMPPublisher rtmpPublisher;
  30 +
  31 + String tag;
  32 + boolean publishing;
  33 + ByteHolder buffer;
  34 + AudioCodec audioCodec;
  35 + FlvEncoder flvEncoder;
  36 + private long firstTimestamp = -1;
  37 +
  38 + public Channel(String tag)
  39 + {
  40 + this.tag = tag;
  41 + this.subscribers = new ConcurrentLinkedQueue<Subscriber>();
  42 + this.flvEncoder = new FlvEncoder(true, true);
  43 + this.buffer = new ByteHolder(2048 * 100);
  44 +
  45 + if (!StringUtils.isEmpty(Configs.get("rtmp.url")))
  46 + {
  47 + rtmpPublisher = new RTMPPublisher(tag);
  48 + rtmpPublisher.start();
  49 + }
  50 + }
  51 +
  52 + public boolean isPublishing()
  53 + {
  54 + return publishing;
  55 + }
  56 +
  57 + public Subscriber subscribe(ChannelHandlerContext ctx)
  58 + {
  59 + logger.info("channel: {} -> {}, subscriber: {}", Long.toHexString(hashCode() & 0xffffffffL), tag, ctx.channel().remoteAddress().toString());
  60 +
  61 + Subscriber subscriber = new VideoSubscriber(this.tag, ctx);
  62 + this.subscribers.add(subscriber);
  63 + return subscriber;
  64 + }
  65 +
  66 + public void writeAudio(long timestamp, int pt, byte[] data)
  67 + {
  68 + if (audioCodec == null)
  69 + {
  70 + audioCodec = AudioCodec.getCodec(pt);
  71 + logger.info("audio codec: {}", MediaEncoding.getEncoding(Media.Type.Audio, pt));
  72 + }
  73 + broadcastAudio(timestamp, audioCodec.toPCM(data));
  74 + }
  75 +
  76 + public void writeVideo(long sequence, long timeoffset, int payloadType, byte[] h264)
  77 + {
  78 + if (firstTimestamp == -1) firstTimestamp = timeoffset;
  79 + this.publishing = true;
  80 + this.buffer.write(h264);
  81 + while (true)
  82 + {
  83 + byte[] nalu = readNalu();
  84 + if (nalu == null) break;
  85 + if (nalu.length < 4) continue;
  86 +
  87 + byte[] flvTag = this.flvEncoder.write(nalu, (int) (timeoffset - firstTimestamp));
  88 +
  89 + if (flvTag == null) continue;
  90 +
  91 + // 广播给所有的观众
  92 + broadcastVideo(timeoffset, flvTag);
  93 + }
  94 + }
  95 +
  96 + public void broadcastVideo(long timeoffset, byte[] flvTag)
  97 + {
  98 + for (Subscriber subscriber : subscribers)
  99 + {
  100 + subscriber.onVideoData(timeoffset, flvTag, flvEncoder);
  101 + }
  102 + }
  103 +
  104 + public void broadcastAudio(long timeoffset, byte[] flvTag)
  105 + {
  106 + for (Subscriber subscriber : subscribers)
  107 + {
  108 + subscriber.onAudioData(timeoffset, flvTag, flvEncoder);
  109 + }
  110 + }
  111 +
  112 + public void unsubscribe(long watcherId)
  113 + {
  114 + for (Iterator<Subscriber> itr = subscribers.iterator(); itr.hasNext(); )
  115 + {
  116 + Subscriber subscriber = itr.next();
  117 + if (subscriber.getId() == watcherId)
  118 + {
  119 + itr.remove();
  120 + subscriber.close();
  121 + return;
  122 + }
  123 + }
  124 + }
  125 +
  126 + public void close()
  127 + {
  128 + for (Iterator<Subscriber> itr = subscribers.iterator(); itr.hasNext(); )
  129 + {
  130 + Subscriber subscriber = itr.next();
  131 + subscriber.close();
  132 + itr.remove();
  133 + }
  134 + if (rtmpPublisher != null) rtmpPublisher.close();
  135 + }
  136 +
  137 + private byte[] readNalu()
  138 + {
  139 + for (int i = 0; i < buffer.size() - 3; i++)
  140 + {
  141 + int a = buffer.get(i + 0) & 0xff;
  142 + int b = buffer.get(i + 1) & 0xff;
  143 + int c = buffer.get(i + 2) & 0xff;
  144 + int d = buffer.get(i + 3) & 0xff;
  145 + if (a == 0x00 && b == 0x00 && c == 0x00 && d == 0x01)
  146 + {
  147 + if (i == 0) continue;
  148 + byte[] nalu = new byte[i];
  149 + buffer.sliceInto(nalu, i);
  150 + return nalu;
  151 + }
  152 + }
  153 + return null;
  154 + }
  155 +}
src/main/java/com/genersoft/iot/vmp/jtt1078/publisher/PublishManager.java 0 → 100644
  1 +package com.genersoft.iot.vmp.jtt1078.publisher;
  2 +
  3 +import com.genersoft.iot.vmp.jtt1078.entity.Media;
  4 +import com.genersoft.iot.vmp.jtt1078.subscriber.Subscriber;
  5 +import io.netty.channel.ChannelHandlerContext;
  6 +import org.slf4j.Logger;
  7 +import org.slf4j.LoggerFactory;
  8 +
  9 +import java.util.concurrent.ConcurrentHashMap;
  10 +
  11 +/**
  12 + * Created by houcheng on 2019-12-11.
  13 + */
  14 +public final class PublishManager
  15 +{
  16 + static Logger logger = LoggerFactory.getLogger(PublishManager.class);
  17 + ConcurrentHashMap<String, Channel> channels;
  18 +
  19 + private PublishManager()
  20 + {
  21 + channels = new ConcurrentHashMap<String, Channel>();
  22 + }
  23 +
  24 + public Subscriber subscribe(String tag, Media.Type type, ChannelHandlerContext ctx)
  25 + {
  26 + Channel chl = channels.get(tag);
  27 + if (chl == null)
  28 + {
  29 + chl = new Channel(tag);
  30 + channels.put(tag, chl);
  31 + }
  32 + Subscriber subscriber = null;
  33 + if (type.equals(Media.Type.Video)) subscriber = chl.subscribe(ctx);
  34 + else throw new RuntimeException("unknown media type: " + type);
  35 +
  36 + subscriber.setName("subscriber-" + tag + "-" + subscriber.getId());
  37 + subscriber.start();
  38 +
  39 + return subscriber;
  40 + }
  41 +
  42 + public void publishAudio(String tag, int sequence, long timestamp, int payloadType, byte[] data)
  43 + {
  44 + Channel chl = channels.get(tag);
  45 + if (chl != null) chl.writeAudio(timestamp, payloadType, data);
  46 + }
  47 +
  48 + public void publishVideo(String tag, int sequence, long timestamp, int payloadType, byte[] data)
  49 + {
  50 + Channel chl = channels.get(tag);
  51 + if (chl != null) chl.writeVideo(sequence, timestamp, payloadType, data);
  52 + }
  53 +
  54 + public Channel open(String tag)
  55 + {
  56 + Channel chl = channels.get(tag);
  57 + if (chl == null)
  58 + {
  59 + chl = new Channel(tag);
  60 + channels.put(tag, chl);
  61 + }
  62 + if (chl.isPublishing()) throw new RuntimeException("channel already publishing");
  63 + return chl;
  64 + }
  65 +
  66 + public void close(String tag)
  67 + {
  68 + Channel chl = channels.remove(tag);
  69 + if (chl != null) chl.close();
  70 + }
  71 +
  72 + public void unsubscribe(String tag, long watcherId)
  73 + {
  74 + Channel chl = channels.get(tag);
  75 + if (chl != null) chl.unsubscribe(watcherId);
  76 + logger.info("unsubscribe: {} - {}", tag, watcherId);
  77 + }
  78 + static final PublishManager instance = new PublishManager();
  79 + public static void init() { }
  80 +
  81 + public static PublishManager getInstance()
  82 + {
  83 + return instance;
  84 + }
  85 +}
src/main/java/com/genersoft/iot/vmp/jt1078/server/Jtt1078Decoder.java renamed to src/main/java/com/genersoft/iot/vmp/jtt1078/server/Jtt1078Decoder.java
1 -package com.genersoft.iot.vmp.jt1078.server; 1 +package com.genersoft.iot.vmp.jtt1078.server;
2 2
3 -import com.genersoft.iot.vmp.jt1078.util.ByteHolder;  
4 -import com.genersoft.iot.vmp.jt1078.util.ByteUtils;  
5 -import com.genersoft.iot.vmp.jt1078.util.Packet; 3 +import com.genersoft.iot.vmp.jtt1078.util.ByteHolder;
  4 +import com.genersoft.iot.vmp.jtt1078.util.ByteUtils;
  5 +import com.genersoft.iot.vmp.jtt1078.util.Packet;
6 6
7 /** 7 /**
8 * Created by matrixy on 2019/4/9. 8 * Created by matrixy on 2019/4/9.
src/main/java/com/genersoft/iot/vmp/jtt1078/server/Jtt1078Handler.java 0 → 100644
  1 +package com.genersoft.iot.vmp.jtt1078.server;
  2 +
  3 +import com.genersoft.iot.vmp.jtt1078.publisher.Channel;
  4 +import com.genersoft.iot.vmp.jtt1078.publisher.PublishManager;
  5 +import com.genersoft.iot.vmp.jtt1078.util.Packet;
  6 +import com.genersoft.iot.vmp.vmanager.jt1078.platform.Jt1078OfCarController;
  7 +import com.genersoft.iot.vmp.vmanager.jt1078.platform.config.DataBuffer;
  8 +import com.genersoft.iot.vmp.vmanager.jt1078.platform.domain.SimFlow;
  9 +import io.netty.channel.ChannelHandlerContext;
  10 +import io.netty.channel.SimpleChannelInboundHandler;
  11 +import io.netty.handler.timeout.IdleState;
  12 +import io.netty.handler.timeout.IdleStateEvent;
  13 +import io.netty.util.AttributeKey;
  14 +import org.slf4j.Logger;
  15 +import org.slf4j.LoggerFactory;
  16 +import org.springframework.context.ApplicationContext;
  17 +import org.springframework.data.redis.core.StringRedisTemplate;
  18 +
  19 +import java.math.BigDecimal;
  20 +import java.util.Set;
  21 +import java.util.concurrent.TimeUnit;
  22 +
  23 +import static com.genersoft.iot.vmp.VManageBootstrap.getBean;
  24 +
  25 +/**
  26 + * Created by matrixy on 2019/4/9.
  27 + */
  28 +public class Jtt1078Handler extends SimpleChannelInboundHandler<Packet>
  29 +{
  30 + private static ApplicationContext applicationContext;
  31 + static Logger logger = LoggerFactory.getLogger(Jtt1078Handler.class);
  32 + private static final AttributeKey<Session> SESSION_KEY = AttributeKey.valueOf("session-key");
  33 + private Integer port;
  34 +
  35 + public Jtt1078Handler(Integer port) {
  36 + this.port = port;
  37 + }
  38 +
  39 + public Jtt1078Handler() {
  40 + }
  41 +
  42 + /**
  43 + * 流来
  44 + */
  45 + @Override
  46 + protected void channelRead0(ChannelHandlerContext ctx, Packet packet) throws Exception
  47 + {
  48 + io.netty.channel.Channel nettyChannel = ctx.channel();
  49 + packet.seek(8);
  50 + String sim = packet.nextBCD() + packet.nextBCD() + packet.nextBCD() + packet.nextBCD() + packet.nextBCD() + packet.nextBCD();
  51 + int channel = packet.nextByte() & 0xff;
  52 + String tag = sim + "-" + channel;
  53 + tag = tag.replaceAll("^0+", "");
  54 + if (port != null){
  55 + Set<String> set = Jt1078OfCarController.map.get(port);
  56 + String findSet = Jt1078OfCarController.getFindSet(set, tag);
  57 + if (findSet != null){
  58 + tag = findSet + "_" + port;
  59 + }else {
  60 + return;
  61 + }
  62 + }
  63 + StringRedisTemplate redisTemplate = getBean(StringRedisTemplate.class);
  64 + if (redisTemplate.opsForSet().add("tag:" + tag, tag) > 0){
  65 + redisTemplate.expire("tag:" + tag, 60, TimeUnit.SECONDS);
  66 + logger.info("[ {} ] --> 流接收成功 ",tag);
  67 + }else {
  68 + redisTemplate.expire("tag:" + tag, 60, TimeUnit.SECONDS);
  69 + }
  70 + double num = new BigDecimal(packet.size()).divide(new BigDecimal(1024 * 1024 * 1024), 10, BigDecimal.ROUND_HALF_UP).doubleValue();
  71 + DataBuffer simFlowDataBuffer = getBean(DataBuffer.class);
  72 + if (simFlowDataBuffer != null) {
  73 + simFlowDataBuffer.setValue(SimFlow.build(sim,String.valueOf(channel),num));
  74 + }
  75 + if (SessionManager.contains(nettyChannel, "tag") == false)
  76 + {
  77 + Channel chl = PublishManager.getInstance().open(tag);
  78 + SessionManager.set(nettyChannel, "tag", tag);
  79 + logger.info("start publishing: {} -> {}-{}", Long.toHexString(chl.hashCode() & 0xffffffffL), sim, channel);
  80 + }
  81 +
  82 + Integer sequence = SessionManager.get(nettyChannel, "video-sequence");
  83 + if (sequence == null) sequence = 0;
  84 + // 1. 做好序号
  85 + // 2. 音频需要转码后提供订阅
  86 + int lengthOffset = 28;
  87 + int dataType = (packet.seek(15).nextByte() >> 4) & 0x0f;
  88 + int pkType = packet.seek(15).nextByte() & 0x0f;
  89 + // 透传数据类型:0100,没有后面的时间以及Last I Frame Interval和Last Frame Interval字段
  90 + if (dataType == 0x04) lengthOffset = 28 - 8 - 2 - 2;
  91 + else if (dataType == 0x03) lengthOffset = 28 - 4;
  92 +
  93 + int pt = packet.seek(5).nextByte() & 0x7f;
  94 +
  95 + if (dataType == 0x00 || dataType == 0x01 || dataType == 0x02)
  96 + {
  97 + // 碰到结束标记时,序号+1
  98 + if (pkType == 0 || pkType == 2)
  99 + {
  100 + sequence += 1;
  101 + SessionManager.set(nettyChannel, "video-sequence", sequence);
  102 + }
  103 + long timestamp = packet.seek(16).nextLong();
  104 + PublishManager.getInstance().publishVideo(tag, sequence, timestamp, pt, packet.seek(lengthOffset + 2).nextBytes());
  105 + }
  106 + else if (dataType == 0x03)
  107 + {
  108 + long timestamp = packet.seek(16).nextLong();
  109 + byte[] data = packet.seek(lengthOffset + 2).nextBytes();
  110 + PublishManager.getInstance().publishAudio(tag, sequence, timestamp, pt, data);
  111 + }
  112 + }
  113 +
  114 + @Override
  115 + public void channelInactive(ChannelHandlerContext ctx) throws Exception
  116 + {
  117 + super.channelInactive(ctx);
  118 + release(ctx.channel());
  119 + }
  120 +
  121 + @Override
  122 + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception
  123 + {
  124 + // super.exceptionCaught(ctx, cause);
  125 + cause.printStackTrace();
  126 + release(ctx.channel());
  127 + ctx.close();
  128 + }
  129 +
  130 + @Override
  131 + public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
  132 + if (IdleStateEvent.class.isAssignableFrom(evt.getClass())) {
  133 + IdleStateEvent event = (IdleStateEvent) evt;
  134 + if (event.state() == IdleState.READER_IDLE) {
  135 + String tag = SessionManager.get(ctx.channel(), "tag");
  136 + logger.info("read timeout: {}",tag);
  137 + release(ctx.channel());
  138 + }
  139 + }
  140 + }
  141 +
  142 + private void release(io.netty.channel.Channel channel)
  143 + {
  144 + String tag = SessionManager.get(channel, "tag");
  145 + if (tag != null)
  146 + {
  147 + logger.info("close netty channel: {}", tag);
  148 + PublishManager.getInstance().close(tag);
  149 + }
  150 + }
  151 +
  152 +
  153 +}
src/main/java/com/genersoft/iot/vmp/jt1078/server/Jtt1078MessageDecoder.java renamed to src/main/java/com/genersoft/iot/vmp/jtt1078/server/Jtt1078MessageDecoder.java
1 -package com.genersoft.iot.vmp.jt1078.server; 1 +package com.genersoft.iot.vmp.jtt1078.server;
2 2
3 -import com.genersoft.iot.vmp.jt1078.util.ByteUtils;  
4 -import com.genersoft.iot.vmp.jt1078.util.Packet; 3 +import com.genersoft.iot.vmp.jtt1078.util.Packet;
5 import io.netty.buffer.ByteBuf; 4 import io.netty.buffer.ByteBuf;
6 import io.netty.channel.ChannelHandlerContext; 5 import io.netty.channel.ChannelHandlerContext;
7 import io.netty.handler.codec.ByteToMessageDecoder; 6 import io.netty.handler.codec.ByteToMessageDecoder;
src/main/java/com/genersoft/iot/vmp/jt1078/server/Session.java renamed to src/main/java/com/genersoft/iot/vmp/jtt1078/server/Session.java
1 -package com.genersoft.iot.vmp.jt1078.server; 1 +package com.genersoft.iot.vmp.jtt1078.server;
2 2
3 import java.util.HashMap; 3 import java.util.HashMap;
4 import java.util.Map; 4 import java.util.Map;
src/main/java/com/genersoft/iot/vmp/jt1078/server/SessionManager.java renamed to src/main/java/com/genersoft/iot/vmp/jtt1078/server/SessionManager.java
1 -package com.genersoft.iot.vmp.jt1078.server; 1 +package com.genersoft.iot.vmp.jtt1078.server;
2 2
3 import io.netty.channel.Channel; 3 import io.netty.channel.Channel;
  4 +import org.apache.commons.collections4.map.HashedMap;
  5 +
4 6
5 -import java.util.HashMap;  
6 import java.util.Map; 7 import java.util.Map;
7 8
8 public final class SessionManager 9 public final class SessionManager
9 { 10 {
10 - private static final Map<String, Object> mappings = new HashMap<>(); 11 + private static final Map<String, Object> mappings = new HashedMap();
11 12
12 public static void init() 13 public static void init()
13 { 14 {
@@ -28,4 +29,4 @@ public final class SessionManager @@ -28,4 +29,4 @@ public final class SessionManager
28 { 29 {
29 return mappings.containsKey(channel.id().asLongText() + key); 30 return mappings.containsKey(channel.id().asLongText() + key);
30 } 31 }
31 -}  
32 \ No newline at end of file 32 \ No newline at end of file
  33 +}
src/main/java/com/genersoft/iot/vmp/jt1078/subscriber/RTMPPublisher.java renamed to src/main/java/com/genersoft/iot/vmp/jtt1078/subscriber/RTMPPublisher.java
1 -//  
2 -// Source code recreated from a .class file by IntelliJ IDEA  
3 -// (powered by FernFlower decompiler)  
4 -// 1 +package com.genersoft.iot.vmp.jtt1078.subscriber;
5 2
6 -package com.genersoft.iot.vmp.jt1078.subscriber;  
7 -  
8 -import com.genersoft.iot.vmp.jt1078.util.Configs;  
9 -import java.io.InputStream; 3 +import com.genersoft.iot.vmp.jtt1078.util.*;
10 import org.slf4j.Logger; 4 import org.slf4j.Logger;
11 import org.slf4j.LoggerFactory; 5 import org.slf4j.LoggerFactory;
  6 +import org.springframework.data.redis.core.RedisTemplate;
  7 +
  8 +import javax.annotation.Resource;
  9 +import java.io.InputStream;
12 10
13 -public class RTMPPublisher extends Thread { 11 +public class RTMPPublisher extends Thread
  12 +{
14 static Logger logger = LoggerFactory.getLogger(RTMPPublisher.class); 13 static Logger logger = LoggerFactory.getLogger(RTMPPublisher.class);
  14 +
15 String tag = null; 15 String tag = null;
16 - private Integer port;  
17 Process process = null; 16 Process process = null;
18 17
19 - public RTMPPublisher(String tag, Integer port) { 18 + public RTMPPublisher(String tag)
  19 + {
20 this.tag = tag; 20 this.tag = tag;
21 - this.port = port;  
22 } 21 }
23 22
24 @Override 23 @Override
@@ -31,14 +30,15 @@ public class RTMPPublisher extends Thread { @@ -31,14 +30,15 @@ public class RTMPPublisher extends Thread {
31 30
32 try 31 try
33 { 32 {
34 - String rtmpUrl = Configs.get("rtmp.url").replaceAll("\\{TAG\\}", tag);  
35 - String cmd = String.format("%s -i http://localhost:%d/video/%s -vcodec copy -acodec aac -f flv %s", 33 + String sign = "41db35390ddad33f83944f44b8b75ded";
  34 + String rtmpUrl = Configs.get("rtmp.url").replaceAll("\\{TAG\\}", tag).replaceAll("\\{sign\\}",sign);
  35 + String cmd = String.format("%s -i http://127.0.0.1:%d/video/%s -vcodec copy -acodec aac -f rtsp %s",
36 Configs.get("ffmpeg.path"), 36 Configs.get("ffmpeg.path"),
37 Configs.getInt("server.http.port", 3333), 37 Configs.getInt("server.http.port", 3333),
38 tag, 38 tag,
39 rtmpUrl 39 rtmpUrl
40 ); 40 );
41 - logger.info("Execute: {}", cmd); 41 + logger.info("推流命令 Execute: {}", cmd);
42 process = Runtime.getRuntime().exec(cmd); 42 process = Runtime.getRuntime().exec(cmd);
43 stderr = process.getErrorStream(); 43 stderr = process.getErrorStream();
44 while ((len = stderr.read(buff)) > -1) 44 while ((len = stderr.read(buff)) > -1)
@@ -57,4 +57,4 @@ public class RTMPPublisher extends Thread { @@ -57,4 +57,4 @@ public class RTMPPublisher extends Thread {
57 { 57 {
58 try { if (process != null) process.destroyForcibly(); } catch(Exception e) { } 58 try { if (process != null) process.destroyForcibly(); } catch(Exception e) { }
59 } 59 }
60 -}  
61 \ No newline at end of file 60 \ No newline at end of file
  61 +}
src/main/java/com/genersoft/iot/vmp/jt1078/subscriber/Subscriber.java renamed to src/main/java/com/genersoft/iot/vmp/jtt1078/subscriber/Subscriber.java
1 -package com.genersoft.iot.vmp.jt1078.subscriber; 1 +package com.genersoft.iot.vmp.jtt1078.subscriber;
2 2
3 -import com.genersoft.iot.vmp.jt1078.flv.FlvEncoder;  
4 -import com.genersoft.iot.vmp.jt1078.util.Packet; 3 +import com.genersoft.iot.vmp.jtt1078.flv.FlvEncoder;
5 import io.netty.channel.ChannelFuture; 4 import io.netty.channel.ChannelFuture;
6 import io.netty.channel.ChannelHandlerContext; 5 import io.netty.channel.ChannelHandlerContext;
7 import org.slf4j.Logger; 6 import org.slf4j.Logger;
src/main/java/com/genersoft/iot/vmp/jt1078/subscriber/VideoSubscriber.java renamed to src/main/java/com/genersoft/iot/vmp/jtt1078/subscriber/VideoSubscriber.java
1 -package com.genersoft.iot.vmp.jt1078.subscriber;  
2 -  
3 -import com.genersoft.iot.vmp.jt1078.codec.MP3Encoder;  
4 -import com.genersoft.iot.vmp.jt1078.flv.AudioTag;  
5 -import com.genersoft.iot.vmp.jt1078.flv.FlvAudioTagEncoder;  
6 -import com.genersoft.iot.vmp.jt1078.flv.FlvEncoder;  
7 -import com.genersoft.iot.vmp.jt1078.util.ByteBufUtils;  
8 -import com.genersoft.iot.vmp.jt1078.util.FLVUtils;  
9 -import com.genersoft.iot.vmp.jt1078.util.HttpChunk; 1 +package com.genersoft.iot.vmp.jtt1078.subscriber;
  2 +
  3 +import com.genersoft.iot.vmp.jtt1078.codec.MP3Encoder;
  4 +import com.genersoft.iot.vmp.jtt1078.flv.AudioTag;
  5 +import com.genersoft.iot.vmp.jtt1078.flv.FlvAudioTagEncoder;
  6 +import com.genersoft.iot.vmp.jtt1078.flv.FlvEncoder;
  7 +import com.genersoft.iot.vmp.jtt1078.util.ByteBufUtils;
  8 +import com.genersoft.iot.vmp.jtt1078.util.FLVUtils;
  9 +import com.genersoft.iot.vmp.jtt1078.util.HttpChunk;
10 import io.netty.buffer.ByteBuf; 10 import io.netty.buffer.ByteBuf;
11 import io.netty.channel.ChannelHandlerContext; 11 import io.netty.channel.ChannelHandlerContext;
12 12
@@ -30,7 +30,6 @@ public class VideoSubscriber extends Subscriber @@ -30,7 +30,6 @@ public class VideoSubscriber extends Subscriber
30 public void onVideoData(long timeoffset, byte[] data, FlvEncoder flvEncoder) 30 public void onVideoData(long timeoffset, byte[] data, FlvEncoder flvEncoder)
31 { 31 {
32 if (lastVideoFrameTimeOffset == 0) lastVideoFrameTimeOffset = timeoffset; 32 if (lastVideoFrameTimeOffset == 0) lastVideoFrameTimeOffset = timeoffset;
33 -  
34 // 之前是不是已经发送过了?没有的话,需要补发FLV HEADER的。。。 33 // 之前是不是已经发送过了?没有的话,需要补发FLV HEADER的。。。
35 if (videoHeaderSent == false && flvEncoder.videoReady()) 34 if (videoHeaderSent == false && flvEncoder.videoReady())
36 { 35 {
@@ -47,9 +46,7 @@ public class VideoSubscriber extends Subscriber @@ -47,9 +46,7 @@ public class VideoSubscriber extends Subscriber
47 46
48 videoHeaderSent = true; 47 videoHeaderSent = true;
49 } 48 }
50 -  
51 if (data == null) return; 49 if (data == null) return;
52 -  
53 // 修改时间戳 50 // 修改时间戳
54 // System.out.println("Time: " + videoTimestamp + ", current: " + timeoffset); 51 // System.out.println("Time: " + videoTimestamp + ", current: " + timeoffset);
55 FLVUtils.resetTimestamp(data, (int) videoTimestamp); 52 FLVUtils.resetTimestamp(data, (int) videoTimestamp);
src/main/java/com/genersoft/iot/vmp/jt1078/util/Bin.java renamed to src/main/java/com/genersoft/iot/vmp/jtt1078/util/Bin.java
1 -package com.genersoft.iot.vmp.jt1078.util; 1 +package com.genersoft.iot.vmp.jtt1078.util;
2 2
3 /** 3 /**
4 * 32位整型的二进制读写 4 * 32位整型的二进制读写
src/main/java/com/genersoft/iot/vmp/jt1078/util/ByteBufUtils.java renamed to src/main/java/com/genersoft/iot/vmp/jtt1078/util/ByteBufUtils.java
1 -package com.genersoft.iot.vmp.jt1078.util; 1 +package com.genersoft.iot.vmp.jtt1078.util;
2 2
3 import io.netty.buffer.ByteBuf; 3 import io.netty.buffer.ByteBuf;
4 4
src/main/java/com/genersoft/iot/vmp/jt1078/util/ByteHolder.java renamed to src/main/java/com/genersoft/iot/vmp/jtt1078/util/ByteHolder.java
1 -package com.genersoft.iot.vmp.jt1078.util; 1 +package com.genersoft.iot.vmp.jtt1078.util;
2 2
3 import java.util.Arrays; 3 import java.util.Arrays;
4 4
@@ -93,4 +93,4 @@ public class ByteHolder @@ -93,4 +93,4 @@ public class ByteHolder
93 int l = this.buffer[position + 1] & 0xff; 93 int l = this.buffer[position + 1] & 0xff;
94 return ((h << 8) | l) & 0xffff; 94 return ((h << 8) | l) & 0xffff;
95 } 95 }
96 -}  
97 \ No newline at end of file 96 \ No newline at end of file
  97 +}
src/main/java/com/genersoft/iot/vmp/jt1078/util/ByteUtils.java renamed to src/main/java/com/genersoft/iot/vmp/jtt1078/util/ByteUtils.java
1 -package com.genersoft.iot.vmp.jt1078.util; 1 +package com.genersoft.iot.vmp.jtt1078.util;
2 2
3 /** 3 /**
4 * Created by matrixy on 2017/8/22. 4 * Created by matrixy on 2017/8/22.
src/main/java/com/genersoft/iot/vmp/jt1078/util/Configs.java renamed to src/main/java/com/genersoft/iot/vmp/jtt1078/util/Configs.java
1 -package com.genersoft.iot.vmp.jt1078.util; 1 +package com.genersoft.iot.vmp.jtt1078.util;
2 2
3 import java.io.File; 3 import java.io.File;
4 import java.io.FileInputStream; 4 import java.io.FileInputStream;
src/main/java/com/genersoft/iot/vmp/jt1078/util/FLVUtils.java renamed to src/main/java/com/genersoft/iot/vmp/jtt1078/util/FLVUtils.java
1 -package com.genersoft.iot.vmp.jt1078.util;  
2 -  
3 -import java.util.Arrays; 1 +package com.genersoft.iot.vmp.jtt1078.util;
4 2
5 /** 3 /**
6 * Created by matrixy on 2019/12/16. 4 * Created by matrixy on 2019/12/16.
src/main/java/com/genersoft/iot/vmp/jt1078/util/FileUtils.java renamed to src/main/java/com/genersoft/iot/vmp/jtt1078/util/FileUtils.java
1 -package com.genersoft.iot.vmp.jt1078.util; 1 +package com.genersoft.iot.vmp.jtt1078.util;
2 2
3 import java.io.*; 3 import java.io.*;
4 4
src/main/java/com/genersoft/iot/vmp/jt1078/util/HttpChunk.java renamed to src/main/java/com/genersoft/iot/vmp/jtt1078/util/HttpChunk.java
1 -package com.genersoft.iot.vmp.jt1078.util; 1 +package com.genersoft.iot.vmp.jtt1078.util;
2 2
3 /** 3 /**
4 * Created by matrixy on 2020/1/15. 4 * Created by matrixy on 2020/1/15.
src/main/java/com/genersoft/iot/vmp/jt1078/util/Packet.java renamed to src/main/java/com/genersoft/iot/vmp/jtt1078/util/Packet.java
1 -package com.genersoft.iot.vmp.jt1078.util; 1 +package com.genersoft.iot.vmp.jtt1078.util;
2 2
3 import java.util.Arrays; 3 import java.util.Arrays;
4 4
src/main/java/com/genersoft/iot/vmp/jt1078/util/WAVUtils.java renamed to src/main/java/com/genersoft/iot/vmp/jtt1078/util/WAVUtils.java
1 -package com.genersoft.iot.vmp.jt1078.util; 1 +package com.genersoft.iot.vmp.jtt1078.util;
2 2
3 /** 3 /**
4 * Created by matrixy on 2019/12/18. 4 * Created by matrixy on 2019/12/18.
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
@@ -29,10 +29,7 @@ import com.genersoft.iot.vmp.service.bean.SSRCInfo; @@ -29,10 +29,7 @@ import com.genersoft.iot.vmp.service.bean.SSRCInfo;
29 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 29 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
30 import com.genersoft.iot.vmp.storager.IVideoManagerStorage; 30 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
31 import com.genersoft.iot.vmp.utils.DateUtil; 31 import com.genersoft.iot.vmp.utils.DateUtil;
32 -import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;  
33 -import com.genersoft.iot.vmp.vmanager.bean.OtherPsSendInfo;  
34 -import com.genersoft.iot.vmp.vmanager.bean.OtherRtpSendInfo;  
35 -import com.genersoft.iot.vmp.vmanager.bean.StreamContent; 32 +import com.genersoft.iot.vmp.vmanager.bean.*;
36 import com.genersoft.iot.vmp.vmanager.jt1078.platform.Jt1078OfCarController; 33 import com.genersoft.iot.vmp.vmanager.jt1078.platform.Jt1078OfCarController;
37 import org.apache.commons.lang3.StringUtils; 34 import org.apache.commons.lang3.StringUtils;
38 import org.slf4j.Logger; 35 import org.slf4j.Logger;
@@ -40,6 +37,7 @@ import org.slf4j.LoggerFactory; @@ -40,6 +37,7 @@ import org.slf4j.LoggerFactory;
40 import org.springframework.beans.factory.annotation.Autowired; 37 import org.springframework.beans.factory.annotation.Autowired;
41 import org.springframework.beans.factory.annotation.Qualifier; 38 import org.springframework.beans.factory.annotation.Qualifier;
42 import org.springframework.data.redis.core.RedisTemplate; 39 import org.springframework.data.redis.core.RedisTemplate;
  40 +import org.springframework.scheduling.annotation.Scheduled;
43 import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; 41 import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
44 import org.springframework.util.ObjectUtils; 42 import org.springframework.util.ObjectUtils;
45 import org.springframework.web.bind.annotation.*; 43 import org.springframework.web.bind.annotation.*;
@@ -50,6 +48,7 @@ import javax.sip.InvalidArgumentException; @@ -50,6 +48,7 @@ import javax.sip.InvalidArgumentException;
50 import javax.sip.SipException; 48 import javax.sip.SipException;
51 import java.text.ParseException; 49 import java.text.ParseException;
52 import java.util.*; 50 import java.util.*;
  51 +import java.util.concurrent.TimeUnit;
53 52
54 /** 53 /**
55 * @description:针对 ZLMediaServer的hook事件监听 54 * @description:针对 ZLMediaServer的hook事件监听
@@ -187,7 +186,6 @@ public class ZLMHttpHookListener { @@ -187,7 +186,6 @@ public class ZLMHttpHookListener {
187 return new HookResult(401, "Unauthorized"); 186 return new HookResult(401, "Unauthorized");
188 } 187 }
189 } 188 }
190 -  
191 return HookResult.SUCCESS(); 189 return HookResult.SUCCESS();
192 } 190 }
193 191
@@ -679,8 +677,16 @@ public class ZLMHttpHookListener { @@ -679,8 +677,16 @@ public class ZLMHttpHookListener {
679 // StreamPushItem streamPushItem = streamPushService.getPush(app, streamId); 677 // StreamPushItem streamPushItem = streamPushService.getPush(app, streamId);
680 // if (streamPushItem != null) { 678 // if (streamPushItem != null) {
681 // // TODO 发送停止 679 // // TODO 发送停止
682 -//  
683 // } 680 // }
  681 + //推流需要更新缓存数据以防止端口占用
  682 + logger.info("无人观看流 ---> {}", JSONObject.toJSONString(param));
  683 + Object object = redisTemplate.opsForValue().get("patrol:stream:" + param.getStream());
  684 + if (object == null) {
  685 + String[] split = param.getStream().split("_");
  686 + if (split != null && split.length == 2) {
  687 + jt1078OfCarController.clearMap(split[1],split[0]);
  688 + }
  689 + }
684 } 690 }
685 return ret; 691 return ret;
686 } 692 }
@@ -700,7 +706,6 @@ public class ZLMHttpHookListener { @@ -700,7 +706,6 @@ public class ZLMHttpHookListener {
700 defaultResult.setResult(new HookResult(ErrorCode.ERROR404.getCode(), ErrorCode.ERROR404.getMsg())); 706 defaultResult.setResult(new HookResult(ErrorCode.ERROR404.getCode(), ErrorCode.ERROR404.getMsg()));
701 return defaultResult; 707 return defaultResult;
702 } 708 }
703 -  
704 if ("rtp".equals(param.getApp())) { 709 if ("rtp".equals(param.getApp())) {
705 String[] s = param.getStream().split("_"); 710 String[] s = param.getStream().split("_");
706 if ((s.length != 2 && s.length != 4)) { 711 if ((s.length != 2 && s.length != 4)) {
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java
@@ -18,6 +18,9 @@ import java.util.Map; @@ -18,6 +18,9 @@ import java.util.Map;
18 import java.util.Objects; 18 import java.util.Objects;
19 import java.util.concurrent.TimeUnit; 19 import java.util.concurrent.TimeUnit;
20 20
  21 +/**
  22 + * ZLM工具类
  23 + */
21 @Component 24 @Component
22 public class ZLMRESTfulUtils { 25 public class ZLMRESTfulUtils {
23 26
src/main/java/com/genersoft/iot/vmp/service/IStreamProxyService.java
@@ -114,6 +114,10 @@ public interface IStreamProxyService { @@ -114,6 +114,10 @@ public interface IStreamProxyService {
114 * 更新代理流 114 * 更新代理流
115 */ 115 */
116 boolean updateStreamProxy(StreamProxyItem streamProxyItem); 116 boolean updateStreamProxy(StreamProxyItem streamProxyItem);
  117 + /**
  118 + * 更新代理流
  119 + */
  120 + boolean updateStreamProxy(StreamProxyItem streamProxyItem, GeneralCallback<StreamInfo> callback);
117 121
118 /** 122 /**
119 * 获取统计信息 123 * 获取统计信息
src/main/java/com/genersoft/iot/vmp/service/IStreamPushService.java
@@ -7,6 +7,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; @@ -7,6 +7,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
7 import com.genersoft.iot.vmp.service.bean.StreamPushItemFromRedis; 7 import com.genersoft.iot.vmp.service.bean.StreamPushItemFromRedis;
8 import com.genersoft.iot.vmp.vmanager.bean.ResourceBaseInfo; 8 import com.genersoft.iot.vmp.vmanager.bean.ResourceBaseInfo;
9 import com.github.pagehelper.PageInfo; 9 import com.github.pagehelper.PageInfo;
  10 +import org.springframework.scheduling.annotation.Scheduled;
10 11
11 import java.util.List; 12 import java.util.List;
12 import java.util.Map; 13 import java.util.Map;
src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java
@@ -193,6 +193,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService { @@ -193,6 +193,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
193 callback.run(ErrorCode.ERROR100.getCode(), "超时", null); 193 callback.run(ErrorCode.ERROR100.getCode(), "超时", null);
194 } 194 }
195 }, 7000); 195 }, 7000);
  196 + //TODO
196 JSONObject jsonObject = addStreamProxyToZlm(param); 197 JSONObject jsonObject = addStreamProxyToZlm(param);
197 if (jsonObject != null && jsonObject.getInteger("code") == 0) { 198 if (jsonObject != null && jsonObject.getInteger("code") == 0) {
198 hookSubscribe.removeSubscribe(hookSubscribeForStreamChange); 199 hookSubscribe.removeSubscribe(hookSubscribeForStreamChange);
@@ -273,8 +274,6 @@ public class StreamProxyServiceImpl implements IStreamProxyService { @@ -273,8 +274,6 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
273 logger.error("向数据库添加流代理失败:", e); 274 logger.error("向数据库添加流代理失败:", e);
274 dataSourceTransactionManager.rollback(transactionStatus); 275 dataSourceTransactionManager.rollback(transactionStatus);
275 } 276 }
276 -  
277 -  
278 return result; 277 return result;
279 } 278 }
280 279
@@ -312,6 +311,42 @@ public class StreamProxyServiceImpl implements IStreamProxyService { @@ -312,6 +311,42 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
312 } 311 }
313 return result; 312 return result;
314 } 313 }
  314 + /**
  315 + * 更新代理流
  316 + *
  317 + * @param streamProxyItem
  318 + * @return
  319 + */
  320 + @Override
  321 + public boolean updateStreamProxy(StreamProxyItem streamProxyItem, GeneralCallback<StreamInfo> callback) {
  322 + TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
  323 + boolean result = false;
  324 + streamProxyItem.setStreamType("proxy");
  325 + try {
  326 + if (streamProxyMapper.update(streamProxyItem) > 0) {
  327 + if (!ObjectUtils.isEmpty(streamProxyItem.getGbId())) {
  328 + if (gbStreamMapper.updateByAppAndStream(streamProxyItem) == 0) {
  329 + //事务回滚
  330 + dataSourceTransactionManager.rollback(transactionStatus);
  331 + callback.run(ErrorCode.ERROR100.getCode(), ErrorCode.ERROR100.getMsg(), null);
  332 + return false;
  333 + }
  334 + }
  335 + } else {
  336 + //事务回滚
  337 + dataSourceTransactionManager.rollback(transactionStatus);
  338 + callback.run(ErrorCode.ERROR100.getCode(), ErrorCode.ERROR100.getMsg(), null);
  339 + return false;
  340 + }
  341 + callback.run(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg(), null);
  342 + dataSourceTransactionManager.commit(transactionStatus); //手动提交
  343 + result = true;
  344 + } catch (Exception e) {
  345 + logger.error("未处理的异常 ", e);
  346 + dataSourceTransactionManager.rollback(transactionStatus);
  347 + }
  348 + return result;
  349 + }
315 350
316 @Override 351 @Override
317 public JSONObject addStreamProxyToZlm(StreamProxyItem param) { 352 public JSONObject addStreamProxyToZlm(StreamProxyItem param) {
@@ -491,8 +526,10 @@ public class StreamProxyServiceImpl implements IStreamProxyService { @@ -491,8 +526,10 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
491 @Override 526 @Override
492 public void zlmServerOnline(String mediaServerId) { 527 public void zlmServerOnline(String mediaServerId) {
493 // 移除开启了无人观看自动移除的流 528 // 移除开启了无人观看自动移除的流
  529 + choose1078HistoryLister();
494 530
495 choose1078Lister(); 531 choose1078Lister();
  532 +
496 List<StreamProxyItem> streamProxyItemList = streamProxyMapper.selectAutoRemoveItemByMediaServerId(mediaServerId); 533 List<StreamProxyItem> streamProxyItemList = streamProxyMapper.selectAutoRemoveItemByMediaServerId(mediaServerId);
497 if (streamProxyItemList.size() > 0) { 534 if (streamProxyItemList.size() > 0) {
498 gbStreamMapper.batchDel(streamProxyItemList); 535 gbStreamMapper.batchDel(streamProxyItemList);
@@ -647,7 +684,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService { @@ -647,7 +684,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
647 } 684 }
648 685
649 686
650 - public void choose1078Lister() { 687 + public void choose1078HistoryLister() {
651 Set<String> keys = redisTemplate.keys("tag:history:port:*"); 688 Set<String> keys = redisTemplate.keys("tag:history:port:*");
652 if (org.apache.commons.collections4.CollectionUtils.isEmpty(keys)) { 689 if (org.apache.commons.collections4.CollectionUtils.isEmpty(keys)) {
653 return; 690 return;
@@ -680,10 +717,45 @@ public class StreamProxyServiceImpl implements IStreamProxyService { @@ -680,10 +717,45 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
680 logger.error("[{}]停流失败", stream, e); 717 logger.error("[{}]停流失败", stream, e);
681 } 718 }
682 } 719 }
683 -  
684 // task execution logic 720 // task execution logic
685 } 721 }
686 722
  723 +
  724 + public void choose1078Lister() {
  725 + Set<String> keys = redisTemplate.keys("tag:history:port:*");
  726 + if (org.apache.commons.collections4.CollectionUtils.isEmpty(keys)) {
  727 + return;
  728 + }
  729 + Long nowDate = new Date().getTime();
  730 + for (String key : keys) {
  731 + String stream = StringUtils.substringAfter(key, "tag:history:port:");
  732 + if (StringUtils.isEmpty(stream)) {
  733 + continue;
  734 + }
  735 +
  736 + Object value = redisTemplate.opsForValue().get("tag:history:httpPort:time:" + stream);
  737 + if (Objects.isNull(value)) {
  738 + sendIORequestStop(stream);
  739 + continue;
  740 + }
  741 + try {
  742 + Long val = (Long) value;
  743 + if (val == 0L) {
  744 + sendIORequestStop(stream);
  745 + continue;
  746 + }
  747 +
  748 + Long val1 = (nowDate - val) / 1000;
  749 + if (val1 > StreamProxyTask.TIME_OUT) {
  750 + sendIORequestStop(stream);
  751 + }
  752 +
  753 + } catch (Exception e) {
  754 + logger.error("[{}]停流失败", stream, e);
  755 + }
  756 + }
  757 + }
  758 +
687 private void sendIORequestStop(String stream) { 759 private void sendIORequestStop(String stream) {
688 try { 760 try {
689 String sim = StringUtils.substringBeforeLast(stream, "-"); 761 String sim = StringUtils.substringBeforeLast(stream, "-");
src/main/java/com/genersoft/iot/vmp/service/impl/StremProxyService1078Impl.java
1 package com.genersoft.iot.vmp.service.impl; 1 package com.genersoft.iot.vmp.service.impl;
2 2
3 import com.genersoft.iot.vmp.VManageBootstrap; 3 import com.genersoft.iot.vmp.VManageBootstrap;
4 -import com.genersoft.iot.vmp.jt1078.app.VideoServerApp;  
5 import com.genersoft.iot.vmp.service.IStreamProxyService; 4 import com.genersoft.iot.vmp.service.IStreamProxyService;
6 import com.genersoft.iot.vmp.service.StremProxyService1078; 5 import com.genersoft.iot.vmp.service.StremProxyService1078;
7 import com.genersoft.iot.vmp.vmanager.jt1078.platform.ben.HttpClientPostEntity; 6 import com.genersoft.iot.vmp.vmanager.jt1078.platform.ben.HttpClientPostEntity;
8 import com.genersoft.iot.vmp.vmanager.jt1078.platform.config.Jt1078ConfigBean; 7 import com.genersoft.iot.vmp.vmanager.jt1078.platform.config.Jt1078ConfigBean;
9 import com.genersoft.iot.vmp.vmanager.jt1078.platform.handler.HttpClientUtil; 8 import com.genersoft.iot.vmp.vmanager.jt1078.platform.handler.HttpClientUtil;
10 -import org.apache.commons.collections4.CollectionUtils;  
11 import org.apache.commons.lang3.StringUtils; 9 import org.apache.commons.lang3.StringUtils;
12 import org.slf4j.Logger; 10 import org.slf4j.Logger;
13 import org.slf4j.LoggerFactory; 11 import org.slf4j.LoggerFactory;
14 import org.springframework.beans.factory.annotation.Autowired; 12 import org.springframework.beans.factory.annotation.Autowired;
15 import org.springframework.data.redis.core.RedisTemplate; 13 import org.springframework.data.redis.core.RedisTemplate;
16 import org.springframework.stereotype.Service; 14 import org.springframework.stereotype.Service;
17 -import org.springframework.web.bind.annotation.PathVariable;  
18 15
19 import java.io.IOException; 16 import java.io.IOException;
20 import java.net.URISyntaxException; 17 import java.net.URISyntaxException;
21 import java.util.HashMap; 18 import java.util.HashMap;
22 -import java.util.List;  
23 import java.util.Map; 19 import java.util.Map;
24 import java.util.Objects; 20 import java.util.Objects;
25 import java.util.concurrent.TimeUnit; 21 import java.util.concurrent.TimeUnit;
@@ -35,10 +31,8 @@ public class StremProxyService1078Impl implements StremProxyService1078 { @@ -35,10 +31,8 @@ public class StremProxyService1078Impl implements StremProxyService1078 {
35 @Autowired 31 @Autowired
36 private RedisTemplate<Object, Object> redisTemplate; 32 private RedisTemplate<Object, Object> redisTemplate;
37 33
38 -  
39 private static final Logger log = LoggerFactory.getLogger(StremProxyService1078Impl.class); 34 private static final Logger log = LoggerFactory.getLogger(StremProxyService1078Impl.class);
40 35
41 -  
42 @Override 36 @Override
43 public Map<String, Object> sendIORequestStop(String sim, String channel, String stream, Integer port, Integer httpPort) { 37 public Map<String, Object> sendIORequestStop(String sim, String channel, String stream, Integer port, Integer httpPort) {
44 Map<String, Object> resultMap = new HashMap<>(); 38 Map<String, Object> resultMap = new HashMap<>();
@@ -70,7 +64,7 @@ public class StremProxyService1078Impl implements StremProxyService1078 { @@ -70,7 +64,7 @@ public class StremProxyService1078Impl implements StremProxyService1078 {
70 } 64 }
71 log.info("port:[{}]",port); 65 log.info("port:[{}]",port);
72 if(Objects.nonNull(port)){ 66 if(Objects.nonNull(port)){
73 - VideoServerApp.stopServer(port,httpPort); 67 +// VideoServerApp.stopServer(port,httpPort);
74 } 68 }
75 69
76 70
src/main/java/com/genersoft/iot/vmp/utils/JsonUtil.java
@@ -31,4 +31,13 @@ public final class JsonUtil { @@ -31,4 +31,13 @@ public final class JsonUtil {
31 } 31 }
32 return clazz.cast(jsonObject); 32 return clazz.cast(jsonObject);
33 } 33 }
34 -}  
35 \ No newline at end of file 34 \ No newline at end of file
  35 +
  36 + /**
  37 + * 存入redis
  38 + * @param key redis key
  39 + * @param object redis value
  40 + */
  41 + public static void redisJsonToObject(RedisTemplate<Object, Object> redisTemplate, String key, Object object) {
  42 + redisTemplate.opsForValue().set(key, object);
  43 + }
  44 +}
src/main/java/com/genersoft/iot/vmp/vmanager/bean/ErrorCode.java
@@ -10,7 +10,11 @@ public enum ErrorCode { @@ -10,7 +10,11 @@ public enum ErrorCode {
10 ERROR404(404, "资源未找到"), 10 ERROR404(404, "资源未找到"),
11 ERROR403(403, "无权限操作"), 11 ERROR403(403, "无权限操作"),
12 ERROR401(401, "请登录后重新请求"), 12 ERROR401(401, "请登录后重新请求"),
13 - ERROR500(500, "系统异常"); 13 + ERROR500(500, "系统异常"),
  14 + ERROR450(450, "新建链接错误,请稍后再试"),
  15 + ERROR420(420, "发送推流指令异常"),
  16 + ERROR301(301, "下发指令异常"),
  17 + ERROR304(304, "离线的客户端(请检查设备是否注册或者鉴权");
14 18
15 private final int code; 19 private final int code;
16 private final String msg; 20 private final String msg;
src/main/java/com/genersoft/iot/vmp/vmanager/bean/StreamContent.java
@@ -4,96 +4,202 @@ import com.genersoft.iot.vmp.common.StreamInfo; @@ -4,96 +4,202 @@ import com.genersoft.iot.vmp.common.StreamInfo;
4 import com.genersoft.iot.vmp.service.bean.DownloadFileInfo; 4 import com.genersoft.iot.vmp.service.bean.DownloadFileInfo;
5 import io.swagger.v3.oas.annotations.media.Schema; 5 import io.swagger.v3.oas.annotations.media.Schema;
6 6
  7 +/**
  8 + * 流信息
  9 + */
7 @Schema(description = "流信息") 10 @Schema(description = "流信息")
8 public class StreamContent { 11 public class StreamContent {
9 12
  13 + /**
  14 + * 应用名
  15 + */
10 @Schema(description = "应用名") 16 @Schema(description = "应用名")
11 private String app; 17 private String app;
12 18
  19 +
  20 + /**
  21 + * http端口
  22 + */
  23 + @Schema(description = "http端口")
  24 + private Integer httpPort;
  25 +
  26 + /**
  27 + * 接受流端口
  28 + */
  29 + @Schema(description = "接受流端口")
  30 + private Integer port;
  31 +
  32 + /**
  33 + * 流ID
  34 + */
13 @Schema(description = "流ID") 35 @Schema(description = "流ID")
14 private String stream; 36 private String stream;
15 37
  38 + /**
  39 + * IP
  40 + */
16 @Schema(description = "IP") 41 @Schema(description = "IP")
17 private String ip; 42 private String ip;
18 43
  44 + /**
  45 + * HTTP-FLV流地址
  46 + */
19 @Schema(description = "HTTP-FLV流地址") 47 @Schema(description = "HTTP-FLV流地址")
20 private String flv; 48 private String flv;
21 49
  50 + /**
  51 + * HTTPS-FLV流地址
  52 + */
22 @Schema(description = "HTTPS-FLV流地址") 53 @Schema(description = "HTTPS-FLV流地址")
23 private String https_flv; 54 private String https_flv;
24 55
  56 + /**
  57 + * Websocket-FLV流地址
  58 + */
25 @Schema(description = "Websocket-FLV流地址") 59 @Schema(description = "Websocket-FLV流地址")
26 private String ws_flv; 60 private String ws_flv;
27 61
  62 + /**
  63 + * Websockets-FLV流地址
  64 + */
28 @Schema(description = "Websockets-FLV流地址") 65 @Schema(description = "Websockets-FLV流地址")
29 private String wss_flv; 66 private String wss_flv;
30 67
  68 + /**
  69 + * HTTP-FMP4流地址
  70 + */
31 @Schema(description = "HTTP-FMP4流地址") 71 @Schema(description = "HTTP-FMP4流地址")
32 private String fmp4; 72 private String fmp4;
33 73
  74 + /**
  75 + * HTTPS-FMP4流地址
  76 + */
34 @Schema(description = "HTTPS-FMP4流地址") 77 @Schema(description = "HTTPS-FMP4流地址")
35 private String https_fmp4; 78 private String https_fmp4;
36 79
  80 + /**
  81 + * Websocket-FMP4流地址
  82 + */
37 @Schema(description = "Websocket-FMP4流地址") 83 @Schema(description = "Websocket-FMP4流地址")
38 private String ws_fmp4; 84 private String ws_fmp4;
39 85
  86 + /**
  87 + * Websockets-FMP4流地址
  88 + */
40 @Schema(description = "Websockets-FMP4流地址") 89 @Schema(description = "Websockets-FMP4流地址")
41 private String wss_fmp4; 90 private String wss_fmp4;
42 91
  92 + /**
  93 + * HLS流地址
  94 + */
43 @Schema(description = "HLS流地址") 95 @Schema(description = "HLS流地址")
44 private String hls; 96 private String hls;
45 97
  98 + /**
  99 + * HTTPS-HLS流地址
  100 + */
46 @Schema(description = "HTTPS-HLS流地址") 101 @Schema(description = "HTTPS-HLS流地址")
47 private String https_hls; 102 private String https_hls;
48 103
  104 + /**
  105 + * Websocket-HLS流地址
  106 + */
49 @Schema(description = "Websocket-HLS流地址") 107 @Schema(description = "Websocket-HLS流地址")
50 private String ws_hls; 108 private String ws_hls;
51 109
  110 + /**
  111 + * Websockets-HLS流地址
  112 + */
52 @Schema(description = "Websockets-HLS流地址") 113 @Schema(description = "Websockets-HLS流地址")
53 private String wss_hls; 114 private String wss_hls;
54 115
  116 + /**
  117 + * HTTP-TS流地址
  118 + */
55 @Schema(description = "HTTP-TS流地址") 119 @Schema(description = "HTTP-TS流地址")
56 private String ts; 120 private String ts;
57 121
  122 + /**
  123 + * HTTPS-TS流地址
  124 + */
58 @Schema(description = "HTTPS-TS流地址") 125 @Schema(description = "HTTPS-TS流地址")
59 private String https_ts; 126 private String https_ts;
60 127
  128 + /**
  129 + * Websocket-TS流地址
  130 + */
61 @Schema(description = "Websocket-TS流地址") 131 @Schema(description = "Websocket-TS流地址")
62 private String ws_ts; 132 private String ws_ts;
63 133
  134 + /**
  135 + * Websockets-TS流地址
  136 + */
64 @Schema(description = "Websockets-TS流地址") 137 @Schema(description = "Websockets-TS流地址")
65 private String wss_ts; 138 private String wss_ts;
66 139
  140 + /**
  141 + * RTMP流地址
  142 + */
67 @Schema(description = "RTMP流地址") 143 @Schema(description = "RTMP流地址")
68 private String rtmp; 144 private String rtmp;
69 145
  146 + /**
  147 + * RTMPS流地址
  148 + */
70 @Schema(description = "RTMPS流地址") 149 @Schema(description = "RTMPS流地址")
71 private String rtmps; 150 private String rtmps;
72 151
  152 + /**
  153 + * RTSP流地址
  154 + */
73 @Schema(description = "RTSP流地址") 155 @Schema(description = "RTSP流地址")
74 private String rtsp; 156 private String rtsp;
75 157
  158 + /**
  159 + * RTSPS流地址
  160 + */
76 @Schema(description = "RTSPS流地址") 161 @Schema(description = "RTSPS流地址")
77 private String rtsps; 162 private String rtsps;
78 163
  164 + /**
  165 + * RTC流地址
  166 + */
79 @Schema(description = "RTC流地址") 167 @Schema(description = "RTC流地址")
80 private String rtc; 168 private String rtc;
81 169
  170 + /**
  171 + * RTCS流地址
  172 + */
82 @Schema(description = "RTCS流地址") 173 @Schema(description = "RTCS流地址")
83 private String rtcs; 174 private String rtcs;
84 175
  176 + /**
  177 + * 流媒体ID
  178 + */
85 @Schema(description = "流媒体ID") 179 @Schema(description = "流媒体ID")
86 private String mediaServerId; 180 private String mediaServerId;
87 181
  182 + /**
  183 + * 流编码信息
  184 + */
88 @Schema(description = "流编码信息") 185 @Schema(description = "流编码信息")
89 private Object tracks; 186 private Object tracks;
90 187
  188 + /**
  189 + * 开始时间
  190 + */
91 @Schema(description = "开始时间") 191 @Schema(description = "开始时间")
92 private String startTime; 192 private String startTime;
93 193
  194 + /**
  195 + * 结束时间
  196 + */
94 @Schema(description = "结束时间") 197 @Schema(description = "结束时间")
95 private String endTime; 198 private String endTime;
96 199
  200 + /**
  201 + * 文件下载地址
  202 + */
97 @Schema(description = "文件下载地址(录像下载使用)") 203 @Schema(description = "文件下载地址(录像下载使用)")
98 private DownloadFileInfo downLoadFilePath; 204 private DownloadFileInfo downLoadFilePath;
99 205
@@ -102,6 +208,23 @@ public class StreamContent { @@ -102,6 +208,23 @@ public class StreamContent {
102 public StreamContent(){ 208 public StreamContent(){
103 209
104 } 210 }
  211 +
  212 + public Integer getHttpPort() {
  213 + return httpPort;
  214 + }
  215 +
  216 + public void setHttpPort(Integer httpPort) {
  217 + this.httpPort = httpPort;
  218 + }
  219 +
  220 + public Integer getPort() {
  221 + return port;
  222 + }
  223 +
  224 + public void setPort(Integer port) {
  225 + this.port = port;
  226 + }
  227 +
105 public StreamContent(StreamInfo streamInfo) { 228 public StreamContent(StreamInfo streamInfo) {
106 if (streamInfo == null) { 229 if (streamInfo == null) {
107 return; 230 return;
src/main/java/com/genersoft/iot/vmp/vmanager/bean/StreamPlayPath.java 0 → 100644
  1 +package com.genersoft.iot.vmp.vmanager.bean;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +
  5 +/**
  6 + * 视频流播放地址对象
  7 + *
  8 + * @Author WangXin
  9 + * @Data 2025/1/14
  10 + * @Version 1.0.0
  11 + */
  12 +@Schema(description = "视频流播放地址对象")
  13 +public class StreamPlayPath {
  14 + /**
  15 + * 应用名
  16 + */
  17 + @Schema(description = "应用名")
  18 + private String app;
  19 +
  20 + /**
  21 + * 流ID
  22 + */
  23 + @Schema(description = "流ID")
  24 + private String stream;
  25 +
  26 + /**
  27 + * IP
  28 + */
  29 + @Schema(description = "IP")
  30 + private String ip;
  31 +
  32 + /**
  33 + * HTTP-FLV流地址
  34 + */
  35 + @Schema(description = "HTTP-FLV流地址")
  36 + private String flv;
  37 +
  38 + /**
  39 + * HTTPS-FLV流地址
  40 + */
  41 + @Schema(description = "HTTPS-FLV流地址")
  42 + private String https_flv;
  43 +
  44 + /**
  45 + * Websocket-FLV流地址
  46 + */
  47 + @Schema(description = "Websocket-FLV流地址")
  48 + private String ws_flv;
  49 +
  50 + /**
  51 + * Websockets-FLV流地址
  52 + */
  53 + @Schema(description = "Websockets-FLV流地址")
  54 + private String wss_flv;
  55 +
  56 + /**
  57 + * HTTP-FMP4流地址
  58 + */
  59 + @Schema(description = "HTTP-FMP4流地址")
  60 + private String fmp4;
  61 +
  62 + /**
  63 + * HTTPS-FMP4流地址
  64 + */
  65 + @Schema(description = "HTTPS-FMP4流地址")
  66 + private String https_fmp4;
  67 +
  68 + /**
  69 + * Websocket-FMP4流地址
  70 + */
  71 + @Schema(description = "Websocket-FMP4流地址")
  72 + private String ws_fmp4;
  73 +
  74 + /**
  75 + * Websockets-FMP4流地址
  76 + */
  77 + @Schema(description = "Websockets-FMP4流地址")
  78 + private String wss_fmp4;
  79 +
  80 + /**
  81 + * HLS流地址
  82 + */
  83 + @Schema(description = "HLS流地址")
  84 + private String hls;
  85 +
  86 + /**
  87 + * HTTPS-HLS流地址
  88 + */
  89 + @Schema(description = "HTTPS-HLS流地址")
  90 + private String https_hls;
  91 +
  92 + /**
  93 + * Websocket-HLS流地址
  94 + */
  95 + @Schema(description = "Websocket-HLS流地址")
  96 + private String ws_hls;
  97 +
  98 + /**
  99 + * Websockets-HLS流地址
  100 + */
  101 + @Schema(description = "Websockets-HLS流地址")
  102 + private String wss_hls;
  103 +
  104 + /**
  105 + * HTTP-TS流地址
  106 + */
  107 + @Schema(description = "HTTP-TS流地址")
  108 + private String ts;
  109 +
  110 + /**
  111 + * HTTPS-TS流地址
  112 + */
  113 + @Schema(description = "HTTPS-TS流地址")
  114 + private String https_ts;
  115 +
  116 + /**
  117 + * Websocket-TS流地址
  118 + */
  119 + @Schema(description = "Websocket-TS流地址")
  120 + private String ws_ts;
  121 +
  122 + /**
  123 + * Websockets-TS流地址
  124 + */
  125 + @Schema(description = "Websockets-TS流地址")
  126 + private String wss_ts;
  127 +
  128 + /**
  129 + * RTMP流地址
  130 + */
  131 + @Schema(description = "RTMP流地址")
  132 + private String rtmp;
  133 +
  134 + /**
  135 + * RTMPS流地址
  136 + */
  137 + @Schema(description = "RTMPS流地址")
  138 + private String rtmps;
  139 +
  140 + /**
  141 + * RTSP流地址
  142 + */
  143 + @Schema(description = "RTSP流地址")
  144 + private String rtsp;
  145 +
  146 + /**
  147 + * RTSPS流地址
  148 + */
  149 + @Schema(description = "RTSPS流地址")
  150 + private String rtsps;
  151 +
  152 + /**
  153 + * RTC流地址
  154 + */
  155 + @Schema(description = "RTC流地址")
  156 + private String rtc;
  157 +
  158 + /**
  159 + * RTCS流地址
  160 + */
  161 + @Schema(description = "RTCS流地址")
  162 + private String rtcs;
  163 +
  164 + public String getApp() {
  165 + return app;
  166 + }
  167 +
  168 + public void setApp(String app) {
  169 + this.app = app;
  170 + }
  171 +
  172 + public String getStream() {
  173 + return stream;
  174 + }
  175 +
  176 + public void setStream(String stream) {
  177 + this.stream = stream;
  178 + }
  179 +
  180 + public String getIp() {
  181 + return ip;
  182 + }
  183 +
  184 + public void setIp(String ip) {
  185 + this.ip = ip;
  186 + }
  187 +
  188 + public String getFlv() {
  189 + return flv;
  190 + }
  191 +
  192 + public void setFlv(String flv) {
  193 + this.flv = flv;
  194 + }
  195 +
  196 + public String getHttps_flv() {
  197 + return https_flv;
  198 + }
  199 +
  200 + public void setHttps_flv(String https_flv) {
  201 + this.https_flv = https_flv;
  202 + }
  203 +
  204 + public String getWs_flv() {
  205 + return ws_flv;
  206 + }
  207 +
  208 + public void setWs_flv(String ws_flv) {
  209 + this.ws_flv = ws_flv;
  210 + }
  211 +
  212 + public String getWss_flv() {
  213 + return wss_flv;
  214 + }
  215 +
  216 + public void setWss_flv(String wss_flv) {
  217 + this.wss_flv = wss_flv;
  218 + }
  219 +
  220 + public String getFmp4() {
  221 + return fmp4;
  222 + }
  223 +
  224 + public void setFmp4(String fmp4) {
  225 + this.fmp4 = fmp4;
  226 + }
  227 +
  228 + public String getHttps_fmp4() {
  229 + return https_fmp4;
  230 + }
  231 +
  232 + public void setHttps_fmp4(String https_fmp4) {
  233 + this.https_fmp4 = https_fmp4;
  234 + }
  235 +
  236 + public String getWs_fmp4() {
  237 + return ws_fmp4;
  238 + }
  239 +
  240 + public void setWs_fmp4(String ws_fmp4) {
  241 + this.ws_fmp4 = ws_fmp4;
  242 + }
  243 +
  244 + public String getWss_fmp4() {
  245 + return wss_fmp4;
  246 + }
  247 +
  248 + public void setWss_fmp4(String wss_fmp4) {
  249 + this.wss_fmp4 = wss_fmp4;
  250 + }
  251 +
  252 + public String getHls() {
  253 + return hls;
  254 + }
  255 +
  256 + public void setHls(String hls) {
  257 + this.hls = hls;
  258 + }
  259 +
  260 + public String getHttps_hls() {
  261 + return https_hls;
  262 + }
  263 +
  264 + public void setHttps_hls(String https_hls) {
  265 + this.https_hls = https_hls;
  266 + }
  267 +
  268 + public String getWs_hls() {
  269 + return ws_hls;
  270 + }
  271 +
  272 + public void setWs_hls(String ws_hls) {
  273 + this.ws_hls = ws_hls;
  274 + }
  275 +
  276 + public String getWss_hls() {
  277 + return wss_hls;
  278 + }
  279 +
  280 + public void setWss_hls(String wss_hls) {
  281 + this.wss_hls = wss_hls;
  282 + }
  283 +
  284 + public String getTs() {
  285 + return ts;
  286 + }
  287 +
  288 + public void setTs(String ts) {
  289 + this.ts = ts;
  290 + }
  291 +
  292 + public String getHttps_ts() {
  293 + return https_ts;
  294 + }
  295 +
  296 + public void setHttps_ts(String https_ts) {
  297 + this.https_ts = https_ts;
  298 + }
  299 +
  300 + public String getWs_ts() {
  301 + return ws_ts;
  302 + }
  303 +
  304 + public void setWs_ts(String ws_ts) {
  305 + this.ws_ts = ws_ts;
  306 + }
  307 +
  308 + public String getWss_ts() {
  309 + return wss_ts;
  310 + }
  311 +
  312 + public void setWss_ts(String wss_ts) {
  313 + this.wss_ts = wss_ts;
  314 + }
  315 +
  316 + public String getRtmp() {
  317 + return rtmp;
  318 + }
  319 +
  320 + public void setRtmp(String rtmp) {
  321 + this.rtmp = rtmp;
  322 + }
  323 +
  324 + public String getRtmps() {
  325 + return rtmps;
  326 + }
  327 +
  328 + public void setRtmps(String rtmps) {
  329 + this.rtmps = rtmps;
  330 + }
  331 +
  332 + public String getRtsp() {
  333 + return rtsp;
  334 + }
  335 +
  336 + public void setRtsp(String rtsp) {
  337 + this.rtsp = rtsp;
  338 + }
  339 +
  340 + public String getRtsps() {
  341 + return rtsps;
  342 + }
  343 +
  344 + public void setRtsps(String rtsps) {
  345 + this.rtsps = rtsps;
  346 + }
  347 +
  348 + public String getRtc() {
  349 + return rtc;
  350 + }
  351 +
  352 + public void setRtc(String rtc) {
  353 + this.rtc = rtc;
  354 + }
  355 +
  356 + public String getRtcs() {
  357 + return rtcs;
  358 + }
  359 +
  360 + public void setRtcs(String rtcs) {
  361 + this.rtcs = rtcs;
  362 + }
  363 +
  364 + @Override
  365 + public String toString() {
  366 + final StringBuilder sb = new StringBuilder("StreamPlayPath{");
  367 + sb.append("app='").append(app).append('\'');
  368 + sb.append(", stream='").append(stream).append('\'');
  369 + sb.append(", ip='").append(ip).append('\'');
  370 + sb.append(", flv='").append(flv).append('\'');
  371 + sb.append(", https_flv='").append(https_flv).append('\'');
  372 + sb.append(", ws_flv='").append(ws_flv).append('\'');
  373 + sb.append(", wss_flv='").append(wss_flv).append('\'');
  374 + sb.append(", fmp4='").append(fmp4).append('\'');
  375 + sb.append(", https_fmp4='").append(https_fmp4).append('\'');
  376 + sb.append(", ws_fmp4='").append(ws_fmp4).append('\'');
  377 + sb.append(", wss_fmp4='").append(wss_fmp4).append('\'');
  378 + sb.append(", hls='").append(hls).append('\'');
  379 + sb.append(", https_hls='").append(https_hls).append('\'');
  380 + sb.append(", ws_hls='").append(ws_hls).append('\'');
  381 + sb.append(", wss_hls='").append(wss_hls).append('\'');
  382 + sb.append(", ts='").append(ts).append('\'');
  383 + sb.append(", https_ts='").append(https_ts).append('\'');
  384 + sb.append(", ws_ts='").append(ws_ts).append('\'');
  385 + sb.append(", wss_ts='").append(wss_ts).append('\'');
  386 + sb.append(", rtmp='").append(rtmp).append('\'');
  387 + sb.append(", rtmps='").append(rtmps).append('\'');
  388 + sb.append(", rtsp='").append(rtsp).append('\'');
  389 + sb.append(", rtsps='").append(rtsps).append('\'');
  390 + sb.append(", rtc='").append(rtc).append('\'');
  391 + sb.append(", rtcs='").append(rtcs).append('\'');
  392 + sb.append('}');
  393 + return sb.toString();
  394 + }
  395 +
  396 + public static StreamPlayPath build(StreamContent streamContent,String stream){
  397 + StreamPlayPath streamPlayPath = new StreamPlayPath();
  398 + streamPlayPath.setApp(streamContent.getApp());
  399 + streamPlayPath.setStream(streamContent.getStream()==null?stream:streamContent.getStream());
  400 + streamPlayPath.setIp(streamContent.getIp());
  401 + streamPlayPath.setFlv(streamContent.getFlv());
  402 + streamPlayPath.setHttps_flv(streamContent.getHttps_flv());
  403 + streamPlayPath.setWs_flv(streamContent.getWs_flv());
  404 + streamPlayPath.setWss_flv(streamContent.getWss_flv());
  405 + streamPlayPath.setFmp4(streamContent.getFmp4());
  406 + streamPlayPath.setHttps_fmp4(streamContent.getHttps_fmp4());
  407 + streamPlayPath.setWs_fmp4(streamContent.getWs_fmp4());
  408 + streamPlayPath.setWss_fmp4(streamContent.getWss_fmp4());
  409 + streamPlayPath.setHls(streamContent.getHls());
  410 + streamPlayPath.setHttps_hls(streamContent.getHttps_hls());
  411 + streamPlayPath.setWs_hls(streamContent.getWs_hls());
  412 + streamPlayPath.setWss_hls(streamContent.getWss_hls());
  413 + streamPlayPath.setTs(streamContent.getTs());
  414 + streamPlayPath.setHttps_ts(streamContent.getHttps_ts());
  415 + streamPlayPath.setWs_ts(streamContent.getWs_ts());
  416 + streamPlayPath.setWss_ts(streamContent.getWss_ts());
  417 + streamPlayPath.setRtmp(streamContent.getRtmp());
  418 + streamPlayPath.setRtmps(streamContent.getRtmps());
  419 + streamPlayPath.setRtsp(streamContent.getRtsp());
  420 + streamPlayPath.setRtsps(streamContent.getRtsps());
  421 + streamPlayPath.setRtc(streamContent.getRtc());
  422 + streamPlayPath.setRtcs(streamContent.getRtcs());
  423 + return streamPlayPath;
  424 + }
  425 +}
src/main/java/com/genersoft/iot/vmp/vmanager/jt1078/platform/Jt1078OfCarController.java
@@ -9,45 +9,29 @@ import com.alibaba.fastjson2.JSON; @@ -9,45 +9,29 @@ import com.alibaba.fastjson2.JSON;
9 import com.alibaba.fastjson2.JSONArray; 9 import com.alibaba.fastjson2.JSONArray;
10 import com.alibaba.fastjson2.JSONException; 10 import com.alibaba.fastjson2.JSONException;
11 import com.alibaba.fastjson2.JSONObject; 11 import com.alibaba.fastjson2.JSONObject;
12 -import com.genersoft.iot.vmp.VManageBootstrap;  
13 import com.genersoft.iot.vmp.conf.MediaConfig; 12 import com.genersoft.iot.vmp.conf.MediaConfig;
14 import com.genersoft.iot.vmp.conf.StreamProxyTask; 13 import com.genersoft.iot.vmp.conf.StreamProxyTask;
15 import com.genersoft.iot.vmp.conf.exception.ControllerException; 14 import com.genersoft.iot.vmp.conf.exception.ControllerException;
16 -import com.genersoft.iot.vmp.jt1078.app.VideoServerApp;  
17 -import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;  
18 -import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; 15 +import com.genersoft.iot.vmp.jtt1078.app.VideoServerApp;
  16 +import com.genersoft.iot.vmp.jtt1078.publisher.PublishManager;
19 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; 17 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
20 import com.genersoft.iot.vmp.service.IStreamProxyService; 18 import com.genersoft.iot.vmp.service.IStreamProxyService;
21 import com.genersoft.iot.vmp.service.IStreamPushService; 19 import com.genersoft.iot.vmp.service.IStreamPushService;
22 import com.genersoft.iot.vmp.service.StremProxyService1078; 20 import com.genersoft.iot.vmp.service.StremProxyService1078;
  21 +import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
23 import com.genersoft.iot.vmp.vmanager.bean.StreamContent; 22 import com.genersoft.iot.vmp.vmanager.bean.StreamContent;
  23 +import com.genersoft.iot.vmp.vmanager.bean.StreamPlayPath;
24 import com.genersoft.iot.vmp.vmanager.jt1078.platform.ben.HttpClientPostEntity; 24 import com.genersoft.iot.vmp.vmanager.jt1078.platform.ben.HttpClientPostEntity;
25 -import com.genersoft.iot.vmp.vmanager.jt1078.platform.ben.TestEntity;  
26 import com.genersoft.iot.vmp.vmanager.jt1078.platform.config.Jt1078ConfigBean; 25 import com.genersoft.iot.vmp.vmanager.jt1078.platform.config.Jt1078ConfigBean;
27 import com.genersoft.iot.vmp.vmanager.jt1078.platform.config.RtspConfigBean; 26 import com.genersoft.iot.vmp.vmanager.jt1078.platform.config.RtspConfigBean;
28 import com.genersoft.iot.vmp.vmanager.jt1078.platform.config.TuohuaConfigBean; 27 import com.genersoft.iot.vmp.vmanager.jt1078.platform.config.TuohuaConfigBean;
  28 +import com.genersoft.iot.vmp.vmanager.jt1078.platform.domain.PatrolDataReq;
  29 +import com.genersoft.iot.vmp.vmanager.jt1078.platform.domain.SimFlow;
29 import com.genersoft.iot.vmp.vmanager.jt1078.platform.handler.HttpClientUtil; 30 import com.genersoft.iot.vmp.vmanager.jt1078.platform.handler.HttpClientUtil;
  31 +import com.genersoft.iot.vmp.vmanager.jt1078.platform.service.FlowService;
  32 +import com.genersoft.iot.vmp.vmanager.jt1078.platform.service.Jt1078OfService;
30 import com.genersoft.iot.vmp.vmanager.streamProxy.StreamProxyController; 33 import com.genersoft.iot.vmp.vmanager.streamProxy.StreamProxyController;
31 import com.genersoft.iot.vmp.vmanager.streamPush.StreamPushController; 34 import com.genersoft.iot.vmp.vmanager.streamPush.StreamPushController;
32 -  
33 -import java.io.ByteArrayOutputStream;  
34 -import java.io.IOException;  
35 -import java.net.URISyntaxException;  
36 -import java.security.Key;  
37 -import java.security.KeyFactory;  
38 -import java.security.spec.X509EncodedKeySpec;  
39 -import java.text.MessageFormat;  
40 -import java.util.ArrayList;  
41 -import java.util.Date;  
42 -import java.util.HashMap;  
43 -import java.util.Iterator;  
44 -import java.util.List;  
45 -import java.util.Map;  
46 -import java.util.Objects;  
47 -import java.util.concurrent.TimeUnit;  
48 -import javax.crypto.Cipher;  
49 -import javax.servlet.http.HttpServletRequest;  
50 -  
51 import org.apache.commons.collections4.CollectionUtils; 35 import org.apache.commons.collections4.CollectionUtils;
52 import org.apache.commons.collections4.MapUtils; 36 import org.apache.commons.collections4.MapUtils;
53 import org.apache.commons.lang3.RandomUtils; 37 import org.apache.commons.lang3.RandomUtils;
@@ -59,14 +43,35 @@ import org.slf4j.Logger; @@ -59,14 +43,35 @@ import org.slf4j.Logger;
59 import org.slf4j.LoggerFactory; 43 import org.slf4j.LoggerFactory;
60 import org.springframework.beans.factory.annotation.Autowired; 44 import org.springframework.beans.factory.annotation.Autowired;
61 import org.springframework.beans.factory.annotation.Value; 45 import org.springframework.beans.factory.annotation.Value;
  46 +import org.springframework.data.redis.core.Cursor;
  47 +import org.springframework.data.redis.core.RedisCallback;
62 import org.springframework.data.redis.core.RedisTemplate; 48 import org.springframework.data.redis.core.RedisTemplate;
  49 +import org.springframework.data.redis.core.ScanOptions;
63 import org.springframework.util.Base64Utils; 50 import org.springframework.util.Base64Utils;
64 -import org.springframework.web.bind.annotation.GetMapping;  
65 -import org.springframework.web.bind.annotation.PathVariable;  
66 -import org.springframework.web.bind.annotation.PostMapping;  
67 -import org.springframework.web.bind.annotation.RequestBody;  
68 -import org.springframework.web.bind.annotation.RequestMapping;  
69 -import org.springframework.web.bind.annotation.RestController; 51 +import org.springframework.web.bind.annotation.*;
  52 +import sun.misc.Signal;
  53 +import sun.misc.SignalHandler;
  54 +
  55 +import javax.annotation.Resource;
  56 +import javax.crypto.Cipher;
  57 +import javax.validation.constraints.NotBlank;
  58 +import java.io.ByteArrayOutputStream;
  59 +import java.io.IOException;
  60 +import java.net.URISyntaxException;
  61 +import java.security.Key;
  62 +import java.security.KeyFactory;
  63 +import java.security.spec.X509EncodedKeySpec;
  64 +import java.text.MessageFormat;
  65 +import java.text.SimpleDateFormat;
  66 +import java.time.LocalDateTime;
  67 +import java.util.*;
  68 +import java.util.concurrent.ArrayBlockingQueue;
  69 +import java.util.concurrent.ConcurrentHashMap;
  70 +import java.util.concurrent.ThreadPoolExecutor;
  71 +import java.util.concurrent.TimeUnit;
  72 +import java.util.stream.Collectors;
  73 +
  74 +import static com.genersoft.iot.vmp.utils.DateUtil.formatter;
70 75
71 @RestController 76 @RestController
72 @RequestMapping({"/api/jt1078/query"}) 77 @RequestMapping({"/api/jt1078/query"})
@@ -97,6 +102,14 @@ public class Jt1078OfCarController { @@ -97,6 +102,14 @@ public class Jt1078OfCarController {
97 private Date tokenDate; 102 private Date tokenDate;
98 @Autowired 103 @Autowired
99 private IStreamProxyService streamProxyService; 104 private IStreamProxyService streamProxyService;
  105 + @Resource
  106 + private FlowService flowService;
  107 + @Resource
  108 + private Jt1078OfService jt1078OfService;
  109 + //存储历史端口 key -->端口 value ---> sim-channel-startTime-endTime-port
  110 + public static final ConcurrentHashMap<Integer, Set<String>> map = new ConcurrentHashMap<>();
  111 +
  112 + private static final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10,20,40,TimeUnit.SECONDS,new ArrayBlockingQueue<>(10));
100 113
101 @Value("${spring.profiles.active}") 114 @Value("${spring.profiles.active}")
102 private String profilesActive; 115 private String profilesActive;
@@ -105,10 +118,14 @@ public class Jt1078OfCarController { @@ -105,10 +118,14 @@ public class Jt1078OfCarController {
105 public Jt1078OfCarController() { 118 public Jt1078OfCarController() {
106 } 119 }
107 120
  121 + @GetMapping("/flow/countList/{timeType}/{statisticsType}/{time}")
  122 + public Map<String, SimFlow> flowCountList(@PathVariable String statisticsType, @PathVariable String time, @PathVariable String timeType) {
  123 + return flowService.getList(timeType, statisticsType, time);
  124 + }
  125 +
108 @GetMapping({"/company/tree"}) 126 @GetMapping({"/company/tree"})
109 public Map<String, Object> requestTreeOfCompany() { 127 public Map<String, Object> requestTreeOfCompany() {
110 Map<String, Object> resultMap = new HashMap(); 128 Map<String, Object> resultMap = new HashMap();
111 -  
112 try { 129 try {
113 resultMap.put("code", "1"); 130 resultMap.put("code", "1");
114 List<HashMap<String, Object>> compList = new ArrayList(); 131 List<HashMap<String, Object>> compList = new ArrayList();
@@ -119,14 +136,13 @@ public class Jt1078OfCarController { @@ -119,14 +136,13 @@ public class Jt1078OfCarController {
119 resultMap.put("code", "-100"); 136 resultMap.put("code", "-100");
120 resultMap.put("msg", "请求错误,请联系管理员"); 137 resultMap.put("msg", "请求错误,请联系管理员");
121 } 138 }
122 -  
123 return resultMap; 139 return resultMap;
124 } 140 }
125 141
126 @GetMapping({"/car/tree/{companyId}"}) 142 @GetMapping({"/car/tree/{companyId}"})
127 public Map<String, Object> requestTreeOfCarByCompanyId(@PathVariable String companyId) { 143 public Map<String, Object> requestTreeOfCarByCompanyId(@PathVariable String companyId) {
  144 + clearRedisTree();
128 Map<String, Object> resultMap = new HashMap(); 145 Map<String, Object> resultMap = new HashMap();
129 -  
130 try { 146 try {
131 List<HashMap<String, Object>> linesCars = this.tuohuaConfigBean.requestOfLineAndCarAndCombationTree(this.httpClientUtil, companyId); 147 List<HashMap<String, Object>> linesCars = this.tuohuaConfigBean.requestOfLineAndCarAndCombationTree(this.httpClientUtil, companyId);
132 resultMap.put("result", linesCars); 148 resultMap.put("result", linesCars);
@@ -135,19 +151,45 @@ public class Jt1078OfCarController { @@ -135,19 +151,45 @@ public class Jt1078OfCarController {
135 resultMap.put("code", "-100"); 151 resultMap.put("code", "-100");
136 resultMap.put("msg", "请求错误,请联系管理员"); 152 resultMap.put("msg", "请求错误,请联系管理员");
137 } 153 }
138 -  
139 return resultMap; 154 return resultMap;
140 } 155 }
141 156
  157 + /**
  158 + * redis清除在线车辆
  159 + */
  160 + public void clearRedisTree() {
  161 + Set<Object> carId = redisTemplate.keys("carId");
  162 + if (carId != null) {
  163 + redisTemplate.delete(carId);
  164 + }
  165 + }
  166 + /**
  167 + * redis存储在线车辆
  168 + * @param linesCars
  169 + */
  170 + public HashMap<String, Object> storageRedisTree(List<HashMap<String, Object>> linesCars) {
  171 + HashMap<String, Object> map = new HashMap<>();
  172 + for (HashMap<String, Object> linesCar : linesCars) {
  173 + if (null == linesCar.get("children") && linesCar.get("abnormalStatus").equals(1)) {
  174 + map.put(linesCar.get("id").toString(), linesCar);
  175 + }
  176 + if (null == linesCar.get("abnormalStatus")) {
  177 + List<HashMap<String, Object>> listMap = (List<HashMap<String, Object>>) linesCar.get("children");
  178 + if (!listMap.isEmpty()) {
  179 + storageRedisTree(listMap);
  180 + }
  181 + }
  182 + }
  183 + return map;
  184 + }
  185 +
142 @GetMapping({"/car/sim/{zbh}"}) 186 @GetMapping({"/car/sim/{zbh}"})
143 public Map<String, Object> requestSimple(@PathVariable String zbh) { 187 public Map<String, Object> requestSimple(@PathVariable String zbh) {
144 Map<String, Object> resultMap = new HashMap(); 188 Map<String, Object> resultMap = new HashMap();
145 -  
146 try { 189 try {
147 if (this.cookieTimeOut()) { 190 if (this.cookieTimeOut()) {
148 this.requestToken(); 191 this.requestToken();
149 } 192 }
150 -  
151 String url = MessageFormat.format(this.tuohuaConfigBean.getSimURL(), zbh); 193 String url = MessageFormat.format(this.tuohuaConfigBean.getSimURL(), zbh);
152 HttpClientPostEntity clientPostEntity = this.httpClientUtil.doGet(url, this.jsessionid); 194 HttpClientPostEntity clientPostEntity = this.httpClientUtil.doGet(url, this.jsessionid);
153 if (Objects.isNull(clientPostEntity)) { 195 if (Objects.isNull(clientPostEntity)) {
@@ -170,83 +212,184 @@ public class Jt1078OfCarController { @@ -170,83 +212,184 @@ public class Jt1078OfCarController {
170 } 212 }
171 } 213 }
172 214
  215 + /**
  216 + * 请求设备推送流
  217 + * @param sim sim号
  218 + * @param channel 通道号
  219 + * @return
  220 + */
173 @GetMapping({"/send/request/io/{sim}/{channel}"}) 221 @GetMapping({"/send/request/io/{sim}/{channel}"})
174 - public Map<String, Object> sendIORequest(@PathVariable String sim, @PathVariable String channel) {  
175 - Map<String, Object> resultMap = new HashMap(); 222 + public StreamContent sendIORequest(@PathVariable String sim, @PathVariable String channel) {
176 if (StringUtils.isBlank(sim)) { 223 if (StringUtils.isBlank(sim)) {
177 - resultMap.put("code", "-100");  
178 - resultMap.put("msg", "sim 不能为空");  
179 - return resultMap;  
180 - } else if (StringUtils.isBlank(channel)) {  
181 - resultMap.put("code", "-100");  
182 - resultMap.put("msg", "channel 不能为空");  
183 - return resultMap;  
184 - } else {  
185 - String msg = null;  
186 - String stream = StringUtils.join(new String[]{sim, "-", channel});  
187 - String url = StringUtils.replace(this.jt1078ConfigBean.getJt1078Url(), "{0}", this.jt1078ConfigBean.getJt1078SendPort()); 224 + throw new ControllerException(-100,"sim 不能为空");
  225 + }
  226 + if (StringUtils.isBlank(channel)) {
  227 + throw new ControllerException(-100, "channel 不能为空");
  228 + }
  229 + String stream = StringUtils.join(new String[]{sim, "-", channel});
  230 + StreamContent streamContent = getStreamContentPlayURL(stream);
  231 + if (Objects.isNull(streamContent) || StringUtils.isBlank(streamContent.getWs_flv())){
  232 + sendIORequest(stream);
  233 + }
  234 + streamContent = getStreamContent(stream);
  235 + streamContent.setPort(jt1078ConfigBean.getPort());
  236 + streamContent.setHttpPort(jt1078ConfigBean.getHttpPort());
  237 + return streamContent;
  238 + }
188 239
189 - try {  
190 - StreamContent streamContent = this.getStreamContentPlayURL(StringUtils.join(new String[]{stream}));  
191 - if (Objects.isNull(streamContent) || StringUtils.isBlank(streamContent.getWs_flv())) {  
192 - HttpClientPostEntity entity = this.createServerLister(stream);  
193 - if (Objects.isNull(entity)) {  
194 - resultMap.put("code", "-20");  
195 - resultMap.put("msg", "新建链接错误,请稍后再试");  
196 -  
197 - return resultMap;  
198 - } 240 + /**
  241 + * 批量请求设备推送流
  242 + * @param streamList 流唯一值集合 {sim-channel}
  243 + */
  244 + @PostMapping({"/beachSend/request/io"})
  245 + public List<StreamContent> beachSendIORequest(@RequestBody List<String> streamList) {
  246 + if (CollectionUtils.isEmpty(streamList)) {
  247 + throw new ControllerException(ErrorCode.ERROR400);
  248 + }
  249 + List<StreamContent> list = new ArrayList<>();
  250 + for (String stream : streamList) {
  251 + sendIORequest(stream);
  252 + list.add(getStreamContent(stream));
  253 + }
  254 + return list;
  255 + }
199 256
200 - resultMap.put("port", entity.getPort());  
201 - resultMap.put("httpPort", entity.getHttpPort());  
202 - resultMap.put("stream", stream);  
203 - this.redisTemplate.opsForValue().set("tag:history:port:" + stream, entity.getPort(), 2L, TimeUnit.DAYS);  
204 - this.redisTemplate.opsForValue().set("tag:history:httpPort:" + stream, entity.getHttpPort(), 2L, TimeUnit.DAYS);  
205 - this.redisTemplate.opsForValue().set("tag:history:httpPort:time:" + stream, (new Date()).getTime(), StreamProxyTask.TIME_OUT, TimeUnit.SECONDS);  
206 - redisTemplate.delete("jt1078:count:" + stream);  
207 -  
208 - msg = this.jt1078ConfigBean.formatMessageId(sim, channel, this.rtspConfigBean, entity.getPort());  
209 - VManageBootstrap.getBean(VideoServerApp.class).newVideoServer(stream, entity.getPort(), entity.getHttpPort());  
210 -  
211 - HttpClientPostEntity entity1 = httpClientUtil.doPost(url, msg, null);  
212 - Map<String, Object> resultMap1 = this.chooseEntity(entity1, url, false);  
213 - if (Objects.nonNull(resultMap1)) {  
214 - return resultMap1;  
215 - } 257 + /**
  258 + * 视频巡查功能开启
  259 + * @param PatrolDataReqList 视频巡查请求对象
  260 + */
  261 + @PostMapping({"/startPatrol/request/io"})
  262 + public List<StreamContent> startPatrol(@RequestBody List<PatrolDataReq> PatrolDataReqList) {
  263 + if (CollectionUtils.isEmpty(PatrolDataReqList)) {
  264 + throw new ControllerException(ErrorCode.ERROR400);
  265 + }
  266 + List<String> simList = PatrolDataReqList.stream().map(patrolDataReq -> {
  267 + String id = patrolDataReq.getId();
  268 + String[] split = id.split("_");
  269 + String stream = split[1] + "-" + split[2];
  270 + patrolDataReq.setId(stream);
  271 + redisTemplate.opsForValue().set("patrol:stream:" + stream, patrolDataReq);
  272 + return stream;
  273 + }).distinct().collect(Collectors.toList());
  274 + return beachSendIORequest(simList);
  275 + }
216 276
217 - createStreamProxy(stream, entity.getPort());  
218 - Map<String, Object> resultMap2 = this.getStreamContent(stream, entity.getHttpPort());  
219 - if (Objects.nonNull(resultMap2) && Objects.nonNull(resultMap2.get("code")) && !StringUtils.equals(resultMap2.get("code").toString(), "1")) {  
220 - return resultMap2;  
221 - } 277 + /**
  278 + * 关闭视频巡查 (必须在关闭按钮后关闭,否则流量在一直消耗)
  279 + */
  280 + @GetMapping("/stopPatrol/request/io")
  281 + public void stopPatrol(){
  282 + Set<Object> keys = redisTemplate.keys("patrol:stream:*");
  283 + redisTemplate.delete(keys);
  284 + }
222 285
223 - streamContent = (StreamContent) resultMap2.get("streamContent");  
224 - } else {  
225 - resultMap.put("port", redisTemplate.opsForValue().get("tag:history:port:" + stream));  
226 - resultMap.put("httpPort", redisTemplate.opsForValue().get("tag:history:httpPort:" + stream));  
227 - resultMap.put("stream", stream); 286 + /**
  287 + * 获取播放地址对外接口
  288 + * @param sim
  289 + * @param channel
  290 + * @return
  291 + */
  292 + @PostMapping("/send/request/getPlay")
  293 + public Object sendGetPlay(@RequestParam String sim, @RequestParam String channel) {
  294 + if (StringUtils.isBlank(sim)) {
  295 + throw new ControllerException(-100,"sim 不能为空");
  296 + }
  297 + if (StringUtils.isBlank(channel)) {
  298 + throw new ControllerException(-100, "channel 不能为空");
  299 + }
  300 + String stream = sim + "-" + channel;
  301 +
  302 + StreamPushItem streamPushItem = streamPushController.getStreamPushItem(sim, channel);
  303 + StreamContent playUrl = null;
  304 + if (null != streamPushItem) {
  305 + playUrl = streamPushController.getPlayUrl(streamPushItem.getApp(), stream, streamPushItem.getMediaServerId());
  306 + if (playUrl != null){
  307 + return StreamPlayPath.build(playUrl,stream);
  308 + }
  309 + }
  310 + HashMap<String, Object> resultMap = new HashMap<>();
  311 + sendIORequest(stream);
  312 + try {
  313 + Thread.sleep(4000);
  314 + } catch (InterruptedException e) {
  315 + throw new RuntimeException(e);
  316 + }
  317 + if (map.get("code").equals("1")){
  318 +
  319 + while (true){
  320 + streamPushItem = streamPushController.getStreamPushItem(sim, channel);
  321 + if (null == streamPushItem) {
  322 + try {
  323 + Thread.sleep(1000);
  324 + } catch (InterruptedException e) {
  325 + throw new RuntimeException(e);
  326 + }
  327 + continue;
  328 + }
  329 + playUrl = streamPushController.getPlayUrl(streamPushItem.getApp(), stream, streamPushItem.getMediaServerId());
  330 + if (playUrl == null){
  331 + try {
  332 + Thread.sleep(1000);
  333 + } catch (InterruptedException e) {
  334 + throw new RuntimeException(e);
  335 + }
  336 + continue;
228 } 337 }
  338 + return StreamPlayPath.build(playUrl,stream);
  339 + }
  340 + }
  341 + throw new RuntimeException("获取视频失败");
  342 + }
229 343
230 344
231 - resultMap.put("code", "1");  
232 - resultMap.put("message", "OK");  
233 - resultMap.put("data", streamContent);  
234 - return resultMap;  
235 - } catch (IOException | InterruptedException | URISyntaxException var11) {  
236 - Exception e = var11;  
237 - log.error("发送推流指令异常;[{}],[{}]", new Object[]{url, msg, e});  
238 - resultMap.put("code", "-20");  
239 - resultMap.put("msg", "发送推流指令异常");  
240 - return resultMap;  
241 - } catch (Exception e) {  
242 - log.error("发送推流指令异常;[{}],[{}]", new Object[]{url, msg, e});  
243 - resultMap.put("code", "-20");  
244 - resultMap.put("msg", "发送推流指令异常");  
245 - return resultMap; 345 + /**
  346 + * 请求设备开始推流
  347 + * @param stream 流唯一标识
  348 + */
  349 + public void sendIORequest(String stream) {
  350 +
  351 + threadPoolExecutor.execute(() -> {
  352 + String msg = null;
  353 + // http://192.168.168.241:8100/device/{0} 指令下发地址
  354 + String url = StringUtils.replace(jt1078ConfigBean.getJt1078Url(), "{0}", jt1078ConfigBean.getJt1078SendPort());
  355 + try {
  356 + // http://192.169.1.88:3333/new/server/{pushKey}/{port}/{httpPort}
  357 + // 根据 开始和结束1078的端口号生成
  358 + Integer port = jt1078ConfigBean.getPort();
  359 + Integer httpPort = jt1078ConfigBean.getHttpPort();
  360 + HttpClientPostEntity entity = createServerLister(stream, port, httpPort);
  361 + if (Objects.isNull(entity)) {
  362 + throw new ControllerException(ErrorCode.ERROR450);
  363 + }
  364 + //port 推流端口
  365 + //httpPort 拉流端口
  366 + //stream 流名称
  367 + redisTemplate.opsForValue().set("tag:history:port:" + stream, entity.getPort(), 2L, TimeUnit.DAYS);
  368 + redisTemplate.opsForValue().set("tag:history:httpPort:" + stream, entity.getHttpPort(), 2L, TimeUnit.DAYS);
  369 + redisTemplate.opsForValue().set("tag:history:httpPort:time:" + stream, (new Date()).getTime(), StreamProxyTask.TIME_OUT, TimeUnit.SECONDS);
  370 + redisTemplate.delete("jt1078:count:" + stream);
  371 + String[] split = stream.split("-");
  372 + msg = jt1078ConfigBean.formatMessageId(split[0], split[1], rtspConfigBean, entity.getPort());
  373 + HttpClientPostEntity entity1 = httpClientUtil.doPost(url, msg, jsessionid);
  374 + chooseEntity(entity1, url, false);
  375 + log.info("发送[ {} ]推流指令成功 ===》 {}", stream, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
  376 + } catch (Exception e) {
  377 + log.error("发送推流指令异常;[{}], [{}], [{}]", url, msg, e.getMessage());
  378 + throw new ControllerException(ErrorCode.ERROR420);
246 } 379 }
247 - } 380 + });
248 } 381 }
249 382
  383 + /**
  384 + * 停止推送
  385 + *
  386 + * @param sim
  387 + * @param channel
  388 + * @param stream
  389 + * @param port
  390 + * @param httpPort
  391 + * @return
  392 + */
250 @GetMapping({"/send/stop/io/{sim}/{channel}/{stream}/{port}/{httpPort}"}) 393 @GetMapping({"/send/stop/io/{sim}/{channel}/{stream}/{port}/{httpPort}"})
251 public Map<String, Object> sendIORequestStop(@PathVariable String sim, @PathVariable String channel, @PathVariable String stream, @PathVariable Integer port, @PathVariable Integer httpPort) { 394 public Map<String, Object> sendIORequestStop(@PathVariable String sim, @PathVariable String channel, @PathVariable String stream, @PathVariable Integer port, @PathVariable Integer httpPort) {
252 Map<String, Object> resultMap = new HashMap(); 395 Map<String, Object> resultMap = new HashMap();
@@ -292,6 +435,13 @@ public class Jt1078OfCarController { @@ -292,6 +435,13 @@ public class Jt1078OfCarController {
292 } 435 }
293 } 436 }
294 437
  438 + /**
  439 + * 停止推送
  440 + *
  441 + * @param sim
  442 + * @param channel
  443 + * @return
  444 + */
295 @GetMapping({"/send/stop/io/{sim}/{channel}"}) 445 @GetMapping({"/send/stop/io/{sim}/{channel}"})
296 public Map<String, Object> sendIORequestStop(@PathVariable String sim, @PathVariable String channel) { 446 public Map<String, Object> sendIORequestStop(@PathVariable String sim, @PathVariable String channel) {
297 Map<String, Object> resultMap = new HashMap(); 447 Map<String, Object> resultMap = new HashMap();
@@ -323,7 +473,6 @@ public class Jt1078OfCarController { @@ -323,7 +473,6 @@ public class Jt1078OfCarController {
323 473
324 for (int i = 0; i < count; ++i) { 474 for (int i = 0; i < count; ++i) {
325 StreamPushItem item = streamPushItems.get(i); 475 StreamPushItem item = streamPushItems.get(i);
326 -  
327 try { 476 try {
328 this.streamProxyController.del(item.getApp(), item.getStream()); 477 this.streamProxyController.del(item.getApp(), item.getStream());
329 this.streamPushService.stop(item.getApp(), item.getStream()); 478 this.streamPushService.stop(item.getApp(), item.getStream());
@@ -332,7 +481,6 @@ public class Jt1078OfCarController { @@ -332,7 +481,6 @@ public class Jt1078OfCarController {
332 log.error("推流停止失败,[{}]", item, e); 481 log.error("推流停止失败,[{}]", item, e);
333 } 482 }
334 } 483 }
335 -  
336 resultMap.put("code", "1"); 484 resultMap.put("code", "1");
337 resultMap.put("message", "OK"); 485 resultMap.put("message", "OK");
338 return resultMap; 486 return resultMap;
@@ -345,6 +493,15 @@ public class Jt1078OfCarController { @@ -345,6 +493,15 @@ public class Jt1078OfCarController {
345 } 493 }
346 } 494 }
347 495
  496 + /**
  497 + * 历史数据列表
  498 + *
  499 + * @param sim
  500 + * @param channel
  501 + * @param startTime
  502 + * @param endTime
  503 + * @return
  504 + */
348 @GetMapping({"/history/list/{sim}/{channel}/{startTime}/{endTime}"}) 505 @GetMapping({"/history/list/{sim}/{channel}/{startTime}/{endTime}"})
349 public Map<String, Object> historyListOfSim(@PathVariable String sim, @PathVariable String channel, @PathVariable String startTime, @PathVariable String endTime) { 506 public Map<String, Object> historyListOfSim(@PathVariable String sim, @PathVariable String channel, @PathVariable String startTime, @PathVariable String endTime) {
350 Map<String, Object> resultMap = new HashMap(); 507 Map<String, Object> resultMap = new HashMap();
@@ -366,10 +523,9 @@ public class Jt1078OfCarController { @@ -366,10 +523,9 @@ public class Jt1078OfCarController {
366 return resultMap; 523 return resultMap;
367 } else { 524 } else {
368 String url = StringUtils.replace(this.jt1078ConfigBean.getJt1078Url(), "{0}", this.jt1078ConfigBean.getHistoryListPort()); 525 String url = StringUtils.replace(this.jt1078ConfigBean.getJt1078Url(), "{0}", this.jt1078ConfigBean.getHistoryListPort());
369 - startTime = this.formatTime(startTime);  
370 - endTime = this.formatTime(endTime); 526 + startTime = this.formatTime(startTime).substring(2);
  527 + endTime = this.formatTime(endTime).substring(2);
371 String msg = this.jt1078ConfigBean.formatMessageHistoryListRTSP(sim, channel, startTime, endTime); 528 String msg = this.jt1078ConfigBean.formatMessageHistoryListRTSP(sim, channel, startTime, endTime);
372 -  
373 try { 529 try {
374 HttpClientPostEntity entity = this.httpClientUtil.doPost(url, msg, (String) null); 530 HttpClientPostEntity entity = this.httpClientUtil.doPost(url, msg, (String) null);
375 if (Objects.isNull(entity)) { 531 if (Objects.isNull(entity)) {
@@ -377,263 +533,353 @@ public class Jt1078OfCarController { @@ -377,263 +533,353 @@ public class Jt1078OfCarController {
377 resultMap.put("msg", "请求历史视频列表错误,请联系管理员"); 533 resultMap.put("msg", "请求历史视频列表错误,请联系管理员");
378 return resultMap; 534 return resultMap;
379 } else { 535 } else {
380 - Map<String, Object> resultMap1 = this.chooseEntity(entity, url, true);  
381 - if (Objects.nonNull(resultMap1)) {  
382 - return resultMap1;  
383 - } else {  
384 - HashMap<String, Object> hashMap = (HashMap) JSON.parseObject(entity.getResultStr(), HashMap.class);  
385 - if (MapUtils.isNotEmpty(hashMap) && Objects.nonNull(hashMap.get("data"))) {  
386 - JSONObject dataJO = (JSONObject) hashMap.get("data");  
387 - if (Objects.nonNull(dataJO.get("items"))) {  
388 - JSONArray jsonArray = (JSONArray) dataJO.get("items");  
389 - for (Object o : jsonArray) {  
390 - JSONObject jo = (JSONObject) o;  
391 - String startTimeStr = jo.getString("startTime");  
392 - if (StringUtils.isEmpty(startTimeStr)) {  
393 - startTimeStr = StringUtils.join(String.valueOf(System.currentTimeMillis()), "-", String.valueOf(RandomUtils.nextInt(1, 1000)));  
394 - } else {  
395 - startTimeStr = StringUtils.replace(startTimeStr, "-", "");  
396 - startTimeStr = StringUtils.replace(startTimeStr, ":", "");  
397 - startTimeStr = StringUtils.replace(startTimeStr, " ", "");  
398 - }  
399 - String channelMapping = StringUtils.join(new String[]{sim, "-", startTimeStr, "-", channel});  
400 - jo.put("channelMapping", channelMapping);  
401 - } 536 + chooseEntity(entity, url, true);
  537 + HashMap<String, Object> hashMap = (HashMap) JSON.parseObject(entity.getResultStr(), HashMap.class);
  538 + if (MapUtils.isNotEmpty(hashMap) && Objects.nonNull(hashMap.get("data"))) {
  539 + JSONObject dataJO = (JSONObject) hashMap.get("data");
  540 + HashSet<String> set = new HashSet<>();
  541 + if (Objects.nonNull(dataJO.get("items"))) {
  542 + JSONArray jsonArray = (JSONArray) dataJO.get("items");
  543 + jsonArray =
  544 + new JSONArray(
  545 + jsonArray.stream()
  546 + .map(json -> dateCon((JSONObject) json, sim, channel))
  547 + .filter(jsonObject -> {
  548 + // 获取channelMapping并转换为List以便于比较
  549 + String channelMapping = jsonObject.getString("channelMapping");
  550 + return set.add(channelMapping);
  551 + })
  552 + .collect(Collectors.toList())
  553 + );
  554 + if (jsonArray.size() > 1) {
  555 + jsonArray = filterContainedRanges(jsonArray);
402 } 556 }
  557 + dataJO.put("items", jsonArray);
403 } 558 }
404 - resultMap.put("code", "1");  
405 -  
406 - resultMap.put("obj", hashMap);  
407 - return resultMap;  
408 } 559 }
  560 + resultMap.put("code", "1");
  561 + resultMap.put("obj", hashMap);
  562 + return resultMap;
409 } 563 }
410 - } catch (URISyntaxException var11) {  
411 - URISyntaxException e = var11;  
412 - log.error("发送获取历史视频指令异常;[{}],[{}]", new Object[]{url, msg, e});  
413 - resultMap.put("code", "-20");  
414 - resultMap.put("msg", "发送获取历史视频指令异常");  
415 - return resultMap;  
416 - } catch (IOException var12) {  
417 - IOException e = var12; 564 + } catch (Exception e) {
418 log.error("发送获取历史视频指令异常;[{}],[{}]", new Object[]{url, msg, e}); 565 log.error("发送获取历史视频指令异常;[{}],[{}]", new Object[]{url, msg, e});
419 - resultMap.put("code", "-20");  
420 - resultMap.put("msg", "发送获取历史视频指令异常");  
421 - return resultMap; 566 + throw new ControllerException(-20, "发送获取历史视频指令异常");
422 } 567 }
423 } 568 }
424 } 569 }
425 570
426 - @GetMapping({"/send/request/io/history/{sim}/{channel}/{startTime}/{endTime}/{channelMapping}"})  
427 - public Map<String, Object> sendIORequestOfHistory(@PathVariable String sim, @PathVariable String channel, @PathVariable String startTime, @PathVariable String endTime, @PathVariable String channelMapping) { 571 + public static JSONArray filterContainedRanges(JSONArray jsonArray) {
  572 + List<JSONObject> list = new ArrayList<>();
  573 + for (int i = 0; i < jsonArray.size(); i++) {
  574 + list.add(jsonArray.getJSONObject(i));
  575 + }
  576 +
  577 + // 过滤逻辑
  578 + List<JSONObject> filteredList = list.stream()
  579 + .filter(timeRange -> !isAnyOtherRangeContainingThis(list, timeRange))
  580 + .collect(Collectors.toList());
  581 +
  582 + // 将过滤后的列表转换回 JSONArray
  583 + return new JSONArray(filteredList);
  584 + }
  585 +
  586 + private static boolean isAnyOtherRangeContainingThis(List<JSONObject> jsonArray, JSONObject timeRange) {
  587 + LocalDateTime startTimeInner = LocalDateTime.parse(timeRange.getString("startTime"), formatter);
  588 + LocalDateTime endTimeInner = LocalDateTime.parse(timeRange.getString("endTime"), formatter);
  589 +
  590 + return jsonArray.stream()
  591 + .anyMatch(other -> !other.equals(timeRange) &&
  592 + isContainedIn(startTimeInner, endTimeInner, other));
  593 + }
  594 +
  595 + private static boolean isContainedIn(LocalDateTime startTimeInner, LocalDateTime endTimeInner, JSONObject outer) {
  596 + LocalDateTime startTimeOuter = LocalDateTime.parse(outer.getString("startTime"), formatter);
  597 + LocalDateTime endTimeOuter = LocalDateTime.parse(outer.getString("endTime"), formatter);
  598 +
  599 + return !startTimeInner.isBefore(startTimeOuter) && !endTimeInner.isAfter(endTimeOuter);
  600 + }
  601 +
  602 + /**
  603 + * json对象时间转换
  604 + *
  605 + * @param jsonObject
  606 + * @param sim
  607 + * @param channel
  608 + */
  609 + public JSONObject dateCon(JSONObject jsonObject, String sim, String channel) {
  610 + String startTimeStr = jsonObject.getString("startTime");
  611 + if (StringUtils.isEmpty(startTimeStr)) {
  612 + startTimeStr = StringUtils.join(String.valueOf(System.currentTimeMillis()), "-", String.valueOf(RandomUtils.nextInt(1, 1000)));
  613 + } else {
  614 + startTimeStr = StringUtils
  615 + .replace(startTimeStr, "-", "")
  616 + .replace(":", "")
  617 + .replace(" ", "");
  618 + }
  619 + String channelMapping = StringUtils.join(new String[]{sim, "-", startTimeStr, "-", channel});
  620 + jsonObject.put("channelMapping", channelMapping);
  621 + return jsonObject;
  622 + }
  623 +
  624 + /**
  625 + * 停止历史视频回放
  626 + *
  627 + * @param channel
  628 + * @param sim
  629 + * @return
  630 + */
  631 + @PostMapping("/send/request/stop/history/{sim}/{channel}")
  632 + public Map<String, Object> stopHistory(@PathVariable String channel, @PathVariable String sim) {
428 Map<String, Object> resultMap = new HashMap(); 633 Map<String, Object> resultMap = new HashMap();
429 if (StringUtils.isBlank(sim)) { 634 if (StringUtils.isBlank(sim)) {
430 resultMap.put("code", "-100"); 635 resultMap.put("code", "-100");
431 resultMap.put("msg", "sim 不能为空"); 636 resultMap.put("msg", "sim 不能为空");
432 return resultMap; 637 return resultMap;
433 - } else if (StringUtils.isBlank(channel)) { 638 + }
  639 + if (StringUtils.isBlank(channel)) {
434 resultMap.put("code", "-100"); 640 resultMap.put("code", "-100");
435 resultMap.put("msg", "channel 不能为空"); 641 resultMap.put("msg", "channel 不能为空");
436 return resultMap; 642 return resultMap;
437 - } else if (StringUtils.isBlank(startTime)) {  
438 - resultMap.put("code", "-100");  
439 - resultMap.put("msg", "开始时间不能为空");  
440 - return resultMap;  
441 - } else if (StringUtils.isBlank(endTime)) {  
442 - resultMap.put("code", "-100");  
443 - resultMap.put("msg", "结束时间不能为空"); 643 + }
  644 + String url = StringUtils.replace(this.jt1078ConfigBean.getJt1078Url(), "{0}", "9202");
  645 + String msg = this.jt1078ConfigBean.formatMessageHistoryStopRTSP(sim, channel, this.rtspConfigBean);
  646 + try {
  647 + HttpClientPostEntity entity1 = this.httpClientUtil.doPost(url, msg, (String) null);
  648 + resultMap.put("code", "1");
  649 + resultMap.put("obj", entity1);
444 return resultMap; 650 return resultMap;
445 - } else { 651 + } catch (Exception e) {
  652 + throw new RuntimeException(e);
  653 + }
  654 + }
446 655
447 - StreamContent streamContent = this.getStreamContentPlayURL(StringUtils.join(new String[]{channelMapping}));  
448 - if (Objects.nonNull(streamContent) && StringUtils.isNotEmpty(streamContent.getWs_flv())) { 656 + /**
  657 + * 历史视频回放
  658 + *
  659 + * @param sim sim号
  660 + * @param channel 通道号
  661 + * @param startTime 开始时间
  662 + * @param endTime 结束时间
  663 + * @param channelMapping 通道唯一值
  664 + */
  665 + @GetMapping({"/send/request/io/history/{sim}/{channel}/{startTime}/{endTime}/{channelMapping}"})
  666 + public Map<String, Object> sendIORequestOfHistory(@PathVariable @NotBlank(message = "sim 不能为空") String sim,
  667 + @PathVariable @NotBlank(message = "channel 不能为空") String channel,
  668 + @PathVariable @NotBlank(message = "开始时间不能为空") String startTime,
  669 + @PathVariable @NotBlank(message = "结束时间不能为空") String endTime,
  670 + String channelMapping) {
  671 + Map<String, Object> resultMap = new HashMap();
  672 + startTime = this.formatTime(startTime);
  673 + endTime = this.formatTime(endTime);
  674 + String key = StringUtils.join(new String[]{sim, "-", channel});
  675 + channelMapping = StringUtils.join(new String[]{sim, "-", channel,"-",startTime,"-",endTime});
  676 + Integer historyPort = createHistoryPort(channelMapping);
  677 + channelMapping = StringUtils.join(new String[]{channelMapping,"_", String.valueOf(historyPort)});
  678 + this.redisTemplate.opsForValue().set(key, channelMapping, 1L, TimeUnit.HOURS);
  679 +// PublishManager.getInstance().open(channelMapping);
  680 + StreamContent streamContent = this.getStreamContentPlayURL(StringUtils.join(new String[]{channelMapping}));
  681 + if (Objects.nonNull(streamContent) && StringUtils.isNotEmpty(streamContent.getWs_flv())) {
  682 + resultMap.put("code", "1");
  683 + resultMap.put("data", streamContent);
  684 + resultMap.put("port", redisTemplate.opsForValue().get("tag:history:port:" + channelMapping));
  685 + resultMap.put("httpPort", redisTemplate.opsForValue().get("tag:history:httpPort:" + channelMapping));
  686 + resultMap.put("stream", channelMapping);
  687 + return resultMap;
  688 + }
  689 + String msg = null;
  690 + String url = StringUtils.replace(this.jt1078ConfigBean.getJt1078Url(), "{0}", this.jt1078ConfigBean.getPlayHistoryPort());
  691 + try {
  692 + Integer httpPort = this.jt1078ConfigBean.getHttpPort();
  693 + HttpClientPostEntity entity = this.createServerLister(channelMapping, historyPort, httpPort);
  694 + if (Objects.isNull(entity)) {
  695 + resultMap.put("code", "-20");
  696 + resultMap.put("msg", "新建链接错误,请稍后再试");
  697 + return resultMap;
  698 + } else {
  699 + resultMap.put("stream", channelMapping);
  700 + resultMap.put("port", entity.getPort());
  701 + resultMap.put("httpPort", entity.getHttpPort());
  702 + this.redisTemplate.opsForValue().set("tag:history:port:" + channelMapping, entity.getPort(), 2L, TimeUnit.DAYS);
  703 + this.redisTemplate.opsForValue().set("tag:history:httpPort:" + channelMapping, entity.getHttpPort(), 2L, TimeUnit.DAYS);
  704 + this.redisTemplate.opsForValue().set("tag:history:httpPort:time:" + channelMapping, (new Date()).getTime(), StreamProxyTask.TIME_OUT, TimeUnit.SECONDS);
  705 + msg = this.jt1078ConfigBean.formatMessageHistoryPlayRTSP(sim, channel, startTime, endTime, this.rtspConfigBean, entity.getPort());
  706 +
  707 + HttpClientPostEntity entity1 = this.httpClientUtil.doPost(url, msg, (String) null);
  708 + chooseEntity(entity1, url, true);
449 resultMap.put("code", "1"); 709 resultMap.put("code", "1");
  710 + streamContent = this.getStreamContent(channelMapping);
450 log.info("StreamContent:[{}]", streamContent); 711 log.info("StreamContent:[{}]", streamContent);
451 resultMap.put("data", streamContent); 712 resultMap.put("data", streamContent);
452 -  
453 - resultMap.put("port", redisTemplate.opsForValue().get("tag:history:port:" + channelMapping));  
454 - resultMap.put("httpPort", redisTemplate.opsForValue().get("tag:history:httpPort:" + channelMapping));  
455 - resultMap.put("stream", channelMapping);  
456 return resultMap; 713 return resultMap;
457 } 714 }
458 - redisTemplate.delete("jt1078:count:" + channelMapping); 715 + }catch (Exception e) {
  716 + log.error("发送推流指令异常;[{}], [{}], [{}]", url, msg, e.getMessage());
  717 + throw new ControllerException(-20, "发送推流指令异常");
  718 + }
  719 + }
459 720
460 - startTime = this.formatTime(startTime);  
461 - endTime = this.formatTime(endTime); 721 + /**
  722 + * 从set<String>中找到对应唯一的sim-channel值
  723 + */
  724 + public static String getFindSet(Set<String> set,String targetString) {
  725 + for (String str : set) {
  726 + if (str.startsWith(targetString)) {
  727 + return str; // 找到匹配项后立即返回
  728 + }
  729 + }
  730 + return null;
  731 + }
  732 + /**
  733 + * 从形如"sim-channel-start-end"的字符串中提取第二个'-'之前的值。
  734 + */
  735 + private static String getSecondDashValue(String str) {
  736 + if (str == null || !str.contains("-")) {
  737 + return null; // 如果输入为空或没有'-',则返回null
  738 + }
462 739
463 - String key = StringUtils.join(new String[]{sim, "-", channel});  
464 - this.redisTemplate.opsForValue().set(key, channelMapping, 1L, TimeUnit.HOURS);  
465 - String msg = null;  
466 - log.info("msg:{}", msg);  
467 - String url = StringUtils.replace(this.jt1078ConfigBean.getJt1078Url(), "{0}", this.jt1078ConfigBean.getPlayHistoryPort()); 740 + // 找到第一个和第二个'-'的位置
  741 + int firstDashIndex = str.indexOf('-');
  742 + int secondDashIndex = str.indexOf('-', firstDashIndex + 1);
468 743
469 - try {  
470 - HttpClientPostEntity entity = this.createServerLister(channelMapping);  
471 - if (Objects.isNull(entity)) {  
472 - resultMap.put("code", "-20");  
473 - resultMap.put("msg", "新建链接错误,请稍后再试");  
474 - return resultMap;  
475 - } else {  
476 - this.chooseEntity(entity, url, false);  
477 - resultMap.put("stream", channelMapping);  
478 - resultMap.put("port", entity.getPort());  
479 - resultMap.put("httpPort", entity.getHttpPort());  
480 - this.redisTemplate.opsForValue().set("tag:history:port:" + channelMapping, entity.getPort(), 2L, TimeUnit.DAYS);  
481 - this.redisTemplate.opsForValue().set("tag:history:httpPort:" + channelMapping, entity.getHttpPort(), 2L, TimeUnit.DAYS);  
482 - this.redisTemplate.opsForValue().set("tag:history:httpPort:time:" + channelMapping, (new Date()).getTime(), StreamProxyTask.TIME_OUT, TimeUnit.SECONDS);  
483 - msg = this.jt1078ConfigBean.formatMessageHistoryPlayRTSP(sim, channel, startTime, endTime, this.rtspConfigBean, entity.getPort());  
484 - VManageBootstrap.getBean(VideoServerApp.class).newVideoServer(channelMapping, entity.getPort(), entity.getHttpPort());  
485 -  
486 - this.createStreamProxy(sim + "-" + channel, entity.getHttpPort());  
487 - HttpClientPostEntity entity1 = this.httpClientUtil.doPost(url, msg, (String) null);  
488 - createStreamProxy(channelMapping, entity.getHttpPort());  
489 -  
490 - Map<String, Object> resultMap2 = this.chooseEntity(entity1, url, true);  
491 - if (Objects.nonNull(resultMap2)) {  
492 - return resultMap2;  
493 - } else {  
494 - resultMap.put("code", "1");  
495 - Map<String, Object> resultMap3 = this.getStreamContent(channelMapping, entity.getHttpPort());  
496 - if (Objects.nonNull(resultMap3) && Objects.nonNull(resultMap3.get("code")) && !StringUtils.equals(resultMap3.get("code").toString(), "1")) {  
497 - return resultMap3;  
498 - } else {  
499 - streamContent = (StreamContent) resultMap3.get("streamContent");  
500 - if (Objects.isNull(streamContent)) {  
501 - resultMap.put("code", "-20");  
502 - resultMap.put("msg", "新建链接错误,请稍后再试");  
503 - return resultMap;  
504 - } else {  
505 - log.info("StreamContent:[{}]", streamContent);  
506 - resultMap.put("data", streamContent);  
507 - return resultMap;  
508 - }  
509 - }  
510 - }  
511 - }  
512 - } catch (IOException | URISyntaxException e) {  
513 - log.error("发送推流指令异常;[{}],[{}]", new Object[]{url, msg, e});  
514 - resultMap.put("code", "-20");  
515 - resultMap.put("msg", "发送推流指令异常");  
516 - return resultMap;  
517 - } catch (InterruptedException e) {  
518 - log.error("发送推流指令异常;[{}],[{}]", new Object[]{url, msg, e});  
519 - resultMap.put("code", "-20");  
520 - resultMap.put("msg", "发送推流指令异常");  
521 - return resultMap;  
522 - } catch (Exception e) {  
523 - log.error("发送推流指令异常;[{}],[{}]", new Object[]{url, msg, e});  
524 - resultMap.put("code", "-20");  
525 - resultMap.put("msg", "发送推流指令异常");  
526 - return resultMap; 744 + // 确保字符串中有至少两个'-'
  745 + if (firstDashIndex != -1 && secondDashIndex != -1) {
  746 + // 提取并返回第一个'-'之后、第二个'-'之前的部分
  747 + return str.substring(0, secondDashIndex);
  748 + } else {
  749 + return null; // 如果少于两个'-',则返回null
  750 + }
  751 + }
  752 + /**
  753 + * 遍历Map,寻找第一个不包含指定string的Set<String>,
  754 + * 将该string添加到Set中并返回对应的key,如果没有找到则返回null。
  755 + */
  756 + private Integer addStringToFirstNonContainingSet(String targetString) {
  757 + // 使用entrySet()方法直接获取键值对进行迭代,效率更高
  758 + for (Map.Entry<Integer, Set<String>> entry : map.entrySet()) {
  759 + Set<String> set = entry.getValue();
  760 + if (set.contains(targetString)){
  761 + return entry.getKey();
  762 + }
  763 + // 如果当前Set不包含目标字符串,则添加并返回key
  764 + String secondDashValue = getSecondDashValue(targetString);
  765 + String findSet = getFindSet(set, secondDashValue);
  766 + set.add(targetString);
  767 + if (secondDashValue != null && findSet == null) {
  768 + return entry.getKey(); // 立即返回对应的key,不再继续查找
  769 + }else {
  770 + clearMap(String.valueOf(entry.getKey()),findSet);
527 } 771 }
528 } 772 }
  773 + return null; // 如果所有Set都包含目标字符串,则返回null
529 } 774 }
530 775
  776 + /**
  777 + * 清理map中的值
  778 + */
  779 + public void clearMap(String key,String value) {
  780 + if (StringUtils.isNotBlank(key) && StringUtils.isNotBlank(value)) {
  781 + Set<String> strings = map.get(Integer.valueOf(key));
  782 + if (strings == null) {
  783 + return;
  784 + }
  785 + if (strings.contains(value)) {
  786 + PublishManager.getInstance().close(value + "_" + key);
  787 + try {
  788 + Thread.sleep(200);
  789 + } catch (InterruptedException e) {
  790 + throw new RuntimeException(e);
  791 + }
  792 + String[] split = value.split("-");
  793 + stopHistory(split[1],split[0]);
  794 + strings.remove(value);
  795 + }
  796 + }else {
  797 + log.error("清理端口缓存错误 !!!");
  798 + }
  799 + }
531 800
532 - @PostMapping({"/test"})  
533 - public String test(@RequestBody TestEntity test) {  
534 - return "OK"; 801 + /**
  802 + * 创建历史端口
  803 + * @param key 通道唯一值
  804 + */
  805 + public Integer createHistoryPort(String key){
  806 + Integer port = addStringToFirstNonContainingSet(key);
  807 + if (port == null) {
  808 + throw new RuntimeException(String.format("[ %s ]通道观看人数太多,请等待 !!!",key));
  809 + }
  810 + try {
  811 + if (redisTemplate.opsForValue().get("history:port:"+port) == null) {
  812 + startPost(port);
  813 + redisTemplate.opsForValue().set("history:port:"+port, port);
  814 + }
  815 + return port;
  816 + } catch (Exception e) {
  817 + log.error("{}",e.getMessage(),e);
  818 + throw new RuntimeException(String.format("[ %s ]端口启动异常", port));
  819 + }
535 } 820 }
536 821
537 - @GetMapping({"/test1"})  
538 - public String test1(HttpServletRequest request) throws URISyntaxException, IOException {  
539 - this.jsessionid = StringUtils.join(new String[]{"JSESSIONID=", request.getParameter("jsessionid")});  
540 - return "OK"; 822 + /**
  823 + * 启动历史端口监听
  824 + * @param port 端口
  825 + */
  826 + private void startPost(Integer port) throws Exception {
  827 + VideoServerApp videoServerApp = new VideoServerApp();
  828 +
  829 + VideoServerApp.VideoServer videoServer = videoServerApp.getVideoServer(port);
  830 + Signal.handle(new Signal("TERM"), new SignalHandler()
  831 + {
  832 + @Override
  833 + public void handle(Signal signal)
  834 + {
  835 + videoServer.shutdown();
  836 + }
  837 + });
  838 + videoServer.historyStart();
541 } 839 }
542 840
543 - @Nullable  
544 - private Map<String, Object> getStreamContent(String stream, int httpPort) throws InterruptedException {  
545 841
546 - Map<String, Object> datas = new HashMap();  
547 - StreamContent streamContent = requestStreamContent(1, stream, httpPort); 842 + @Nullable
  843 + private StreamContent getStreamContent(String stream){
548 844
  845 + StreamContent streamContent = this.getStreamContentPlayURL(stream);
549 if (Objects.isNull(streamContent) || StringUtils.isEmpty(streamContent.getWs_flv())) { 846 if (Objects.isNull(streamContent) || StringUtils.isEmpty(streamContent.getWs_flv())) {
550 streamContent = new StreamContent(); 847 streamContent = new StreamContent();
551 - streamContent.setWs_flv(StringUtils.replace(this.jt1078ConfigBean.getWs(), "{stream}", stream));  
552 - streamContent.setWss_flv(StringUtils.replace(this.jt1078ConfigBean.getWss(), "{stream}", stream));  
553 - streamContent.setFlv(StringUtils.replace(this.jt1078ConfigBean.getDownloadFlv(), "{stream}", stream));  
554 -  
555 -  
556 - new Thread(new Runnable() {  
557 - @Override  
558 - public void run() {  
559 - requestStreamContent(100, stream, httpPort);  
560 - }  
561 - }).start(); 848 + String authKey = this.jt1078ConfigBean.getPushKey();
  849 + streamContent.setWs_flv(StringUtils.replace(this.jt1078ConfigBean.getWs() + authKey, "{stream}", stream));
  850 + streamContent.setWss_flv(StringUtils.replace(this.jt1078ConfigBean.getWss() + authKey, "{stream}", stream));
  851 + streamContent.setFlv(StringUtils.replace(this.jt1078ConfigBean.getDownloadFlv() + authKey, "{stream}", stream));
562 } 852 }
563 853
564 - log.info("StreamContent:[{}]", streamContent);  
565 - datas.put("code", "1");  
566 - datas.put("streamContent", streamContent);  
567 - return datas; 854 + return streamContent;
568 } 855 }
569 856
  857 + /**
  858 + * 请求获取流
  859 + *
  860 + * @param count
  861 + * @param stream
  862 + * @param httpPort
  863 + * @return
  864 + */
570 private StreamContent requestStreamContent(int count, String stream, int httpPort) { 865 private StreamContent requestStreamContent(int count, String stream, int httpPort) {
571 - int index = 0;  
572 - StreamContent streamContent = null;  
573 - try {  
574 - do {  
575 - ++index;  
576 - streamContent = this.getStreamContentPlayURL(stream);  
577 - if (Objects.nonNull(streamContent) && StringUtils.isNotEmpty(streamContent.getWs_flv())) {  
578 - break;  
579 - }  
580 -  
581 - Object valObj = redisTemplate.opsForValue().get("jt1078:stream:status:" + stream);  
582 - if (Objects.nonNull(valObj) && StringUtils.equals(valObj.toString(), "1")) {  
583 - StreamProxyItem streamProxyItem = streamProxyController.one("schedule", stream);  
584 - if (Objects.nonNull(streamProxyItem) && StringUtils.isNotEmpty(streamProxyItem.getApp())) {  
585 - try {  
586 - streamProxyController.start("schedule", stream);  
587 - } catch (Exception e) {  
588 - log.error(e.getMessage());  
589 - }  
590 - } else {  
591 - createStreamProxy(stream, httpPort);  
592 - }  
593 -  
594 -  
595 - } else if (Objects.nonNull(valObj) && StringUtils.equals(valObj.toString(), "2")) {  
596 -// streamProxyService.del("schedule", stream);  
597 -// redisTemplate.delete("jt1078:stream:status:" + stream);  
598 -// createStreamProxy(stream,httpPort);  
599 - streamProxyService.stop1("schedule", stream);  
600 -  
601 - } else {  
602 - Object val = this.redisTemplate.opsForValue().get("timeout:" + stream);  
603 - if (Objects.nonNull(val) && StringUtils.equals(val.toString(), "1")) {  
604 - try {  
605 - streamProxyController.start("schedule", stream);  
606 - } catch (Exception e) {  
607 - log.error(e.getMessage());  
608 - }  
609 - }  
610 - }  
611 -  
612 - Integer countVal = stremProxyService1078.stopCount(stream);  
613 - if (Objects.nonNull(countVal)) {  
614 - index = countVal;  
615 - }  
616 - if (index >= count) {  
617 -  
618 - break;  
619 - }  
620 866
621 - try {  
622 - Thread.sleep(1000L);  
623 - } catch (InterruptedException e) {  
624 - log.info(e.getMessage());  
625 - }  
626 - } while (index < count);  
627 867
628 - } catch (Exception e) {  
629 - log.error(e.getMessage());  
630 - } 868 + StreamContent streamContent = this.getStreamContentPlayURL(stream);
631 return streamContent; 869 return streamContent;
632 } 870 }
633 871
  872 + /**
  873 + * 获取视频播放地址
  874 + *
  875 + * @param stream 流名称
  876 + * @return 流信息
  877 + */
634 private StreamContent getStreamContentPlayURL(String stream) { 878 private StreamContent getStreamContentPlayURL(String stream) {
635 try { 879 try {
636 - return this.streamPushController.getPlayUrl("schedule", stream, this.mediaConfig.getId()); 880 + StreamContent streamContent = this.streamPushController.getPlayUrl("schedule", stream, this.mediaConfig.getId());
  881 + streamContent.setStream(stream);
  882 + return streamContent;
637 } catch (ControllerException var3) { 883 } catch (ControllerException var3) {
638 log.debug("获取播放地址失败:[{}],[{}]", stream, this.mediaConfig.getId()); 884 log.debug("获取播放地址失败:[{}],[{}]", stream, this.mediaConfig.getId());
639 return null; 885 return null;
@@ -728,69 +974,80 @@ public class Jt1078OfCarController { @@ -728,69 +974,80 @@ public class Jt1078OfCarController {
728 return StringUtils.replace(time, ":", ""); 974 return StringUtils.replace(time, ":", "");
729 } 975 }
730 976
731 - private HttpClientPostEntity createServerLister(String channelMapping) throws URISyntaxException, IOException {  
732 -  
733 - Integer port = RandomUtils.nextInt(this.jt1078ConfigBean.getStart1078Port(), this.jt1078ConfigBean.getEnd1078Port());  
734 - while (true) {  
735 - port = RandomUtils.nextInt(this.jt1078ConfigBean.getStart1078Port(), this.jt1078ConfigBean.getEnd1078Port());  
736 -  
737 - String key = "jt1078:server:port:" + port;  
738 - if (!this.redisTemplate.hasKey(key)) {  
739 - redisTemplate.opsForValue().set("jt1078:server:port:" + port, port, 3, TimeUnit.HOURS);  
740 - break; 977 + /**
  978 + * 获取所有匹配模式 jt1078:server:port:* 的键,并找到其中剩余时间最短的键。
  979 + */
  980 + public String findKeyWithShortestTTL(String keyMatch) {
  981 + String shortestTTLKey = null;
  982 + long shortestTTL = Long.MAX_VALUE;
  983 + // 使用 SCAN 命令遍历键空间
  984 + Cursor<byte[]> cursor = redisTemplate.execute(
  985 + (RedisCallback<Cursor<byte[]>>) connection -> {
  986 + ScanOptions options = ScanOptions.scanOptions().match(keyMatch).count(100).build();
  987 + return connection.scan(options);
  988 + });
  989 +
  990 + if (cursor != null) {
  991 + while (cursor.hasNext()) {
  992 + byte[] keyBytes = cursor.next();
  993 + String key = new String(keyBytes);
  994 +
  995 + // 获取当前键的 TTL
  996 + Long ttl = redisTemplate.getExpire(key, TimeUnit.SECONDS);
  997 + if (ttl != null && ttl >= 0 && ttl < shortestTTL) {
  998 + shortestTTL = ttl;
  999 + shortestTTLKey = key;
  1000 + }
741 } 1001 }
742 -  
743 } 1002 }
  1003 + return shortestTTLKey;
  1004 + }
  1005 +
  1006 + /**
  1007 + * 创建监听者
  1008 + *
  1009 + * @param channelMapping
  1010 + * @return
  1011 + */
  1012 + private HttpClientPostEntity createServerLister(String channelMapping, Integer port, Integer httPort) throws URISyntaxException, IOException {
  1013 +
  1014 + //不存在存入redis
  1015 + redisTemplate.opsForValue().set("jt1078:server:port:" + port, port, 3, TimeUnit.HOURS);
744 // Integer port = 11078; 1016 // Integer port = 11078;
745 - Integer httPort = 3333;  
746 1017
747 String url = this.jt1078ConfigBean.formatPushURL(channelMapping, port, httPort); 1018 String url = this.jt1078ConfigBean.formatPushURL(channelMapping, port, httPort);
748 -  
749 try { 1019 try {
750 HttpClientPostEntity httpClientPostEntity = new HttpClientPostEntity(); 1020 HttpClientPostEntity httpClientPostEntity = new HttpClientPostEntity();
751 -  
752 httpClientPostEntity.setHttpPort(httPort); 1021 httpClientPostEntity.setHttpPort(httPort);
753 httpClientPostEntity.setPort(port); 1022 httpClientPostEntity.setPort(port);
754 return httpClientPostEntity; 1023 return httpClientPostEntity;
755 -  
756 } catch (Exception e) { 1024 } catch (Exception e) {
757 log.error("url:[{}]", url, e); 1025 log.error("url:[{}]", url, e);
758 return null; 1026 return null;
759 } 1027 }
760 } 1028 }
761 1029
762 - private Map<String, Object> chooseEntity(HttpClientPostEntity entity, String url, boolean flag) { 1030 + private void chooseEntity(HttpClientPostEntity entity, String url, boolean flag) {
763 Map<String, Object> result = new HashMap(); 1031 Map<String, Object> result = new HashMap();
764 if (Objects.isNull(entity)) { 1032 if (Objects.isNull(entity)) {
765 - result.put("code", "301");  
766 - result.put("msg", "下发指令异常");  
767 - return result; 1033 + throw new ControllerException(ErrorCode.ERROR301);
768 } else { 1034 } else {
769 try { 1035 try {
770 Map<String, Object> rsultMap = (Map) JSON.parseObject(entity.getResultStr(), HashMap.class); 1036 Map<String, Object> rsultMap = (Map) JSON.parseObject(entity.getResultStr(), HashMap.class);
771 if (Objects.equals(rsultMap.get("code"), "4000") || Objects.equals(rsultMap.get("code"), 4000)) { 1037 if (Objects.equals(rsultMap.get("code"), "4000") || Objects.equals(rsultMap.get("code"), 4000)) {
772 - result.put("code", "304");  
773 - result.put("msg", "离线的客户端(请检查设备是否注册或者鉴权");  
774 - return result; 1038 + throw new ControllerException(ErrorCode.ERROR304);
775 } 1039 }
776 1040
777 if (flag) { 1041 if (flag) {
778 - if (Objects.nonNull(rsultMap.get("success")) && StringUtils.equalsAnyIgnoreCase(String.valueOf(rsultMap.get("success")), new CharSequence[]{"true"})) {  
779 - return null;  
780 - }  
781 -  
782 if (StringUtils.isNoneBlank(new CharSequence[]{rsultMap.get("msg") + ""})) { 1042 if (StringUtils.isNoneBlank(new CharSequence[]{rsultMap.get("msg") + ""})) {
783 - result.put("code", "304");  
784 - result.put("msg", rsultMap.get("msg"));  
785 - return result; 1043 + throw new ControllerException(304, String.valueOf(rsultMap.get("msg")));
786 } 1044 }
787 } 1045 }
788 } catch (Exception var6) { 1046 } catch (Exception var6) {
789 Exception e = var6; 1047 Exception e = var6;
790 - log.error("entity.getResultStr():{{}}", entity.getResultStr(), e.getMessage()); 1048 + log.error("entity.getResultStr():{{}}", entity.getResultStr(), e.getMessage(), e);
  1049 + throw new ControllerException(500,e.getMessage());
791 } 1050 }
792 -  
793 - return null;  
794 } 1051 }
795 } 1052 }
796 1053
@@ -841,27 +1098,5 @@ public class Jt1078OfCarController { @@ -841,27 +1098,5 @@ public class Jt1078OfCarController {
841 } 1098 }
842 } 1099 }
843 }).start(); 1100 }).start();
844 -  
845 -  
846 -// String url = StringUtils.replace(jt1078ConfigBean.getGetURL(), "{stream}", stream);  
847 -// url = StringUtils.replace(url, "{port}", port + "");  
848 -// StreamProxyItem item = new StreamProxyItem();  
849 -// item.setApp("schedule");  
850 -// item.setEnable(true);  
851 -// item.setEnableAudio(true);  
852 -// item.setRtpType("default");  
853 -// item.setStream(stream);  
854 -// item.setMediaServerId(mediaConfig.getId());  
855 -// item.setUrl(url);  
856 -// item.setFfmpegCmdKey("ffmpeg.cmd");  
857 -// item.setEnable(true);  
858 -// item.setEnableAudio(true);  
859 -// item.setEnableMp4(false);  
860 -// item.setEnableRemoveNoneReader(false);  
861 -// item.setEnableDisableNoneReader(false);  
862 -// item.setName(stream);  
863 -// streamProxyController.save(item);  
864 -  
865 -  
866 } 1101 }
867 } 1102 }
src/main/java/com/genersoft/iot/vmp/vmanager/jt1078/platform/config/DataBuffer.java 0 → 100644
  1 +package com.genersoft.iot.vmp.vmanager.jt1078.platform.config;
  2 +
  3 +import java.util.ArrayList;
  4 +import java.util.List;
  5 +import java.util.concurrent.LinkedBlockingDeque;
  6 +import java.util.concurrent.atomic.AtomicBoolean;
  7 +
  8 +/**
  9 + * 数据缓存区
  10 + * @Author WangXin
  11 + * @Data 2024/11/26
  12 + * @Version 1.0.0
  13 + */
  14 +public class DataBuffer<T> {
  15 +
  16 + private LinkedBlockingDeque<T> trueQueue = new LinkedBlockingDeque<>();
  17 +
  18 + private LinkedBlockingDeque<T> falseQueue = new LinkedBlockingDeque<>();
  19 +
  20 + private final AtomicBoolean booleanValue = new AtomicBoolean(false);
  21 +
  22 + public void setValue(T dataValue){
  23 + if (booleanValue.get()){
  24 + trueQueue.add(dataValue);
  25 + }else {
  26 + falseQueue.add(dataValue);
  27 + }
  28 + }
  29 +
  30 + public List<T> getDataList(){
  31 + if (booleanValue.getAndSet(!booleanValue.get())){
  32 + return new ArrayList<>(trueQueue);
  33 + }
  34 + return new ArrayList<>(falseQueue);
  35 + }
  36 +}
src/main/java/com/genersoft/iot/vmp/vmanager/jt1078/platform/config/DataBufferConfig.java 0 → 100644
  1 +package com.genersoft.iot.vmp.vmanager.jt1078.platform.config;
  2 +
  3 +import com.genersoft.iot.vmp.vmanager.jt1078.platform.domain.SimFlow;
  4 +import com.genersoft.iot.vmp.vmanager.jt1078.platform.service.FlowService;
  5 +import org.apache.commons.collections4.CollectionUtils;
  6 +import org.slf4j.Logger;
  7 +import org.slf4j.LoggerFactory;
  8 +import org.springframework.context.annotation.Bean;
  9 +import org.springframework.context.annotation.Configuration;
  10 +
  11 +import javax.annotation.Resource;
  12 +import java.text.SimpleDateFormat;
  13 +import java.util.Date;
  14 +import java.util.List;
  15 +import java.util.Map;
  16 +import java.util.Set;
  17 +import java.util.concurrent.ScheduledExecutorService;
  18 +import java.util.concurrent.TimeUnit;
  19 +import java.util.stream.Collectors;
  20 +
  21 +/**
  22 + * 数据缓存配置类
  23 + * @Author WangXin
  24 + * @Data 2024/11/26
  25 + * @Version 1.0.0
  26 + */
  27 +@Configuration
  28 +public class DataBufferConfig {
  29 +
  30 + private static final Logger log = LoggerFactory.getLogger(DataBufferConfig.class);
  31 +
  32 + @Resource
  33 + private FlowService flowService;
  34 +
  35 +
  36 + /**
  37 + * 储存原始数据
  38 + * @return
  39 + */
  40 + @Bean("simFlowDataBuffer")
  41 + public DataBuffer<SimFlow> storeCarOriginalDataDataBuffer(ScheduledExecutorService scheduledExecutor) {
  42 + DataBuffer<SimFlow> carOriginalDataDataBuffer = new DataBuffer<>();
  43 + scheduledExecutor.scheduleAtFixedRate(() -> {
  44 + try {
  45 + List<SimFlow> dataList = carOriginalDataDataBuffer.getDataList();
  46 + if (CollectionUtils.isNotEmpty(dataList)) {
  47 + Map<String, SimFlow> map = dataList.stream()
  48 + .collect(Collectors.toMap(
  49 + // 创建唯一键:simId_channel_timestamp
  50 + record -> record.getSim() + "_" + record.getChannel() + "_" + record.getTime(),
  51 + // 选择要放入map中的值
  52 + record -> record,
  53 + // 解决键冲突问题(如果有相同的键,则保留第一个)
  54 + (existing, replacement) -> {
  55 + existing.setFlow(existing.getFlow() + replacement.getFlow());
  56 + return existing;
  57 + }
  58 + ));
  59 + //批量落库
  60 + Set<Map.Entry<String, SimFlow>> entries = map.entrySet();
  61 + entries.forEach(entry -> {
  62 + SimFlow value = entry.getValue();
  63 + SimFlow simFlow = flowService.selectOne(value);
  64 + if (simFlow == null) {
  65 + boolean b = flowService.addFlow(value);
  66 + log.info("流量信息添加 {} ",b?"成功":"失败");
  67 + }else {
  68 + boolean b = flowService.updateFlow(value);
  69 + log.info("修改库中流量信息 {} ",b?"成功":"失败");
  70 + }
  71 + });
  72 + }
  73 + } catch (Exception e) {
  74 + log.error("流量统计落库异常 ===》 {}",e.getMessage(), e);
  75 + }
  76 + }, 30, 30, TimeUnit.SECONDS);
  77 + return carOriginalDataDataBuffer;
  78 + }
  79 +}
src/main/java/com/genersoft/iot/vmp/vmanager/jt1078/platform/config/Jt1078ConfigBean.java
1 -package com.genersoft.iot.vmp.vmanager.jt1078.platform.config; import com.genersoft.iot.vmp.vmanager.jt1078.platform.config.RtspConfigBean; import java.util.Objects; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Component public class Jt1078ConfigBean { @Value("${tuohua.bsth.jt1078.url}") private String jt1078Url; @Value("${tuohua.bsth.jt1078.sendPort}") private String jt1078SendPort; @Value("${tuohua.bsth.jt1078.stopSendPort}") private String stopSendPort; @Value("${tuohua.bsth.jt1078.historyListPort}") private String historyListPort; @Value("${tuohua.bsth.jt1078.playHistoryPort}") private String playHistoryPort; @Value("${tuohua.bsth.jt1078.ports}") private String portsOf1078; @Value("${tuohua.bsth.jt1078.pushURL}") private String pushURL; @Value("${tuohua.bsth.jt1078.stopPushURL}") private String stopPUshURL; private Integer start1078Port; private Integer end1078Port; @Value("${tuohua.bsth.jt1078.get.url}") private String getURL; @Value("${tuohua.bsth.jt1078.addPortVal}") private Integer addPort; @Value("${tuohua.bsth.jt1078.ws}") private String ws; @Value("${tuohua.bsth.jt1078.wss}") private String wss; @Value("${tuohua.bsth.jt1078.downloadFLV}") private String downloadFlv; private static final String SEND_IO_MESSAGE_RTSP = "{ \"messageId\": 37121, \"properties\": 0, \"clientId\": \"{clientId}\", \"serialNo\": \"1\", \"ip\": \"{ip}\", \"tcpPort\": \"{tcpPort}\", \"udpPort\": \"{udpPort}\", \"channelNo\": \"{channelNo}\", \"mediaType\": \"1\", \"streamType\": \"1\"}"; private static final String SEND_IO_MESSAGE_RTSP_STOP = "{\"messageId\": 37122,\"properties\": 0,\"clientId\": \"{clientId}\",\"serialNo\": \"1\",\"channelNo\": \"{channelNo}\",\"command\": \"0\",\"closeType\": \"0\",\"streamType\": \"1\"}"; private static final String SEND_IO_HISTORY_RTSP = "{\"msgid\":37381,\"clientId\":\"{clientId}\",\"startTime\":\"{startTime}\",\"endTime\":\"{endTime}\",\"mediaType\":0,\"streamType\":0,\"storageType\":0,\"channelId\":{channelNo}}"; private static final String SEND_IO_PLAY_RTSP = "{\"ip\":\"{ip}\",\"tcpPort\":{tcpPort},\"udpPort\":{udpPort},\"channelNo\":\"{channelNo}\",\"mediaType\":0,\"streamType\":0,\"storageType\":0,\"playbackType\":0,\"playbackSpeed\":1,\"startTime\":\"{startTime}\",\"endTime\":\"{endTime}\",\"clientId\":\"{sim}\",\"messageId\":37377}"; public String formatMessageId(String sim, String channel, RtspConfigBean configBean, Integer port) { String msg = StringUtils.replace("{ \"messageId\": 37121, \"properties\": 0, \"clientId\": \"{clientId}\", \"serialNo\": \"1\", \"ip\": \"{ip}\", \"tcpPort\": \"{tcpPort}\", \"udpPort\": \"{udpPort}\", \"channelNo\": \"{channelNo}\", \"mediaType\": \"1\", \"streamType\": \"1\"}", "{clientId}", sim); msg = StringUtils.replace(msg, "{tcpPort}", (port.intValue() +getAddPort()) + ""); msg = StringUtils.replace(msg, "{udpPort}", (port.intValue() +getAddPort()) + ""); msg = StringUtils.replace(msg, "{channelNo}", channel); return StringUtils.replace(msg, "{ip}", configBean.getRtspIp()); } public String formatMessageStop(String sim, String channel) { String msg = StringUtils.replace("{\"messageId\": 37122,\"properties\": 0,\"clientId\": \"{clientId}\",\"serialNo\": \"1\",\"channelNo\": \"{channelNo}\",\"command\": \"0\",\"closeType\": \"0\",\"streamType\": \"1\"}", "{clientId}", sim); return StringUtils.replace(msg, "{channelNo}", channel); } public String formatMessageHistoryListRTSP(String sim, String channel, String startTime, String endTime) { String msg = StringUtils.replace("{\"msgid\":37381,\"clientId\":\"{clientId}\",\"startTime\":\"{startTime}\",\"endTime\":\"{endTime}\",\"mediaType\":0,\"streamType\":0,\"storageType\":0,\"channelId\":{channelNo}}", "{clientId}", sim); msg = StringUtils.replace(msg, "{startTime}", startTime); msg = StringUtils.replace(msg, "{endTime}", endTime); return StringUtils.replace(msg, "{channelNo}", channel); } public String formatMessageHistoryPlayRTSP(String sim, String channel, String startTime, String endTime, RtspConfigBean configBean, Integer port) { String msg = StringUtils.replace("{\"ip\":\"{ip}\",\"tcpPort\":{tcpPort},\"udpPort\":{udpPort},\"channelNo\":\"{channelNo}\",\"mediaType\":0,\"streamType\":0,\"storageType\":0,\"playbackType\":0,\"playbackSpeed\":1,\"startTime\":\"{startTime}\",\"endTime\":\"{endTime}\",\"clientId\":\"{sim}\",\"messageId\":37377}", "{clientId}", sim); msg = StringUtils.replace(msg, "{startTime}", startTime); msg = StringUtils.replace(msg, "{endTime}", endTime); msg = StringUtils.replace(msg, "{channelNo}", channel); msg = StringUtils.replace(msg, "{tcpPort}", (port.intValue() +getAddPort()) + ""); msg = StringUtils.replace(msg, "{udpPort}", (port.intValue() +getAddPort()) + ""); msg = StringUtils.replace(msg, "{sim}", sim); return StringUtils.replace(msg, "{ip}", configBean.getRtspIp()); } public String formatPushURL(String pushKey, int port, int httpPort) { String msg = StringUtils.replace(this.pushURL, "{pushKey}", pushKey); msg = StringUtils.replace(msg, "{port}", String.valueOf(port)); return StringUtils.replace(msg, "{httpPort}", String.valueOf(httpPort)); } public String formatStopPushURL(String pushKey, int port, int httpPort) { String msg = StringUtils.replace(this.stopPUshURL, "{pushKey}", pushKey); msg = StringUtils.replace(msg, "{port}", String.valueOf(port)); return StringUtils.replace(msg, "{httpPort}", String.valueOf(httpPort)); } public String formatVideoURL(String stream){ String url = StringUtils.replace(getGetURL(),"{stream}",stream); if(!StringUtils.endsWith(url,".flv")){ url = url+".flv"; } return url; } public String getJt1078Url() { return this.jt1078Url; } public String getJt1078SendPort() { return this.jt1078SendPort; } public String getStopSendPort() { return this.stopSendPort; } public String getHistoryListPort() { return this.historyListPort; } public String getPlayHistoryPort() { return this.playHistoryPort; } public String getPushURL() { return this.pushURL; } public Integer getStart1078Port() { if (Objects.isNull(this.start1078Port)) this.start1078Port = Integer.valueOf(Integer.parseInt(StringUtils.substringBefore(this.portsOf1078, ","))); return this.start1078Port; } public Integer getEnd1078Port() { if (Objects.isNull(this.end1078Port)) this.end1078Port = Integer.valueOf(Integer.parseInt(StringUtils.substringAfter(this.portsOf1078, ","))); return this.end1078Port; } public String getStopPUshURL() { return this.stopPUshURL; } public String getGetURL() { return this.getURL; } public Integer getAddPort() { return this.addPort; } public String getWs() { return this.ws; } public String getWss() { return this.wss; } public String getDownloadFlv() { return downloadFlv; } public String getPortsOf1078() { return portsOf1078; } }  
2 \ No newline at end of file 1 \ No newline at end of file
  2 +package com.genersoft.iot.vmp.vmanager.jt1078.platform.config; import com.genersoft.iot.vmp.vmanager.jt1078.platform.Jt1078OfCarController; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import javax.annotation.Resource; import java.util.*; @Component public class Jt1078ConfigBean { @Value("${tuohua.bsth.jt1078.url}") private String jt1078Url; @Value("${tuohua.bsth.jt1078.sendPort}") private String jt1078SendPort; @Value("${tuohua.bsth.jt1078.stopSendPort}") private String stopSendPort; @Value("${tuohua.bsth.jt1078.historyListPort}") private String historyListPort; @Value("${tuohua.bsth.jt1078.playHistoryPort}") private String playHistoryPort; @Value("${tuohua.bsth.jt1078.ports}") private String portsOf1078; @Value("${tuohua.bsth.jt1078.pushURL}") private String pushURL; @Value("${tuohua.bsth.jt1078.stopPushURL}") private String stopPUshURL; private Integer start1078Port; private Integer end1078Port; @Value("${tuohua.bsth.jt1078.get.url}") private String getURL; @Value("${tuohua.bsth.jt1078.addPortVal}") private Integer addPort; @Value("${tuohua.bsth.jt1078.ws}") private String ws; @Value("${tuohua.bsth.jt1078.wss}") private String wss; @Value("${tuohua.bsth.jt1078.downloadFLV}") private String downloadFlv; @Value("${tuohua.bsth.jt1078.port}") private Integer port; @Value("${tuohua.bsth.jt1078.httpPort}") private Integer httpPort; @Value("${spring.profiles.active}") private String profilesActive; @Value("${media.pushKey}") private String pushKey; @Resource private RedisTemplate<String, Integer> redisTemplate; public Integer getPort() { if (port == null) { return 30000; } return port; } public Integer getHttpPort() { if (httpPort == null) { return 30000; } return httpPort; } private Integer getIntPort() { return profilesActive.equals("wx-local") ? 10000 : 0; } @PostConstruct public void initMap() { Set<String> historyPortKeys = redisTemplate.keys("history:port:*"); Set<String> keys = redisTemplate.keys("tag:*"); Set<String> patrolKeys = redisTemplate.keys("patrol:stream:*"); if (!historyPortKeys.isEmpty()) { keys.addAll(historyPortKeys); } if (!patrolKeys.isEmpty()) { keys.addAll(patrolKeys); } if (keys != null) { redisTemplate.delete(keys); } Map<Integer, Set<String>> hashMap = new HashMap<>(); for (int number = getStart1078Port(); number <= getEnd1078Port(); number++) { hashMap.put(number, new HashSet<>()); } Jt1078OfCarController.map.putAll(hashMap); } private static final String SEND_IO_MESSAGE_RTSP = "{ \"messageId\": 37121, \"properties\": 0, \"clientId\": \"{clientId}\", \"serialNo\": \"1\", \"ip\": \"{ip}\", \"tcpPort\": \"{tcpPort}\", \"udpPort\": \"{udpPort}\", \"channelNo\": \"{channelNo}\", \"mediaType\": \"1\", \"streamType\": \"1\"}"; private static final String SEND_IO_MESSAGE_RTSP_STOP = "{\"messageId\": 37122,\"properties\": 0,\"clientId\": \"{clientId}\",\"serialNo\": \"1\",\"channelNo\": \"{channelNo}\",\"command\": \"0\",\"closeType\": \"0\",\"streamType\": \"1\"}"; private static final String SEND_IO_HISTORY_RTSP = "{\"msgid\":37381,\"clientId\":\"{clientId}\",\"startTime\":\"{startTime}\",\"endTime\":\"{endTime}\",\"mediaType\":0,\"streamType\":0,\"storageType\":0,\"channelId\":{channelNo}}"; private static final String SEND_IO_PLAY_RTSP = "{\"ip\":\"{ip}\",\"tcpPort\":{tcpPort},\"udpPort\":{udpPort},\"channelNo\":\"{channelNo}\",\"mediaType\":0,\"streamType\":0,\"storageType\":0,\"playbackType\":0,\"playbackSpeed\":1,\"startTime\":\"{startTime}\",\"endTime\":\"{endTime}\",\"clientId\":\"{sim}\",\"messageId\":37377}"; public String formatMessageId(String sim, String channel, RtspConfigBean configBean, Integer port) { String msg = StringUtils.replace("{ \"messageId\": 37121, \"properties\": 0, \"clientId\": \"{clientId}\", \"serialNo\": \"1\", \"ip\": \"{ip}\", \"tcpPort\": \"{tcpPort}\", \"udpPort\": \"{udpPort}\", \"channelNo\": \"{channelNo}\", \"mediaType\": \"1\", \"streamType\": \"1\"}", "{clientId}", sim); msg = StringUtils.replace(msg, "{tcpPort}", (port.intValue() + getIntPort() + getAddPort()) + ""); msg = StringUtils.replace(msg, "{udpPort}", (port.intValue() + getIntPort() + getAddPort()) + ""); msg = StringUtils.replace(msg, "{channelNo}", channel); return StringUtils.replace(msg, "{ip}", configBean.getRtspIp()); } public String formatMessageStop(String sim, String channel) { String msg = StringUtils.replace("{\"messageId\": 37122,\"properties\": 0,\"clientId\": \"{clientId}\",\"serialNo\": \"1\",\"channelNo\": \"{channelNo}\",\"command\": \"0\",\"closeType\": \"0\",\"streamType\": \"1\"}", "{clientId}", sim); return StringUtils.replace(msg, "{channelNo}", channel); } public String formatMessageHistoryListRTSP(String sim, String channel, String startTime, String endTime) { String msg = StringUtils.replace("{\"msgid\":37381,\"clientId\":\"{clientId}\",\"startTime\":\"{startTime}\",\"endTime\":\"{endTime}\",\"mediaType\":0,\"streamType\":0,\"storageType\":0,\"channelId\":{channelNo}}", "{clientId}", sim); msg = StringUtils.replace(msg, "{startTime}", startTime); msg = StringUtils.replace(msg, "{endTime}", endTime); return StringUtils.replace(msg, "{channelNo}", channel); } public String formatMessageHistoryPlayRTSP(String sim, String channel, String startTime, String endTime, RtspConfigBean configBean, Integer port) { String msg = StringUtils.replace("{\"ip\":\"{ip}\",\"tcpPort\":{tcpPort},\"udpPort\":{udpPort},\"channelNo\":\"{channelNo}\",\"mediaType\":0,\"streamType\":0,\"storageType\":0,\"playbackType\":0,\"playbackSpeed\":1,\"startTime\":\"{startTime}\",\"endTime\":\"{endTime}\",\"clientId\":\"{sim}\",\"messageId\":37377}", "{clientId}", sim); msg = StringUtils.replace(msg, "{startTime}", startTime); msg = StringUtils.replace(msg, "{endTime}", endTime); msg = StringUtils.replace(msg, "{channelNo}", channel); msg = StringUtils.replace(msg, "{tcpPort}", (port.intValue() + getIntPort() +getAddPort()) + ""); msg = StringUtils.replace(msg, "{udpPort}", (port.intValue() + getIntPort() + getAddPort()) + ""); msg = StringUtils.replace(msg, "{sim}", sim); return StringUtils.replace(msg, "{ip}", configBean.getRtspIp()); } public String formatMessageHistoryStopRTSP(String sim, String channel, RtspConfigBean configBean) { String msg = StringUtils.replace("{\"playbackMode\":2,\"channelNo\":{channelNo},\"playbackSpeed\":0,\"clientId\":\"{sim}\"}", "{sim}", sim); return StringUtils.replace(msg, "{channelNo}", channel); } public String formatPushURL(String pushKey, int port, int httpPort) { String msg = StringUtils.replace(this.pushURL, "{pushKey}", pushKey); msg = StringUtils.replace(msg, "{port}", String.valueOf(port)); return StringUtils.replace(msg, "{httpPort}", String.valueOf(httpPort)); } public String formatStopPushURL(String pushKey, int port, int httpPort) { String msg = StringUtils.replace(this.stopPUshURL, "{pushKey}", pushKey); msg = StringUtils.replace(msg, "{port}", String.valueOf(port)); return StringUtils.replace(msg, "{httpPort}", String.valueOf(httpPort)); } public String formatVideoURL(String stream) { String url = StringUtils.replace(getGetURL(), "{stream}", stream); if (!StringUtils.endsWith(url, ".flv")) { url = url + ".flv"; } return url; } public String getJt1078Url() { return this.jt1078Url; } public String getJt1078SendPort() { return this.jt1078SendPort; } public String getStopSendPort() { return this.stopSendPort; } public String getHistoryListPort() { return this.historyListPort; } public String getPlayHistoryPort() { return this.playHistoryPort; } public String getPushURL() { return this.pushURL; } public Integer getStart1078Port() { if (Objects.isNull(this.start1078Port)) this.start1078Port = Integer.valueOf(Integer.parseInt(StringUtils.substringBefore(this.portsOf1078, ","))); return this.start1078Port; } public Integer getEnd1078Port() { if (Objects.isNull(this.end1078Port)) this.end1078Port = Integer.valueOf(Integer.parseInt(StringUtils.substringAfter(this.portsOf1078, ","))); return this.end1078Port; } public String getPushKey(){ if (Objects.isNull(this.pushKey)){ this.pushKey = "?callId=41db35390ddad33f83944f44b8b75ded"; } return "?callId="+this.pushKey; } public String getStopPUshURL() { return this.stopPUshURL; } public String getGetURL() { return this.getURL; } public Integer getAddPort() { return this.addPort; } public String getWs() { return this.ws; } public String getWss() { return this.wss; } public String getDownloadFlv() { return downloadFlv; } public String getPortsOf1078() { return portsOf1078; } }
3 \ No newline at end of file 3 \ No newline at end of file
src/main/java/com/genersoft/iot/vmp/vmanager/jt1078/platform/config/ThreadConfig.java 0 → 100644
  1 +package com.genersoft.iot.vmp.vmanager.jt1078.platform.config;
  2 +
  3 +import org.springframework.context.annotation.Bean;
  4 +import org.springframework.context.annotation.Configuration;
  5 +
  6 +import java.util.concurrent.ScheduledExecutorService;
  7 +import java.util.concurrent.ScheduledThreadPoolExecutor;
  8 +
  9 +/**
  10 + * 周期性线程池配置
  11 + *
  12 + * @Author WangXin
  13 + * @Data 2024/11/26
  14 + * @Version 1.0.0
  15 + */
  16 +@Configuration
  17 +public class ThreadConfig {
  18 +
  19 + /**
  20 + * 周期性线程池
  21 + * @return
  22 + */
  23 + @Bean("scheduledExecutor")
  24 + public ScheduledExecutorService scheduledExecutor() {
  25 + return new ScheduledThreadPoolExecutor(Runtime.getRuntime().availableProcessors());
  26 + }
  27 +}
src/main/java/com/genersoft/iot/vmp/vmanager/jt1078/platform/config/TuohuaConfigBean.java
@@ -43,7 +43,7 @@ public class TuohuaConfigBean { @@ -43,7 +43,7 @@ public class TuohuaConfigBean {
43 private String simURL; 43 private String simURL;
44 44
45 @Value("${tuohua.bsth.login.rest.baseURL}") 45 @Value("${tuohua.bsth.login.rest.baseURL}")
46 - public String baseURL; 46 + public String baseURL;
47 @Value("${tuohua.bsth.login.rest.password}") 47 @Value("${tuohua.bsth.login.rest.password}")
48 private String restPassword; 48 private String restPassword;
49 49
@@ -138,15 +138,12 @@ public class TuohuaConfigBean { @@ -138,15 +138,12 @@ public class TuohuaConfigBean {
138 return null; 138 return null;
139 } 139 }
140 return (List<HashMap>) JSON.parseArray(postEntity.getResultStr(), HashMap.class); 140 return (List<HashMap>) JSON.parseArray(postEntity.getResultStr(), HashMap.class);
141 -  
142 } 141 }
143 142
144 public List<HashMap<String, Object>> requestOfLineAndCarAndCombationTree(HttpClientUtil httpClientUtil, String companyId) throws Exception { 143 public List<HashMap<String, Object>> requestOfLineAndCarAndCombationTree(HttpClientUtil httpClientUtil, String companyId) throws Exception {
145 String lineJson = requestLine(httpClientUtil, companyId); 144 String lineJson = requestLine(httpClientUtil, companyId);
146 String carJson = requestCars(httpClientUtil, companyId); 145 String carJson = requestCars(httpClientUtil, companyId);
147 // String carJson = redisTemplate.opsForValue().get("test:car").toString(); 146 // String carJson = redisTemplate.opsForValue().get("test:car").toString();
148 -  
149 -  
150 List<HashMap> linesJsonList = null; 147 List<HashMap> linesJsonList = null;
151 int linesSize = 0; 148 int linesSize = 0;
152 if (StringUtils.isNoneBlank(lineJson)) { 149 if (StringUtils.isNoneBlank(lineJson)) {
@@ -179,15 +176,12 @@ public class TuohuaConfigBean { @@ -179,15 +176,12 @@ public class TuohuaConfigBean {
179 ch.put("used", "1"); 176 ch.put("used", "1");
180 return combatioinCarTree(ch,gpsList); 177 return combatioinCarTree(ch,gpsList);
181 }).collect(Collectors.toList()); 178 }).collect(Collectors.toList());
182 -  
183 map.put("children", carList); 179 map.put("children", carList);
184 } 180 }
185 -  
186 return map; 181 return map;
187 }).collect(Collectors.toList()); 182 }).collect(Collectors.toList());
188 returnData.addAll(lines); 183 returnData.addAll(lines);
189 } 184 }
190 -  
191 if (carsSize > 0) { 185 if (carsSize > 0) {
192 List<HashMap<String, Object>> cars = carJsonList.stream().filter(c -> !Objects.equals(convertStr(c.get("used")), "1")).map(c -> combatioinCarTree(c,gpsList)).collect(Collectors.toList()); 186 List<HashMap<String, Object>> cars = carJsonList.stream().filter(c -> !Objects.equals(convertStr(c.get("used")), "1")).map(c -> combatioinCarTree(c,gpsList)).collect(Collectors.toList());
193 returnData.addAll(cars); 187 returnData.addAll(cars);
@@ -242,7 +236,12 @@ public class TuohuaConfigBean { @@ -242,7 +236,12 @@ public class TuohuaConfigBean {
242 return result; 236 return result;
243 } 237 }
244 238
245 - 239 + /**
  240 + * 修改测试号
  241 + * @param ch
  242 + * @param gpsList
  243 + * @return
  244 + */
246 private HashMap<String, Object> combatioinCarTree(HashMap ch, List<HashMap> gpsList) { 245 private HashMap<String, Object> combatioinCarTree(HashMap ch, List<HashMap> gpsList) {
247 String code = convertStr(ch.get("nbbm")); 246 String code = convertStr(ch.get("nbbm"));
248 String sim = convertStr(ch.get("sim")); 247 String sim = convertStr(ch.get("sim"));
@@ -268,9 +267,9 @@ public class TuohuaConfigBean { @@ -268,9 +267,9 @@ public class TuohuaConfigBean {
268 hashMap.put("sim", formatSim(convertStr(ch.get("sim")))); 267 hashMap.put("sim", formatSim(convertStr(ch.get("sim"))));
269 hashMap.put("abnormalStatus",abnormalStatus); 268 hashMap.put("abnormalStatus",abnormalStatus);
270 269
271 - if (StringUtils.equals(profileActive, "local")) {  
272 -// hashMap.put("sim","123456789011");  
273 - hashMap.put("sim", "122223333444"); 270 + if (StringUtils.equals(profileActive, "wx-local")) {
  271 + hashMap.put("sim","123456789011");
  272 +// hashMap.put("sim", "122223333444");
274 } 273 }
275 // 274 //
276 return hashMap; 275 return hashMap;
src/main/java/com/genersoft/iot/vmp/vmanager/jt1078/platform/domain/CarData.java 0 → 100644
  1 +package com.genersoft.iot.vmp.vmanager.jt1078.platform.domain;
  2 +
  3 +import lombok.AllArgsConstructor;
  4 +import lombok.Data;
  5 +import lombok.NoArgsConstructor;
  6 +import lombok.experimental.SuperBuilder;
  7 +
  8 +/**
  9 + * 大邑车辆对象
  10 + *
  11 + * @Author WangXin
  12 + * @Data 2025/1/17
  13 + * @Version 1.0.0
  14 + */
  15 +@Data
  16 +@SuperBuilder
  17 +@AllArgsConstructor
  18 +@NoArgsConstructor
  19 +public class CarData {
  20 +
  21 + /**
  22 + * 车辆自编号
  23 + */
  24 + private String nbbm;
  25 + /**
  26 + * 公司编码
  27 + */
  28 + private String companyCode;
  29 + /**
  30 + * 子公司编码
  31 + */
  32 + private String brancheCompanyCode;
  33 + /**
  34 + * 车牌号
  35 + */
  36 + private String carPlate;
  37 + /**
  38 + * 车辆编码
  39 + */
  40 + private String equipmentCode;
  41 + /**
  42 + * 车型
  43 + */
  44 + private Object carType;
  45 + /**
  46 + * 车辆状态
  47 + */
  48 + private Object vehicleStats;
  49 + /**
  50 + * "sfdc" : false
  51 + */
  52 + private Boolean sfdc;
  53 + /**
  54 + * "scrapState" : false,
  55 + */
  56 + private Boolean scrapState;
  57 + /**
  58 + * "idRfid" : null,
  59 + */
  60 + private Object idRfid;
  61 + /**
  62 + * "tagRfid" : null
  63 + */
  64 + private Object tagRfid;
  65 + /**
  66 + * 线路编号
  67 + */
  68 + private String lineCode;
  69 + /**
  70 + * 线路名称
  71 + */
  72 + private String lineName;
  73 + /**
  74 + * 备注
  75 + */
  76 + private Object remark;
  77 + /**
  78 + * 修改时间
  79 + */
  80 + private Long updateDate;
  81 + /**
  82 + * sim号
  83 + */
  84 + private String sim;
  85 +}
src/main/java/com/genersoft/iot/vmp/vmanager/jt1078/platform/domain/CarGPSData.java 0 → 100644
  1 +package com.genersoft.iot.vmp.vmanager.jt1078.platform.domain;
  2 +
  3 +import lombok.AllArgsConstructor;
  4 +import lombok.Data;
  5 +import lombok.NoArgsConstructor;
  6 +import lombok.experimental.SuperBuilder;
  7 +
  8 +/**
  9 + * 车辆GPS数据
  10 + *
  11 + * @Author WangXin
  12 + * @Data 2025/1/17
  13 + * @Version 1.0.0
  14 + */
  15 +@Data
  16 +@SuperBuilder
  17 +@AllArgsConstructor
  18 +@NoArgsConstructor
  19 +public class CarGPSData {
  20 +
  21 + /**
  22 + * 公司编码
  23 + */
  24 + private Integer companyCode;
  25 + /**
  26 + * 线路编码
  27 + */
  28 + private String lineId;
  29 + /**
  30 + * 车辆编码
  31 + */
  32 + private String deviceId;
  33 + /**
  34 + * "carparkNo" : "",
  35 + */
  36 + private String carparkNo;
  37 + /**
  38 + * "stopNo" : "144664",
  39 + */
  40 + private String stopNo;
  41 + /**
  42 + * "stationName" : null,
  43 + */
  44 + private Object stationName;
  45 + /**
  46 + * 经度
  47 + */
  48 + private Double lon;
  49 + /**
  50 + * 纬度
  51 + */
  52 + private Double lat;
  53 + /**
  54 + * 时间
  55 + */
  56 + private Long timestamp;
  57 + /**
  58 + * 车速
  59 + */
  60 + private Integer speed;
  61 + /**
  62 + * 方向 "direction" : 236.0,
  63 + */
  64 + private Integer direction;
  65 + /**
  66 + * 车辆状态 0 正常 -1
  67 + */
  68 + private Integer state;
  69 + /**
  70 + * "upDown" : 0,
  71 + */
  72 + private Integer upDown;
  73 + /**
  74 + * 自编号 "nbbm" : null,
  75 + */
  76 + private String nbbm;
  77 + /**
  78 + * "expectStopTime" : null,
  79 + */
  80 + private Object expectStopTime;
  81 + /**
  82 + * "version" : 0,
  83 + */
  84 + private Integer version;
  85 + /**
  86 + * "abnormalStatus" : null,
  87 + */
  88 + private Object abnormalStatus;
  89 + /**
  90 + * "outOfBoundDistance" : 0.0,
  91 + */
  92 + private Integer outOfBoundDistance;
  93 + /**
  94 + * "valid" : 0,
  95 + */
  96 + private Integer valid;
  97 + /**
  98 + * "inOrOutStation" : -1,
  99 + */
  100 + private Integer inOrOutStation;
  101 + /**
  102 + * "sectionCode" : "209599"
  103 + */
  104 + private String sectionCode;
  105 +}
src/main/java/com/genersoft/iot/vmp/vmanager/jt1078/platform/domain/CarTreeData.java 0 → 100644
  1 +package com.genersoft.iot.vmp.vmanager.jt1078.platform.domain;
  2 +
  3 +import lombok.AllArgsConstructor;
  4 +import lombok.Data;
  5 +import lombok.NoArgsConstructor;
  6 +import lombok.experimental.SuperBuilder;
  7 +
  8 +import java.util.List;
  9 +
  10 +/**
  11 + * 大邑车辆树对象
  12 + *
  13 + * @Author WangXin
  14 + * @Data 2025/1/17
  15 + * @Version 1.0.0
  16 + */
  17 +@Data
  18 +@SuperBuilder
  19 +@AllArgsConstructor
  20 +@NoArgsConstructor
  21 +public class CarTreeData {
  22 + /**
  23 + * 唯一Id
  24 + */
  25 + private Integer id;
  26 + /**
  27 + * 名称
  28 + */
  29 + private String name;
  30 + /**
  31 + * 状态
  32 + */
  33 + private Integer state;
  34 + /**
  35 + * 父级Id
  36 + */
  37 + private Integer pid;
  38 + /**
  39 + * sim号
  40 + */
  41 + private String sim;
  42 + /**
  43 + * 子集
  44 + */
  45 + private List<CarTreeData> children;
  46 +
  47 +}
src/main/java/com/genersoft/iot/vmp/vmanager/jt1078/platform/domain/LineData.java 0 → 100644
  1 +package com.genersoft.iot.vmp.vmanager.jt1078.platform.domain;
  2 +
  3 +import lombok.AllArgsConstructor;
  4 +import lombok.Data;
  5 +import lombok.NoArgsConstructor;
  6 +import lombok.experimental.SuperBuilder;
  7 +
  8 +/**
  9 + * 大邑线路对象
  10 + *
  11 + * @Author WangXin
  12 + * @Data 2025/1/17
  13 + * @Version 1.0.0
  14 + */
  15 +@Data
  16 +@SuperBuilder
  17 +@AllArgsConstructor
  18 +@NoArgsConstructor
  19 +public class LineData {
  20 +
  21 + /**
  22 + * 线路名称
  23 + */
  24 + private String name;
  25 + /**
  26 + * 线路编码
  27 + */
  28 + private String lineCode;
  29 + /**
  30 + * 始发站
  31 + */
  32 + private String startStationName;
  33 + /**
  34 + * 终点站
  35 + */
  36 + private String endStationName;
  37 + /**
  38 + * 始发站发车时间
  39 + */
  40 + private String startStationFirstTime;
  41 + /**
  42 + * 始发站末班车时间
  43 + */
  44 + private String startStationEndTime;
  45 + /**
  46 + * 终点站发车时间
  47 + */
  48 + private String endStationFirstTime;
  49 + /**
  50 + * 终点站末班车时间
  51 + */
  52 + private String endStationEndTime;
  53 + /**
  54 + * 公司编号
  55 + */
  56 + private String company;
  57 + /**
  58 + * 公司名称
  59 + */
  60 + private String companyName;
  61 + /**
  62 + * 子公司编号
  63 + */
  64 + private String brancheCompany;
  65 +
  66 + private String nature;
  67 + /**
  68 + * 等级
  69 + */
  70 + private String level;
  71 +
  72 + private Integer destroy;
  73 +
  74 + private Integer supperLine;
  75 +
  76 + private String eqLinecode;
  77 + /**
  78 + * 创建时间
  79 + */
  80 + private Long createDate;
  81 +
  82 + private Integer totalMileage;
  83 +
  84 + private Object earlyIntervalLg;
  85 +
  86 + private Object lateIntervalLg;
  87 +
  88 + private Object intervalLg;
  89 +
  90 + private Integer speedLimit;
  91 +
  92 + private Object lagStation;
  93 +
  94 + private Object skip;
  95 +
  96 + private Integer speeding;
  97 +
  98 + private Object crossedLine;
  99 +
  100 + private Object overflights;
  101 +
  102 + private String shanghaiLinecode;
  103 +
  104 + private Integer linePlayType;
  105 +
  106 + private Integer region;
  107 +
  108 + private Object ticketSellType;
  109 + /**
  110 + * 修改时间
  111 + */
  112 + private Long updateDate;
  113 + /**
  114 + * 使用状态
  115 + */
  116 + private Integer inUse;
  117 +}
src/main/java/com/genersoft/iot/vmp/vmanager/jt1078/platform/domain/PatrolDataReq.java 0 → 100644
  1 +package com.genersoft.iot.vmp.vmanager.jt1078.platform.domain;
  2 +
  3 +import lombok.AllArgsConstructor;
  4 +import lombok.Data;
  5 +import lombok.NoArgsConstructor;
  6 +import lombok.experimental.SuperBuilder;
  7 +
  8 +/**
  9 + * 巡查请求对象
  10 + *
  11 + * @Author WangXin
  12 + * @Data 2025/1/20
  13 + * @Version 1.0.0
  14 + */
  15 +@Data
  16 +@SuperBuilder
  17 +@AllArgsConstructor
  18 +@NoArgsConstructor
  19 +public class PatrolDataReq {
  20 + /**
  21 + * nbbm_sim_channel
  22 + */
  23 + private String id;
  24 + /**
  25 + * 通道名称
  26 + */
  27 + private String name;
  28 + /**
  29 + * nbbm
  30 + */
  31 + private String pid;
  32 + /**
  33 + * 在线情况 true 离线 null 在线
  34 + */
  35 + private Boolean disabled;
  36 +}
src/main/java/com/genersoft/iot/vmp/vmanager/jt1078/platform/domain/SimFlow.java 0 → 100644
  1 +package com.genersoft.iot.vmp.vmanager.jt1078.platform.domain;
  2 +
  3 +import com.fasterxml.jackson.annotation.JsonFormat;
  4 +import org.springframework.format.annotation.DateTimeFormat;
  5 +
  6 +import java.text.SimpleDateFormat;
  7 +import java.util.Date;
  8 +
  9 +/**
  10 + * 流量统计
  11 + *
  12 + * @Author WangXin
  13 + * @Data 2025/1/7
  14 + * @Version 1.0.0
  15 + */
  16 +public class SimFlow {
  17 +
  18 + private String id;
  19 + private String sim;
  20 + private String channel;
  21 + private Double flow;
  22 + private String time;
  23 +
  24 + public String getId() {
  25 + return id;
  26 + }
  27 +
  28 + public void setId(String id) {
  29 + this.id = id;
  30 + }
  31 +
  32 + public String getSim() {
  33 + return sim;
  34 + }
  35 +
  36 + public void setSim(String sim) {
  37 + this.sim = sim;
  38 + }
  39 +
  40 + public String getChannel() {
  41 + return channel;
  42 + }
  43 +
  44 + public void setChannel(String channel) {
  45 + this.channel = channel;
  46 + }
  47 +
  48 + public Double getFlow() {
  49 + return flow;
  50 + }
  51 +
  52 + public void setFlow(Double flow) {
  53 + this.flow = flow;
  54 + }
  55 +
  56 + public String getTime() {
  57 + return time;
  58 + }
  59 +
  60 + public void setTime(String time) {
  61 + this.time = time;
  62 + }
  63 +
  64 + @Override
  65 + public String toString() {
  66 + final StringBuilder sb = new StringBuilder("SimFlow{");
  67 + sb.append("id='").append(id).append('\'');
  68 + sb.append(", sim='").append(sim).append('\'');
  69 + sb.append(", channel='").append(channel).append('\'');
  70 + sb.append(", flow=").append(flow);
  71 + sb.append(", time=").append(time);
  72 + sb.append('}');
  73 + return sb.toString();
  74 + }
  75 +
  76 + public static SimFlow build(String sim, String channel, Double flow) {
  77 + SimFlow simFlow = new SimFlow();
  78 + simFlow.setSim(sim);
  79 + simFlow.setChannel(channel);
  80 + simFlow.setFlow(flow);
  81 + simFlow.setTime(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
  82 + return simFlow;
  83 + }
  84 +}
src/main/java/com/genersoft/iot/vmp/vmanager/jt1078/platform/handler/HttpClientUtil.java
@@ -86,7 +86,7 @@ public class HttpClientUtil { @@ -86,7 +86,7 @@ public class HttpClientUtil {
86 URIBuilder uriBuilder = new URIBuilder(url); 86 URIBuilder uriBuilder = new URIBuilder(url);
87 URI uri = uriBuilder.build(); 87 URI uri = uriBuilder.build();
88 88
89 - // 创建http GET请求 89 + // 创建http POST请求
90 HttpPost httpPost = new HttpPost(uri); 90 HttpPost httpPost = new HttpPost(uri);
91 StringEntity stringEntity = new StringEntity(requestBody, "UTF-8"); 91 StringEntity stringEntity = new StringEntity(requestBody, "UTF-8");
92 stringEntity.setContentType("application/json"); 92 stringEntity.setContentType("application/json");
@@ -194,7 +194,15 @@ public class HttpClientUtil { @@ -194,7 +194,15 @@ public class HttpClientUtil {
194 return false; 194 return false;
195 } 195 }
196 196
197 - 197 + /**
  198 + * 检查设备是否注册
  199 + * @param response
  200 + * @param httpclient
  201 + * @param url
  202 + * @param requestBody
  203 + * @return
  204 + * @throws IOException
  205 + */
198 @NotNull 206 @NotNull
199 private static HttpClientPostEntity combationReturnObj(CloseableHttpResponse response, DefaultHttpClient httpclient,String url,String requestBody) throws IOException { 207 private static HttpClientPostEntity combationReturnObj(CloseableHttpResponse response, DefaultHttpClient httpclient,String url,String requestBody) throws IOException {
200 HttpEntity httpEntity = response.getEntity(); 208 HttpEntity httpEntity = response.getEntity();
@@ -205,7 +213,7 @@ public class HttpClientUtil { @@ -205,7 +213,7 @@ public class HttpClientUtil {
205 HttpClientPostEntity postEntity = new HttpClientPostEntity(); 213 HttpClientPostEntity postEntity = new HttpClientPostEntity();
206 postEntity.setCookieStore(cookieStore); 214 postEntity.setCookieStore(cookieStore);
207 postEntity.setResultStr(result); 215 postEntity.setResultStr(result);
208 - log.info("url:{};requestBody:{};response data:{}",url,requestBody,result); 216 + log.info("url:{};requestBody:{};response :{}",url,requestBody,"请求成功");
209 return postEntity; 217 return postEntity;
210 } 218 }
211 219
src/main/java/com/genersoft/iot/vmp/vmanager/jt1078/platform/handler/RtspHandler.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.vmanager.jt1078.platform.handler;  
2 -  
3 -import org.springframework.beans.factory.annotation.Value;  
4 -import org.springframework.stereotype.Component;  
5 -  
6 -/**  
7 - * @author liujun  
8 - * @date 2024年10月23日 13:24  
9 - */  
10 -@Component  
11 -public class RtspHandler {  
12 -  
13 -}  
src/main/java/com/genersoft/iot/vmp/vmanager/jt1078/platform/mapper/FlowMapper.java 0 → 100644
  1 +package com.genersoft.iot.vmp.vmanager.jt1078.platform.mapper;
  2 +
  3 +import com.genersoft.iot.vmp.vmanager.jt1078.platform.domain.SimFlow;
  4 +import org.apache.ibatis.annotations.*;
  5 +import org.apache.ibatis.annotations.Param;
  6 +
  7 +import java.util.List;
  8 +
  9 +/**
  10 + * @Author WangXin
  11 + * @Data 2025/1/7
  12 + * @Version 1.0.0
  13 + */
  14 +@Mapper
  15 +public interface FlowMapper {
  16 +
  17 + @Select(value = {" <script>" +
  18 + "SELECT " +
  19 + " <if test=\"time != null and time == 'day'\" >" +
  20 + " `time`," +
  21 + " </if>" +
  22 + " <if test=\"time != null and time == 'year'\" >" +
  23 + " YEAR(`time`) `time`," +
  24 + " </if>" +
  25 + " <if test=\"time != null and time == 'month'\" >" +
  26 + " CONCAT(YEAR(`time`),'-',MONTH(`time`)) `time`," +
  27 + " </if>" +
  28 + " `sim`, `channel`, SUM(flow) flow" +
  29 + " FROM `wvp_sim_flow`" +
  30 + " <where> " +
  31 + " <if test=\"time != null and time != '' and statisticsType = 'day'\">" +
  32 + " AND time = #{time}" +
  33 + " </if>" +
  34 + " <if test=\"time != null and time != '' and statisticsType = 'month'\">" +
  35 + " AND CONCAT(YEAR(`time`),'-',MONTH(`time`)) = #{time}" +
  36 + " </if>" +
  37 + " <if test=\"time != null and time != '' and statisticsType = 'year'\">" +
  38 + " AND YEAR(`time`) = #{time}" +
  39 + " </if>" +
  40 + " </where>" +
  41 + " GROUP BY sim " +
  42 + " <if test=\"statisticsType!=null and statisticsType !='' and statisticsType = 'channel' \">" +
  43 + " ,`channel` " +
  44 + " </if>" +
  45 + " <if test=\"timeType == 'day'\">" +
  46 + " ,`time`" +
  47 + " </if>" +
  48 + " <if test=\"timeType == 'year'\" >" +
  49 + " ,YEAR(`time`)" +
  50 + " </if>" +
  51 + " <if test=\"timeType == 'month'\" >" +
  52 + " ,CONCAT(YEAR(`time`),'-',MONTH(`time`))" +
  53 + " </if>" +
  54 + " ORDER BY `time` DESC " +
  55 + " </script>"}
  56 + )
  57 + List<SimFlow> getList(@Param("timeType") String timeType, @Param("statisticsType") String statisticsType, @Param("time") String time);
  58 +
  59 + @Insert(
  60 + "INSERT INTO " +
  61 + "`wvp_sim_flow`" +
  62 + " (`id`,`sim`, `channel`, `flow`, `time`)" +
  63 + " VALUES " +
  64 + " (#{id}, #{sim}, #{channel}, #{flow}, #{time})"
  65 + )
  66 + int addFlow(SimFlow flowList);
  67 +
  68 + @Update(
  69 + "UPDATE `wvp_sim_flow` SET `flow` = `flow` + #{flow} " +
  70 + "WHERE `sim`=#{sim} " +
  71 + "AND `channel`=#{channel} " +
  72 + "AND CONCAT(YEAR(`time`),'-',MONTH(`time`),'-',DAY(`time`)) " +
  73 + "= CONCAT(YEAR(#{time}),'-',MONTH(#{time}),'-',DAY(#{time}))"
  74 + )
  75 + int updateFlow(SimFlow simFlow);
  76 +
  77 + @Select("SELECT * from `wvp_sim_flow` where `sim`=#{sim}" +
  78 + " AND `channel`=#{channel} " +
  79 + " AND CONCAT(YEAR(`time`),'-',MONTH(`time`),'-',DAY(`time`))" +
  80 + " = CONCAT(YEAR(#{time}),'-',MONTH(#{time}),'-',DAY(#{time}))")
  81 + SimFlow selectOne(SimFlow simFlow);
  82 +}
src/main/java/com/genersoft/iot/vmp/vmanager/jt1078/platform/remote/DaYiApi.java 0 → 100644
  1 +package com.genersoft.iot.vmp.vmanager.jt1078.platform.remote;
  2 +
  3 +import com.dtflys.forest.annotation.Address;
  4 +import com.genersoft.iot.vmp.vmanager.jt1078.platform.remote.cnofig.DaYiAddressSourceConfig;
  5 +
  6 +/**
  7 + * 大邑API
  8 + * @Author WangXin
  9 + * @Data 2025/1/17
  10 + * @Version 1.0.0
  11 +*/
  12 +@Address(source = DaYiAddressSourceConfig.class)
  13 +public interface DaYiApi {
  14 +}
src/main/java/com/genersoft/iot/vmp/vmanager/jt1078/platform/remote/cnofig/DaYiAddressSourceConfig.java 0 → 100644
  1 +package com.genersoft.iot.vmp.vmanager.jt1078.platform.remote.cnofig;
  2 +
  3 +import com.dtflys.forest.callback.AddressSource;
  4 +import com.dtflys.forest.http.ForestAddress;
  5 +import com.dtflys.forest.http.ForestRequest;
  6 +import org.springframework.beans.factory.annotation.Value;
  7 +import org.springframework.context.annotation.Configuration;
  8 +
  9 +import java.net.MalformedURLException;
  10 +import java.util.Map;
  11 +
  12 +import static com.genersoft.iot.vmp.vmanager.util.URLParser.parseURL;
  13 +
  14 +/**
  15 + * 大邑地址配置
  16 + */
  17 +@Configuration
  18 +public class DaYiAddressSourceConfig implements AddressSource {
  19 +
  20 + @Value("${tuohua.bsth.login.rest.baseURL}")
  21 + public String baseURL;
  22 + @Value("${tuohua.bsth.login.rest.password}")
  23 + private String restPassword;
  24 +
  25 + @Override
  26 + public ForestAddress getAddress(ForestRequest request) {
  27 + try {
  28 + Map<String, String> map = parseURL(baseURL);
  29 + return new ForestAddress(map.get("scheme"),map.get("host"),Integer.valueOf(map.get("port")),map.get("path"));
  30 + } catch (MalformedURLException e) {
  31 + throw new RuntimeException(e);
  32 + }
  33 + }
  34 +}
src/main/java/com/genersoft/iot/vmp/vmanager/jt1078/platform/service/FlowService.java 0 → 100644
  1 +package com.genersoft.iot.vmp.vmanager.jt1078.platform.service;
  2 +
  3 +import com.genersoft.iot.vmp.vmanager.jt1078.platform.domain.SimFlow;
  4 +
  5 +import java.util.List;
  6 +import java.util.Map;
  7 +
  8 +/**
  9 + * @Author WangXin
  10 + * @Data 2025/1/7
  11 + * @Version 1.0.0
  12 + */
  13 +public interface FlowService {
  14 + /**
  15 + * 流量列表
  16 + * @param timeType 时间类型
  17 + * @param statisticsType 统计类型
  18 + */
  19 + Map<String, SimFlow> getList(String timeType, String statisticsType, String time);
  20 +
  21 + /**
  22 + * 批量添加流量记录
  23 + * @param simFlow 流量记录集合
  24 + */
  25 + boolean addFlow(SimFlow simFlow);
  26 +
  27 + /**
  28 + * 修改
  29 + * @param simFlow 流量统计对象
  30 + */
  31 + boolean updateFlow(SimFlow simFlow);
  32 +
  33 + /**
  34 + * 搜索流量统计是否存在
  35 + * @param simFlow 流量统计对象
  36 + */
  37 + SimFlow selectOne(SimFlow simFlow);
  38 +}
src/main/java/com/genersoft/iot/vmp/vmanager/jt1078/platform/service/Jt1078OfService.java 0 → 100644
  1 +package com.genersoft.iot.vmp.vmanager.jt1078.platform.service;
  2 +
  3 +import com.genersoft.iot.vmp.vmanager.jt1078.platform.domain.CarTreeData;
  4 +
  5 +import java.util.List;
  6 +
  7 +/**
  8 + * Jtt1078业务层
  9 + *
  10 + * @Author WangXin
  11 + * @Data 2025/1/17
  12 + * @Version 1.0.0
  13 + */
  14 +public interface Jt1078OfService {
  15 +
  16 + /**
  17 + * 获取车辆列表数据
  18 + * @return 车辆列表数据
  19 + */
  20 + List<CarTreeData> getCarTreeData();
  21 +}
src/main/java/com/genersoft/iot/vmp/vmanager/jt1078/platform/service/impl/FlowServiceImpl.java 0 → 100644
  1 +package com.genersoft.iot.vmp.vmanager.jt1078.platform.service.impl;
  2 +
  3 +import com.genersoft.iot.vmp.vmanager.jt1078.platform.domain.SimFlow;
  4 +import com.genersoft.iot.vmp.vmanager.jt1078.platform.mapper.FlowMapper;
  5 +import com.genersoft.iot.vmp.vmanager.jt1078.platform.service.FlowService;
  6 +import org.springframework.stereotype.Service;
  7 +
  8 +import javax.annotation.Resource;
  9 +import java.util.*;
  10 +import java.util.stream.Collectors;
  11 +
  12 +/**
  13 + * @Author WangXin
  14 + * @Data 2025/1/7
  15 + * @Version 1.0.0
  16 + */
  17 +@Service
  18 +public class FlowServiceImpl implements FlowService {
  19 +
  20 + @Resource
  21 + private FlowMapper flowMapper;
  22 +
  23 + @Override
  24 + public Map<String, SimFlow> getList(String timeType, String statisticsType, String time) {
  25 + List<SimFlow> list = flowMapper.getList(timeType, statisticsType, time);
  26 +
  27 +
  28 + return null;
  29 + }
  30 +
  31 + @Override
  32 + public boolean addFlow(SimFlow flowList) {
  33 + String id = UUID.randomUUID().toString().replaceAll("-", "");
  34 + flowList.setId(id);
  35 + int i = flowMapper.addFlow(flowList);
  36 + if (i > 0) {
  37 + return true;
  38 + }
  39 + return false;
  40 + }
  41 +
  42 + @Override
  43 + public boolean updateFlow(SimFlow simFlow) {
  44 + int i = flowMapper.updateFlow(simFlow);
  45 + if (i > 0) {
  46 + return true;
  47 + }
  48 + return false;
  49 + }
  50 +
  51 + @Override
  52 + public SimFlow selectOne(SimFlow simFlow) {
  53 + return flowMapper.selectOne(simFlow);
  54 + }
  55 +
  56 +
  57 +}
src/main/java/com/genersoft/iot/vmp/vmanager/jt1078/platform/service/impl/Jt1078OfServiceImpl.java 0 → 100644
  1 +package com.genersoft.iot.vmp.vmanager.jt1078.platform.service.impl;
  2 +
  3 +import com.genersoft.iot.vmp.vmanager.jt1078.platform.config.TuohuaConfigBean;
  4 +import com.genersoft.iot.vmp.vmanager.jt1078.platform.domain.CarTreeData;
  5 +import com.genersoft.iot.vmp.vmanager.jt1078.platform.handler.HttpClientUtil;
  6 +import com.genersoft.iot.vmp.vmanager.jt1078.platform.service.Jt1078OfService;
  7 +import org.springframework.stereotype.Service;
  8 +
  9 +import javax.annotation.Resource;
  10 +import java.util.Collections;
  11 +import java.util.List;
  12 +
  13 +/**
  14 + * Jtt078实现层
  15 + *
  16 + * @Author WangXin
  17 + * @Data 2025/1/17
  18 + * @Version 1.0.0
  19 + */
  20 +@Service
  21 +public class Jt1078OfServiceImpl implements Jt1078OfService {
  22 +
  23 + @Resource
  24 + private TuohuaConfigBean tohuaConfigBean;
  25 + @Resource
  26 + private HttpClientUtil httpClientUtil;
  27 +
  28 + /**
  29 + * 获取车辆列表数据
  30 + * @return 车辆列表数据
  31 + */
  32 + @Override
  33 + public List<CarTreeData> getCarTreeData() {
  34 + try {
  35 + String lineJson = tohuaConfigBean.requestLine(httpClientUtil, String.valueOf(100));
  36 + String carJson = tohuaConfigBean.requestCars(httpClientUtil, String.valueOf(100));
  37 + } catch (Exception e) {
  38 + throw new RuntimeException(e);
  39 + }
  40 + return Collections.emptyList();
  41 + }
  42 +}
src/main/java/com/genersoft/iot/vmp/vmanager/streamProxy/StreamProxyController.java
1 package com.genersoft.iot.vmp.vmanager.streamProxy; 1 package com.genersoft.iot.vmp.vmanager.streamProxy;
2 2
3 import com.alibaba.fastjson2.JSONObject; 3 import com.alibaba.fastjson2.JSONObject;
  4 +import com.genersoft.iot.vmp.common.GeneralCallback;
4 import com.genersoft.iot.vmp.common.StreamInfo; 5 import com.genersoft.iot.vmp.common.StreamInfo;
5 import com.genersoft.iot.vmp.conf.UserSetting; 6 import com.genersoft.iot.vmp.conf.UserSetting;
6 import com.genersoft.iot.vmp.conf.exception.ControllerException; 7 import com.genersoft.iot.vmp.conf.exception.ControllerException;
@@ -104,19 +105,17 @@ public class StreamProxyController { @@ -104,19 +105,17 @@ public class StreamProxyController {
104 if (ObjectUtils.isEmpty(param.getGbId())) { 105 if (ObjectUtils.isEmpty(param.getGbId())) {
105 param.setGbId(null); 106 param.setGbId(null);
106 } 107 }
107 - StreamProxyItem streamProxyItem = streamProxyService.getStreamProxyByAppAndStream(param.getApp(), param.getStream());  
108 - if (streamProxyItem != null) {  
109 - streamProxyService.del(param.getApp(), param.getStream());  
110 - } 108 + DeferredResult<Object> result = new DeferredResult<>(userSetting.getPlayTimeout().longValue());
111 109
112 RequestMessage requestMessage = new RequestMessage(); 110 RequestMessage requestMessage = new RequestMessage();
113 String key = DeferredResultHolder.CALLBACK_CMD_PROXY + param.getApp() + param.getStream(); 111 String key = DeferredResultHolder.CALLBACK_CMD_PROXY + param.getApp() + param.getStream();
114 requestMessage.setKey(key); 112 requestMessage.setKey(key);
115 String uuid = UUID.randomUUID().toString(); 113 String uuid = UUID.randomUUID().toString();
116 requestMessage.setId(uuid); 114 requestMessage.setId(uuid);
117 - DeferredResult<Object> result = new DeferredResult<>(userSetting.getPlayTimeout().longValue()); 115 +
118 // 录像查询以channelId作为deviceId查询 116 // 录像查询以channelId作为deviceId查询
119 resultHolder.put(key, uuid, result); 117 resultHolder.put(key, uuid, result);
  118 +
120 result.onTimeout(()->{ 119 result.onTimeout(()->{
121 WVPResult<StreamInfo> wvpResult = new WVPResult<>(); 120 WVPResult<StreamInfo> wvpResult = new WVPResult<>();
122 wvpResult.setCode(ErrorCode.ERROR100.getCode()); 121 wvpResult.setCode(ErrorCode.ERROR100.getCode());
@@ -127,21 +126,22 @@ public class StreamProxyController { @@ -127,21 +126,22 @@ public class StreamProxyController {
127 126
128 streamProxyService.save(param, (code, msg, streamInfo) -> { 127 streamProxyService.save(param, (code, msg, streamInfo) -> {
129 String stream = null; 128 String stream = null;
130 - if(Objects.nonNull(streamInfo)){ 129 + if (Objects.nonNull(streamInfo)) {
131 stream = streamInfo.getStream(); 130 stream = streamInfo.getStream();
132 } 131 }
133 - logger.info("[拉流代理] {}[{}]", code == ErrorCode.SUCCESS.getCode()? "成功":"失败: " + msg,stream); 132 + logger.info("[拉流代理] {}[{}]", code == ErrorCode.SUCCESS.getCode() ? "成功" : "失败: " + msg, stream);
134 if (code == ErrorCode.SUCCESS.getCode()) { 133 if (code == ErrorCode.SUCCESS.getCode()) {
135 requestMessage.setData(new StreamContent(streamInfo)); 134 requestMessage.setData(new StreamContent(streamInfo));
136 - }else { 135 + } else {
137 requestMessage.setData(WVPResult.fail(code, msg)); 136 requestMessage.setData(WVPResult.fail(code, msg));
138 } 137 }
139 resultHolder.invokeAllResult(requestMessage); 138 resultHolder.invokeAllResult(requestMessage);
140 - if(StringUtils.equals(msg,"This stream already exists")){  
141 - redisTemplate.opsForValue().set("timeout:"+param.getStream(),2,30, TimeUnit.SECONDS);  
142 -  
143 - }else {  
144 - redisTemplate.opsForValue().set("timeout:" + param.getStream(), 1, 30, TimeUnit.SECONDS); 139 + if (StringUtils.equals(msg, "This stream already exists")) {
  140 + redisTemplate.opsForValue()
  141 + .set("timeout:" + param.getStream(), 2, 30, TimeUnit.SECONDS);
  142 + } else {
  143 + redisTemplate.opsForValue()
  144 + .set("timeout:" + param.getStream(), 1, 30, TimeUnit.SECONDS);
145 } 145 }
146 }); 146 });
147 return result; 147 return result;
src/main/java/com/genersoft/iot/vmp/vmanager/streamPush/StreamPushController.java
@@ -30,10 +30,14 @@ import org.springframework.http.HttpStatus; @@ -30,10 +30,14 @@ import org.springframework.http.HttpStatus;
30 import org.springframework.http.ResponseEntity; 30 import org.springframework.http.ResponseEntity;
31 import org.springframework.stereotype.Controller; 31 import org.springframework.stereotype.Controller;
32 import org.springframework.util.ObjectUtils; 32 import org.springframework.util.ObjectUtils;
  33 +import org.springframework.util.StringUtils;
33 import org.springframework.web.bind.annotation.*; 34 import org.springframework.web.bind.annotation.*;
34 import org.springframework.web.context.request.async.DeferredResult; 35 import org.springframework.web.context.request.async.DeferredResult;
35 import org.springframework.web.multipart.MultipartFile; 36 import org.springframework.web.multipart.MultipartFile;
36 37
  38 +import javax.annotation.Resource;
  39 +import javax.servlet.ServletException;
  40 +import javax.servlet.http.HttpServletRequest;
37 import java.io.IOException; 41 import java.io.IOException;
38 import java.io.InputStream; 42 import java.io.InputStream;
39 import java.util.HashMap; 43 import java.util.HashMap;
@@ -41,9 +45,10 @@ import java.util.List; @@ -41,9 +45,10 @@ import java.util.List;
41 import java.util.Map; 45 import java.util.Map;
42 import java.util.UUID; 46 import java.util.UUID;
43 47
  48 +import static com.genersoft.iot.vmp.conf.security.IpWhitelistFilter.verifyIpAndPath;
  49 +
44 @Tag(name = "推流信息管理") 50 @Tag(name = "推流信息管理")
45 @Controller 51 @Controller
46 -  
47 @RequestMapping(value = "/api/push") 52 @RequestMapping(value = "/api/push")
48 public class StreamPushController { 53 public class StreamPushController {
49 54
@@ -64,6 +69,9 @@ public class StreamPushController { @@ -64,6 +69,9 @@ public class StreamPushController {
64 @Autowired 69 @Autowired
65 private UserSetting userSetting; 70 private UserSetting userSetting;
66 71
  72 + @Resource
  73 + private HttpServletRequest request;
  74 +
67 @GetMapping(value = "/list") 75 @GetMapping(value = "/list")
68 @ResponseBody 76 @ResponseBody
69 @Operation(summary = "推流列表查询", security = @SecurityRequirement(name = JwtUtils.HEADER)) 77 @Operation(summary = "推流列表查询", security = @SecurityRequirement(name = JwtUtils.HEADER))
@@ -88,6 +96,18 @@ public class StreamPushController { @@ -88,6 +96,18 @@ public class StreamPushController {
88 return pushList; 96 return pushList;
89 } 97 }
90 98
  99 + @GetMapping(value = "/getStreamPushItem")
  100 + public StreamPushItem getStreamPushItem(@RequestParam(required = false)String sim, @RequestParam(required = false)String channel){
  101 + if (ObjectUtils.isEmpty(sim)) {
  102 + sim = null;
  103 + }
  104 + if (ObjectUtils.isEmpty(channel)) {
  105 + channel = null;
  106 + }
  107 + return streamPushService.getPush("schedule", sim+ "-"+ channel);
  108 + }
  109 +
  110 +
91 @PostMapping(value = "/save_to_gb") 111 @PostMapping(value = "/save_to_gb")
92 @ResponseBody 112 @ResponseBody
93 @Operation(summary = "将推流添加到国标", security = @SecurityRequirement(name = JwtUtils.HEADER)) 113 @Operation(summary = "将推流添加到国标", security = @SecurityRequirement(name = JwtUtils.HEADER))
@@ -241,9 +261,17 @@ public class StreamPushController { @@ -241,9 +261,17 @@ public class StreamPushController {
241 @RequestParam(required = false) String mediaServerId){ 261 @RequestParam(required = false) String mediaServerId){
242 boolean authority = false; 262 boolean authority = false;
243 // 是否登陆用户, 登陆用户返回完整信息 263 // 是否登陆用户, 登陆用户返回完整信息
244 - LoginUser userInfo = SecurityUtils.getUserInfo();  
245 - if (userInfo!= null) {  
246 - authority = true; 264 + try {
  265 + if (!verifyIpAndPath(request)){
  266 + LoginUser userInfo = SecurityUtils.getUserInfo();
  267 + if (userInfo!= null) {
  268 + authority = true;
  269 + }
  270 + }else {
  271 + authority = true;
  272 + }
  273 + } catch (Exception e) {
  274 + throw new RuntimeException(e);
247 } 275 }
248 StreamPushItem push = streamPushService.getPush(app, stream); 276 StreamPushItem push = streamPushService.getPush(app, stream);
249 if (push != null && !push.isSelf()) { 277 if (push != null && !push.isSelf()) {
src/main/java/com/genersoft/iot/vmp/vmanager/util/MD5Util.java 0 → 100644
  1 +package com.genersoft.iot.vmp.vmanager.util;
  2 +
  3 +import java.security.MessageDigest;
  4 +import java.security.NoSuchAlgorithmException;
  5 +
  6 +/**
  7 + * MD5工具
  8 + *
  9 + * @Author WangXin
  10 + * @Data 2025/1/6
  11 + * @Version 1.0.0
  12 + */
  13 +public class MD5Util {
  14 +
  15 + public static String encrypt(String input) {
  16 + try {
  17 + MessageDigest md = MessageDigest.getInstance("MD5");
  18 + byte[] messageDigest = md.digest(input.getBytes());
  19 + StringBuilder hexString = new StringBuilder();
  20 +
  21 + for (byte b : messageDigest) {
  22 + String hex = Integer.toHexString(0xff & b);
  23 + if (hex.length() == 1) hexString.append('0');
  24 + hexString.append(hex);
  25 + }
  26 + return hexString.toString();
  27 + } catch (NoSuchAlgorithmException e) {
  28 + throw new RuntimeException(e);
  29 + }
  30 + }
  31 +}
  32 +
src/main/java/com/genersoft/iot/vmp/vmanager/util/URLParser.java 0 → 100644
  1 +package com.genersoft.iot.vmp.vmanager.util;
  2 +
  3 +import java.net.MalformedURLException;
  4 +import java.net.URL;
  5 +import java.util.HashMap;
  6 +import java.util.Map;
  7 +
  8 +/**
  9 + * url验证工具
  10 + */
  11 +public class URLParser {
  12 +
  13 + public static void main(String[] args) {
  14 + String urlString = "http://127.0.0.1:8080/data/rest"; // 示例URL,实际使用时可以替换为任何URL字符串
  15 +
  16 + try {
  17 + Map<String, String> urlParts = parseURL(urlString);
  18 + System.out.println("URL分割结果:" + urlParts);
  19 + } catch (MalformedURLException e) {
  20 + System.out.println(e.getMessage());
  21 + }
  22 + }
  23 +
  24 + public static Map<String, String> parseURL(String urlString) throws MalformedURLException {
  25 + Map<String, String> result = new HashMap<>();
  26 +
  27 + // 尝试创建URL对象以验证格式是否正确
  28 + URL url = new URL(urlString);
  29 +
  30 + // 验证协议是否为http
  31 + if (!"http".equalsIgnoreCase(url.getProtocol())) {
  32 + throw new MalformedURLException("协议必须是http");
  33 + }
  34 +
  35 + // 确认主机名(域名或IP)存在
  36 + if (url.getHost() == null || url.getHost().isEmpty()) {
  37 + throw new MalformedURLException("必须有域名或IP地址");
  38 + }
  39 +
  40 + // 设置端口,如果未指定则默认为80
  41 + int port = url.getPort();
  42 + if (port == -1) {
  43 + port = 80; // 默认HTTP端口
  44 + }
  45 +
  46 + // 构建最终的路径,包括查询参数(如果有)
  47 + String path = url.getPath();
  48 + if (url.getQuery() != null && !url.getQuery().isEmpty()) {
  49 + path += "?" + url.getQuery();
  50 + }
  51 +
  52 + // 将分割的结果放入集合中
  53 + result.put("scheme", url.getProtocol());
  54 + result.put("hostname", url.getHost());
  55 + result.put("port", String.valueOf(port));
  56 + result.put("path", path.isEmpty() ? "/" : path); // 如果没有路径,默认为根路径
  57 +
  58 + return result;
  59 + }
  60 +}
src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiController.java
@@ -91,7 +91,6 @@ public class ApiController { @@ -91,7 +91,6 @@ public class ApiController {
91 logger.debug(String.format("模拟接口> 登录 API调用,username:%s ,password:%s ", 91 logger.debug(String.format("模拟接口> 登录 API调用,username:%s ,password:%s ",
92 username, password)); 92 username, password));
93 } 93 }
94 -  
95 JSONObject result = new JSONObject(); 94 JSONObject result = new JSONObject();
96 result.put("CookieToken","ynBDDiKMg"); 95 result.put("CookieToken","ynBDDiKMg");
97 result.put("URLToken","MOBkORkqnrnoVGcKIAHXppgfkNWRdV7utZSkDrI448Q.oxNjAxNTM4NDk3LCJwIjoiZGJjODg5NzliNzVj" + 96 result.put("URLToken","MOBkORkqnrnoVGcKIAHXppgfkNWRdV7utZSkDrI448Q.oxNjAxNTM4NDk3LCJwIjoiZGJjODg5NzliNzVj" +
src/main/resources/app-dev100.properties 0 → 100644
  1 +server.port = 9100
  2 +server.http.port = 3333
  3 +server.history.port = 9101
  4 +server.backlog = 1024
  5 +
  6 +# ffmpeg可执行文件路径,可以留空
  7 +ffmpeg.path = ffmpeg
  8 +
  9 +# 配置rtmp地址将在终端发送RTP消息包时,额外的向RTMP服务器推流
  10 +# TAG的形式就是SIM-CHANNEL,如13800138999-2
  11 +# 如果留空将不向RTMP服务器推流
  12 +#rtmp.url = rtsp://192.168.169.100:9555/schedule/{TAG}?sign={sign}
  13 +rtmp.url = rtsp://192.168.169.100:19555/schedule/{TAG}?sign={sign}
  14 +
  15 +#rtmp.url = rtsp://192.168.169.100:19555/schedule/{TAG}?sign={sign}
  16 +# 设置为on时,控制台将输出ffmpeg的输出
  17 +debug.mode = off
src/main/resources/app-dev103.properties 0 → 100644
  1 +server.port = 9100
  2 +server.http.port = 3333
  3 +server.history.port = 9101
  4 +server.backlog = 1024
  5 +
  6 +# ffmpeg可执行文件路径,可以留空
  7 +ffmpeg.path = ffmpeg
  8 +
  9 +# 配置rtmp地址将在终端发送RTP消息包时,额外的向RTMP服务器推流
  10 +# TAG的形式就是SIM-CHANNEL,如13800138999-2
  11 +# 如果留空将不向RTMP服务器推流
  12 +#rtmp.url = rtsp://192.168.169.100:9555/schedule/{TAG}?sign={sign}
  13 +rtmp.url = rtsp://10.10.2.22:9654/schedule/{TAG}?sign={sign}
  14 +
  15 +#rtmp.url = rtsp://192.168.169.100:19555/schedule/{TAG}?sign={sign}
  16 +# 设置为on时,控制台将输出ffmpeg的输出
  17 +debug.mode = off
src/main/resources/app.properties
1 -server.port = 1078 1 +server.port = 30000
2 server.http.port = 3333 2 server.http.port = 3333
  3 +server.history.port = 30001
3 server.backlog = 1024 4 server.backlog = 1024
4 5
5 -# ffmpeg可执行文件路径,可以留空  
6 -ffmpeg.path = D:/Tools/ffmpeg-4.2.2-win64-static/bin/ffmpeg.exe 6 +# ffmpeg可执行文件路径,可以留空
  7 +ffmpeg.path = F:/ffmpeg/ffmpeg-7.0.2-essentials_build/bin/ffmpeg.exe
7 8
8 -# 配置rtmp地址将在终端发送RTP消息包时,额外的向RTMP服务器推流  
9 -# TAG的形式就是SIM-CHANNEL,如13800138999-2  
10 -# 如果留空将不向RTMP服务器推流  
11 -# rtmp.url = rtmp://192.168.0.2/live/{TAG} 9 +# 配置rtmp地址将在终端发送RTP消息包时,额外的向RTMP服务器推流
  10 +# TAG的形式就是SIM-CHANNEL,如13800138999-2
  11 +# 如果留空将不向RTMP服务器推流
  12 +#rtmp.url = rtsp://192.168.169.100:9555/schedule/{TAG}?sign={sign}
  13 +rtmp.url = rtsp://127.0.0.1:554/schedule/{TAG}?sign={sign}
12 14
13 -# 设置为on时,控制台将输出ffmpeg的输出  
14 -debug.mode = off  
15 \ No newline at end of file 15 \ No newline at end of file
  16 +#rtmp.url = rtsp://192.168.169.100:19555/schedule/{TAG}?sign={sign}
  17 +# 设置为on时,控制台将输出ffmpeg的输出
  18 +debug.mode = off
src/main/resources/application-dev100.yml
@@ -16,11 +16,11 @@ spring: @@ -16,11 +16,11 @@ spring:
16 # [必须修改] Redis服务器IP, REDIS安装在本机的,使用127.0.0.1 16 # [必须修改] Redis服务器IP, REDIS安装在本机的,使用127.0.0.1
17 host: 192.168.169.100 17 host: 192.168.169.100
18 # [必须修改] 端口号 18 # [必须修改] 端口号
19 - port: 6379 19 + port: 6879
20 # [可选] 数据库 DB 20 # [可选] 数据库 DB
21 database: 7 21 database: 7
22 # [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接 22 # [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接
23 -# password: luna 23 + password: wvp4@444
24 # [可选] 超时时间 24 # [可选] 超时时间
25 timeout: 10000 25 timeout: 10000
26 # mysql数据源 26 # mysql数据源
@@ -31,7 +31,7 @@ spring: @@ -31,7 +31,7 @@ spring:
31 master: 31 master:
32 type: com.zaxxer.hikari.HikariDataSource 32 type: com.zaxxer.hikari.HikariDataSource
33 driver-class-name: com.mysql.cj.jdbc.Driver 33 driver-class-name: com.mysql.cj.jdbc.Driver
34 - url: jdbc:mysql://192.168.169.100:3306/latest_wvp2?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&serverTimezone=PRC&useSSL=false&allowMultiQueries=true 34 + url: jdbc:mysql://192.168.169.100:3306/wvp4?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&allowPublicKeyRetrieval=TRUE&serverTimezone=PRC&useSSL=false&allowMultiQueries=true
35 username: root 35 username: root
36 password: guzijian 36 password: guzijian
37 hikari: 37 hikari:
@@ -43,7 +43,7 @@ spring: @@ -43,7 +43,7 @@ spring:
43 max-lifetime: 1200000 # 是池中连接关闭后的最长生命周期(以毫秒为单位) 43 max-lifetime: 1200000 # 是池中连接关闭后的最长生命周期(以毫秒为单位)
44 #[可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口 44 #[可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口
45 server: 45 server:
46 - port: 18089 46 + port: 18989
47 # [可选] HTTPS配置, 默认不开启 47 # [可选] HTTPS配置, 默认不开启
48 ssl: 48 ssl:
49 # [可选] 是否开启HTTPS访问 49 # [可选] 是否开启HTTPS访问
@@ -63,7 +63,7 @@ sip: @@ -63,7 +63,7 @@ sip:
63 # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。 63 # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。
64 ip: 192.168.169.100 64 ip: 192.168.169.100
65 # [可选] 28181服务监听的端口 65 # [可选] 28181服务监听的端口
66 - port: 6060 66 + port: 28083
67 # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) 67 # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007)
68 # 后两位为行业编码,定义参照附录D.3 68 # 后两位为行业编码,定义参照附录D.3
69 # 3701020049标识山东济南历下区 信息行业接入 69 # 3701020049标识山东济南历下区 信息行业接入
@@ -78,11 +78,11 @@ sip: @@ -78,11 +78,11 @@ sip:
78 78
79 #zlm 默认服务器配置 79 #zlm 默认服务器配置
80 media: 80 media:
81 - id: guzijian 81 + id: guzijian1
82 # [必须修改] zlm服务器的内网IP 82 # [必须修改] zlm服务器的内网IP
83 ip: 192.168.169.100 83 ip: 192.168.169.100
84 # [必须修改] zlm服务器的http.port 84 # [必须修改] zlm服务器的http.port
85 - http-port: 1090 85 + http-port: 1909
86 # [可选] 返回流地址时的ip,置空使用 media.ip 1 86 # [可选] 返回流地址时的ip,置空使用 media.ip 1
87 stream-ip: 61.169.120.202 87 stream-ip: 61.169.120.202
88 # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip 1 88 # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip 1
@@ -90,17 +90,18 @@ media: @@ -90,17 +90,18 @@ media:
90 # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip 90 # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip
91 hook-ip: 192.168.169.100 91 hook-ip: 192.168.169.100
92 # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置 92 # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置
93 - http-ssl-port: 8443 93 + http-ssl-port: 2939
94 # [可选] zlm服务器的hook.admin_params=secret 94 # [可选] zlm服务器的hook.admin_params=secret
95 - secret: RPorcBlIw26uHGnEHYGesIYyFDXpgjkP 95 + secret: 8KMYsD5ItKkHN1CIcPI9VeLa6u4S8deU
  96 + pushKey: 41db35390ddad33f83944f44b8b75ded
96 # 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试 97 # 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试
97 rtp: 98 rtp:
98 # [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输 99 # [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输
99 enable: true 100 enable: true
100 # [可选] 在此范围内选择端口用于媒体流传输, 必须提前在zlm上配置该属性,不然自动配置此属性可能不成功 101 # [可选] 在此范围内选择端口用于媒体流传输, 必须提前在zlm上配置该属性,不然自动配置此属性可能不成功
101 - port-range: 50000,50500 # 端口范围 102 + port-range: 52000,52500 # 端口范围
102 # [可选] 国标级联在此范围内选择端口发送媒体流, 103 # [可选] 国标级联在此范围内选择端口发送媒体流,
103 - send-port-range: 50000,50500 # 端口范围 104 + send-port-range: 52000,52500 # 端口范围
104 # 录像辅助服务, 部署此服务可以实现zlm录像的管理与下载, 0 表示不使用 105 # 录像辅助服务, 部署此服务可以实现zlm录像的管理与下载, 0 表示不使用
105 record-assist-port: 18081 106 record-assist-port: 18081
106 # [根据业务需求配置] 107 # [根据业务需求配置]
@@ -112,7 +113,49 @@ user-settings: @@ -112,7 +113,49 @@ user-settings:
112 # 设备/通道状态变化时发送消息 113 # 设备/通道状态变化时发送消息
113 device-status-notify: true 114 device-status-notify: true
114 # [可选] 日志配置, 一般不需要改 115 # [可选] 日志配置, 一般不需要改
115 - 116 +jt1078:
  117 + enable: true
  118 + port: 1079
116 logging: 119 logging:
117 config: classpath:logback-spring.xml 120 config: classpath:logback-spring.xml
  121 +tuohua:
  122 + bsth:
  123 + login:
  124 + pageURL: http://192.168.168.152:9088/user/login/jCryptionKey
  125 + url: http://192.168.168.152:9088/user/login
  126 + userName: yuanxiaohu
  127 + password: Yxiaohu1.0
  128 + rest:
  129 + baseURL: http://192.168.168.152:9089/webservice/rest
  130 + password: bafb2b44a07a02e5e9912f42cd197423884116a8
  131 + tree:
  132 + url:
  133 + company: http://192.168.168.152:9088/video/tree
  134 + car: http://192.168.168.152:9088/video/tree/carNo/{0}
  135 + sim: http://192.168.168.152:9088/video//tree/caNO/sim/{0}
  136 + wvp28181:
  137 + rtsp:
  138 + tcpPort: 1078
  139 + udpPort: 1078
  140 + historyTcpPort: 9999
  141 + historyUdpPort: 9999
  142 + ip : 61.169.120.202
  143 + jt1078:
  144 + ports: 9101,9600
  145 + port: 9100
  146 + httpPort: 3333
  147 + addPortVal: 0
  148 + pushURL: http://127.0.0.1:3333/new/server/{pushKey}/{port}/{httpPort}
  149 + stopPushURL: http://127.0.0.1:3333/stop/channel/{pushKey}/{port}/{httpPort}
  150 + url: http://192.168.168.152:8100/device/{0}
  151 + historyListPort: 9205
  152 + playHistoryPort: 9201
  153 + sendPort: 9101
  154 + stopSendPort: 9102
  155 + ws: ws://61.169.120.202:1909/schedule/{stream}.live.flv
  156 + wss: wss://61.169.120.202:2930/schedule/{stream}.live.flv
  157 + downloadFLV: http://118.113.164.50:1909/schedule/{stream}.live.flv
  158 + get:
  159 + url: http://192.168.169.100:3333/video/{stream}.flv
  160 + playURL: /play/wasm/ws%3A%2F%2F{ip}%3A{port}%2Fschedule%2F{sim}-{channel}.live.flv%3FcallId%{publickey}
118 161
src/main/resources/application-local.yml
@@ -15,11 +15,11 @@ spring: @@ -15,11 +15,11 @@ spring:
15 # [必须修改] Redis服务器IP, REDIS安装在本机的,使用127.0.0.1 15 # [必须修改] Redis服务器IP, REDIS安装在本机的,使用127.0.0.1
16 host: 127.0.0.1 16 host: 127.0.0.1
17 # [必须修改] 端口号 17 # [必须修改] 端口号
18 - port: 6379 18 + port: 6879
19 # [可选] 数据库 DB 19 # [可选] 数据库 DB
20 database: 8 20 database: 8
21 # [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接 21 # [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接
22 - # password: guzijian 22 + password: wvp4@444
23 # [可选] 超时时间 23 # [可选] 超时时间
24 timeout: 10000 24 timeout: 10000
25 # mysql数据源 25 # mysql数据源
@@ -30,7 +30,7 @@ spring: @@ -30,7 +30,7 @@ spring:
30 master: 30 master:
31 type: com.zaxxer.hikari.HikariDataSource 31 type: com.zaxxer.hikari.HikariDataSource
32 driver-class-name: com.mysql.cj.jdbc.Driver 32 driver-class-name: com.mysql.cj.jdbc.Driver
33 - url: jdbc:mysql://192.168.169.100:3306/wvp2?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&serverTimezone=PRC&useSSL=false&allowMultiQueries=true 33 + url: jdbc:mysql://192.168.169.100:3306/wvp4?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&serverTimezone=PRC&useSSL=false&allowMultiQueries=true
34 username: root 34 username: root
35 password: guzijian 35 password: guzijian
36 hikari: 36 hikari:
@@ -42,7 +42,7 @@ spring: @@ -42,7 +42,7 @@ spring:
42 max-lifetime: 1200000 # 是池中连接关闭后的最长生命周期(以毫秒为单位) 42 max-lifetime: 1200000 # 是池中连接关闭后的最长生命周期(以毫秒为单位)
43 #[可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口 43 #[可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口
44 server: 44 server:
45 - port: 28080 45 + port: 16030
46 # [可选] HTTPS配置, 默认不开启 46 # [可选] HTTPS配置, 默认不开启
47 ssl: 47 ssl:
48 # [可选] 是否开启HTTPS访问 48 # [可选] 是否开启HTTPS访问
@@ -60,9 +60,9 @@ sip: @@ -60,9 +60,9 @@ sip:
60 # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4 60 # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4
61 # 如果不明白,就使用0.0.0.0,大部分情况都是可以的 61 # 如果不明白,就使用0.0.0.0,大部分情况都是可以的
62 # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。 62 # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。
63 - ip: 0.0.0.0 63 + ip: 192.168.169.100
64 # [可选] 28181服务监听的端口 64 # [可选] 28181服务监听的端口
65 - port: 5060 65 + port: 16030
66 66
67 # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) 67 # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007)
68 # 后两位为行业编码,定义参照附录D.3 68 # 后两位为行业编码,定义参照附录D.3
@@ -82,7 +82,7 @@ media: @@ -82,7 +82,7 @@ media:
82 # [必须修改] zlm服务器的内网IP 82 # [必须修改] zlm服务器的内网IP
83 ip: 192.168.169.100 83 ip: 192.168.169.100
84 # [必须修改] zlm服务器的http.port 84 # [必须修改] zlm服务器的http.port
85 - http-port: 1091 85 + http-port: 1909
86 # [可选] 返回流地址时的ip,置空使用 media.ip 86 # [可选] 返回流地址时的ip,置空使用 media.ip
87 stream-ip: 192.168.169.100 87 stream-ip: 192.168.169.100
88 # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip 88 # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip
@@ -90,17 +90,17 @@ media: @@ -90,17 +90,17 @@ media:
90 # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip 90 # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip
91 hook-ip: 192.168.169.100 91 hook-ip: 192.168.169.100
92 # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置 92 # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置
93 - http-ssl-port: 443 93 + http-ssl-port: 8444
94 # [可选] zlm服务器的hook.admin_params=secret 94 # [可选] zlm服务器的hook.admin_params=secret
95 - secret: RPorcBlIw26uHGnEHYGesIYyFDXpgjkP1 95 + secret: 8KMYsD5ItKkHN1CIcPI9VeLa6u4S8deU
96 # 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试 96 # 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试
97 rtp: 97 rtp:
98 # [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输 98 # [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输
99 enable: true 99 enable: true
100 # [可选] 在此范围内选择端口用于媒体流传输, 必须提前在zlm上配置该属性,不然自动配置此属性可能不成功 100 # [可选] 在此范围内选择端口用于媒体流传输, 必须提前在zlm上配置该属性,不然自动配置此属性可能不成功
101 - port-range: 60000,60300 # 端口范围 101 + port-range: 52000,52500 # 端口范围
102 # [可选] 国标级联在此范围内选择端口发送媒体流, 102 # [可选] 国标级联在此范围内选择端口发送媒体流,
103 - send-port-range: 60000,60300 # 端口范围 103 + send-port-range: 52000,52500 # 端口范围
104 # 录像辅助服务, 部署此服务可以实现zlm录像的管理与下载, 0 表示不使用 104 # 录像辅助服务, 部署此服务可以实现zlm录像的管理与下载, 0 表示不使用
105 record-assist-port: 18081 105 record-assist-port: 18081
106 # [根据业务需求配置] 106 # [根据业务需求配置]
@@ -154,19 +154,19 @@ tuohua: @@ -154,19 +154,19 @@ tuohua:
154 jt1078: 154 jt1078:
155 ports: 9000,9500 155 ports: 9000,9500
156 addPortVal: 30000 156 addPortVal: 30000
157 - pushURL: http://192.169.1.92:3333/new/server/{pushKey}/{port}/{httpPort}  
158 - stopPushURL: http://192.169.1.92:3333/stop/channel/{pushKey}/{port}/{httpPort} 157 + pushURL: http://192.168.169.100:3333/new/server/{pushKey}/{port}/{httpPort}
  158 + stopPushURL: http://192.168.169.100:3333/stop/channel/{pushKey}/{port}/{httpPort}
159 url: http://192.168.168.241:8100/device/{0} 159 url: http://192.168.168.241:8100/device/{0}
160 historyListPort: 9205 160 historyListPort: 9205
161 playHistoryPort: 9201 161 playHistoryPort: 9201
162 sendPort: 9101 162 sendPort: 9101
163 stopSendPort: 9102 163 stopSendPort: 9102
164 - ws: ws://192.168.169.100:1091/schedule/{stream}.live.flv  
165 - wss: wss://192.168.169.100:443/schedule/{stream}.live.flv  
166 - downloadFLV: http://192.168.169.100:1091/schedule/{stream}.live.flv 164 + ws: ws://192.168.169.100:1909/schedule/{stream}.live.flv
  165 + wss: wss://192.168.169.100:8444/schedule/{stream}.live.flv
  166 + downloadFLV: http://192.168.169.100:1909/schedule/{stream}.live.flv
167 get: 167 get:
168 #url: http://192.169.1.92:{port}/video/{stream}.flv 168 #url: http://192.169.1.92:{port}/video/{stream}.flv
169 - url: http://192.169.1.92:3333/video/{stream} 169 + url: http://192.168.169.100:3333/video/{stream}
170 playURL: /play/wasm/ws%3A%2F%2F{ip}%3A{port}%2Fschedule%2F{sim}-{channel}.live.flv%3FcallId%{publickey} 170 playURL: /play/wasm/ws%3A%2F%2F{ip}%3A{port}%2Fschedule%2F{sim}-{channel}.live.flv%3FcallId%{publickey}
171 171
172 172
src/main/resources/application-localDev.yml
@@ -134,7 +134,7 @@ tuohua: @@ -134,7 +134,7 @@ tuohua:
134 userName: yuanxiaohu 134 userName: yuanxiaohu
135 password: Yxiaohu1.0 135 password: Yxiaohu1.0
136 rest: 136 rest:
137 - baseURL: http://10.10.2.20:9089/webservice/rest 137 + baseURL: http://192.168.168.152:9089/webservice/rest
138 password: bafb2b44a07a02e5e9912f42cd197423884116a8 138 password: bafb2b44a07a02e5e9912f42cd197423884116a8
139 tree: 139 tree:
140 url: 140 url:
src/main/resources/application.yml
@@ -2,6 +2,9 @@ spring: @@ -2,6 +2,9 @@ spring:
2 application: 2 application:
3 name: wvp 3 name: wvp
4 profiles: 4 profiles:
5 - active: local 5 + active: wx-local
6 server: 6 server:
7 - port: 18080  
8 \ No newline at end of file 7 \ No newline at end of file
  8 + port: 16030
  9 +
  10 +test:
  11 + port: 30020