Commit 5077713ed944a02a971c941bb1827fa45de454b0
1 parent
d76da120
修改
Showing
58 changed files
with
260 additions
and
4298 deletions
Too many changes to show.
To preserve performance only 58 of 150 files are displayed.
pom.xml
| ... | ... | @@ -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> <!– 复制配置文件 –>--> | |
| 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> <!– 复制配置文件 –>--> | |
| 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 | -} |