Commit 5077713ed944a02a971c941bb1827fa45de454b0

Authored by 王鑫
1 parent d76da120

修改

Showing 150 changed files with 3703 additions and 5457 deletions
... ... @@ -104,7 +104,16 @@
104 104 <artifactId>netty-all</artifactId>
105 105 <version>4.1.42.Final</version>
106 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 117 <dependency>
109 118 <groupId>de.sciss</groupId>
110 119 <artifactId>jump3r</artifactId>
... ... @@ -402,43 +411,43 @@
402 411 </configuration>
403 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 451 </plugins>
443 452 <resources>
444 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 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 5 import com.genersoft.iot.vmp.utils.GitUtil;
4 6 import com.genersoft.iot.vmp.utils.SpringBeanFactory;
5 7 import org.slf4j.Logger;
... ... @@ -9,7 +11,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
9 11 import org.springframework.boot.builder.SpringApplicationBuilder;
10 12 import org.springframework.boot.web.servlet.ServletComponentScan;
11 13 import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
12   -import org.springframework.context.ConfigurableApplicationContext;
  14 +import org.springframework.context.ApplicationContext;
13 15 import org.springframework.scheduling.annotation.EnableScheduling;
14 16  
15 17 import javax.servlet.ServletContext;
... ... @@ -25,25 +27,27 @@ import java.util.Objects;
25 27 @ServletComponentScan("com.genersoft.iot.vmp.conf")
26 28 @SpringBootApplication
27 29 @EnableScheduling
  30 +@ForestScan(basePackages = "com.genersoft.iot.vmp.vmanager.jt1078.platform.remote")
28 31 public class VManageBootstrap extends SpringBootServletInitializer {
29 32  
30 33 private final static Logger logger = LoggerFactory.getLogger(VManageBootstrap.class);
31 34  
32 35 private static String[] args;
33   - private static ConfigurableApplicationContext context;
  36 + private static ApplicationContext context;
34 37 public static void main(String[] args) {
35 38 VManageBootstrap.args = args;
36 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 47 logger.info("构建版本: {}", gitUtil1.getBuildVersion());
39 48 logger.info("构建时间: {}", gitUtil1.getBuildDate());
40 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 52 @Override
49 53 protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
... ...
src/main/java/com/genersoft/iot/vmp/conf/ApiAccessFilter.java
1 1 package com.genersoft.iot.vmp.conf;
2 2  
3 3 import com.genersoft.iot.vmp.common.ApiSaveConstant;
  4 +import com.genersoft.iot.vmp.conf.security.IpWhitelistFilter;
4 5 import com.genersoft.iot.vmp.conf.security.SecurityUtils;
  6 +import com.genersoft.iot.vmp.conf.security.WebSecurityConfig;
5 7 import com.genersoft.iot.vmp.service.ILogService;
6 8 import com.genersoft.iot.vmp.storager.dao.dto.LogDto;
7 9 import com.genersoft.iot.vmp.utils.DateUtil;
... ... @@ -21,6 +23,8 @@ import javax.servlet.http.HttpServletRequest;
21 23 import javax.servlet.http.HttpServletResponse;
22 24 import java.io.IOException;
23 25  
  26 +import static com.genersoft.iot.vmp.conf.security.IpWhitelistFilter.verifyIpAndPath;
  27 +
24 28 /**
25 29 * @author lin
26 30 */
... ... @@ -40,6 +44,10 @@ public class ApiAccessFilter extends OncePerRequestFilter {
40 44  
41 45 @Override
42 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 51 String username = null;
44 52 if (SecurityUtils.getUserInfo() == null) {
45 53 username = servletRequest.getParameter("username");
... ... @@ -66,8 +74,6 @@ public class ApiAccessFilter extends OncePerRequestFilter {
66 74 logDto.setUri(servletRequest.getRequestURI());
67 75 logDto.setCreateTime(DateUtil.getNow());
68 76 logService.add(logDto);
69   -
70   -
71 77 }
72 78 }
73 79  
... ...
src/main/java/com/genersoft/iot/vmp/conf/DynamicTask.java
1 1 package com.genersoft.iot.vmp.conf;
2 2  
  3 +import org.apache.commons.collections4.CollectionUtils;
3 4 import org.apache.commons.lang3.ObjectUtils;
  5 +import org.ehcache.core.util.CollectionUtil;
4 6 import org.slf4j.Logger;
5 7 import org.slf4j.LoggerFactory;
  8 +import org.springframework.data.redis.cache.RedisCache;
  9 +import org.springframework.data.redis.core.RedisTemplate;
6 10 import org.springframework.scheduling.annotation.Scheduled;
7 11 import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
8 12 import org.springframework.stereotype.Component;
9 13  
10 14 import javax.annotation.PostConstruct;
  15 +import javax.annotation.Resource;
11 16 import java.time.Instant;
12 17 import java.util.Date;
13 18 import java.util.Map;
... ... @@ -18,6 +23,7 @@ import java.util.concurrent.TimeUnit;
18 23  
19 24 /**
20 25 * 动态定时任务
  26 + *
21 27 * @author lin
22 28 */
23 29 @Component
... ... @@ -30,6 +36,9 @@ public class DynamicTask {
30 36 private final Map<String, ScheduledFuture<?>> futureMap = new ConcurrentHashMap<>();
31 37 private final Map<String, Runnable> runnableMap = new ConcurrentHashMap<>();
32 38  
  39 + @Resource
  40 + private RedisTemplate<String, String> redisTemplate;
  41 +
33 42 @PostConstruct
34 43 public void DynamicTask() {
35 44 threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
... ... @@ -37,17 +46,23 @@ public class DynamicTask {
37 46 threadPoolTaskScheduler.setWaitForTasksToCompleteOnShutdown(true);
38 47 threadPoolTaskScheduler.setAwaitTerminationSeconds(10);
39 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 61 * @param cycleForCatalog 间隔 毫秒
47 62 * @return
48 63 */
49 64 public void startCron(String key, Runnable task, int cycleForCatalog) {
50   - if(ObjectUtils.isEmpty(key)) {
  65 + if (ObjectUtils.isEmpty(key)) {
51 66 return;
52 67 }
53 68 ScheduledFuture<?> future = futureMap.get(key);
... ... @@ -62,24 +77,25 @@ public class DynamicTask {
62 77 // scheduleWithFixedDelay 必须等待上一个任务结束才开始计时period, cycleForCatalog表示执行的间隔
63 78  
64 79 future = threadPoolTaskScheduler.scheduleAtFixedRate(task, new Date(System.currentTimeMillis() + cycleForCatalog), cycleForCatalog);
65   - if (future != null){
  80 + if (future != null) {
66 81 futureMap.put(key, future);
67 82 runnableMap.put(key, task);
68 83 logger.debug("任务【{}】启动成功!!!", key);
69   - }else {
  84 + } else {
70 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 94 * @param delay 延时 /毫秒
79 95 * @return
80 96 */
81 97 public void startDelay(String key, Runnable task, int delay) {
82   - if(ObjectUtils.isEmpty(key)) {
  98 + if (ObjectUtils.isEmpty(key)) {
83 99 return;
84 100 }
85 101 stop(key);
... ... @@ -98,17 +114,17 @@ public class DynamicTask {
98 114 }
99 115 // scheduleWithFixedDelay 必须等待上一个任务结束才开始计时period, cycleForCatalog表示执行的间隔
100 116 future = threadPoolTaskScheduler.schedule(task, startInstant);
101   - if (future != null){
  117 + if (future != null) {
102 118 futureMap.put(key, future);
103 119 runnableMap.put(key, task);
104 120 logger.debug("任务【{}】启动成功!!!", key);
105   - }else {
  121 + } else {
106 122 logger.debug("任务【{}】启动失败!!!", key);
107 123 }
108 124 }
109 125  
110 126 public boolean stop(String key) {
111   - if(ObjectUtils.isEmpty(key)) {
  127 + if (ObjectUtils.isEmpty(key)) {
112 128 return false;
113 129 }
114 130 boolean result = false;
... ... @@ -121,7 +137,7 @@ public class DynamicTask {
121 137 }
122 138  
123 139 public boolean contains(String key) {
124   - if(ObjectUtils.isEmpty(key)) {
  140 + if (ObjectUtils.isEmpty(key)) {
125 141 return false;
126 142 }
127 143 return futureMap.get(key) != null;
... ... @@ -132,7 +148,7 @@ public class DynamicTask {
132 148 }
133 149  
134 150 public Runnable get(String key) {
135   - if(ObjectUtils.isEmpty(key)) {
  151 + if (ObjectUtils.isEmpty(key)) {
136 152 return null;
137 153 }
138 154 return runnableMap.get(key);
... ... @@ -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 162 if (futureMap.size() > 0) {
147 163 for (String key : futureMap.keySet()) {
148 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 34  
35 35 private static final String keyId = "3e79646c4dbc408383a9eed09f2b85ae";
36 36  
  37 + public static final String token = "interior-api-eyJhbGciOiJSUzI1NiIsImtpZCI6IjNlNzk2NDZjNGRiYzQwODM4M2E5ZWVkMDlmMmI4NWFlIn0.eyJqdGkiOiJHUThFUFhtdGtJd01yVTNES3F3bnN3IiwiaWF0IjoxNzM2ODM2Mjk";
  38 +
37 39 /**
38 40 * token过期时间(分钟)
39 41 */
... ...
src/main/java/com/genersoft/iot/vmp/conf/security/SecurityUtils.java
... ... @@ -54,7 +54,6 @@ public class SecurityUtils {
54 54 if(authentication!=null){
55 55 Object principal = authentication.getPrincipal();
56 56 if(principal!=null && !"anonymousUser".equals(principal.toString())){
57   -
58 57 User user = (User) principal;
59 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 18 import org.springframework.security.config.http.SessionCreationPolicy;
19 19 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
20 20 import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
  21 +import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
21 22 import org.springframework.web.cors.CorsConfiguration;
22 23 import org.springframework.web.cors.CorsConfigurationSource;
23 24 import org.springframework.web.cors.CorsUtils;
... ... @@ -26,6 +27,7 @@ import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
26 27 import java.util.ArrayList;
27 28 import java.util.Arrays;
28 29 import java.util.Collections;
  30 +import java.util.List;
29 31  
30 32 /**
31 33 * 配置Spring Security
... ... @@ -58,6 +60,8 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
58 60 @Autowired
59 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 67 * 描述: 静态资源放行,这里的放行,是不走 Spring Security 过滤器链
... ... @@ -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 118 .and().csrf().disable()
114 119 .sessionManagement()
115 120 .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
116   -
117   - // 配置拦截规则
118 121 .and()
  122 + // 配置拦截规则
119 123 .authorizeRequests()
120 124 .requestMatchers(CorsUtils::isPreFlightRequest).permitAll()
121 125 .antMatchers(userSetting.getInterfaceAuthenticationExcludes().toArray(new String[0])).permitAll()
122 126 .antMatchers("/api/user/login", "/index/hook/**", "/swagger-ui/**", "/doc.html").permitAll()
123 127 .anyRequest().authenticated()
124   - // 异常处理器
125 128 .and()
  129 + .addFilterBefore(new IpWhitelistFilter(), BasicAuthenticationFilter.class)
  130 + // 异常处理器
126 131 .exceptionHandling()
127 132 .authenticationEntryPoint(anonymousAuthenticationEntryPoint)
128 133 .and().logout().logoutUrl("/api/user/logout").permitAll()
129   - .logoutSuccessHandler(logoutHandler)
130   - ;
  134 + .logoutSuccessHandler(logoutHandler);
131 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 37 private final Map<String, SipProviderImpl> tcpSipProviderMap = new ConcurrentHashMap<>();
38 38 private final Map<String, SipProviderImpl> udpSipProviderMap = new ConcurrentHashMap<>();
39 39  
  40 + /**
  41 + * 获取监听的IP
  42 + * @param args
  43 + */
40 44 @Override
41 45 public void run(String... args) {
42 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 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 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 6 import java.io.ByteArrayInputStream;
8 7 import java.io.ByteArrayOutputStream;
9 8 import java.io.FileInputStream;
10 9 import java.io.FileOutputStream;
11   -import java.util.Arrays;
12 10  
13 11 /**
14 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 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 6 * 核心转换,PCM转G711
... ... @@ -154,4 +155,4 @@ public class G711Codec extends AudioCodec
154 155 public byte[] fromPCM(byte[] data) {
155 156 return encode(data);
156 157 }
157   -}
158 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 5 import java.io.ByteArrayOutputStream;
6 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 5 import java.io.FileInputStream;
7 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 3 import de.sciss.jump3r.lowlevel.LameEncoder;
4 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 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 8 /** Common routines for G.721 and G.723 conversions.
9 9 * <p>
... ... @@ -15,7 +15,7 @@ import com.genersoft.iot.vmp.jt1078.codec.G711UCodec;
15 15 * ANSI-C source code to the public domain.
16 16 */
17 17 public abstract class G726 {
18   -
  18 +
19 19 // ##### C-to-Java conversion: #####
20 20 // short becomes int
21 21 // char becomes int
... ... @@ -26,10 +26,10 @@ public abstract class G726 {
26 26  
27 27 /** ISDN u-law */
28 28 public static final int AUDIO_ENCODING_ULAW=1;
29   -
  29 +
30 30 /** ISDN A-law */
31 31 public static final int AUDIO_ENCODING_ALAW=2;
32   -
  32 +
33 33 /** PCM 2's-complement (0-center) */
34 34 public static final int AUDIO_ENCODING_LINEAR=3;
35 35  
... ... @@ -44,7 +44,7 @@ public abstract class G726 {
44 44 * <p>
45 45 * Using linear search for simple coding. */
46 46 private static int quan(int val, /*short*/int[] table, int size) {
47   -
  47 +
48 48 int i;
49 49 for (i=0; i<size; i++) if (val<table[i]) break;
50 50 return i;
... ... @@ -63,24 +63,24 @@ public abstract class G726 {
63 63 * @param size - Table size of short integers
64 64 */
65 65 protected static int quantize(int d, int y, /*short*/int[] table, int size) {
66   -
  66 +
67 67 /* LOG
68 68 * Compute base 2 log of 'd', and store in 'dl'.
69 69 */
70 70 /*short*/int dqm=Math.abs(d); /* Magnitude of 'd' */
71   -
  71 +
72 72 /*short*/int exp=quan(dqm>>1, power2, 15); /* Integer part of base 2 log of 'd' */
73   -
  73 +
74 74 /*short*/int mant=((dqm<<7)>>exp)&0x7F; /* Fractional part of base 2 log */
75   -
  75 +
76 76 /*short*/int dl=(exp<<7)+mant; /* Log of magnitude of 'd' */
77   -
  77 +
78 78 /* SUBTB
79 79 * "Divide" by step size multiplier.
80 80 */
81 81 /* Step size scale factor normalized log */
82 82 /*short*/int dln=dl-(y>>2);
83   -
  83 +
84 84 /* QUAN
85 85 * Obtain codword i for 'd'.
86 86 */
... ... @@ -102,10 +102,10 @@ public abstract class G726 {
102 102 * @param y - Step size multiplier
103 103 */
104 104 protected static int reconstruct(int sign, int dqln, int y) {
105   -
  105 +
106 106 /* Log of 'dq' magnitude */
107 107 /*short*/int dql=dqln+(y>>2); /* ADDA */
108   -
  108 +
109 109 if (dql<0) {
110 110 return ((sign!=0)? -0x8000 : 0);
111 111 }
... ... @@ -119,8 +119,8 @@ public abstract class G726 {
119 119 return ((sign!=0)? (dq-0x8000) : dq);
120 120 }
121 121 }
122   -
123   -
  122 +
  123 +
124 124 /** updates the state variables for each output code
125 125 * @param code_size - distinguish 723_40 with others
126 126 * @param y - quantizer step size
... ... @@ -132,7 +132,7 @@ public abstract class G726 {
132 132 * @param state - coder state
133 133 */
134 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 136 int cnt;
137 137 /*short*/int mag, exp, mant; /* Adaptive predictor, FLOAT A */
138 138 /*short*/int a2p; /* LIMC */
... ... @@ -144,13 +144,13 @@ public abstract class G726 {
144 144 /*short*/int ylint, thr2, dqthr;
145 145 /*short*/int ylfrac, thr1;
146 146 /*short*/int pk0;
147   -
  147 +
148 148 // ##### C-to-Java conversion: #####
149 149 // init a2p
150   - a2p=0;
151   -
  150 + a2p=0;
  151 +
152 152 pk0=(dqsez<0)? 1 : 0; /* needed in updating predictor poles */
153   -
  153 +
154 154 mag=dq&0x7FFF; /* prediction difference magnitude */
155 155 /* TRANS */
156 156 ylint=state.yl>>15; /* exponent part of yl */
... ... @@ -165,24 +165,24 @@ public abstract class G726 {
165 165 tr=0; /* treated as voice */
166 166 else /* signal is data (modem) */
167 167 tr=1;
168   -
  168 +
169 169 /* Quantizer scale factor adaptation. */
170   -
  170 +
171 171 /* FUNCTW&FILTD&DELAY */
172 172 /* update non-steady state step size multiplier */
173 173 state.yu=y+((wi-y)>>5);
174   -
  174 +
175 175 /* LIMB */
176 176 if (state.yu<544) /* 544<=yu<=5120 */
177 177 state.yu=544;
178 178 else
179 179 if (state.yu>5120)
180 180 state.yu=5120;
181   -
  181 +
182 182 /* FILTE&DELAY */
183 183 /* update steady state step size multiplier */
184 184 state.yl+=state.yu+((-state.yl)>>6);
185   -
  185 +
186 186 /*
187 187 * Adaptive predictor coefficients.
188 188 */
... ... @@ -200,7 +200,7 @@ public abstract class G726 {
200 200 else {
201 201 /* update a's and b's */
202 202 pks1=pk0^state.pk[0]; /* UPA2 */
203   -
  203 +
204 204 /* update predictor pole a[1] */
205 205 a2p=state.a[1]-(state.a[1]>>7);
206 206 if (dqsez != 0) {
... ... @@ -212,7 +212,7 @@ public abstract class G726 {
212 212 a2p+=0xFF;
213 213 else
214 214 a2p+=fa1>>5;
215   -
  215 +
216 216 if ((pk0^state.pk[1])!=0) {
217 217 /* LIMC */
218 218 if (a2p<=-12160)
... ... @@ -232,10 +232,10 @@ public abstract class G726 {
232 232 else
233 233 a2p+=0x80;
234 234 }
235   -
  235 +
236 236 /* TRIGB&DELAY */
237 237 state.a[1]=a2p;
238   -
  238 +
239 239 /* UPA1 */
240 240 /* update predictor pole a[0] */
241 241 state.a[0] -= state.a[0]>>8;
... ... @@ -244,17 +244,17 @@ public abstract class G726 {
244 244 state.a[0]+=192;
245 245 else
246 246 state.a[0] -= 192;
247   -
  247 +
248 248 /* LIMD */
249 249 a1ul=15360-a2p;
250 250 if (state.a[0]<-a1ul)
251 251 state.a[0]=-a1ul;
252 252 else if (state.a[0]>a1ul)
253 253 state.a[0]=a1ul;
254   -
  254 +
255 255 /* UPB : update predictor zeros b[6] */
256 256 for (cnt=0; cnt<6; cnt++) {
257   -
  257 +
258 258 if (code_size==5) /* for 40Kbps G.723 */
259 259 state.b[cnt]-=state.b[cnt]>>9;
260 260 else /* for G.721 and 24Kbps G.723 */
... ... @@ -268,7 +268,7 @@ public abstract class G726 {
268 268 }
269 269 }
270 270 }
271   -
  271 +
272 272 for (cnt=5; cnt>0; cnt--) state.dq[cnt]=state.dq[cnt-1];
273 273 /* FLOAT A : convert dq[0] to 4-bit exp, 6-bit mantissa f.p. */
274 274 if (mag==0) {
... ... @@ -278,7 +278,7 @@ public abstract class G726 {
278 278 exp=quan(mag, power2, 15);
279 279 state.dq[0]=(dq>=0) ? (exp<<6)+((mag<<6)>>exp) : (exp<<6)+((mag<<6)>>exp)-0x400;
280 280 }
281   -
  281 +
282 282 state.sr[1]=state.sr[0];
283 283 /* FLOAT B : convert sr to 4-bit exp., 6-bit mantissa f.p. */
284 284 if (sr==0) {
... ... @@ -297,11 +297,11 @@ public abstract class G726 {
297 297 }
298 298 else
299 299 state.sr[0]=0xFC20;
300   -
  300 +
301 301 /* DELAY A */
302 302 state.pk[1]=state.pk[0];
303 303 state.pk[0]=pk0;
304   -
  304 +
305 305 /* TONE */
306 306 if (tr==1) /* this sample has been treated as data */
307 307 state.td=0; /* next one will be treated as voice */
... ... @@ -310,13 +310,13 @@ public abstract class G726 {
310 310 state.td=1; /* signal may be data */
311 311 else /* signal is voice */
312 312 state.td=0;
313   -
  313 +
314 314 /*
315 315 * Adaptation speed control.
316 316 */
317 317 state.dms+=(fi-state.dms)>>5; /* FILTA */
318 318 state.dml+=(((fi<<2)-state.dml)>>7); /* FILTB */
319   -
  319 +
320 320 if (tr==1)
321 321 state.ap=256;
322 322 else
... ... @@ -331,7 +331,7 @@ public abstract class G726 {
331 331 else
332 332 state.ap+=(-state.ap)>>4;
333 333 }
334   -
  334 +
335 335 /** At the end of ADPCM decoding, it simulates an encoder which may be receiving
336 336 * the output of this decoder as a tandem process. If the output of the
337 337 * simulated encoder differs from the input to this decoder, the decoder output
... ... @@ -346,19 +346,19 @@ public abstract class G726 {
346 346 * @return adjusted A-law or u-law compressed sample.
347 347 */
348 348 protected static int tandem_adjust_alaw(int sr, int se, int y, int i, int sign, /*short*/int[] qtab) {
349   -
  349 +
350 350 /*unsigned char*/int sp; /* A-law compressed 8-bit code */
351 351 /*short*/int dx; /* prediction error */
352 352 /*char*/int id; /* quantized prediction error */
353 353 int sd; /* adjusted A-law decoded sample value */
354 354 int im; /* biased magnitude of i */
355 355 int imx; /* biased magnitude of id */
356   -
  356 +
357 357 if (sr<=-32768) sr=-1;
358 358 sp= G711Codec.linear2alaw((short)((sr>>1)<<3)); /* short to A-law compression */
359 359 dx=(G711Codec.alaw2linear((byte)sp)>>2)-se; /* 16-bit prediction error */
360 360 id=quantize(dx, y, qtab, sign-1);
361   -
  361 +
362 362 if (id==i) {
363 363 /* no adjustment on sp */
364 364 return (sp);
... ... @@ -368,12 +368,12 @@ public abstract class G726 {
368 368 /* ADPCM codes : 8, 9, ... F, 0, 1, ... , 6, 7 */
369 369 im=i^sign; /* 2's complement to biased unsigned */
370 370 imx=id^sign;
371   -
  371 +
372 372 if (imx>im) {
373 373 /* sp adjusted to next lower value */
374 374 if ((sp&0x80)!=0) {
375 375 sd=(sp==0xD5)? 0x55 : ((sp^0x55)-1)^0x55;
376   - }
  376 + }
377 377 else {
378 378 sd=(sp==0x2A)? 0x2A : ((sp^0x55)+1)^0x55;
379 379 }
... ... @@ -388,7 +388,7 @@ public abstract class G726 {
388 388 return (sd);
389 389 }
390 390 }
391   -
  391 +
392 392 /** @param sr - decoder output linear PCM sample
393 393 * @param se - predictor estimate sample
394 394 * @param y - quantizer step size
... ... @@ -397,21 +397,21 @@ public abstract class G726 {
397 397 * @param qtab
398 398 */
399 399 protected static int tandem_adjust_ulaw(int sr, int se, int y, int i, int sign, /*short*/int[] qtab) {
400   -
  400 +
401 401 /*unsigned char*/int sp; /* u-law compressed 8-bit code */
402 402 /*short*/int dx; /* prediction error */
403 403 /*char*/int id; /* quantized prediction error */
404 404 int sd; /* adjusted u-law decoded sample value */
405 405 int im; /* biased magnitude of i */
406 406 int imx; /* biased magnitude of id */
407   -
  407 +
408 408 if (sr<=-32768) sr=0;
409 409 sp= G711UCodec.linear2ulaw((short)(sr<<2)); /* short to u-law compression */
410 410 dx=(G711UCodec.ulaw2linear((byte)sp)>>2)-se; /* 16-bit prediction error */
411 411 id=quantize(dx, y, qtab, sign-1);
412 412 if (id==i) {
413 413 return (sp);
414   - }
  414 + }
415 415 else {
416 416 /* ADPCM codes : 8, 9, ... F, 0, 1, ... , 6, 7 */
417 417 im=i^sign; /* 2's complement to biased unsigned */
... ... @@ -422,7 +422,7 @@ public abstract class G726 {
422 422 sd=(sp==0xFF)? 0x7E : sp+1;
423 423 else
424 424 sd=(sp==0)? 0 : sp-1;
425   -
  425 +
426 426 }
427 427 else {
428 428 /* sp adjusted to next higher value */
... ... @@ -437,7 +437,7 @@ public abstract class G726 {
437 437  
438 438  
439 439 // ##### C-to-Java conversion: #####
440   -
  440 +
441 441 /** Converts a byte into an unsigned int. */
442 442 protected static int unsignedInt(byte b) {
443 443 return ((int)b+0x100)&0xFF;
... ... @@ -477,7 +477,7 @@ public abstract class G726 {
477 477 /** Encodes the input vale of linear PCM, A-law or u-law data sl and returns
478 478 * the resulting code. -1 is returned for unknown input coding value. */
479 479 public abstract int encode(int sl, int in_coding);
480   -
  480 +
481 481  
482 482 /** Encodes the input chunk in_buff of linear PCM, A-law or u-law data and returns
483 483 * the G726 encoded chuck into out_buff. <br>
... ... @@ -498,4 +498,4 @@ public abstract class G726 {
498 498 * out_coding value. */
499 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 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 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 6 /** G726_16 encoder and decoder.
8 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 6 /** G726_24 encoder and decoder.
8 7 * <p>
... ... @@ -19,7 +18,7 @@ import com.genersoft.iot.vmp.jt1078.codec.G711UCodec;
19 18 * ANSI-C source code to the public domain.
20 19 */
21 20 public class G726_24 extends G726 {
22   -
  21 +
23 22 // ##### C-to-Java conversion: #####
24 23 // short becomes int
25 24 // char becomes int
... ... @@ -33,30 +32,30 @@ public class G726_24 extends G726 {
33 32 * magnitude values.
34 33 */
35 34 static /*short*/int[] _dqlntab={-2048, 135, 273, 373, 373, 273, 135, -2048};
36   -
  35 +
37 36 /* Maps G726_24 code word to log of scale factor multiplier. */
38 37 static /*short*/int[] _witab={-128, 960, 4384, 18624, 18624, 4384, 960, -128};
39   -
  38 +
40 39 /*
41 40 * Maps G726_24 code words to a set of values whose long and short
42 41 * term averages are computed and then compared to give an indication
43 42 * how stationary (steady state) the signal is.
44 43 */
45 44 static /*short*/int[] _fitab={0, 0x200, 0x400, 0xE00, 0xE00, 0x400, 0x200, 0};
46   -
  45 +
47 46 static /*short*/int[] qtab_723_24={8, 218, 331};
48   -
  47 +
49 48 /** Encodes a linear PCM, A-law or u-law input sample and returns its 3-bit code.
50 49 * Returns -1 if invalid input coding value. */
51 50 public static int encode(int sl, int in_coding, G726State state) {
52   -
  51 +
53 52 /*short*/int sei, sezi, se, sez; /* ACCUM */
54 53 /*short*/int d; /* SUBTA */
55 54 /*short*/int y; /* MIX */
56 55 /*short*/int sr; /* ADDB */
57 56 /*short*/int dqsez; /* ADDC */
58 57 /*short*/int dq, i;
59   -
  58 +
60 59 switch (in_coding) {
61 60 /* linearize input sample to 14-bit PCM */
62 61 case AUDIO_ENCODING_ALAW:
... ... @@ -71,57 +70,57 @@ public class G726_24 extends G726 {
71 70 default:
72 71 return (-1);
73 72 }
74   -
  73 +
75 74 sezi=state.predictor_zero();
76 75 sez=sezi >> 1;
77 76 sei=sezi+state.predictor_pole();
78 77 se=sei >> 1; /* se=estimated signal */
79   -
  78 +
80 79 d=sl-se; /* d=estimation diff. */
81   -
  80 +
82 81 /* quantize prediction difference d */
83 82 y=state.step_size(); /* quantizer step size */
84 83 i=quantize(d, y, qtab_723_24, 3); /* i=ADPCM code */
85 84 dq=reconstruct(i & 4, _dqlntab[i], y); /* quantized diff. */
86   -
  85 +
87 86 sr=(dq<0)? se-(dq & 0x3FFF) : se+dq; /* reconstructed signal */
88   -
  87 +
89 88 dqsez=sr+sez-se; /* pole prediction diff. */
90   -
  89 +
91 90 update(3, y, _witab[i], _fitab[i], dq, sr, dqsez, state);
92   -
  91 +
93 92 return (i);
94 93 }
95   -
  94 +
96 95  
97 96 /** Decodes a 3-bit CCITT G.726 24kbps ADPCM code and returns
98 97 * the resulting 16-bit linear PCM, A-law or u-law sample value.
99 98 * -1 is returned if the output coding is unknown. */
100 99 public static int decode(int i, int out_coding, G726State state) {
101   -
  100 +
102 101 /*short*/int sezi, sei, sez, se; /* ACCUM */
103 102 /*short*/int y; /* MIX */
104 103 /*short*/int sr; /* ADDB */
105 104 /*short*/int dq;
106 105 /*short*/int dqsez;
107   -
  106 +
108 107 i &= 0x07; /* mask to get proper bits */
109 108 sezi=state.predictor_zero();
110 109 sez=sezi >> 1;
111 110 sei=sezi+state.predictor_pole();
112 111 se=sei >> 1; /* se=estimated signal */
113   -
  112 +
114 113 y=state.step_size(); /* adaptive quantizer step size */
115 114 dq=reconstruct(i & 0x04, _dqlntab[i], y); /* unquantize pred diff */
116   -
  115 +
117 116 sr=(dq<0)? (se-(dq & 0x3FFF)) : (se+dq); /* reconst. signal */
118   -
  117 +
119 118 dqsez=sr-se+sez; /* pole prediction diff. */
120   -
  119 +
121 120 update(3, y, _witab[i], _fitab[i], dq, sr, dqsez, state);
122   -
  121 +
123 122 switch (out_coding) {
124   -
  123 +
125 124 case AUDIO_ENCODING_ALAW:
126 125 return (tandem_adjust_alaw(sr, se, y, i, 4, qtab_723_24));
127 126 case AUDIO_ENCODING_ULAW:
... ... @@ -139,9 +138,9 @@ public class G726_24 extends G726 {
139 138 * It returns the actual size of the output data, or -1 in case of unknown
140 139 * in_coding value. */
141 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 142 if (in_coding==AUDIO_ENCODING_ALAW || in_coding==AUDIO_ENCODING_ULAW) {
144   -
  143 +
145 144 int len_div_8=in_len/8;
146 145 for (int i=0; i<len_div_8; i++) {
147 146 int value8=0;
... ... @@ -160,7 +159,7 @@ public class G726_24 extends G726 {
160 159 }
161 160 else
162 161 if (in_coding==AUDIO_ENCODING_LINEAR) {
163   -
  162 +
164 163 int len_div_16=in_len/16;
165 164 for (int i=0; i<len_div_16; i++) {
166 165 int value16=0;
... ... @@ -188,9 +187,9 @@ public class G726_24 extends G726 {
188 187 * It returns the actual size of the output data, or -1 in case of unknown
189 188 * out_coding value. */
190 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 191 if (out_coding==AUDIO_ENCODING_ALAW || out_coding==AUDIO_ENCODING_ULAW) {
193   -
  192 +
194 193 int len_div_3=in_len/3;
195 194 for (int i=0; i<len_div_3; i++) {
196 195 int value8=0;
... ... @@ -209,7 +208,7 @@ public class G726_24 extends G726 {
209 208 }
210 209 else
211 210 if (out_coding==AUDIO_ENCODING_LINEAR) {
212   -
  211 +
213 212 int len_div_3=in_len/3;
214 213 for (int i=0; i<len_div_3; i++) {
215 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 7 /** G726_32 encoder and decoder.
9 8 * <p>
... ... @@ -31,7 +30,7 @@ import com.genersoft.iot.vmp.jt1078.codec.G711UCodec;
31 30 * ANSI-C source code to the public domain.
32 31 */
33 32 public class G726_32 extends G726 {
34   -
  33 +
35 34 // ##### C-to-Java conversion: #####
36 35 // short becomes int
37 36 // char becomes int
... ... @@ -46,7 +45,7 @@ public class G726_32 extends G726 {
46 45 * magnitude values.
47 46 */
48 47 static /*short*/int[] _dqlntab={-2048, 4, 135, 213, 273, 323, 373, 425, 425, 373, 323, 273, 213, 135, 4, -2048};
49   -
  48 +
50 49 /* Maps G726_32 code word to log of scale factor multiplier. */
51 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 55 * how stationary (steady state) the signal is.
57 56 */
58 57 static /*short*/int[] _fitab={0, 0, 0, 0x200, 0x200, 0x200, 0x600, 0xE00, 0xE00, 0x600, 0x200, 0x200, 0x200, 0, 0, 0};
59   -
  58 +
60 59 /** Encodes the input vale of linear PCM, A-law or u-law data sl and returns
61 60 * the resulting code. -1 is returned for unknown input coding value. */
62 61 public static int encode(int sl, int in_coding, G726State state) {
63   -
  62 +
64 63 /*short*/int sezi, se, sez; /* ACCUM */
65 64 /*short*/int d; /* SUBTA */
66 65 /*short*/int sr; /* ADDB */
67 66 /*short*/int y; /* MIX */
68 67 /*short*/int dqsez; /* ADDC */
69 68 /*short*/int dq, i;
70   -
  69 +
71 70 switch (in_coding) {
72 71 /* linearize input sample to 14-bit PCM */
73 72 case AUDIO_ENCODING_ALAW:
... ... @@ -82,57 +81,57 @@ public class G726_32 extends G726 {
82 81 default:
83 82 return -1;
84 83 }
85   -
  84 +
86 85 sezi=state.predictor_zero();
87 86 sez=sezi >> 1;
88 87 se=(sezi+state.predictor_pole()) >> 1; /* estimated signal */
89   -
  88 +
90 89 d=sl-se; /* estimation difference */
91   -
  90 +
92 91 /* quantize the prediction difference */
93 92 y=state.step_size(); /* quantizer step size */
94 93 i=quantize(d, y, qtab_721, 7); /* i=ADPCM code */
95   -
  94 +
96 95 dq=reconstruct(i & 8, _dqlntab[i], y); /* quantized est diff */
97   -
  96 +
98 97 sr=(dq<0)? se-(dq & 0x3FFF) : se+dq; /* reconst. signal */
99   -
  98 +
100 99 dqsez=sr+sez-se; /* pole prediction diff. */
101   -
  100 +
102 101 update(4, y, _witab[i] << 5, _fitab[i], dq, sr, dqsez, state);
103   -
  102 +
104 103 return i;
105 104 }
106   -
  105 +
107 106 /** Decodes a 4-bit code of G726_32 encoded data of i and
108 107 * returns the resulting linear PCM, A-law or u-law value.
109 108 * return -1 for unknown out_coding value. */
110 109 public static int decode(int i, int out_coding, G726State state) {
111   -
  110 +
112 111 /*short*/int sezi, sei, sez, se; /* ACCUM */
113 112 /*short*/int y; /* MIX */
114 113 /*short*/int sr; /* ADDB */
115 114 /*short*/int dq;
116 115 /*short*/int dqsez;
117   -
  116 +
118 117 i &= 0x0f; /* mask to get proper bits */
119 118 sezi=state.predictor_zero();
120 119 sez=sezi >> 1;
121 120 sei=sezi+state.predictor_pole();
122 121 se=sei >> 1; /* se=estimated signal */
123   -
  122 +
124 123 y=state.step_size(); /* dynamic quantizer step size */
125   -
  124 +
126 125 dq=reconstruct(i & 0x08, _dqlntab[i], y); /* quantized diff. */
127   -
  126 +
128 127 sr=(dq<0)? (se-(dq & 0x3FFF)) : se+dq; /* reconst. signal */
129   -
  128 +
130 129 dqsez=sr-se+sez; /* pole prediction diff. */
131   -
  130 +
132 131 update(4, y, _witab[i] << 5, _fitab[i], dq, sr, dqsez, state);
133   -
  132 +
134 133 switch (out_coding) {
135   -
  134 +
136 135 case AUDIO_ENCODING_ALAW:
137 136 return (tandem_adjust_alaw(sr, se, y, i, 8, qtab_721));
138 137 case AUDIO_ENCODING_ULAW:
... ... @@ -150,9 +149,9 @@ public class G726_32 extends G726 {
150 149 * It returns the actual size of the output data, or -1 in case of unknown
151 150 * in_coding value. */
152 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 153 if (in_coding==AUDIO_ENCODING_ALAW || in_coding==AUDIO_ENCODING_ULAW) {
155   -
  154 +
156 155 /*
157 156 for (int i=0; i<in_len; i++) {
158 157 int in_value=in_buff[in_offset+i];
... ... @@ -170,25 +169,25 @@ public class G726_32 extends G726 {
170 169 int in_index=in_offset+i*2;
171 170 int in_value1=in_buff[in_index];
172 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 174 out_buff[out_offset+i]=(byte)((out_value1<<4) + out_value2);
176 175 }
177 176 return len_div_2;
178 177 }
179 178 else
180 179 if (in_coding==AUDIO_ENCODING_LINEAR) {
181   -
  180 +
182 181 int len_div_4=in_len/4;
183 182 for (int i=0; i<len_div_4; i++) {
184 183 int in_index=in_offset+i*4;
185 184 int in_value1=signedIntLittleEndian(in_buff[in_index+1],in_buff[in_index+0]);
186 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 191 out_buff[out_offset+i]=(byte)((out_value1<<4) + out_value2);
193 192 }
194 193 return len_div_4;
... ... @@ -202,24 +201,24 @@ public class G726_32 extends G726 {
202 201 * It returns the actual size of the output data, or -1 in case of unknown
203 202 * out_coding value. */
204 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 205 if (out_coding==AUDIO_ENCODING_ALAW || out_coding==AUDIO_ENCODING_ULAW) {
207   -
  206 +
208 207 /*
209 208 for (int i=0; i<in_len*2; i++) {
210 209 int in_value=unsignedInt(in_buff[in_offset+i/2]);
211 210 if ((i/2)*2==i)
212 211 in_value>>=4;
213 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 215 out_buff[out_offset+i]=(byte)out_value;
217 216 }
218 217 return in_len*2;
219 218 */
220 219 for (int i=0; i<in_len; i++) {
221 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 222 int out_value2=decode(in_value&0xF,out_coding,state);
224 223 int out_index=out_offset+i*2;
225 224 out_buff[out_index]=(byte)out_value1;
... ... @@ -229,12 +228,12 @@ public class G726_32 extends G726 {
229 228 }
230 229 else
231 230 if (out_coding==AUDIO_ENCODING_LINEAR) {
232   -
  231 +
233 232 for (int i=0; i<in_len; i++) {
234 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 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 237 int out_value2=decode(in_value&0xF,out_coding,state);
239 238 int out_index=out_offset+i*4;
240 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 6 /** G726_40 encoder and decoder.
8 7 * <p>
... ... @@ -27,12 +26,12 @@ import com.genersoft.iot.vmp.jt1078.codec.G711UCodec;
27 26 * ANSI-C source code to the public domain.
28 27 */
29 28 public class G726_40 extends G726 {
30   -
  29 +
31 30 // ##### C-to-Java conversion: #####
32 31 // short becomes int
33 32 // char becomes int
34 33 // unsigned char becomes int
35   -
  34 +
36 35  
37 36 // *************************** STATIC ***************************
38 37  
... ... @@ -41,31 +40,31 @@ public class G726_40 extends G726 {
41 40 * magnitude values.
42 41 */
43 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 44 /* Maps G723_40 code word to log of scale factor multiplier. */
46 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 48 * Maps G723_40 code words to a set of values whose long and short
50 49 * term averages are computed and then compared to give an indication
51 50 * how stationary (steady state) the signal is.
52 51 */
53 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 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 56 /** Encodes a 16-bit linear PCM, A-law or u-law input sample and retuens
58 57 * the resulting 5-bit CCITT G726 40kbps code.
59 58 * Returns -1 if the input coding value is invalid. */
60 59 public static int encode(int sl, int in_coding, G726State state) {
61   -
  60 +
62 61 /*short*/int sei, sezi, se, sez; /* ACCUM */
63 62 /*short*/int d; /* SUBTA */
64 63 /*short*/int y; /* MIX */
65 64 /*short*/int sr; /* ADDB */
66 65 /*short*/int dqsez; /* ADDC */
67 66 /*short*/int dq, i;
68   -
  67 +
69 68 switch (in_coding) {
70 69 /* linearize input sample to 14-bit PCM */
71 70 case AUDIO_ENCODING_ALAW:
... ... @@ -80,58 +79,58 @@ public class G726_40 extends G726 {
80 79 default:
81 80 return (-1);
82 81 }
83   -
  82 +
84 83 sezi=state.predictor_zero();
85 84 sez=sezi >> 1;
86 85 sei=sezi+state.predictor_pole();
87 86 se=sei >> 1; /* se=estimated signal */
88   -
  87 +
89 88 d=sl-se; /* d=estimation difference */
90   -
  89 +
91 90 /* quantize prediction difference */
92 91 y=state.step_size(); /* adaptive quantizer step size */
93 92 i=quantize(d, y, qtab_723_40, 15); /* i=ADPCM code */
94   -
  93 +
95 94 dq=reconstruct(i & 0x10, _dqlntab[i], y); /* quantized diff */
96   -
  95 +
97 96 sr=(dq<0)? se-(dq & 0x7FFF) : se+dq; /* reconstructed signal */
98   -
  97 +
99 98 dqsez=sr+sez-se; /* dqsez=pole prediction diff. */
100   -
  99 +
101 100 update(5, y, _witab[i], _fitab[i], dq, sr, dqsez, state);
102   -
  101 +
103 102 return (i);
104 103 }
105 104  
106   -
  105 +
107 106 /** Decodes a 5-bit CCITT G.726 40kbps code and returns
108 107 * the resulting 16-bit linear PCM, A-law or u-law sample value.
109 108 * -1 is returned if the output coding is unknown. */
110 109 public static int decode(int i, int out_coding, G726State state) {
111   -
  110 +
112 111 /*short*/int sezi, sei, sez, se; /* ACCUM */
113 112 /*short*/int y, dif; /* MIX */
114 113 /*short*/int sr; /* ADDB */
115 114 /*short*/int dq;
116 115 /*short*/int dqsez;
117   -
  116 +
118 117 i &= 0x1f; /* mask to get proper bits */
119 118 sezi=state.predictor_zero();
120 119 sez=sezi >> 1;
121 120 sei=sezi+state.predictor_pole();
122 121 se=sei >> 1; /* se=estimated signal */
123   -
  122 +
124 123 y=state.step_size(); /* adaptive quantizer step size */
125 124 dq=reconstruct(i & 0x10, _dqlntab[i], y); /* estimation diff. */
126   -
  125 +
127 126 sr=(dq<0)? (se-(dq & 0x7FFF)) : (se+dq); /* reconst. signal */
128   -
  127 +
129 128 dqsez=sr-se+sez; /* pole prediction diff. */
130   -
  129 +
131 130 update(5, y, _witab[i], _fitab[i], dq, sr, dqsez, state);
132   -
  131 +
133 132 switch (out_coding) {
134   -
  133 +
135 134 case AUDIO_ENCODING_ALAW:
136 135 return (tandem_adjust_alaw(sr, se, y, i, 0x10, qtab_723_40));
137 136 case AUDIO_ENCODING_ULAW:
... ... @@ -149,9 +148,9 @@ public class G726_40 extends G726 {
149 148 * It returns the actual size of the output data, or -1 in case of unknown
150 149 * in_coding value. */
151 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 152 if (in_coding==AUDIO_ENCODING_ALAW || in_coding==AUDIO_ENCODING_ULAW) {
154   -
  153 +
155 154 int len_div_8=in_len/8;
156 155 for (int i=0; i<len_div_8; i++) {
157 156 long value8=0;
... ... @@ -170,7 +169,7 @@ public class G726_40 extends G726 {
170 169 }
171 170 else
172 171 if (in_coding==AUDIO_ENCODING_LINEAR) {
173   -
  172 +
174 173 int len_div_16=in_len/16;
175 174 for (int i=0; i<len_div_16; i++) {
176 175 long value16=0;
... ... @@ -197,9 +196,9 @@ public class G726_40 extends G726 {
197 196 * It returns the actual size of the output data, or -1 in case of unknown
198 197 * out_coding value. */
199 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 200 if (out_coding==AUDIO_ENCODING_ALAW || out_coding==AUDIO_ENCODING_ULAW) {
202   -
  201 +
203 202 int len_div_5=in_len/5;
204 203 for (int i=0; i<len_div_5; i++) {
205 204 long value8=0;
... ... @@ -218,7 +217,7 @@ public class G726_40 extends G726 {
218 217 }
219 218 else
220 219 if (out_coding==AUDIO_ENCODING_LINEAR) {
221   -
  220 +
222 221 int len_div_5=in_len/5;
223 222 for (int i=0; i<len_div_5; i++) {
224 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 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 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 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 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 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 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 3 import io.netty.buffer.ByteBuf;
4 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 5 import java.io.ByteArrayOutputStream;
6   -import java.io.IOException;
7   -import java.io.OutputStream;
8 6  
9 7 /**
10 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 3 //由于flv格式是header+body,而body是preTagSize+currentTagData.......循环形式,并且第一个的preTagSize始终为0,
4 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 3 import io.netty.buffer.ByteBuf;
4 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 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 4 import io.netty.buffer.ByteBuf;
6 5 import io.netty.channel.ChannelHandlerContext;
7 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 3 import java.util.HashMap;
4 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 3 import io.netty.channel.Channel;
  4 +import org.apache.commons.collections4.map.HashedMap;
  5 +
4 6  
5   -import java.util.HashMap;
6 7 import java.util.Map;
7 8  
8 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 13 public static void init()
13 14 {
... ... @@ -28,4 +29,4 @@ public final class SessionManager
28 29 {
29 30 return mappings.containsKey(channel.id().asLongText() + key);
30 31 }
31   -}
32 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 4 import org.slf4j.Logger;
11 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 13 static Logger logger = LoggerFactory.getLogger(RTMPPublisher.class);
  14 +
15 15 String tag = null;
16   - private Integer port;
17 16 Process process = null;
18 17  
19   - public RTMPPublisher(String tag, Integer port) {
  18 + public RTMPPublisher(String tag)
  19 + {
20 20 this.tag = tag;
21   - this.port = port;
22 21 }
23 22  
24 23 @Override
... ... @@ -31,14 +30,15 @@ public class RTMPPublisher extends Thread {
31 30  
32 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 36 Configs.get("ffmpeg.path"),
37 37 Configs.getInt("server.http.port", 3333),
38 38 tag,
39 39 rtmpUrl
40 40 );
41   - logger.info("Execute: {}", cmd);
  41 + logger.info("推流命令 Execute: {}", cmd);
42 42 process = Runtime.getRuntime().exec(cmd);
43 43 stderr = process.getErrorStream();
44 44 while ((len = stderr.read(buff)) > -1)
... ... @@ -57,4 +57,4 @@ public class RTMPPublisher extends Thread {
57 57 {
58 58 try { if (process != null) process.destroyForcibly(); } catch(Exception e) { }
59 59 }
60   -}
61 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 4 import io.netty.channel.ChannelFuture;
6 5 import io.netty.channel.ChannelHandlerContext;
7 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 10 import io.netty.buffer.ByteBuf;
11 11 import io.netty.channel.ChannelHandlerContext;
12 12  
... ... @@ -30,7 +30,6 @@ public class VideoSubscriber extends Subscriber
30 30 public void onVideoData(long timeoffset, byte[] data, FlvEncoder flvEncoder)
31 31 {
32 32 if (lastVideoFrameTimeOffset == 0) lastVideoFrameTimeOffset = timeoffset;
33   -
34 33 // 之前是不是已经发送过了?没有的话,需要补发FLV HEADER的。。。
35 34 if (videoHeaderSent == false && flvEncoder.videoReady())
36 35 {
... ... @@ -47,9 +46,7 @@ public class VideoSubscriber extends Subscriber
47 46  
48 47 videoHeaderSent = true;
49 48 }
50   -
51 49 if (data == null) return;
52   -
53 50 // 修改时间戳
54 51 // System.out.println("Time: " + videoTimestamp + ", current: " + timeoffset);
55 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 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 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 3 import java.util.Arrays;
4 4  
... ... @@ -93,4 +93,4 @@ public class ByteHolder
93 93 int l = this.buffer[position + 1] & 0xff;
94 94 return ((h << 8) | l) & 0xffff;
95 95 }
96   -}
97 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 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 3 import java.io.File;
4 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 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 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 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 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 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 29 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
30 30 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
31 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 33 import com.genersoft.iot.vmp.vmanager.jt1078.platform.Jt1078OfCarController;
37 34 import org.apache.commons.lang3.StringUtils;
38 35 import org.slf4j.Logger;
... ... @@ -40,6 +37,7 @@ import org.slf4j.LoggerFactory;
40 37 import org.springframework.beans.factory.annotation.Autowired;
41 38 import org.springframework.beans.factory.annotation.Qualifier;
42 39 import org.springframework.data.redis.core.RedisTemplate;
  40 +import org.springframework.scheduling.annotation.Scheduled;
43 41 import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
44 42 import org.springframework.util.ObjectUtils;
45 43 import org.springframework.web.bind.annotation.*;
... ... @@ -50,6 +48,7 @@ import javax.sip.InvalidArgumentException;
50 48 import javax.sip.SipException;
51 49 import java.text.ParseException;
52 50 import java.util.*;
  51 +import java.util.concurrent.TimeUnit;
53 52  
54 53 /**
55 54 * @description:针对 ZLMediaServer的hook事件监听
... ... @@ -187,7 +186,6 @@ public class ZLMHttpHookListener {
187 186 return new HookResult(401, "Unauthorized");
188 187 }
189 188 }
190   -
191 189 return HookResult.SUCCESS();
192 190 }
193 191  
... ... @@ -679,8 +677,16 @@ public class ZLMHttpHookListener {
679 677 // StreamPushItem streamPushItem = streamPushService.getPush(app, streamId);
680 678 // if (streamPushItem != null) {
681 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 691 return ret;
686 692 }
... ... @@ -700,7 +706,6 @@ public class ZLMHttpHookListener {
700 706 defaultResult.setResult(new HookResult(ErrorCode.ERROR404.getCode(), ErrorCode.ERROR404.getMsg()));
701 707 return defaultResult;
702 708 }
703   -
704 709 if ("rtp".equals(param.getApp())) {
705 710 String[] s = param.getStream().split("_");
706 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 18 import java.util.Objects;
19 19 import java.util.concurrent.TimeUnit;
20 20  
  21 +/**
  22 + * ZLM工具类
  23 + */
21 24 @Component
22 25 public class ZLMRESTfulUtils {
23 26  
... ...
src/main/java/com/genersoft/iot/vmp/service/IStreamProxyService.java
... ... @@ -114,6 +114,10 @@ public interface IStreamProxyService {
114 114 * 更新代理流
115 115 */
116 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 7 import com.genersoft.iot.vmp.service.bean.StreamPushItemFromRedis;
8 8 import com.genersoft.iot.vmp.vmanager.bean.ResourceBaseInfo;
9 9 import com.github.pagehelper.PageInfo;
  10 +import org.springframework.scheduling.annotation.Scheduled;
10 11  
11 12 import java.util.List;
12 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 193 callback.run(ErrorCode.ERROR100.getCode(), "超时", null);
194 194 }
195 195 }, 7000);
  196 + //TODO
196 197 JSONObject jsonObject = addStreamProxyToZlm(param);
197 198 if (jsonObject != null && jsonObject.getInteger("code") == 0) {
198 199 hookSubscribe.removeSubscribe(hookSubscribeForStreamChange);
... ... @@ -273,8 +274,6 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
273 274 logger.error("向数据库添加流代理失败:", e);
274 275 dataSourceTransactionManager.rollback(transactionStatus);
275 276 }
276   -
277   -
278 277 return result;
279 278 }
280 279  
... ... @@ -312,6 +311,42 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
312 311 }
313 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 351 @Override
317 352 public JSONObject addStreamProxyToZlm(StreamProxyItem param) {
... ... @@ -491,8 +526,10 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
491 526 @Override
492 527 public void zlmServerOnline(String mediaServerId) {
493 528 // 移除开启了无人观看自动移除的流
  529 + choose1078HistoryLister();
494 530  
495 531 choose1078Lister();
  532 +
496 533 List<StreamProxyItem> streamProxyItemList = streamProxyMapper.selectAutoRemoveItemByMediaServerId(mediaServerId);
497 534 if (streamProxyItemList.size() > 0) {
498 535 gbStreamMapper.batchDel(streamProxyItemList);
... ... @@ -647,7 +684,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
647 684 }
648 685  
649 686  
650   - public void choose1078Lister() {
  687 + public void choose1078HistoryLister() {
651 688 Set<String> keys = redisTemplate.keys("tag:history:port:*");
652 689 if (org.apache.commons.collections4.CollectionUtils.isEmpty(keys)) {
653 690 return;
... ... @@ -680,10 +717,45 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
680 717 logger.error("[{}]停流失败", stream, e);
681 718 }
682 719 }
683   -
684 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 759 private void sendIORequestStop(String stream) {
688 760 try {
689 761 String sim = StringUtils.substringBeforeLast(stream, "-");
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/StremProxyService1078Impl.java
1 1 package com.genersoft.iot.vmp.service.impl;
2 2  
3 3 import com.genersoft.iot.vmp.VManageBootstrap;
4   -import com.genersoft.iot.vmp.jt1078.app.VideoServerApp;
5 4 import com.genersoft.iot.vmp.service.IStreamProxyService;
6 5 import com.genersoft.iot.vmp.service.StremProxyService1078;
7 6 import com.genersoft.iot.vmp.vmanager.jt1078.platform.ben.HttpClientPostEntity;
8 7 import com.genersoft.iot.vmp.vmanager.jt1078.platform.config.Jt1078ConfigBean;
9 8 import com.genersoft.iot.vmp.vmanager.jt1078.platform.handler.HttpClientUtil;
10   -import org.apache.commons.collections4.CollectionUtils;
11 9 import org.apache.commons.lang3.StringUtils;
12 10 import org.slf4j.Logger;
13 11 import org.slf4j.LoggerFactory;
14 12 import org.springframework.beans.factory.annotation.Autowired;
15 13 import org.springframework.data.redis.core.RedisTemplate;
16 14 import org.springframework.stereotype.Service;
17   -import org.springframework.web.bind.annotation.PathVariable;
18 15  
19 16 import java.io.IOException;
20 17 import java.net.URISyntaxException;
21 18 import java.util.HashMap;
22   -import java.util.List;
23 19 import java.util.Map;
24 20 import java.util.Objects;
25 21 import java.util.concurrent.TimeUnit;
... ... @@ -35,10 +31,8 @@ public class StremProxyService1078Impl implements StremProxyService1078 {
35 31 @Autowired
36 32 private RedisTemplate<Object, Object> redisTemplate;
37 33  
38   -
39 34 private static final Logger log = LoggerFactory.getLogger(StremProxyService1078Impl.class);
40 35  
41   -
42 36 @Override
43 37 public Map<String, Object> sendIORequestStop(String sim, String channel, String stream, Integer port, Integer httpPort) {
44 38 Map<String, Object> resultMap = new HashMap<>();
... ... @@ -70,7 +64,7 @@ public class StremProxyService1078Impl implements StremProxyService1078 {
70 64 }
71 65 log.info("port:[{}]",port);
72 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 31 }
32 32 return clazz.cast(jsonObject);
33 33 }
34   -}
35 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 10 ERROR404(404, "资源未找到"),
11 11 ERROR403(403, "无权限操作"),
12 12 ERROR401(401, "请登录后重新请求"),
13   - ERROR500(500, "系统异常");
  13 + ERROR500(500, "系统异常"),
  14 + ERROR450(450, "新建链接错误,请稍后再试"),
  15 + ERROR420(420, "发送推流指令异常"),
  16 + ERROR301(301, "下发指令异常"),
  17 + ERROR304(304, "离线的客户端(请检查设备是否注册或者鉴权");
14 18  
15 19 private final int code;
16 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 4 import com.genersoft.iot.vmp.service.bean.DownloadFileInfo;
5 5 import io.swagger.v3.oas.annotations.media.Schema;
6 6  
  7 +/**
  8 + * 流信息
  9 + */
7 10 @Schema(description = "流信息")
8 11 public class StreamContent {
9 12  
  13 + /**
  14 + * 应用名
  15 + */
10 16 @Schema(description = "应用名")
11 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 35 @Schema(description = "流ID")
14 36 private String stream;
15 37  
  38 + /**
  39 + * IP
  40 + */
16 41 @Schema(description = "IP")
17 42 private String ip;
18 43  
  44 + /**
  45 + * HTTP-FLV流地址
  46 + */
19 47 @Schema(description = "HTTP-FLV流地址")
20 48 private String flv;
21 49  
  50 + /**
  51 + * HTTPS-FLV流地址
  52 + */
22 53 @Schema(description = "HTTPS-FLV流地址")
23 54 private String https_flv;
24 55  
  56 + /**
  57 + * Websocket-FLV流地址
  58 + */
25 59 @Schema(description = "Websocket-FLV流地址")
26 60 private String ws_flv;
27 61  
  62 + /**
  63 + * Websockets-FLV流地址
  64 + */
28 65 @Schema(description = "Websockets-FLV流地址")
29 66 private String wss_flv;
30 67  
  68 + /**
  69 + * HTTP-FMP4流地址
  70 + */
31 71 @Schema(description = "HTTP-FMP4流地址")
32 72 private String fmp4;
33 73  
  74 + /**
  75 + * HTTPS-FMP4流地址
  76 + */
34 77 @Schema(description = "HTTPS-FMP4流地址")
35 78 private String https_fmp4;
36 79  
  80 + /**
  81 + * Websocket-FMP4流地址
  82 + */
37 83 @Schema(description = "Websocket-FMP4流地址")
38 84 private String ws_fmp4;
39 85  
  86 + /**
  87 + * Websockets-FMP4流地址
  88 + */
40 89 @Schema(description = "Websockets-FMP4流地址")
41 90 private String wss_fmp4;
42 91  
  92 + /**
  93 + * HLS流地址
  94 + */
43 95 @Schema(description = "HLS流地址")
44 96 private String hls;
45 97  
  98 + /**
  99 + * HTTPS-HLS流地址
  100 + */
46 101 @Schema(description = "HTTPS-HLS流地址")
47 102 private String https_hls;
48 103  
  104 + /**
  105 + * Websocket-HLS流地址
  106 + */
49 107 @Schema(description = "Websocket-HLS流地址")
50 108 private String ws_hls;
51 109  
  110 + /**
  111 + * Websockets-HLS流地址
  112 + */
52 113 @Schema(description = "Websockets-HLS流地址")
53 114 private String wss_hls;
54 115  
  116 + /**
  117 + * HTTP-TS流地址
  118 + */
55 119 @Schema(description = "HTTP-TS流地址")
56 120 private String ts;
57 121  
  122 + /**
  123 + * HTTPS-TS流地址
  124 + */
58 125 @Schema(description = "HTTPS-TS流地址")
59 126 private String https_ts;
60 127  
  128 + /**
  129 + * Websocket-TS流地址
  130 + */
61 131 @Schema(description = "Websocket-TS流地址")
62 132 private String ws_ts;
63 133  
  134 + /**
  135 + * Websockets-TS流地址
  136 + */
64 137 @Schema(description = "Websockets-TS流地址")
65 138 private String wss_ts;
66 139  
  140 + /**
  141 + * RTMP流地址
  142 + */
67 143 @Schema(description = "RTMP流地址")
68 144 private String rtmp;
69 145  
  146 + /**
  147 + * RTMPS流地址
  148 + */
70 149 @Schema(description = "RTMPS流地址")
71 150 private String rtmps;
72 151  
  152 + /**
  153 + * RTSP流地址
  154 + */
73 155 @Schema(description = "RTSP流地址")
74 156 private String rtsp;
75 157  
  158 + /**
  159 + * RTSPS流地址
  160 + */
76 161 @Schema(description = "RTSPS流地址")
77 162 private String rtsps;
78 163  
  164 + /**
  165 + * RTC流地址
  166 + */
79 167 @Schema(description = "RTC流地址")
80 168 private String rtc;
81 169  
  170 + /**
  171 + * RTCS流地址
  172 + */
82 173 @Schema(description = "RTCS流地址")
83 174 private String rtcs;
84 175  
  176 + /**
  177 + * 流媒体ID
  178 + */
85 179 @Schema(description = "流媒体ID")
86 180 private String mediaServerId;
87 181  
  182 + /**
  183 + * 流编码信息
  184 + */
88 185 @Schema(description = "流编码信息")
89 186 private Object tracks;
90 187  
  188 + /**
  189 + * 开始时间
  190 + */
91 191 @Schema(description = "开始时间")
92 192 private String startTime;
93 193  
  194 + /**
  195 + * 结束时间
  196 + */
94 197 @Schema(description = "结束时间")
95 198 private String endTime;
96 199  
  200 + /**
  201 + * 文件下载地址
  202 + */
97 203 @Schema(description = "文件下载地址(录像下载使用)")
98 204 private DownloadFileInfo downLoadFilePath;
99 205  
... ... @@ -102,6 +208,23 @@ public class StreamContent {
102 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 228 public StreamContent(StreamInfo streamInfo) {
106 229 if (streamInfo == null) {
107 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 9 import com.alibaba.fastjson2.JSONArray;
10 10 import com.alibaba.fastjson2.JSONException;
11 11 import com.alibaba.fastjson2.JSONObject;
12   -import com.genersoft.iot.vmp.VManageBootstrap;
13 12 import com.genersoft.iot.vmp.conf.MediaConfig;
14 13 import com.genersoft.iot.vmp.conf.StreamProxyTask;
15 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 17 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
20 18 import com.genersoft.iot.vmp.service.IStreamProxyService;
21 19 import com.genersoft.iot.vmp.service.IStreamPushService;
22 20 import com.genersoft.iot.vmp.service.StremProxyService1078;
  21 +import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
23 22 import com.genersoft.iot.vmp.vmanager.bean.StreamContent;
  23 +import com.genersoft.iot.vmp.vmanager.bean.StreamPlayPath;
24 24 import com.genersoft.iot.vmp.vmanager.jt1078.platform.ben.HttpClientPostEntity;
25   -import com.genersoft.iot.vmp.vmanager.jt1078.platform.ben.TestEntity;
26 25 import com.genersoft.iot.vmp.vmanager.jt1078.platform.config.Jt1078ConfigBean;
27 26 import com.genersoft.iot.vmp.vmanager.jt1078.platform.config.RtspConfigBean;
28 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 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 33 import com.genersoft.iot.vmp.vmanager.streamProxy.StreamProxyController;
31 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 35 import org.apache.commons.collections4.CollectionUtils;
52 36 import org.apache.commons.collections4.MapUtils;
53 37 import org.apache.commons.lang3.RandomUtils;
... ... @@ -59,14 +43,35 @@ import org.slf4j.Logger;
59 43 import org.slf4j.LoggerFactory;
60 44 import org.springframework.beans.factory.annotation.Autowired;
61 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 48 import org.springframework.data.redis.core.RedisTemplate;
  49 +import org.springframework.data.redis.core.ScanOptions;
63 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 76 @RestController
72 77 @RequestMapping({"/api/jt1078/query"})
... ... @@ -97,6 +102,14 @@ public class Jt1078OfCarController {
97 102 private Date tokenDate;
98 103 @Autowired
99 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 114 @Value("${spring.profiles.active}")
102 115 private String profilesActive;
... ... @@ -105,10 +118,14 @@ public class Jt1078OfCarController {
105 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 126 @GetMapping({"/company/tree"})
109 127 public Map<String, Object> requestTreeOfCompany() {
110 128 Map<String, Object> resultMap = new HashMap();
111   -
112 129 try {
113 130 resultMap.put("code", "1");
114 131 List<HashMap<String, Object>> compList = new ArrayList();
... ... @@ -119,14 +136,13 @@ public class Jt1078OfCarController {
119 136 resultMap.put("code", "-100");
120 137 resultMap.put("msg", "请求错误,请联系管理员");
121 138 }
122   -
123 139 return resultMap;
124 140 }
125 141  
126 142 @GetMapping({"/car/tree/{companyId}"})
127 143 public Map<String, Object> requestTreeOfCarByCompanyId(@PathVariable String companyId) {
  144 + clearRedisTree();
128 145 Map<String, Object> resultMap = new HashMap();
129   -
130 146 try {
131 147 List<HashMap<String, Object>> linesCars = this.tuohuaConfigBean.requestOfLineAndCarAndCombationTree(this.httpClientUtil, companyId);
132 148 resultMap.put("result", linesCars);
... ... @@ -135,19 +151,45 @@ public class Jt1078OfCarController {
135 151 resultMap.put("code", "-100");
136 152 resultMap.put("msg", "请求错误,请联系管理员");
137 153 }
138   -
139 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 186 @GetMapping({"/car/sim/{zbh}"})
143 187 public Map<String, Object> requestSimple(@PathVariable String zbh) {
144 188 Map<String, Object> resultMap = new HashMap();
145   -
146 189 try {
147 190 if (this.cookieTimeOut()) {
148 191 this.requestToken();
149 192 }
150   -
151 193 String url = MessageFormat.format(this.tuohuaConfigBean.getSimURL(), zbh);
152 194 HttpClientPostEntity clientPostEntity = this.httpClientUtil.doGet(url, this.jsessionid);
153 195 if (Objects.isNull(clientPostEntity)) {
... ... @@ -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 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 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 393 @GetMapping({"/send/stop/io/{sim}/{channel}/{stream}/{port}/{httpPort}"})
251 394 public Map<String, Object> sendIORequestStop(@PathVariable String sim, @PathVariable String channel, @PathVariable String stream, @PathVariable Integer port, @PathVariable Integer httpPort) {
252 395 Map<String, Object> resultMap = new HashMap();
... ... @@ -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 445 @GetMapping({"/send/stop/io/{sim}/{channel}"})
296 446 public Map<String, Object> sendIORequestStop(@PathVariable String sim, @PathVariable String channel) {
297 447 Map<String, Object> resultMap = new HashMap();
... ... @@ -323,7 +473,6 @@ public class Jt1078OfCarController {
323 473  
324 474 for (int i = 0; i < count; ++i) {
325 475 StreamPushItem item = streamPushItems.get(i);
326   -
327 476 try {
328 477 this.streamProxyController.del(item.getApp(), item.getStream());
329 478 this.streamPushService.stop(item.getApp(), item.getStream());
... ... @@ -332,7 +481,6 @@ public class Jt1078OfCarController {
332 481 log.error("推流停止失败,[{}]", item, e);
333 482 }
334 483 }
335   -
336 484 resultMap.put("code", "1");
337 485 resultMap.put("message", "OK");
338 486 return resultMap;
... ... @@ -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 505 @GetMapping({"/history/list/{sim}/{channel}/{startTime}/{endTime}"})
349 506 public Map<String, Object> historyListOfSim(@PathVariable String sim, @PathVariable String channel, @PathVariable String startTime, @PathVariable String endTime) {
350 507 Map<String, Object> resultMap = new HashMap();
... ... @@ -366,10 +523,9 @@ public class Jt1078OfCarController {
366 523 return resultMap;
367 524 } else {
368 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 528 String msg = this.jt1078ConfigBean.formatMessageHistoryListRTSP(sim, channel, startTime, endTime);
372   -
373 529 try {
374 530 HttpClientPostEntity entity = this.httpClientUtil.doPost(url, msg, (String) null);
375 531 if (Objects.isNull(entity)) {
... ... @@ -377,263 +533,353 @@ public class Jt1078OfCarController {
377 533 resultMap.put("msg", "请求历史视频列表错误,请联系管理员");
378 534 return resultMap;
379 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 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 633 Map<String, Object> resultMap = new HashMap();
429 634 if (StringUtils.isBlank(sim)) {
430 635 resultMap.put("code", "-100");
431 636 resultMap.put("msg", "sim 不能为空");
432 637 return resultMap;
433   - } else if (StringUtils.isBlank(channel)) {
  638 + }
  639 + if (StringUtils.isBlank(channel)) {
434 640 resultMap.put("code", "-100");
435 641 resultMap.put("msg", "channel 不能为空");
436 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 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 709 resultMap.put("code", "1");
  710 + streamContent = this.getStreamContent(channelMapping);
450 711 log.info("StreamContent:[{}]", streamContent);
451 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 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 846 if (Objects.isNull(streamContent) || StringUtils.isEmpty(streamContent.getWs_flv())) {
550 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 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 869 return streamContent;
632 870 }
633 871  
  872 + /**
  873 + * 获取视频播放地址
  874 + *
  875 + * @param stream 流名称
  876 + * @return 流信息
  877 + */
634 878 private StreamContent getStreamContentPlayURL(String stream) {
635 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 883 } catch (ControllerException var3) {
638 884 log.debug("获取播放地址失败:[{}],[{}]", stream, this.mediaConfig.getId());
639 885 return null;
... ... @@ -728,69 +974,80 @@ public class Jt1078OfCarController {
728 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 1016 // Integer port = 11078;
745   - Integer httPort = 3333;
746 1017  
747 1018 String url = this.jt1078ConfigBean.formatPushURL(channelMapping, port, httPort);
748   -
749 1019 try {
750 1020 HttpClientPostEntity httpClientPostEntity = new HttpClientPostEntity();
751   -
752 1021 httpClientPostEntity.setHttpPort(httPort);
753 1022 httpClientPostEntity.setPort(port);
754 1023 return httpClientPostEntity;
755   -
756 1024 } catch (Exception e) {
757 1025 log.error("url:[{}]", url, e);
758 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 1031 Map<String, Object> result = new HashMap();
764 1032 if (Objects.isNull(entity)) {
765   - result.put("code", "301");
766   - result.put("msg", "下发指令异常");
767   - return result;
  1033 + throw new ControllerException(ErrorCode.ERROR301);
768 1034 } else {
769 1035 try {
770 1036 Map<String, Object> rsultMap = (Map) JSON.parseObject(entity.getResultStr(), HashMap.class);
771 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 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 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 1046 } catch (Exception var6) {
789 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 1098 }
842 1099 }
843 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 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 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 43 private String simURL;
44 44  
45 45 @Value("${tuohua.bsth.login.rest.baseURL}")
46   - public String baseURL;
  46 + public String baseURL;
47 47 @Value("${tuohua.bsth.login.rest.password}")
48 48 private String restPassword;
49 49  
... ... @@ -138,15 +138,12 @@ public class TuohuaConfigBean {
138 138 return null;
139 139 }
140 140 return (List<HashMap>) JSON.parseArray(postEntity.getResultStr(), HashMap.class);
141   -
142 141 }
143 142  
144 143 public List<HashMap<String, Object>> requestOfLineAndCarAndCombationTree(HttpClientUtil httpClientUtil, String companyId) throws Exception {
145 144 String lineJson = requestLine(httpClientUtil, companyId);
146 145 String carJson = requestCars(httpClientUtil, companyId);
147 146 // String carJson = redisTemplate.opsForValue().get("test:car").toString();
148   -
149   -
150 147 List<HashMap> linesJsonList = null;
151 148 int linesSize = 0;
152 149 if (StringUtils.isNoneBlank(lineJson)) {
... ... @@ -179,15 +176,12 @@ public class TuohuaConfigBean {
179 176 ch.put("used", "1");
180 177 return combatioinCarTree(ch,gpsList);
181 178 }).collect(Collectors.toList());
182   -
183 179 map.put("children", carList);
184 180 }
185   -
186 181 return map;
187 182 }).collect(Collectors.toList());
188 183 returnData.addAll(lines);
189 184 }
190   -
191 185 if (carsSize > 0) {
192 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 187 returnData.addAll(cars);
... ... @@ -242,7 +236,12 @@ public class TuohuaConfigBean {
242 236 return result;
243 237 }
244 238  
245   -
  239 + /**
  240 + * 修改测试号
  241 + * @param ch
  242 + * @param gpsList
  243 + * @return
  244 + */
246 245 private HashMap<String, Object> combatioinCarTree(HashMap ch, List<HashMap> gpsList) {
247 246 String code = convertStr(ch.get("nbbm"));
248 247 String sim = convertStr(ch.get("sim"));
... ... @@ -268,9 +267,9 @@ public class TuohuaConfigBean {
268 267 hashMap.put("sim", formatSim(convertStr(ch.get("sim"))));
269 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 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 86 URIBuilder uriBuilder = new URIBuilder(url);
87 87 URI uri = uriBuilder.build();
88 88  
89   - // 创建http GET请求
  89 + // 创建http POST请求
90 90 HttpPost httpPost = new HttpPost(uri);
91 91 StringEntity stringEntity = new StringEntity(requestBody, "UTF-8");
92 92 stringEntity.setContentType("application/json");
... ... @@ -194,7 +194,15 @@ public class HttpClientUtil {
194 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 206 @NotNull
199 207 private static HttpClientPostEntity combationReturnObj(CloseableHttpResponse response, DefaultHttpClient httpclient,String url,String requestBody) throws IOException {
200 208 HttpEntity httpEntity = response.getEntity();
... ... @@ -205,7 +213,7 @@ public class HttpClientUtil {
205 213 HttpClientPostEntity postEntity = new HttpClientPostEntity();
206 214 postEntity.setCookieStore(cookieStore);
207 215 postEntity.setResultStr(result);
208   - log.info("url:{};requestBody:{};response data:{}",url,requestBody,result);
  216 + log.info("url:{};requestBody:{};response :{}",url,requestBody,"请求成功");
209 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 1 package com.genersoft.iot.vmp.vmanager.streamProxy;
2 2  
3 3 import com.alibaba.fastjson2.JSONObject;
  4 +import com.genersoft.iot.vmp.common.GeneralCallback;
4 5 import com.genersoft.iot.vmp.common.StreamInfo;
5 6 import com.genersoft.iot.vmp.conf.UserSetting;
6 7 import com.genersoft.iot.vmp.conf.exception.ControllerException;
... ... @@ -104,19 +105,17 @@ public class StreamProxyController {
104 105 if (ObjectUtils.isEmpty(param.getGbId())) {
105 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 110 RequestMessage requestMessage = new RequestMessage();
113 111 String key = DeferredResultHolder.CALLBACK_CMD_PROXY + param.getApp() + param.getStream();
114 112 requestMessage.setKey(key);
115 113 String uuid = UUID.randomUUID().toString();
116 114 requestMessage.setId(uuid);
117   - DeferredResult<Object> result = new DeferredResult<>(userSetting.getPlayTimeout().longValue());
  115 +
118 116 // 录像查询以channelId作为deviceId查询
119 117 resultHolder.put(key, uuid, result);
  118 +
120 119 result.onTimeout(()->{
121 120 WVPResult<StreamInfo> wvpResult = new WVPResult<>();
122 121 wvpResult.setCode(ErrorCode.ERROR100.getCode());
... ... @@ -127,21 +126,22 @@ public class StreamProxyController {
127 126  
128 127 streamProxyService.save(param, (code, msg, streamInfo) -> {
129 128 String stream = null;
130   - if(Objects.nonNull(streamInfo)){
  129 + if (Objects.nonNull(streamInfo)) {
131 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 133 if (code == ErrorCode.SUCCESS.getCode()) {
135 134 requestMessage.setData(new StreamContent(streamInfo));
136   - }else {
  135 + } else {
137 136 requestMessage.setData(WVPResult.fail(code, msg));
138 137 }
139 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 147 return result;
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/streamPush/StreamPushController.java
... ... @@ -30,10 +30,14 @@ import org.springframework.http.HttpStatus;
30 30 import org.springframework.http.ResponseEntity;
31 31 import org.springframework.stereotype.Controller;
32 32 import org.springframework.util.ObjectUtils;
  33 +import org.springframework.util.StringUtils;
33 34 import org.springframework.web.bind.annotation.*;
34 35 import org.springframework.web.context.request.async.DeferredResult;
35 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 41 import java.io.IOException;
38 42 import java.io.InputStream;
39 43 import java.util.HashMap;
... ... @@ -41,9 +45,10 @@ import java.util.List;
41 45 import java.util.Map;
42 46 import java.util.UUID;
43 47  
  48 +import static com.genersoft.iot.vmp.conf.security.IpWhitelistFilter.verifyIpAndPath;
  49 +
44 50 @Tag(name = "推流信息管理")
45 51 @Controller
46   -
47 52 @RequestMapping(value = "/api/push")
48 53 public class StreamPushController {
49 54  
... ... @@ -64,6 +69,9 @@ public class StreamPushController {
64 69 @Autowired
65 70 private UserSetting userSetting;
66 71  
  72 + @Resource
  73 + private HttpServletRequest request;
  74 +
67 75 @GetMapping(value = "/list")
68 76 @ResponseBody
69 77 @Operation(summary = "推流列表查询", security = @SecurityRequirement(name = JwtUtils.HEADER))
... ... @@ -88,6 +96,18 @@ public class StreamPushController {
88 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 111 @PostMapping(value = "/save_to_gb")
92 112 @ResponseBody
93 113 @Operation(summary = "将推流添加到国标", security = @SecurityRequirement(name = JwtUtils.HEADER))
... ... @@ -241,9 +261,17 @@ public class StreamPushController {
241 261 @RequestParam(required = false) String mediaServerId){
242 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 276 StreamPushItem push = streamPushService.getPush(app, stream);
249 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 91 logger.debug(String.format("模拟接口> 登录 API调用,username:%s ,password:%s ",
92 92 username, password));
93 93 }
94   -
95 94 JSONObject result = new JSONObject();
96 95 result.put("CookieToken","ynBDDiKMg");
97 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 2 server.http.port = 3333
  3 +server.history.port = 30001
3 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 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 16 # [必须修改] Redis服务器IP, REDIS安装在本机的,使用127.0.0.1
17 17 host: 192.168.169.100
18 18 # [必须修改] 端口号
19   - port: 6379
  19 + port: 6879
20 20 # [可选] 数据库 DB
21 21 database: 7
22 22 # [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接
23   -# password: luna
  23 + password: wvp4@444
24 24 # [可选] 超时时间
25 25 timeout: 10000
26 26 # mysql数据源
... ... @@ -31,7 +31,7 @@ spring:
31 31 master:
32 32 type: com.zaxxer.hikari.HikariDataSource
33 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 35 username: root
36 36 password: guzijian
37 37 hikari:
... ... @@ -43,7 +43,7 @@ spring:
43 43 max-lifetime: 1200000 # 是池中连接关闭后的最长生命周期(以毫秒为单位)
44 44 #[可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口
45 45 server:
46   - port: 18089
  46 + port: 18989
47 47 # [可选] HTTPS配置, 默认不开启
48 48 ssl:
49 49 # [可选] 是否开启HTTPS访问
... ... @@ -63,7 +63,7 @@ sip:
63 63 # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。
64 64 ip: 192.168.169.100
65 65 # [可选] 28181服务监听的端口
66   - port: 6060
  66 + port: 28083
67 67 # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007)
68 68 # 后两位为行业编码,定义参照附录D.3
69 69 # 3701020049标识山东济南历下区 信息行业接入
... ... @@ -78,11 +78,11 @@ sip:
78 78  
79 79 #zlm 默认服务器配置
80 80 media:
81   - id: guzijian
  81 + id: guzijian1
82 82 # [必须修改] zlm服务器的内网IP
83 83 ip: 192.168.169.100
84 84 # [必须修改] zlm服务器的http.port
85   - http-port: 1090
  85 + http-port: 1909
86 86 # [可选] 返回流地址时的ip,置空使用 media.ip 1
87 87 stream-ip: 61.169.120.202
88 88 # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip 1
... ... @@ -90,17 +90,18 @@ media:
90 90 # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip
91 91 hook-ip: 192.168.169.100
92 92 # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置
93   - http-ssl-port: 8443
  93 + http-ssl-port: 2939
94 94 # [可选] zlm服务器的hook.admin_params=secret
95   - secret: RPorcBlIw26uHGnEHYGesIYyFDXpgjkP
  95 + secret: 8KMYsD5ItKkHN1CIcPI9VeLa6u4S8deU
  96 + pushKey: 41db35390ddad33f83944f44b8b75ded
96 97 # 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试
97 98 rtp:
98 99 # [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输
99 100 enable: true
100 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 105 # 录像辅助服务, 部署此服务可以实现zlm录像的管理与下载, 0 表示不使用
105 106 record-assist-port: 18081
106 107 # [根据业务需求配置]
... ... @@ -112,7 +113,49 @@ user-settings:
112 113 # 设备/通道状态变化时发送消息
113 114 device-status-notify: true
114 115 # [可选] 日志配置, 一般不需要改
115   -
  116 +jt1078:
  117 + enable: true
  118 + port: 1079
116 119 logging:
117 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 15 # [必须修改] Redis服务器IP, REDIS安装在本机的,使用127.0.0.1
16 16 host: 127.0.0.1
17 17 # [必须修改] 端口号
18   - port: 6379
  18 + port: 6879
19 19 # [可选] 数据库 DB
20 20 database: 8
21 21 # [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接
22   - # password: guzijian
  22 + password: wvp4@444
23 23 # [可选] 超时时间
24 24 timeout: 10000
25 25 # mysql数据源
... ... @@ -30,7 +30,7 @@ spring:
30 30 master:
31 31 type: com.zaxxer.hikari.HikariDataSource
32 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 34 username: root
35 35 password: guzijian
36 36 hikari:
... ... @@ -42,7 +42,7 @@ spring:
42 42 max-lifetime: 1200000 # 是池中连接关闭后的最长生命周期(以毫秒为单位)
43 43 #[可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口
44 44 server:
45   - port: 28080
  45 + port: 16030
46 46 # [可选] HTTPS配置, 默认不开启
47 47 ssl:
48 48 # [可选] 是否开启HTTPS访问
... ... @@ -60,9 +60,9 @@ sip:
60 60 # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4
61 61 # 如果不明白,就使用0.0.0.0,大部分情况都是可以的
62 62 # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。
63   - ip: 0.0.0.0
  63 + ip: 192.168.169.100
64 64 # [可选] 28181服务监听的端口
65   - port: 5060
  65 + port: 16030
66 66  
67 67 # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007)
68 68 # 后两位为行业编码,定义参照附录D.3
... ... @@ -82,7 +82,7 @@ media:
82 82 # [必须修改] zlm服务器的内网IP
83 83 ip: 192.168.169.100
84 84 # [必须修改] zlm服务器的http.port
85   - http-port: 1091
  85 + http-port: 1909
86 86 # [可选] 返回流地址时的ip,置空使用 media.ip
87 87 stream-ip: 192.168.169.100
88 88 # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip
... ... @@ -90,17 +90,17 @@ media:
90 90 # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip
91 91 hook-ip: 192.168.169.100
92 92 # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置
93   - http-ssl-port: 443
  93 + http-ssl-port: 8444
94 94 # [可选] zlm服务器的hook.admin_params=secret
95   - secret: RPorcBlIw26uHGnEHYGesIYyFDXpgjkP1
  95 + secret: 8KMYsD5ItKkHN1CIcPI9VeLa6u4S8deU
96 96 # 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试
97 97 rtp:
98 98 # [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输
99 99 enable: true
100 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 104 # 录像辅助服务, 部署此服务可以实现zlm录像的管理与下载, 0 表示不使用
105 105 record-assist-port: 18081
106 106 # [根据业务需求配置]
... ... @@ -154,19 +154,19 @@ tuohua:
154 154 jt1078:
155 155 ports: 9000,9500
156 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 159 url: http://192.168.168.241:8100/device/{0}
160 160 historyListPort: 9205
161 161 playHistoryPort: 9201
162 162 sendPort: 9101
163 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 167 get:
168 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 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 134 userName: yuanxiaohu
135 135 password: Yxiaohu1.0
136 136 rest:
137   - baseURL: http://10.10.2.20:9089/webservice/rest
  137 + baseURL: http://192.168.168.152:9089/webservice/rest
138 138 password: bafb2b44a07a02e5e9912f42cd197423884116a8
139 139 tree:
140 140 url:
... ...
src/main/resources/application.yml
... ... @@ -2,6 +2,9 @@ spring:
2 2 application:
3 3 name: wvp
4 4 profiles:
5   - active: local
  5 + active: wx-local
6 6 server:
7   - port: 18080
8 7 \ No newline at end of file
  8 + port: 16030
  9 +
  10 +test:
  11 + port: 30020
... ...