Commit b4048fbe80dba8e7756ae557a15ab60b4f80a44b
合并开源主线
Showing
165 changed files
with
3011 additions
and
1000 deletions
README.md
| @@ -99,15 +99,16 @@ https://gitee.com/pan648540858/wvp-GB28181-pro.git | @@ -99,15 +99,16 @@ https://gitee.com/pan648540858/wvp-GB28181-pro.git | ||
| 99 | - [X] 支持接口鉴权 | 99 | - [X] 支持接口鉴权 |
| 100 | - [X] 云端录像,推流/代理/国标视频均可以录制在云端服务器,支持预览和下载 | 100 | - [X] 云端录像,推流/代理/国标视频均可以录制在云端服务器,支持预览和下载 |
| 101 | - [X] 支持打包可执行jar和war | 101 | - [X] 支持打包可执行jar和war |
| 102 | +- [X] 支持跨域请求,支持前后端分离部署 | ||
| 102 | 103 | ||
| 103 | 104 | ||
| 104 | # 遇到问题如何解决 | 105 | # 遇到问题如何解决 |
| 105 | 国标最麻烦的地方在于设备的兼容性,所以需要大量的设备来测试,目前作者手里的设备有限,再加上作者水平有限,所以遇到问题在所难免; | 106 | 国标最麻烦的地方在于设备的兼容性,所以需要大量的设备来测试,目前作者手里的设备有限,再加上作者水平有限,所以遇到问题在所难免; |
| 106 | -1. 查看wiki,仔细的阅读可以帮你避免几乎所有的问题 | 107 | +1. 查看文档网站,仔细的阅读可以帮你避免几乎所有的问题 |
| 107 | 2. 搜索issues,这里有大部分的答案 | 108 | 2. 搜索issues,这里有大部分的答案 |
| 108 | 3. 加QQ群(901799015),这里有大量热心的小伙伴,但是前提新希望你已经仔细阅读了wiki和搜索了issues。 | 109 | 3. 加QQ群(901799015),这里有大量热心的小伙伴,但是前提新希望你已经仔细阅读了wiki和搜索了issues。 |
| 109 | 4. 你可以请作者为你解答,但是我不是免费的。 | 110 | 4. 你可以请作者为你解答,但是我不是免费的。 |
| 110 | -5. 你可以把遇到问题的设备寄给我,可以更容易的复现问题。 | 111 | +5. 你可以把遇到问题的设备寄给我,可以更容易的兼容设备和解决问题。 |
| 111 | 112 | ||
| 112 | # 使用帮助 | 113 | # 使用帮助 |
| 113 | QQ群: 901799015, ZLM使用文档[https://github.com/ZLMediaKit/ZLMediaKit](https://github.com/ZLMediaKit/ZLMediaKit) | 114 | QQ群: 901799015, ZLM使用文档[https://github.com/ZLMediaKit/ZLMediaKit](https://github.com/ZLMediaKit/ZLMediaKit) |
doc/_content/ability/gis.md
| @@ -14,7 +14,7 @@ WVP提供了简单的电子地图用于设备的定位以及移动设备的轨 | @@ -14,7 +14,7 @@ WVP提供了简单的电子地图用于设备的定位以及移动设备的轨 | ||
| 14 | PS: 目前的底图仅用用作演示和学习,商用情况请自行购买授权使用。 | 14 | PS: 目前的底图仅用用作演示和学习,商用情况请自行购买授权使用。 |
| 15 | 15 | ||
| 16 | ### 更换底图以及底图配置 | 16 | ### 更换底图以及底图配置 |
| 17 | -目前WVP支持使用了更换底图,配置文件在web_src/static/js/mapConfig.js,请修改后重新编译前端文件。 | 17 | +目前WVP支持使用了更换底图,配置文件在web_src/static/js/config.js,请修改后重新编译前端文件。 |
| 18 | ```javascript | 18 | ```javascript |
| 19 | window.mapParam = { | 19 | window.mapParam = { |
| 20 | // 开启/关闭地图功能 | 20 | // 开启/关闭地图功能 |
doc/_content/introduction/deployment.md
| @@ -27,13 +27,32 @@ | @@ -27,13 +27,32 @@ | ||
| 27 | ```shell | 27 | ```shell |
| 28 | nohup java -jar wvp-pro-*.jar & | 28 | nohup java -jar wvp-pro-*.jar & |
| 29 | ``` | 29 | ``` |
| 30 | -war包: | 30 | +**war包:** |
| 31 | 下载Tomcat后将war包放入webapps中,启动Tomcat以解压war包,停止Tomcat后,删除ROOT目录以及war包,将解压后的war包目录重命名为ROOT,将配置文件中的Server.port配置为与Tomcat端口一致 | 31 | 下载Tomcat后将war包放入webapps中,启动Tomcat以解压war包,停止Tomcat后,删除ROOT目录以及war包,将解压后的war包目录重命名为ROOT,将配置文件中的Server.port配置为与Tomcat端口一致 |
| 32 | 然后启动Tomcat。 | 32 | 然后启动Tomcat。 |
| 33 | **启动ZLM** | 33 | **启动ZLM** |
| 34 | ```shell | 34 | ```shell |
| 35 | nohup ./MediaServer -d -m 3 & | 35 | nohup ./MediaServer -d -m 3 & |
| 36 | ``` | 36 | ``` |
| 37 | - | 37 | +### 前后端分离部署 |
| 38 | +前后端部署目前在最新的版本已经支持,请使用3月15日之后的版本部署 | ||
| 39 | +前端编译后的文件在`src/main/resources/static`中,将此目录下的文件部署。 | ||
| 40 | +前后端分离部署最大的问题是跨域的解决,之前版本使用cookie完成登录流程,而cookie是不可以在复杂跨域中使用的。所以当前版本使用JWT生成的TOKEN作为认证凭据, | ||
| 41 | +部署前端后需要在wvp中配置前端访问的地址以完成跨域流程。 | ||
| 42 | +**配置前端服务器** | ||
| 43 | +1. 假如你的服务有公网域名为xxx.com,公网IP为11.11.11.11, 那么你可以在wvp中这样配置: | ||
| 44 | +```yaml | ||
| 45 | +user-settings: | ||
| 46 | + # 跨域配置,配置你访问前端页面的地址即可, 可以配置多个 | ||
| 47 | + allowed-origins: | ||
| 48 | + - http://xxx.com:8008 | ||
| 49 | + - http://11.11.11.11:8008 | ||
| 50 | +``` | ||
| 51 | +配置不是必须的,你使用哪个ip/域名访问就配置哪个即可。修改配置后重启wvp以使配置生效。 | ||
| 52 | +2. 在`src/main/resources/static/static/js/config.js`下配置服务器的地址,也就是wvp服务的地址 | ||
| 53 | +```javascript | ||
| 54 | +window.baseUrl = "http://xxx.com:18080" | ||
| 55 | +``` | ||
| 56 | +`这里的地址是需要客户电脑能访问到的,因为请求是客户端电脑发起,与代理不同` | ||
| 38 | [接入设备](./_content/ability/device.md) | 57 | [接入设备](./_content/ability/device.md) |
| 39 | 58 |
pom.xml
| @@ -11,7 +11,7 @@ | @@ -11,7 +11,7 @@ | ||
| 11 | 11 | ||
| 12 | <groupId>com.genersoft</groupId> | 12 | <groupId>com.genersoft</groupId> |
| 13 | <artifactId>wvp-pro</artifactId> | 13 | <artifactId>wvp-pro</artifactId> |
| 14 | - <version>2.6.7</version> | 14 | + <version>2.6.8</version> |
| 15 | <name>web video platform</name> | 15 | <name>web video platform</name> |
| 16 | <description>国标28181视频平台</description> | 16 | <description>国标28181视频平台</description> |
| 17 | <packaging>${project.packaging}</packaging> | 17 | <packaging>${project.packaging}</packaging> |
| @@ -123,11 +123,9 @@ | @@ -123,11 +123,9 @@ | ||
| 123 | <artifactId>spring-boot-starter-security</artifactId> | 123 | <artifactId>spring-boot-starter-security</artifactId> |
| 124 | </dependency> | 124 | </dependency> |
| 125 | 125 | ||
| 126 | - <!-- druid数据库连接池 --> | ||
| 127 | <dependency> | 126 | <dependency> |
| 128 | - <groupId>com.alibaba</groupId> | ||
| 129 | - <artifactId>druid-spring-boot-starter</artifactId> | ||
| 130 | - <version>1.2.11</version> | 127 | + <groupId>org.springframework.boot</groupId> |
| 128 | + <artifactId>spring-boot-starter-jdbc</artifactId> | ||
| 131 | </dependency> | 129 | </dependency> |
| 132 | 130 | ||
| 133 | <!-- mysql数据库 --> | 131 | <!-- mysql数据库 --> |
| @@ -216,8 +214,6 @@ | @@ -216,8 +214,6 @@ | ||
| 216 | <version>4.10.0</version> | 214 | <version>4.10.0</version> |
| 217 | </dependency> | 215 | </dependency> |
| 218 | 216 | ||
| 219 | - | ||
| 220 | - | ||
| 221 | <!-- okhttp-digest --> | 217 | <!-- okhttp-digest --> |
| 222 | <dependency> | 218 | <dependency> |
| 223 | <groupId>io.github.rburgst</groupId> | 219 | <groupId>io.github.rburgst</groupId> |
| @@ -226,10 +222,17 @@ | @@ -226,10 +222,17 @@ | ||
| 226 | </dependency> | 222 | </dependency> |
| 227 | 223 | ||
| 228 | <!-- https://mvnrepository.com/artifact/net.sf.kxml/kxml2 --> | 224 | <!-- https://mvnrepository.com/artifact/net.sf.kxml/kxml2 --> |
| 225 | +<!-- <dependency>--> | ||
| 226 | +<!-- <groupId>net.sf.kxml</groupId>--> | ||
| 227 | +<!-- <artifactId>kxml2</artifactId>--> | ||
| 228 | +<!-- <version>2.3.0</version>--> | ||
| 229 | +<!-- </dependency>--> | ||
| 230 | + | ||
| 231 | + <!-- jwt实现 --> | ||
| 229 | <dependency> | 232 | <dependency> |
| 230 | - <groupId>net.sf.kxml</groupId> | ||
| 231 | - <artifactId>kxml2</artifactId> | ||
| 232 | - <version>2.3.0</version> | 233 | + <groupId>org.bitbucket.b_c</groupId> |
| 234 | + <artifactId>jose4j</artifactId> | ||
| 235 | + <version>0.9.3</version> | ||
| 233 | </dependency> | 236 | </dependency> |
| 234 | 237 | ||
| 235 | <!--反向代理--> | 238 | <!--反向代理--> |
| @@ -289,7 +292,7 @@ | @@ -289,7 +292,7 @@ | ||
| 289 | <plugin> | 292 | <plugin> |
| 290 | <groupId>org.springframework.boot</groupId> | 293 | <groupId>org.springframework.boot</groupId> |
| 291 | <artifactId>spring-boot-maven-plugin</artifactId> | 294 | <artifactId>spring-boot-maven-plugin</artifactId> |
| 292 | - <version>2.3.5.RELEASE</version> | 295 | + <version>2.7.2</version> |
| 293 | <configuration> | 296 | <configuration> |
| 294 | <includeSystemScope>true</includeSystemScope> | 297 | <includeSystemScope>true</includeSystemScope> |
| 295 | </configuration> | 298 | </configuration> |
sql/2.6.6-2.6.7更新.sql
0 → 100755
src/main/resources/db/migration/V2.6.7_20230201__初始化.sql renamed to sql/初始化.sql
| @@ -32,6 +32,7 @@ CREATE TABLE `device` ( | @@ -32,6 +32,7 @@ CREATE TABLE `device` ( | ||
| 32 | `transport` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | 32 | `transport` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, |
| 33 | `streamMode` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | 33 | `streamMode` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, |
| 34 | `online` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | 34 | `online` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, |
| 35 | + `mediaServerId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | ||
| 35 | `registerTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | 36 | `registerTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, |
| 36 | `keepaliveTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | 37 | `keepaliveTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, |
| 37 | `ip` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | 38 | `ip` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, |
| @@ -47,6 +48,7 @@ CREATE TABLE `device` ( | @@ -47,6 +48,7 @@ CREATE TABLE `device` ( | ||
| 47 | `mobilePositionSubmissionInterval` int DEFAULT '5', | 48 | `mobilePositionSubmissionInterval` int DEFAULT '5', |
| 48 | `subscribeCycleForAlarm` int DEFAULT NULL, | 49 | `subscribeCycleForAlarm` int DEFAULT NULL, |
| 49 | `ssrcCheck` int DEFAULT '0', | 50 | `ssrcCheck` int DEFAULT '0', |
| 51 | + `asMessageChannel` int DEFAULT '0', | ||
| 50 | `geoCoordSys` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | 52 | `geoCoordSys` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, |
| 51 | `treeType` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | 53 | `treeType` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, |
| 52 | `custom_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | 54 | `custom_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, |
| @@ -329,6 +331,7 @@ CREATE TABLE `parent_platform` ( | @@ -329,6 +331,7 @@ CREATE TABLE `parent_platform` ( | ||
| 329 | `catalogId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | 331 | `catalogId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, |
| 330 | `ptz` int DEFAULT NULL, | 332 | `ptz` int DEFAULT NULL, |
| 331 | `rtcp` int DEFAULT NULL, | 333 | `rtcp` int DEFAULT NULL, |
| 334 | + `asMessageChannel` int DEFAULT '0', | ||
| 332 | `status` bit(1) DEFAULT NULL, | 335 | `status` bit(1) DEFAULT NULL, |
| 333 | `startOfflinePush` int DEFAULT '0', | 336 | `startOfflinePush` int DEFAULT '0', |
| 334 | `administrativeDivision` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | 337 | `administrativeDivision` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, |
src/main/java/com/genersoft/iot/vmp/VManageBootstrap.java
| 1 | package com.genersoft.iot.vmp; | 1 | package com.genersoft.iot.vmp; |
| 2 | 2 | ||
| 3 | -import com.genersoft.iot.vmp.conf.druid.EnableDruidSupport; | ||
| 4 | import com.genersoft.iot.vmp.utils.GitUtil; | 3 | import com.genersoft.iot.vmp.utils.GitUtil; |
| 5 | import com.genersoft.iot.vmp.utils.SpringBeanFactory; | 4 | import com.genersoft.iot.vmp.utils.SpringBeanFactory; |
| 6 | import org.slf4j.Logger; | 5 | import org.slf4j.Logger; |
| @@ -25,7 +24,6 @@ import java.util.Collections; | @@ -25,7 +24,6 @@ import java.util.Collections; | ||
| 25 | @ServletComponentScan("com.genersoft.iot.vmp.conf") | 24 | @ServletComponentScan("com.genersoft.iot.vmp.conf") |
| 26 | @SpringBootApplication | 25 | @SpringBootApplication |
| 27 | @EnableScheduling | 26 | @EnableScheduling |
| 28 | -@EnableDruidSupport | ||
| 29 | public class VManageBootstrap extends SpringBootServletInitializer { | 27 | public class VManageBootstrap extends SpringBootServletInitializer { |
| 30 | 28 | ||
| 31 | private final static Logger logger = LoggerFactory.getLogger(VManageBootstrap.class); | 29 | private final static Logger logger = LoggerFactory.getLogger(VManageBootstrap.class); |
src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java
| @@ -3,6 +3,7 @@ package com.genersoft.iot.vmp.common; | @@ -3,6 +3,7 @@ package com.genersoft.iot.vmp.common; | ||
| 3 | import io.swagger.v3.oas.annotations.media.Schema; | 3 | import io.swagger.v3.oas.annotations.media.Schema; |
| 4 | 4 | ||
| 5 | import java.io.Serializable; | 5 | import java.io.Serializable; |
| 6 | +import java.util.Objects; | ||
| 6 | 7 | ||
| 7 | @Schema(description = "流信息") | 8 | @Schema(description = "流信息") |
| 8 | public class StreamInfo implements Serializable, Cloneable{ | 9 | public class StreamInfo implements Serializable, Cloneable{ |
| @@ -168,7 +169,7 @@ public class StreamInfo implements Serializable, Cloneable{ | @@ -168,7 +169,7 @@ public class StreamInfo implements Serializable, Cloneable{ | ||
| 168 | } | 169 | } |
| 169 | 170 | ||
| 170 | public void setRtmp(String host, int port, int sslPort, String app, String stream, String callIdParam) { | 171 | public void setRtmp(String host, int port, int sslPort, String app, String stream, String callIdParam) { |
| 171 | - String file = String.format("%s/%s/%s", app, stream, callIdParam); | 172 | + String file = String.format("%s/%s%s", app, stream, callIdParam); |
| 172 | if (port > 0) { | 173 | if (port > 0) { |
| 173 | this.rtmp = new StreamURL("rtmp", host, port, file); | 174 | this.rtmp = new StreamURL("rtmp", host, port, file); |
| 174 | } | 175 | } |
| @@ -178,7 +179,7 @@ public class StreamInfo implements Serializable, Cloneable{ | @@ -178,7 +179,7 @@ public class StreamInfo implements Serializable, Cloneable{ | ||
| 178 | } | 179 | } |
| 179 | 180 | ||
| 180 | public void setRtsp(String host, int port, int sslPort, String app, String stream, String callIdParam) { | 181 | public void setRtsp(String host, int port, int sslPort, String app, String stream, String callIdParam) { |
| 181 | - String file = String.format("%s/%s/%s", app, stream, callIdParam); | 182 | + String file = String.format("%s/%s%s", app, stream, callIdParam); |
| 182 | if (port > 0) { | 183 | if (port > 0) { |
| 183 | this.rtsp = new StreamURL("rtsp", host, port, file); | 184 | this.rtsp = new StreamURL("rtsp", host, port, file); |
| 184 | } | 185 | } |
| @@ -236,8 +237,11 @@ public class StreamInfo implements Serializable, Cloneable{ | @@ -236,8 +237,11 @@ public class StreamInfo implements Serializable, Cloneable{ | ||
| 236 | } | 237 | } |
| 237 | } | 238 | } |
| 238 | 239 | ||
| 239 | - public void setRtc(String host, int port, int sslPort, String app, String stream, String callIdParam, boolean isPlay) { | ||
| 240 | - String file = String.format("index/api/webrtc?app=%s&stream=%s&type=%s%s", app, stream, isPlay?"play":"push", callIdParam); | 240 | + public void setRtc(String host, int port, int sslPort, String app, String stream, String callIdParam) { |
| 241 | + if (callIdParam != null) { | ||
| 242 | + callIdParam = Objects.equals(callIdParam, "") ? callIdParam : callIdParam.replace("?", "&"); | ||
| 243 | + } | ||
| 244 | + String file = String.format("index/api/webrtc?app=%s&stream=%s&type=play%s", app, stream, callIdParam); | ||
| 241 | if (port > 0) { | 245 | if (port > 0) { |
| 242 | this.rtc = new StreamURL("http", host, port, file); | 246 | this.rtc = new StreamURL("http", host, port, file); |
| 243 | } | 247 | } |
src/main/java/com/genersoft/iot/vmp/conf/ApiAccessFilter.java
| @@ -66,9 +66,7 @@ public class ApiAccessFilter extends OncePerRequestFilter { | @@ -66,9 +66,7 @@ public class ApiAccessFilter extends OncePerRequestFilter { | ||
| 66 | logDto.setUri(servletRequest.getRequestURI()); | 66 | logDto.setUri(servletRequest.getRequestURI()); |
| 67 | logDto.setCreateTime(DateUtil.getNow()); | 67 | logDto.setCreateTime(DateUtil.getNow()); |
| 68 | logService.add(logDto); | 68 | logService.add(logDto); |
| 69 | -// logger.warn("[Api Access] [{}] [{}] [{}] [{}] [{}] {}ms", | ||
| 70 | -// uriName, servletRequest.getMethod(), servletRequest.getRequestURI(), servletRequest.getRemoteAddr(), HttpStatus.valueOf(servletResponse.getStatus()), | ||
| 71 | -// System.currentTimeMillis() - start); | 69 | + |
| 72 | 70 | ||
| 73 | } | 71 | } |
| 74 | } | 72 | } |
src/main/java/com/genersoft/iot/vmp/conf/GlobalExceptionHandler.java
| @@ -8,6 +8,7 @@ import org.slf4j.LoggerFactory; | @@ -8,6 +8,7 @@ import org.slf4j.LoggerFactory; | ||
| 8 | import org.springframework.http.HttpStatus; | 8 | import org.springframework.http.HttpStatus; |
| 9 | import org.springframework.http.ResponseEntity; | 9 | import org.springframework.http.ResponseEntity; |
| 10 | import org.springframework.security.authentication.BadCredentialsException; | 10 | import org.springframework.security.authentication.BadCredentialsException; |
| 11 | +import org.springframework.web.HttpRequestMethodNotSupportedException; | ||
| 11 | import org.springframework.web.bind.annotation.ExceptionHandler; | 12 | import org.springframework.web.bind.annotation.ExceptionHandler; |
| 12 | import org.springframework.web.bind.annotation.ResponseStatus; | 13 | import org.springframework.web.bind.annotation.ResponseStatus; |
| 13 | import org.springframework.web.bind.annotation.RestControllerAdvice; | 14 | import org.springframework.web.bind.annotation.RestControllerAdvice; |
| @@ -32,6 +33,28 @@ public class GlobalExceptionHandler { | @@ -32,6 +33,28 @@ public class GlobalExceptionHandler { | ||
| 32 | return WVPResult.fail(ErrorCode.ERROR500.getCode(), e.getMessage()); | 33 | return WVPResult.fail(ErrorCode.ERROR500.getCode(), e.getMessage()); |
| 33 | } | 34 | } |
| 34 | 35 | ||
| 36 | + /** | ||
| 37 | + * 默认异常处理 | ||
| 38 | + * @param e 异常 | ||
| 39 | + * @return 统一返回结果 | ||
| 40 | + */ | ||
| 41 | + @ExceptionHandler(IllegalStateException.class) | ||
| 42 | + @ResponseStatus(HttpStatus.BAD_REQUEST) | ||
| 43 | + public WVPResult<String> exceptionHandler(IllegalStateException e) { | ||
| 44 | + return WVPResult.fail(ErrorCode.ERROR400); | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + /** | ||
| 48 | + * 默认异常处理 | ||
| 49 | + * @param e 异常 | ||
| 50 | + * @return 统一返回结果 | ||
| 51 | + */ | ||
| 52 | + @ExceptionHandler(HttpRequestMethodNotSupportedException.class) | ||
| 53 | + @ResponseStatus(HttpStatus.BAD_REQUEST) | ||
| 54 | + public WVPResult<String> exceptionHandler(HttpRequestMethodNotSupportedException e) { | ||
| 55 | + return WVPResult.fail(ErrorCode.ERROR400); | ||
| 56 | + } | ||
| 57 | + | ||
| 35 | 58 | ||
| 36 | /** | 59 | /** |
| 37 | * 自定义异常处理, 处理controller中返回的错误 | 60 | * 自定义异常处理, 处理controller中返回的错误 |
src/main/java/com/genersoft/iot/vmp/conf/GlobalResponseAdvice.java
| @@ -10,14 +10,11 @@ import org.springframework.context.annotation.Bean; | @@ -10,14 +10,11 @@ import org.springframework.context.annotation.Bean; | ||
| 10 | import org.springframework.core.MethodParameter; | 10 | import org.springframework.core.MethodParameter; |
| 11 | import org.springframework.http.MediaType; | 11 | import org.springframework.http.MediaType; |
| 12 | import org.springframework.http.converter.HttpMessageConverter; | 12 | import org.springframework.http.converter.HttpMessageConverter; |
| 13 | -import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; | ||
| 14 | import org.springframework.http.server.ServerHttpRequest; | 13 | import org.springframework.http.server.ServerHttpRequest; |
| 15 | import org.springframework.http.server.ServerHttpResponse; | 14 | import org.springframework.http.server.ServerHttpResponse; |
| 16 | import org.springframework.web.bind.annotation.RestControllerAdvice; | 15 | import org.springframework.web.bind.annotation.RestControllerAdvice; |
| 17 | import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; | 16 | import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; |
| 18 | 17 | ||
| 19 | -import java.util.List; | ||
| 20 | - | ||
| 21 | /** | 18 | /** |
| 22 | * 全局统一返回结果 | 19 | * 全局统一返回结果 |
| 23 | * @author lin | 20 | * @author lin |
src/main/java/com/genersoft/iot/vmp/conf/ProxyServletConfig.java
| @@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.conf; | @@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.conf; | ||
| 2 | 2 | ||
| 3 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | 3 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 4 | import com.genersoft.iot.vmp.service.IMediaServerService; | 4 | import com.genersoft.iot.vmp.service.IMediaServerService; |
| 5 | +import org.apache.catalina.connector.ClientAbortException; | ||
| 5 | import org.apache.http.HttpHost; | 6 | import org.apache.http.HttpHost; |
| 6 | import org.apache.http.HttpRequest; | 7 | import org.apache.http.HttpRequest; |
| 7 | import org.apache.http.HttpResponse; | 8 | import org.apache.http.HttpResponse; |
| @@ -169,13 +170,14 @@ public class ProxyServletConfig { | @@ -169,13 +170,14 @@ public class ProxyServletConfig { | ||
| 169 | protected String rewriteQueryStringFromRequest(HttpServletRequest servletRequest, String queryString) { | 170 | protected String rewriteQueryStringFromRequest(HttpServletRequest servletRequest, String queryString) { |
| 170 | String queryStr = super.rewriteQueryStringFromRequest(servletRequest, queryString); | 171 | String queryStr = super.rewriteQueryStringFromRequest(servletRequest, queryString); |
| 171 | MediaServerItem mediaInfo = getMediaInfoByUri(servletRequest.getRequestURI()); | 172 | MediaServerItem mediaInfo = getMediaInfoByUri(servletRequest.getRequestURI()); |
| 172 | - String remoteHost = String.format("http://%s:%s", mediaInfo.getIp(), mediaInfo.getHttpPort()); | ||
| 173 | - if (mediaInfo != null) { | ||
| 174 | - if (!ObjectUtils.isEmpty(queryStr)) { | ||
| 175 | - queryStr += "&remoteHost=" + remoteHost; | ||
| 176 | - }else { | ||
| 177 | - queryStr = "remoteHost=" + remoteHost; | ||
| 178 | - } | 173 | + if (mediaInfo == null) { |
| 174 | + return null; | ||
| 175 | + } | ||
| 176 | + String remoteHost = String.format("http://%s:%s", mediaInfo.getStreamIp(), mediaInfo.getRecordAssistPort()); | ||
| 177 | + if (!ObjectUtils.isEmpty(queryStr)) { | ||
| 178 | + queryStr += "&remoteHost=" + remoteHost; | ||
| 179 | + }else { | ||
| 180 | + queryStr = "remoteHost=" + remoteHost; | ||
| 179 | } | 181 | } |
| 180 | return queryStr; | 182 | return queryStr; |
| 181 | } | 183 | } |
| @@ -192,6 +194,12 @@ public class ProxyServletConfig { | @@ -192,6 +194,12 @@ public class ProxyServletConfig { | ||
| 192 | } catch (IOException ioException) { | 194 | } catch (IOException ioException) { |
| 193 | if (ioException instanceof ConnectException) { | 195 | if (ioException instanceof ConnectException) { |
| 194 | logger.error("录像服务 连接失败"); | 196 | logger.error("录像服务 连接失败"); |
| 197 | + }else if (ioException instanceof ClientAbortException) { | ||
| 198 | + /** | ||
| 199 | + * TODO 使用这个代理库实现代理在遇到代理视频文件时,如果是206结果,会遇到报错蛋市目前功能正常, | ||
| 200 | + * TODO 暂时去除异常处理。后续使用其他代理框架修改测试 | ||
| 201 | + */ | ||
| 202 | + | ||
| 195 | }else { | 203 | }else { |
| 196 | logger.error("录像服务 代理失败: ", e); | 204 | logger.error("录像服务 代理失败: ", e); |
| 197 | } | 205 | } |
src/main/java/com/genersoft/iot/vmp/conf/SipConfig.java
| @@ -4,7 +4,6 @@ package com.genersoft.iot.vmp.conf; | @@ -4,7 +4,6 @@ package com.genersoft.iot.vmp.conf; | ||
| 4 | import org.junit.jupiter.api.Order; | 4 | import org.junit.jupiter.api.Order; |
| 5 | import org.springframework.boot.context.properties.ConfigurationProperties; | 5 | import org.springframework.boot.context.properties.ConfigurationProperties; |
| 6 | import org.springframework.stereotype.Component; | 6 | import org.springframework.stereotype.Component; |
| 7 | -import org.springframework.util.ObjectUtils; | ||
| 8 | 7 | ||
| 9 | @Component | 8 | @Component |
| 10 | @ConfigurationProperties(prefix = "sip", ignoreInvalidFields = true) | 9 | @ConfigurationProperties(prefix = "sip", ignoreInvalidFields = true) |
| @@ -13,6 +12,8 @@ public class SipConfig { | @@ -13,6 +12,8 @@ public class SipConfig { | ||
| 13 | 12 | ||
| 14 | private String ip; | 13 | private String ip; |
| 15 | 14 | ||
| 15 | + private String showIp; | ||
| 16 | + | ||
| 16 | private Integer port; | 17 | private Integer port; |
| 17 | 18 | ||
| 18 | private String domain; | 19 | private String domain; |
| @@ -96,4 +97,14 @@ public class SipConfig { | @@ -96,4 +97,14 @@ public class SipConfig { | ||
| 96 | this.alarm = alarm; | 97 | this.alarm = alarm; |
| 97 | } | 98 | } |
| 98 | 99 | ||
| 100 | + public String getShowIp() { | ||
| 101 | + if (this.showIp == null) { | ||
| 102 | + return this.ip; | ||
| 103 | + } | ||
| 104 | + return showIp; | ||
| 105 | + } | ||
| 106 | + | ||
| 107 | + public void setShowIp(String showIp) { | ||
| 108 | + this.showIp = showIp; | ||
| 109 | + } | ||
| 99 | } | 110 | } |
src/main/java/com/genersoft/iot/vmp/conf/SipPlatformRunner.java
| @@ -40,17 +40,20 @@ public class SipPlatformRunner implements CommandLineRunner { | @@ -40,17 +40,20 @@ public class SipPlatformRunner implements CommandLineRunner { | ||
| 40 | List<ParentPlatform> parentPlatforms = storager.queryEnableParentPlatformList(true); | 40 | List<ParentPlatform> parentPlatforms = storager.queryEnableParentPlatformList(true); |
| 41 | 41 | ||
| 42 | for (ParentPlatform parentPlatform : parentPlatforms) { | 42 | for (ParentPlatform parentPlatform : parentPlatforms) { |
| 43 | + | ||
| 44 | + ParentPlatformCatch parentPlatformCatchOld = redisCatchStorage.queryPlatformCatchInfo(parentPlatform.getServerGBId()); | ||
| 45 | + | ||
| 43 | // 更新缓存 | 46 | // 更新缓存 |
| 44 | ParentPlatformCatch parentPlatformCatch = new ParentPlatformCatch(); | 47 | ParentPlatformCatch parentPlatformCatch = new ParentPlatformCatch(); |
| 45 | parentPlatformCatch.setParentPlatform(parentPlatform); | 48 | parentPlatformCatch.setParentPlatform(parentPlatform); |
| 46 | parentPlatformCatch.setId(parentPlatform.getServerGBId()); | 49 | parentPlatformCatch.setId(parentPlatform.getServerGBId()); |
| 47 | redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch); | 50 | redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch); |
| 48 | - // 设置所有平台离线 | ||
| 49 | - platformService.offline(parentPlatform, true); | ||
| 50 | // 取消订阅 | 51 | // 取消订阅 |
| 51 | - sipCommanderForPlatform.unregister(parentPlatform, null, (eventResult)->{ | 52 | + sipCommanderForPlatform.unregister(parentPlatform, parentPlatformCatchOld.getSipTransactionInfo(), null, (eventResult)->{ |
| 52 | platformService.login(parentPlatform); | 53 | platformService.login(parentPlatform); |
| 53 | }); | 54 | }); |
| 55 | + // 设置所有平台离线 | ||
| 56 | + platformService.offline(parentPlatform, true); | ||
| 54 | } | 57 | } |
| 55 | } | 58 | } |
| 56 | } | 59 | } |
src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java
| @@ -50,15 +50,22 @@ public class UserSetting { | @@ -50,15 +50,22 @@ public class UserSetting { | ||
| 50 | private Boolean pushStreamAfterAck = Boolean.FALSE; | 50 | private Boolean pushStreamAfterAck = Boolean.FALSE; |
| 51 | 51 | ||
| 52 | private Boolean sipLog = Boolean.FALSE; | 52 | private Boolean sipLog = Boolean.FALSE; |
| 53 | + private Boolean sendToPlatformsWhenIdLost = Boolean.FALSE; | ||
| 54 | + | ||
| 55 | + private Boolean refuseChannelStatusChannelFormNotify = Boolean.FALSE; | ||
| 53 | 56 | ||
| 54 | private String serverId = "000000"; | 57 | private String serverId = "000000"; |
| 55 | 58 | ||
| 59 | + private String recordPath = null; | ||
| 60 | + | ||
| 56 | private String thirdPartyGBIdReg = "[\\s\\S]*"; | 61 | private String thirdPartyGBIdReg = "[\\s\\S]*"; |
| 57 | 62 | ||
| 58 | private String broadcastForPlatform = "UDP"; | 63 | private String broadcastForPlatform = "UDP"; |
| 59 | 64 | ||
| 60 | private List<String> interfaceAuthenticationExcludes = new ArrayList<>(); | 65 | private List<String> interfaceAuthenticationExcludes = new ArrayList<>(); |
| 61 | 66 | ||
| 67 | + private List<String> allowedOrigins = new ArrayList<>(); | ||
| 68 | + | ||
| 62 | public Boolean getSavePositionHistory() { | 69 | public Boolean getSavePositionHistory() { |
| 63 | return savePositionHistory; | 70 | return savePositionHistory; |
| 64 | } | 71 | } |
| @@ -238,4 +245,36 @@ public class UserSetting { | @@ -238,4 +245,36 @@ public class UserSetting { | ||
| 238 | public void setSipLog(Boolean sipLog) { | 245 | public void setSipLog(Boolean sipLog) { |
| 239 | this.sipLog = sipLog; | 246 | this.sipLog = sipLog; |
| 240 | } | 247 | } |
| 248 | + | ||
| 249 | + public List<String> getAllowedOrigins() { | ||
| 250 | + return allowedOrigins; | ||
| 251 | + } | ||
| 252 | + | ||
| 253 | + public void setAllowedOrigins(List<String> allowedOrigins) { | ||
| 254 | + this.allowedOrigins = allowedOrigins; | ||
| 255 | + } | ||
| 256 | + | ||
| 257 | + public Boolean getSendToPlatformsWhenIdLost() { | ||
| 258 | + return sendToPlatformsWhenIdLost; | ||
| 259 | + } | ||
| 260 | + | ||
| 261 | + public void setSendToPlatformsWhenIdLost(Boolean sendToPlatformsWhenIdLost) { | ||
| 262 | + this.sendToPlatformsWhenIdLost = sendToPlatformsWhenIdLost; | ||
| 263 | + } | ||
| 264 | + | ||
| 265 | + public Boolean getRefuseChannelStatusChannelFormNotify() { | ||
| 266 | + return refuseChannelStatusChannelFormNotify; | ||
| 267 | + } | ||
| 268 | + | ||
| 269 | + public void setRefuseChannelStatusChannelFormNotify(Boolean refuseChannelStatusChannelFormNotify) { | ||
| 270 | + this.refuseChannelStatusChannelFormNotify = refuseChannelStatusChannelFormNotify; | ||
| 271 | + } | ||
| 272 | + | ||
| 273 | + public String getRecordPath() { | ||
| 274 | + return recordPath; | ||
| 275 | + } | ||
| 276 | + | ||
| 277 | + public void setRecordPath(String recordPath) { | ||
| 278 | + this.recordPath = recordPath; | ||
| 279 | + } | ||
| 241 | } | 280 | } |
src/main/java/com/genersoft/iot/vmp/conf/druid/DruidConfiguration.java deleted
100644 → 0
| 1 | -package com.genersoft.iot.vmp.conf.druid; | ||
| 2 | - | ||
| 3 | -import com.alibaba.druid.support.http.StatViewServlet; | ||
| 4 | -import com.alibaba.druid.support.http.WebStatFilter; | ||
| 5 | -import org.springframework.beans.factory.annotation.Value; | ||
| 6 | -import org.springframework.boot.web.servlet.FilterRegistrationBean; | ||
| 7 | -import org.springframework.boot.web.servlet.ServletRegistrationBean; | ||
| 8 | -import org.springframework.context.annotation.Bean; | ||
| 9 | - | ||
| 10 | -import javax.servlet.Filter; | ||
| 11 | -import javax.servlet.Servlet; | ||
| 12 | - | ||
| 13 | -/** | ||
| 14 | - * druid监控配置 | ||
| 15 | - * @author | ||
| 16 | - */ | ||
| 17 | -public class DruidConfiguration { | ||
| 18 | - | ||
| 19 | - @Value("${rj-druid-manage.allow:127.0.0.1}") | ||
| 20 | - private String allow; | ||
| 21 | - | ||
| 22 | - @Value("${rj-druid-manage.deny:}") | ||
| 23 | - private String deny; | ||
| 24 | - | ||
| 25 | - @Value("${rj-druid-manage.loginUsername:admin}") | ||
| 26 | - private String loginUsername; | ||
| 27 | - | ||
| 28 | - @Value("${rj-druid-manage.loginPassword:admin}") | ||
| 29 | - private String loginPassword; | ||
| 30 | - | ||
| 31 | - @Value("${rj-druid-manage.resetEnable:false}") | ||
| 32 | - private String resetEnable; | ||
| 33 | - | ||
| 34 | - /** | ||
| 35 | - * druid监控页面开启 | ||
| 36 | - */ | ||
| 37 | - @Bean | ||
| 38 | - public ServletRegistrationBean druidServlet() { | ||
| 39 | - ServletRegistrationBean<Servlet> servletRegistrationBean = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*"); | ||
| 40 | - // IP白名单 | ||
| 41 | - servletRegistrationBean.addInitParameter("allow", allow); | ||
| 42 | - // IP黑名单(共同存在时,deny优先于allow) | ||
| 43 | - servletRegistrationBean.addInitParameter("deny", deny); | ||
| 44 | - //控制台管理用户 | ||
| 45 | - servletRegistrationBean.addInitParameter("loginUsername", loginUsername); | ||
| 46 | - servletRegistrationBean.addInitParameter("loginPassword", loginPassword); | ||
| 47 | - //是否能够重置数据 禁用HTML页面上的“Reset All”功能 | ||
| 48 | - servletRegistrationBean.addInitParameter("resetEnable", resetEnable); | ||
| 49 | - return servletRegistrationBean; | ||
| 50 | - } | ||
| 51 | - | ||
| 52 | - /** | ||
| 53 | - * druid url监控配置 | ||
| 54 | - */ | ||
| 55 | - @Bean | ||
| 56 | - public FilterRegistrationBean filterRegistrationBean() { | ||
| 57 | - FilterRegistrationBean<Filter> filterRegistrationBean = new FilterRegistrationBean<>(new WebStatFilter()); | ||
| 58 | - filterRegistrationBean.addUrlPatterns("/*"); | ||
| 59 | - filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"); | ||
| 60 | - return filterRegistrationBean; | ||
| 61 | - } | ||
| 62 | - | ||
| 63 | - | ||
| 64 | -} | ||
| 65 | \ No newline at end of file | 0 | \ No newline at end of file |
src/main/java/com/genersoft/iot/vmp/conf/druid/EnableDruidSupport.java deleted
100644 → 0
| 1 | -package com.genersoft.iot.vmp.conf.druid; | ||
| 2 | - | ||
| 3 | -import org.springframework.boot.web.servlet.ServletComponentScan; | ||
| 4 | -import org.springframework.context.annotation.Import; | ||
| 5 | - | ||
| 6 | -import java.lang.annotation.*; | ||
| 7 | - | ||
| 8 | -/** | ||
| 9 | - * druid监控支持注解 | ||
| 10 | - * | ||
| 11 | - * @author | ||
| 12 | - * {@link DruidConfiguration} druid监控页面安全配置支持 | ||
| 13 | - * {@link ServletComponentScan} druid监控页面需要扫描servlet | ||
| 14 | - */ | ||
| 15 | -@Target(ElementType.TYPE) | ||
| 16 | -@Retention(RetentionPolicy.RUNTIME) | ||
| 17 | -@Documented | ||
| 18 | -@Inherited | ||
| 19 | -@Import({ | ||
| 20 | - DruidConfiguration.class, | ||
| 21 | -}) | ||
| 22 | -@ServletComponentScan | ||
| 23 | -public @interface EnableDruidSupport { | ||
| 24 | -} |
src/main/java/com/genersoft/iot/vmp/conf/security/AnonymousAuthenticationEntryPoint.java
| 1 | package com.genersoft.iot.vmp.conf.security; | 1 | package com.genersoft.iot.vmp.conf.security; |
| 2 | 2 | ||
| 3 | import com.alibaba.fastjson2.JSONObject; | 3 | import com.alibaba.fastjson2.JSONObject; |
| 4 | +import com.genersoft.iot.vmp.conf.security.dto.JwtUser; | ||
| 4 | import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; | 5 | import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; |
| 5 | -import org.apache.poi.hssf.eventmodel.ERFListener; | ||
| 6 | -import org.slf4j.Logger; | ||
| 7 | -import org.slf4j.LoggerFactory; | 6 | +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; |
| 8 | import org.springframework.security.core.AuthenticationException; | 7 | import org.springframework.security.core.AuthenticationException; |
| 8 | +import org.springframework.security.core.context.SecurityContextHolder; | ||
| 9 | import org.springframework.security.web.AuthenticationEntryPoint; | 9 | import org.springframework.security.web.AuthenticationEntryPoint; |
| 10 | import org.springframework.stereotype.Component; | 10 | import org.springframework.stereotype.Component; |
| 11 | 11 | ||
| @@ -18,17 +18,15 @@ import java.io.IOException; | @@ -18,17 +18,15 @@ import java.io.IOException; | ||
| 18 | * @author lin | 18 | * @author lin |
| 19 | */ | 19 | */ |
| 20 | @Component | 20 | @Component |
| 21 | -public class AnonymousAuthenticationEntryPoint implements AuthenticationEntryPoint { | ||
| 22 | - | ||
| 23 | - private final static Logger logger = LoggerFactory.getLogger(DefaultUserDetailsServiceImpl.class); | 21 | +public class AnonymousAuthenticationEntryPoint implements AuthenticationEntryPoint { |
| 24 | 22 | ||
| 25 | @Override | 23 | @Override |
| 26 | public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) { | 24 | public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) { |
| 27 | - // 允许跨域 | ||
| 28 | - response.setHeader("Access-Control-Allow-Origin", "*"); | ||
| 29 | - // 允许自定义请求头token(允许head跨域) | ||
| 30 | - response.setHeader("Access-Control-Allow-Headers", "token, Accept, Origin, X-Requested-With, Content-Type, Last-Modified"); | ||
| 31 | - response.setHeader("Content-type", "application/json;charset=UTF-8"); | 25 | + String jwt = request.getHeader(JwtUtils.getHeader()); |
| 26 | + JwtUser jwtUser = JwtUtils.verifyToken(jwt); | ||
| 27 | + String username = jwtUser.getUserName(); | ||
| 28 | + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, jwtUser.getPassword() ); | ||
| 29 | + SecurityContextHolder.getContext().setAuthentication(token); | ||
| 32 | JSONObject jsonObject = new JSONObject(); | 30 | JSONObject jsonObject = new JSONObject(); |
| 33 | jsonObject.put("code", ErrorCode.ERROR401.getCode()); | 31 | jsonObject.put("code", ErrorCode.ERROR401.getCode()); |
| 34 | jsonObject.put("msg", ErrorCode.ERROR401.getMsg()); | 32 | jsonObject.put("msg", ErrorCode.ERROR401.getMsg()); |
src/main/java/com/genersoft/iot/vmp/conf/security/DefaultUserDetailsServiceImpl.java
| 1 | package com.genersoft.iot.vmp.conf.security; | 1 | package com.genersoft.iot.vmp.conf.security; |
| 2 | 2 | ||
| 3 | -import java.time.LocalDateTime; | ||
| 4 | - | 3 | +import com.alibaba.excel.util.StringUtils; |
| 4 | +import com.genersoft.iot.vmp.conf.security.dto.LoginUser; | ||
| 5 | +import com.genersoft.iot.vmp.service.IUserService; | ||
| 6 | +import com.genersoft.iot.vmp.storager.dao.dto.User; | ||
| 5 | import org.slf4j.Logger; | 7 | import org.slf4j.Logger; |
| 6 | import org.slf4j.LoggerFactory; | 8 | import org.slf4j.LoggerFactory; |
| 7 | import org.springframework.beans.factory.annotation.Autowired; | 9 | import org.springframework.beans.factory.annotation.Autowired; |
| @@ -10,10 +12,7 @@ import org.springframework.security.core.userdetails.UserDetailsService; | @@ -10,10 +12,7 @@ import org.springframework.security.core.userdetails.UserDetailsService; | ||
| 10 | import org.springframework.security.core.userdetails.UsernameNotFoundException; | 12 | import org.springframework.security.core.userdetails.UsernameNotFoundException; |
| 11 | import org.springframework.stereotype.Component; | 13 | import org.springframework.stereotype.Component; |
| 12 | 14 | ||
| 13 | -import com.alibaba.excel.util.StringUtils; | ||
| 14 | -import com.genersoft.iot.vmp.conf.security.dto.LoginUser; | ||
| 15 | -import com.genersoft.iot.vmp.service.IUserService; | ||
| 16 | -import com.genersoft.iot.vmp.storager.dao.dto.User; | 15 | +import java.time.LocalDateTime; |
| 17 | 16 | ||
| 18 | /** | 17 | /** |
| 19 | * 用户登录认证逻辑 | 18 | * 用户登录认证逻辑 |
| @@ -45,4 +44,8 @@ public class DefaultUserDetailsServiceImpl implements UserDetailsService { | @@ -45,4 +44,8 @@ public class DefaultUserDetailsServiceImpl implements UserDetailsService { | ||
| 45 | } | 44 | } |
| 46 | 45 | ||
| 47 | 46 | ||
| 47 | + | ||
| 48 | + | ||
| 49 | + | ||
| 50 | + | ||
| 48 | } | 51 | } |
src/main/java/com/genersoft/iot/vmp/conf/security/InvalidSessionHandler.java deleted
100644 → 0
| 1 | -package com.genersoft.iot.vmp.conf.security; | ||
| 2 | - | ||
| 3 | -import org.slf4j.Logger; | ||
| 4 | -import org.slf4j.LoggerFactory; | ||
| 5 | -import org.springframework.security.web.session.InvalidSessionStrategy; | ||
| 6 | - | ||
| 7 | -import javax.servlet.ServletException; | ||
| 8 | -import javax.servlet.http.HttpServletRequest; | ||
| 9 | -import javax.servlet.http.HttpServletResponse; | ||
| 10 | -import java.io.IOException; | ||
| 11 | - | ||
| 12 | -/** | ||
| 13 | - * 登录超时的处理 | ||
| 14 | - */ | ||
| 15 | -public class InvalidSessionHandler implements InvalidSessionStrategy { | ||
| 16 | - | ||
| 17 | - private final static Logger logger = LoggerFactory.getLogger(InvalidSessionHandler.class); | ||
| 18 | - | ||
| 19 | - @Override | ||
| 20 | - public void onInvalidSessionDetected(HttpServletRequest request, HttpServletResponse httpServletResponse) throws IOException, ServletException { | ||
| 21 | - String username = request.getParameter("username"); | ||
| 22 | - logger.info("[登录超时] - [{}]", username); | ||
| 23 | - } | ||
| 24 | -} |
src/main/java/com/genersoft/iot/vmp/conf/security/JwtAuthenticationFilter.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.conf.security; | ||
| 2 | + | ||
| 3 | +import com.genersoft.iot.vmp.conf.UserSetting; | ||
| 4 | +import com.genersoft.iot.vmp.conf.security.dto.JwtUser; | ||
| 5 | +import org.apache.commons.lang3.StringUtils; | ||
| 6 | +import org.springframework.beans.factory.annotation.Autowired; | ||
| 7 | +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; | ||
| 8 | +import org.springframework.security.core.context.SecurityContextHolder; | ||
| 9 | +import org.springframework.stereotype.Component; | ||
| 10 | +import org.springframework.web.filter.OncePerRequestFilter; | ||
| 11 | + | ||
| 12 | +import javax.servlet.FilterChain; | ||
| 13 | +import javax.servlet.ServletException; | ||
| 14 | +import javax.servlet.http.HttpServletRequest; | ||
| 15 | +import javax.servlet.http.HttpServletResponse; | ||
| 16 | +import java.io.IOException; | ||
| 17 | +import java.util.ArrayList; | ||
| 18 | + | ||
| 19 | +/** | ||
| 20 | + * jwt token 过滤器 | ||
| 21 | + */ | ||
| 22 | + | ||
| 23 | +@Component | ||
| 24 | +public class JwtAuthenticationFilter extends OncePerRequestFilter { | ||
| 25 | + | ||
| 26 | + | ||
| 27 | + @Autowired | ||
| 28 | + private UserSetting userSetting; | ||
| 29 | + | ||
| 30 | + | ||
| 31 | + @Override | ||
| 32 | + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { | ||
| 33 | + | ||
| 34 | + // 忽略登录请求的token验证 | ||
| 35 | + String requestURI = request.getRequestURI(); | ||
| 36 | + if (requestURI.equalsIgnoreCase("/api/user/login")) { | ||
| 37 | + chain.doFilter(request, response); | ||
| 38 | + return; | ||
| 39 | + } | ||
| 40 | + if (!userSetting.isInterfaceAuthentication()) { | ||
| 41 | + // 构建UsernamePasswordAuthenticationToken,这里密码为null,是因为提供了正确的JWT,实现自动登录 | ||
| 42 | + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(null, null, new ArrayList<>() ); | ||
| 43 | + SecurityContextHolder.getContext().setAuthentication(token); | ||
| 44 | + chain.doFilter(request, response); | ||
| 45 | + return; | ||
| 46 | + } | ||
| 47 | + String jwt = request.getHeader(JwtUtils.getHeader()); | ||
| 48 | + // 这里如果没有jwt,继续往后走,因为后面还有鉴权管理器等去判断是否拥有身份凭证,所以是可以放行的 | ||
| 49 | + // 没有jwt相当于匿名访问,若有一些接口是需要权限的,则不能访问这些接口 | ||
| 50 | + if (StringUtils.isBlank(jwt)) { | ||
| 51 | + jwt = request.getParameter(JwtUtils.getHeader()); | ||
| 52 | + if (StringUtils.isBlank(jwt)) { | ||
| 53 | + chain.doFilter(request, response); | ||
| 54 | + return; | ||
| 55 | + } | ||
| 56 | + } | ||
| 57 | + | ||
| 58 | + JwtUser jwtUser = JwtUtils.verifyToken(jwt); | ||
| 59 | + String username = jwtUser.getUserName(); | ||
| 60 | + // TODO 处理各个状态 | ||
| 61 | + switch (jwtUser.getStatus()){ | ||
| 62 | + case EXPIRED: | ||
| 63 | + response.setStatus(400); | ||
| 64 | + chain.doFilter(request, response); | ||
| 65 | + // 异常 | ||
| 66 | + return; | ||
| 67 | + case EXCEPTION: | ||
| 68 | + // 过期 | ||
| 69 | + response.setStatus(400); | ||
| 70 | + chain.doFilter(request, response); | ||
| 71 | + return; | ||
| 72 | + case EXPIRING_SOON: | ||
| 73 | + // 即将过期 | ||
| 74 | +// return; | ||
| 75 | + default: | ||
| 76 | + } | ||
| 77 | + | ||
| 78 | + // 构建UsernamePasswordAuthenticationToken,这里密码为null,是因为提供了正确的JWT,实现自动登录 | ||
| 79 | + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, jwtUser.getPassword(), new ArrayList<>() ); | ||
| 80 | + SecurityContextHolder.getContext().setAuthentication(token); | ||
| 81 | + chain.doFilter(request, response); | ||
| 82 | + } | ||
| 83 | + | ||
| 84 | +} |
src/main/java/com/genersoft/iot/vmp/conf/security/JwtUtils.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.conf.security; | ||
| 2 | + | ||
| 3 | +import com.genersoft.iot.vmp.conf.security.dto.JwtUser; | ||
| 4 | +import org.jose4j.json.JsonUtil; | ||
| 5 | +import org.jose4j.jwk.RsaJsonWebKey; | ||
| 6 | +import org.jose4j.jws.AlgorithmIdentifiers; | ||
| 7 | +import org.jose4j.jws.JsonWebSignature; | ||
| 8 | +import org.jose4j.jwt.JwtClaims; | ||
| 9 | +import org.jose4j.jwt.NumericDate; | ||
| 10 | +import org.jose4j.jwt.consumer.ErrorCodes; | ||
| 11 | +import org.jose4j.jwt.consumer.InvalidJwtException; | ||
| 12 | +import org.jose4j.jwt.consumer.JwtConsumer; | ||
| 13 | +import org.jose4j.jwt.consumer.JwtConsumerBuilder; | ||
| 14 | +import org.jose4j.lang.JoseException; | ||
| 15 | +import org.slf4j.Logger; | ||
| 16 | +import org.slf4j.LoggerFactory; | ||
| 17 | + | ||
| 18 | +import java.security.PrivateKey; | ||
| 19 | +import java.time.LocalDateTime; | ||
| 20 | +import java.time.ZoneOffset; | ||
| 21 | + | ||
| 22 | +public class JwtUtils { | ||
| 23 | + | ||
| 24 | + private static final Logger logger = LoggerFactory.getLogger(JwtUtils.class); | ||
| 25 | + | ||
| 26 | + private static final String HEADER = "access-token"; | ||
| 27 | + private static final String AUDIENCE = "Audience"; | ||
| 28 | + | ||
| 29 | + private static final long EXPIRED_THRESHOLD = 10 * 60; | ||
| 30 | + | ||
| 31 | + private static final String keyId = "3e79646c4dbc408383a9eed09f2b85ae"; | ||
| 32 | + private static final String privateKeyStr = "{\"kty\":\"RSA\",\"kid\":\"3e79646c4dbc408383a9eed09f2b85ae\",\"alg\":\"RS256\",\"n\":\"gndmVdiOTSJ5et2HIeTM5f1m61x5ojLUi5HDfvr-jRrESQ5kbKuySGHVwR4QhwinpY1wQqBnwc80tx7cb_6SSqsTOoGln6T_l3k2Pb54ClVnGWiW_u1kmX78V2TZOsVmZmwtdZCMi-2zWIyAdIEXE-gncIehoAgEoq2VAhaCURbJWro_EwzzQwNmCTkDodLAx4npXRd_qSu0Ayp0txym9OFovBXBULRvk4DPiy3i_bPUmCDxzC46pTtFOe9p82uybTehZfULZtXXqRm85FL9n5zkrsTllPNAyEGhgb0RK9sE5nK1m_wNNysDyfLC4EFf1VXTrKm14XNVjc2vqLb7Mw\",\"e\":\"AQAB\",\"d\":\"ed7U_k3rJ4yTk70JtRSIfjKGiEb67BO1TabcymnljKO7RU8nage84zZYuSu_XpQsHk6P1f0Gzxkicghm_Er-FrfVn2pp70Xu52z3yRd6BJUgWLDFk97ngScIyw5OiULKU9SrZk2frDpftNCSUcIgb50F8m0QAnBa_CdPsQKbuuhLv8V8tBAV7F_lAwvSBgu56wRo3hPz5dWH8YeXM7XBfQ9viFMNEKd21sP_j5C7ueUnXT66nBxe3ZJEU3iuMYM6D6dB_KW2GfZC6WmTgvGhhxJD0h7aYmfjkD99MDleB7SkpbvoODOqiQ5Epb7Nyh6kv5u4KUv2CJYtATLZkUeMkQ\",\"p\":\"uBUjWPWtlGksmOqsqCNWksfqJvMcnP_8TDYN7e4-WnHL4N-9HjRuPDnp6kHvCIEi9SEfxm7gNxlRcWegvNQr3IZCz7TnCTexXc5NOklB9OavWFla6u-s3Thn6Tz45-EUjpJr0VJMxhO-KxGmuTwUXBBp4vN6K2qV6rQNFmgkWzk\",\"q\":\"tW_i7cCec56bHkhITL_79dXHz_PLC_f7xlynmlZJGU_d6mqOKmLBNBbTMLnYW8uAFiFzWxDeDHh1o5uF0mSQR-Z1Fg35OftnpbWpy0Cbc2la5WgXQjOwtG1eLYIY2BD3-wQ1VYDBCvowr4FDi-sngxwLqvwmrJ0xjhi99O-Gzcs\",\"dp\":\"q1d5jE85Hz_6M-eTh_lEluEf0NtPEc-vvhw-QO4V-cecNpbrCBdTWBmr4dE3NdpFeJc5ZVFEv-SACyei1MBEh0ItI_pFZi4BmMfy2ELh8ptaMMkTOESYyVy8U7veDq9RnBcr5i1Nqr0rsBkA77-9T6gzdvycBZdzLYAkAmwzEvk\",\"dq\":\"q29A2K08Crs-jmp2Bi8Q_8QzvIX6wSBbwZ4ir24AO-5_HNP56IrPS0yV2GCB0pqCOGb6_Hz_koDvhtuYoqdqvMVAtMoXR3YJBUaVXPt65p4RyNmFwIPe31zHs_BNUTsXVRMw4c16mci03-Af1sEm4HdLfxAp6sfM3xr5wcnhcek\",\"qi\":\"rHPgVTyHUHuYzcxfouyBfb1XAY8nshwn0ddo81o1BccD4Z7zo5It6SefDHjxCAbcmbiCcXBSooLcY-NF5FMv3fg19UE21VyLQltHcVjRRp2tRs4OHcM8yaXIU2x6N6Z6BP2tOksHb9MOBY1wAQzFOAKg_G4Sxev6-_6ud6RISuc\"}"; | ||
| 33 | + private static final String publicKeyStr = "{\"kty\":\"RSA\",\"kid\":\"3e79646c4dbc408383a9eed09f2b85ae\",\"alg\":\"RS256\",\"n\":\"gndmVdiOTSJ5et2HIeTM5f1m61x5ojLUi5HDfvr-jRrESQ5kbKuySGHVwR4QhwinpY1wQqBnwc80tx7cb_6SSqsTOoGln6T_l3k2Pb54ClVnGWiW_u1kmX78V2TZOsVmZmwtdZCMi-2zWIyAdIEXE-gncIehoAgEoq2VAhaCURbJWro_EwzzQwNmCTkDodLAx4npXRd_qSu0Ayp0txym9OFovBXBULRvk4DPiy3i_bPUmCDxzC46pTtFOe9p82uybTehZfULZtXXqRm85FL9n5zkrsTllPNAyEGhgb0RK9sE5nK1m_wNNysDyfLC4EFf1VXTrKm14XNVjc2vqLb7Mw\",\"e\":\"AQAB\"}"; | ||
| 34 | + | ||
| 35 | + /** | ||
| 36 | + * token过期时间(分钟) | ||
| 37 | + */ | ||
| 38 | + public static final long expirationTime = 30; | ||
| 39 | + | ||
| 40 | + public static String createToken(String username, String password) { | ||
| 41 | + try { | ||
| 42 | + /** | ||
| 43 | + * “iss” (issuer) 发行人 | ||
| 44 | + * | ||
| 45 | + * “sub” (subject) 主题 | ||
| 46 | + * | ||
| 47 | + * “aud” (audience) 接收方 用户 | ||
| 48 | + * | ||
| 49 | + * “exp” (expiration time) 到期时间 | ||
| 50 | + * | ||
| 51 | + * “nbf” (not before) 在此之前不可用 | ||
| 52 | + * | ||
| 53 | + * “iat” (issued at) jwt的签发时间 | ||
| 54 | + */ | ||
| 55 | + //Payload | ||
| 56 | + JwtClaims claims = new JwtClaims(); | ||
| 57 | + claims.setGeneratedJwtId(); | ||
| 58 | + claims.setIssuedAtToNow(); | ||
| 59 | + // 令牌将过期的时间 分钟 | ||
| 60 | + claims.setExpirationTimeMinutesInTheFuture(expirationTime); | ||
| 61 | + claims.setNotBeforeMinutesInThePast(0); | ||
| 62 | + claims.setSubject("login"); | ||
| 63 | + claims.setAudience(AUDIENCE); | ||
| 64 | + //添加自定义参数,必须是字符串类型 | ||
| 65 | + claims.setClaim("username", username); | ||
| 66 | + claims.setClaim("password", password); | ||
| 67 | + | ||
| 68 | + //jws | ||
| 69 | + JsonWebSignature jws = new JsonWebSignature(); | ||
| 70 | + //签名算法RS256 | ||
| 71 | + jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256); | ||
| 72 | + jws.setKeyIdHeaderValue(keyId); | ||
| 73 | + jws.setPayload(claims.toJson()); | ||
| 74 | + | ||
| 75 | + PrivateKey privateKey = new RsaJsonWebKey(JsonUtil.parseJson(privateKeyStr)).getPrivateKey(); | ||
| 76 | + jws.setKey(privateKey); | ||
| 77 | + | ||
| 78 | + //get token | ||
| 79 | + String idToken = jws.getCompactSerialization(); | ||
| 80 | + return idToken; | ||
| 81 | + } catch (JoseException e) { | ||
| 82 | + logger.error("[Token生成失败]: {}", e.getMessage()); | ||
| 83 | + } | ||
| 84 | + | ||
| 85 | + return null; | ||
| 86 | + } | ||
| 87 | + | ||
| 88 | + public static String getHeader() { | ||
| 89 | + return HEADER; | ||
| 90 | + } | ||
| 91 | + | ||
| 92 | + | ||
| 93 | + public static JwtUser verifyToken(String token) { | ||
| 94 | + | ||
| 95 | + JwtUser jwtUser = new JwtUser(); | ||
| 96 | + | ||
| 97 | + try { | ||
| 98 | + JwtConsumer consumer = new JwtConsumerBuilder() | ||
| 99 | + .setRequireExpirationTime() | ||
| 100 | + .setMaxFutureValidityInMinutes(5256000) | ||
| 101 | + .setAllowedClockSkewInSeconds(30) | ||
| 102 | + .setRequireSubject() | ||
| 103 | + //.setExpectedIssuer("") | ||
| 104 | + .setExpectedAudience(AUDIENCE) | ||
| 105 | + .setVerificationKey(new RsaJsonWebKey(JsonUtil.parseJson(publicKeyStr)).getPublicKey()) | ||
| 106 | + .build(); | ||
| 107 | + | ||
| 108 | + JwtClaims claims = consumer.processToClaims(token); | ||
| 109 | + NumericDate expirationTime = claims.getExpirationTime(); | ||
| 110 | + // 判断是否即将过期, 默认剩余时间小于5分钟未即将过期 | ||
| 111 | + // 剩余时间 (秒) | ||
| 112 | + long timeRemaining = LocalDateTime.now().toEpochSecond(ZoneOffset.ofHours(8)) - expirationTime.getValue(); | ||
| 113 | + if (timeRemaining < 5 * 60) { | ||
| 114 | + jwtUser.setStatus(JwtUser.TokenStatus.EXPIRING_SOON); | ||
| 115 | + }else { | ||
| 116 | + jwtUser.setStatus(JwtUser.TokenStatus.NORMAL); | ||
| 117 | + } | ||
| 118 | + | ||
| 119 | + String username = (String) claims.getClaimValue("username"); | ||
| 120 | + String password = (String) claims.getClaimValue("password"); | ||
| 121 | + jwtUser.setUserName(username); | ||
| 122 | + jwtUser.setPassword(password); | ||
| 123 | + | ||
| 124 | + return jwtUser; | ||
| 125 | + } catch (InvalidJwtException e) { | ||
| 126 | + if (e.hasErrorCode(ErrorCodes.EXPIRED)) { | ||
| 127 | + jwtUser.setStatus(JwtUser.TokenStatus.EXPIRED); | ||
| 128 | + }else { | ||
| 129 | + jwtUser.setStatus(JwtUser.TokenStatus.EXCEPTION); | ||
| 130 | + } | ||
| 131 | + return jwtUser; | ||
| 132 | + }catch (Exception e) { | ||
| 133 | + logger.error("[Token解析失败]: {}", e.getMessage()); | ||
| 134 | + jwtUser.setStatus(JwtUser.TokenStatus.EXPIRED); | ||
| 135 | + return jwtUser; | ||
| 136 | + } | ||
| 137 | + } | ||
| 138 | +} |
src/main/java/com/genersoft/iot/vmp/conf/security/LoginSuccessHandler.java
| @@ -21,7 +21,16 @@ public class LoginSuccessHandler implements AuthenticationSuccessHandler { | @@ -21,7 +21,16 @@ public class LoginSuccessHandler implements AuthenticationSuccessHandler { | ||
| 21 | 21 | ||
| 22 | @Override | 22 | @Override |
| 23 | public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException { | 23 | public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException { |
| 24 | - String username = request.getParameter("username"); | ||
| 25 | - logger.info("[登录成功] - [{}]", username); | 24 | +// String username = request.getParameter("username"); |
| 25 | +// httpServletResponse.setContentType("application/json;charset=UTF-8"); | ||
| 26 | +// // 生成JWT,并放置到请求头中 | ||
| 27 | +// String jwt = JwtUtils.createToken(authentication.getName(), ); | ||
| 28 | +// httpServletResponse.setHeader(JwtUtils.getHeader(), jwt); | ||
| 29 | +// ServletOutputStream outputStream = httpServletResponse.getOutputStream(); | ||
| 30 | +// outputStream.write(JSON.toJSONString(ErrorCode.SUCCESS).getBytes(StandardCharsets.UTF_8)); | ||
| 31 | +// outputStream.flush(); | ||
| 32 | +// outputStream.close(); | ||
| 33 | + | ||
| 34 | +// logger.info("[登录成功] - [{}]", username); | ||
| 26 | } | 35 | } |
| 27 | } | 36 | } |
src/main/java/com/genersoft/iot/vmp/conf/security/SecurityUtils.java
| 1 | package com.genersoft.iot.vmp.conf.security; | 1 | package com.genersoft.iot.vmp.conf.security; |
| 2 | 2 | ||
| 3 | import com.genersoft.iot.vmp.conf.security.dto.LoginUser; | 3 | import com.genersoft.iot.vmp.conf.security.dto.LoginUser; |
| 4 | +import com.genersoft.iot.vmp.storager.dao.dto.User; | ||
| 4 | import org.springframework.security.authentication.AuthenticationManager; | 5 | import org.springframework.security.authentication.AuthenticationManager; |
| 5 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; | 6 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; |
| 6 | import org.springframework.security.core.Authentication; | 7 | import org.springframework.security.core.Authentication; |
| @@ -9,6 +10,7 @@ import org.springframework.security.core.context.SecurityContextHolder; | @@ -9,6 +10,7 @@ import org.springframework.security.core.context.SecurityContextHolder; | ||
| 9 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; | 10 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; |
| 10 | 11 | ||
| 11 | import javax.security.sasl.AuthenticationException; | 12 | import javax.security.sasl.AuthenticationException; |
| 13 | +import java.time.LocalDateTime; | ||
| 12 | 14 | ||
| 13 | public class SecurityUtils { | 15 | public class SecurityUtils { |
| 14 | 16 | ||
| @@ -25,9 +27,12 @@ public class SecurityUtils { | @@ -25,9 +27,12 @@ public class SecurityUtils { | ||
| 25 | public static LoginUser login(String username, String password, AuthenticationManager authenticationManager) throws AuthenticationException { | 27 | public static LoginUser login(String username, String password, AuthenticationManager authenticationManager) throws AuthenticationException { |
| 26 | //使用security框架自带的验证token生成器 也可以自定义。 | 28 | //使用security框架自带的验证token生成器 也可以自定义。 |
| 27 | UsernamePasswordAuthenticationToken token =new UsernamePasswordAuthenticationToken(username,password); | 29 | UsernamePasswordAuthenticationToken token =new UsernamePasswordAuthenticationToken(username,password); |
| 30 | + //认证 如果失败,这里会自动异常后返回,所以这里不需要判断返回值是否为空,确定是否登录成功 | ||
| 28 | Authentication authenticate = authenticationManager.authenticate(token); | 31 | Authentication authenticate = authenticationManager.authenticate(token); |
| 29 | - SecurityContextHolder.getContext().setAuthentication(authenticate); | ||
| 30 | LoginUser user = (LoginUser) authenticate.getPrincipal(); | 32 | LoginUser user = (LoginUser) authenticate.getPrincipal(); |
| 33 | + | ||
| 34 | + SecurityContextHolder.getContext().setAuthentication(token); | ||
| 35 | + | ||
| 31 | return user; | 36 | return user; |
| 32 | } | 37 | } |
| 33 | 38 | ||
| @@ -49,8 +54,13 @@ public class SecurityUtils { | @@ -49,8 +54,13 @@ public class SecurityUtils { | ||
| 49 | if(authentication!=null){ | 54 | if(authentication!=null){ |
| 50 | Object principal = authentication.getPrincipal(); | 55 | Object principal = authentication.getPrincipal(); |
| 51 | if(principal!=null && !"anonymousUser".equals(principal)){ | 56 | if(principal!=null && !"anonymousUser".equals(principal)){ |
| 52 | - LoginUser user = (LoginUser) authentication.getPrincipal(); | ||
| 53 | - return user; | 57 | +// LoginUser user = (LoginUser) authentication.getPrincipal(); |
| 58 | + | ||
| 59 | + String username = (String) principal; | ||
| 60 | + User user = new User(); | ||
| 61 | + user.setUsername(username); | ||
| 62 | + LoginUser loginUser = new LoginUser(user, LocalDateTime.now()); | ||
| 63 | + return loginUser; | ||
| 54 | } | 64 | } |
| 55 | } | 65 | } |
| 56 | return null; | 66 | return null; |
src/main/java/com/genersoft/iot/vmp/conf/security/WebSecurityConfig.java
| @@ -15,9 +15,16 @@ import org.springframework.security.config.annotation.web.builders.HttpSecurity; | @@ -15,9 +15,16 @@ import org.springframework.security.config.annotation.web.builders.HttpSecurity; | ||
| 15 | import org.springframework.security.config.annotation.web.builders.WebSecurity; | 15 | import org.springframework.security.config.annotation.web.builders.WebSecurity; |
| 16 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; | 16 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; |
| 17 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; | 17 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; |
| 18 | +import org.springframework.security.config.http.SessionCreationPolicy; | ||
| 18 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; | 19 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; |
| 20 | +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; | ||
| 21 | +import org.springframework.web.cors.CorsConfiguration; | ||
| 22 | +import org.springframework.web.cors.CorsConfigurationSource; | ||
| 23 | +import org.springframework.web.cors.CorsUtils; | ||
| 24 | +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; | ||
| 19 | 25 | ||
| 20 | -import java.util.List; | 26 | +import java.util.ArrayList; |
| 27 | +import java.util.Arrays; | ||
| 21 | 28 | ||
| 22 | /** | 29 | /** |
| 23 | * 配置Spring Security | 30 | * 配置Spring Security |
| @@ -56,22 +63,8 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { | @@ -56,22 +63,8 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { | ||
| 56 | */ | 63 | */ |
| 57 | @Autowired | 64 | @Autowired |
| 58 | private AnonymousAuthenticationEntryPoint anonymousAuthenticationEntryPoint; | 65 | private AnonymousAuthenticationEntryPoint anonymousAuthenticationEntryPoint; |
| 59 | -// /** | ||
| 60 | -// * 超时处理 | ||
| 61 | -// */ | ||
| 62 | -// @Autowired | ||
| 63 | -// private InvalidSessionHandler invalidSessionHandler; | ||
| 64 | - | ||
| 65 | -// /** | ||
| 66 | -// * 顶号处理 | ||
| 67 | -// */ | ||
| 68 | -// @Autowired | ||
| 69 | -// private SessionInformationExpiredHandler sessionInformationExpiredHandler; | ||
| 70 | -// /** | ||
| 71 | -// * 登录用户没有权限访问资源 | ||
| 72 | -// */ | ||
| 73 | -// @Autowired | ||
| 74 | -// private LoginUserAccessDeniedHandler accessDeniedHandler; | 66 | + @Autowired |
| 67 | + private JwtAuthenticationFilter jwtAuthenticationFilter; | ||
| 75 | 68 | ||
| 76 | 69 | ||
| 77 | /** | 70 | /** |
| @@ -80,31 +73,21 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { | @@ -80,31 +73,21 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { | ||
| 80 | @Override | 73 | @Override |
| 81 | public void configure(WebSecurity web) { | 74 | public void configure(WebSecurity web) { |
| 82 | 75 | ||
| 83 | - if (!userSetting.isInterfaceAuthentication()) { | ||
| 84 | - web.ignoring().antMatchers("**"); | ||
| 85 | - }else { | ||
| 86 | - // 可以直接访问的静态数据 | ||
| 87 | - web.ignoring() | ||
| 88 | - .antMatchers("/") | ||
| 89 | - .antMatchers("/#/**") | ||
| 90 | - .antMatchers("/static/**") | ||
| 91 | - .antMatchers("/index.html") | ||
| 92 | - .antMatchers("/doc.html") // "/webjars/**", "/swagger-resources/**", "/v3/api-docs/**" | ||
| 93 | - .antMatchers("/webjars/**") | ||
| 94 | - .antMatchers("/swagger-resources/**") | ||
| 95 | - .antMatchers("/v3/api-docs/**") | ||
| 96 | - .antMatchers("/favicon.ico") | ||
| 97 | - .antMatchers("/js/**"); | ||
| 98 | - List<String> interfaceAuthenticationExcludes = userSetting.getInterfaceAuthenticationExcludes(); | ||
| 99 | - for (String interfaceAuthenticationExclude : interfaceAuthenticationExcludes) { | ||
| 100 | - if (interfaceAuthenticationExclude.split("/").length < 4 ) { | ||
| 101 | - logger.warn("{}不满足两级目录,已忽略", interfaceAuthenticationExclude); | ||
| 102 | - }else { | ||
| 103 | - web.ignoring().antMatchers(interfaceAuthenticationExclude); | ||
| 104 | - } | ||
| 105 | - | ||
| 106 | - } | ||
| 107 | - } | 76 | + ArrayList<String> matchers = new ArrayList<>(); |
| 77 | + matchers.add("/"); | ||
| 78 | + matchers.add("/#/**"); | ||
| 79 | + matchers.add("/static/**"); | ||
| 80 | + matchers.add("/index.html"); | ||
| 81 | + matchers.add("/doc.html"); | ||
| 82 | + matchers.add("/webjars/**"); | ||
| 83 | + matchers.add("/swagger-resources/**"); | ||
| 84 | + matchers.add("/v3/api-docs/**"); | ||
| 85 | + matchers.add("/js/**"); | ||
| 86 | + matchers.add("/api/device/query/snap/**"); | ||
| 87 | + matchers.add("/record_proxy/*/**"); | ||
| 88 | + matchers.addAll(userSetting.getInterfaceAuthenticationExcludes()); | ||
| 89 | + // 可以直接访问的静态数据 | ||
| 90 | + web.ignoring().antMatchers(matchers.toArray(new String[0])); | ||
| 108 | } | 91 | } |
| 109 | 92 | ||
| 110 | /** | 93 | /** |
| @@ -126,36 +109,43 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { | @@ -126,36 +109,43 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { | ||
| 126 | 109 | ||
| 127 | @Override | 110 | @Override |
| 128 | protected void configure(HttpSecurity http) throws Exception { | 111 | protected void configure(HttpSecurity http) throws Exception { |
| 129 | - http.cors().and().csrf().disable(); | ||
| 130 | - // 设置允许添加静态文件 | ||
| 131 | - http.headers().contentTypeOptions().disable(); | ||
| 132 | - http.authorizeRequests() | ||
| 133 | - // 放行接口 | ||
| 134 | - .antMatchers("/api/user/login","/index/hook/**").permitAll() | ||
| 135 | - // 除上面外的所有请求全部需要鉴权认证 | 112 | + http.headers().contentTypeOptions().disable() |
| 113 | + .and().cors().configurationSource(configurationSource()) | ||
| 114 | + .and().csrf().disable() | ||
| 115 | + .sessionManagement() | ||
| 116 | + .sessionCreationPolicy(SessionCreationPolicy.STATELESS) | ||
| 117 | + | ||
| 118 | + // 配置拦截规则 | ||
| 119 | + .and() | ||
| 120 | + .authorizeRequests() | ||
| 121 | + .requestMatchers(CorsUtils::isPreFlightRequest).permitAll() | ||
| 122 | + .antMatchers(userSetting.getInterfaceAuthenticationExcludes().toArray(new String[0])).permitAll() | ||
| 123 | + .antMatchers("/api/user/login","/index/hook/**","/zlm_Proxy/FhTuMYqB2HeCuNOb/record/t/1/2023-03-25/16:35:07-16:35:16-9353.mp4").permitAll() | ||
| 136 | .anyRequest().authenticated() | 124 | .anyRequest().authenticated() |
| 137 | - // 异常处理(权限拒绝、登录失效等) | ||
| 138 | - .and().exceptionHandling() | ||
| 139 | - //匿名用户访问无权限资源时的异常处理 | 125 | + // 异常处理器 |
| 126 | + .and() | ||
| 127 | + .exceptionHandling() | ||
| 140 | .authenticationEntryPoint(anonymousAuthenticationEntryPoint) | 128 | .authenticationEntryPoint(anonymousAuthenticationEntryPoint) |
| 141 | -// .accessDeniedHandler(accessDeniedHandler)//登录用户没有权限访问资源 | ||
| 142 | - // 登入 允许所有用户 | ||
| 143 | - .and().formLogin().permitAll() | ||
| 144 | - //登录成功处理逻辑 | ||
| 145 | - .successHandler(loginSuccessHandler) | ||
| 146 | - //登录失败处理逻辑 | ||
| 147 | - .failureHandler(loginFailureHandler) | ||
| 148 | - // 登出 | ||
| 149 | .and().logout().logoutUrl("/api/user/logout").permitAll() | 129 | .and().logout().logoutUrl("/api/user/logout").permitAll() |
| 150 | - //登出成功处理逻辑 | ||
| 151 | .logoutSuccessHandler(logoutHandler) | 130 | .logoutSuccessHandler(logoutHandler) |
| 152 | - .deleteCookies("JSESSIONID") | ||
| 153 | - // 会话管理 | ||
| 154 | -// .and().sessionManagement().invalidSessionStrategy(invalidSessionHandler) // 超时处理 | ||
| 155 | -// .maximumSessions(1)//同一账号同时登录最大用户数 | ||
| 156 | -// .expiredSessionStrategy(sessionInformationExpiredHandler) // 顶号处理 | ||
| 157 | ; | 131 | ; |
| 132 | + http.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); | ||
| 133 | + | ||
| 134 | + } | ||
| 158 | 135 | ||
| 136 | + CorsConfigurationSource configurationSource(){ | ||
| 137 | + // 配置跨域 | ||
| 138 | + CorsConfiguration corsConfiguration = new CorsConfiguration(); | ||
| 139 | + corsConfiguration.setAllowedHeaders(Arrays.asList("*")); | ||
| 140 | + corsConfiguration.setAllowedMethods(Arrays.asList("*")); | ||
| 141 | + corsConfiguration.setMaxAge(3600L); | ||
| 142 | + corsConfiguration.setAllowCredentials(true); | ||
| 143 | + corsConfiguration.setAllowedOrigins(userSetting.getAllowedOrigins()); | ||
| 144 | + corsConfiguration.setExposedHeaders(Arrays.asList(JwtUtils.getHeader())); | ||
| 145 | + | ||
| 146 | + UrlBasedCorsConfigurationSource url = new UrlBasedCorsConfigurationSource(); | ||
| 147 | + url.registerCorsConfiguration("/**",corsConfiguration); | ||
| 148 | + return url; | ||
| 159 | } | 149 | } |
| 160 | 150 | ||
| 161 | /** | 151 | /** |
src/main/java/com/genersoft/iot/vmp/conf/security/dto/JwtUser.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.conf.security.dto; | ||
| 2 | + | ||
| 3 | +public class JwtUser { | ||
| 4 | + | ||
| 5 | + public enum TokenStatus{ | ||
| 6 | + /** | ||
| 7 | + * 正常的使用状态 | ||
| 8 | + */ | ||
| 9 | + NORMAL, | ||
| 10 | + /** | ||
| 11 | + * 过期而失效 | ||
| 12 | + */ | ||
| 13 | + EXPIRED, | ||
| 14 | + /** | ||
| 15 | + * 即将过期 | ||
| 16 | + */ | ||
| 17 | + EXPIRING_SOON, | ||
| 18 | + /** | ||
| 19 | + * 异常 | ||
| 20 | + */ | ||
| 21 | + EXCEPTION | ||
| 22 | + } | ||
| 23 | + | ||
| 24 | + private String userName; | ||
| 25 | + | ||
| 26 | + private String password; | ||
| 27 | + | ||
| 28 | + private TokenStatus status; | ||
| 29 | + | ||
| 30 | + public String getUserName() { | ||
| 31 | + return userName; | ||
| 32 | + } | ||
| 33 | + | ||
| 34 | + public void setUserName(String userName) { | ||
| 35 | + this.userName = userName; | ||
| 36 | + } | ||
| 37 | + | ||
| 38 | + public TokenStatus getStatus() { | ||
| 39 | + return status; | ||
| 40 | + } | ||
| 41 | + | ||
| 42 | + public void setStatus(TokenStatus status) { | ||
| 43 | + this.status = status; | ||
| 44 | + } | ||
| 45 | + | ||
| 46 | + public String getPassword() { | ||
| 47 | + return password; | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + public void setPassword(String password) { | ||
| 51 | + this.password = password; | ||
| 52 | + } | ||
| 53 | +} |
src/main/java/com/genersoft/iot/vmp/conf/security/dto/LoginUser.java
| @@ -19,6 +19,8 @@ public class LoginUser implements UserDetails, CredentialsContainer { | @@ -19,6 +19,8 @@ public class LoginUser implements UserDetails, CredentialsContainer { | ||
| 19 | */ | 19 | */ |
| 20 | private User user; | 20 | private User user; |
| 21 | 21 | ||
| 22 | + private String accessToken; | ||
| 23 | + | ||
| 22 | 24 | ||
| 23 | /** | 25 | /** |
| 24 | * 登录时间 | 26 | * 登录时间 |
| @@ -102,4 +104,11 @@ public class LoginUser implements UserDetails, CredentialsContainer { | @@ -102,4 +104,11 @@ public class LoginUser implements UserDetails, CredentialsContainer { | ||
| 102 | return user.getPushKey(); | 104 | return user.getPushKey(); |
| 103 | } | 105 | } |
| 104 | 106 | ||
| 107 | + public String getAccessToken() { | ||
| 108 | + return accessToken; | ||
| 109 | + } | ||
| 110 | + | ||
| 111 | + public void setAccessToken(String accessToken) { | ||
| 112 | + this.accessToken = accessToken; | ||
| 113 | + } | ||
| 105 | } | 114 | } |
src/main/java/com/genersoft/iot/vmp/gb28181/auth/DigestServerAuthenticationHelper.java
| @@ -171,7 +171,7 @@ public class DigestServerAuthenticationHelper { | @@ -171,7 +171,7 @@ public class DigestServerAuthenticationHelper { | ||
| 171 | */ | 171 | */ |
| 172 | public boolean doAuthenticatePlainTextPassword(Request request, String pass) { | 172 | public boolean doAuthenticatePlainTextPassword(Request request, String pass) { |
| 173 | AuthorizationHeader authHeader = (AuthorizationHeader) request.getHeader(AuthorizationHeader.NAME); | 173 | AuthorizationHeader authHeader = (AuthorizationHeader) request.getHeader(AuthorizationHeader.NAME); |
| 174 | - if ( authHeader == null ) { | 174 | + if ( authHeader == null || authHeader.getRealm() == null) { |
| 175 | return false; | 175 | return false; |
| 176 | } | 176 | } |
| 177 | String realm = authHeader.getRealm().trim(); | 177 | String realm = authHeader.getRealm().trim(); |
src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java
| @@ -188,6 +188,13 @@ public class Device { | @@ -188,6 +188,13 @@ public class Device { | ||
| 188 | @Schema(description = "SIP交互IP(设备访问平台的IP)") | 188 | @Schema(description = "SIP交互IP(设备访问平台的IP)") |
| 189 | private String localIp; | 189 | private String localIp; |
| 190 | 190 | ||
| 191 | + @Schema(description = "是否作为消息通道") | ||
| 192 | + private boolean asMessageChannel; | ||
| 193 | + | ||
| 194 | + @Schema(description = "设备注册的事务信息") | ||
| 195 | + private SipTransactionInfo sipTransactionInfo; | ||
| 196 | + | ||
| 197 | + | ||
| 191 | public String getDeviceId() { | 198 | public String getDeviceId() { |
| 192 | return deviceId; | 199 | return deviceId; |
| 193 | } | 200 | } |
| @@ -428,4 +435,20 @@ public class Device { | @@ -428,4 +435,20 @@ public class Device { | ||
| 428 | public void setKeepaliveIntervalTime(int keepaliveIntervalTime) { | 435 | public void setKeepaliveIntervalTime(int keepaliveIntervalTime) { |
| 429 | this.keepaliveIntervalTime = keepaliveIntervalTime; | 436 | this.keepaliveIntervalTime = keepaliveIntervalTime; |
| 430 | } | 437 | } |
| 438 | + | ||
| 439 | + public boolean isAsMessageChannel() { | ||
| 440 | + return asMessageChannel; | ||
| 441 | + } | ||
| 442 | + | ||
| 443 | + public void setAsMessageChannel(boolean asMessageChannel) { | ||
| 444 | + this.asMessageChannel = asMessageChannel; | ||
| 445 | + } | ||
| 446 | + | ||
| 447 | + public SipTransactionInfo getSipTransactionInfo() { | ||
| 448 | + return sipTransactionInfo; | ||
| 449 | + } | ||
| 450 | + | ||
| 451 | + public void setSipTransactionInfo(SipTransactionInfo sipTransactionInfo) { | ||
| 452 | + this.sipTransactionInfo = sipTransactionInfo; | ||
| 453 | + } | ||
| 431 | } | 454 | } |
src/main/java/com/genersoft/iot/vmp/gb28181/bean/ParentPlatform.java
| @@ -189,6 +189,9 @@ public class ParentPlatform { | @@ -189,6 +189,9 @@ public class ParentPlatform { | ||
| 189 | @Schema(description = "树类型 国标规定了两种树的展现方式 行政区划 CivilCode 和业务分组:BusinessGrou") | 189 | @Schema(description = "树类型 国标规定了两种树的展现方式 行政区划 CivilCode 和业务分组:BusinessGrou") |
| 190 | private String treeType; | 190 | private String treeType; |
| 191 | 191 | ||
| 192 | + @Schema(description = "是否作为消息通道") | ||
| 193 | + private boolean asMessageChannel; | ||
| 194 | + | ||
| 192 | public Integer getId() { | 195 | public Integer getId() { |
| 193 | return id; | 196 | return id; |
| 194 | } | 197 | } |
| @@ -428,4 +431,12 @@ public class ParentPlatform { | @@ -428,4 +431,12 @@ public class ParentPlatform { | ||
| 428 | public void setTreeType(String treeType) { | 431 | public void setTreeType(String treeType) { |
| 429 | this.treeType = treeType; | 432 | this.treeType = treeType; |
| 430 | } | 433 | } |
| 434 | + | ||
| 435 | + public boolean isAsMessageChannel() { | ||
| 436 | + return asMessageChannel; | ||
| 437 | + } | ||
| 438 | + | ||
| 439 | + public void setAsMessageChannel(boolean asMessageChannel) { | ||
| 440 | + this.asMessageChannel = asMessageChannel; | ||
| 441 | + } | ||
| 431 | } | 442 | } |
src/main/java/com/genersoft/iot/vmp/gb28181/bean/ParentPlatformCatch.java
| @@ -16,6 +16,8 @@ public class ParentPlatformCatch { | @@ -16,6 +16,8 @@ public class ParentPlatformCatch { | ||
| 16 | 16 | ||
| 17 | private ParentPlatform parentPlatform; | 17 | private ParentPlatform parentPlatform; |
| 18 | 18 | ||
| 19 | + private SipTransactionInfo sipTransactionInfo; | ||
| 20 | + | ||
| 19 | public String getId() { | 21 | public String getId() { |
| 20 | return id; | 22 | return id; |
| 21 | } | 23 | } |
| @@ -55,4 +57,12 @@ public class ParentPlatformCatch { | @@ -55,4 +57,12 @@ public class ParentPlatformCatch { | ||
| 55 | public void setCallId(String callId) { | 57 | public void setCallId(String callId) { |
| 56 | this.callId = callId; | 58 | this.callId = callId; |
| 57 | } | 59 | } |
| 60 | + | ||
| 61 | + public SipTransactionInfo getSipTransactionInfo() { | ||
| 62 | + return sipTransactionInfo; | ||
| 63 | + } | ||
| 64 | + | ||
| 65 | + public void setSipTransactionInfo(SipTransactionInfo sipTransactionInfo) { | ||
| 66 | + this.sipTransactionInfo = sipTransactionInfo; | ||
| 67 | + } | ||
| 58 | } | 68 | } |
src/main/java/com/genersoft/iot/vmp/gb28181/bean/RecordInfo.java
| 1 | package com.genersoft.iot.vmp.gb28181.bean; | 1 | package com.genersoft.iot.vmp.gb28181.bean; |
| 2 | 2 | ||
| 3 | 3 | ||
| 4 | +import io.swagger.v3.oas.annotations.media.Schema; | ||
| 5 | + | ||
| 4 | import java.time.Instant; | 6 | import java.time.Instant; |
| 5 | import java.util.List; | 7 | import java.util.List; |
| 6 | 8 | ||
| @@ -9,22 +11,29 @@ import java.util.List; | @@ -9,22 +11,29 @@ import java.util.List; | ||
| 9 | * @author: swwheihei | 11 | * @author: swwheihei |
| 10 | * @date: 2020年5月8日 下午2:05:56 | 12 | * @date: 2020年5月8日 下午2:05:56 |
| 11 | */ | 13 | */ |
| 14 | +@Schema(description = "设备录像查询结果信息") | ||
| 12 | public class RecordInfo { | 15 | public class RecordInfo { |
| 13 | 16 | ||
| 17 | + @Schema(description = "设备编号") | ||
| 14 | private String deviceId; | 18 | private String deviceId; |
| 15 | 19 | ||
| 20 | + @Schema(description = "通道编号") | ||
| 16 | private String channelId; | 21 | private String channelId; |
| 17 | 22 | ||
| 23 | + @Schema(description = "命令序列号") | ||
| 18 | private String sn; | 24 | private String sn; |
| 19 | 25 | ||
| 26 | + @Schema(description = "设备名称") | ||
| 20 | private String name; | 27 | private String name; |
| 21 | - | 28 | + |
| 29 | + @Schema(description = "列表总数") | ||
| 22 | private int sumNum; | 30 | private int sumNum; |
| 23 | 31 | ||
| 24 | private int count; | 32 | private int count; |
| 25 | 33 | ||
| 26 | private Instant lastTime; | 34 | private Instant lastTime; |
| 27 | - | 35 | + |
| 36 | + @Schema(description = "") | ||
| 28 | private List<RecordItem> recordList; | 37 | private List<RecordItem> recordList; |
| 29 | 38 | ||
| 30 | public String getDeviceId() { | 39 | public String getDeviceId() { |
src/main/java/com/genersoft/iot/vmp/gb28181/bean/RecordItem.java
| @@ -2,9 +2,9 @@ package com.genersoft.iot.vmp.gb28181.bean; | @@ -2,9 +2,9 @@ package com.genersoft.iot.vmp.gb28181.bean; | ||
| 2 | 2 | ||
| 3 | 3 | ||
| 4 | import com.genersoft.iot.vmp.utils.DateUtil; | 4 | import com.genersoft.iot.vmp.utils.DateUtil; |
| 5 | +import io.swagger.v3.oas.annotations.media.Schema; | ||
| 5 | import org.jetbrains.annotations.NotNull; | 6 | import org.jetbrains.annotations.NotNull; |
| 6 | 7 | ||
| 7 | -import java.text.ParseException; | ||
| 8 | import java.time.Instant; | 8 | import java.time.Instant; |
| 9 | import java.time.temporal.TemporalAccessor; | 9 | import java.time.temporal.TemporalAccessor; |
| 10 | 10 | ||
| @@ -13,26 +13,37 @@ import java.time.temporal.TemporalAccessor; | @@ -13,26 +13,37 @@ import java.time.temporal.TemporalAccessor; | ||
| 13 | * @author: swwheihei | 13 | * @author: swwheihei |
| 14 | * @date: 2020年5月8日 下午2:06:54 | 14 | * @date: 2020年5月8日 下午2:06:54 |
| 15 | */ | 15 | */ |
| 16 | +@Schema(description = "设备录像详情") | ||
| 16 | public class RecordItem implements Comparable<RecordItem>{ | 17 | public class RecordItem implements Comparable<RecordItem>{ |
| 17 | 18 | ||
| 19 | + @Schema(description = "设备编号") | ||
| 18 | private String deviceId; | 20 | private String deviceId; |
| 19 | - | 21 | + |
| 22 | + @Schema(description = "名称") | ||
| 20 | private String name; | 23 | private String name; |
| 21 | - | 24 | + |
| 25 | + @Schema(description = "文件路径名 (可选)") | ||
| 22 | private String filePath; | 26 | private String filePath; |
| 23 | 27 | ||
| 28 | + @Schema(description = "录像文件大小,单位:Byte(可选)") | ||
| 24 | private String fileSize; | 29 | private String fileSize; |
| 25 | 30 | ||
| 31 | + @Schema(description = "录像地址(可选)") | ||
| 26 | private String address; | 32 | private String address; |
| 27 | - | 33 | + |
| 34 | + @Schema(description = "录像开始时间(可选)") | ||
| 28 | private String startTime; | 35 | private String startTime; |
| 29 | - | 36 | + |
| 37 | + @Schema(description = "录像结束时间(可选)") | ||
| 30 | private String endTime; | 38 | private String endTime; |
| 31 | - | 39 | + |
| 40 | + @Schema(description = "保密属性(必选)缺省为0;0:不涉密,1:涉密") | ||
| 32 | private int secrecy; | 41 | private int secrecy; |
| 33 | - | 42 | + |
| 43 | + @Schema(description = "录像产生类型(可选)time或alarm 或 manua") | ||
| 34 | private String type; | 44 | private String type; |
| 35 | - | 45 | + |
| 46 | + @Schema(description = "录像触发者ID(可选)") | ||
| 36 | private String recorderId; | 47 | private String recorderId; |
| 37 | 48 | ||
| 38 | public String getDeviceId() { | 49 | public String getDeviceId() { |
src/main/java/com/genersoft/iot/vmp/gb28181/event/device/RequestTimeoutEventImpl.java
| 1 | package com.genersoft.iot.vmp.gb28181.event.device; | 1 | package com.genersoft.iot.vmp.gb28181.event.device; |
| 2 | 2 | ||
| 3 | import com.genersoft.iot.vmp.gb28181.bean.Device; | 3 | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| 4 | -import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; | ||
| 5 | import com.genersoft.iot.vmp.service.IDeviceService; | 4 | import com.genersoft.iot.vmp.service.IDeviceService; |
| 6 | import org.springframework.beans.factory.annotation.Autowired; | 5 | import org.springframework.beans.factory.annotation.Autowired; |
| 7 | import org.springframework.context.ApplicationListener; | 6 | import org.springframework.context.ApplicationListener; |
| @@ -9,8 +8,6 @@ import org.springframework.stereotype.Component; | @@ -9,8 +8,6 @@ import org.springframework.stereotype.Component; | ||
| 9 | 8 | ||
| 10 | import javax.sip.ClientTransaction; | 9 | import javax.sip.ClientTransaction; |
| 11 | import javax.sip.address.SipURI; | 10 | import javax.sip.address.SipURI; |
| 12 | -import javax.sip.header.CallIdHeader; | ||
| 13 | -import javax.sip.header.ToHeader; | ||
| 14 | import javax.sip.message.Request; | 11 | import javax.sip.message.Request; |
| 15 | 12 | ||
| 16 | /** | 13 | /** |
| @@ -34,7 +31,7 @@ public class RequestTimeoutEventImpl implements ApplicationListener<RequestTimeo | @@ -34,7 +31,7 @@ public class RequestTimeoutEventImpl implements ApplicationListener<RequestTimeo | ||
| 34 | if (device == null) { | 31 | if (device == null) { |
| 35 | return; | 32 | return; |
| 36 | } | 33 | } |
| 37 | - deviceService.offline(device.getDeviceId()); | 34 | + deviceService.offline(device.getDeviceId(), "等待消息超时"); |
| 38 | } | 35 | } |
| 39 | 36 | ||
| 40 | } | 37 | } |
src/main/java/com/genersoft/iot/vmp/gb28181/task/SipRunner.java
| @@ -61,9 +61,9 @@ public class SipRunner implements CommandLineRunner { | @@ -61,9 +61,9 @@ public class SipRunner implements CommandLineRunner { | ||
| 61 | 61 | ||
| 62 | for (Device device : deviceList) { | 62 | for (Device device : deviceList) { |
| 63 | if (deviceService.expire(device)){ | 63 | if (deviceService.expire(device)){ |
| 64 | - deviceService.offline(device.getDeviceId()); | 64 | + deviceService.offline(device.getDeviceId(), "注册已过期"); |
| 65 | }else { | 65 | }else { |
| 66 | - deviceService.online(device); | 66 | + deviceService.online(device, null); |
| 67 | } | 67 | } |
| 68 | } | 68 | } |
| 69 | // 重置cseq计数 | 69 | // 重置cseq计数 |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java
| @@ -120,7 +120,7 @@ public interface ISIPCommander { | @@ -120,7 +120,7 @@ public interface ISIPCommander { | ||
| 120 | */ | 120 | */ |
| 121 | void downloadStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, | 121 | void downloadStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, |
| 122 | String startTime, String endTime, int downloadSpeed, InviteStreamCallback inviteStreamCallback, InviteStreamCallback hookEvent, | 122 | String startTime, String endTime, int downloadSpeed, InviteStreamCallback inviteStreamCallback, InviteStreamCallback hookEvent, |
| 123 | - SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException; | 123 | + SipSubscribe.Event errorEvent,SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException; |
| 124 | 124 | ||
| 125 | 125 | ||
| 126 | /** | 126 | /** |
| @@ -217,7 +217,6 @@ public interface ISIPCommander { | @@ -217,7 +217,6 @@ public interface ISIPCommander { | ||
| 217 | * | 217 | * |
| 218 | * @param device 视频设备 | 218 | * @param device 视频设备 |
| 219 | * @param channelId 通道id,非通道则是设备本身 | 219 | * @param channelId 通道id,非通道则是设备本身 |
| 220 | - * @param frontCmd 上级平台的指令,如果存在则直接下发 | ||
| 221 | * @param enabled 看守位使能:1 = 开启,0 = 关闭 | 220 | * @param enabled 看守位使能:1 = 开启,0 = 关闭 |
| 222 | * @param resetTime 自动归位时间间隔,开启看守位时使用,单位:秒(s) | 221 | * @param resetTime 自动归位时间间隔,开启看守位时使用,单位:秒(s) |
| 223 | * @param presetIndex 调用预置位编号,开启看守位时使用,取值范围0~255 | 222 | * @param presetIndex 调用预置位编号,开启看守位时使用,取值范围0~255 |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java
| @@ -22,12 +22,10 @@ public interface ISIPCommanderForPlatform { | @@ -22,12 +22,10 @@ public interface ISIPCommanderForPlatform { | ||
| 22 | * @param parentPlatform | 22 | * @param parentPlatform |
| 23 | * @return | 23 | * @return |
| 24 | */ | 24 | */ |
| 25 | - void register(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent) | ||
| 26 | - throws InvalidArgumentException, ParseException, SipException; | 25 | + void register(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) throws InvalidArgumentException, ParseException, SipException; |
| 27 | 26 | ||
| 28 | - void register(ParentPlatform parentPlatform, String callId, WWWAuthenticateHeader www, | ||
| 29 | - SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent, boolean registerAgain, boolean isRegister) | ||
| 30 | - throws SipException, InvalidArgumentException, ParseException; | 27 | + void register(ParentPlatform parentPlatform, SipTransactionInfo sipTransactionInfo, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) throws InvalidArgumentException, ParseException, SipException; |
| 28 | + void register(ParentPlatform parentPlatform, SipTransactionInfo sipTransactionInfo, WWWAuthenticateHeader www, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent, boolean registerAgain, boolean isRegister) throws SipException, InvalidArgumentException, ParseException; | ||
| 31 | 29 | ||
| 32 | /** | 30 | /** |
| 33 | * 向上级平台注销 | 31 | * 向上级平台注销 |
| @@ -35,8 +33,7 @@ public interface ISIPCommanderForPlatform { | @@ -35,8 +33,7 @@ public interface ISIPCommanderForPlatform { | ||
| 35 | * @param parentPlatform | 33 | * @param parentPlatform |
| 36 | * @return | 34 | * @return |
| 37 | */ | 35 | */ |
| 38 | - void unregister(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent) | ||
| 39 | - throws InvalidArgumentException, ParseException, SipException; | 36 | + void unregister(ParentPlatform parentPlatform, SipTransactionInfo sipTransactionInfo, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) throws InvalidArgumentException, ParseException, SipException; |
| 40 | 37 | ||
| 41 | 38 | ||
| 42 | /** | 39 | /** |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderPlarformProvider.java
| @@ -46,7 +46,7 @@ public class SIPRequestHeaderPlarformProvider { | @@ -46,7 +46,7 @@ public class SIPRequestHeaderPlarformProvider { | ||
| 46 | @Autowired | 46 | @Autowired |
| 47 | private IRedisCatchStorage redisCatchStorage; | 47 | private IRedisCatchStorage redisCatchStorage; |
| 48 | 48 | ||
| 49 | - public Request createRegisterRequest(@NotNull ParentPlatform parentPlatform, long CSeq, String fromTag, String viaTag, CallIdHeader callIdHeader, boolean isRegister) throws ParseException, InvalidArgumentException, PeerUnavailableException { | 49 | + public Request createRegisterRequest(@NotNull ParentPlatform parentPlatform, long CSeq, String fromTag, String toTag, CallIdHeader callIdHeader, boolean isRegister) throws ParseException, InvalidArgumentException, PeerUnavailableException { |
| 50 | Request request = null; | 50 | Request request = null; |
| 51 | String sipAddress = parentPlatform.getDeviceIp() + ":" + parentPlatform.getDevicePort(); | 51 | String sipAddress = parentPlatform.getDeviceIp() + ":" + parentPlatform.getDevicePort(); |
| 52 | //请求行 | 52 | //请求行 |
| @@ -54,7 +54,8 @@ public class SIPRequestHeaderPlarformProvider { | @@ -54,7 +54,8 @@ public class SIPRequestHeaderPlarformProvider { | ||
| 54 | parentPlatform.getServerIP() + ":" + parentPlatform.getServerPort()); | 54 | parentPlatform.getServerIP() + ":" + parentPlatform.getServerPort()); |
| 55 | //via | 55 | //via |
| 56 | ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>(); | 56 | ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>(); |
| 57 | - ViaHeader viaHeader = sipLayer.getSipFactory().createHeaderFactory().createViaHeader(parentPlatform.getServerIP(), parentPlatform.getServerPort(), parentPlatform.getTransport(), viaTag); | 57 | + ViaHeader viaHeader = sipLayer.getSipFactory().createHeaderFactory().createViaHeader(parentPlatform.getServerIP(), |
| 58 | + parentPlatform.getServerPort(), parentPlatform.getTransport(), SipUtils.getNewViaTag()); | ||
| 58 | viaHeader.setRPort(); | 59 | viaHeader.setRPort(); |
| 59 | viaHeaders.add(viaHeader); | 60 | viaHeaders.add(viaHeader); |
| 60 | //from | 61 | //from |
| @@ -64,7 +65,7 @@ public class SIPRequestHeaderPlarformProvider { | @@ -64,7 +65,7 @@ public class SIPRequestHeaderPlarformProvider { | ||
| 64 | //to | 65 | //to |
| 65 | SipURI toSipURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(parentPlatform.getDeviceGBId(), sipConfig.getDomain()); | 66 | SipURI toSipURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(parentPlatform.getDeviceGBId(), sipConfig.getDomain()); |
| 66 | Address toAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(toSipURI); | 67 | Address toAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(toSipURI); |
| 67 | - ToHeader toHeader = sipLayer.getSipFactory().createHeaderFactory().createToHeader(toAddress,null); | 68 | + ToHeader toHeader = sipLayer.getSipFactory().createHeaderFactory().createToHeader(toAddress,toTag); |
| 68 | 69 | ||
| 69 | //Forwards | 70 | //Forwards |
| 70 | MaxForwardsHeader maxForwards = sipLayer.getSipFactory().createHeaderFactory().createMaxForwardsHeader(70); | 71 | MaxForwardsHeader maxForwards = sipLayer.getSipFactory().createHeaderFactory().createMaxForwardsHeader(70); |
| @@ -86,15 +87,21 @@ public class SIPRequestHeaderPlarformProvider { | @@ -86,15 +87,21 @@ public class SIPRequestHeaderPlarformProvider { | ||
| 86 | return request; | 87 | return request; |
| 87 | } | 88 | } |
| 88 | 89 | ||
| 89 | - public Request createRegisterRequest(@NotNull ParentPlatform parentPlatform, String fromTag, String viaTag, | ||
| 90 | - String callId, WWWAuthenticateHeader www , CallIdHeader callIdHeader, boolean isRegister) throws ParseException, PeerUnavailableException, InvalidArgumentException { | 90 | + public Request createRegisterRequest(@NotNull ParentPlatform parentPlatform, String fromTag, String toTag, |
| 91 | + WWWAuthenticateHeader www , CallIdHeader callIdHeader, boolean isRegister) throws ParseException, PeerUnavailableException, InvalidArgumentException { | ||
| 91 | 92 | ||
| 92 | 93 | ||
| 93 | - Request registerRequest = createRegisterRequest(parentPlatform, redisCatchStorage.getCSEQ(), fromTag, viaTag, callIdHeader, isRegister); | 94 | + Request registerRequest = createRegisterRequest(parentPlatform, redisCatchStorage.getCSEQ(), fromTag, toTag, callIdHeader, isRegister); |
| 94 | SipURI requestURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(parentPlatform.getServerGBId(), parentPlatform.getServerIP() + ":" + parentPlatform.getServerPort()); | 95 | SipURI requestURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(parentPlatform.getServerGBId(), parentPlatform.getServerIP() + ":" + parentPlatform.getServerPort()); |
| 95 | if (www == null) { | 96 | if (www == null) { |
| 96 | AuthorizationHeader authorizationHeader = sipLayer.getSipFactory().createHeaderFactory().createAuthorizationHeader("Digest"); | 97 | AuthorizationHeader authorizationHeader = sipLayer.getSipFactory().createHeaderFactory().createAuthorizationHeader("Digest"); |
| 97 | - authorizationHeader.setUsername(parentPlatform.getDeviceGBId()); | 98 | + String username = parentPlatform.getUsername(); |
| 99 | + if ( username == null || username == "" ) | ||
| 100 | + { | ||
| 101 | + authorizationHeader.setUsername(parentPlatform.getDeviceGBId()); | ||
| 102 | + } else { | ||
| 103 | + authorizationHeader.setUsername(username); | ||
| 104 | + } | ||
| 98 | authorizationHeader.setURI(requestURI); | 105 | authorizationHeader.setURI(requestURI); |
| 99 | authorizationHeader.setAlgorithm("MD5"); | 106 | authorizationHeader.setAlgorithm("MD5"); |
| 100 | registerRequest.addHeader(authorizationHeader); | 107 | registerRequest.addHeader(authorizationHeader); |
| @@ -108,8 +115,6 @@ public class SIPRequestHeaderPlarformProvider { | @@ -108,8 +115,6 @@ public class SIPRequestHeaderPlarformProvider { | ||
| 108 | // qop 保护质量 包含auth(默认的)和auth-int(增加了报文完整性检测)两种策略 | 115 | // qop 保护质量 包含auth(默认的)和auth-int(增加了报文完整性检测)两种策略 |
| 109 | String qop = www.getQop(); | 116 | String qop = www.getQop(); |
| 110 | 117 | ||
| 111 | - callIdHeader.setCallId(callId); | ||
| 112 | - | ||
| 113 | String cNonce = null; | 118 | String cNonce = null; |
| 114 | String nc = "00000001"; | 119 | String nc = "00000001"; |
| 115 | if (qop != null) { | 120 | if (qop != null) { |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
| @@ -276,7 +276,7 @@ public class SIPCommander implements ISIPCommander { | @@ -276,7 +276,7 @@ public class SIPCommander implements ISIPCommander { | ||
| 276 | return; | 276 | return; |
| 277 | } | 277 | } |
| 278 | 278 | ||
| 279 | - logger.info("{} 分配的ZLM为: {} [{}:{}]", stream, mediaServerItem.getId(), mediaServerItem.getIp(), ssrcInfo.getPort()); | 279 | + logger.info("{} 分配的ZLM为: {} [{}:{}]", stream, mediaServerItem.getId(), mediaServerItem.getSdpIp(), ssrcInfo.getPort()); |
| 280 | HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", stream, true, "rtsp", mediaServerItem.getId()); | 280 | HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", stream, true, "rtsp", mediaServerItem.getId()); |
| 281 | subscribe.addSubscribe(hookSubscribe, (MediaServerItem mediaServerItemInUse, JSONObject json) -> { | 281 | subscribe.addSubscribe(hookSubscribe, (MediaServerItem mediaServerItemInUse, JSONObject json) -> { |
| 282 | if (event != null) { | 282 | if (event != null) { |
| @@ -377,7 +377,7 @@ public class SIPCommander implements ISIPCommander { | @@ -377,7 +377,7 @@ public class SIPCommander implements ISIPCommander { | ||
| 377 | SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException { | 377 | SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException { |
| 378 | 378 | ||
| 379 | 379 | ||
| 380 | - logger.info("{} 分配的ZLM为: {} [{}:{}]", ssrcInfo.getStream(), mediaServerItem.getId(), mediaServerItem.getIp(), ssrcInfo.getPort()); | 380 | + logger.info("{} 分配的ZLM为: {} [{}:{}]", ssrcInfo.getStream(), mediaServerItem.getSdpIp(), mediaServerItem.getIp(), ssrcInfo.getPort()); |
| 381 | String sdpIp; | 381 | String sdpIp; |
| 382 | if (!ObjectUtils.isEmpty(device.getSdpIp())) { | 382 | if (!ObjectUtils.isEmpty(device.getSdpIp())) { |
| 383 | sdpIp = device.getSdpIp(); | 383 | sdpIp = device.getSdpIp(); |
| @@ -479,10 +479,11 @@ public class SIPCommander implements ISIPCommander { | @@ -479,10 +479,11 @@ public class SIPCommander implements ISIPCommander { | ||
| 479 | */ | 479 | */ |
| 480 | @Override | 480 | @Override |
| 481 | public void downloadStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, | 481 | public void downloadStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, |
| 482 | - String startTime, String endTime, int downloadSpeed, InviteStreamCallback inviteStreamCallback, InviteStreamCallback hookEvent, | ||
| 483 | - SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException { | 482 | + String startTime, String endTime, int downloadSpeed, |
| 483 | + InviteStreamCallback inviteStreamCallback, InviteStreamCallback hookEvent, | ||
| 484 | + SipSubscribe.Event errorEvent,SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException { | ||
| 484 | 485 | ||
| 485 | - logger.info("{} 分配的ZLM为: {} [{}:{}]", ssrcInfo.getStream(), mediaServerItem.getId(), mediaServerItem.getIp(), ssrcInfo.getPort()); | 486 | + logger.info("{} 分配的ZLM为: {} [{}:{}]", ssrcInfo.getStream(), mediaServerItem.getSdpIp(), mediaServerItem.getIp(), ssrcInfo.getPort()); |
| 486 | String sdpIp; | 487 | String sdpIp; |
| 487 | if (!ObjectUtils.isEmpty(device.getSdpIp())) { | 488 | if (!ObjectUtils.isEmpty(device.getSdpIp())) { |
| 488 | sdpIp = device.getSdpIp(); | 489 | sdpIp = device.getSdpIp(); |
| @@ -549,11 +550,14 @@ public class SIPCommander implements ISIPCommander { | @@ -549,11 +550,14 @@ public class SIPCommander implements ISIPCommander { | ||
| 549 | content.append("a=downloadspeed:" + downloadSpeed + "\r\n"); | 550 | content.append("a=downloadspeed:" + downloadSpeed + "\r\n"); |
| 550 | 551 | ||
| 551 | content.append("y=" + ssrcInfo.getSsrc() + "\r\n");//ssrc | 552 | content.append("y=" + ssrcInfo.getSsrc() + "\r\n");//ssrc |
| 552 | - | 553 | + logger.debug("此时请求下载信令的ssrc===>{}",ssrcInfo.getSsrc()); |
| 553 | HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", ssrcInfo.getStream(), true, null, mediaServerItem.getId()); | 554 | HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", ssrcInfo.getStream(), true, null, mediaServerItem.getId()); |
| 554 | // 添加订阅 | 555 | // 添加订阅 |
| 556 | + CallIdHeader newCallIdHeader = sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()), device.getTransport()); | ||
| 557 | + String callId=newCallIdHeader.getCallId(); | ||
| 555 | subscribe.addSubscribe(hookSubscribe, (MediaServerItem mediaServerItemInUse, JSONObject json) -> { | 558 | subscribe.addSubscribe(hookSubscribe, (MediaServerItem mediaServerItemInUse, JSONObject json) -> { |
| 556 | - hookEvent.call(new InviteStreamInfo(mediaServerItem, json,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport()).getCallId(), "rtp", ssrcInfo.getStream())); | 559 | + logger.debug("sipc 添加订阅===callId {}",callId); |
| 560 | + hookEvent.call(new InviteStreamInfo(mediaServerItem, json,callId, "rtp", ssrcInfo.getStream())); | ||
| 557 | subscribe.removeSubscribe(hookSubscribe); | 561 | subscribe.removeSubscribe(hookSubscribe); |
| 558 | hookSubscribe.getContent().put("regist", false); | 562 | hookSubscribe.getContent().put("regist", false); |
| 559 | hookSubscribe.getContent().put("schema", "rtsp"); | 563 | hookSubscribe.getContent().put("schema", "rtsp"); |
| @@ -562,7 +566,7 @@ public class SIPCommander implements ISIPCommander { | @@ -562,7 +566,7 @@ public class SIPCommander implements ISIPCommander { | ||
| 562 | (MediaServerItem mediaServerItemForEnd, JSONObject jsonForEnd) -> { | 566 | (MediaServerItem mediaServerItemForEnd, JSONObject jsonForEnd) -> { |
| 563 | logger.info("[录像]下载结束, 发送BYE"); | 567 | logger.info("[录像]下载结束, 发送BYE"); |
| 564 | try { | 568 | try { |
| 565 | - streamByeCmd(device, channelId, ssrcInfo.getStream(),sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport()).getCallId()); | 569 | + streamByeCmd(device, channelId, ssrcInfo.getStream(),callId); |
| 566 | } catch (InvalidArgumentException | ParseException | SipException | | 570 | } catch (InvalidArgumentException | ParseException | SipException | |
| 567 | SsrcTransactionNotFoundException e) { | 571 | SsrcTransactionNotFoundException e) { |
| 568 | logger.error("[录像]下载结束, 发送BYE失败 {}", e.getMessage()); | 572 | logger.error("[录像]下载结束, 发送BYE失败 {}", e.getMessage()); |
| @@ -570,15 +574,24 @@ public class SIPCommander implements ISIPCommander { | @@ -570,15 +574,24 @@ public class SIPCommander implements ISIPCommander { | ||
| 570 | }); | 574 | }); |
| 571 | }); | 575 | }); |
| 572 | 576 | ||
| 573 | - Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport()), ssrcInfo.getSsrc()); | 577 | + Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, SipUtils.getNewFromTag(), null,newCallIdHeader, ssrcInfo.getSsrc()); |
| 574 | if (inviteStreamCallback != null) { | 578 | if (inviteStreamCallback != null) { |
| 575 | - inviteStreamCallback.call(new InviteStreamInfo(mediaServerItem, null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport()).getCallId(), "rtp", ssrcInfo.getStream())); | 579 | + inviteStreamCallback.call(new InviteStreamInfo(mediaServerItem, null,callId, "rtp", ssrcInfo.getStream())); |
| 576 | } | 580 | } |
| 577 | 581 | ||
| 578 | - sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent, okEvent -> { | ||
| 579 | - ResponseEvent responseEvent = (ResponseEvent) okEvent.event; | 582 | + sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent, event -> { |
| 583 | + ResponseEvent responseEvent = (ResponseEvent) event.event; | ||
| 580 | SIPResponse response = (SIPResponse) responseEvent.getResponse(); | 584 | SIPResponse response = (SIPResponse) responseEvent.getResponse(); |
| 581 | - streamSession.put(device.getDeviceId(), channelId, response.getCallIdHeader().getCallId(), ssrcInfo.getStream(), ssrcInfo.getSsrc(), mediaServerItem.getId(), response, VideoStreamSessionManager.SessionType.download); | 585 | + String contentString =new String(response.getRawContent()); |
| 586 | + int ssrcIndex = contentString.indexOf("y="); | ||
| 587 | + String ssrc=ssrcInfo.getSsrc(); | ||
| 588 | + if (ssrcIndex >= 0) { | ||
| 589 | + ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12); | ||
| 590 | + } | ||
| 591 | + logger.debug("接收到的下载响应ssrc====>{}",ssrcInfo.getSsrc()); | ||
| 592 | + logger.debug("接收到的下载响应ssrc====>{}",ssrc); | ||
| 593 | + streamSession.put(device.getDeviceId(), channelId, response.getCallIdHeader().getCallId(), ssrcInfo.getStream(), ssrc, mediaServerItem.getId(), response, VideoStreamSessionManager.SessionType.download); | ||
| 594 | + okEvent.response(event); | ||
| 582 | }); | 595 | }); |
| 583 | } | 596 | } |
| 584 | 597 | ||
| @@ -778,7 +791,7 @@ public class SIPCommander implements ISIPCommander { | @@ -778,7 +791,7 @@ public class SIPCommander implements ISIPCommander { | ||
| 778 | cmdXml.append("<GuardCmd>" + guardCmdStr + "</GuardCmd>\r\n"); | 791 | cmdXml.append("<GuardCmd>" + guardCmdStr + "</GuardCmd>\r\n"); |
| 779 | cmdXml.append("</Control>\r\n"); | 792 | cmdXml.append("</Control>\r\n"); |
| 780 | 793 | ||
| 781 | - | 794 | + |
| 782 | 795 | ||
| 783 | Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport())); | 796 | Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport())); |
| 784 | sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent,okEvent); | 797 | sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent,okEvent); |
| @@ -854,7 +867,6 @@ public class SIPCommander implements ISIPCommander { | @@ -854,7 +867,6 @@ public class SIPCommander implements ISIPCommander { | ||
| 854 | * | 867 | * |
| 855 | * @param device 视频设备 | 868 | * @param device 视频设备 |
| 856 | * @param channelId 通道id,非通道则是设备本身 | 869 | * @param channelId 通道id,非通道则是设备本身 |
| 857 | - * @param frontCmd 上级平台的指令,如果存在则直接下发 | ||
| 858 | * @param enabled 看守位使能:1 = 开启,0 = 关闭 | 870 | * @param enabled 看守位使能:1 = 开启,0 = 关闭 |
| 859 | * @param resetTime 自动归位时间间隔,开启看守位时使用,单位:秒(s) | 871 | * @param resetTime 自动归位时间间隔,开启看守位时使用,单位:秒(s) |
| 860 | * @param presetIndex 调用预置位编号,开启看守位时使用,取值范围0~255 | 872 | * @param presetIndex 调用预置位编号,开启看守位时使用,取值范围0~255 |
| @@ -978,7 +990,7 @@ public class SIPCommander implements ISIPCommander { | @@ -978,7 +990,7 @@ public class SIPCommander implements ISIPCommander { | ||
| 978 | catalogXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n"); | 990 | catalogXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n"); |
| 979 | catalogXml.append("</Query>\r\n"); | 991 | catalogXml.append("</Query>\r\n"); |
| 980 | 992 | ||
| 981 | - | 993 | + |
| 982 | 994 | ||
| 983 | Request request = headerProvider.createMessageRequest(device, catalogXml.toString(), null, SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport())); | 995 | Request request = headerProvider.createMessageRequest(device, catalogXml.toString(), null, SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport())); |
| 984 | 996 | ||
| @@ -1181,7 +1193,6 @@ public class SIPCommander implements ISIPCommander { | @@ -1181,7 +1193,6 @@ public class SIPCommander implements ISIPCommander { | ||
| 1181 | cmdXml.append("</Query>\r\n"); | 1193 | cmdXml.append("</Query>\r\n"); |
| 1182 | 1194 | ||
| 1183 | 1195 | ||
| 1184 | - | ||
| 1185 | Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport())); | 1196 | Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport())); |
| 1186 | sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent); | 1197 | sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent); |
| 1187 | } | 1198 | } |
| @@ -1427,7 +1438,7 @@ public class SIPCommander implements ISIPCommander { | @@ -1427,7 +1438,7 @@ public class SIPCommander implements ISIPCommander { | ||
| 1427 | if (device == null) { | 1438 | if (device == null) { |
| 1428 | return; | 1439 | return; |
| 1429 | } | 1440 | } |
| 1430 | - logger.info("[发送 报警通知] {}/{}->{},{}", device.getDeviceId(), deviceAlarm.getChannelId(), | 1441 | + logger.info("[发送报警通知]设备: {}/{}->{},{}", device.getDeviceId(), deviceAlarm.getChannelId(), |
| 1431 | deviceAlarm.getLongitude(), deviceAlarm.getLatitude()); | 1442 | deviceAlarm.getLongitude(), deviceAlarm.getLatitude()); |
| 1432 | 1443 | ||
| 1433 | String characterSet = device.getCharset(); | 1444 | String characterSet = device.getCharset(); |
| @@ -1439,7 +1450,7 @@ public class SIPCommander implements ISIPCommander { | @@ -1439,7 +1450,7 @@ public class SIPCommander implements ISIPCommander { | ||
| 1439 | deviceStatusXml.append("<DeviceID>" + deviceAlarm.getChannelId() + "</DeviceID>\r\n"); | 1450 | deviceStatusXml.append("<DeviceID>" + deviceAlarm.getChannelId() + "</DeviceID>\r\n"); |
| 1440 | deviceStatusXml.append("<AlarmPriority>" + deviceAlarm.getAlarmPriority() + "</AlarmPriority>\r\n"); | 1451 | deviceStatusXml.append("<AlarmPriority>" + deviceAlarm.getAlarmPriority() + "</AlarmPriority>\r\n"); |
| 1441 | deviceStatusXml.append("<AlarmMethod>" + deviceAlarm.getAlarmMethod() + "</AlarmMethod>\r\n"); | 1452 | deviceStatusXml.append("<AlarmMethod>" + deviceAlarm.getAlarmMethod() + "</AlarmMethod>\r\n"); |
| 1442 | - deviceStatusXml.append("<AlarmTime>" + deviceAlarm.getAlarmTime() + "</AlarmTime>\r\n"); | 1453 | + deviceStatusXml.append("<AlarmTime>" + DateUtil.yyyy_MM_dd_HH_mm_ssToISO8601(deviceAlarm.getAlarmTime()) + "</AlarmTime>\r\n"); |
| 1443 | deviceStatusXml.append("<AlarmDescription>" + deviceAlarm.getAlarmDescription() + "</AlarmDescription>\r\n"); | 1454 | deviceStatusXml.append("<AlarmDescription>" + deviceAlarm.getAlarmDescription() + "</AlarmDescription>\r\n"); |
| 1444 | deviceStatusXml.append("<Longitude>" + deviceAlarm.getLongitude() + "</Longitude>\r\n"); | 1455 | deviceStatusXml.append("<Longitude>" + deviceAlarm.getLongitude() + "</Longitude>\r\n"); |
| 1445 | deviceStatusXml.append("<Latitude>" + deviceAlarm.getLatitude() + "</Latitude>\r\n"); | 1456 | deviceStatusXml.append("<Latitude>" + deviceAlarm.getLatitude() + "</Latitude>\r\n"); |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java
| @@ -24,6 +24,7 @@ import com.genersoft.iot.vmp.service.bean.SSRCInfo; | @@ -24,6 +24,7 @@ import com.genersoft.iot.vmp.service.bean.SSRCInfo; | ||
| 24 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; | 24 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| 25 | import com.genersoft.iot.vmp.storager.dao.dto.PlatformRegisterInfo; | 25 | import com.genersoft.iot.vmp.storager.dao.dto.PlatformRegisterInfo; |
| 26 | import com.genersoft.iot.vmp.utils.DateUtil; | 26 | import com.genersoft.iot.vmp.utils.DateUtil; |
| 27 | +import com.genersoft.iot.vmp.utils.GitUtil; | ||
| 27 | import gov.nist.javax.sip.message.MessageFactoryImpl; | 28 | import gov.nist.javax.sip.message.MessageFactoryImpl; |
| 28 | import gov.nist.javax.sip.message.SIPRequest; | 29 | import gov.nist.javax.sip.message.SIPRequest; |
| 29 | import gov.nist.javax.sip.message.SIPResponse; | 30 | import gov.nist.javax.sip.message.SIPResponse; |
| @@ -85,26 +86,49 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { | @@ -85,26 +86,49 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { | ||
| 85 | @Autowired | 86 | @Autowired |
| 86 | private DynamicTask dynamicTask; | 87 | private DynamicTask dynamicTask; |
| 87 | 88 | ||
| 89 | + @Autowired | ||
| 90 | + private GitUtil gitUtil; | ||
| 91 | + | ||
| 88 | @Override | 92 | @Override |
| 89 | public void register(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) throws InvalidArgumentException, ParseException, SipException { | 93 | public void register(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) throws InvalidArgumentException, ParseException, SipException { |
| 90 | register(parentPlatform, null, null, errorEvent, okEvent, false, true); | 94 | register(parentPlatform, null, null, errorEvent, okEvent, false, true); |
| 91 | } | 95 | } |
| 92 | 96 | ||
| 93 | @Override | 97 | @Override |
| 94 | - public void unregister(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) throws InvalidArgumentException, ParseException, SipException { | ||
| 95 | - register(parentPlatform, null, null, errorEvent, okEvent, false, false); | 98 | + public void register(ParentPlatform parentPlatform, SipTransactionInfo sipTransactionInfo, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) throws InvalidArgumentException, ParseException, SipException { |
| 99 | + | ||
| 100 | + register(parentPlatform, sipTransactionInfo, null, errorEvent, okEvent, false, true); | ||
| 96 | } | 101 | } |
| 97 | 102 | ||
| 98 | @Override | 103 | @Override |
| 99 | - public void register(ParentPlatform parentPlatform, @Nullable String callId, @Nullable WWWAuthenticateHeader www, | 104 | + public void unregister(ParentPlatform parentPlatform, SipTransactionInfo sipTransactionInfo, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) throws InvalidArgumentException, ParseException, SipException { |
| 105 | + register(parentPlatform, sipTransactionInfo, null, errorEvent, okEvent, false, false); | ||
| 106 | + } | ||
| 107 | + | ||
| 108 | + @Override | ||
| 109 | + public void register(ParentPlatform parentPlatform, @Nullable SipTransactionInfo sipTransactionInfo, @Nullable WWWAuthenticateHeader www, | ||
| 100 | SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent, boolean registerAgain, boolean isRegister) throws SipException, InvalidArgumentException, ParseException { | 110 | SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent, boolean registerAgain, boolean isRegister) throws SipException, InvalidArgumentException, ParseException { |
| 101 | Request request; | 111 | Request request; |
| 102 | - if (!registerAgain ) { | ||
| 103 | - CallIdHeader callIdHeader = sipSender.getNewCallIdHeader(parentPlatform.getDeviceIp(),parentPlatform.getTransport()); | ||
| 104 | 112 | ||
| 113 | + CallIdHeader callIdHeader = sipSender.getNewCallIdHeader(parentPlatform.getDeviceIp(),parentPlatform.getTransport()); | ||
| 114 | + String fromTag = SipUtils.getNewFromTag(); | ||
| 115 | + String toTag = null; | ||
| 116 | + if (sipTransactionInfo != null ) { | ||
| 117 | + if (sipTransactionInfo.getCallId() != null) { | ||
| 118 | + callIdHeader.setCallId(sipTransactionInfo.getCallId()); | ||
| 119 | + } | ||
| 120 | + if (sipTransactionInfo.getFromTag() != null) { | ||
| 121 | + fromTag = sipTransactionInfo.getFromTag(); | ||
| 122 | + } | ||
| 123 | + if (sipTransactionInfo.getToTag() != null) { | ||
| 124 | + toTag = sipTransactionInfo.getToTag(); | ||
| 125 | + } | ||
| 126 | + } | ||
| 127 | + | ||
| 128 | + if (!registerAgain ) { | ||
| 105 | request = headerProviderPlatformProvider.createRegisterRequest(parentPlatform, | 129 | request = headerProviderPlatformProvider.createRegisterRequest(parentPlatform, |
| 106 | - redisCatchStorage.getCSEQ(), SipUtils.getNewFromTag(), | ||
| 107 | - SipUtils.getNewViaTag(), callIdHeader, isRegister); | 130 | + redisCatchStorage.getCSEQ(), fromTag, |
| 131 | + toTag, callIdHeader, isRegister); | ||
| 108 | // 将 callid 写入缓存, 等注册成功可以更新状态 | 132 | // 将 callid 写入缓存, 等注册成功可以更新状态 |
| 109 | String callIdFromHeader = callIdHeader.getCallId(); | 133 | String callIdFromHeader = callIdHeader.getCallId(); |
| 110 | redisCatchStorage.updatePlatformRegisterInfo(callIdFromHeader, PlatformRegisterInfo.getInstance(parentPlatform.getServerGBId(), isRegister)); | 134 | redisCatchStorage.updatePlatformRegisterInfo(callIdFromHeader, PlatformRegisterInfo.getInstance(parentPlatform.getServerGBId(), isRegister)); |
| @@ -122,8 +146,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { | @@ -122,8 +146,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { | ||
| 122 | }); | 146 | }); |
| 123 | 147 | ||
| 124 | }else { | 148 | }else { |
| 125 | - CallIdHeader callIdHeader = sipSender.getNewCallIdHeader(parentPlatform.getDeviceIp(),parentPlatform.getTransport()); | ||
| 126 | - request = headerProviderPlatformProvider.createRegisterRequest(parentPlatform, SipUtils.getNewFromTag(), null, callId, www, callIdHeader, isRegister); | 149 | + request = headerProviderPlatformProvider.createRegisterRequest(parentPlatform, fromTag, toTag, www, callIdHeader, isRegister); |
| 127 | } | 150 | } |
| 128 | 151 | ||
| 129 | sipSender.transmitRequest(parentPlatform.getDeviceIp(), request, null, okEvent); | 152 | sipSender.transmitRequest(parentPlatform.getDeviceIp(), request, null, okEvent); |
| @@ -245,6 +268,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { | @@ -245,6 +268,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { | ||
| 245 | catalogXml.append("<IPAddress>" + channel.getIpAddress() + "</IPAddress>\r\n"); | 268 | catalogXml.append("<IPAddress>" + channel.getIpAddress() + "</IPAddress>\r\n"); |
| 246 | catalogXml.append("<Port>" + channel.getPort() + "</Port>\r\n"); | 269 | catalogXml.append("<Port>" + channel.getPort() + "</Port>\r\n"); |
| 247 | catalogXml.append("<Password>" + channel.getPort() + "</Password>\r\n"); | 270 | catalogXml.append("<Password>" + channel.getPort() + "</Password>\r\n"); |
| 271 | + catalogXml.append("<PTZType>" + channel.getPTZType() + "</PTZType>\r\n"); | ||
| 248 | catalogXml.append("<Status>" + (channel.getStatus() == 1?"ON":"OFF") + "</Status>\r\n"); | 272 | catalogXml.append("<Status>" + (channel.getStatus() == 1?"ON":"OFF") + "</Status>\r\n"); |
| 249 | catalogXml.append("<Longitude>" + | 273 | catalogXml.append("<Longitude>" + |
| 250 | (channel.getLongitudeWgs84() != 0? channel.getLongitudeWgs84():channel.getLongitude()) | 274 | (channel.getLongitudeWgs84() != 0? channel.getLongitudeWgs84():channel.getLongitude()) |
| @@ -285,6 +309,9 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { | @@ -285,6 +309,9 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { | ||
| 285 | 309 | ||
| 286 | String callId = request.getCallIdHeader().getCallId(); | 310 | String callId = request.getCallIdHeader().getCallId(); |
| 287 | 311 | ||
| 312 | + logger.info("[命令发送] 国标级联{} 目录查询回复: 共{}条,已发送{}条", parentPlatform.getServerGBId(), | ||
| 313 | + channels.size(), Math.min(index + parentPlatform.getCatalogGroup(), channels.size())); | ||
| 314 | + logger.debug(catalogXml); | ||
| 288 | if (sendAfterResponse) { | 315 | if (sendAfterResponse) { |
| 289 | // 默认按照收到200回复后发送下一条, 如果超时收不到回复,就以30毫秒的间隔直接发送。 | 316 | // 默认按照收到200回复后发送下一条, 如果超时收不到回复,就以30毫秒的间隔直接发送。 |
| 290 | dynamicTask.startDelay(timeoutTaskKey, ()->{ | 317 | dynamicTask.startDelay(timeoutTaskKey, ()->{ |
| @@ -336,17 +363,22 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { | @@ -336,17 +363,22 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { | ||
| 336 | if (parentPlatform == null) { | 363 | if (parentPlatform == null) { |
| 337 | return; | 364 | return; |
| 338 | } | 365 | } |
| 366 | + String deviceId = device == null ? parentPlatform.getDeviceGBId() : device.getDeviceId(); | ||
| 367 | + String deviceName = device == null ? parentPlatform.getName() : device.getName(); | ||
| 368 | + String manufacturer = device == null ? "WVP-28181-PRO" : device.getManufacturer(); | ||
| 369 | + String model = device == null ? "platform" : device.getModel(); | ||
| 370 | + String firmware = device == null ? gitUtil.getBuildVersion() : device.getFirmware(); | ||
| 339 | String characterSet = parentPlatform.getCharacterSet(); | 371 | String characterSet = parentPlatform.getCharacterSet(); |
| 340 | StringBuffer deviceInfoXml = new StringBuffer(600); | 372 | StringBuffer deviceInfoXml = new StringBuffer(600); |
| 341 | deviceInfoXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n"); | 373 | deviceInfoXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n"); |
| 342 | deviceInfoXml.append("<Response>\r\n"); | 374 | deviceInfoXml.append("<Response>\r\n"); |
| 343 | deviceInfoXml.append("<CmdType>DeviceInfo</CmdType>\r\n"); | 375 | deviceInfoXml.append("<CmdType>DeviceInfo</CmdType>\r\n"); |
| 344 | deviceInfoXml.append("<SN>" +sn + "</SN>\r\n"); | 376 | deviceInfoXml.append("<SN>" +sn + "</SN>\r\n"); |
| 345 | - deviceInfoXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n"); | ||
| 346 | - deviceInfoXml.append("<DeviceName>" + device.getName() + "</DeviceName>\r\n"); | ||
| 347 | - deviceInfoXml.append("<Manufacturer>" + device.getManufacturer() + "</Manufacturer>\r\n"); | ||
| 348 | - deviceInfoXml.append("<Model>" + device.getModel() + "</Model>\r\n"); | ||
| 349 | - deviceInfoXml.append("<Firmware>" + device.getFirmware() + "</Firmware>\r\n"); | 377 | + deviceInfoXml.append("<DeviceID>" + deviceId + "</DeviceID>\r\n"); |
| 378 | + deviceInfoXml.append("<DeviceName>" + deviceName + "</DeviceName>\r\n"); | ||
| 379 | + deviceInfoXml.append("<Manufacturer>" + manufacturer + "</Manufacturer>\r\n"); | ||
| 380 | + deviceInfoXml.append("<Model>" + model + "</Model>\r\n"); | ||
| 381 | + deviceInfoXml.append("<Firmware>" + firmware + "</Firmware>\r\n"); | ||
| 350 | deviceInfoXml.append("<Result>OK</Result>\r\n"); | 382 | deviceInfoXml.append("<Result>OK</Result>\r\n"); |
| 351 | deviceInfoXml.append("</Response>\r\n"); | 383 | deviceInfoXml.append("</Response>\r\n"); |
| 352 | 384 | ||
| @@ -423,7 +455,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { | @@ -423,7 +455,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { | ||
| 423 | if (parentPlatform == null) { | 455 | if (parentPlatform == null) { |
| 424 | return; | 456 | return; |
| 425 | } | 457 | } |
| 426 | - logger.info("[发送报警通知] {}/{}->{},{}: {}", parentPlatform.getServerGBId(), deviceAlarm.getChannelId(), | 458 | + logger.info("[发送报警通知]平台: {}/{}->{},{}: {}", parentPlatform.getServerGBId(), deviceAlarm.getChannelId(), |
| 427 | deviceAlarm.getLongitude(), deviceAlarm.getLatitude(), JSON.toJSONString(deviceAlarm)); | 459 | deviceAlarm.getLongitude(), deviceAlarm.getLatitude(), JSON.toJSONString(deviceAlarm)); |
| 428 | String characterSet = parentPlatform.getCharacterSet(); | 460 | String characterSet = parentPlatform.getCharacterSet(); |
| 429 | StringBuffer deviceStatusXml = new StringBuffer(600); | 461 | StringBuffer deviceStatusXml = new StringBuffer(600); |
| @@ -434,7 +466,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { | @@ -434,7 +466,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { | ||
| 434 | .append("<DeviceID>" + deviceAlarm.getChannelId() + "</DeviceID>\r\n") | 466 | .append("<DeviceID>" + deviceAlarm.getChannelId() + "</DeviceID>\r\n") |
| 435 | .append("<AlarmPriority>" + deviceAlarm.getAlarmPriority() + "</AlarmPriority>\r\n") | 467 | .append("<AlarmPriority>" + deviceAlarm.getAlarmPriority() + "</AlarmPriority>\r\n") |
| 436 | .append("<AlarmMethod>" + deviceAlarm.getAlarmMethod() + "</AlarmMethod>\r\n") | 468 | .append("<AlarmMethod>" + deviceAlarm.getAlarmMethod() + "</AlarmMethod>\r\n") |
| 437 | - .append("<AlarmTime>" + deviceAlarm.getAlarmTime() + "</AlarmTime>\r\n") | 469 | + .append("<AlarmTime>" + DateUtil.yyyy_MM_dd_HH_mm_ssToISO8601(deviceAlarm.getAlarmTime()) + "</AlarmTime>\r\n") |
| 438 | .append("<AlarmDescription>" + deviceAlarm.getAlarmDescription() + "</AlarmDescription>\r\n") | 470 | .append("<AlarmDescription>" + deviceAlarm.getAlarmDescription() + "</AlarmDescription>\r\n") |
| 439 | .append("<Longitude>" + deviceAlarm.getLongitude() + "</Longitude>\r\n") | 471 | .append("<Longitude>" + deviceAlarm.getLongitude() + "</Longitude>\r\n") |
| 440 | .append("<Latitude>" + deviceAlarm.getLatitude() + "</Latitude>\r\n") | 472 | .append("<Latitude>" + deviceAlarm.getLatitude() + "</Latitude>\r\n") |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java
| @@ -45,7 +45,7 @@ public abstract class SIPRequestProcessorParent { | @@ -45,7 +45,7 @@ public abstract class SIPRequestProcessorParent { | ||
| 45 | try { | 45 | try { |
| 46 | return SipFactory.getInstance().createHeaderFactory(); | 46 | return SipFactory.getInstance().createHeaderFactory(); |
| 47 | } catch (PeerUnavailableException e) { | 47 | } catch (PeerUnavailableException e) { |
| 48 | - e.printStackTrace(); | 48 | + logger.error("未处理的异常 ", e); |
| 49 | } | 49 | } |
| 50 | return null; | 50 | return null; |
| 51 | } | 51 | } |
| @@ -54,7 +54,7 @@ public abstract class SIPRequestProcessorParent { | @@ -54,7 +54,7 @@ public abstract class SIPRequestProcessorParent { | ||
| 54 | try { | 54 | try { |
| 55 | return SipFactory.getInstance().createMessageFactory(); | 55 | return SipFactory.getInstance().createMessageFactory(); |
| 56 | } catch (PeerUnavailableException e) { | 56 | } catch (PeerUnavailableException e) { |
| 57 | - e.printStackTrace(); | 57 | + logger.error("未处理的异常 ", e); |
| 58 | } | 58 | } |
| 59 | return null; | 59 | return null; |
| 60 | } | 60 | } |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java
| @@ -8,6 +8,7 @@ import com.genersoft.iot.vmp.conf.UserSetting; | @@ -8,6 +8,7 @@ import com.genersoft.iot.vmp.conf.UserSetting; | ||
| 8 | import com.genersoft.iot.vmp.gb28181.bean.*; | 8 | import com.genersoft.iot.vmp.gb28181.bean.*; |
| 9 | import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; | 9 | import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; |
| 10 | import com.genersoft.iot.vmp.gb28181.session.AudioBroadcastManager; | 10 | import com.genersoft.iot.vmp.gb28181.session.AudioBroadcastManager; |
| 11 | +import com.genersoft.iot.vmp.gb28181.session.SsrcConfig; | ||
| 11 | import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; | 12 | import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; |
| 12 | import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; | 13 | import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; |
| 13 | import com.genersoft.iot.vmp.gb28181.transmit.SIPSender; | 14 | import com.genersoft.iot.vmp.gb28181.transmit.SIPSender; |
| @@ -457,12 +458,8 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements | @@ -457,12 +458,8 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements | ||
| 457 | if (!userSetting.getPushStreamAfterAck()) { | 458 | if (!userSetting.getPushStreamAfterAck()) { |
| 458 | playService.startPushStream(sendRtpItem, sipResponse, platform, request.getCallIdHeader()); | 459 | playService.startPushStream(sendRtpItem, sipResponse, platform, request.getCallIdHeader()); |
| 459 | } | 460 | } |
| 460 | - } catch (SipException e) { | ||
| 461 | - e.printStackTrace(); | ||
| 462 | - } catch (InvalidArgumentException e) { | ||
| 463 | - e.printStackTrace(); | ||
| 464 | - } catch (ParseException e) { | ||
| 465 | - e.printStackTrace(); | 461 | + } catch (SipException | InvalidArgumentException | ParseException e) { |
| 462 | + logger.error("[命令发送失败] 国标级联 回复SdpAck", e); | ||
| 466 | } | 463 | } |
| 467 | }; | 464 | }; |
| 468 | SipSubscribe.Event errorEvent = ((event) -> { | 465 | SipSubscribe.Event errorEvent = ((event) -> { |
| @@ -471,7 +468,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements | @@ -471,7 +468,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements | ||
| 471 | Response response = getMessageFactory().createResponse(event.statusCode, evt.getRequest()); | 468 | Response response = getMessageFactory().createResponse(event.statusCode, evt.getRequest()); |
| 472 | sipSender.transmitRequest(request.getLocalAddress().getHostAddress(), response); | 469 | sipSender.transmitRequest(request.getLocalAddress().getHostAddress(), response); |
| 473 | } catch (ParseException | SipException e) { | 470 | } catch (ParseException | SipException e) { |
| 474 | - e.printStackTrace(); | 471 | + logger.error("未处理的异常 ", e); |
| 475 | } | 472 | } |
| 476 | }); | 473 | }); |
| 477 | sendRtpItem.setApp("rtp"); | 474 | sendRtpItem.setApp("rtp"); |
| @@ -543,6 +540,15 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements | @@ -543,6 +540,15 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements | ||
| 543 | } | 540 | } |
| 544 | } | 541 | } |
| 545 | } else if (gbStream != null) { | 542 | } else if (gbStream != null) { |
| 543 | + if(ssrc.equals(ssrcDefault)) | ||
| 544 | + { | ||
| 545 | + SsrcConfig ssrcConfig = mediaServerItem.getSsrcConfig(); | ||
| 546 | + if(ssrcConfig != null) | ||
| 547 | + { | ||
| 548 | + ssrc = ssrcConfig.getPlaySsrc(); | ||
| 549 | + ssrcConfig.releaseSsrc(ssrc); | ||
| 550 | + } | ||
| 551 | + } | ||
| 546 | if("push".equals(gbStream.getStreamType())) { | 552 | if("push".equals(gbStream.getStreamType())) { |
| 547 | if (streamPushItem != null && streamPushItem.isPushIng()) { | 553 | if (streamPushItem != null && streamPushItem.isPushIng()) { |
| 548 | // 推流状态 | 554 | // 推流状态 |
| @@ -572,7 +578,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements | @@ -572,7 +578,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements | ||
| 572 | } catch (SdpParseException e) { | 578 | } catch (SdpParseException e) { |
| 573 | logger.error("sdp解析错误", e); | 579 | logger.error("sdp解析错误", e); |
| 574 | } catch (SdpException e) { | 580 | } catch (SdpException e) { |
| 575 | - e.printStackTrace(); | 581 | + logger.error("未处理的异常 ", e); |
| 576 | } | 582 | } |
| 577 | } | 583 | } |
| 578 | 584 | ||
| @@ -727,11 +733,11 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements | @@ -727,11 +733,11 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements | ||
| 727 | mediaListManager.removedChannelOnlineEventLister(gbStream.getApp(), gbStream.getStream()); | 733 | mediaListManager.removedChannelOnlineEventLister(gbStream.getApp(), gbStream.getStream()); |
| 728 | responseAck(request, Response.REQUEST_TIMEOUT); // 超时 | 734 | responseAck(request, Response.REQUEST_TIMEOUT); // 超时 |
| 729 | } catch (SipException e) { | 735 | } catch (SipException e) { |
| 730 | - e.printStackTrace(); | 736 | + logger.error("未处理的异常 ", e); |
| 731 | } catch (InvalidArgumentException e) { | 737 | } catch (InvalidArgumentException e) { |
| 732 | - e.printStackTrace(); | 738 | + logger.error("未处理的异常 ", e); |
| 733 | } catch (ParseException e) { | 739 | } catch (ParseException e) { |
| 734 | - e.printStackTrace(); | 740 | + logger.error("未处理的异常 ", e); |
| 735 | } | 741 | } |
| 736 | }, userSetting.getPlatformPlayTimeout()); | 742 | }, userSetting.getPlatformPlayTimeout()); |
| 737 | // 添加监听 | 743 | // 添加监听 |
| @@ -750,11 +756,11 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements | @@ -750,11 +756,11 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements | ||
| 750 | try { | 756 | try { |
| 751 | responseAck(request, Response.BUSY_HERE); | 757 | responseAck(request, Response.BUSY_HERE); |
| 752 | } catch (SipException e) { | 758 | } catch (SipException e) { |
| 753 | - e.printStackTrace(); | 759 | + logger.error("未处理的异常 ", e); |
| 754 | } catch (InvalidArgumentException e) { | 760 | } catch (InvalidArgumentException e) { |
| 755 | - e.printStackTrace(); | 761 | + logger.error("未处理的异常 ", e); |
| 756 | } catch (ParseException e) { | 762 | } catch (ParseException e) { |
| 757 | - e.printStackTrace(); | 763 | + logger.error("未处理的异常 ", e); |
| 758 | } | 764 | } |
| 759 | return; | 765 | return; |
| 760 | } | 766 | } |
| @@ -812,11 +818,11 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements | @@ -812,11 +818,11 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements | ||
| 812 | try { | 818 | try { |
| 813 | responseAck(request, Response.BUSY_HERE); | 819 | responseAck(request, Response.BUSY_HERE); |
| 814 | } catch (SipException e) { | 820 | } catch (SipException e) { |
| 815 | - e.printStackTrace(); | 821 | + logger.error("未处理的异常 ", e); |
| 816 | } catch (InvalidArgumentException e) { | 822 | } catch (InvalidArgumentException e) { |
| 817 | - e.printStackTrace(); | 823 | + logger.error("未处理的异常 ", e); |
| 818 | } catch (ParseException e) { | 824 | } catch (ParseException e) { |
| 819 | - e.printStackTrace(); | 825 | + logger.error("未处理的异常 ", e); |
| 820 | } | 826 | } |
| 821 | return; | 827 | return; |
| 822 | } | 828 | } |
| @@ -869,7 +875,13 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements | @@ -869,7 +875,13 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements | ||
| 869 | content.append("s=Play\r\n"); | 875 | content.append("s=Play\r\n"); |
| 870 | content.append("c=IN IP4 " + mediaServerItem.getSdpIp() + "\r\n"); | 876 | content.append("c=IN IP4 " + mediaServerItem.getSdpIp() + "\r\n"); |
| 871 | content.append("t=0 0\r\n"); | 877 | content.append("t=0 0\r\n"); |
| 872 | - content.append("m=video " + sendRtpItem.getLocalPort() + " RTP/AVP 96\r\n"); | 878 | + // 非严格模式端口不统一, 增加兼容性,修改为一个不为0的端口 |
| 879 | + int localPort = sendRtpItem.getLocalPort(); | ||
| 880 | + if(localPort == 0) | ||
| 881 | + { | ||
| 882 | + localPort = new Random().nextInt(65535) + 1; | ||
| 883 | + } | ||
| 884 | + content.append("m=video " + localPort + " RTP/AVP 96\r\n"); | ||
| 873 | content.append("a=sendonly\r\n"); | 885 | content.append("a=sendonly\r\n"); |
| 874 | content.append("a=rtpmap:96 PS/90000\r\n"); | 886 | content.append("a=rtpmap:96 PS/90000\r\n"); |
| 875 | if (sendRtpItem.isTcp()) { | 887 | if (sendRtpItem.isTcp()) { |
| @@ -890,11 +902,11 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements | @@ -890,11 +902,11 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements | ||
| 890 | } | 902 | } |
| 891 | return sipResponse; | 903 | return sipResponse; |
| 892 | } catch (SipException e) { | 904 | } catch (SipException e) { |
| 893 | - e.printStackTrace(); | 905 | + logger.error("未处理的异常 ", e); |
| 894 | } catch (InvalidArgumentException e) { | 906 | } catch (InvalidArgumentException e) { |
| 895 | - e.printStackTrace(); | 907 | + logger.error("未处理的异常 ", e); |
| 896 | } catch (ParseException e) { | 908 | } catch (ParseException e) { |
| 897 | - e.printStackTrace(); | 909 | + logger.error("未处理的异常 ", e); |
| 898 | } | 910 | } |
| 899 | return null; | 911 | return null; |
| 900 | } | 912 | } |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestProcessor.java
| @@ -93,7 +93,7 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements | @@ -93,7 +93,7 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements | ||
| 93 | try { | 93 | try { |
| 94 | responseAck((SIPRequest) evt.getRequest(), Response.OK, null, null); | 94 | responseAck((SIPRequest) evt.getRequest(), Response.OK, null, null); |
| 95 | }catch (SipException | InvalidArgumentException | ParseException e) { | 95 | }catch (SipException | InvalidArgumentException | ParseException e) { |
| 96 | - e.printStackTrace(); | 96 | + logger.error("未处理的异常 ", e); |
| 97 | } | 97 | } |
| 98 | boolean runed = !taskQueue.isEmpty(); | 98 | boolean runed = !taskQueue.isEmpty(); |
| 99 | taskQueue.offer(new HandlerCatchData(evt, null, null)); | 99 | taskQueue.offer(new HandlerCatchData(evt, null, null)); |
| @@ -229,7 +229,7 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements | @@ -229,7 +229,7 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements | ||
| 229 | jsonObject.put("speed", mobilePosition.getSpeed()); | 229 | jsonObject.put("speed", mobilePosition.getSpeed()); |
| 230 | redisCatchStorage.sendMobilePositionMsg(jsonObject); | 230 | redisCatchStorage.sendMobilePositionMsg(jsonObject); |
| 231 | } catch (DocumentException e) { | 231 | } catch (DocumentException e) { |
| 232 | - e.printStackTrace(); | 232 | + logger.error("未处理的异常 ", e); |
| 233 | } | 233 | } |
| 234 | } | 234 | } |
| 235 | 235 | ||
| @@ -339,7 +339,7 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements | @@ -339,7 +339,7 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements | ||
| 339 | publisher.deviceAlarmEventPublish(deviceAlarm); | 339 | publisher.deviceAlarmEventPublish(deviceAlarm); |
| 340 | } | 340 | } |
| 341 | } catch (DocumentException e) { | 341 | } catch (DocumentException e) { |
| 342 | - e.printStackTrace(); | 342 | + logger.error("未处理的异常 ", e); |
| 343 | } | 343 | } |
| 344 | } | 344 | } |
| 345 | 345 | ||
| @@ -397,12 +397,20 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements | @@ -397,12 +397,20 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements | ||
| 397 | case CatalogEvent.OFF : | 397 | case CatalogEvent.OFF : |
| 398 | // 离线 | 398 | // 离线 |
| 399 | logger.info("[收到通道离线通知] 来自设备: {}, 通道 {}", device.getDeviceId(), channel.getChannelId()); | 399 | logger.info("[收到通道离线通知] 来自设备: {}, 通道 {}", device.getDeviceId(), channel.getChannelId()); |
| 400 | - storager.deviceChannelOffline(deviceId, channel.getChannelId()); | 400 | + if (userSetting.getRefuseChannelStatusChannelFormNotify()) { |
| 401 | + storager.deviceChannelOffline(deviceId, channel.getChannelId()); | ||
| 402 | + }else { | ||
| 403 | + logger.info("[收到通道离线通知] 但是平台已配置拒绝此消息,来自设备: {}, 通道 {}", device.getDeviceId(), channel.getChannelId()); | ||
| 404 | + } | ||
| 401 | break; | 405 | break; |
| 402 | case CatalogEvent.VLOST: | 406 | case CatalogEvent.VLOST: |
| 403 | // 视频丢失 | 407 | // 视频丢失 |
| 404 | logger.info("[收到通道视频丢失通知] 来自设备: {}, 通道 {}", device.getDeviceId(), channel.getChannelId()); | 408 | logger.info("[收到通道视频丢失通知] 来自设备: {}, 通道 {}", device.getDeviceId(), channel.getChannelId()); |
| 405 | - storager.deviceChannelOffline(deviceId, channel.getChannelId()); | 409 | + if (userSetting.getRefuseChannelStatusChannelFormNotify()) { |
| 410 | + storager.deviceChannelOffline(deviceId, channel.getChannelId()); | ||
| 411 | + }else { | ||
| 412 | + logger.info("[收到通道视频丢失通知] 但是平台已配置拒绝此消息,来自设备: {}, 通道 {}", device.getDeviceId(), channel.getChannelId()); | ||
| 413 | + } | ||
| 406 | break; | 414 | break; |
| 407 | case CatalogEvent.DEFECT: | 415 | case CatalogEvent.DEFECT: |
| 408 | // 故障 | 416 | // 故障 |
| @@ -432,7 +440,7 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements | @@ -432,7 +440,7 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements | ||
| 432 | } | 440 | } |
| 433 | } | 441 | } |
| 434 | } catch (DocumentException e) { | 442 | } catch (DocumentException e) { |
| 435 | - e.printStackTrace(); | 443 | + logger.error("未处理的异常 ", e); |
| 436 | } | 444 | } |
| 437 | } | 445 | } |
| 438 | 446 |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java
| @@ -5,6 +5,7 @@ import com.genersoft.iot.vmp.conf.UserSetting; | @@ -5,6 +5,7 @@ import com.genersoft.iot.vmp.conf.UserSetting; | ||
| 5 | import com.genersoft.iot.vmp.gb28181.auth.DigestServerAuthenticationHelper; | 5 | import com.genersoft.iot.vmp.gb28181.auth.DigestServerAuthenticationHelper; |
| 6 | import com.genersoft.iot.vmp.gb28181.bean.Device; | 6 | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| 7 | import com.genersoft.iot.vmp.gb28181.bean.RemoteAddressInfo; | 7 | import com.genersoft.iot.vmp.gb28181.bean.RemoteAddressInfo; |
| 8 | +import com.genersoft.iot.vmp.gb28181.bean.SipTransactionInfo; | ||
| 8 | import com.genersoft.iot.vmp.gb28181.bean.WvpSipDate; | 9 | import com.genersoft.iot.vmp.gb28181.bean.WvpSipDate; |
| 9 | import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; | 10 | import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; |
| 10 | import com.genersoft.iot.vmp.gb28181.transmit.SIPSender; | 11 | import com.genersoft.iot.vmp.gb28181.transmit.SIPSender; |
| @@ -18,6 +19,7 @@ import gov.nist.javax.sip.address.AddressImpl; | @@ -18,6 +19,7 @@ import gov.nist.javax.sip.address.AddressImpl; | ||
| 18 | import gov.nist.javax.sip.address.SipUri; | 19 | import gov.nist.javax.sip.address.SipUri; |
| 19 | import gov.nist.javax.sip.header.SIPDateHeader; | 20 | import gov.nist.javax.sip.header.SIPDateHeader; |
| 20 | import gov.nist.javax.sip.message.SIPRequest; | 21 | import gov.nist.javax.sip.message.SIPRequest; |
| 22 | +import gov.nist.javax.sip.message.SIPResponse; | ||
| 21 | import org.slf4j.Logger; | 23 | import org.slf4j.Logger; |
| 22 | import org.slf4j.LoggerFactory; | 24 | import org.slf4j.LoggerFactory; |
| 23 | import org.springframework.beans.factory.InitializingBean; | 25 | import org.springframework.beans.factory.InitializingBean; |
| @@ -34,6 +36,7 @@ import javax.sip.header.AuthorizationHeader; | @@ -34,6 +36,7 @@ import javax.sip.header.AuthorizationHeader; | ||
| 34 | import javax.sip.header.ContactHeader; | 36 | import javax.sip.header.ContactHeader; |
| 35 | import javax.sip.header.FromHeader; | 37 | import javax.sip.header.FromHeader; |
| 36 | import javax.sip.header.ViaHeader; | 38 | import javax.sip.header.ViaHeader; |
| 39 | +import javax.sip.message.Request; | ||
| 37 | import javax.sip.message.Response; | 40 | import javax.sip.message.Response; |
| 38 | import java.security.NoSuchAlgorithmException; | 41 | import java.security.NoSuchAlgorithmException; |
| 39 | import java.text.ParseException; | 42 | import java.text.ParseException; |
| @@ -105,6 +108,30 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen | @@ -105,6 +108,30 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen | ||
| 105 | SipUri uri = (SipUri) address.getURI(); | 108 | SipUri uri = (SipUri) address.getURI(); |
| 106 | String deviceId = uri.getUser(); | 109 | String deviceId = uri.getUser(); |
| 107 | Device device = deviceService.getDevice(deviceId); | 110 | Device device = deviceService.getDevice(deviceId); |
| 111 | + | ||
| 112 | + RemoteAddressInfo remoteAddressInfo = SipUtils.getRemoteAddressFromRequest(request, | ||
| 113 | + userSetting.getSipUseSourceIpAsRemoteAddress()); | ||
| 114 | + | ||
| 115 | + if (device != null && | ||
| 116 | + device.getSipTransactionInfo() != null && | ||
| 117 | + request.getCallIdHeader().getCallId().equals(device.getSipTransactionInfo().getCallId())) { | ||
| 118 | + logger.info("[注册请求] 注册续订: {}", device.getDeviceId()); | ||
| 119 | + device.setExpires(request.getExpires().getExpires()); | ||
| 120 | + device.setIp(remoteAddressInfo.getIp()); | ||
| 121 | + device.setPort(remoteAddressInfo.getPort()); | ||
| 122 | + device.setHostAddress(remoteAddressInfo.getIp().concat(":").concat(String.valueOf(remoteAddressInfo.getPort()))); | ||
| 123 | + device.setLocalIp(request.getLocalAddress().getHostAddress()); | ||
| 124 | + Response registerOkResponse = getRegisterOkResponse(request); | ||
| 125 | + // 判断TCP还是UDP | ||
| 126 | + ViaHeader reqViaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME); | ||
| 127 | + String transport = reqViaHeader.getTransport(); | ||
| 128 | + device.setTransport("TCP".equalsIgnoreCase(transport) ? "TCP" : "UDP"); | ||
| 129 | + sipSender.transmitRequest(request.getLocalAddress().getHostAddress(), registerOkResponse); | ||
| 130 | + device.setRegisterTime(DateUtil.getNow()); | ||
| 131 | + SipTransactionInfo sipTransactionInfo = new SipTransactionInfo((SIPResponse)registerOkResponse); | ||
| 132 | + deviceService.online(device, sipTransactionInfo); | ||
| 133 | + return; | ||
| 134 | + } | ||
| 108 | String password = (device != null && !ObjectUtils.isEmpty(device.getPassword()))? device.getPassword() : sipConfig.getPassword(); | 135 | String password = (device != null && !ObjectUtils.isEmpty(device.getPassword()))? device.getPassword() : sipConfig.getPassword(); |
| 109 | AuthorizationHeader authHead = (AuthorizationHeader) request.getHeader(AuthorizationHeader.NAME); | 136 | AuthorizationHeader authHead = (AuthorizationHeader) request.getHeader(AuthorizationHeader.NAME); |
| 110 | if (authHead == null && !ObjectUtils.isEmpty(password)) { | 137 | if (authHead == null && !ObjectUtils.isEmpty(password)) { |
| @@ -147,9 +174,6 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen | @@ -147,9 +174,6 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen | ||
| 147 | // 添加Expires头 | 174 | // 添加Expires头 |
| 148 | response.addHeader(request.getExpires()); | 175 | response.addHeader(request.getExpires()); |
| 149 | 176 | ||
| 150 | - RemoteAddressInfo remoteAddressInfo = SipUtils.getRemoteAddressFromRequest(request, | ||
| 151 | - userSetting.getSipUseSourceIpAsRemoteAddress()); | ||
| 152 | - | ||
| 153 | if (device == null) { | 177 | if (device == null) { |
| 154 | device = new Device(); | 178 | device = new Device(); |
| 155 | device.setStreamMode("UDP"); | 179 | device.setStreamMode("UDP"); |
| @@ -182,13 +206,33 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen | @@ -182,13 +206,33 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen | ||
| 182 | if (registerFlag) { | 206 | if (registerFlag) { |
| 183 | logger.info("[注册成功] deviceId: {}->{}", deviceId, requestAddress); | 207 | logger.info("[注册成功] deviceId: {}->{}", deviceId, requestAddress); |
| 184 | device.setRegisterTime(DateUtil.getNow()); | 208 | device.setRegisterTime(DateUtil.getNow()); |
| 185 | - deviceService.online(device); | 209 | + SipTransactionInfo sipTransactionInfo = new SipTransactionInfo((SIPResponse)response); |
| 210 | + deviceService.online(device, sipTransactionInfo); | ||
| 186 | } else { | 211 | } else { |
| 187 | logger.info("[注销成功] deviceId: {}->{}" ,deviceId, requestAddress); | 212 | logger.info("[注销成功] deviceId: {}->{}" ,deviceId, requestAddress); |
| 188 | - deviceService.offline(deviceId); | 213 | + deviceService.offline(deviceId, "主动注销"); |
| 189 | } | 214 | } |
| 190 | } catch (SipException | NoSuchAlgorithmException | ParseException e) { | 215 | } catch (SipException | NoSuchAlgorithmException | ParseException e) { |
| 191 | - e.printStackTrace(); | 216 | + logger.error("未处理的异常 ", e); |
| 192 | } | 217 | } |
| 193 | } | 218 | } |
| 219 | + | ||
| 220 | + private Response getRegisterOkResponse(Request request) throws ParseException { | ||
| 221 | + // 携带授权头并且密码正确 | ||
| 222 | + Response response = getMessageFactory().createResponse(Response.OK, request); | ||
| 223 | + // 添加date头 | ||
| 224 | + SIPDateHeader dateHeader = new SIPDateHeader(); | ||
| 225 | + // 使用自己修改的 | ||
| 226 | + WvpSipDate wvpSipDate = new WvpSipDate(Calendar.getInstance(Locale.ENGLISH).getTimeInMillis()); | ||
| 227 | + dateHeader.setDate(wvpSipDate); | ||
| 228 | + response.addHeader(dateHeader); | ||
| 229 | + | ||
| 230 | + // 添加Contact头 | ||
| 231 | + response.addHeader(request.getHeader(ContactHeader.NAME)); | ||
| 232 | + // 添加Expires头 | ||
| 233 | + response.addHeader(request.getExpires()); | ||
| 234 | + | ||
| 235 | + return response; | ||
| 236 | + | ||
| 237 | + } | ||
| 194 | } | 238 | } |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/SubscribeRequestProcessor.java
| 1 | package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl; | 1 | package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl; |
| 2 | 2 | ||
| 3 | +import com.genersoft.iot.vmp.common.VideoManagerConstants; | ||
| 3 | import com.genersoft.iot.vmp.conf.DynamicTask; | 4 | import com.genersoft.iot.vmp.conf.DynamicTask; |
| 4 | import com.genersoft.iot.vmp.conf.UserSetting; | 5 | import com.genersoft.iot.vmp.conf.UserSetting; |
| 5 | import com.genersoft.iot.vmp.gb28181.bean.CmdType; | 6 | import com.genersoft.iot.vmp.gb28181.bean.CmdType; |
| @@ -8,14 +9,11 @@ import com.genersoft.iot.vmp.gb28181.bean.SubscribeHolder; | @@ -8,14 +9,11 @@ import com.genersoft.iot.vmp.gb28181.bean.SubscribeHolder; | ||
| 8 | import com.genersoft.iot.vmp.gb28181.bean.SubscribeInfo; | 9 | import com.genersoft.iot.vmp.gb28181.bean.SubscribeInfo; |
| 9 | import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; | 10 | import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; |
| 10 | import com.genersoft.iot.vmp.gb28181.transmit.SIPSender; | 11 | import com.genersoft.iot.vmp.gb28181.transmit.SIPSender; |
| 11 | -import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; | ||
| 12 | -import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; | ||
| 13 | import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor; | 12 | import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor; |
| 14 | import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; | 13 | import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; |
| 15 | import com.genersoft.iot.vmp.gb28181.utils.SipUtils; | 14 | import com.genersoft.iot.vmp.gb28181.utils.SipUtils; |
| 16 | import com.genersoft.iot.vmp.gb28181.utils.XmlUtil; | 15 | import com.genersoft.iot.vmp.gb28181.utils.XmlUtil; |
| 17 | import com.genersoft.iot.vmp.storager.IVideoManagerStorage; | 16 | import com.genersoft.iot.vmp.storager.IVideoManagerStorage; |
| 18 | -import gov.nist.javax.sip.SipProviderImpl; | ||
| 19 | import gov.nist.javax.sip.message.SIPRequest; | 17 | import gov.nist.javax.sip.message.SIPRequest; |
| 20 | import gov.nist.javax.sip.message.SIPResponse; | 18 | import gov.nist.javax.sip.message.SIPResponse; |
| 21 | import org.dom4j.DocumentException; | 19 | import org.dom4j.DocumentException; |
| @@ -26,7 +24,9 @@ import org.springframework.beans.factory.InitializingBean; | @@ -26,7 +24,9 @@ import org.springframework.beans.factory.InitializingBean; | ||
| 26 | import org.springframework.beans.factory.annotation.Autowired; | 24 | import org.springframework.beans.factory.annotation.Autowired; |
| 27 | import org.springframework.stereotype.Component; | 25 | import org.springframework.stereotype.Component; |
| 28 | 26 | ||
| 29 | -import javax.sip.*; | 27 | +import javax.sip.InvalidArgumentException; |
| 28 | +import javax.sip.RequestEvent; | ||
| 29 | +import javax.sip.SipException; | ||
| 30 | import javax.sip.header.ExpiresHeader; | 30 | import javax.sip.header.ExpiresHeader; |
| 31 | import javax.sip.message.Response; | 31 | import javax.sip.message.Response; |
| 32 | import java.text.ParseException; | 32 | import java.text.ParseException; |
| @@ -93,7 +93,7 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme | @@ -93,7 +93,7 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme | ||
| 93 | sipSender.transmitRequest(request.getLocalAddress().getHostAddress(), response); | 93 | sipSender.transmitRequest(request.getLocalAddress().getHostAddress(), response); |
| 94 | } | 94 | } |
| 95 | } catch (ParseException | SipException | InvalidArgumentException | DocumentException e) { | 95 | } catch (ParseException | SipException | InvalidArgumentException | DocumentException e) { |
| 96 | - e.printStackTrace(); | 96 | + logger.error("未处理的异常 ", e); |
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | } | 99 | } |
| @@ -146,7 +146,7 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme | @@ -146,7 +146,7 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme | ||
| 146 | } | 146 | } |
| 147 | 147 | ||
| 148 | } catch (SipException | InvalidArgumentException | ParseException e) { | 148 | } catch (SipException | InvalidArgumentException | ParseException e) { |
| 149 | - e.printStackTrace(); | 149 | + logger.error("未处理的异常 ", e); |
| 150 | } | 150 | } |
| 151 | } | 151 | } |
| 152 | 152 | ||
| @@ -192,7 +192,7 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme | @@ -192,7 +192,7 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme | ||
| 192 | subscribeHolder.putCatalogSubscribe(platformId, subscribeInfo); | 192 | subscribeHolder.putCatalogSubscribe(platformId, subscribeInfo); |
| 193 | } | 193 | } |
| 194 | } catch (SipException | InvalidArgumentException | ParseException e) { | 194 | } catch (SipException | InvalidArgumentException | ParseException e) { |
| 195 | - e.printStackTrace(); | 195 | + logger.error("未处理的异常 ", e); |
| 196 | } | 196 | } |
| 197 | } | 197 | } |
| 198 | } | 198 | } |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/control/cmd/DeviceControlQueryMessageHandler.java
| @@ -73,35 +73,38 @@ public class DeviceControlQueryMessageHandler extends SIPRequestProcessorParent | @@ -73,35 +73,38 @@ public class DeviceControlQueryMessageHandler extends SIPRequestProcessorParent | ||
| 73 | String channelId = getText(rootElement, "DeviceID"); | 73 | String channelId = getText(rootElement, "DeviceID"); |
| 74 | // 远程启动功能 | 74 | // 远程启动功能 |
| 75 | if (!ObjectUtils.isEmpty(getText(rootElement, "TeleBoot"))) { | 75 | if (!ObjectUtils.isEmpty(getText(rootElement, "TeleBoot"))) { |
| 76 | - if (parentPlatform.getServerGBId().equals(targetGBId)) { | ||
| 77 | - // 远程启动本平台:需要在重新启动程序后先对SipStack解绑 | ||
| 78 | - logger.info("执行远程启动本平台命令"); | ||
| 79 | - try { | ||
| 80 | - cmderFroPlatform.unregister(parentPlatform, null, null); | ||
| 81 | - } catch (InvalidArgumentException | ParseException | SipException e) { | ||
| 82 | - logger.error("[命令发送失败] 国标级联 注销: {}", e.getMessage()); | ||
| 83 | - } | ||
| 84 | - taskExecutor.execute(() -> { | ||
| 85 | - // 远程启动 | ||
| 86 | -// try { | ||
| 87 | -// Thread.sleep(3000); | ||
| 88 | -// SipProvider up = (SipProvider) SpringBeanFactory.getBean("udpSipProvider"); | ||
| 89 | -// SipStackImpl stack = (SipStackImpl)up.getSipStack(); | ||
| 90 | -// stack.stop(); | ||
| 91 | -// Iterator listener = stack.getListeningPoints(); | ||
| 92 | -// while (listener.hasNext()) { | ||
| 93 | -// stack.deleteListeningPoint((ListeningPoint) listener.next()); | ||
| 94 | -// } | ||
| 95 | -// Iterator providers = stack.getSipProviders(); | ||
| 96 | -// while (providers.hasNext()) { | ||
| 97 | -// stack.deleteSipProvider((SipProvider) providers.next()); | ||
| 98 | -// } | ||
| 99 | -// VManageBootstrap.restart(); | ||
| 100 | -// } catch (InterruptedException | ObjectInUseException e) { | ||
| 101 | -// logger.error("[任务执行失败] 服务重启: {}", e.getMessage()); | ||
| 102 | -// } | ||
| 103 | - }); | ||
| 104 | - } | 76 | + // TODO 拒绝远程启动命令 |
| 77 | + logger.warn("[国标级联]收到平台的远程启动命令, 不处理"); | ||
| 78 | + | ||
| 79 | +// if (parentPlatform.getServerGBId().equals(targetGBId)) { | ||
| 80 | +// // 远程启动本平台:需要在重新启动程序后先对SipStack解绑 | ||
| 81 | +// logger.info("执行远程启动本平台命令"); | ||
| 82 | +// try { | ||
| 83 | +// cmderFroPlatform.unregister(parentPlatform, null, null); | ||
| 84 | +// } catch (InvalidArgumentException | ParseException | SipException e) { | ||
| 85 | +// logger.error("[命令发送失败] 国标级联 注销: {}", e.getMessage()); | ||
| 86 | +// } | ||
| 87 | +// taskExecutor.execute(() -> { | ||
| 88 | +// // 远程启动 | ||
| 89 | +//// try { | ||
| 90 | +//// Thread.sleep(3000); | ||
| 91 | +//// SipProvider up = (SipProvider) SpringBeanFactory.getBean("udpSipProvider"); | ||
| 92 | +//// SipStackImpl stack = (SipStackImpl)up.getSipStack(); | ||
| 93 | +//// stack.stop(); | ||
| 94 | +//// Iterator listener = stack.getListeningPoints(); | ||
| 95 | +//// while (listener.hasNext()) { | ||
| 96 | +//// stack.deleteListeningPoint((ListeningPoint) listener.next()); | ||
| 97 | +//// } | ||
| 98 | +//// Iterator providers = stack.getSipProviders(); | ||
| 99 | +//// while (providers.hasNext()) { | ||
| 100 | +//// stack.deleteSipProvider((SipProvider) providers.next()); | ||
| 101 | +//// } | ||
| 102 | +//// VManageBootstrap.restart(); | ||
| 103 | +//// } catch (InterruptedException | ObjectInUseException e) { | ||
| 104 | +//// logger.error("[任务执行失败] 服务重启: {}", e.getMessage()); | ||
| 105 | +//// } | ||
| 106 | +// }); | ||
| 107 | +// } | ||
| 105 | } | 108 | } |
| 106 | DeviceControlType deviceControlType = DeviceControlType.typeOf(rootElement); | 109 | DeviceControlType deviceControlType = DeviceControlType.typeOf(rootElement); |
| 107 | logger.info("[接受deviceControl命令] 命令: {}", deviceControlType); | 110 | logger.info("[接受deviceControl命令] 命令: {}", deviceControlType); |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/AlarmNotifyMessageHandler.java
| @@ -186,9 +186,13 @@ public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent impleme | @@ -186,9 +186,13 @@ public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent impleme | ||
| 186 | // 发送给平台的报警信息。 发送redis通知 | 186 | // 发送给平台的报警信息。 发送redis通知 |
| 187 | logger.info("[发送给平台的报警信息]内容:{}", JSONObject.toJSONString(deviceAlarm)); | 187 | logger.info("[发送给平台的报警信息]内容:{}", JSONObject.toJSONString(deviceAlarm)); |
| 188 | AlarmChannelMessage alarmChannelMessage = new AlarmChannelMessage(); | 188 | AlarmChannelMessage alarmChannelMessage = new AlarmChannelMessage(); |
| 189 | - alarmChannelMessage.setAlarmSn(Integer.parseInt(deviceAlarm.getAlarmMethod())); | 189 | + if (deviceAlarm.getAlarmMethod() != null) { |
| 190 | + alarmChannelMessage.setAlarmSn(Integer.parseInt(deviceAlarm.getAlarmMethod())); | ||
| 191 | + } | ||
| 190 | alarmChannelMessage.setAlarmDescription(deviceAlarm.getAlarmDescription()); | 192 | alarmChannelMessage.setAlarmDescription(deviceAlarm.getAlarmDescription()); |
| 191 | - alarmChannelMessage.setAlarmType(Integer.parseInt(deviceAlarm.getAlarmType())); | 193 | + if (deviceAlarm.getAlarmType() != null) { |
| 194 | + alarmChannelMessage.setAlarmType(Integer.parseInt(deviceAlarm.getAlarmType())); | ||
| 195 | + } | ||
| 192 | alarmChannelMessage.setGbId(channelId); | 196 | alarmChannelMessage.setGbId(channelId); |
| 193 | redisCatchStorage.sendAlarmMsg(alarmChannelMessage); | 197 | redisCatchStorage.sendAlarmMsg(alarmChannelMessage); |
| 194 | continue; | 198 | continue; |
| @@ -204,6 +208,7 @@ public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent impleme | @@ -204,6 +208,7 @@ public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent impleme | ||
| 204 | publisher.deviceAlarmEventPublish(deviceAlarm); | 208 | publisher.deviceAlarmEventPublish(deviceAlarm); |
| 205 | } | 209 | } |
| 206 | }catch (Exception e) { | 210 | }catch (Exception e) { |
| 211 | + logger.error("未处理的异常 ", e); | ||
| 207 | logger.warn("[收到报警通知] 发现未处理的异常, {}\r\n{}",e.getMessage(), evt.getRequest()); | 212 | logger.warn("[收到报警通知] 发现未处理的异常, {}\r\n{}",e.getMessage(), evt.getRequest()); |
| 208 | } | 213 | } |
| 209 | } | 214 | } |
| @@ -264,12 +269,15 @@ public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent impleme | @@ -264,12 +269,15 @@ public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent impleme | ||
| 264 | if (channelId.equals(parentPlatform.getDeviceGBId())) { | 269 | if (channelId.equals(parentPlatform.getDeviceGBId())) { |
| 265 | // 发送给平台的报警信息。 发送redis通知 | 270 | // 发送给平台的报警信息。 发送redis通知 |
| 266 | AlarmChannelMessage alarmChannelMessage = new AlarmChannelMessage(); | 271 | AlarmChannelMessage alarmChannelMessage = new AlarmChannelMessage(); |
| 267 | - alarmChannelMessage.setAlarmSn(Integer.parseInt(deviceAlarm.getAlarmMethod())); | 272 | + if (deviceAlarm.getAlarmMethod() != null) { |
| 273 | + alarmChannelMessage.setAlarmSn(Integer.parseInt(deviceAlarm.getAlarmMethod())); | ||
| 274 | + } | ||
| 268 | alarmChannelMessage.setAlarmDescription(deviceAlarm.getAlarmDescription()); | 275 | alarmChannelMessage.setAlarmDescription(deviceAlarm.getAlarmDescription()); |
| 269 | alarmChannelMessage.setGbId(channelId); | 276 | alarmChannelMessage.setGbId(channelId); |
| 270 | - alarmChannelMessage.setAlarmType(Integer.parseInt(deviceAlarm.getAlarmType())); | 277 | + if (deviceAlarm.getAlarmType() != null) { |
| 278 | + alarmChannelMessage.setAlarmType(Integer.parseInt(deviceAlarm.getAlarmType())); | ||
| 279 | + } | ||
| 271 | redisCatchStorage.sendAlarmMsg(alarmChannelMessage); | 280 | redisCatchStorage.sendAlarmMsg(alarmChannelMessage); |
| 272 | - return; | ||
| 273 | } | 281 | } |
| 274 | } | 282 | } |
| 275 | } | 283 | } |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java
| @@ -88,13 +88,13 @@ public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent imp | @@ -88,13 +88,13 @@ public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent imp | ||
| 88 | // 对于已经离线的设备判断他的注册是否已经过期 | 88 | // 对于已经离线的设备判断他的注册是否已经过期 |
| 89 | if (!deviceService.expire(device)){ | 89 | if (!deviceService.expire(device)){ |
| 90 | device.setOnline(0); | 90 | device.setOnline(0); |
| 91 | - deviceService.online(device); | 91 | + deviceService.online(device, null); |
| 92 | } | 92 | } |
| 93 | } | 93 | } |
| 94 | // 刷新过期任务 | 94 | // 刷新过期任务 |
| 95 | String registerExpireTaskKey = VideoManagerConstants.REGISTER_EXPIRE_TASK_KEY_PREFIX + device.getDeviceId(); | 95 | String registerExpireTaskKey = VideoManagerConstants.REGISTER_EXPIRE_TASK_KEY_PREFIX + device.getDeviceId(); |
| 96 | // 如果三次心跳失败,则设置设备离线 | 96 | // 如果三次心跳失败,则设置设备离线 |
| 97 | - dynamicTask.startDelay(registerExpireTaskKey, ()-> deviceService.offline(device.getDeviceId()), device.getKeepaliveIntervalTime()*1000*3); | 97 | + dynamicTask.startDelay(registerExpireTaskKey, ()-> deviceService.offline(device.getDeviceId(), "三次心跳失败"), device.getKeepaliveIntervalTime()*1000*3); |
| 98 | 98 | ||
| 99 | } | 99 | } |
| 100 | 100 |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MobilePositionNotifyMessageHandler.java
| @@ -149,9 +149,10 @@ public class MobilePositionNotifyMessageHandler extends SIPRequestProcessorParen | @@ -149,9 +149,10 @@ public class MobilePositionNotifyMessageHandler extends SIPRequestProcessorParen | ||
| 149 | redisCatchStorage.sendMobilePositionMsg(jsonObject); | 149 | redisCatchStorage.sendMobilePositionMsg(jsonObject); |
| 150 | 150 | ||
| 151 | } catch (DocumentException e) { | 151 | } catch (DocumentException e) { |
| 152 | - e.printStackTrace(); | 152 | + logger.error("未处理的异常 ", e); |
| 153 | } catch (Exception e) { | 153 | } catch (Exception e) { |
| 154 | - logger.warn("[移动位置通知] 发现未处理的异常, {}\r\n{}",e.getMessage(), evt.getRequest()); | 154 | + logger.warn("[移动位置通知] 发现未处理的异常, \r\n{}", evt.getRequest()); |
| 155 | + logger.error("[移动位置通知] 异常内容: ", e); | ||
| 155 | } | 156 | } |
| 156 | } | 157 | } |
| 157 | }); | 158 | }); |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/DeviceInfoQueryMessageHandler.java
| @@ -60,17 +60,24 @@ public class DeviceInfoQueryMessageHandler extends SIPRequestProcessorParent imp | @@ -60,17 +60,24 @@ public class DeviceInfoQueryMessageHandler extends SIPRequestProcessorParent imp | ||
| 60 | return; | 60 | return; |
| 61 | } | 61 | } |
| 62 | String sn = rootElement.element("SN").getText(); | 62 | String sn = rootElement.element("SN").getText(); |
| 63 | + | ||
| 63 | /*根据WVP原有的数据结构,设备和通道是分开放置,设备信息都是存放在设备表里,通道表里的设备信息不可作为真实信息处理 | 64 | /*根据WVP原有的数据结构,设备和通道是分开放置,设备信息都是存放在设备表里,通道表里的设备信息不可作为真实信息处理 |
| 64 | 大部分NVR/IPC设备对他的通道信息实现都是返回默认的值没有什么参考价值。NVR/IPC通道我们统一使用设备表的设备信息来作为返回。 | 65 | 大部分NVR/IPC设备对他的通道信息实现都是返回默认的值没有什么参考价值。NVR/IPC通道我们统一使用设备表的设备信息来作为返回。 |
| 65 | 我们这里使用查询数据库的方式来实现这个设备信息查询的功能,在其他地方对设备信息更新达到正确的目的。*/ | 66 | 我们这里使用查询数据库的方式来实现这个设备信息查询的功能,在其他地方对设备信息更新达到正确的目的。*/ |
| 67 | + | ||
| 66 | String channelId = getText(rootElement, "DeviceID"); | 68 | String channelId = getText(rootElement, "DeviceID"); |
| 67 | - Device device = storager.queryDeviceInfoByPlatformIdAndChannelId(parentPlatform.getServerGBId(), channelId); | ||
| 68 | - if (device ==null){ | ||
| 69 | - logger.error("[平台没有该通道的使用权限]:platformId"+parentPlatform.getServerGBId()+" deviceID:"+channelId); | ||
| 70 | - return; | 69 | + // 查询这是通道id还是设备id |
| 70 | + Device device = null; | ||
| 71 | + // 如果id指向平台的国标编号,那么就是查询平台的信息 | ||
| 72 | + if (!parentPlatform.getDeviceGBId().equals(channelId)) { | ||
| 73 | + device = storager.queryDeviceInfoByPlatformIdAndChannelId(parentPlatform.getServerGBId(), channelId); | ||
| 74 | + if (device ==null){ | ||
| 75 | + logger.error("[平台没有该通道的使用权限]:platformId"+parentPlatform.getServerGBId()+" deviceID:"+channelId); | ||
| 76 | + return; | ||
| 77 | + } | ||
| 71 | } | 78 | } |
| 72 | try { | 79 | try { |
| 73 | - cmderFroPlatform.deviceInfoResponse(parentPlatform,device, sn, fromHeader.getTag()); | 80 | + cmderFroPlatform.deviceInfoResponse(parentPlatform, device, sn, fromHeader.getTag()); |
| 74 | } catch (SipException | InvalidArgumentException | ParseException e) { | 81 | } catch (SipException | InvalidArgumentException | ParseException e) { |
| 75 | logger.error("[命令发送失败] 国标级联 DeviceInfo查询回复: {}", e.getMessage()); | 82 | logger.error("[命令发送失败] 国标级联 DeviceInfo查询回复: {}", e.getMessage()); |
| 76 | } | 83 | } |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/CatalogResponseMessageHandler.java
| @@ -132,7 +132,8 @@ public class CatalogResponseMessageHandler extends SIPRequestProcessorParent imp | @@ -132,7 +132,8 @@ public class CatalogResponseMessageHandler extends SIPRequestProcessorParent imp | ||
| 132 | 132 | ||
| 133 | } | 133 | } |
| 134 | }catch (Exception e) { | 134 | }catch (Exception e) { |
| 135 | - logger.warn("[收到通道] 发现未处理的异常, {}\r\n{}",e.getMessage(), evt.getRequest()); | 135 | + logger.warn("[收到通道] 发现未处理的异常, \r\n{}", evt.getRequest()); |
| 136 | + logger.error("[收到通道] 异常内容: ", e); | ||
| 136 | } | 137 | } |
| 137 | } | 138 | } |
| 138 | }); | 139 | }); |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/DeviceStatusResponseMessageHandler.java
| 1 | package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.cmd; | 1 | package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.cmd; |
| 2 | 2 | ||
| 3 | import com.alibaba.fastjson2.JSONObject; | 3 | import com.alibaba.fastjson2.JSONObject; |
| 4 | -import com.genersoft.iot.vmp.common.VideoManagerConstants; | ||
| 5 | import com.genersoft.iot.vmp.gb28181.bean.Device; | 4 | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| 6 | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; | 5 | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; |
| 7 | -import com.genersoft.iot.vmp.gb28181.event.EventPublisher; | ||
| 8 | import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; | 6 | import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; |
| 9 | import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; | 7 | import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; |
| 10 | import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; | 8 | import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; |
| @@ -26,7 +24,6 @@ import javax.sip.RequestEvent; | @@ -26,7 +24,6 @@ import javax.sip.RequestEvent; | ||
| 26 | import javax.sip.SipException; | 24 | import javax.sip.SipException; |
| 27 | import javax.sip.message.Response; | 25 | import javax.sip.message.Response; |
| 28 | import java.text.ParseException; | 26 | import java.text.ParseException; |
| 29 | -import java.util.Objects; | ||
| 30 | 27 | ||
| 31 | @Component | 28 | @Component |
| 32 | public class DeviceStatusResponseMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler { | 29 | public class DeviceStatusResponseMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler { |
| @@ -74,9 +71,9 @@ public class DeviceStatusResponseMessageHandler extends SIPRequestProcessorParen | @@ -74,9 +71,9 @@ public class DeviceStatusResponseMessageHandler extends SIPRequestProcessorParen | ||
| 74 | } | 71 | } |
| 75 | String text = onlineElement.getText(); | 72 | String text = onlineElement.getText(); |
| 76 | if ("ONLINE".equalsIgnoreCase(text.trim())) { | 73 | if ("ONLINE".equalsIgnoreCase(text.trim())) { |
| 77 | - deviceService.online(device); | 74 | + deviceService.online(device, null); |
| 78 | }else { | 75 | }else { |
| 79 | - deviceService.offline(device.getDeviceId()); | 76 | + deviceService.offline(device.getDeviceId(), "设备状态查询结果:" + text.trim()); |
| 80 | } | 77 | } |
| 81 | RequestMessage msg = new RequestMessage(); | 78 | RequestMessage msg = new RequestMessage(); |
| 82 | msg.setKey(DeferredResultHolder.CALLBACK_CMD_DEVICESTATUS + device.getDeviceId()); | 79 | msg.setKey(DeferredResultHolder.CALLBACK_CMD_DEVICESTATUS + device.getDeviceId()); |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/MobilePositionResponseMessageHandler.java
| @@ -142,7 +142,7 @@ public class MobilePositionResponseMessageHandler extends SIPRequestProcessorPar | @@ -142,7 +142,7 @@ public class MobilePositionResponseMessageHandler extends SIPRequestProcessorPar | ||
| 142 | } | 142 | } |
| 143 | 143 | ||
| 144 | } catch (DocumentException e) { | 144 | } catch (DocumentException e) { |
| 145 | - e.printStackTrace(); | 145 | + logger.error("未处理的异常 ", e); |
| 146 | } | 146 | } |
| 147 | } | 147 | } |
| 148 | 148 |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/RecordInfoResponseMessageHandler.java
| @@ -150,7 +150,8 @@ public class RecordInfoResponseMessageHandler extends SIPRequestProcessorParent | @@ -150,7 +150,8 @@ public class RecordInfoResponseMessageHandler extends SIPRequestProcessorParent | ||
| 150 | } | 150 | } |
| 151 | } | 151 | } |
| 152 | } catch (Exception e) { | 152 | } catch (Exception e) { |
| 153 | - logger.error("[国标录像] 发现未处理的异常, "+e.getMessage(), e); | 153 | + logger.error("[国标录像] 发现未处理的异常, \r\n{}", evt.getRequest()); |
| 154 | + logger.error("[国标录像] 异常内容: ", e); | ||
| 154 | } | 155 | } |
| 155 | }); | 156 | }); |
| 156 | } | 157 | } |
| @@ -163,7 +164,11 @@ public class RecordInfoResponseMessageHandler extends SIPRequestProcessorParent | @@ -163,7 +164,11 @@ public class RecordInfoResponseMessageHandler extends SIPRequestProcessorParent | ||
| 163 | public void releaseRequest(String deviceId, String sn,RecordInfo recordInfo){ | 164 | public void releaseRequest(String deviceId, String sn,RecordInfo recordInfo){ |
| 164 | String key = DeferredResultHolder.CALLBACK_CMD_RECORDINFO + deviceId + sn; | 165 | String key = DeferredResultHolder.CALLBACK_CMD_RECORDINFO + deviceId + sn; |
| 165 | // 对数据进行排序 | 166 | // 对数据进行排序 |
| 166 | - Collections.sort(recordInfo.getRecordList()); | 167 | + if(recordInfo!=null && recordInfo.getRecordList()!=null) { |
| 168 | + Collections.sort(recordInfo.getRecordList()); | ||
| 169 | + }else{ | ||
| 170 | + recordInfo.setRecordList(new ArrayList<>()); | ||
| 171 | + } | ||
| 167 | 172 | ||
| 168 | RequestMessage msg = new RequestMessage(); | 173 | RequestMessage msg = new RequestMessage(); |
| 169 | msg.setKey(key); | 174 | msg.setKey(key); |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/RegisterResponseProcessor.java
| @@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.gb28181.transmit.event.response.impl; | @@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.gb28181.transmit.event.response.impl; | ||
| 2 | 2 | ||
| 3 | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; | 3 | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; |
| 4 | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch; | 4 | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch; |
| 5 | +import com.genersoft.iot.vmp.gb28181.bean.SipTransactionInfo; | ||
| 5 | import com.genersoft.iot.vmp.gb28181.bean.SubscribeHolder; | 6 | import com.genersoft.iot.vmp.gb28181.bean.SubscribeHolder; |
| 6 | import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; | 7 | import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; |
| 7 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; | 8 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; |
| @@ -10,6 +11,7 @@ import com.genersoft.iot.vmp.service.IPlatformService; | @@ -10,6 +11,7 @@ import com.genersoft.iot.vmp.service.IPlatformService; | ||
| 10 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; | 11 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| 11 | import com.genersoft.iot.vmp.storager.IVideoManagerStorage; | 12 | import com.genersoft.iot.vmp.storager.IVideoManagerStorage; |
| 12 | import com.genersoft.iot.vmp.storager.dao.dto.PlatformRegisterInfo; | 13 | import com.genersoft.iot.vmp.storager.dao.dto.PlatformRegisterInfo; |
| 14 | +import gov.nist.javax.sip.message.SIPResponse; | ||
| 13 | import org.slf4j.Logger; | 15 | import org.slf4j.Logger; |
| 14 | import org.slf4j.LoggerFactory; | 16 | import org.slf4j.LoggerFactory; |
| 15 | import org.springframework.beans.factory.annotation.Autowired; | 17 | import org.springframework.beans.factory.annotation.Autowired; |
| @@ -18,7 +20,6 @@ import org.springframework.stereotype.Component; | @@ -18,7 +20,6 @@ import org.springframework.stereotype.Component; | ||
| 18 | import javax.sip.InvalidArgumentException; | 20 | import javax.sip.InvalidArgumentException; |
| 19 | import javax.sip.ResponseEvent; | 21 | import javax.sip.ResponseEvent; |
| 20 | import javax.sip.SipException; | 22 | import javax.sip.SipException; |
| 21 | -import javax.sip.header.CallIdHeader; | ||
| 22 | import javax.sip.header.WWWAuthenticateHeader; | 23 | import javax.sip.header.WWWAuthenticateHeader; |
| 23 | import javax.sip.message.Response; | 24 | import javax.sip.message.Response; |
| 24 | import java.text.ParseException; | 25 | import java.text.ParseException; |
| @@ -65,9 +66,8 @@ public class RegisterResponseProcessor extends SIPResponseProcessorAbstract { | @@ -65,9 +66,8 @@ public class RegisterResponseProcessor extends SIPResponseProcessorAbstract { | ||
| 65 | */ | 66 | */ |
| 66 | @Override | 67 | @Override |
| 67 | public void process(ResponseEvent evt) { | 68 | public void process(ResponseEvent evt) { |
| 68 | - Response response = evt.getResponse(); | ||
| 69 | - CallIdHeader callIdHeader = (CallIdHeader) response.getHeader(CallIdHeader.NAME); | ||
| 70 | - String callId = callIdHeader.getCallId(); | 69 | + SIPResponse response = (SIPResponse)evt.getResponse(); |
| 70 | + String callId = response.getCallIdHeader().getCallId(); | ||
| 71 | PlatformRegisterInfo platformRegisterInfo = redisCatchStorage.queryPlatformRegisterInfo(callId); | 71 | PlatformRegisterInfo platformRegisterInfo = redisCatchStorage.queryPlatformRegisterInfo(callId); |
| 72 | if (platformRegisterInfo == null) { | 72 | if (platformRegisterInfo == null) { |
| 73 | logger.info(String.format("[国标级联]未找到callId: %s 的注册/注销平台id", callId )); | 73 | logger.info(String.format("[国标级联]未找到callId: %s 的注册/注销平台id", callId )); |
| @@ -90,15 +90,17 @@ public class RegisterResponseProcessor extends SIPResponseProcessorAbstract { | @@ -90,15 +90,17 @@ public class RegisterResponseProcessor extends SIPResponseProcessorAbstract { | ||
| 90 | 90 | ||
| 91 | if (response.getStatusCode() == Response.UNAUTHORIZED) { | 91 | if (response.getStatusCode() == Response.UNAUTHORIZED) { |
| 92 | WWWAuthenticateHeader www = (WWWAuthenticateHeader)response.getHeader(WWWAuthenticateHeader.NAME); | 92 | WWWAuthenticateHeader www = (WWWAuthenticateHeader)response.getHeader(WWWAuthenticateHeader.NAME); |
| 93 | + SipTransactionInfo sipTransactionInfo = new SipTransactionInfo(response); | ||
| 93 | try { | 94 | try { |
| 94 | - sipCommanderForPlatform.register(parentPlatform, callId, www, null, null, true, platformRegisterInfo.isRegister()); | 95 | + sipCommanderForPlatform.register(parentPlatform, sipTransactionInfo, www, null, null, true, platformRegisterInfo.isRegister()); |
| 95 | } catch (SipException | InvalidArgumentException | ParseException e) { | 96 | } catch (SipException | InvalidArgumentException | ParseException e) { |
| 96 | logger.error("[命令发送失败] 国标级联 再次注册: {}", e.getMessage()); | 97 | logger.error("[命令发送失败] 国标级联 再次注册: {}", e.getMessage()); |
| 97 | } | 98 | } |
| 98 | }else if (response.getStatusCode() == Response.OK){ | 99 | }else if (response.getStatusCode() == Response.OK){ |
| 99 | 100 | ||
| 100 | if (platformRegisterInfo.isRegister()) { | 101 | if (platformRegisterInfo.isRegister()) { |
| 101 | - platformService.online(parentPlatform); | 102 | + SipTransactionInfo sipTransactionInfo = new SipTransactionInfo(response); |
| 103 | + platformService.online(parentPlatform, sipTransactionInfo); | ||
| 102 | }else { | 104 | }else { |
| 103 | platformService.offline(parentPlatform, false); | 105 | platformService.offline(parentPlatform, false); |
| 104 | } | 106 | } |
src/main/java/com/genersoft/iot/vmp/media/zlm/AssistRESTfulUtils.java
| @@ -9,17 +9,12 @@ import org.jetbrains.annotations.NotNull; | @@ -9,17 +9,12 @@ import org.jetbrains.annotations.NotNull; | ||
| 9 | import org.slf4j.Logger; | 9 | import org.slf4j.Logger; |
| 10 | import org.slf4j.LoggerFactory; | 10 | import org.slf4j.LoggerFactory; |
| 11 | import org.springframework.stereotype.Component; | 11 | import org.springframework.stereotype.Component; |
| 12 | -import org.springframework.util.ObjectUtils; | ||
| 13 | -import org.springframework.util.StringUtils; | ||
| 14 | 12 | ||
| 15 | -import java.io.File; | ||
| 16 | -import java.io.FileOutputStream; | ||
| 17 | import java.io.IOException; | 13 | import java.io.IOException; |
| 18 | import java.net.ConnectException; | 14 | import java.net.ConnectException; |
| 19 | import java.util.HashMap; | 15 | import java.util.HashMap; |
| 20 | import java.util.Map; | 16 | import java.util.Map; |
| 21 | import java.util.Objects; | 17 | import java.util.Objects; |
| 22 | -import java.util.concurrent.TimeUnit; | ||
| 23 | 18 | ||
| 24 | @Component | 19 | @Component |
| 25 | public class AssistRESTfulUtils { | 20 | public class AssistRESTfulUtils { |
| @@ -137,6 +132,11 @@ public class AssistRESTfulUtils { | @@ -137,6 +132,11 @@ public class AssistRESTfulUtils { | ||
| 137 | return sendGet(mediaServerItem, "api/record/file/duration",param, callback); | 132 | return sendGet(mediaServerItem, "api/record/file/duration",param, callback); |
| 138 | } | 133 | } |
| 139 | 134 | ||
| 135 | + public JSONObject getInfo(MediaServerItem mediaServerItem, RequestCallback callback){ | ||
| 136 | + Map<String, Object> param = new HashMap<>(); | ||
| 137 | + return sendGet(mediaServerItem, "api/record/info",param, callback); | ||
| 138 | + } | ||
| 139 | + | ||
| 140 | public JSONObject addStreamCallInfo(MediaServerItem mediaServerItem, String app, String stream, String callId, RequestCallback callback){ | 140 | public JSONObject addStreamCallInfo(MediaServerItem mediaServerItem, String app, String stream, String callId, RequestCallback callback){ |
| 141 | Map<String, Object> param = new HashMap<>(); | 141 | Map<String, Object> param = new HashMap<>(); |
| 142 | param.put("app",app); | 142 | param.put("app",app); |
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
| @@ -119,10 +119,11 @@ public class ZLMHttpHookListener { | @@ -119,10 +119,11 @@ public class ZLMHttpHookListener { | ||
| 119 | * 服务器定时上报时间,上报间隔可配置,默认10s上报一次 | 119 | * 服务器定时上报时间,上报间隔可配置,默认10s上报一次 |
| 120 | */ | 120 | */ |
| 121 | @ResponseBody | 121 | @ResponseBody |
| 122 | + | ||
| 122 | @PostMapping(value = "/on_server_keepalive", produces = "application/json;charset=UTF-8") | 123 | @PostMapping(value = "/on_server_keepalive", produces = "application/json;charset=UTF-8") |
| 123 | public HookResult onServerKeepalive(@RequestBody OnServerKeepaliveHookParam param) { | 124 | public HookResult onServerKeepalive(@RequestBody OnServerKeepaliveHookParam param) { |
| 124 | 125 | ||
| 125 | - logger.info("[ZLM HOOK] 收到zlm心跳:" + param.getMediaServerId()); | 126 | +// logger.info("[ZLM HOOK] 收到zlm心跳:" + param.getMediaServerId()); |
| 126 | 127 | ||
| 127 | taskExecutor.execute(() -> { | 128 | taskExecutor.execute(() -> { |
| 128 | List<ZlmHttpHookSubscribe.Event> subscribes = this.subscribe.getSubscribes(HookType.on_server_keepalive); | 129 | List<ZlmHttpHookSubscribe.Event> subscribes = this.subscribe.getSubscribes(HookType.on_server_keepalive); |
| @@ -142,6 +143,7 @@ public class ZLMHttpHookListener { | @@ -142,6 +143,7 @@ public class ZLMHttpHookListener { | ||
| 142 | * 播放器鉴权事件,rtsp/rtmp/http-flv/ws-flv/hls的播放都将触发此鉴权事件。 | 143 | * 播放器鉴权事件,rtsp/rtmp/http-flv/ws-flv/hls的播放都将触发此鉴权事件。 |
| 143 | */ | 144 | */ |
| 144 | @ResponseBody | 145 | @ResponseBody |
| 146 | + | ||
| 145 | @PostMapping(value = "/on_play", produces = "application/json;charset=UTF-8") | 147 | @PostMapping(value = "/on_play", produces = "application/json;charset=UTF-8") |
| 146 | public HookResult onPlay(@RequestBody OnPlayHookParam param) { | 148 | public HookResult onPlay(@RequestBody OnPlayHookParam param) { |
| 147 | if (logger.isDebugEnabled()) { | 149 | if (logger.isDebugEnabled()) { |
| @@ -264,9 +266,28 @@ public class ZLMHttpHookListener { | @@ -264,9 +266,28 @@ public class ZLMHttpHookListener { | ||
| 264 | } | 266 | } |
| 265 | 267 | ||
| 266 | } | 268 | } |
| 269 | + if (mediaInfo.getRecordAssistPort() > 0 && userSetting.getRecordPath() == null) { | ||
| 270 | + logger.info("推流时发现尚未设置录像路径,从assist服务中读取"); | ||
| 271 | + JSONObject info = assistRESTfulUtils.getInfo(mediaInfo, null); | ||
| 272 | + if (info != null && info.getInteger("code") != null && info.getInteger("code") == 0 ) { | ||
| 273 | + JSONObject dataJson = info.getJSONObject("data"); | ||
| 274 | + if (dataJson != null) { | ||
| 275 | + String recordPath = dataJson.getString("record"); | ||
| 276 | + userSetting.setRecordPath(recordPath); | ||
| 277 | + result.setMp4_save_path(recordPath); | ||
| 278 | + // 修改zlm中的录像路径 | ||
| 279 | + if (mediaInfo.isAutoConfig()) { | ||
| 280 | + taskExecutor.execute(() -> { | ||
| 281 | + mediaServerService.setZLMConfig(mediaInfo, false); | ||
| 282 | + }); | ||
| 283 | + } | ||
| 284 | + } | ||
| 285 | + } | ||
| 286 | + } | ||
| 267 | return result; | 287 | return result; |
| 268 | } | 288 | } |
| 269 | 289 | ||
| 290 | + | ||
| 270 | /** | 291 | /** |
| 271 | * rtsp/rtmp流注册或注销时触发此事件;此事件对回复不敏感。 | 292 | * rtsp/rtmp流注册或注销时触发此事件;此事件对回复不敏感。 |
| 272 | */ | 293 | */ |
| @@ -293,8 +314,12 @@ public class ZLMHttpHookListener { | @@ -293,8 +314,12 @@ public class ZLMHttpHookListener { | ||
| 293 | subscribe.response(mediaInfo, json); | 314 | subscribe.response(mediaInfo, json); |
| 294 | } | 315 | } |
| 295 | } | 316 | } |
| 296 | - // 流消失移除redis play | 317 | + |
| 318 | + List<OnStreamChangedHookParam.MediaTrack> tracks = param.getTracks(); | ||
| 319 | + // TODO 重构此处逻辑 | ||
| 320 | + | ||
| 297 | if (param.isRegist()) { | 321 | if (param.isRegist()) { |
| 322 | + // 处理流注册的鉴权信息 | ||
| 298 | if (param.getOriginType() == OriginType.RTMP_PUSH.ordinal() | 323 | if (param.getOriginType() == OriginType.RTMP_PUSH.ordinal() |
| 299 | || param.getOriginType() == OriginType.RTSP_PUSH.ordinal() | 324 | || param.getOriginType() == OriginType.RTSP_PUSH.ordinal() |
| 300 | || param.getOriginType() == OriginType.RTC_PUSH.ordinal()) { | 325 | || param.getOriginType() == OriginType.RTC_PUSH.ordinal()) { |
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java
| @@ -334,9 +334,9 @@ public class ZLMRESTfulUtils { | @@ -334,9 +334,9 @@ public class ZLMRESTfulUtils { | ||
| 334 | sendPost(mediaServerItem, "kick_sessions",param, null); | 334 | sendPost(mediaServerItem, "kick_sessions",param, null); |
| 335 | } | 335 | } |
| 336 | 336 | ||
| 337 | - public void getSnap(MediaServerItem mediaServerItem, String flvUrl, int timeout_sec, int expire_sec, String targetPath, String fileName) { | 337 | + public void getSnap(MediaServerItem mediaServerItem, String streamUrl, int timeout_sec, int expire_sec, String targetPath, String fileName) { |
| 338 | Map<String, Object> param = new HashMap<>(3); | 338 | Map<String, Object> param = new HashMap<>(3); |
| 339 | - param.put("url", flvUrl); | 339 | + param.put("url", streamUrl); |
| 340 | param.put("timeout_sec", timeout_sec); | 340 | param.put("timeout_sec", timeout_sec); |
| 341 | param.put("expire_sec", expire_sec); | 341 | param.put("expire_sec", expire_sec); |
| 342 | sendGetForImg(mediaServerItem, "getSnap", param, targetPath, fileName); | 342 | sendGetForImg(mediaServerItem, "getSnap", param, targetPath, fileName); |
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java
| @@ -262,8 +262,11 @@ public class ZLMRTPServerFactory { | @@ -262,8 +262,11 @@ public class ZLMRTPServerFactory { | ||
| 262 | logger.info("[保持端口] {}->监听端口到期继续保持监听", ssrc); | 262 | logger.info("[保持端口] {}->监听端口到期继续保持监听", ssrc); |
| 263 | keepPort(serverItem, ssrc); | 263 | keepPort(serverItem, ssrc); |
| 264 | }); | 264 | }); |
| 265 | - } | ||
| 266 | logger.info("[保持端口] {}->监听端口: {}", ssrc, localPort); | 265 | logger.info("[保持端口] {}->监听端口: {}", ssrc, localPort); |
| 266 | + logger.info("[保持端口] {}->监听端口: {}", ssrc, localPort); | ||
| 267 | + }else { | ||
| 268 | + logger.info("[保持端口] 监听端口失败: {}", ssrc); | ||
| 269 | + } | ||
| 267 | return localPort; | 270 | return localPort; |
| 268 | } | 271 | } |
| 269 | 272 |
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMServerConfig.java
| @@ -10,21 +10,87 @@ public class ZLMServerConfig { | @@ -10,21 +10,87 @@ public class ZLMServerConfig { | ||
| 10 | @JSONField(name = "api.secret") | 10 | @JSONField(name = "api.secret") |
| 11 | private String apiSecret; | 11 | private String apiSecret; |
| 12 | 12 | ||
| 13 | + @JSONField(name = "api.snapRoot") | ||
| 14 | + private String apiSnapRoot; | ||
| 15 | + | ||
| 16 | + @JSONField(name = "api.defaultSnap") | ||
| 17 | + private String apiDefaultSnap; | ||
| 18 | + | ||
| 13 | @JSONField(name = "ffmpeg.bin") | 19 | @JSONField(name = "ffmpeg.bin") |
| 14 | private String ffmpegBin; | 20 | private String ffmpegBin; |
| 15 | 21 | ||
| 16 | @JSONField(name = "ffmpeg.cmd") | 22 | @JSONField(name = "ffmpeg.cmd") |
| 17 | private String ffmpegCmd; | 23 | private String ffmpegCmd; |
| 18 | 24 | ||
| 25 | + @JSONField(name = "ffmpeg.snap") | ||
| 26 | + private String ffmpegSnap; | ||
| 27 | + | ||
| 19 | @JSONField(name = "ffmpeg.log") | 28 | @JSONField(name = "ffmpeg.log") |
| 20 | private String ffmpegLog; | 29 | private String ffmpegLog; |
| 21 | 30 | ||
| 31 | + @JSONField(name = "ffmpeg.restart_sec") | ||
| 32 | + private String ffmpegRestartSec; | ||
| 33 | + | ||
| 34 | + @JSONField(name = "protocol.modify_stamp") | ||
| 35 | + private String protocolModifyStamp; | ||
| 36 | + | ||
| 37 | + @JSONField(name = "protocol.enable_audio") | ||
| 38 | + private String protocolEnableAudio; | ||
| 39 | + | ||
| 40 | + @JSONField(name = "protocol.add_mute_audio") | ||
| 41 | + private String protocolAddMuteAudio; | ||
| 42 | + | ||
| 43 | + @JSONField(name = "protocol.continue_push_ms") | ||
| 44 | + private String protocolContinuePushMs; | ||
| 45 | + | ||
| 46 | + @JSONField(name = "protocol.enable_hls") | ||
| 47 | + private String protocolEnableHls; | ||
| 48 | + | ||
| 49 | + @JSONField(name = "protocol.enable_mp4") | ||
| 50 | + private String protocolEnableMp4; | ||
| 51 | + | ||
| 52 | + @JSONField(name = "protocol.enable_rtsp") | ||
| 53 | + private String protocolEnableRtsp; | ||
| 54 | + | ||
| 55 | + @JSONField(name = "protocol.enable_rtmp") | ||
| 56 | + private String protocolEnableRtmp; | ||
| 57 | + | ||
| 58 | + @JSONField(name = "protocol.enable_ts") | ||
| 59 | + private String protocolEnableTs; | ||
| 60 | + | ||
| 61 | + @JSONField(name = "protocol.enable_fmp4") | ||
| 62 | + private String protocolEnableFmp4; | ||
| 63 | + | ||
| 64 | + @JSONField(name = "protocol.mp4_as_player") | ||
| 65 | + private String protocolMp4AsPlayer; | ||
| 66 | + | ||
| 67 | + @JSONField(name = "protocol.mp4_max_second") | ||
| 68 | + private String protocolMp4MaxSecond; | ||
| 69 | + | ||
| 70 | + @JSONField(name = "protocol.mp4_save_path") | ||
| 71 | + private String protocolMp4SavePath; | ||
| 72 | + | ||
| 73 | + @JSONField(name = "protocol.hls_save_path") | ||
| 74 | + private String protocolHlsSavePath; | ||
| 75 | + | ||
| 76 | + @JSONField(name = "protocol.hls_demand") | ||
| 77 | + private String protocolHlsDemand; | ||
| 78 | + | ||
| 79 | + @JSONField(name = "protocol.rtsp_demand") | ||
| 80 | + private String protocolRtspDemand; | ||
| 81 | + | ||
| 82 | + @JSONField(name = "protocol.rtmp_demand") | ||
| 83 | + private String protocolRtmpDemand; | ||
| 84 | + | ||
| 85 | + @JSONField(name = "protocol.ts_demand") | ||
| 86 | + private String protocolTsDemand; | ||
| 87 | + | ||
| 88 | + @JSONField(name = "protocol.fmp4_demand") | ||
| 89 | + private String protocolFmp4Demand; | ||
| 90 | + | ||
| 22 | @JSONField(name = "general.enableVhost") | 91 | @JSONField(name = "general.enableVhost") |
| 23 | private String generalEnableVhost; | 92 | private String generalEnableVhost; |
| 24 | 93 | ||
| 25 | - @JSONField(name = "general.mediaServerId") | ||
| 26 | - private String generalMediaServerId; | ||
| 27 | - | ||
| 28 | @JSONField(name = "general.flowThreshold") | 94 | @JSONField(name = "general.flowThreshold") |
| 29 | private String generalFlowThreshold; | 95 | private String generalFlowThreshold; |
| 30 | 96 | ||
| @@ -34,6 +100,25 @@ public class ZLMServerConfig { | @@ -34,6 +100,25 @@ public class ZLMServerConfig { | ||
| 34 | @JSONField(name = "general.streamNoneReaderDelayMS") | 100 | @JSONField(name = "general.streamNoneReaderDelayMS") |
| 35 | private int generalStreamNoneReaderDelayMS; | 101 | private int generalStreamNoneReaderDelayMS; |
| 36 | 102 | ||
| 103 | + @JSONField(name = "general.resetWhenRePlay") | ||
| 104 | + private String generalResetWhenRePlay; | ||
| 105 | + | ||
| 106 | + @JSONField(name = "general.mergeWriteMS") | ||
| 107 | + private String generalMergeWriteMS; | ||
| 108 | + | ||
| 109 | + @JSONField(name = "general.mediaServerId") | ||
| 110 | + private String generalMediaServerId; | ||
| 111 | + | ||
| 112 | + @JSONField(name = "general.wait_track_ready_ms") | ||
| 113 | + private String generalWaitTrackReadyMs; | ||
| 114 | + | ||
| 115 | + @JSONField(name = "general.wait_add_track_ms") | ||
| 116 | + private String generalWaitAddTrackMs; | ||
| 117 | + | ||
| 118 | + @JSONField(name = "general.unready_frame_cache") | ||
| 119 | + private String generalUnreadyFrameCache; | ||
| 120 | + | ||
| 121 | + | ||
| 37 | @JSONField(name = "ip") | 122 | @JSONField(name = "ip") |
| 38 | private String ip; | 123 | private String ip; |
| 39 | 124 | ||
| @@ -59,6 +144,18 @@ public class ZLMServerConfig { | @@ -59,6 +144,18 @@ public class ZLMServerConfig { | ||
| 59 | @JSONField(name = "hls.segNum") | 144 | @JSONField(name = "hls.segNum") |
| 60 | private String hlsSegNum; | 145 | private String hlsSegNum; |
| 61 | 146 | ||
| 147 | + @JSONField(name = "hls.segRetain") | ||
| 148 | + private String hlsSegRetain; | ||
| 149 | + | ||
| 150 | + @JSONField(name = "hls.broadcastRecordTs") | ||
| 151 | + private String hlsBroadcastRecordTs; | ||
| 152 | + | ||
| 153 | + @JSONField(name = "hls.deleteDelaySec") | ||
| 154 | + private String hlsDeleteDelaySec; | ||
| 155 | + | ||
| 156 | + @JSONField(name = "hls.segKeep") | ||
| 157 | + private String hlsSegKeep; | ||
| 158 | + | ||
| 62 | @JSONField(name = "hook.access_file_except_hls") | 159 | @JSONField(name = "hook.access_file_except_hls") |
| 63 | private String hookAccessFileExceptHLS; | 160 | private String hookAccessFileExceptHLS; |
| 64 | 161 | ||
| @@ -104,6 +201,18 @@ public class ZLMServerConfig { | @@ -104,6 +201,18 @@ public class ZLMServerConfig { | ||
| 104 | @JSONField(name = "hook.on_stream_not_found") | 201 | @JSONField(name = "hook.on_stream_not_found") |
| 105 | private String hookOnStreamNotFound; | 202 | private String hookOnStreamNotFound; |
| 106 | 203 | ||
| 204 | + @JSONField(name = "hook.on_server_started") | ||
| 205 | + private String hookOnServerStarted; | ||
| 206 | + | ||
| 207 | + @JSONField(name = "hook.on_server_keepalive") | ||
| 208 | + private String hookOnServerKeepalive; | ||
| 209 | + | ||
| 210 | + @JSONField(name = "hook.on_send_rtp_stopped") | ||
| 211 | + private String hookOnSendRtpStopped; | ||
| 212 | + | ||
| 213 | + @JSONField(name = "hook.on_rtp_server_timeout") | ||
| 214 | + private String hookOnRtpServerTimeout; | ||
| 215 | + | ||
| 107 | @JSONField(name = "hook.timeoutSec") | 216 | @JSONField(name = "hook.timeoutSec") |
| 108 | private String hookTimeoutSec; | 217 | private String hookTimeoutSec; |
| 109 | 218 | ||
| @@ -813,4 +922,292 @@ public class ZLMServerConfig { | @@ -813,4 +922,292 @@ public class ZLMServerConfig { | ||
| 813 | public void setPortRange(String portRange) { | 922 | public void setPortRange(String portRange) { |
| 814 | this.portRange = portRange; | 923 | this.portRange = portRange; |
| 815 | } | 924 | } |
| 925 | + | ||
| 926 | + public String getApiSnapRoot() { | ||
| 927 | + return apiSnapRoot; | ||
| 928 | + } | ||
| 929 | + | ||
| 930 | + public void setApiSnapRoot(String apiSnapRoot) { | ||
| 931 | + this.apiSnapRoot = apiSnapRoot; | ||
| 932 | + } | ||
| 933 | + | ||
| 934 | + public String getApiDefaultSnap() { | ||
| 935 | + return apiDefaultSnap; | ||
| 936 | + } | ||
| 937 | + | ||
| 938 | + public void setApiDefaultSnap(String apiDefaultSnap) { | ||
| 939 | + this.apiDefaultSnap = apiDefaultSnap; | ||
| 940 | + } | ||
| 941 | + | ||
| 942 | + public String getFfmpegSnap() { | ||
| 943 | + return ffmpegSnap; | ||
| 944 | + } | ||
| 945 | + | ||
| 946 | + public void setFfmpegSnap(String ffmpegSnap) { | ||
| 947 | + this.ffmpegSnap = ffmpegSnap; | ||
| 948 | + } | ||
| 949 | + | ||
| 950 | + public String getFfmpegRestartSec() { | ||
| 951 | + return ffmpegRestartSec; | ||
| 952 | + } | ||
| 953 | + | ||
| 954 | + public void setFfmpegRestartSec(String ffmpegRestartSec) { | ||
| 955 | + this.ffmpegRestartSec = ffmpegRestartSec; | ||
| 956 | + } | ||
| 957 | + | ||
| 958 | + public String getProtocolModifyStamp() { | ||
| 959 | + return protocolModifyStamp; | ||
| 960 | + } | ||
| 961 | + | ||
| 962 | + public void setProtocolModifyStamp(String protocolModifyStamp) { | ||
| 963 | + this.protocolModifyStamp = protocolModifyStamp; | ||
| 964 | + } | ||
| 965 | + | ||
| 966 | + public String getProtocolEnableAudio() { | ||
| 967 | + return protocolEnableAudio; | ||
| 968 | + } | ||
| 969 | + | ||
| 970 | + public void setProtocolEnableAudio(String protocolEnableAudio) { | ||
| 971 | + this.protocolEnableAudio = protocolEnableAudio; | ||
| 972 | + } | ||
| 973 | + | ||
| 974 | + public String getProtocolAddMuteAudio() { | ||
| 975 | + return protocolAddMuteAudio; | ||
| 976 | + } | ||
| 977 | + | ||
| 978 | + public void setProtocolAddMuteAudio(String protocolAddMuteAudio) { | ||
| 979 | + this.protocolAddMuteAudio = protocolAddMuteAudio; | ||
| 980 | + } | ||
| 981 | + | ||
| 982 | + public String getProtocolContinuePushMs() { | ||
| 983 | + return protocolContinuePushMs; | ||
| 984 | + } | ||
| 985 | + | ||
| 986 | + public void setProtocolContinuePushMs(String protocolContinuePushMs) { | ||
| 987 | + this.protocolContinuePushMs = protocolContinuePushMs; | ||
| 988 | + } | ||
| 989 | + | ||
| 990 | + public String getProtocolEnableHls() { | ||
| 991 | + return protocolEnableHls; | ||
| 992 | + } | ||
| 993 | + | ||
| 994 | + public void setProtocolEnableHls(String protocolEnableHls) { | ||
| 995 | + this.protocolEnableHls = protocolEnableHls; | ||
| 996 | + } | ||
| 997 | + | ||
| 998 | + public String getProtocolEnableMp4() { | ||
| 999 | + return protocolEnableMp4; | ||
| 1000 | + } | ||
| 1001 | + | ||
| 1002 | + public void setProtocolEnableMp4(String protocolEnableMp4) { | ||
| 1003 | + this.protocolEnableMp4 = protocolEnableMp4; | ||
| 1004 | + } | ||
| 1005 | + | ||
| 1006 | + public String getProtocolEnableRtsp() { | ||
| 1007 | + return protocolEnableRtsp; | ||
| 1008 | + } | ||
| 1009 | + | ||
| 1010 | + public void setProtocolEnableRtsp(String protocolEnableRtsp) { | ||
| 1011 | + this.protocolEnableRtsp = protocolEnableRtsp; | ||
| 1012 | + } | ||
| 1013 | + | ||
| 1014 | + public String getProtocolEnableRtmp() { | ||
| 1015 | + return protocolEnableRtmp; | ||
| 1016 | + } | ||
| 1017 | + | ||
| 1018 | + public void setProtocolEnableRtmp(String protocolEnableRtmp) { | ||
| 1019 | + this.protocolEnableRtmp = protocolEnableRtmp; | ||
| 1020 | + } | ||
| 1021 | + | ||
| 1022 | + public String getProtocolEnableTs() { | ||
| 1023 | + return protocolEnableTs; | ||
| 1024 | + } | ||
| 1025 | + | ||
| 1026 | + public void setProtocolEnableTs(String protocolEnableTs) { | ||
| 1027 | + this.protocolEnableTs = protocolEnableTs; | ||
| 1028 | + } | ||
| 1029 | + | ||
| 1030 | + public String getProtocolEnableFmp4() { | ||
| 1031 | + return protocolEnableFmp4; | ||
| 1032 | + } | ||
| 1033 | + | ||
| 1034 | + public void setProtocolEnableFmp4(String protocolEnableFmp4) { | ||
| 1035 | + this.protocolEnableFmp4 = protocolEnableFmp4; | ||
| 1036 | + } | ||
| 1037 | + | ||
| 1038 | + public String getProtocolMp4AsPlayer() { | ||
| 1039 | + return protocolMp4AsPlayer; | ||
| 1040 | + } | ||
| 1041 | + | ||
| 1042 | + public void setProtocolMp4AsPlayer(String protocolMp4AsPlayer) { | ||
| 1043 | + this.protocolMp4AsPlayer = protocolMp4AsPlayer; | ||
| 1044 | + } | ||
| 1045 | + | ||
| 1046 | + public String getProtocolMp4MaxSecond() { | ||
| 1047 | + return protocolMp4MaxSecond; | ||
| 1048 | + } | ||
| 1049 | + | ||
| 1050 | + public void setProtocolMp4MaxSecond(String protocolMp4MaxSecond) { | ||
| 1051 | + this.protocolMp4MaxSecond = protocolMp4MaxSecond; | ||
| 1052 | + } | ||
| 1053 | + | ||
| 1054 | + public String getProtocolMp4SavePath() { | ||
| 1055 | + return protocolMp4SavePath; | ||
| 1056 | + } | ||
| 1057 | + | ||
| 1058 | + public void setProtocolMp4SavePath(String protocolMp4SavePath) { | ||
| 1059 | + this.protocolMp4SavePath = protocolMp4SavePath; | ||
| 1060 | + } | ||
| 1061 | + | ||
| 1062 | + public String getProtocolHlsSavePath() { | ||
| 1063 | + return protocolHlsSavePath; | ||
| 1064 | + } | ||
| 1065 | + | ||
| 1066 | + public void setProtocolHlsSavePath(String protocolHlsSavePath) { | ||
| 1067 | + this.protocolHlsSavePath = protocolHlsSavePath; | ||
| 1068 | + } | ||
| 1069 | + | ||
| 1070 | + public String getProtocolHlsDemand() { | ||
| 1071 | + return protocolHlsDemand; | ||
| 1072 | + } | ||
| 1073 | + | ||
| 1074 | + public void setProtocolHlsDemand(String protocolHlsDemand) { | ||
| 1075 | + this.protocolHlsDemand = protocolHlsDemand; | ||
| 1076 | + } | ||
| 1077 | + | ||
| 1078 | + public String getProtocolRtspDemand() { | ||
| 1079 | + return protocolRtspDemand; | ||
| 1080 | + } | ||
| 1081 | + | ||
| 1082 | + public void setProtocolRtspDemand(String protocolRtspDemand) { | ||
| 1083 | + this.protocolRtspDemand = protocolRtspDemand; | ||
| 1084 | + } | ||
| 1085 | + | ||
| 1086 | + public String getProtocolRtmpDemand() { | ||
| 1087 | + return protocolRtmpDemand; | ||
| 1088 | + } | ||
| 1089 | + | ||
| 1090 | + public void setProtocolRtmpDemand(String protocolRtmpDemand) { | ||
| 1091 | + this.protocolRtmpDemand = protocolRtmpDemand; | ||
| 1092 | + } | ||
| 1093 | + | ||
| 1094 | + public String getProtocolTsDemand() { | ||
| 1095 | + return protocolTsDemand; | ||
| 1096 | + } | ||
| 1097 | + | ||
| 1098 | + public void setProtocolTsDemand(String protocolTsDemand) { | ||
| 1099 | + this.protocolTsDemand = protocolTsDemand; | ||
| 1100 | + } | ||
| 1101 | + | ||
| 1102 | + public String getProtocolFmp4Demand() { | ||
| 1103 | + return protocolFmp4Demand; | ||
| 1104 | + } | ||
| 1105 | + | ||
| 1106 | + public void setProtocolFmp4Demand(String protocolFmp4Demand) { | ||
| 1107 | + this.protocolFmp4Demand = protocolFmp4Demand; | ||
| 1108 | + } | ||
| 1109 | + | ||
| 1110 | + public String getGeneralResetWhenRePlay() { | ||
| 1111 | + return generalResetWhenRePlay; | ||
| 1112 | + } | ||
| 1113 | + | ||
| 1114 | + public void setGeneralResetWhenRePlay(String generalResetWhenRePlay) { | ||
| 1115 | + this.generalResetWhenRePlay = generalResetWhenRePlay; | ||
| 1116 | + } | ||
| 1117 | + | ||
| 1118 | + public String getGeneralMergeWriteMS() { | ||
| 1119 | + return generalMergeWriteMS; | ||
| 1120 | + } | ||
| 1121 | + | ||
| 1122 | + public void setGeneralMergeWriteMS(String generalMergeWriteMS) { | ||
| 1123 | + this.generalMergeWriteMS = generalMergeWriteMS; | ||
| 1124 | + } | ||
| 1125 | + | ||
| 1126 | + public String getGeneralWaitTrackReadyMs() { | ||
| 1127 | + return generalWaitTrackReadyMs; | ||
| 1128 | + } | ||
| 1129 | + | ||
| 1130 | + public void setGeneralWaitTrackReadyMs(String generalWaitTrackReadyMs) { | ||
| 1131 | + this.generalWaitTrackReadyMs = generalWaitTrackReadyMs; | ||
| 1132 | + } | ||
| 1133 | + | ||
| 1134 | + public String getGeneralWaitAddTrackMs() { | ||
| 1135 | + return generalWaitAddTrackMs; | ||
| 1136 | + } | ||
| 1137 | + | ||
| 1138 | + public void setGeneralWaitAddTrackMs(String generalWaitAddTrackMs) { | ||
| 1139 | + this.generalWaitAddTrackMs = generalWaitAddTrackMs; | ||
| 1140 | + } | ||
| 1141 | + | ||
| 1142 | + public String getGeneralUnreadyFrameCache() { | ||
| 1143 | + return generalUnreadyFrameCache; | ||
| 1144 | + } | ||
| 1145 | + | ||
| 1146 | + public void setGeneralUnreadyFrameCache(String generalUnreadyFrameCache) { | ||
| 1147 | + this.generalUnreadyFrameCache = generalUnreadyFrameCache; | ||
| 1148 | + } | ||
| 1149 | + | ||
| 1150 | + public String getHlsSegRetain() { | ||
| 1151 | + return hlsSegRetain; | ||
| 1152 | + } | ||
| 1153 | + | ||
| 1154 | + public void setHlsSegRetain(String hlsSegRetain) { | ||
| 1155 | + this.hlsSegRetain = hlsSegRetain; | ||
| 1156 | + } | ||
| 1157 | + | ||
| 1158 | + public String getHlsBroadcastRecordTs() { | ||
| 1159 | + return hlsBroadcastRecordTs; | ||
| 1160 | + } | ||
| 1161 | + | ||
| 1162 | + public void setHlsBroadcastRecordTs(String hlsBroadcastRecordTs) { | ||
| 1163 | + this.hlsBroadcastRecordTs = hlsBroadcastRecordTs; | ||
| 1164 | + } | ||
| 1165 | + | ||
| 1166 | + public String getHlsDeleteDelaySec() { | ||
| 1167 | + return hlsDeleteDelaySec; | ||
| 1168 | + } | ||
| 1169 | + | ||
| 1170 | + public void setHlsDeleteDelaySec(String hlsDeleteDelaySec) { | ||
| 1171 | + this.hlsDeleteDelaySec = hlsDeleteDelaySec; | ||
| 1172 | + } | ||
| 1173 | + | ||
| 1174 | + public String getHlsSegKeep() { | ||
| 1175 | + return hlsSegKeep; | ||
| 1176 | + } | ||
| 1177 | + | ||
| 1178 | + public void setHlsSegKeep(String hlsSegKeep) { | ||
| 1179 | + this.hlsSegKeep = hlsSegKeep; | ||
| 1180 | + } | ||
| 1181 | + | ||
| 1182 | + public String getHookOnServerStarted() { | ||
| 1183 | + return hookOnServerStarted; | ||
| 1184 | + } | ||
| 1185 | + | ||
| 1186 | + public void setHookOnServerStarted(String hookOnServerStarted) { | ||
| 1187 | + this.hookOnServerStarted = hookOnServerStarted; | ||
| 1188 | + } | ||
| 1189 | + | ||
| 1190 | + public String getHookOnServerKeepalive() { | ||
| 1191 | + return hookOnServerKeepalive; | ||
| 1192 | + } | ||
| 1193 | + | ||
| 1194 | + public void setHookOnServerKeepalive(String hookOnServerKeepalive) { | ||
| 1195 | + this.hookOnServerKeepalive = hookOnServerKeepalive; | ||
| 1196 | + } | ||
| 1197 | + | ||
| 1198 | + public String getHookOnSendRtpStopped() { | ||
| 1199 | + return hookOnSendRtpStopped; | ||
| 1200 | + } | ||
| 1201 | + | ||
| 1202 | + public void setHookOnSendRtpStopped(String hookOnSendRtpStopped) { | ||
| 1203 | + this.hookOnSendRtpStopped = hookOnSendRtpStopped; | ||
| 1204 | + } | ||
| 1205 | + | ||
| 1206 | + public String getHookOnRtpServerTimeout() { | ||
| 1207 | + return hookOnRtpServerTimeout; | ||
| 1208 | + } | ||
| 1209 | + | ||
| 1210 | + public void setHookOnRtpServerTimeout(String hookOnRtpServerTimeout) { | ||
| 1211 | + this.hookOnRtpServerTimeout = hookOnRtpServerTimeout; | ||
| 1212 | + } | ||
| 816 | } | 1213 | } |
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/HookResultForOnPublish.java
| @@ -5,6 +5,7 @@ public class HookResultForOnPublish extends HookResult{ | @@ -5,6 +5,7 @@ public class HookResultForOnPublish extends HookResult{ | ||
| 5 | private boolean enable_audio; | 5 | private boolean enable_audio; |
| 6 | private boolean enable_mp4; | 6 | private boolean enable_mp4; |
| 7 | private int mp4_max_second; | 7 | private int mp4_max_second; |
| 8 | + private String mp4_save_path; | ||
| 8 | 9 | ||
| 9 | public HookResultForOnPublish() { | 10 | public HookResultForOnPublish() { |
| 10 | } | 11 | } |
| @@ -41,4 +42,12 @@ public class HookResultForOnPublish extends HookResult{ | @@ -41,4 +42,12 @@ public class HookResultForOnPublish extends HookResult{ | ||
| 41 | public void setMp4_max_second(int mp4_max_second) { | 42 | public void setMp4_max_second(int mp4_max_second) { |
| 42 | this.mp4_max_second = mp4_max_second; | 43 | this.mp4_max_second = mp4_max_second; |
| 43 | } | 44 | } |
| 45 | + | ||
| 46 | + public String getMp4_save_path() { | ||
| 47 | + return mp4_save_path; | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + public void setMp4_save_path(String mp4_save_path) { | ||
| 51 | + this.mp4_save_path = mp4_save_path; | ||
| 52 | + } | ||
| 44 | } | 53 | } |
src/main/java/com/genersoft/iot/vmp/service/IDeviceService.java
| @@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.service; | @@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.service; | ||
| 2 | 2 | ||
| 3 | import com.genersoft.iot.vmp.gb28181.bean.Device; | 3 | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| 4 | import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; | 4 | import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; |
| 5 | +import com.genersoft.iot.vmp.gb28181.bean.SipTransactionInfo; | ||
| 5 | import com.genersoft.iot.vmp.gb28181.bean.SyncStatus; | 6 | import com.genersoft.iot.vmp.gb28181.bean.SyncStatus; |
| 6 | import com.genersoft.iot.vmp.vmanager.bean.BaseTree; | 7 | import com.genersoft.iot.vmp.vmanager.bean.BaseTree; |
| 7 | import com.genersoft.iot.vmp.vmanager.bean.ResourceBaceInfo; | 8 | import com.genersoft.iot.vmp.vmanager.bean.ResourceBaceInfo; |
| @@ -18,13 +19,13 @@ public interface IDeviceService { | @@ -18,13 +19,13 @@ public interface IDeviceService { | ||
| 18 | * 设备上线 | 19 | * 设备上线 |
| 19 | * @param device 设备信息 | 20 | * @param device 设备信息 |
| 20 | */ | 21 | */ |
| 21 | - void online(Device device); | 22 | + void online(Device device, SipTransactionInfo sipTransactionInfo); |
| 22 | 23 | ||
| 23 | /** | 24 | /** |
| 24 | * 设备下线 | 25 | * 设备下线 |
| 25 | * @param deviceId 设备编号 | 26 | * @param deviceId 设备编号 |
| 26 | */ | 27 | */ |
| 27 | - void offline(String deviceId); | 28 | + void offline(String deviceId, String reason); |
| 28 | 29 | ||
| 29 | /** | 30 | /** |
| 30 | * 添加目录订阅 | 31 | * 添加目录订阅 |
src/main/java/com/genersoft/iot/vmp/service/IPlatformService.java
| @@ -6,6 +6,7 @@ import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; | @@ -6,6 +6,7 @@ import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; | ||
| 6 | import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; | 6 | import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; |
| 7 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | 7 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 8 | import com.genersoft.iot.vmp.service.bean.InviteTimeOutCallback; | 8 | import com.genersoft.iot.vmp.service.bean.InviteTimeOutCallback; |
| 9 | +import com.genersoft.iot.vmp.gb28181.bean.SipTransactionInfo; | ||
| 9 | import com.github.pagehelper.PageInfo; | 10 | import com.github.pagehelper.PageInfo; |
| 10 | 11 | ||
| 11 | import javax.sip.InvalidArgumentException; | 12 | import javax.sip.InvalidArgumentException; |
| @@ -35,10 +36,16 @@ public interface IPlatformService { | @@ -35,10 +36,16 @@ public interface IPlatformService { | ||
| 35 | boolean add(ParentPlatform parentPlatform); | 36 | boolean add(ParentPlatform parentPlatform); |
| 36 | 37 | ||
| 37 | /** | 38 | /** |
| 39 | + * 添加级联平台 | ||
| 40 | + * @param parentPlatform 级联平台 | ||
| 41 | + */ | ||
| 42 | + boolean update(ParentPlatform parentPlatform); | ||
| 43 | + | ||
| 44 | + /** | ||
| 38 | * 平台上线 | 45 | * 平台上线 |
| 39 | * @param parentPlatform 平台信息 | 46 | * @param parentPlatform 平台信息 |
| 40 | */ | 47 | */ |
| 41 | - void online(ParentPlatform parentPlatform); | 48 | + void online(ParentPlatform parentPlatform, SipTransactionInfo sipTransactionInfo); |
| 42 | 49 | ||
| 43 | /** | 50 | /** |
| 44 | * 平台离线 | 51 | * 平台离线 |
src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java
| @@ -96,7 +96,7 @@ public class DeviceServiceImpl implements IDeviceService { | @@ -96,7 +96,7 @@ public class DeviceServiceImpl implements IDeviceService { | ||
| 96 | private ZLMRESTfulUtils zlmresTfulUtils; | 96 | private ZLMRESTfulUtils zlmresTfulUtils; |
| 97 | 97 | ||
| 98 | @Override | 98 | @Override |
| 99 | - public void online(Device device) { | 99 | + public void online(Device device, SipTransactionInfo sipTransactionInfo) { |
| 100 | logger.info("[设备上线] deviceId:{}->{}:{}", device.getDeviceId(), device.getIp(), device.getPort()); | 100 | logger.info("[设备上线] deviceId:{}->{}:{}", device.getDeviceId(), device.getIp(), device.getPort()); |
| 101 | Device deviceInRedis = redisCatchStorage.getDevice(device.getDeviceId()); | 101 | Device deviceInRedis = redisCatchStorage.getDevice(device.getDeviceId()); |
| 102 | Device deviceInDb = deviceMapper.getDeviceByDeviceId(device.getDeviceId()); | 102 | Device deviceInDb = deviceMapper.getDeviceByDeviceId(device.getDeviceId()); |
| @@ -111,6 +111,14 @@ public class DeviceServiceImpl implements IDeviceService { | @@ -111,6 +111,14 @@ public class DeviceServiceImpl implements IDeviceService { | ||
| 111 | // 默认心跳间隔60 | 111 | // 默认心跳间隔60 |
| 112 | device.setKeepaliveIntervalTime(60); | 112 | device.setKeepaliveIntervalTime(60); |
| 113 | } | 113 | } |
| 114 | + if (sipTransactionInfo != null) { | ||
| 115 | + device.setSipTransactionInfo(sipTransactionInfo); | ||
| 116 | + }else { | ||
| 117 | + if (deviceInRedis != null) { | ||
| 118 | + device.setSipTransactionInfo(deviceInRedis.getSipTransactionInfo()); | ||
| 119 | + } | ||
| 120 | + } | ||
| 121 | + | ||
| 114 | // 第一次上线 或则设备之前是离线状态--进行通道同步和设备信息查询 | 122 | // 第一次上线 或则设备之前是离线状态--进行通道同步和设备信息查询 |
| 115 | if (device.getCreateTime() == null) { | 123 | if (device.getCreateTime() == null) { |
| 116 | device.setOnline(1); | 124 | device.setOnline(1); |
| @@ -163,12 +171,12 @@ public class DeviceServiceImpl implements IDeviceService { | @@ -163,12 +171,12 @@ public class DeviceServiceImpl implements IDeviceService { | ||
| 163 | // 刷新过期任务 | 171 | // 刷新过期任务 |
| 164 | String registerExpireTaskKey = VideoManagerConstants.REGISTER_EXPIRE_TASK_KEY_PREFIX + device.getDeviceId(); | 172 | String registerExpireTaskKey = VideoManagerConstants.REGISTER_EXPIRE_TASK_KEY_PREFIX + device.getDeviceId(); |
| 165 | // 如果第一次注册那么必须在60 * 3时间内收到一个心跳,否则设备离线 | 173 | // 如果第一次注册那么必须在60 * 3时间内收到一个心跳,否则设备离线 |
| 166 | - dynamicTask.startDelay(registerExpireTaskKey, ()-> offline(device.getDeviceId()), device.getKeepaliveIntervalTime() * 1000 * 3); | 174 | + dynamicTask.startDelay(registerExpireTaskKey, ()-> offline(device.getDeviceId(), "首次注册后未能收到心跳"), device.getKeepaliveIntervalTime() * 1000 * 3); |
| 167 | } | 175 | } |
| 168 | 176 | ||
| 169 | @Override | 177 | @Override |
| 170 | - public void offline(String deviceId) { | ||
| 171 | - logger.error("[设备离线], device:{}", deviceId); | 178 | + public void offline(String deviceId, String reason) { |
| 179 | + logger.error("[设备离线],{}, device:{}", reason, deviceId); | ||
| 172 | Device device = deviceMapper.getDeviceByDeviceId(deviceId); | 180 | Device device = deviceMapper.getDeviceByDeviceId(deviceId); |
| 173 | if (device == null) { | 181 | if (device == null) { |
| 174 | return; | 182 | return; |
src/main/java/com/genersoft/iot/vmp/service/impl/GbStreamServiceImpl.java
| @@ -41,6 +41,9 @@ public class GbStreamServiceImpl implements IGbStreamService { | @@ -41,6 +41,9 @@ public class GbStreamServiceImpl implements IGbStreamService { | ||
| 41 | private PlatformGbStreamMapper platformGbStreamMapper; | 41 | private PlatformGbStreamMapper platformGbStreamMapper; |
| 42 | 42 | ||
| 43 | @Autowired | 43 | @Autowired |
| 44 | + private SubscribeHolder subscribeHolder; | ||
| 45 | + | ||
| 46 | + @Autowired | ||
| 44 | private ParentPlatformMapper platformMapper; | 47 | private ParentPlatformMapper platformMapper; |
| 45 | 48 | ||
| 46 | @Autowired | 49 | @Autowired |
| @@ -73,16 +76,23 @@ public class GbStreamServiceImpl implements IGbStreamService { | @@ -73,16 +76,23 @@ public class GbStreamServiceImpl implements IGbStreamService { | ||
| 73 | } | 76 | } |
| 74 | try { | 77 | try { |
| 75 | List<DeviceChannel> deviceChannelList = new ArrayList<>(); | 78 | List<DeviceChannel> deviceChannelList = new ArrayList<>(); |
| 76 | - for (GbStream gbStream : gbStreams) { | 79 | + |
| 80 | + | ||
| 81 | + for (int i = 0; i < gbStreams.size(); i++) { | ||
| 82 | + GbStream gbStream = gbStreams.get(i); | ||
| 77 | gbStream.setCatalogId(catalogId); | 83 | gbStream.setCatalogId(catalogId); |
| 78 | gbStream.setPlatformId(platformId); | 84 | gbStream.setPlatformId(platformId); |
| 79 | // TODO 修改为批量提交 | 85 | // TODO 修改为批量提交 |
| 80 | platformGbStreamMapper.add(gbStream); | 86 | platformGbStreamMapper.add(gbStream); |
| 87 | + logger.info("[关联通道]直播流通道 平台:{}, 共需关联通道数:{}, 已关联:{}", platformId, gbStreams.size(), i + 1); | ||
| 81 | DeviceChannel deviceChannelListByStream = getDeviceChannelListByStreamWithStatus(gbStream, catalogId, parentPlatform); | 88 | DeviceChannel deviceChannelListByStream = getDeviceChannelListByStreamWithStatus(gbStream, catalogId, parentPlatform); |
| 82 | deviceChannelList.add(deviceChannelListByStream); | 89 | deviceChannelList.add(deviceChannelListByStream); |
| 83 | } | 90 | } |
| 84 | dataSourceTransactionManager.commit(transactionStatus); //手动提交 | 91 | dataSourceTransactionManager.commit(transactionStatus); //手动提交 |
| 85 | - eventPublisher.catalogEventPublish(platformId, deviceChannelList, CatalogEvent.ADD); | 92 | + if (subscribeHolder.getCatalogSubscribe(platformId) != null) { |
| 93 | + eventPublisher.catalogEventPublish(platformId, deviceChannelList, CatalogEvent.ADD); | ||
| 94 | + } | ||
| 95 | + | ||
| 86 | result = true; | 96 | result = true; |
| 87 | }catch (Exception e) { | 97 | }catch (Exception e) { |
| 88 | logger.error("批量保存流与平台的关系时错误", e); | 98 | logger.error("批量保存流与平台的关系时错误", e); |
src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java
| @@ -11,6 +11,7 @@ import com.genersoft.iot.vmp.conf.exception.ControllerException; | @@ -11,6 +11,7 @@ import com.genersoft.iot.vmp.conf.exception.ControllerException; | ||
| 11 | import com.genersoft.iot.vmp.gb28181.event.EventPublisher; | 11 | import com.genersoft.iot.vmp.gb28181.event.EventPublisher; |
| 12 | import com.genersoft.iot.vmp.gb28181.session.SsrcConfig; | 12 | import com.genersoft.iot.vmp.gb28181.session.SsrcConfig; |
| 13 | import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; | 13 | import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; |
| 14 | +import com.genersoft.iot.vmp.media.zlm.AssistRESTfulUtils; | ||
| 14 | import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; | 15 | import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; |
| 15 | import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; | 16 | import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; |
| 16 | import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig; | 17 | import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig; |
| @@ -38,6 +39,7 @@ import org.springframework.transaction.TransactionDefinition; | @@ -38,6 +39,7 @@ import org.springframework.transaction.TransactionDefinition; | ||
| 38 | import org.springframework.transaction.TransactionStatus; | 39 | import org.springframework.transaction.TransactionStatus; |
| 39 | import org.springframework.util.ObjectUtils; | 40 | import org.springframework.util.ObjectUtils; |
| 40 | 41 | ||
| 42 | +import java.io.File; | ||
| 41 | import java.time.LocalDateTime; | 43 | import java.time.LocalDateTime; |
| 42 | import java.util.*; | 44 | import java.util.*; |
| 43 | 45 | ||
| @@ -64,6 +66,9 @@ public class MediaServerServiceImpl implements IMediaServerService { | @@ -64,6 +66,9 @@ public class MediaServerServiceImpl implements IMediaServerService { | ||
| 64 | private UserSetting userSetting; | 66 | private UserSetting userSetting; |
| 65 | 67 | ||
| 66 | @Autowired | 68 | @Autowired |
| 69 | + private AssistRESTfulUtils assistRESTfulUtils; | ||
| 70 | + | ||
| 71 | + @Autowired | ||
| 67 | private ZLMRESTfulUtils zlmresTfulUtils; | 72 | private ZLMRESTfulUtils zlmresTfulUtils; |
| 68 | 73 | ||
| 69 | @Autowired | 74 | @Autowired |
| @@ -409,13 +414,27 @@ public class MediaServerServiceImpl implements IMediaServerService { | @@ -409,13 +414,27 @@ public class MediaServerServiceImpl implements IMediaServerService { | ||
| 409 | } | 414 | } |
| 410 | RedisUtil.set(key, serverItem); | 415 | RedisUtil.set(key, serverItem); |
| 411 | resetOnlineServerItem(serverItem); | 416 | resetOnlineServerItem(serverItem); |
| 417 | + | ||
| 418 | + | ||
| 412 | if (serverItem.isAutoConfig()) { | 419 | if (serverItem.isAutoConfig()) { |
| 420 | + // 查看assist服务的录像路径配置 | ||
| 421 | + if (serverItem.getRecordAssistPort() > 0 && userSetting.getRecordPath() == null) { | ||
| 422 | + JSONObject info = assistRESTfulUtils.getInfo(serverItem, null); | ||
| 423 | + if (info != null && info.getInteger("code") != null && info.getInteger("code") == 0 ) { | ||
| 424 | + JSONObject dataJson = info.getJSONObject("data"); | ||
| 425 | + if (dataJson != null) { | ||
| 426 | + String recordPath = dataJson.getString("record"); | ||
| 427 | + userSetting.setRecordPath(recordPath); | ||
| 428 | + } | ||
| 429 | + } | ||
| 430 | + } | ||
| 413 | setZLMConfig(serverItem, "0".equals(zlmServerConfig.getHookEnable())); | 431 | setZLMConfig(serverItem, "0".equals(zlmServerConfig.getHookEnable())); |
| 414 | } | 432 | } |
| 415 | final String zlmKeepaliveKey = zlmKeepaliveKeyPrefix + serverItem.getId(); | 433 | final String zlmKeepaliveKey = zlmKeepaliveKeyPrefix + serverItem.getId(); |
| 416 | dynamicTask.stop(zlmKeepaliveKey); | 434 | dynamicTask.stop(zlmKeepaliveKey); |
| 417 | dynamicTask.startDelay(zlmKeepaliveKey, new KeepAliveTimeoutRunnable(serverItem), (Math.getExponent(serverItem.getHookAliveInterval()) + 5) * 1000); | 435 | dynamicTask.startDelay(zlmKeepaliveKey, new KeepAliveTimeoutRunnable(serverItem), (Math.getExponent(serverItem.getHookAliveInterval()) + 5) * 1000); |
| 418 | publisher.zlmOnlineEventPublish(serverItem.getId()); | 436 | publisher.zlmOnlineEventPublish(serverItem.getId()); |
| 437 | + | ||
| 419 | logger.info("[ZLM] 连接成功 {} - {}:{} ", | 438 | logger.info("[ZLM] 连接成功 {} - {}:{} ", |
| 420 | zlmServerConfig.getGeneralMediaServerId(), zlmServerConfig.getIp(), zlmServerConfig.getHttpPort()); | 439 | zlmServerConfig.getGeneralMediaServerId(), zlmServerConfig.getIp(), zlmServerConfig.getHttpPort()); |
| 421 | } | 440 | } |
| @@ -549,6 +568,9 @@ public class MediaServerServiceImpl implements IMediaServerService { | @@ -549,6 +568,9 @@ public class MediaServerServiceImpl implements IMediaServerService { | ||
| 549 | 568 | ||
| 550 | Map<String, Object> param = new HashMap<>(); | 569 | Map<String, Object> param = new HashMap<>(); |
| 551 | param.put("api.secret",mediaServerItem.getSecret()); // -profile:v Baseline | 570 | param.put("api.secret",mediaServerItem.getSecret()); // -profile:v Baseline |
| 571 | + if (mediaServerItem.getRtspPort() != 0) { | ||
| 572 | + param.put("ffmpeg.snap", "%s -rtsp_transport tcp -i %s -y -f mjpeg -t 0.001 %s"); | ||
| 573 | + } | ||
| 552 | param.put("hook.enable","1"); | 574 | param.put("hook.enable","1"); |
| 553 | param.put("hook.on_flow_report",""); | 575 | param.put("hook.on_flow_report",""); |
| 554 | param.put("hook.on_play",String.format("%s/on_play", hookPrex)); | 576 | param.put("hook.on_play",String.format("%s/on_play", hookPrex)); |
| @@ -583,6 +605,13 @@ public class MediaServerServiceImpl implements IMediaServerService { | @@ -583,6 +605,13 @@ public class MediaServerServiceImpl implements IMediaServerService { | ||
| 583 | param.put("rtp_proxy.port_range", mediaServerItem.getRtpPortRange().replace(",", "-")); | 605 | param.put("rtp_proxy.port_range", mediaServerItem.getRtpPortRange().replace(",", "-")); |
| 584 | } | 606 | } |
| 585 | 607 | ||
| 608 | + if (userSetting.getRecordPath() != null) { | ||
| 609 | + File recordPathFile = new File(userSetting.getRecordPath()); | ||
| 610 | + File mp4SavePathFile = recordPathFile.getParentFile().getAbsoluteFile(); | ||
| 611 | + param.put("protocol.mp4_save_path", mp4SavePathFile.getAbsoluteFile()); | ||
| 612 | + param.put("record.appName", recordPathFile.getName()); | ||
| 613 | + } | ||
| 614 | + | ||
| 586 | JSONObject responseJSON = zlmresTfulUtils.setServerConfig(mediaServerItem, param); | 615 | JSONObject responseJSON = zlmresTfulUtils.setServerConfig(mediaServerItem, param); |
| 587 | 616 | ||
| 588 | if (responseJSON != null && responseJSON.getInteger("code") == 0) { | 617 | if (responseJSON != null && responseJSON.getInteger("code") == 0) { |
src/main/java/com/genersoft/iot/vmp/service/impl/PlatformChannelServiceImpl.java
| 1 | package com.genersoft.iot.vmp.service.impl; | 1 | package com.genersoft.iot.vmp.service.impl; |
| 2 | 2 | ||
| 3 | -import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; | ||
| 4 | -import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; | ||
| 5 | -import com.genersoft.iot.vmp.gb28181.bean.PlatformCatalog; | ||
| 6 | -import com.genersoft.iot.vmp.gb28181.bean.TreeType; | 3 | +import com.genersoft.iot.vmp.gb28181.bean.*; |
| 7 | import com.genersoft.iot.vmp.gb28181.event.EventPublisher; | 4 | import com.genersoft.iot.vmp.gb28181.event.EventPublisher; |
| 8 | import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent; | 5 | import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent; |
| 9 | import com.genersoft.iot.vmp.service.IPlatformChannelService; | 6 | import com.genersoft.iot.vmp.service.IPlatformChannelService; |
| @@ -15,7 +12,10 @@ import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce; | @@ -15,7 +12,10 @@ import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce; | ||
| 15 | import org.slf4j.Logger; | 12 | import org.slf4j.Logger; |
| 16 | import org.slf4j.LoggerFactory; | 13 | import org.slf4j.LoggerFactory; |
| 17 | import org.springframework.beans.factory.annotation.Autowired; | 14 | import org.springframework.beans.factory.annotation.Autowired; |
| 15 | +import org.springframework.jdbc.datasource.DataSourceTransactionManager; | ||
| 18 | import org.springframework.stereotype.Service; | 16 | import org.springframework.stereotype.Service; |
| 17 | +import org.springframework.transaction.TransactionDefinition; | ||
| 18 | +import org.springframework.transaction.TransactionStatus; | ||
| 19 | import org.springframework.util.ObjectUtils; | 19 | import org.springframework.util.ObjectUtils; |
| 20 | 20 | ||
| 21 | import java.util.ArrayList; | 21 | import java.util.ArrayList; |
| @@ -35,6 +35,16 @@ public class PlatformChannelServiceImpl implements IPlatformChannelService { | @@ -35,6 +35,16 @@ public class PlatformChannelServiceImpl implements IPlatformChannelService { | ||
| 35 | private PlatformChannelMapper platformChannelMapper; | 35 | private PlatformChannelMapper platformChannelMapper; |
| 36 | 36 | ||
| 37 | @Autowired | 37 | @Autowired |
| 38 | + TransactionDefinition transactionDefinition; | ||
| 39 | + | ||
| 40 | + @Autowired | ||
| 41 | + DataSourceTransactionManager dataSourceTransactionManager; | ||
| 42 | + | ||
| 43 | + @Autowired | ||
| 44 | + private SubscribeHolder subscribeHolder; | ||
| 45 | + | ||
| 46 | + | ||
| 47 | + @Autowired | ||
| 38 | private DeviceChannelMapper deviceChannelMapper; | 48 | private DeviceChannelMapper deviceChannelMapper; |
| 39 | 49 | ||
| 40 | @Autowired | 50 | @Autowired |
| @@ -69,17 +79,47 @@ public class PlatformChannelServiceImpl implements IPlatformChannelService { | @@ -69,17 +79,47 @@ public class PlatformChannelServiceImpl implements IPlatformChannelService { | ||
| 69 | } | 79 | } |
| 70 | List<ChannelReduce> channelReducesToAdd = new ArrayList<>(deviceAndChannels.values()); | 80 | List<ChannelReduce> channelReducesToAdd = new ArrayList<>(deviceAndChannels.values()); |
| 71 | // 对剩下的数据进行存储 | 81 | // 对剩下的数据进行存储 |
| 72 | - int result = 0; | 82 | + int allCount = 0; |
| 83 | + boolean result = false; | ||
| 84 | + TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition); | ||
| 85 | + int limitCount = 300; | ||
| 73 | if (channelReducesToAdd.size() > 0) { | 86 | if (channelReducesToAdd.size() > 0) { |
| 74 | - result = platformChannelMapper.addChannels(platformId, channelReducesToAdd); | ||
| 75 | - // TODO 后续给平台增加控制开关以控制是否响应目录订阅 | ||
| 76 | - List<DeviceChannel> deviceChannelList = getDeviceChannelListByChannelReduceList(channelReducesToAdd, catalogId, platform); | ||
| 77 | - if (deviceChannelList != null) { | ||
| 78 | - eventPublisher.catalogEventPublish(platformId, deviceChannelList, CatalogEvent.ADD); | 87 | + if (channelReducesToAdd.size() > limitCount) { |
| 88 | + for (int i = 0; i < channelReducesToAdd.size(); i += limitCount) { | ||
| 89 | + int toIndex = i + limitCount; | ||
| 90 | + if (i + limitCount > channelReducesToAdd.size()) { | ||
| 91 | + toIndex = channelReducesToAdd.size(); | ||
| 92 | + } | ||
| 93 | + int count = platformChannelMapper.addChannels(platformId, channelReducesToAdd.subList(i, toIndex)); | ||
| 94 | + result = result || count < 0; | ||
| 95 | + allCount += count; | ||
| 96 | + logger.info("[关联通道]国标通道 平台:{}, 共需关联通道数:{}, 已关联:{}", platformId, channelReducesToAdd.size(), toIndex); | ||
| 97 | + } | ||
| 98 | + }else { | ||
| 99 | + allCount = platformChannelMapper.addChannels(platformId, channelReducesToAdd); | ||
| 100 | + result = result || allCount < 0; | ||
| 101 | + logger.info("[关联通道]国标通道 平台:{}, 关联通道数:{}", platformId, channelReducesToAdd.size()); | ||
| 79 | } | 102 | } |
| 80 | - } | ||
| 81 | 103 | ||
| 82 | - return result; | 104 | + if (result) { |
| 105 | + //事务回滚 | ||
| 106 | + dataSourceTransactionManager.rollback(transactionStatus); | ||
| 107 | + allCount = 0; | ||
| 108 | + }else { | ||
| 109 | + logger.info("[关联通道]国标通道 平台:{}, 正在存入数据库", platformId); | ||
| 110 | + dataSourceTransactionManager.commit(transactionStatus); | ||
| 111 | + | ||
| 112 | + } | ||
| 113 | + SubscribeInfo catalogSubscribe = subscribeHolder.getCatalogSubscribe(platformId); | ||
| 114 | + if (catalogSubscribe != null) { | ||
| 115 | + List<DeviceChannel> deviceChannelList = getDeviceChannelListByChannelReduceList(channelReducesToAdd, catalogId, platform); | ||
| 116 | + if (deviceChannelList != null) { | ||
| 117 | + eventPublisher.catalogEventPublish(platformId, deviceChannelList, CatalogEvent.ADD); | ||
| 118 | + } | ||
| 119 | + } | ||
| 120 | + logger.info("[关联通道]国标通道 平台:{}, 存入数据库成功", platformId); | ||
| 121 | + } | ||
| 122 | + return allCount; | ||
| 83 | } | 123 | } |
| 84 | 124 | ||
| 85 | private List<DeviceChannel> getDeviceChannelListByChannelReduceList(List<ChannelReduce> channelReduces, String catalogId, ParentPlatform platform) { | 125 | private List<DeviceChannel> getDeviceChannelListByChannelReduceList(List<ChannelReduce> channelReduces, String catalogId, ParentPlatform platform) { |
src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java
| @@ -21,8 +21,8 @@ import com.genersoft.iot.vmp.service.bean.GPSMsgInfo; | @@ -21,8 +21,8 @@ import com.genersoft.iot.vmp.service.bean.GPSMsgInfo; | ||
| 21 | import com.genersoft.iot.vmp.service.bean.InviteTimeOutCallback; | 21 | import com.genersoft.iot.vmp.service.bean.InviteTimeOutCallback; |
| 22 | import com.genersoft.iot.vmp.service.bean.SSRCInfo; | 22 | import com.genersoft.iot.vmp.service.bean.SSRCInfo; |
| 23 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; | 23 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| 24 | -import com.genersoft.iot.vmp.storager.dao.GbStreamMapper; | ||
| 25 | -import com.genersoft.iot.vmp.storager.dao.ParentPlatformMapper; | 24 | +import com.genersoft.iot.vmp.storager.dao.*; |
| 25 | +import com.genersoft.iot.vmp.utils.DateUtil; | ||
| 26 | import com.github.pagehelper.PageHelper; | 26 | import com.github.pagehelper.PageHelper; |
| 27 | import com.github.pagehelper.PageInfo; | 27 | import com.github.pagehelper.PageInfo; |
| 28 | import org.slf4j.Logger; | 28 | import org.slf4j.Logger; |
| @@ -54,6 +54,15 @@ public class PlatformServiceImpl implements IPlatformService { | @@ -54,6 +54,15 @@ public class PlatformServiceImpl implements IPlatformService { | ||
| 54 | private ParentPlatformMapper platformMapper; | 54 | private ParentPlatformMapper platformMapper; |
| 55 | 55 | ||
| 56 | @Autowired | 56 | @Autowired |
| 57 | + private PlatformCatalogMapper catalogMapper; | ||
| 58 | + | ||
| 59 | + @Autowired | ||
| 60 | + private PlatformChannelMapper platformChannelMapper; | ||
| 61 | + | ||
| 62 | + @Autowired | ||
| 63 | + private PlatformGbStreamMapper platformGbStreamMapper; | ||
| 64 | + | ||
| 65 | + @Autowired | ||
| 57 | private IRedisCatchStorage redisCatchStorage; | 66 | private IRedisCatchStorage redisCatchStorage; |
| 58 | 67 | ||
| 59 | @Autowired | 68 | @Autowired |
| @@ -135,36 +144,106 @@ public class PlatformServiceImpl implements IPlatformService { | @@ -135,36 +144,106 @@ public class PlatformServiceImpl implements IPlatformService { | ||
| 135 | } | 144 | } |
| 136 | 145 | ||
| 137 | @Override | 146 | @Override |
| 138 | - public void online(ParentPlatform parentPlatform) { | ||
| 139 | - logger.info("[国标级联]:{}, 平台上线/更新注册", parentPlatform.getServerGBId()); | 147 | + public boolean update(ParentPlatform parentPlatform) { |
| 148 | + logger.info("[国标级联]更新平台 {}", parentPlatform.getDeviceGBId()); | ||
| 149 | + parentPlatform.setCharacterSet(parentPlatform.getCharacterSet().toUpperCase()); | ||
| 150 | + ParentPlatform parentPlatformOld = platformMapper.getParentPlatById(parentPlatform.getId()); | ||
| 151 | + ParentPlatformCatch parentPlatformCatchOld = redisCatchStorage.queryPlatformCatchInfo(parentPlatformOld.getServerGBId()); | ||
| 152 | + parentPlatform.setUpdateTime(DateUtil.getNow()); | ||
| 153 | + if (!parentPlatformOld.getTreeType().equals(parentPlatform.getTreeType())) { | ||
| 154 | + // 目录结构发生变化,清空之前的关联关系 | ||
| 155 | + logger.info("保存平台{}时发现目录结构变化,清空关联关系", parentPlatform.getDeviceGBId()); | ||
| 156 | + catalogMapper.delByPlatformId(parentPlatformOld.getServerGBId()); | ||
| 157 | + platformChannelMapper.delByPlatformId(parentPlatformOld.getServerGBId()); | ||
| 158 | + platformGbStreamMapper.delByPlatformId(parentPlatformOld.getServerGBId()); | ||
| 159 | + } | ||
| 160 | + | ||
| 161 | + | ||
| 162 | + // 停止心跳定时 | ||
| 163 | + final String keepaliveTaskKey = KEEPALIVE_KEY_PREFIX + parentPlatformOld.getServerGBId(); | ||
| 164 | + dynamicTask.stop(keepaliveTaskKey); | ||
| 165 | + // 停止注册定时 | ||
| 166 | + final String registerTaskKey = REGISTER_KEY_PREFIX + parentPlatformOld.getServerGBId(); | ||
| 167 | + dynamicTask.stop(registerTaskKey); | ||
| 168 | + // 注销旧的 | ||
| 169 | + try { | ||
| 170 | + if (parentPlatformOld.isStatus()) { | ||
| 171 | + logger.info("保存平台{}时发现救平台在线,发送注销命令", parentPlatform.getDeviceGBId()); | ||
| 172 | + commanderForPlatform.unregister(parentPlatformOld, parentPlatformCatchOld.getSipTransactionInfo(), null, eventResult -> { | ||
| 173 | + logger.info("[国标级联] 注销成功, 平台:{}", parentPlatformOld.getServerGBId()); | ||
| 174 | + }); | ||
| 175 | + } | ||
| 176 | + | ||
| 177 | + } catch (InvalidArgumentException | ParseException | SipException e) { | ||
| 178 | + logger.error("[命令发送失败] 国标级联 注销: {}", e.getMessage()); | ||
| 179 | + } | ||
| 180 | + | ||
| 181 | + // 更新数据库 | ||
| 182 | + if (parentPlatform.getCatalogGroup() == 0) { | ||
| 183 | + parentPlatform.setCatalogGroup(1); | ||
| 184 | + } | ||
| 185 | + if (parentPlatform.getAdministrativeDivision() == null) { | ||
| 186 | + parentPlatform.setAdministrativeDivision(parentPlatform.getAdministrativeDivision()); | ||
| 187 | + } | ||
| 188 | + | ||
| 189 | + platformMapper.updateParentPlatform(parentPlatform); | ||
| 190 | + // 更新redis | ||
| 191 | + redisCatchStorage.delPlatformCatchInfo(parentPlatformOld.getServerGBId()); | ||
| 192 | + ParentPlatformCatch parentPlatformCatch = new ParentPlatformCatch(); | ||
| 193 | + parentPlatformCatch.setParentPlatform(parentPlatform); | ||
| 194 | + parentPlatformCatch.setId(parentPlatform.getServerGBId()); | ||
| 195 | + redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch); | ||
| 196 | + // 注册 | ||
| 197 | + if (parentPlatform.isEnable()) { | ||
| 198 | + // 保存时启用就发送注册 | ||
| 199 | + // 注册成功时由程序直接调用了online方法 | ||
| 200 | + try { | ||
| 201 | + commanderForPlatform.register(parentPlatform, eventResult -> { | ||
| 202 | + logger.info("[国标级联] {},添加向上级注册失败,请确定上级平台可用时重新保存", parentPlatform.getServerGBId()); | ||
| 203 | + }, null); | ||
| 204 | + } catch (InvalidArgumentException | ParseException | SipException e) { | ||
| 205 | + logger.error("[命令发送失败] 国标级联: {}", e.getMessage()); | ||
| 206 | + } | ||
| 207 | + } | ||
| 208 | + // 重新开启定时注册, 使用续订消息 | ||
| 209 | + // 重新开始心跳保活 | ||
| 210 | + | ||
| 211 | + | ||
| 212 | + return false; | ||
| 213 | + } | ||
| 214 | + | ||
| 215 | + | ||
| 216 | + @Override | ||
| 217 | + public void online(ParentPlatform parentPlatform, SipTransactionInfo sipTransactionInfo) { | ||
| 218 | + logger.info("[国标级联]:{}, 平台上线", parentPlatform.getServerGBId()); | ||
| 140 | platformMapper.updateParentPlatformStatus(parentPlatform.getServerGBId(), true); | 219 | platformMapper.updateParentPlatformStatus(parentPlatform.getServerGBId(), true); |
| 141 | ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(parentPlatform.getServerGBId()); | 220 | ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(parentPlatform.getServerGBId()); |
| 142 | - if (parentPlatformCatch != null) { | ||
| 143 | - parentPlatformCatch.getParentPlatform().setStatus(true); | ||
| 144 | - redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch); | ||
| 145 | - }else { | 221 | + if (parentPlatformCatch == null) { |
| 146 | parentPlatformCatch = new ParentPlatformCatch(); | 222 | parentPlatformCatch = new ParentPlatformCatch(); |
| 147 | parentPlatformCatch.setParentPlatform(parentPlatform); | 223 | parentPlatformCatch.setParentPlatform(parentPlatform); |
| 148 | parentPlatformCatch.setId(parentPlatform.getServerGBId()); | 224 | parentPlatformCatch.setId(parentPlatform.getServerGBId()); |
| 149 | parentPlatform.setStatus(true); | 225 | parentPlatform.setStatus(true); |
| 150 | parentPlatformCatch.setParentPlatform(parentPlatform); | 226 | parentPlatformCatch.setParentPlatform(parentPlatform); |
| 151 | - redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch); | ||
| 152 | } | 227 | } |
| 153 | 228 | ||
| 229 | + parentPlatformCatch.getParentPlatform().setStatus(true); | ||
| 230 | + parentPlatformCatch.setSipTransactionInfo(sipTransactionInfo); | ||
| 231 | + redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch); | ||
| 232 | + | ||
| 154 | final String registerTaskKey = REGISTER_KEY_PREFIX + parentPlatform.getServerGBId(); | 233 | final String registerTaskKey = REGISTER_KEY_PREFIX + parentPlatform.getServerGBId(); |
| 155 | if (!dynamicTask.isAlive(registerTaskKey)) { | 234 | if (!dynamicTask.isAlive(registerTaskKey)) { |
| 235 | + logger.info("[国标级联]:{}, 添加定时注册任务", parentPlatform.getServerGBId()); | ||
| 156 | // 添加注册任务 | 236 | // 添加注册任务 |
| 157 | dynamicTask.startCron(registerTaskKey, | 237 | dynamicTask.startCron(registerTaskKey, |
| 158 | // 注册失败(注册成功时由程序直接调用了online方法) | 238 | // 注册失败(注册成功时由程序直接调用了online方法) |
| 159 | - ()-> { | ||
| 160 | - registerTask(parentPlatform); | ||
| 161 | - }, | ||
| 162 | - (parentPlatform.getExpires() - 10) *1000); | 239 | + ()-> registerTask(parentPlatform, sipTransactionInfo), |
| 240 | + parentPlatform.getExpires() * 1000); | ||
| 163 | } | 241 | } |
| 164 | 242 | ||
| 165 | 243 | ||
| 166 | final String keepaliveTaskKey = KEEPALIVE_KEY_PREFIX + parentPlatform.getServerGBId(); | 244 | final String keepaliveTaskKey = KEEPALIVE_KEY_PREFIX + parentPlatform.getServerGBId(); |
| 167 | if (!dynamicTask.contains(keepaliveTaskKey)) { | 245 | if (!dynamicTask.contains(keepaliveTaskKey)) { |
| 246 | + logger.info("[国标级联]:{}, 添加定时心跳任务", parentPlatform.getServerGBId()); | ||
| 168 | // 添加心跳任务 | 247 | // 添加心跳任务 |
| 169 | dynamicTask.startCron(keepaliveTaskKey, | 248 | dynamicTask.startCron(keepaliveTaskKey, |
| 170 | ()-> { | 249 | ()-> { |
| @@ -205,11 +284,11 @@ public class PlatformServiceImpl implements IPlatformService { | @@ -205,11 +284,11 @@ public class PlatformServiceImpl implements IPlatformService { | ||
| 205 | logger.error("[命令发送失败] 国标级联 发送心跳: {}", e.getMessage()); | 284 | logger.error("[命令发送失败] 国标级联 发送心跳: {}", e.getMessage()); |
| 206 | } | 285 | } |
| 207 | }, | 286 | }, |
| 208 | - (parentPlatform.getKeepTimeout() - 10)*1000); | 287 | + (parentPlatform.getKeepTimeout())*1000); |
| 209 | } | 288 | } |
| 210 | } | 289 | } |
| 211 | 290 | ||
| 212 | - private void registerTask(ParentPlatform parentPlatform){ | 291 | + private void registerTask(ParentPlatform parentPlatform, SipTransactionInfo sipTransactionInfo){ |
| 213 | try { | 292 | try { |
| 214 | // 设置超时重发, 后续从底层支持消息重发 | 293 | // 设置超时重发, 后续从底层支持消息重发 |
| 215 | String key = KEEPALIVE_KEY_PREFIX + parentPlatform.getServerGBId() + "_timeout"; | 294 | String key = KEEPALIVE_KEY_PREFIX + parentPlatform.getServerGBId() + "_timeout"; |
| @@ -217,10 +296,10 @@ public class PlatformServiceImpl implements IPlatformService { | @@ -217,10 +296,10 @@ public class PlatformServiceImpl implements IPlatformService { | ||
| 217 | return; | 296 | return; |
| 218 | } | 297 | } |
| 219 | dynamicTask.startDelay(key, ()->{ | 298 | dynamicTask.startDelay(key, ()->{ |
| 220 | - registerTask(parentPlatform); | 299 | + registerTask(parentPlatform, sipTransactionInfo); |
| 221 | }, 1000); | 300 | }, 1000); |
| 222 | - logger.info("[国标级联] 平台:{}注册即将到期,重新注册", parentPlatform.getServerGBId()); | ||
| 223 | - commanderForPlatform.register(parentPlatform, eventResult -> { | 301 | + logger.info("[国标级联] 平台:{}注册即将到期,开始续订", parentPlatform.getServerGBId()); |
| 302 | + commanderForPlatform.register(parentPlatform, sipTransactionInfo, eventResult -> { | ||
| 224 | dynamicTask.stop(key); | 303 | dynamicTask.stop(key); |
| 225 | offline(parentPlatform, false); | 304 | offline(parentPlatform, false); |
| 226 | },eventResult -> { | 305 | },eventResult -> { |
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
| @@ -438,7 +438,12 @@ public class PlayServiceImpl implements IPlayService { | @@ -438,7 +438,12 @@ public class PlayServiceImpl implements IPlayService { | ||
| 438 | onPublishHandlerForPlay(mediaServerItemInuse, response, device.getDeviceId(), channelId); | 438 | onPublishHandlerForPlay(mediaServerItemInuse, response, device.getDeviceId(), channelId); |
| 439 | hookEvent.response(mediaServerItemInuse, response); | 439 | hookEvent.response(mediaServerItemInuse, response); |
| 440 | logger.info("[点播成功] deviceId: {}, channelId: {}", device.getDeviceId(), channelId); | 440 | logger.info("[点播成功] deviceId: {}, channelId: {}", device.getDeviceId(), channelId); |
| 441 | - String streamUrl = String.format("http://127.0.0.1:%s/%s/%s.live.flv", mediaServerItemInuse.getHttpPort(), "rtp", ssrcInfo.getStream()); | 441 | + String streamUrl; |
| 442 | + if (mediaServerItemInuse.getRtspPort() != 0) { | ||
| 443 | + streamUrl = String.format("rtsp://127.0.0.1:%s/%s/%s", mediaServerItemInuse.getRtspPort(), "rtp", ssrcInfo.getStream()); | ||
| 444 | + }else { | ||
| 445 | + streamUrl = String.format("http://127.0.0.1:%s/%s/%s.live.mp4", mediaServerItemInuse.getHttpPort(), "rtp", ssrcInfo.getStream()); | ||
| 446 | + } | ||
| 442 | String path = "snap"; | 447 | String path = "snap"; |
| 443 | String fileName = device.getDeviceId() + "_" + channelId + ".jpg"; | 448 | String fileName = device.getDeviceId() + "_" + channelId + ".jpg"; |
| 444 | // 请求截图 | 449 | // 请求截图 |
| @@ -806,23 +811,75 @@ public class PlayServiceImpl implements IPlayService { | @@ -806,23 +811,75 @@ public class PlayServiceImpl implements IPlayService { | ||
| 806 | hookCallBack.call(downloadResult); | 811 | hookCallBack.call(downloadResult); |
| 807 | streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream()); | 812 | streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream()); |
| 808 | }; | 813 | }; |
| 809 | - | 814 | + InviteStreamCallback hookEvent = (InviteStreamInfo inviteStreamInfo) -> { |
| 815 | + logger.info("收到订阅消息: " + inviteStreamInfo.getCallId()); | ||
| 816 | + dynamicTask.stop(downLoadTimeOutTaskKey); | ||
| 817 | + StreamInfo streamInfo = onPublishHandler(inviteStreamInfo.getMediaServerItem(), inviteStreamInfo.getResponse(), deviceId, channelId); | ||
| 818 | + streamInfo.setStartTime(startTime); | ||
| 819 | + streamInfo.setEndTime(endTime); | ||
| 820 | + redisCatchStorage.startDownload(streamInfo, inviteStreamInfo.getCallId()); | ||
| 821 | + downloadResult.setCode(ErrorCode.SUCCESS.getCode()); | ||
| 822 | + downloadResult.setMsg(ErrorCode.SUCCESS.getMsg()); | ||
| 823 | + downloadResult.setData(streamInfo); | ||
| 824 | + downloadResult.setMediaServerItem(inviteStreamInfo.getMediaServerItem()); | ||
| 825 | + downloadResult.setResponse(inviteStreamInfo.getResponse()); | ||
| 826 | + hookCallBack.call(downloadResult); | ||
| 827 | + }; | ||
| 810 | try { | 828 | try { |
| 811 | cmder.downloadStreamCmd(mediaServerItem, ssrcInfo, device, channelId, startTime, endTime, downloadSpeed, infoCallBack, | 829 | cmder.downloadStreamCmd(mediaServerItem, ssrcInfo, device, channelId, startTime, endTime, downloadSpeed, infoCallBack, |
| 812 | - inviteStreamInfo -> { | ||
| 813 | - logger.info("收到订阅消息: " + inviteStreamInfo.getResponse().toJSONString()); | ||
| 814 | - dynamicTask.stop(downLoadTimeOutTaskKey); | ||
| 815 | - StreamInfo streamInfo = onPublishHandler(inviteStreamInfo.getMediaServerItem(), inviteStreamInfo.getResponse(), deviceId, channelId); | ||
| 816 | - streamInfo.setStartTime(startTime); | ||
| 817 | - streamInfo.setEndTime(endTime); | ||
| 818 | - redisCatchStorage.startDownload(streamInfo, inviteStreamInfo.getCallId()); | ||
| 819 | - downloadResult.setCode(ErrorCode.SUCCESS.getCode()); | ||
| 820 | - downloadResult.setMsg(ErrorCode.SUCCESS.getMsg()); | ||
| 821 | - downloadResult.setData(streamInfo); | ||
| 822 | - downloadResult.setMediaServerItem(inviteStreamInfo.getMediaServerItem()); | ||
| 823 | - downloadResult.setResponse(inviteStreamInfo.getResponse()); | ||
| 824 | - hookCallBack.call(downloadResult); | ||
| 825 | - }, errorEvent); | 830 | + hookEvent, errorEvent, eventResult -> |
| 831 | + { | ||
| 832 | + if (eventResult.type == SipSubscribe.EventResultType.response) { | ||
| 833 | + ResponseEvent responseEvent = (ResponseEvent) eventResult.event; | ||
| 834 | + String contentString = new String(responseEvent.getResponse().getRawContent()); | ||
| 835 | + // 获取ssrc | ||
| 836 | + int ssrcIndex = contentString.indexOf("y="); | ||
| 837 | + // 检查是否有y字段 | ||
| 838 | + if (ssrcIndex >= 0) { | ||
| 839 | + //ssrc规定长度为10字节,不取余下长度以避免后续还有“f=”字段 TODO 后续对不规范的非10位ssrc兼容 | ||
| 840 | + String ssrcInResponse = contentString.substring(ssrcIndex + 2, ssrcIndex + 12); | ||
| 841 | + // 查询到ssrc不一致且开启了ssrc校验则需要针对处理 | ||
| 842 | + if (ssrcInfo.getSsrc().equals(ssrcInResponse)) { | ||
| 843 | + return; | ||
| 844 | + } | ||
| 845 | + logger.info("[回放消息] 收到invite 200, 发现下级自定义了ssrc: {}", ssrcInResponse); | ||
| 846 | + if (!mediaServerItem.isRtpEnable() || device.isSsrcCheck()) { | ||
| 847 | + logger.info("[回放消息] SSRC修正 {}->{}", ssrcInfo.getSsrc(), ssrcInResponse); | ||
| 848 | + | ||
| 849 | + if (!mediaServerItem.getSsrcConfig().checkSsrc(ssrcInResponse)) { | ||
| 850 | + // ssrc 不可用 | ||
| 851 | + // 释放ssrc | ||
| 852 | + mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); | ||
| 853 | + streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream()); | ||
| 854 | + eventResult.msg = "下级自定义了ssrc,但是此ssrc不可用"; | ||
| 855 | + eventResult.statusCode = 400; | ||
| 856 | + errorEvent.response(eventResult); | ||
| 857 | + return; | ||
| 858 | + } | ||
| 859 | + | ||
| 860 | + // 单端口模式streamId也有变化,需要重新设置监听 | ||
| 861 | + if (!mediaServerItem.isRtpEnable()) { | ||
| 862 | + // 添加订阅 | ||
| 863 | + HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", ssrcInfo.getStream(), true, "rtsp", mediaServerItem.getId()); | ||
| 864 | + subscribe.removeSubscribe(hookSubscribe); | ||
| 865 | + hookSubscribe.getContent().put("stream", String.format("%08x", Integer.parseInt(ssrcInResponse)).toUpperCase()); | ||
| 866 | + subscribe.addSubscribe(hookSubscribe, (MediaServerItem mediaServerItemInUse, JSONObject response) -> { | ||
| 867 | + logger.info("[ZLM HOOK] ssrc修正后收到订阅消息: " + response.toJSONString()); | ||
| 868 | + dynamicTask.stop(downLoadTimeOutTaskKey); | ||
| 869 | + // hook响应 | ||
| 870 | + onPublishHandlerForPlayback(mediaServerItemInUse, response, device.getDeviceId(), channelId, hookCallBack); | ||
| 871 | + hookEvent.call(new InviteStreamInfo(mediaServerItem, null, eventResult.callId, "rtp", ssrcInfo.getStream())); | ||
| 872 | + }); | ||
| 873 | + } | ||
| 874 | + // 关闭rtp server | ||
| 875 | + mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream()); | ||
| 876 | + // 重新开启ssrc server | ||
| 877 | + mediaServerService.openRTPServer(mediaServerItem, ssrcInfo.getStream(), ssrcInResponse, device.isSsrcCheck(), true, ssrcInfo.getPort()); | ||
| 878 | + } | ||
| 879 | + } | ||
| 880 | + } | ||
| 881 | + | ||
| 882 | + }); | ||
| 826 | } catch (InvalidArgumentException | SipException | ParseException e) { | 883 | } catch (InvalidArgumentException | SipException | ParseException e) { |
| 827 | logger.error("[命令发送失败] 录像下载: {}", e.getMessage()); | 884 | logger.error("[命令发送失败] 录像下载: {}", e.getMessage()); |
| 828 | 885 |
src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java
| @@ -201,7 +201,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService { | @@ -201,7 +201,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService { | ||
| 201 | dataSourceTransactionManager.commit(transactionStatus); //手动提交 | 201 | dataSourceTransactionManager.commit(transactionStatus); //手动提交 |
| 202 | result = true; | 202 | result = true; |
| 203 | }catch (Exception e) { | 203 | }catch (Exception e) { |
| 204 | - e.printStackTrace(); | 204 | + logger.error("未处理的异常 ", e); |
| 205 | dataSourceTransactionManager.rollback(transactionStatus); | 205 | dataSourceTransactionManager.rollback(transactionStatus); |
| 206 | } | 206 | } |
| 207 | return result; | 207 | return result; |
src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisAlarmMsgListener.java
| 1 | package com.genersoft.iot.vmp.service.redisMsg; | 1 | package com.genersoft.iot.vmp.service.redisMsg; |
| 2 | 2 | ||
| 3 | import com.alibaba.fastjson2.JSON; | 3 | import com.alibaba.fastjson2.JSON; |
| 4 | +import com.genersoft.iot.vmp.conf.UserSetting; | ||
| 4 | import com.genersoft.iot.vmp.gb28181.bean.*; | 5 | import com.genersoft.iot.vmp.gb28181.bean.*; |
| 5 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; | 6 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; |
| 6 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; | 7 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; |
| @@ -44,13 +45,17 @@ public class RedisAlarmMsgListener implements MessageListener { | @@ -44,13 +45,17 @@ public class RedisAlarmMsgListener implements MessageListener { | ||
| 44 | @Autowired | 45 | @Autowired |
| 45 | private ThreadPoolTaskExecutor taskExecutor; | 46 | private ThreadPoolTaskExecutor taskExecutor; |
| 46 | 47 | ||
| 48 | + @Autowired | ||
| 49 | + private UserSetting userSetting; | ||
| 50 | + | ||
| 47 | @Override | 51 | @Override |
| 48 | public void onMessage(@NotNull Message message, byte[] bytes) { | 52 | public void onMessage(@NotNull Message message, byte[] bytes) { |
| 53 | + // 消息示例: PUBLISH alarm_receive '{ "gbId": "", "alarmSn": 1, "alarmType": "111", "alarmDescription": "222", }' | ||
| 49 | logger.info("收到来自REDIS的ALARM通知: {}", new String(message.getBody())); | 54 | logger.info("收到来自REDIS的ALARM通知: {}", new String(message.getBody())); |
| 50 | boolean isEmpty = taskQueue.isEmpty(); | 55 | boolean isEmpty = taskQueue.isEmpty(); |
| 51 | taskQueue.offer(message); | 56 | taskQueue.offer(message); |
| 52 | if (isEmpty) { | 57 | if (isEmpty) { |
| 53 | - logger.info("[线程池信息]活动线程数:{}, 最大线程数: {}", taskExecutor.getActiveCount(), taskExecutor.getMaxPoolSize()); | 58 | +// logger.info("[线程池信息]活动线程数:{}, 最大线程数: {}", taskExecutor.getActiveCount(), taskExecutor.getMaxPoolSize()); |
| 54 | taskExecutor.execute(() -> { | 59 | taskExecutor.execute(() -> { |
| 55 | while (!taskQueue.isEmpty()) { | 60 | while (!taskQueue.isEmpty()) { |
| 56 | Message msg = taskQueue.poll(); | 61 | Message msg = taskQueue.poll(); |
| @@ -69,22 +74,52 @@ public class RedisAlarmMsgListener implements MessageListener { | @@ -69,22 +74,52 @@ public class RedisAlarmMsgListener implements MessageListener { | ||
| 69 | deviceAlarm.setAlarmMethod("" + alarmChannelMessage.getAlarmSn()); | 74 | deviceAlarm.setAlarmMethod("" + alarmChannelMessage.getAlarmSn()); |
| 70 | deviceAlarm.setAlarmType("" + alarmChannelMessage.getAlarmType()); | 75 | deviceAlarm.setAlarmType("" + alarmChannelMessage.getAlarmType()); |
| 71 | deviceAlarm.setAlarmPriority("1"); | 76 | deviceAlarm.setAlarmPriority("1"); |
| 72 | - deviceAlarm.setAlarmTime(DateUtil.getNowForISO8601()); | 77 | + deviceAlarm.setAlarmTime(DateUtil.getNow()); |
| 73 | deviceAlarm.setLongitude(0); | 78 | deviceAlarm.setLongitude(0); |
| 74 | deviceAlarm.setLatitude(0); | 79 | deviceAlarm.setLatitude(0); |
| 75 | 80 | ||
| 76 | if (ObjectUtils.isEmpty(gbId)) { | 81 | if (ObjectUtils.isEmpty(gbId)) { |
| 77 | - // 发送给所有的上级 | ||
| 78 | - List<ParentPlatform> parentPlatforms = storage.queryEnableParentPlatformList(true); | ||
| 79 | - if (parentPlatforms.size() > 0) { | ||
| 80 | - for (ParentPlatform parentPlatform : parentPlatforms) { | 82 | + if (userSetting.getSendToPlatformsWhenIdLost()) { |
| 83 | + // 发送给所有的上级 | ||
| 84 | + List<ParentPlatform> parentPlatforms = storage.queryEnableParentPlatformList(true); | ||
| 85 | + if (parentPlatforms.size() > 0) { | ||
| 86 | + for (ParentPlatform parentPlatform : parentPlatforms) { | ||
| 87 | + try { | ||
| 88 | + deviceAlarm.setChannelId(parentPlatform.getDeviceGBId()); | ||
| 89 | + commanderForPlatform.sendAlarmMessage(parentPlatform, deviceAlarm); | ||
| 90 | + } catch (SipException | InvalidArgumentException | ParseException e) { | ||
| 91 | + logger.error("[命令发送失败] 国标级联 发送报警: {}", e.getMessage()); | ||
| 92 | + } | ||
| 93 | + } | ||
| 94 | + } | ||
| 95 | + }else { | ||
| 96 | + // 获取开启了消息推送的设备和平台 | ||
| 97 | + List<ParentPlatform> parentPlatforms = storage.queryEnablePlatformListWithAsMessageChannel(); | ||
| 98 | + if (parentPlatforms.size() > 0) { | ||
| 99 | + for (ParentPlatform parentPlatform : parentPlatforms) { | ||
| 100 | + try { | ||
| 101 | + deviceAlarm.setChannelId(parentPlatform.getDeviceGBId()); | ||
| 102 | + commanderForPlatform.sendAlarmMessage(parentPlatform, deviceAlarm); | ||
| 103 | + } catch (SipException | InvalidArgumentException | ParseException e) { | ||
| 104 | + logger.error("[命令发送失败] 国标级联 发送报警: {}", e.getMessage()); | ||
| 105 | + } | ||
| 106 | + } | ||
| 107 | + } | ||
| 108 | + | ||
| 109 | + } | ||
| 110 | + // 获取开启了消息推送的设备和平台 | ||
| 111 | + List<Device> devices = storage.queryDeviceWithAsMessageChannel(); | ||
| 112 | + if (devices.size() > 0) { | ||
| 113 | + for (Device device : devices) { | ||
| 81 | try { | 114 | try { |
| 82 | - commanderForPlatform.sendAlarmMessage(parentPlatform, deviceAlarm); | ||
| 83 | - } catch (SipException | InvalidArgumentException | ParseException e) { | ||
| 84 | - logger.error("[命令发送失败] 国标级联 发送报警: {}", e.getMessage()); | 115 | + deviceAlarm.setChannelId(device.getDeviceId()); |
| 116 | + commander.sendAlarmMessage(device, deviceAlarm); | ||
| 117 | + } catch (InvalidArgumentException | SipException | ParseException e) { | ||
| 118 | + logger.error("[命令发送失败] 发送报警: {}", e.getMessage()); | ||
| 85 | } | 119 | } |
| 86 | } | 120 | } |
| 87 | } | 121 | } |
| 122 | + | ||
| 88 | }else { | 123 | }else { |
| 89 | Device device = storage.queryVideoDevice(gbId); | 124 | Device device = storage.queryVideoDevice(gbId); |
| 90 | ParentPlatform platform = storage.queryParentPlatByServerGBId(gbId); | 125 | ParentPlatform platform = storage.queryParentPlatByServerGBId(gbId); |
| @@ -105,6 +140,7 @@ public class RedisAlarmMsgListener implements MessageListener { | @@ -105,6 +140,7 @@ public class RedisAlarmMsgListener implements MessageListener { | ||
| 105 | } | 140 | } |
| 106 | } | 141 | } |
| 107 | }catch (Exception e) { | 142 | }catch (Exception e) { |
| 143 | + logger.error("未处理的异常 ", e); | ||
| 108 | logger.warn("[REDIS的ALARM通知] 发现未处理的异常, {}",e.getMessage()); | 144 | logger.warn("[REDIS的ALARM通知] 发现未处理的异常, {}",e.getMessage()); |
| 109 | } | 145 | } |
| 110 | } | 146 | } |
src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java
| @@ -202,7 +202,8 @@ public class RedisGbPlayMsgListener implements MessageListener { | @@ -202,7 +202,8 @@ public class RedisGbPlayMsgListener implements MessageListener { | ||
| 202 | 202 | ||
| 203 | } | 203 | } |
| 204 | }catch (Exception e) { | 204 | }catch (Exception e) { |
| 205 | - logger.warn("[RedisGbPlayMsg] 发现未处理的异常, {}",e.getMessage()); | 205 | + logger.warn("[RedisGbPlayMsg] 发现未处理的异常, \r\n{}", JSON.toJSONString(message)); |
| 206 | + logger.error("[RedisGbPlayMsg] 异常内容: ", e); | ||
| 206 | } | 207 | } |
| 207 | } | 208 | } |
| 208 | }); | 209 | }); |
src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGpsMsgListener.java
| @@ -53,7 +53,8 @@ public class RedisGpsMsgListener implements MessageListener { | @@ -53,7 +53,8 @@ public class RedisGpsMsgListener implements MessageListener { | ||
| 53 | // 只是放入redis缓存起来 | 53 | // 只是放入redis缓存起来 |
| 54 | redisCatchStorage.updateGpsMsgInfo(gpsMsgInfo); | 54 | redisCatchStorage.updateGpsMsgInfo(gpsMsgInfo); |
| 55 | }catch (Exception e) { | 55 | }catch (Exception e) { |
| 56 | - logger.warn("[REDIS的ALARM通知] 发现未处理的异常, {}",e.getMessage()); | 56 | + logger.warn("[REDIS的ALARM通知] 发现未处理的异常, \r\n{}", JSON.toJSONString(message)); |
| 57 | + logger.error("[REDIS的ALARM通知] 异常内容: ", e); | ||
| 57 | } | 58 | } |
| 58 | } | 59 | } |
| 59 | }); | 60 | }); |
src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamResponseListener.java
| @@ -58,7 +58,8 @@ public class RedisPushStreamResponseListener implements MessageListener { | @@ -58,7 +58,8 @@ public class RedisPushStreamResponseListener implements MessageListener { | ||
| 58 | responseEvents.get(response.getApp() + response.getStream()).run(response); | 58 | responseEvents.get(response.getApp() + response.getStream()).run(response); |
| 59 | } | 59 | } |
| 60 | }catch (Exception e) { | 60 | }catch (Exception e) { |
| 61 | - logger.warn("[REDIS的ALARM通知] 发现未处理的异常, {}",e.getMessage()); | 61 | + logger.warn("[REDIS消息-请求推流结果] 发现未处理的异常, \r\n{}", JSON.toJSONString(message)); |
| 62 | + logger.error("[REDIS消息-请求推流结果] 异常内容: ", e); | ||
| 62 | } | 63 | } |
| 63 | } | 64 | } |
| 64 | }); | 65 | }); |
src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamStatusListMsgListener.java
| @@ -95,7 +95,8 @@ public class RedisPushStreamStatusListMsgListener implements MessageListener { | @@ -95,7 +95,8 @@ public class RedisPushStreamStatusListMsgListener implements MessageListener { | ||
| 95 | gbStreamService.updateGbIdOrName(streamPushItemForUpdate); | 95 | gbStreamService.updateGbIdOrName(streamPushItemForUpdate); |
| 96 | } | 96 | } |
| 97 | }catch (Exception e) { | 97 | }catch (Exception e) { |
| 98 | - logger.warn("[REDIS的ALARM通知] 发现未处理的异常, {}",e.getMessage()); | 98 | + logger.warn("[REDIS消息-推流设备列表更新] 发现未处理的异常, \r\n{}", JSON.toJSONString(message)); |
| 99 | + logger.error("[REDIS消息-推流设备列表更新] 异常内容: ", e); | ||
| 99 | } | 100 | } |
| 100 | } | 101 | } |
| 101 | }); | 102 | }); |
src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamStatusMsgListener.java
| @@ -79,7 +79,8 @@ public class RedisPushStreamStatusMsgListener implements MessageListener, Applic | @@ -79,7 +79,8 @@ public class RedisPushStreamStatusMsgListener implements MessageListener, Applic | ||
| 79 | streamPushService.online(statusChangeFromPushStream.getOnlineStreams()); | 79 | streamPushService.online(statusChangeFromPushStream.getOnlineStreams()); |
| 80 | } | 80 | } |
| 81 | }catch (Exception e) { | 81 | }catch (Exception e) { |
| 82 | - logger.warn("[REDIS的ALARM通知] 发现未处理的异常, {}",e.getMessage()); | 82 | + logger.warn("[REDIS消息-推流设备状态变化] 发现未处理的异常, \r\n{}", JSON.toJSONString(message)); |
| 83 | + logger.error("[REDIS消息-推流设备状态变化] 异常内容: ", e); | ||
| 83 | } | 84 | } |
| 84 | } | 85 | } |
| 85 | }); | 86 | }); |
src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisStreamMsgListener.java
| @@ -82,7 +82,8 @@ public class RedisStreamMsgListener implements MessageListener { | @@ -82,7 +82,8 @@ public class RedisStreamMsgListener implements MessageListener { | ||
| 82 | zlmMediaListManager.removeMedia(app, stream); | 82 | zlmMediaListManager.removeMedia(app, stream); |
| 83 | } | 83 | } |
| 84 | }catch (Exception e) { | 84 | }catch (Exception e) { |
| 85 | - logger.warn("[REDIS的ALARM通知] 发现未处理的异常, {}",e.getMessage()); | 85 | + logger.warn("[REDIS消息-流变化] 发现未处理的异常, \r\n{}", JSON.toJSONString(message)); |
| 86 | + logger.error("[REDIS消息-流变化] 异常内容: ", e); | ||
| 86 | } | 87 | } |
| 87 | } | 88 | } |
| 88 | }); | 89 | }); |
src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorage.java
| @@ -5,6 +5,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; | @@ -5,6 +5,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; | ||
| 5 | import com.genersoft.iot.vmp.service.bean.GPSMsgInfo; | 5 | import com.genersoft.iot.vmp.service.bean.GPSMsgInfo; |
| 6 | import com.genersoft.iot.vmp.storager.dao.dto.ChannelSourceInfo; | 6 | import com.genersoft.iot.vmp.storager.dao.dto.ChannelSourceInfo; |
| 7 | import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce; | 7 | import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce; |
| 8 | +import com.genersoft.iot.vmp.web.gb28181.dto.DeviceChannelExtend; | ||
| 8 | import com.github.pagehelper.PageInfo; | 9 | import com.github.pagehelper.PageInfo; |
| 9 | 10 | ||
| 10 | import java.util.List; | 11 | import java.util.List; |
| @@ -58,7 +59,7 @@ public interface IVideoManagerStorage { | @@ -58,7 +59,7 @@ public interface IVideoManagerStorage { | ||
| 58 | */ | 59 | */ |
| 59 | public PageInfo<DeviceChannel> queryChannelsByDeviceId(String deviceId, String query, Boolean hasSubChannel, Boolean online, Boolean catalogUnderDevice, int page, int count); | 60 | public PageInfo<DeviceChannel> queryChannelsByDeviceId(String deviceId, String query, Boolean hasSubChannel, Boolean online, Boolean catalogUnderDevice, int page, int count); |
| 60 | 61 | ||
| 61 | - public List<DeviceChannel> queryChannelsByDeviceIdWithStartAndLimit(String deviceId, String query, Boolean hasSubChannel, Boolean online, int start, int limit,List<String> channelIds); | 62 | + public List<DeviceChannelExtend> queryChannelsByDeviceIdWithStartAndLimit(String deviceId, List<String> channelIds, String query, Boolean hasSubChannel, Boolean online, int start, int limit); |
| 62 | 63 | ||
| 63 | 64 | ||
| 64 | /** | 65 | /** |
| @@ -374,4 +375,10 @@ public interface IVideoManagerStorage { | @@ -374,4 +375,10 @@ public interface IVideoManagerStorage { | ||
| 374 | void cleanContentForPlatform(String serverGBId); | 375 | void cleanContentForPlatform(String serverGBId); |
| 375 | 376 | ||
| 376 | List<DeviceChannel> queryChannelWithCatalog(String serverGBId); | 377 | List<DeviceChannel> queryChannelWithCatalog(String serverGBId); |
| 378 | + | ||
| 379 | + List<DeviceChannelExtend> queryChannelsByDeviceId(String serial, List<String> channelIds, Boolean online); | ||
| 380 | + | ||
| 381 | + List<ParentPlatform> queryEnablePlatformListWithAsMessageChannel(); | ||
| 382 | + | ||
| 383 | + List<Device> queryDeviceWithAsMessageChannel(); | ||
| 377 | } | 384 | } |
src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceChannelMapper.java
| @@ -5,6 +5,7 @@ import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; | @@ -5,6 +5,7 @@ import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; | ||
| 5 | import com.genersoft.iot.vmp.gb28181.bean.DeviceChannelInPlatform; | 5 | import com.genersoft.iot.vmp.gb28181.bean.DeviceChannelInPlatform; |
| 6 | import com.genersoft.iot.vmp.vmanager.bean.ResourceBaceInfo; | 6 | import com.genersoft.iot.vmp.vmanager.bean.ResourceBaceInfo; |
| 7 | import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce; | 7 | import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce; |
| 8 | +import com.genersoft.iot.vmp.web.gb28181.dto.DeviceChannelExtend; | ||
| 8 | import org.apache.ibatis.annotations.*; | 9 | import org.apache.ibatis.annotations.*; |
| 9 | import org.springframework.stereotype.Repository; | 10 | import org.springframework.stereotype.Repository; |
| 10 | 11 | ||
| @@ -82,7 +83,56 @@ public interface DeviceChannelMapper { | @@ -82,7 +83,56 @@ public interface DeviceChannelMapper { | ||
| 82 | "</foreach> </if>" + | 83 | "</foreach> </if>" + |
| 83 | "ORDER BY dc.channelId " + | 84 | "ORDER BY dc.channelId " + |
| 84 | " </script>"}) | 85 | " </script>"}) |
| 85 | - List<DeviceChannel> queryChannels(String deviceId, String parentChannelId, String query, Boolean hasSubChannel, Boolean online,List<String> channelIds); | 86 | + List<DeviceChannel> queryChannels(String deviceId, String parentChannelId, String query, Boolean hasSubChannel, Boolean online, List<String> channelIds); |
| 87 | + | ||
| 88 | + @Select(value = {" <script>" + | ||
| 89 | + "SELECT " + | ||
| 90 | + "dc.*, " + | ||
| 91 | + "de.name as deviceName, " + | ||
| 92 | + "de.online as deviceOnline " + | ||
| 93 | + "from " + | ||
| 94 | + "device_channel dc " + | ||
| 95 | + "LEFT JOIN device de ON dc.deviceId = de.deviceId " + | ||
| 96 | + "WHERE 1=1" + | ||
| 97 | + " <if test='deviceId != null'> AND dc.deviceId = #{deviceId} </if> " + | ||
| 98 | + " <if test='query != null'> AND (dc.channelId LIKE '%${query}%' OR dc.name LIKE '%${query}%' OR dc.name LIKE '%${query}%')</if> " + | ||
| 99 | + " <if test='parentChannelId != null'> AND dc.parentId=#{parentChannelId} </if> " + | ||
| 100 | + " <if test='online == true' > AND dc.status=1</if>" + | ||
| 101 | + " <if test='online == false' > AND dc.status=0</if>" + | ||
| 102 | + " <if test='hasSubChannel == true' > AND dc.subCount > 0 </if>" + | ||
| 103 | + " <if test='hasSubChannel == false' > AND dc.subCount = 0 </if>" + | ||
| 104 | + "<if test='channelIds != null'> AND dc.channelId in <foreach item='item' index='index' collection='channelIds' open='(' separator=',' close=')'>" + | ||
| 105 | + "#{item} " + | ||
| 106 | + "</foreach> </if>" + | ||
| 107 | + "ORDER BY dc.channelId ASC" + | ||
| 108 | + " </script>"}) | ||
| 109 | + List<DeviceChannelExtend> queryChannelsWithDeviceInfo(String deviceId, String parentChannelId, String query, Boolean hasSubChannel, Boolean online, List<String> channelIds); | ||
| 110 | + | ||
| 111 | + | ||
| 112 | + @Select(value = {" <script>" + | ||
| 113 | + "SELECT " + | ||
| 114 | + "dc.*, " + | ||
| 115 | + "de.name as deviceName, " + | ||
| 116 | + "de.online as deviceOnline " + | ||
| 117 | + "from " + | ||
| 118 | + "device_channel dc " + | ||
| 119 | + "LEFT JOIN device de ON dc.deviceId = de.deviceId " + | ||
| 120 | + "WHERE 1=1" + | ||
| 121 | + " <if test='deviceId != null'> AND dc.deviceId = #{deviceId} </if> " + | ||
| 122 | + " <if test='query != null'> AND (dc.channelId LIKE '%${query}%' OR dc.name LIKE '%${query}%' OR dc.name LIKE '%${query}%')</if> " + | ||
| 123 | + " <if test='parentChannelId != null'> AND dc.parentId=#{parentChannelId} </if> " + | ||
| 124 | + " <if test='online == true' > AND dc.status=1</if>" + | ||
| 125 | + " <if test='online == false' > AND dc.status=0</if>" + | ||
| 126 | + " <if test='hasSubChannel == true' > AND dc.subCount > 0 </if>" + | ||
| 127 | + " <if test='hasSubChannel == false' > AND dc.subCount = 0 </if>" + | ||
| 128 | + "<if test='channelIds != null'> AND dc.channelId in <foreach item='item' index='index' collection='channelIds' open='(' separator=',' close=')'>" + | ||
| 129 | + "#{item} " + | ||
| 130 | + "</foreach> </if>" + | ||
| 131 | + "ORDER BY dc.channelId ASC " + | ||
| 132 | + "Limit #{limit} OFFSET #{start}" + | ||
| 133 | + " </script>"}) | ||
| 134 | + List<DeviceChannelExtend> queryChannelsByDeviceIdWithStartAndLimit(String deviceId,List<String> channelIds, String parentChannelId, String query, | ||
| 135 | + Boolean hasSubChannel, Boolean online, int start, int limit); | ||
| 86 | 136 | ||
| 87 | @Select("SELECT * FROM device_channel WHERE deviceId=#{deviceId} AND channelId=#{channelId}") | 137 | @Select("SELECT * FROM device_channel WHERE deviceId=#{deviceId} AND channelId=#{channelId}") |
| 88 | DeviceChannel queryChannel(String deviceId, String channelId); | 138 | DeviceChannel queryChannel(String deviceId, String channelId); |
| @@ -245,28 +295,6 @@ public interface DeviceChannelMapper { | @@ -245,28 +295,6 @@ public interface DeviceChannelMapper { | ||
| 245 | int batchUpdate(List<DeviceChannel> updateChannels); | 295 | int batchUpdate(List<DeviceChannel> updateChannels); |
| 246 | 296 | ||
| 247 | 297 | ||
| 248 | - @Select(value = {" <script>" + | ||
| 249 | - "SELECT " + | ||
| 250 | - "dc1.* " + | ||
| 251 | - "from " + | ||
| 252 | - "device_channel dc1 " + | ||
| 253 | - "WHERE " + | ||
| 254 | - "dc1.deviceId = #{deviceId} " + | ||
| 255 | - " <if test='query != null'> AND (dc1.channelId LIKE concat('%',#{query},'%') OR dc1.name LIKE concat('%',#{query},'%') OR dc1.name LIKE concat('%',#{query},'%'))</if> " + | ||
| 256 | - " <if test='parentChannelId != null'> AND dc1.parentId=#{parentChannelId} </if> " + | ||
| 257 | - " <if test='online == true' > AND dc1.status=1</if>" + | ||
| 258 | - " <if test='online == false' > AND dc1.status=0</if>" + | ||
| 259 | - " <if test='hasSubChannel == true' > AND dc1.subCount >0</if>" + | ||
| 260 | - " <if test='hasSubChannel == false' > AND dc1.subCount=0</if>" + | ||
| 261 | - "<if test='channelIds != null'> AND dc1.channelId in <foreach item='item' index='index' collection='channelIds' open='(' separator=',' close=')'>" + | ||
| 262 | - "#{item} " + | ||
| 263 | - "</foreach> </if>" + | ||
| 264 | - "ORDER BY dc1.channelId ASC " + | ||
| 265 | - "Limit #{limit} OFFSET #{start}" + | ||
| 266 | - " </script>"}) | ||
| 267 | - List<DeviceChannel> queryChannelsByDeviceIdWithStartAndLimit(String deviceId, String parentChannelId, String query, | ||
| 268 | - Boolean hasSubChannel, Boolean online, int start, int limit,List<String> channelIds); | ||
| 269 | - | ||
| 270 | @Select("SELECT * FROM device_channel WHERE deviceId=#{deviceId} AND status=1") | 298 | @Select("SELECT * FROM device_channel WHERE deviceId=#{deviceId} AND status=1") |
| 271 | List<DeviceChannel> queryOnlineChannelsByDeviceId(String deviceId); | 299 | List<DeviceChannel> queryOnlineChannelsByDeviceId(String deviceId); |
| 272 | 300 | ||
| @@ -316,10 +344,10 @@ public interface DeviceChannelMapper { | @@ -316,10 +344,10 @@ public interface DeviceChannelMapper { | ||
| 316 | "select * " + | 344 | "select * " + |
| 317 | "from device_channel " + | 345 | "from device_channel " + |
| 318 | "where deviceId=#{deviceId}" + | 346 | "where deviceId=#{deviceId}" + |
| 319 | - " <if test='parentId != null and length != null' > and parentId = #{parentId} or left(channelId, #{parentId.length()}) = #{parentId} and length(channelId)=#{length} </if>" + | 347 | + " <if test='parentId != null and length != null' > and parentId = #{parentId} or left(channelId, LENGTH(#{parentId})) = #{parentId} and length(channelId)=#{length} </if>" + |
| 320 | " <if test='parentId == null and length != null' > and parentId = #{parentId} or length(channelId)=#{length} </if>" + | 348 | " <if test='parentId == null and length != null' > and parentId = #{parentId} or length(channelId)=#{length} </if>" + |
| 321 | " <if test='parentId == null and length == null' > and parentId = #{parentId} </if>" + | 349 | " <if test='parentId == null and length == null' > and parentId = #{parentId} </if>" + |
| 322 | - " <if test='parentId != null and length == null' > and parentId = #{parentId} or left(channelId, #{parentId.length()}) = #{parentId} </if>" + | 350 | + " <if test='parentId != null and length == null' > and parentId = #{parentId} or left(channelId, LENGTH(#{parentId})) = #{parentId} </if>" + |
| 323 | " </script>"}) | 351 | " </script>"}) |
| 324 | List<DeviceChannel> getChannelsWithCivilCodeAndLength(String deviceId, String parentId, Integer length); | 352 | List<DeviceChannel> getChannelsWithCivilCodeAndLength(String deviceId, String parentId, Integer length); |
| 325 | 353 |
src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceMapper.java
| @@ -39,9 +39,12 @@ public interface DeviceMapper { | @@ -39,9 +39,12 @@ public interface DeviceMapper { | ||
| 39 | "mobilePositionSubmissionInterval," + | 39 | "mobilePositionSubmissionInterval," + |
| 40 | "subscribeCycleForAlarm," + | 40 | "subscribeCycleForAlarm," + |
| 41 | "ssrcCheck," + | 41 | "ssrcCheck," + |
| 42 | + "asMessageChannel," + | ||
| 42 | "geoCoordSys," + | 43 | "geoCoordSys," + |
| 43 | "treeType," + | 44 | "treeType," + |
| 44 | - "online" + | 45 | + "online," + |
| 46 | + "mediaServerId," + | ||
| 47 | + "(SELECT count(0) FROM device_channel WHERE deviceId=device.deviceId) as channelCount "+ | ||
| 45 | " FROM device WHERE deviceId = #{deviceId}") | 48 | " FROM device WHERE deviceId = #{deviceId}") |
| 46 | Device getDeviceByDeviceId(String deviceId); | 49 | Device getDeviceByDeviceId(String deviceId); |
| 47 | 50 | ||
| @@ -70,6 +73,7 @@ public interface DeviceMapper { | @@ -70,6 +73,7 @@ public interface DeviceMapper { | ||
| 70 | "mobilePositionSubmissionInterval," + | 73 | "mobilePositionSubmissionInterval," + |
| 71 | "subscribeCycleForAlarm," + | 74 | "subscribeCycleForAlarm," + |
| 72 | "ssrcCheck," + | 75 | "ssrcCheck," + |
| 76 | + "asMessageChannel," + | ||
| 73 | "geoCoordSys," + | 77 | "geoCoordSys," + |
| 74 | "treeType," + | 78 | "treeType," + |
| 75 | "online" + | 79 | "online" + |
| @@ -98,6 +102,7 @@ public interface DeviceMapper { | @@ -98,6 +102,7 @@ public interface DeviceMapper { | ||
| 98 | "#{mobilePositionSubmissionInterval}," + | 102 | "#{mobilePositionSubmissionInterval}," + |
| 99 | "#{subscribeCycleForAlarm}," + | 103 | "#{subscribeCycleForAlarm}," + |
| 100 | "#{ssrcCheck}," + | 104 | "#{ssrcCheck}," + |
| 105 | + "#{asMessageChannel}," + | ||
| 101 | "#{geoCoordSys}," + | 106 | "#{geoCoordSys}," + |
| 102 | "#{treeType}," + | 107 | "#{treeType}," + |
| 103 | "#{online}" + | 108 | "#{online}" + |
| @@ -152,9 +157,11 @@ public interface DeviceMapper { | @@ -152,9 +157,11 @@ public interface DeviceMapper { | ||
| 152 | "mobilePositionSubmissionInterval," + | 157 | "mobilePositionSubmissionInterval," + |
| 153 | "subscribeCycleForAlarm," + | 158 | "subscribeCycleForAlarm," + |
| 154 | "ssrcCheck," + | 159 | "ssrcCheck," + |
| 160 | + "asMessageChannel," + | ||
| 155 | "geoCoordSys," + | 161 | "geoCoordSys," + |
| 156 | "treeType," + | 162 | "treeType," + |
| 157 | "online," + | 163 | "online," + |
| 164 | + "mediaServerId," + | ||
| 158 | "(SELECT count(0) FROM device_channel WHERE deviceId=de.deviceId) as channelCount FROM device de" + | 165 | "(SELECT count(0) FROM device_channel WHERE deviceId=de.deviceId) as channelCount FROM device de" + |
| 159 | "<if test=\"online != null\"> where online=${online}</if>"+ | 166 | "<if test=\"online != null\"> where online=${online}</if>"+ |
| 160 | " </script>" | 167 | " </script>" |
| @@ -164,9 +171,6 @@ public interface DeviceMapper { | @@ -164,9 +171,6 @@ public interface DeviceMapper { | ||
| 164 | @Delete("DELETE FROM device WHERE deviceId=#{deviceId}") | 171 | @Delete("DELETE FROM device WHERE deviceId=#{deviceId}") |
| 165 | int del(String deviceId); | 172 | int del(String deviceId); |
| 166 | 173 | ||
| 167 | - @Update("UPDATE device SET online=0") | ||
| 168 | - int outlineForAll(); | ||
| 169 | - | ||
| 170 | @Select("SELECT " + | 174 | @Select("SELECT " + |
| 171 | "deviceId, " + | 175 | "deviceId, " + |
| 172 | "coalesce(custom_name, name) as name, " + | 176 | "coalesce(custom_name, name) as name, " + |
| @@ -192,6 +196,7 @@ public interface DeviceMapper { | @@ -192,6 +196,7 @@ public interface DeviceMapper { | ||
| 192 | "mobilePositionSubmissionInterval," + | 196 | "mobilePositionSubmissionInterval," + |
| 193 | "subscribeCycleForAlarm," + | 197 | "subscribeCycleForAlarm," + |
| 194 | "ssrcCheck," + | 198 | "ssrcCheck," + |
| 199 | + "asMessageChannel," + | ||
| 195 | "geoCoordSys," + | 200 | "geoCoordSys," + |
| 196 | "treeType," + | 201 | "treeType," + |
| 197 | "online " + | 202 | "online " + |
| @@ -222,6 +227,7 @@ public interface DeviceMapper { | @@ -222,6 +227,7 @@ public interface DeviceMapper { | ||
| 222 | "mobilePositionSubmissionInterval," + | 227 | "mobilePositionSubmissionInterval," + |
| 223 | "subscribeCycleForAlarm," + | 228 | "subscribeCycleForAlarm," + |
| 224 | "ssrcCheck," + | 229 | "ssrcCheck," + |
| 230 | + "asMessageChannel," + | ||
| 225 | "geoCoordSys," + | 231 | "geoCoordSys," + |
| 226 | "treeType," + | 232 | "treeType," + |
| 227 | "online" + | 233 | "online" + |
| @@ -243,12 +249,13 @@ public interface DeviceMapper { | @@ -243,12 +249,13 @@ public interface DeviceMapper { | ||
| 243 | "<if test=\"mobilePositionSubmissionInterval != null\">, mobilePositionSubmissionInterval=#{mobilePositionSubmissionInterval}</if>" + | 249 | "<if test=\"mobilePositionSubmissionInterval != null\">, mobilePositionSubmissionInterval=#{mobilePositionSubmissionInterval}</if>" + |
| 244 | "<if test=\"subscribeCycleForAlarm != null\">, subscribeCycleForAlarm=#{subscribeCycleForAlarm}</if>" + | 250 | "<if test=\"subscribeCycleForAlarm != null\">, subscribeCycleForAlarm=#{subscribeCycleForAlarm}</if>" + |
| 245 | "<if test=\"ssrcCheck != null\">, ssrcCheck=#{ssrcCheck}</if>" + | 251 | "<if test=\"ssrcCheck != null\">, ssrcCheck=#{ssrcCheck}</if>" + |
| 252 | + "<if test=\"asMessageChannel != null\">, asMessageChannel=#{asMessageChannel}</if>" + | ||
| 246 | "<if test=\"geoCoordSys != null\">, geoCoordSys=#{geoCoordSys}</if>" + | 253 | "<if test=\"geoCoordSys != null\">, geoCoordSys=#{geoCoordSys}</if>" + |
| 247 | "<if test=\"treeType != null\">, treeType=#{treeType}</if>" + | 254 | "<if test=\"treeType != null\">, treeType=#{treeType}</if>" + |
| 248 | "<if test=\"mediaServerId != null\">, mediaServerId=#{mediaServerId}</if>" + | 255 | "<if test=\"mediaServerId != null\">, mediaServerId=#{mediaServerId}</if>" + |
| 249 | "WHERE deviceId=#{deviceId}"+ | 256 | "WHERE deviceId=#{deviceId}"+ |
| 250 | " </script>"}) | 257 | " </script>"}) |
| 251 | - int updateCustom(Device device); | 258 | + void updateCustom(Device device); |
| 252 | 259 | ||
| 253 | @Insert("INSERT INTO device (" + | 260 | @Insert("INSERT INTO device (" + |
| 254 | "deviceId, " + | 261 | "deviceId, " + |
| @@ -259,9 +266,11 @@ public interface DeviceMapper { | @@ -259,9 +266,11 @@ public interface DeviceMapper { | ||
| 259 | "updateTime," + | 266 | "updateTime," + |
| 260 | "charset," + | 267 | "charset," + |
| 261 | "ssrcCheck," + | 268 | "ssrcCheck," + |
| 269 | + "asMessageChannel," + | ||
| 262 | "geoCoordSys," + | 270 | "geoCoordSys," + |
| 263 | "treeType," + | 271 | "treeType," + |
| 264 | - "online" + | 272 | + "online," + |
| 273 | + "mediaServerId" + | ||
| 265 | ") VALUES (" + | 274 | ") VALUES (" + |
| 266 | "#{deviceId}," + | 275 | "#{deviceId}," + |
| 267 | "#{name}," + | 276 | "#{name}," + |
| @@ -271,9 +280,11 @@ public interface DeviceMapper { | @@ -271,9 +280,11 @@ public interface DeviceMapper { | ||
| 271 | "#{updateTime}," + | 280 | "#{updateTime}," + |
| 272 | "#{charset}," + | 281 | "#{charset}," + |
| 273 | "#{ssrcCheck}," + | 282 | "#{ssrcCheck}," + |
| 283 | + "#{asMessageChannel}," + | ||
| 274 | "#{geoCoordSys}," + | 284 | "#{geoCoordSys}," + |
| 275 | "#{treeType}," + | 285 | "#{treeType}," + |
| 276 | - "#{online}" + | 286 | + "#{online}," + |
| 287 | + "#{mediaServerId}" + | ||
| 277 | ")") | 288 | ")") |
| 278 | void addCustomDevice(Device device); | 289 | void addCustomDevice(Device device); |
| 279 | 290 | ||
| @@ -282,4 +293,7 @@ public interface DeviceMapper { | @@ -282,4 +293,7 @@ public interface DeviceMapper { | ||
| 282 | 293 | ||
| 283 | @Select("select * from device") | 294 | @Select("select * from device") |
| 284 | List<Device> getAll(); | 295 | List<Device> getAll(); |
| 296 | + | ||
| 297 | + @Select("select * from device where asMessageChannel = 1") | ||
| 298 | + List<Device> queryDeviceWithAsMessageChannel(); | ||
| 285 | } | 299 | } |
src/main/java/com/genersoft/iot/vmp/storager/dao/ParentPlatformMapper.java
| @@ -15,10 +15,10 @@ import java.util.List; | @@ -15,10 +15,10 @@ import java.util.List; | ||
| 15 | public interface ParentPlatformMapper { | 15 | public interface ParentPlatformMapper { |
| 16 | 16 | ||
| 17 | @Insert("INSERT INTO parent_platform (enable, name, serverGBId, serverGBDomain, serverIP, serverPort, deviceGBId, deviceIp, " + | 17 | @Insert("INSERT INTO parent_platform (enable, name, serverGBId, serverGBDomain, serverIP, serverPort, deviceGBId, deviceIp, " + |
| 18 | - " devicePort, username, password, expires, keepTimeout, transport, characterSet, ptz, rtcp, " + | 18 | + " devicePort, username, password, expires, keepTimeout, transport, characterSet, ptz, rtcp, asMessageChannel, " + |
| 19 | " status, startOfflinePush, catalogId, administrativeDivision, catalogGroup, createTime, updateTime, treeType) " + | 19 | " status, startOfflinePush, catalogId, administrativeDivision, catalogGroup, createTime, updateTime, treeType) " + |
| 20 | " VALUES (#{enable}, #{name}, #{serverGBId}, #{serverGBDomain}, #{serverIP}, #{serverPort}, #{deviceGBId}, #{deviceIp}, " + | 20 | " VALUES (#{enable}, #{name}, #{serverGBId}, #{serverGBDomain}, #{serverIP}, #{serverPort}, #{deviceGBId}, #{deviceIp}, " + |
| 21 | - " #{devicePort}, #{username}, #{password}, #{expires}, #{keepTimeout}, #{transport}, #{characterSet}, #{ptz}, #{rtcp}, " + | 21 | + " #{devicePort}, #{username}, #{password}, #{expires}, #{keepTimeout}, #{transport}, #{characterSet}, #{ptz}, #{rtcp}, #{asMessageChannel}, " + |
| 22 | " #{status}, #{startOfflinePush}, #{catalogId}, #{administrativeDivision}, #{catalogGroup}, #{createTime}, #{updateTime}, #{treeType})") | 22 | " #{status}, #{startOfflinePush}, #{catalogId}, #{administrativeDivision}, #{catalogGroup}, #{createTime}, #{updateTime}, #{treeType})") |
| 23 | int addParentPlatform(ParentPlatform parentPlatform); | 23 | int addParentPlatform(ParentPlatform parentPlatform); |
| 24 | 24 | ||
| @@ -40,6 +40,7 @@ public interface ParentPlatformMapper { | @@ -40,6 +40,7 @@ public interface ParentPlatformMapper { | ||
| 40 | "characterSet=#{characterSet}, " + | 40 | "characterSet=#{characterSet}, " + |
| 41 | "ptz=#{ptz}, " + | 41 | "ptz=#{ptz}, " + |
| 42 | "rtcp=#{rtcp}, " + | 42 | "rtcp=#{rtcp}, " + |
| 43 | + "asMessageChannel=#{asMessageChannel}, " + | ||
| 43 | "status=#{status}, " + | 44 | "status=#{status}, " + |
| 44 | "startOfflinePush=#{startOfflinePush}, " + | 45 | "startOfflinePush=#{startOfflinePush}, " + |
| 45 | "catalogGroup=#{catalogGroup}, " + | 46 | "catalogGroup=#{catalogGroup}, " + |
| @@ -68,9 +69,12 @@ public interface ParentPlatformMapper { | @@ -68,9 +69,12 @@ public interface ParentPlatformMapper { | ||
| 68 | "FROM parent_platform pp ") | 69 | "FROM parent_platform pp ") |
| 69 | List<ParentPlatform> getParentPlatformList(); | 70 | List<ParentPlatform> getParentPlatformList(); |
| 70 | 71 | ||
| 71 | - @Select("SELECT * FROM parent_platform WHERE enable=#{enable}") | 72 | + @Select("SELECT * FROM parent_platform WHERE enable=#{enable} ") |
| 72 | List<ParentPlatform> getEnableParentPlatformList(boolean enable); | 73 | List<ParentPlatform> getEnableParentPlatformList(boolean enable); |
| 73 | 74 | ||
| 75 | + @Select("SELECT * FROM parent_platform WHERE enable=1 and asMessageChannel = 1") | ||
| 76 | + List<ParentPlatform> queryEnablePlatformListWithAsMessageChannel(); | ||
| 77 | + | ||
| 74 | @Select("SELECT * FROM parent_platform WHERE serverGBId=#{platformGbId}") | 78 | @Select("SELECT * FROM parent_platform WHERE serverGBId=#{platformGbId}") |
| 75 | ParentPlatform getParentPlatByServerGBId(String platformGbId); | 79 | ParentPlatform getParentPlatByServerGBId(String platformGbId); |
| 76 | 80 |
src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java
| @@ -177,12 +177,14 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { | @@ -177,12 +177,14 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { | ||
| 177 | @Override | 177 | @Override |
| 178 | public boolean startDownload(StreamInfo stream, String callId) { | 178 | public boolean startDownload(StreamInfo stream, String callId) { |
| 179 | boolean result; | 179 | boolean result; |
| 180 | + String key=String.format("%S_%s_%s_%s_%s_%s_%s", VideoManagerConstants.DOWNLOAD_PREFIX, | ||
| 181 | + userSetting.getServerId(), stream.getMediaServerId(), stream.getDeviceID(), stream.getChannelId(), stream.getStream(), callId); | ||
| 180 | if (stream.getProgress() == 1) { | 182 | if (stream.getProgress() == 1) { |
| 181 | - result = RedisUtil.set(String.format("%S_%s_%s_%s_%s_%s_%s", VideoManagerConstants.DOWNLOAD_PREFIX, | ||
| 182 | - userSetting.getServerId(), stream.getMediaServerId(), stream.getDeviceID(), stream.getChannelId(), stream.getStream(), callId), stream); | 183 | + logger.debug("添加下载缓存==已完成下载=》{}",key); |
| 184 | + result = RedisUtil.set(key, stream); | ||
| 183 | }else { | 185 | }else { |
| 184 | - result = RedisUtil.set(String.format("%S_%s_%s_%s_%s_%s_%s", VideoManagerConstants.DOWNLOAD_PREFIX, | ||
| 185 | - userSetting.getServerId(), stream.getMediaServerId(), stream.getDeviceID(), stream.getChannelId(), stream.getStream(), callId), stream, 60*60); | 186 | + logger.debug("添加下载缓存==未完成下载=》{}",key); |
| 187 | + result = RedisUtil.set(key, stream, 60*60); | ||
| 186 | } | 188 | } |
| 187 | return result; | 189 | return result; |
| 188 | } | 190 | } |
| @@ -617,7 +619,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { | @@ -617,7 +619,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { | ||
| 617 | stream, | 619 | stream, |
| 618 | callId | 620 | callId |
| 619 | ); | 621 | ); |
| 620 | - List<Object> streamInfoScan = RedisUtil.scan(key); | 622 | + List<Object> streamInfoScan = RedisUtil.scan2(key); |
| 621 | if (streamInfoScan.size() > 0) { | 623 | if (streamInfoScan.size() > 0) { |
| 622 | return (StreamInfo) RedisUtil.get((String) streamInfoScan.get(0)); | 624 | return (StreamInfo) RedisUtil.get((String) streamInfoScan.get(0)); |
| 623 | }else { | 625 | }else { |
| @@ -855,7 +857,8 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { | @@ -855,7 +857,8 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { | ||
| 855 | 857 | ||
| 856 | @Override | 858 | @Override |
| 857 | public void sendAlarmMsg(AlarmChannelMessage msg) { | 859 | public void sendAlarmMsg(AlarmChannelMessage msg) { |
| 858 | - String key = VideoManagerConstants.VM_MSG_SUBSCRIBE_ALARM_RECEIVE; | 860 | + // 此消息用于对接第三方服务下级来的消息内容 |
| 861 | + String key = VideoManagerConstants.VM_MSG_SUBSCRIBE_ALARM; | ||
| 859 | logger.info("[redis发送通知] 报警{}: {}", key, JSON.toJSON(msg)); | 862 | logger.info("[redis发送通知] 报警{}: {}", key, JSON.toJSON(msg)); |
| 860 | RedisUtil.convertAndSend(key, (JSONObject)JSON.toJSON(msg)); | 863 | RedisUtil.convertAndSend(key, (JSONObject)JSON.toJSON(msg)); |
| 861 | } | 864 | } |
src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStorageImpl.java
| @@ -13,6 +13,7 @@ import com.genersoft.iot.vmp.storager.dao.*; | @@ -13,6 +13,7 @@ import com.genersoft.iot.vmp.storager.dao.*; | ||
| 13 | import com.genersoft.iot.vmp.storager.dao.dto.ChannelSourceInfo; | 13 | import com.genersoft.iot.vmp.storager.dao.dto.ChannelSourceInfo; |
| 14 | import com.genersoft.iot.vmp.utils.DateUtil; | 14 | import com.genersoft.iot.vmp.utils.DateUtil; |
| 15 | import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce; | 15 | import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce; |
| 16 | +import com.genersoft.iot.vmp.web.gb28181.dto.DeviceChannelExtend; | ||
| 16 | import com.github.pagehelper.PageHelper; | 17 | import com.github.pagehelper.PageHelper; |
| 17 | import com.github.pagehelper.PageInfo; | 18 | import com.github.pagehelper.PageInfo; |
| 18 | import org.slf4j.Logger; | 19 | import org.slf4j.Logger; |
| @@ -189,7 +190,7 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage { | @@ -189,7 +190,7 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage { | ||
| 189 | dataSourceTransactionManager.commit(transactionStatus); //手动提交 | 190 | dataSourceTransactionManager.commit(transactionStatus); //手动提交 |
| 190 | return true; | 191 | return true; |
| 191 | }catch (Exception e) { | 192 | }catch (Exception e) { |
| 192 | - e.printStackTrace(); | 193 | + logger.error("未处理的异常 ", e); |
| 193 | dataSourceTransactionManager.rollback(transactionStatus); | 194 | dataSourceTransactionManager.rollback(transactionStatus); |
| 194 | return false; | 195 | return false; |
| 195 | } | 196 | } |
| @@ -305,7 +306,7 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage { | @@ -305,7 +306,7 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage { | ||
| 305 | } | 306 | } |
| 306 | return true; | 307 | return true; |
| 307 | }catch (Exception e) { | 308 | }catch (Exception e) { |
| 308 | - e.printStackTrace(); | 309 | + logger.error("未处理的异常 ", e); |
| 309 | dataSourceTransactionManager.rollback(transactionStatus); | 310 | dataSourceTransactionManager.rollback(transactionStatus); |
| 310 | return false; | 311 | return false; |
| 311 | } | 312 | } |
| @@ -359,8 +360,8 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage { | @@ -359,8 +360,8 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage { | ||
| 359 | } | 360 | } |
| 360 | 361 | ||
| 361 | @Override | 362 | @Override |
| 362 | - public List<DeviceChannel> queryChannelsByDeviceIdWithStartAndLimit(String deviceId, String query, Boolean hasSubChannel, Boolean online, int start, int limit,List<String> channelIds) { | ||
| 363 | - return deviceChannelMapper.queryChannelsByDeviceIdWithStartAndLimit(deviceId, null, query, hasSubChannel, online, start, limit,channelIds); | 363 | + public List<DeviceChannelExtend> queryChannelsByDeviceIdWithStartAndLimit(String deviceId, List<String> channelIds, String query, Boolean hasSubChannel, Boolean online, int start, int limit) { |
| 364 | + return deviceChannelMapper.queryChannelsByDeviceIdWithStartAndLimit(deviceId, channelIds, null, query, hasSubChannel, online, start, limit); | ||
| 364 | } | 365 | } |
| 365 | 366 | ||
| 366 | 367 | ||
| @@ -370,6 +371,11 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage { | @@ -370,6 +371,11 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage { | ||
| 370 | } | 371 | } |
| 371 | 372 | ||
| 372 | @Override | 373 | @Override |
| 374 | + public List<DeviceChannelExtend> queryChannelsByDeviceId(String deviceId, List<String> channelIds, Boolean online) { | ||
| 375 | + return deviceChannelMapper.queryChannelsWithDeviceInfo(deviceId, null,null, null, online,channelIds); | ||
| 376 | + } | ||
| 377 | + | ||
| 378 | + @Override | ||
| 373 | public PageInfo<DeviceChannel> querySubChannels(String deviceId, String parentChannelId, String query, Boolean hasSubChannel, Boolean online, int page, int count) { | 379 | public PageInfo<DeviceChannel> querySubChannels(String deviceId, String parentChannelId, String query, Boolean hasSubChannel, Boolean online, int page, int count) { |
| 374 | PageHelper.startPage(page, count); | 380 | PageHelper.startPage(page, count); |
| 375 | List<DeviceChannel> all = deviceChannelMapper.queryChannels(deviceId, parentChannelId, query, hasSubChannel, online,null); | 381 | List<DeviceChannel> all = deviceChannelMapper.queryChannels(deviceId, parentChannelId, query, hasSubChannel, online,null); |
| @@ -512,6 +518,16 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage { | @@ -512,6 +518,16 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage { | ||
| 512 | } | 518 | } |
| 513 | 519 | ||
| 514 | @Override | 520 | @Override |
| 521 | + public List<ParentPlatform> queryEnablePlatformListWithAsMessageChannel() { | ||
| 522 | + return platformMapper.queryEnablePlatformListWithAsMessageChannel(); | ||
| 523 | + } | ||
| 524 | + | ||
| 525 | + @Override | ||
| 526 | + public List<Device> queryDeviceWithAsMessageChannel() { | ||
| 527 | + return deviceMapper.queryDeviceWithAsMessageChannel(); | ||
| 528 | + } | ||
| 529 | + | ||
| 530 | + @Override | ||
| 515 | public void outlineForAllParentPlatform() { | 531 | public void outlineForAllParentPlatform() { |
| 516 | platformMapper.outlineForAllParentPlatform(); | 532 | platformMapper.outlineForAllParentPlatform(); |
| 517 | } | 533 | } |
src/main/java/com/genersoft/iot/vmp/utils/DateUtil.java
| @@ -45,7 +45,6 @@ public class DateUtil { | @@ -45,7 +45,6 @@ public class DateUtil { | ||
| 45 | 45 | ||
| 46 | public static String ISO8601Toyyyy_MM_dd_HH_mm_ss(String formatTime) { | 46 | public static String ISO8601Toyyyy_MM_dd_HH_mm_ss(String formatTime) { |
| 47 | return formatter.format(formatterCompatibleISO8601.parse(formatTime)); | 47 | return formatter.format(formatterCompatibleISO8601.parse(formatTime)); |
| 48 | - | ||
| 49 | } | 48 | } |
| 50 | 49 | ||
| 51 | /** | 50 | /** |
src/main/java/com/genersoft/iot/vmp/utils/redis/RedisUtil.java
| @@ -881,7 +881,13 @@ public class RedisUtil { | @@ -881,7 +881,13 @@ public class RedisUtil { | ||
| 881 | 881 | ||
| 882 | return new ArrayList<>(resultKeys); | 882 | return new ArrayList<>(resultKeys); |
| 883 | } | 883 | } |
| 884 | - | 884 | + public static List<Object> scan2(String query) { |
| 885 | + if (redisTemplate == null) { | ||
| 886 | + redisTemplate = SpringBeanFactory.getBean("redisTemplate"); | ||
| 887 | + } | ||
| 888 | + Set<String> keys = redisTemplate.keys(query); | ||
| 889 | + return new ArrayList<>(keys); | ||
| 890 | + } | ||
| 885 | // ============================== 消息发送与订阅 ============================== | 891 | // ============================== 消息发送与订阅 ============================== |
| 886 | public static void convertAndSend(String channel, JSONObject msg) { | 892 | public static void convertAndSend(String channel, JSONObject msg) { |
| 887 | if (redisTemplate == null) { | 893 | if (redisTemplate == null) { |
src/main/java/com/genersoft/iot/vmp/vmanager/bean/WVPResult.java
| @@ -28,6 +28,10 @@ public class WVPResult<T> implements Cloneable{ | @@ -28,6 +28,10 @@ public class WVPResult<T> implements Cloneable{ | ||
| 28 | return new WVPResult<>(ErrorCode.SUCCESS.getCode(), msg, t); | 28 | return new WVPResult<>(ErrorCode.SUCCESS.getCode(), msg, t); |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | + public static WVPResult success() { | ||
| 32 | + return new WVPResult<>(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg(), null); | ||
| 33 | + } | ||
| 34 | + | ||
| 31 | public static <T> WVPResult<T> success(T t) { | 35 | public static <T> WVPResult<T> success(T t) { |
| 32 | return success(t, ErrorCode.SUCCESS.getMsg()); | 36 | return success(t, ErrorCode.SUCCESS.getMsg()); |
| 33 | } | 37 | } |
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/MobilePosition/MobilePositionController.java
| @@ -30,7 +30,7 @@ import java.util.UUID; | @@ -30,7 +30,7 @@ import java.util.UUID; | ||
| 30 | * 位置信息管理 | 30 | * 位置信息管理 |
| 31 | */ | 31 | */ |
| 32 | @Tag(name = "位置信息管理") | 32 | @Tag(name = "位置信息管理") |
| 33 | -@CrossOrigin | 33 | + |
| 34 | @RestController | 34 | @RestController |
| 35 | @RequestMapping("/api/position") | 35 | @RequestMapping("/api/position") |
| 36 | public class MobilePositionController { | 36 | public class MobilePositionController { |
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/SseController/SseController.java
| @@ -17,7 +17,7 @@ import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; | @@ -17,7 +17,7 @@ import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; | ||
| 17 | * @data: 2021-01-20 | 17 | * @data: 2021-01-20 |
| 18 | */ | 18 | */ |
| 19 | @Tag(name = "SSE推送") | 19 | @Tag(name = "SSE推送") |
| 20 | -@CrossOrigin | 20 | + |
| 21 | @Controller | 21 | @Controller |
| 22 | @RequestMapping("/api") | 22 | @RequestMapping("/api") |
| 23 | public class SseController { | 23 | public class SseController { |
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/alarm/AlarmController.java
| @@ -6,35 +6,28 @@ import com.genersoft.iot.vmp.gb28181.bean.DeviceAlarm; | @@ -6,35 +6,28 @@ import com.genersoft.iot.vmp.gb28181.bean.DeviceAlarm; | ||
| 6 | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; | 6 | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; |
| 7 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; | 7 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; |
| 8 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; | 8 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; |
| 9 | -import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookListener; | ||
| 10 | import com.genersoft.iot.vmp.service.IDeviceAlarmService; | 9 | import com.genersoft.iot.vmp.service.IDeviceAlarmService; |
| 11 | import com.genersoft.iot.vmp.storager.IVideoManagerStorage; | 10 | import com.genersoft.iot.vmp.storager.IVideoManagerStorage; |
| 12 | import com.genersoft.iot.vmp.utils.DateUtil; | 11 | import com.genersoft.iot.vmp.utils.DateUtil; |
| 13 | import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; | 12 | import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; |
| 14 | -import com.genersoft.iot.vmp.vmanager.bean.WVPResult; | ||
| 15 | import com.github.pagehelper.PageInfo; | 13 | import com.github.pagehelper.PageInfo; |
| 16 | import io.swagger.v3.oas.annotations.Operation; | 14 | import io.swagger.v3.oas.annotations.Operation; |
| 17 | import io.swagger.v3.oas.annotations.Parameter; | 15 | import io.swagger.v3.oas.annotations.Parameter; |
| 18 | -import io.swagger.v3.oas.annotations.responses.ApiResponse; | ||
| 19 | import io.swagger.v3.oas.annotations.tags.Tag; | 16 | import io.swagger.v3.oas.annotations.tags.Tag; |
| 20 | import org.slf4j.Logger; | 17 | import org.slf4j.Logger; |
| 21 | import org.slf4j.LoggerFactory; | 18 | import org.slf4j.LoggerFactory; |
| 22 | import org.springframework.beans.factory.annotation.Autowired; | 19 | import org.springframework.beans.factory.annotation.Autowired; |
| 23 | -import org.springframework.http.HttpStatus; | ||
| 24 | -import org.springframework.http.ResponseEntity; | ||
| 25 | import org.springframework.util.ObjectUtils; | 20 | import org.springframework.util.ObjectUtils; |
| 26 | -import org.springframework.util.StringUtils; | ||
| 27 | import org.springframework.web.bind.annotation.*; | 21 | import org.springframework.web.bind.annotation.*; |
| 28 | 22 | ||
| 29 | import javax.sip.InvalidArgumentException; | 23 | import javax.sip.InvalidArgumentException; |
| 30 | import javax.sip.SipException; | 24 | import javax.sip.SipException; |
| 31 | import java.text.ParseException; | 25 | import java.text.ParseException; |
| 32 | -import java.time.LocalDateTime; | ||
| 33 | import java.util.Arrays; | 26 | import java.util.Arrays; |
| 34 | import java.util.List; | 27 | import java.util.List; |
| 35 | 28 | ||
| 36 | @Tag(name = "报警信息管理") | 29 | @Tag(name = "报警信息管理") |
| 37 | -@CrossOrigin | 30 | + |
| 38 | @RestController | 31 | @RestController |
| 39 | @RequestMapping("/api/alarm") | 32 | @RequestMapping("/api/alarm") |
| 40 | public class AlarmController { | 33 | public class AlarmController { |
| @@ -78,11 +71,11 @@ public class AlarmController { | @@ -78,11 +71,11 @@ public class AlarmController { | ||
| 78 | if (ObjectUtils.isEmpty(deviceIds)) { | 71 | if (ObjectUtils.isEmpty(deviceIds)) { |
| 79 | deviceIds = null; | 72 | deviceIds = null; |
| 80 | } | 73 | } |
| 74 | + | ||
| 81 | if (ObjectUtils.isEmpty(time)) { | 75 | if (ObjectUtils.isEmpty(time)) { |
| 82 | time = null; | 76 | time = null; |
| 83 | - } | ||
| 84 | - if (!DateUtil.verification(time, DateUtil.formatter) ){ | ||
| 85 | - return null; | 77 | + }else if (!DateUtil.verification(time, DateUtil.formatter) ){ |
| 78 | + throw new ControllerException(ErrorCode.ERROR400.getCode(), "time格式为" + DateUtil.PATTERN); | ||
| 86 | } | 79 | } |
| 87 | List<String> deviceIdList = null; | 80 | List<String> deviceIdList = null; |
| 88 | if (deviceIds != null) { | 81 | if (deviceIds != null) { |
| @@ -110,7 +103,7 @@ public class AlarmController { | @@ -110,7 +103,7 @@ public class AlarmController { | ||
| 110 | deviceAlarm.setAlarmDescription("test"); | 103 | deviceAlarm.setAlarmDescription("test"); |
| 111 | deviceAlarm.setAlarmMethod("1"); | 104 | deviceAlarm.setAlarmMethod("1"); |
| 112 | deviceAlarm.setAlarmPriority("1"); | 105 | deviceAlarm.setAlarmPriority("1"); |
| 113 | - deviceAlarm.setAlarmTime(DateUtil.formatterISO8601.format(LocalDateTime.now())); | 106 | + deviceAlarm.setAlarmTime(DateUtil.getNow()); |
| 114 | deviceAlarm.setAlarmType("1"); | 107 | deviceAlarm.setAlarmType("1"); |
| 115 | deviceAlarm.setLongitude(115.33333); | 108 | deviceAlarm.setLongitude(115.33333); |
| 116 | deviceAlarm.setLatitude(39.33333); | 109 | deviceAlarm.setLatitude(39.33333); |
| @@ -177,16 +170,17 @@ public class AlarmController { | @@ -177,16 +170,17 @@ public class AlarmController { | ||
| 177 | if (ObjectUtils.isEmpty(alarmType)) { | 170 | if (ObjectUtils.isEmpty(alarmType)) { |
| 178 | alarmType = null; | 171 | alarmType = null; |
| 179 | } | 172 | } |
| 173 | + | ||
| 180 | if (ObjectUtils.isEmpty(startTime)) { | 174 | if (ObjectUtils.isEmpty(startTime)) { |
| 181 | startTime = null; | 175 | startTime = null; |
| 176 | + }else if (!DateUtil.verification(startTime, DateUtil.formatter) ){ | ||
| 177 | + throw new ControllerException(ErrorCode.ERROR400.getCode(), "startTime格式为" + DateUtil.PATTERN); | ||
| 182 | } | 178 | } |
| 179 | + | ||
| 183 | if (ObjectUtils.isEmpty(endTime)) { | 180 | if (ObjectUtils.isEmpty(endTime)) { |
| 184 | endTime = null; | 181 | endTime = null; |
| 185 | - } | ||
| 186 | - | ||
| 187 | - | ||
| 188 | - if (!DateUtil.verification(startTime, DateUtil.formatter) || !DateUtil.verification(endTime, DateUtil.formatter)){ | ||
| 189 | - throw new ControllerException(ErrorCode.ERROR100.getCode(), "开始时间或结束时间格式有误"); | 182 | + }else if (!DateUtil.verification(endTime, DateUtil.formatter) ){ |
| 183 | + throw new ControllerException(ErrorCode.ERROR400.getCode(), "endTime格式为" + DateUtil.PATTERN); | ||
| 190 | } | 184 | } |
| 191 | 185 | ||
| 192 | return deviceAlarmService.getAllAlarm(page, count, deviceId, alarmPriority, alarmMethod, | 186 | return deviceAlarmService.getAllAlarm(page, count, deviceId, alarmPriority, alarmMethod, |
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceConfig.java
| @@ -14,7 +14,6 @@ import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; | @@ -14,7 +14,6 @@ import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; | ||
| 14 | import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; | 14 | import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; |
| 15 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; | 15 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; |
| 16 | import com.genersoft.iot.vmp.storager.IVideoManagerStorage; | 16 | import com.genersoft.iot.vmp.storager.IVideoManagerStorage; |
| 17 | - | ||
| 18 | import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; | 17 | import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; |
| 19 | import io.swagger.v3.oas.annotations.Operation; | 18 | import io.swagger.v3.oas.annotations.Operation; |
| 20 | import io.swagger.v3.oas.annotations.Parameter; | 19 | import io.swagger.v3.oas.annotations.Parameter; |
| @@ -22,9 +21,7 @@ import io.swagger.v3.oas.annotations.tags.Tag; | @@ -22,9 +21,7 @@ import io.swagger.v3.oas.annotations.tags.Tag; | ||
| 22 | import org.slf4j.Logger; | 21 | import org.slf4j.Logger; |
| 23 | import org.slf4j.LoggerFactory; | 22 | import org.slf4j.LoggerFactory; |
| 24 | import org.springframework.beans.factory.annotation.Autowired; | 23 | import org.springframework.beans.factory.annotation.Autowired; |
| 25 | -import org.springframework.http.ResponseEntity; | ||
| 26 | import org.springframework.util.ObjectUtils; | 24 | import org.springframework.util.ObjectUtils; |
| 27 | -import org.springframework.util.StringUtils; | ||
| 28 | import org.springframework.web.bind.annotation.*; | 25 | import org.springframework.web.bind.annotation.*; |
| 29 | import org.springframework.web.context.request.async.DeferredResult; | 26 | import org.springframework.web.context.request.async.DeferredResult; |
| 30 | 27 | ||
| @@ -34,7 +31,6 @@ import java.text.ParseException; | @@ -34,7 +31,6 @@ import java.text.ParseException; | ||
| 34 | import java.util.UUID; | 31 | import java.util.UUID; |
| 35 | 32 | ||
| 36 | @Tag(name = "国标设备配置") | 33 | @Tag(name = "国标设备配置") |
| 37 | -@CrossOrigin | ||
| 38 | @RestController | 34 | @RestController |
| 39 | @RequestMapping("/api/device/config") | 35 | @RequestMapping("/api/device/config") |
| 40 | public class DeviceConfig { | 36 | public class DeviceConfig { |
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceControl.java
| @@ -32,7 +32,7 @@ import java.text.ParseException; | @@ -32,7 +32,7 @@ import java.text.ParseException; | ||
| 32 | import java.util.UUID; | 32 | import java.util.UUID; |
| 33 | 33 | ||
| 34 | @Tag(name = "国标设备控制") | 34 | @Tag(name = "国标设备控制") |
| 35 | -@CrossOrigin | 35 | + |
| 36 | @RestController | 36 | @RestController |
| 37 | @RequestMapping("/api/device/control") | 37 | @RequestMapping("/api/device/control") |
| 38 | public class DeviceControl { | 38 | public class DeviceControl { |
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java
| @@ -24,6 +24,7 @@ import io.swagger.v3.oas.annotations.Operation; | @@ -24,6 +24,7 @@ import io.swagger.v3.oas.annotations.Operation; | ||
| 24 | import io.swagger.v3.oas.annotations.Parameter; | 24 | import io.swagger.v3.oas.annotations.Parameter; |
| 25 | import io.swagger.v3.oas.annotations.tags.Tag; | 25 | import io.swagger.v3.oas.annotations.tags.Tag; |
| 26 | import org.apache.commons.compress.utils.IOUtils; | 26 | import org.apache.commons.compress.utils.IOUtils; |
| 27 | +import org.apache.ibatis.annotations.Options; | ||
| 27 | import org.slf4j.Logger; | 28 | import org.slf4j.Logger; |
| 28 | import org.slf4j.LoggerFactory; | 29 | import org.slf4j.LoggerFactory; |
| 29 | import org.springframework.beans.factory.annotation.Autowired; | 30 | import org.springframework.beans.factory.annotation.Autowired; |
| @@ -46,7 +47,7 @@ import java.util.*; | @@ -46,7 +47,7 @@ import java.util.*; | ||
| 46 | 47 | ||
| 47 | @Tag(name = "国标设备查询", description = "国标设备查询") | 48 | @Tag(name = "国标设备查询", description = "国标设备查询") |
| 48 | @SuppressWarnings("rawtypes") | 49 | @SuppressWarnings("rawtypes") |
| 49 | -@CrossOrigin | 50 | + |
| 50 | @RestController | 51 | @RestController |
| 51 | @RequestMapping("/api/device/query") | 52 | @RequestMapping("/api/device/query") |
| 52 | public class DeviceQuery { | 53 | public class DeviceQuery { |
| @@ -97,8 +98,10 @@ public class DeviceQuery { | @@ -97,8 +98,10 @@ public class DeviceQuery { | ||
| 97 | @Parameter(name = "page", description = "当前页", required = true) | 98 | @Parameter(name = "page", description = "当前页", required = true) |
| 98 | @Parameter(name = "count", description = "每页查询数量", required = true) | 99 | @Parameter(name = "count", description = "每页查询数量", required = true) |
| 99 | @GetMapping("/devices") | 100 | @GetMapping("/devices") |
| 101 | + @Options() | ||
| 100 | public PageInfo<Device> devices(int page, int count){ | 102 | public PageInfo<Device> devices(int page, int count){ |
| 101 | - | 103 | +// if (page == null) page = 0; |
| 104 | +// if (count == null) count = 20; | ||
| 102 | return storager.queryVideoDeviceList(page, count,null); | 105 | return storager.queryVideoDeviceList(page, count,null); |
| 103 | } | 106 | } |
| 104 | 107 |
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/gbStream/GbStreamController.java
| @@ -17,7 +17,7 @@ import org.springframework.web.bind.annotation.*; | @@ -17,7 +17,7 @@ import org.springframework.web.bind.annotation.*; | ||
| 17 | import java.util.List; | 17 | import java.util.List; |
| 18 | 18 | ||
| 19 | @Tag(name = "视频流关联到级联平台") | 19 | @Tag(name = "视频流关联到级联平台") |
| 20 | -@CrossOrigin | 20 | + |
| 21 | @RestController | 21 | @RestController |
| 22 | @RequestMapping("/api/gbStream") | 22 | @RequestMapping("/api/gbStream") |
| 23 | public class GbStreamController { | 23 | public class GbStreamController { |
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/media/MediaController.java
| @@ -24,7 +24,7 @@ import javax.servlet.http.HttpServletRequest; | @@ -24,7 +24,7 @@ import javax.servlet.http.HttpServletRequest; | ||
| 24 | 24 | ||
| 25 | @Tag(name = "媒体流相关") | 25 | @Tag(name = "媒体流相关") |
| 26 | @Controller | 26 | @Controller |
| 27 | -@CrossOrigin | 27 | + |
| 28 | @RequestMapping(value = "/api/media") | 28 | @RequestMapping(value = "/api/media") |
| 29 | public class MediaController { | 29 | public class MediaController { |
| 30 | 30 |
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/PlatformController.java
| @@ -7,6 +7,7 @@ import com.genersoft.iot.vmp.conf.DynamicTask; | @@ -7,6 +7,7 @@ import com.genersoft.iot.vmp.conf.DynamicTask; | ||
| 7 | import com.genersoft.iot.vmp.conf.UserSetting; | 7 | import com.genersoft.iot.vmp.conf.UserSetting; |
| 8 | import com.genersoft.iot.vmp.conf.exception.ControllerException; | 8 | import com.genersoft.iot.vmp.conf.exception.ControllerException; |
| 9 | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; | 9 | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; |
| 10 | +import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch; | ||
| 10 | import com.genersoft.iot.vmp.gb28181.bean.PlatformCatalog; | 11 | import com.genersoft.iot.vmp.gb28181.bean.PlatformCatalog; |
| 11 | import com.genersoft.iot.vmp.gb28181.bean.SubscribeHolder; | 12 | import com.genersoft.iot.vmp.gb28181.bean.SubscribeHolder; |
| 12 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; | 13 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; |
| @@ -37,7 +38,7 @@ import java.util.List; | @@ -37,7 +38,7 @@ import java.util.List; | ||
| 37 | * 级联平台管理 | 38 | * 级联平台管理 |
| 38 | */ | 39 | */ |
| 39 | @Tag(name = "级联平台管理") | 40 | @Tag(name = "级联平台管理") |
| 40 | -@CrossOrigin | 41 | + |
| 41 | @RestController | 42 | @RestController |
| 42 | @RequestMapping("/api/platform") | 43 | @RequestMapping("/api/platform") |
| 43 | public class PlatformController { | 44 | public class PlatformController { |
| @@ -205,58 +206,8 @@ public class PlatformController { | @@ -205,58 +206,8 @@ public class PlatformController { | ||
| 205 | ) { | 206 | ) { |
| 206 | throw new ControllerException(ErrorCode.ERROR400); | 207 | throw new ControllerException(ErrorCode.ERROR400); |
| 207 | } | 208 | } |
| 208 | - parentPlatform.setCharacterSet(parentPlatform.getCharacterSet().toUpperCase()); | ||
| 209 | - ParentPlatform parentPlatformOld = storager.queryParentPlatByServerGBId(parentPlatform.getServerGBId()); | ||
| 210 | - parentPlatform.setUpdateTime(DateUtil.getNow()); | ||
| 211 | - if (!parentPlatformOld.getTreeType().equals(parentPlatform.getTreeType())) { | ||
| 212 | - // 目录结构发生变化,清空之前的关联关系 | ||
| 213 | - logger.info("保存平台{}时发现目录结构变化,清空关联关系", parentPlatform.getDeviceGBId()); | ||
| 214 | - storager.cleanContentForPlatform(parentPlatform.getServerGBId()); | ||
| 215 | - | ||
| 216 | - } | ||
| 217 | - boolean updateResult = storager.updateParentPlatform(parentPlatform); | ||
| 218 | - | ||
| 219 | - if (updateResult) { | ||
| 220 | - // 保存时启用就发送注册 | ||
| 221 | - if (parentPlatform.isEnable()) { | ||
| 222 | - if (parentPlatformOld != null && parentPlatformOld.isStatus()) { | ||
| 223 | - try { | ||
| 224 | - commanderForPlatform.unregister(parentPlatformOld, null, null); | ||
| 225 | - } catch (InvalidArgumentException | ParseException | SipException e) { | ||
| 226 | - logger.error("[命令发送失败] 国标级联 注销: {}", e.getMessage()); | ||
| 227 | - } | ||
| 228 | - try { | ||
| 229 | - Thread.sleep(500); | ||
| 230 | - } catch (InterruptedException e) { | ||
| 231 | - logger.error("[线程休眠失败] : {}", e.getMessage()); | ||
| 232 | - } | ||
| 233 | - // 只要保存就发送注册 | ||
| 234 | - try { | ||
| 235 | - commanderForPlatform.register(parentPlatform, null, null); | ||
| 236 | - } catch (InvalidArgumentException | ParseException | SipException e) { | ||
| 237 | - logger.error("[命令发送失败] 国标级联 注册: {}", e.getMessage()); | ||
| 238 | - } | ||
| 239 | - | ||
| 240 | - } else { | ||
| 241 | - // 只要保存就发送注册 | ||
| 242 | - try { | ||
| 243 | - commanderForPlatform.register(parentPlatform, null, null); | ||
| 244 | - } catch (InvalidArgumentException | ParseException | SipException e) { | ||
| 245 | - logger.error("[命令发送失败] 国标级联 注册: {}", e.getMessage()); | ||
| 246 | - } | ||
| 247 | - } | ||
| 248 | - } else if (parentPlatformOld != null && parentPlatformOld.isEnable() && !parentPlatform.isEnable()) { // 关闭启用时注销 | ||
| 249 | - try { | ||
| 250 | - commanderForPlatform.unregister(parentPlatformOld, null, null); | ||
| 251 | - } catch (InvalidArgumentException | ParseException | SipException e) { | ||
| 252 | - logger.error("[命令发送失败] 国标级联 注销: {}", e.getMessage()); | ||
| 253 | - } | ||
| 254 | - // 停止订阅相关的定时任务 | ||
| 255 | - subscribeHolder.removeAllSubscribe(parentPlatform.getServerGBId()); | ||
| 256 | - } | ||
| 257 | - } else { | ||
| 258 | - throw new ControllerException(ErrorCode.ERROR100.getCode(),"写入数据库失败"); | ||
| 259 | - } | 209 | + |
| 210 | + platformService.update(parentPlatform); | ||
| 260 | } | 211 | } |
| 261 | 212 | ||
| 262 | /** | 213 | /** |
| @@ -279,12 +230,16 @@ public class PlatformController { | @@ -279,12 +230,16 @@ public class PlatformController { | ||
| 279 | throw new ControllerException(ErrorCode.ERROR400); | 230 | throw new ControllerException(ErrorCode.ERROR400); |
| 280 | } | 231 | } |
| 281 | ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(serverGBId); | 232 | ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(serverGBId); |
| 233 | + ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(serverGBId); | ||
| 282 | if (parentPlatform == null) { | 234 | if (parentPlatform == null) { |
| 283 | throw new ControllerException(ErrorCode.ERROR100.getCode(), "平台不存在"); | 235 | throw new ControllerException(ErrorCode.ERROR100.getCode(), "平台不存在"); |
| 284 | } | 236 | } |
| 237 | + if (parentPlatformCatch == null) { | ||
| 238 | + throw new ControllerException(ErrorCode.ERROR100.getCode(), "平台不存在"); | ||
| 239 | + } | ||
| 285 | // 发送离线消息,无论是否成功都删除缓存 | 240 | // 发送离线消息,无论是否成功都删除缓存 |
| 286 | try { | 241 | try { |
| 287 | - commanderForPlatform.unregister(parentPlatform, (event -> { | 242 | + commanderForPlatform.unregister(parentPlatform, parentPlatformCatch.getSipTransactionInfo(), (event -> { |
| 288 | // 清空redis缓存 | 243 | // 清空redis缓存 |
| 289 | redisCatchStorage.delPlatformCatchInfo(parentPlatform.getServerGBId()); | 244 | redisCatchStorage.delPlatformCatchInfo(parentPlatform.getServerGBId()); |
| 290 | redisCatchStorage.delPlatformKeepalive(parentPlatform.getServerGBId()); | 245 | redisCatchStorage.delPlatformKeepalive(parentPlatform.getServerGBId()); |
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java
| @@ -41,7 +41,7 @@ import java.util.UUID; | @@ -41,7 +41,7 @@ import java.util.UUID; | ||
| 41 | * @author lin | 41 | * @author lin |
| 42 | */ | 42 | */ |
| 43 | @Tag(name = "国标设备点播") | 43 | @Tag(name = "国标设备点播") |
| 44 | -@CrossOrigin | 44 | + |
| 45 | @RestController | 45 | @RestController |
| 46 | @RequestMapping("/api/play") | 46 | @RequestMapping("/api/play") |
| 47 | public class PlayController { | 47 | public class PlayController { |
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/playback/PlaybackController.java
| @@ -40,7 +40,7 @@ import java.util.UUID; | @@ -40,7 +40,7 @@ import java.util.UUID; | ||
| 40 | * @author lin | 40 | * @author lin |
| 41 | */ | 41 | */ |
| 42 | @Tag(name = "视频回放") | 42 | @Tag(name = "视频回放") |
| 43 | -@CrossOrigin | 43 | + |
| 44 | @RestController | 44 | @RestController |
| 45 | @RequestMapping("/api/playback") | 45 | @RequestMapping("/api/playback") |
| 46 | public class PlaybackController { | 46 | public class PlaybackController { |
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/ptz/PtzController.java
| 1 | package com.genersoft.iot.vmp.vmanager.gb28181.ptz; | 1 | package com.genersoft.iot.vmp.vmanager.gb28181.ptz; |
| 2 | 2 | ||
| 3 | - | 3 | + |
| 4 | import com.genersoft.iot.vmp.conf.exception.ControllerException; | 4 | import com.genersoft.iot.vmp.conf.exception.ControllerException; |
| 5 | +import com.genersoft.iot.vmp.gb28181.bean.Device; | ||
| 6 | +import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; | ||
| 7 | +import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; | ||
| 8 | +import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; | ||
| 9 | +import com.genersoft.iot.vmp.storager.IVideoManagerStorage; | ||
| 5 | import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; | 10 | import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; |
| 6 | import io.swagger.v3.oas.annotations.Operation; | 11 | import io.swagger.v3.oas.annotations.Operation; |
| 7 | import io.swagger.v3.oas.annotations.Parameter; | 12 | import io.swagger.v3.oas.annotations.Parameter; |
| @@ -10,23 +15,16 @@ import org.slf4j.Logger; | @@ -10,23 +15,16 @@ import org.slf4j.Logger; | ||
| 10 | import org.slf4j.LoggerFactory; | 15 | import org.slf4j.LoggerFactory; |
| 11 | import org.springframework.beans.factory.annotation.Autowired; | 16 | import org.springframework.beans.factory.annotation.Autowired; |
| 12 | import org.springframework.util.ObjectUtils; | 17 | import org.springframework.util.ObjectUtils; |
| 13 | -import org.springframework.util.StringUtils; | ||
| 14 | import org.springframework.web.bind.annotation.*; | 18 | import org.springframework.web.bind.annotation.*; |
| 15 | import org.springframework.web.context.request.async.DeferredResult; | 19 | import org.springframework.web.context.request.async.DeferredResult; |
| 16 | 20 | ||
| 17 | -import com.genersoft.iot.vmp.gb28181.bean.Device; | ||
| 18 | -import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; | ||
| 19 | -import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; | ||
| 20 | -import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; | ||
| 21 | -import com.genersoft.iot.vmp.storager.IVideoManagerStorage; | ||
| 22 | - | ||
| 23 | import javax.sip.InvalidArgumentException; | 21 | import javax.sip.InvalidArgumentException; |
| 24 | import javax.sip.SipException; | 22 | import javax.sip.SipException; |
| 25 | import java.text.ParseException; | 23 | import java.text.ParseException; |
| 26 | import java.util.UUID; | 24 | import java.util.UUID; |
| 27 | 25 | ||
| 28 | @Tag(name = "云台控制") | 26 | @Tag(name = "云台控制") |
| 29 | -@CrossOrigin | 27 | + |
| 30 | @RestController | 28 | @RestController |
| 31 | @RequestMapping("/api/ptz") | 29 | @RequestMapping("/api/ptz") |
| 32 | public class PtzController { | 30 | public class PtzController { |
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/record/GBRecordController.java
| @@ -3,40 +3,37 @@ package com.genersoft.iot.vmp.vmanager.gb28181.record; | @@ -3,40 +3,37 @@ package com.genersoft.iot.vmp.vmanager.gb28181.record; | ||
| 3 | import com.genersoft.iot.vmp.common.StreamInfo; | 3 | import com.genersoft.iot.vmp.common.StreamInfo; |
| 4 | import com.genersoft.iot.vmp.conf.exception.ControllerException; | 4 | import com.genersoft.iot.vmp.conf.exception.ControllerException; |
| 5 | import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException; | 5 | import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException; |
| 6 | +import com.genersoft.iot.vmp.gb28181.bean.Device; | ||
| 7 | +import com.genersoft.iot.vmp.gb28181.bean.RecordInfo; | ||
| 8 | +import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; | ||
| 6 | import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; | 9 | import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; |
| 10 | +import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; | ||
| 7 | import com.genersoft.iot.vmp.service.IDeviceService; | 11 | import com.genersoft.iot.vmp.service.IDeviceService; |
| 8 | import com.genersoft.iot.vmp.service.IPlayService; | 12 | import com.genersoft.iot.vmp.service.IPlayService; |
| 13 | +import com.genersoft.iot.vmp.storager.IVideoManagerStorage; | ||
| 9 | import com.genersoft.iot.vmp.utils.DateUtil; | 14 | import com.genersoft.iot.vmp.utils.DateUtil; |
| 10 | import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; | 15 | import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; |
| 11 | import com.genersoft.iot.vmp.vmanager.bean.StreamContent; | 16 | import com.genersoft.iot.vmp.vmanager.bean.StreamContent; |
| 12 | import com.genersoft.iot.vmp.vmanager.bean.WVPResult; | 17 | import com.genersoft.iot.vmp.vmanager.bean.WVPResult; |
| 13 | - | ||
| 14 | import io.swagger.v3.oas.annotations.Operation; | 18 | import io.swagger.v3.oas.annotations.Operation; |
| 15 | import io.swagger.v3.oas.annotations.Parameter; | 19 | import io.swagger.v3.oas.annotations.Parameter; |
| 16 | import io.swagger.v3.oas.annotations.tags.Tag; | 20 | import io.swagger.v3.oas.annotations.tags.Tag; |
| 17 | import org.slf4j.Logger; | 21 | import org.slf4j.Logger; |
| 18 | import org.slf4j.LoggerFactory; | 22 | import org.slf4j.LoggerFactory; |
| 19 | import org.springframework.beans.factory.annotation.Autowired; | 23 | import org.springframework.beans.factory.annotation.Autowired; |
| 20 | -import org.springframework.web.bind.annotation.CrossOrigin; | ||
| 21 | import org.springframework.web.bind.annotation.GetMapping; | 24 | import org.springframework.web.bind.annotation.GetMapping; |
| 22 | import org.springframework.web.bind.annotation.PathVariable; | 25 | import org.springframework.web.bind.annotation.PathVariable; |
| 23 | import org.springframework.web.bind.annotation.RequestMapping; | 26 | import org.springframework.web.bind.annotation.RequestMapping; |
| 24 | import org.springframework.web.bind.annotation.RestController; | 27 | import org.springframework.web.bind.annotation.RestController; |
| 25 | import org.springframework.web.context.request.async.DeferredResult; | 28 | import org.springframework.web.context.request.async.DeferredResult; |
| 26 | 29 | ||
| 27 | -import com.genersoft.iot.vmp.gb28181.bean.Device; | ||
| 28 | -import com.genersoft.iot.vmp.gb28181.bean.RecordInfo; | ||
| 29 | -import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; | ||
| 30 | -import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; | ||
| 31 | -import com.genersoft.iot.vmp.storager.IVideoManagerStorage; | ||
| 32 | - | ||
| 33 | import javax.sip.InvalidArgumentException; | 30 | import javax.sip.InvalidArgumentException; |
| 34 | import javax.sip.SipException; | 31 | import javax.sip.SipException; |
| 35 | import java.text.ParseException; | 32 | import java.text.ParseException; |
| 36 | import java.util.UUID; | 33 | import java.util.UUID; |
| 37 | 34 | ||
| 38 | @Tag(name = "国标录像") | 35 | @Tag(name = "国标录像") |
| 39 | -@CrossOrigin | 36 | + |
| 40 | @RestController | 37 | @RestController |
| 41 | @RequestMapping("/api/gb_record") | 38 | @RequestMapping("/api/gb_record") |
| 42 | public class GBRecordController { | 39 | public class GBRecordController { |
| @@ -74,10 +71,10 @@ public class GBRecordController { | @@ -74,10 +71,10 @@ public class GBRecordController { | ||
| 74 | } | 71 | } |
| 75 | DeferredResult<WVPResult<RecordInfo>> result = new DeferredResult<>(); | 72 | DeferredResult<WVPResult<RecordInfo>> result = new DeferredResult<>(); |
| 76 | if (!DateUtil.verification(startTime, DateUtil.formatter)){ | 73 | if (!DateUtil.verification(startTime, DateUtil.formatter)){ |
| 77 | - throw new ControllerException(ErrorCode.ERROR100.getCode(), "startTime error, format is " + DateUtil.PATTERN); | 74 | + throw new ControllerException(ErrorCode.ERROR100.getCode(), "startTime格式为" + DateUtil.PATTERN); |
| 78 | } | 75 | } |
| 79 | if (!DateUtil.verification(endTime, DateUtil.formatter)){ | 76 | if (!DateUtil.verification(endTime, DateUtil.formatter)){ |
| 80 | - throw new ControllerException(ErrorCode.ERROR100.getCode(), "endTime error, format is " + DateUtil.PATTERN); | 77 | + throw new ControllerException(ErrorCode.ERROR100.getCode(), "endTime格式为" + DateUtil.PATTERN); |
| 81 | } | 78 | } |
| 82 | 79 | ||
| 83 | Device device = storager.queryVideoDevice(deviceId); | 80 | Device device = storager.queryVideoDevice(deviceId); |
src/main/java/com/genersoft/iot/vmp/vmanager/log/LogController.java
| @@ -6,25 +6,18 @@ import com.genersoft.iot.vmp.service.ILogService; | @@ -6,25 +6,18 @@ import com.genersoft.iot.vmp.service.ILogService; | ||
| 6 | import com.genersoft.iot.vmp.storager.dao.dto.LogDto; | 6 | import com.genersoft.iot.vmp.storager.dao.dto.LogDto; |
| 7 | import com.genersoft.iot.vmp.utils.DateUtil; | 7 | import com.genersoft.iot.vmp.utils.DateUtil; |
| 8 | import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; | 8 | import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; |
| 9 | -import com.genersoft.iot.vmp.vmanager.bean.WVPResult; | ||
| 10 | import com.github.pagehelper.PageInfo; | 9 | import com.github.pagehelper.PageInfo; |
| 11 | - | ||
| 12 | import io.swagger.v3.oas.annotations.Operation; | 10 | import io.swagger.v3.oas.annotations.Operation; |
| 13 | import io.swagger.v3.oas.annotations.Parameter; | 11 | import io.swagger.v3.oas.annotations.Parameter; |
| 14 | import io.swagger.v3.oas.annotations.tags.Tag; | 12 | import io.swagger.v3.oas.annotations.tags.Tag; |
| 15 | import org.slf4j.Logger; | 13 | import org.slf4j.Logger; |
| 16 | import org.slf4j.LoggerFactory; | 14 | import org.slf4j.LoggerFactory; |
| 17 | import org.springframework.beans.factory.annotation.Autowired; | 15 | import org.springframework.beans.factory.annotation.Autowired; |
| 18 | -import org.springframework.http.HttpStatus; | ||
| 19 | -import org.springframework.http.ResponseEntity; | ||
| 20 | import org.springframework.util.ObjectUtils; | 16 | import org.springframework.util.ObjectUtils; |
| 21 | -import org.springframework.util.StringUtils; | ||
| 22 | import org.springframework.web.bind.annotation.*; | 17 | import org.springframework.web.bind.annotation.*; |
| 23 | 18 | ||
| 24 | -import java.text.ParseException; | ||
| 25 | - | ||
| 26 | @Tag(name = "日志管理") | 19 | @Tag(name = "日志管理") |
| 27 | -@CrossOrigin | 20 | + |
| 28 | @RestController | 21 | @RestController |
| 29 | @RequestMapping("/api/log") | 22 | @RequestMapping("/api/log") |
| 30 | public class LogController { | 23 | public class LogController { |
| @@ -67,18 +60,21 @@ public class LogController { | @@ -67,18 +60,21 @@ public class LogController { | ||
| 67 | if (ObjectUtils.isEmpty(query)) { | 60 | if (ObjectUtils.isEmpty(query)) { |
| 68 | query = null; | 61 | query = null; |
| 69 | } | 62 | } |
| 63 | + | ||
| 64 | + if (!userSetting.getLogInDatebase()) { | ||
| 65 | + logger.warn("自动记录日志功能已关闭,查询结果可能不完整。"); | ||
| 66 | + } | ||
| 67 | + | ||
| 70 | if (ObjectUtils.isEmpty(startTime)) { | 68 | if (ObjectUtils.isEmpty(startTime)) { |
| 71 | startTime = null; | 69 | startTime = null; |
| 70 | + }else if (!DateUtil.verification(startTime, DateUtil.formatter) ){ | ||
| 71 | + throw new ControllerException(ErrorCode.ERROR400.getCode(), "startTime格式为" + DateUtil.PATTERN); | ||
| 72 | } | 72 | } |
| 73 | + | ||
| 73 | if (ObjectUtils.isEmpty(endTime)) { | 74 | if (ObjectUtils.isEmpty(endTime)) { |
| 74 | endTime = null; | 75 | endTime = null; |
| 75 | - } | ||
| 76 | - if (!userSetting.getLogInDatebase()) { | ||
| 77 | - logger.warn("自动记录日志功能已关闭,查询结果可能不完整。"); | ||
| 78 | - } | ||
| 79 | - | ||
| 80 | - if (!DateUtil.verification(startTime, DateUtil.formatter) || !DateUtil.verification(endTime, DateUtil.formatter)){ | ||
| 81 | - throw new ControllerException(ErrorCode.ERROR400); | 76 | + }else if (!DateUtil.verification(endTime, DateUtil.formatter) ){ |
| 77 | + throw new ControllerException(ErrorCode.ERROR400.getCode(), "endTime格式为" + DateUtil.PATTERN); | ||
| 82 | } | 78 | } |
| 83 | 79 | ||
| 84 | return logService.getAll(page, count, query, type, startTime, endTime); | 80 | return logService.getAll(page, count, query, type, startTime, endTime); |
src/main/java/com/genersoft/iot/vmp/vmanager/record/RecordController.java
| @@ -14,7 +14,7 @@ | @@ -14,7 +14,7 @@ | ||
| 14 | //import org.springframework.web.bind.annotation.*; | 14 | //import org.springframework.web.bind.annotation.*; |
| 15 | // | 15 | // |
| 16 | //@Tag(name = "云端录像") | 16 | //@Tag(name = "云端录像") |
| 17 | -//@CrossOrigin | 17 | +// |
| 18 | //@RestController | 18 | //@RestController |
| 19 | //@RequestMapping("/api/record") | 19 | //@RequestMapping("/api/record") |
| 20 | //public class RecordController { | 20 | //public class RecordController { |
src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java
| @@ -2,7 +2,6 @@ package com.genersoft.iot.vmp.vmanager.server; | @@ -2,7 +2,6 @@ package com.genersoft.iot.vmp.vmanager.server; | ||
| 2 | 2 | ||
| 3 | import com.alibaba.fastjson2.JSON; | 3 | import com.alibaba.fastjson2.JSON; |
| 4 | import com.alibaba.fastjson2.JSONObject; | 4 | import com.alibaba.fastjson2.JSONObject; |
| 5 | -import com.genersoft.iot.vmp.VManageBootstrap; | ||
| 6 | import com.genersoft.iot.vmp.common.SystemAllInfo; | 5 | import com.genersoft.iot.vmp.common.SystemAllInfo; |
| 7 | import com.genersoft.iot.vmp.common.VersionPo; | 6 | import com.genersoft.iot.vmp.common.VersionPo; |
| 8 | import com.genersoft.iot.vmp.conf.SipConfig; | 7 | import com.genersoft.iot.vmp.conf.SipConfig; |
| @@ -15,30 +14,24 @@ import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | @@ -15,30 +14,24 @@ import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | ||
| 15 | import com.genersoft.iot.vmp.service.*; | 14 | import com.genersoft.iot.vmp.service.*; |
| 16 | import com.genersoft.iot.vmp.service.bean.MediaServerLoad; | 15 | import com.genersoft.iot.vmp.service.bean.MediaServerLoad; |
| 17 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; | 16 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| 18 | -import com.genersoft.iot.vmp.utils.SpringBeanFactory; | ||
| 19 | import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; | 17 | import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; |
| 20 | import com.genersoft.iot.vmp.vmanager.bean.ResourceBaceInfo; | 18 | import com.genersoft.iot.vmp.vmanager.bean.ResourceBaceInfo; |
| 21 | import com.genersoft.iot.vmp.vmanager.bean.ResourceInfo; | 19 | import com.genersoft.iot.vmp.vmanager.bean.ResourceInfo; |
| 22 | import com.genersoft.iot.vmp.vmanager.bean.SystemConfigInfo; | 20 | import com.genersoft.iot.vmp.vmanager.bean.SystemConfigInfo; |
| 23 | -import gov.nist.javax.sip.SipStackImpl; | ||
| 24 | - | ||
| 25 | import io.swagger.v3.oas.annotations.Operation; | 21 | import io.swagger.v3.oas.annotations.Operation; |
| 26 | import io.swagger.v3.oas.annotations.Parameter; | 22 | import io.swagger.v3.oas.annotations.Parameter; |
| 27 | import io.swagger.v3.oas.annotations.tags.Tag; | 23 | import io.swagger.v3.oas.annotations.tags.Tag; |
| 28 | import org.springframework.beans.factory.annotation.Autowired; | 24 | import org.springframework.beans.factory.annotation.Autowired; |
| 29 | import org.springframework.beans.factory.annotation.Value; | 25 | import org.springframework.beans.factory.annotation.Value; |
| 30 | -import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; | ||
| 31 | import org.springframework.util.ObjectUtils; | 26 | import org.springframework.util.ObjectUtils; |
| 32 | import org.springframework.web.bind.annotation.*; | 27 | import org.springframework.web.bind.annotation.*; |
| 33 | 28 | ||
| 34 | -import javax.sip.ListeningPoint; | ||
| 35 | -import javax.sip.ObjectInUseException; | ||
| 36 | -import javax.sip.SipProvider; | ||
| 37 | -import java.util.*; | 29 | +import java.util.ArrayList; |
| 30 | +import java.util.List; | ||
| 38 | 31 | ||
| 39 | @SuppressWarnings("rawtypes") | 32 | @SuppressWarnings("rawtypes") |
| 40 | @Tag(name = "服务控制") | 33 | @Tag(name = "服务控制") |
| 41 | -@CrossOrigin | 34 | + |
| 42 | @RestController | 35 | @RestController |
| 43 | @RequestMapping("/api/server") | 36 | @RequestMapping("/api/server") |
| 44 | public class ServerController { | 37 | public class ServerController { |
| @@ -77,9 +70,6 @@ public class ServerController { | @@ -77,9 +70,6 @@ public class ServerController { | ||
| 77 | 70 | ||
| 78 | 71 | ||
| 79 | @Autowired | 72 | @Autowired |
| 80 | - private ThreadPoolTaskExecutor taskExecutor; | ||
| 81 | - | ||
| 82 | - @Autowired | ||
| 83 | private IRedisCatchStorage redisCatchStorage; | 73 | private IRedisCatchStorage redisCatchStorage; |
| 84 | 74 | ||
| 85 | 75 |
src/main/java/com/genersoft/iot/vmp/vmanager/streamProxy/StreamProxyController.java
| @@ -25,7 +25,7 @@ import org.springframework.web.bind.annotation.*; | @@ -25,7 +25,7 @@ import org.springframework.web.bind.annotation.*; | ||
| 25 | */ | 25 | */ |
| 26 | @Tag(name = "拉流代理", description = "") | 26 | @Tag(name = "拉流代理", description = "") |
| 27 | @Controller | 27 | @Controller |
| 28 | -@CrossOrigin | 28 | + |
| 29 | @RequestMapping(value = "/api/proxy") | 29 | @RequestMapping(value = "/api/proxy") |
| 30 | public class StreamProxyController { | 30 | public class StreamProxyController { |
| 31 | 31 |
src/main/java/com/genersoft/iot/vmp/vmanager/streamPush/StreamPushController.java
| @@ -41,7 +41,7 @@ import java.util.UUID; | @@ -41,7 +41,7 @@ import java.util.UUID; | ||
| 41 | 41 | ||
| 42 | @Tag(name = "推流信息管理") | 42 | @Tag(name = "推流信息管理") |
| 43 | @Controller | 43 | @Controller |
| 44 | -@CrossOrigin | 44 | + |
| 45 | @RequestMapping(value = "/api/push") | 45 | @RequestMapping(value = "/api/push") |
| 46 | public class StreamPushController { | 46 | public class StreamPushController { |
| 47 | 47 | ||
| @@ -181,7 +181,7 @@ public class StreamPushController { | @@ -181,7 +181,7 @@ public class StreamPushController { | ||
| 181 | String name = file.getName(); | 181 | String name = file.getName(); |
| 182 | inputStream = file.getInputStream(); | 182 | inputStream = file.getInputStream(); |
| 183 | } catch (IOException e) { | 183 | } catch (IOException e) { |
| 184 | - e.printStackTrace(); | 184 | + logger.error("未处理的异常 ", e); |
| 185 | } | 185 | } |
| 186 | try { | 186 | try { |
| 187 | //传入参数 | 187 | //传入参数 |
src/main/java/com/genersoft/iot/vmp/vmanager/user/RoleController.java
| @@ -6,20 +6,16 @@ import com.genersoft.iot.vmp.service.IRoleService; | @@ -6,20 +6,16 @@ import com.genersoft.iot.vmp.service.IRoleService; | ||
| 6 | import com.genersoft.iot.vmp.storager.dao.dto.Role; | 6 | import com.genersoft.iot.vmp.storager.dao.dto.Role; |
| 7 | import com.genersoft.iot.vmp.utils.DateUtil; | 7 | import com.genersoft.iot.vmp.utils.DateUtil; |
| 8 | import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; | 8 | import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; |
| 9 | -import com.genersoft.iot.vmp.vmanager.bean.WVPResult; | ||
| 10 | - | ||
| 11 | import io.swagger.v3.oas.annotations.Operation; | 9 | import io.swagger.v3.oas.annotations.Operation; |
| 12 | import io.swagger.v3.oas.annotations.Parameter; | 10 | import io.swagger.v3.oas.annotations.Parameter; |
| 13 | import io.swagger.v3.oas.annotations.tags.Tag; | 11 | import io.swagger.v3.oas.annotations.tags.Tag; |
| 14 | import org.springframework.beans.factory.annotation.Autowired; | 12 | import org.springframework.beans.factory.annotation.Autowired; |
| 15 | -import org.springframework.http.HttpStatus; | ||
| 16 | -import org.springframework.http.ResponseEntity; | ||
| 17 | import org.springframework.web.bind.annotation.*; | 13 | import org.springframework.web.bind.annotation.*; |
| 18 | 14 | ||
| 19 | import java.util.List; | 15 | import java.util.List; |
| 20 | 16 | ||
| 21 | @Tag(name = "角色管理") | 17 | @Tag(name = "角色管理") |
| 22 | -@CrossOrigin | 18 | + |
| 23 | @RestController | 19 | @RestController |
| 24 | @RequestMapping("/api/role") | 20 | @RequestMapping("/api/role") |
| 25 | public class RoleController { | 21 | public class RoleController { |
src/main/java/com/genersoft/iot/vmp/vmanager/user/UserController.java
| 1 | package com.genersoft.iot.vmp.vmanager.user; | 1 | package com.genersoft.iot.vmp.vmanager.user; |
| 2 | 2 | ||
| 3 | import com.genersoft.iot.vmp.conf.exception.ControllerException; | 3 | import com.genersoft.iot.vmp.conf.exception.ControllerException; |
| 4 | +import com.genersoft.iot.vmp.conf.security.JwtUtils; | ||
| 4 | import com.genersoft.iot.vmp.conf.security.SecurityUtils; | 5 | import com.genersoft.iot.vmp.conf.security.SecurityUtils; |
| 5 | import com.genersoft.iot.vmp.conf.security.dto.LoginUser; | 6 | import com.genersoft.iot.vmp.conf.security.dto.LoginUser; |
| 6 | import com.genersoft.iot.vmp.service.IRoleService; | 7 | import com.genersoft.iot.vmp.service.IRoleService; |
| @@ -21,10 +22,11 @@ import org.springframework.util.ObjectUtils; | @@ -21,10 +22,11 @@ import org.springframework.util.ObjectUtils; | ||
| 21 | import org.springframework.web.bind.annotation.*; | 22 | import org.springframework.web.bind.annotation.*; |
| 22 | 23 | ||
| 23 | import javax.security.sasl.AuthenticationException; | 24 | import javax.security.sasl.AuthenticationException; |
| 25 | +import javax.servlet.http.HttpServletRequest; | ||
| 26 | +import javax.servlet.http.HttpServletResponse; | ||
| 24 | import java.util.List; | 27 | import java.util.List; |
| 25 | 28 | ||
| 26 | @Tag(name = "用户管理") | 29 | @Tag(name = "用户管理") |
| 27 | -@CrossOrigin | ||
| 28 | @RestController | 30 | @RestController |
| 29 | @RequestMapping("/api/user") | 31 | @RequestMapping("/api/user") |
| 30 | public class UserController { | 32 | public class UserController { |
| @@ -40,11 +42,13 @@ public class UserController { | @@ -40,11 +42,13 @@ public class UserController { | ||
| 40 | 42 | ||
| 41 | @GetMapping("/login") | 43 | @GetMapping("/login") |
| 42 | @PostMapping("/login") | 44 | @PostMapping("/login") |
| 43 | - @Operation(summary = "登录") | 45 | + @Operation(summary = "登录", description = "登录成功后返回AccessToken, 可以从返回值获取到也可以从响应头中获取到," + |
| 46 | + "后续的请求需要添加请求头 'access-token'或者放在参数里") | ||
| 47 | + | ||
| 44 | @Parameter(name = "username", description = "用户名", required = true) | 48 | @Parameter(name = "username", description = "用户名", required = true) |
| 45 | @Parameter(name = "password", description = "密码(32位md5加密)", required = true) | 49 | @Parameter(name = "password", description = "密码(32位md5加密)", required = true) |
| 46 | - public LoginUser login(@RequestParam String username, @RequestParam String password){ | ||
| 47 | - LoginUser user = null; | 50 | + public LoginUser login(HttpServletRequest request, HttpServletResponse response, @RequestParam String username, @RequestParam String password){ |
| 51 | + LoginUser user; | ||
| 48 | try { | 52 | try { |
| 49 | user = SecurityUtils.login(username, password, authenticationManager); | 53 | user = SecurityUtils.login(username, password, authenticationManager); |
| 50 | } catch (AuthenticationException e) { | 54 | } catch (AuthenticationException e) { |
| @@ -52,10 +56,15 @@ public class UserController { | @@ -52,10 +56,15 @@ public class UserController { | ||
| 52 | } | 56 | } |
| 53 | if (user == null) { | 57 | if (user == null) { |
| 54 | throw new ControllerException(ErrorCode.ERROR100.getCode(), "用户名或密码错误"); | 58 | throw new ControllerException(ErrorCode.ERROR100.getCode(), "用户名或密码错误"); |
| 59 | + }else { | ||
| 60 | + String jwt = JwtUtils.createToken(username, password); | ||
| 61 | + response.setHeader(JwtUtils.getHeader(), jwt); | ||
| 62 | + user.setAccessToken(jwt); | ||
| 55 | } | 63 | } |
| 56 | return user; | 64 | return user; |
| 57 | } | 65 | } |
| 58 | 66 | ||
| 67 | + | ||
| 59 | @PostMapping("/changePassword") | 68 | @PostMapping("/changePassword") |
| 60 | @Operation(summary = "修改密码") | 69 | @Operation(summary = "修改密码") |
| 61 | @Parameter(name = "username", description = "用户名", required = true) | 70 | @Parameter(name = "username", description = "用户名", required = true) |
| @@ -74,8 +83,8 @@ public class UserController { | @@ -74,8 +83,8 @@ public class UserController { | ||
| 74 | if (user == null) { | 83 | if (user == null) { |
| 75 | throw new ControllerException(ErrorCode.ERROR100); | 84 | throw new ControllerException(ErrorCode.ERROR100); |
| 76 | } | 85 | } |
| 77 | - int userId = SecurityUtils.getUserId(); | ||
| 78 | - boolean result = userService.changePassword(userId, DigestUtils.md5DigestAsHex(password.getBytes())); | 86 | + //int userId = SecurityUtils.getUserId(); |
| 87 | + boolean result = userService.changePassword(user.getId(), DigestUtils.md5DigestAsHex(password.getBytes())); | ||
| 79 | if (!result) { | 88 | if (!result) { |
| 80 | throw new ControllerException(ErrorCode.ERROR100); | 89 | throw new ControllerException(ErrorCode.ERROR100); |
| 81 | } | 90 | } |
src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiControlController.java
| 1 | package com.genersoft.iot.vmp.web.gb28181; | 1 | package com.genersoft.iot.vmp.web.gb28181; |
| 2 | 2 | ||
| 3 | -import com.alibaba.fastjson2.JSONObject; | ||
| 4 | import com.genersoft.iot.vmp.conf.exception.ControllerException; | 3 | import com.genersoft.iot.vmp.conf.exception.ControllerException; |
| 5 | import com.genersoft.iot.vmp.gb28181.bean.Device; | 4 | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| 6 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; | 5 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; |
| @@ -9,7 +8,9 @@ import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; | @@ -9,7 +8,9 @@ import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; | ||
| 9 | import org.slf4j.Logger; | 8 | import org.slf4j.Logger; |
| 10 | import org.slf4j.LoggerFactory; | 9 | import org.slf4j.LoggerFactory; |
| 11 | import org.springframework.beans.factory.annotation.Autowired; | 10 | import org.springframework.beans.factory.annotation.Autowired; |
| 12 | -import org.springframework.web.bind.annotation.*; | 11 | +import org.springframework.web.bind.annotation.RequestMapping; |
| 12 | +import org.springframework.web.bind.annotation.RequestParam; | ||
| 13 | +import org.springframework.web.bind.annotation.RestController; | ||
| 13 | 14 | ||
| 14 | import javax.sip.InvalidArgumentException; | 15 | import javax.sip.InvalidArgumentException; |
| 15 | import javax.sip.SipException; | 16 | import javax.sip.SipException; |
| @@ -18,7 +19,7 @@ import java.text.ParseException; | @@ -18,7 +19,7 @@ import java.text.ParseException; | ||
| 18 | /** | 19 | /** |
| 19 | * API兼容:设备控制 | 20 | * API兼容:设备控制 |
| 20 | */ | 21 | */ |
| 21 | -@CrossOrigin | 22 | + |
| 22 | @RestController | 23 | @RestController |
| 23 | @RequestMapping(value = "/api/v1/control") | 24 | @RequestMapping(value = "/api/v1/control") |
| 24 | public class ApiControlController { | 25 | public class ApiControlController { |
| @@ -102,4 +103,53 @@ public class ApiControlController { | @@ -102,4 +103,53 @@ public class ApiControlController { | ||
| 102 | throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage()); | 103 | throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage()); |
| 103 | } | 104 | } |
| 104 | } | 105 | } |
| 106 | + | ||
| 107 | + /** | ||
| 108 | + * 设备控制 - 预置位控制 | ||
| 109 | + * @param serial 设备编号 | ||
| 110 | + * @param code 通道编号,通过 /api/v1/device/channellist 获取的 ChannelList.ID, 该参数和 channel 二选一传递即可 | ||
| 111 | + * @param channel 通道序号, 默认值: 1 | ||
| 112 | + * @param command 控制指令 允许值: set, goto, remove | ||
| 113 | + * @param preset 预置位编号(1~255) | ||
| 114 | + * @param name 预置位名称, command=set 时有效 | ||
| 115 | + * @return | ||
| 116 | + */ | ||
| 117 | + @RequestMapping(value = "/preset") | ||
| 118 | + private void list(String serial,String command, | ||
| 119 | + @RequestParam(required = false)Integer channel, | ||
| 120 | + @RequestParam(required = false)String code, | ||
| 121 | + @RequestParam(required = false)String name, | ||
| 122 | + @RequestParam(required = false)Integer preset){ | ||
| 123 | + | ||
| 124 | + if (logger.isDebugEnabled()) { | ||
| 125 | + logger.debug("模拟接口> 预置位控制 API调用,deviceId:{} ,channelId:{} ,command:{} ,name:{} ,preset:{} ", | ||
| 126 | + serial, code, command, name, preset); | ||
| 127 | + } | ||
| 128 | + | ||
| 129 | + if (channel == null) {channel = 0;} | ||
| 130 | + Device device = storager.queryVideoDevice(serial); | ||
| 131 | + if (device == null) { | ||
| 132 | + throw new ControllerException(ErrorCode.ERROR100.getCode(), "device[ " + serial + " ]未找到"); | ||
| 133 | + } | ||
| 134 | + int cmdCode = 0; | ||
| 135 | + switch (command){ | ||
| 136 | + case "set": | ||
| 137 | + cmdCode = 129; | ||
| 138 | + break; | ||
| 139 | + case "goto": | ||
| 140 | + cmdCode = 130; | ||
| 141 | + break; | ||
| 142 | + case "remove": | ||
| 143 | + cmdCode = 131; | ||
| 144 | + break; | ||
| 145 | + default: | ||
| 146 | + break; | ||
| 147 | + } | ||
| 148 | + try { | ||
| 149 | + cmder.frontEndCmd(device, code, cmdCode, 0, preset, 0); | ||
| 150 | + } catch (SipException | InvalidArgumentException | ParseException e) { | ||
| 151 | + logger.error("[命令发送失败] 预置位控制: {}", e.getMessage()); | ||
| 152 | + throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage()); | ||
| 153 | + } | ||
| 154 | + } | ||
| 105 | } | 155 | } |
src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiController.java
| @@ -6,7 +6,6 @@ import org.slf4j.Logger; | @@ -6,7 +6,6 @@ import org.slf4j.Logger; | ||
| 6 | import org.slf4j.LoggerFactory; | 6 | import org.slf4j.LoggerFactory; |
| 7 | import org.springframework.beans.factory.annotation.Autowired; | 7 | import org.springframework.beans.factory.annotation.Autowired; |
| 8 | import org.springframework.stereotype.Controller; | 8 | import org.springframework.stereotype.Controller; |
| 9 | -import org.springframework.web.bind.annotation.CrossOrigin; | ||
| 10 | import org.springframework.web.bind.annotation.RequestMapping; | 9 | import org.springframework.web.bind.annotation.RequestMapping; |
| 11 | import org.springframework.web.bind.annotation.ResponseBody; | 10 | import org.springframework.web.bind.annotation.ResponseBody; |
| 12 | 11 | ||
| @@ -14,7 +13,7 @@ import org.springframework.web.bind.annotation.ResponseBody; | @@ -14,7 +13,7 @@ import org.springframework.web.bind.annotation.ResponseBody; | ||
| 14 | * API兼容:系统接口 | 13 | * API兼容:系统接口 |
| 15 | */ | 14 | */ |
| 16 | @Controller | 15 | @Controller |
| 17 | -@CrossOrigin | 16 | + |
| 18 | @RequestMapping(value = "/api/v1") | 17 | @RequestMapping(value = "/api/v1") |
| 19 | public class ApiController { | 18 | public class ApiController { |
| 20 | 19 |
src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiDeviceController.java
| @@ -2,25 +2,38 @@ package com.genersoft.iot.vmp.web.gb28181; | @@ -2,25 +2,38 @@ package com.genersoft.iot.vmp.web.gb28181; | ||
| 2 | 2 | ||
| 3 | import com.alibaba.fastjson2.JSONArray; | 3 | import com.alibaba.fastjson2.JSONArray; |
| 4 | import com.alibaba.fastjson2.JSONObject; | 4 | import com.alibaba.fastjson2.JSONObject; |
| 5 | +import com.genersoft.iot.vmp.conf.exception.ControllerException; | ||
| 5 | import com.genersoft.iot.vmp.gb28181.bean.Device; | 6 | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| 6 | -import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; | 7 | +import com.genersoft.iot.vmp.gb28181.bean.PresetQuerySipReq; |
| 8 | +import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; | ||
| 9 | +import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; | ||
| 10 | +import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; | ||
| 7 | import com.genersoft.iot.vmp.service.IDeviceService; | 11 | import com.genersoft.iot.vmp.service.IDeviceService; |
| 8 | import com.genersoft.iot.vmp.storager.IVideoManagerStorage; | 12 | import com.genersoft.iot.vmp.storager.IVideoManagerStorage; |
| 13 | +import com.genersoft.iot.vmp.vmanager.bean.DeferredResultEx; | ||
| 14 | +import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; | ||
| 15 | +import com.genersoft.iot.vmp.web.gb28181.dto.DeviceChannelExtend; | ||
| 9 | import com.github.pagehelper.PageInfo; | 16 | import com.github.pagehelper.PageInfo; |
| 10 | import org.slf4j.Logger; | 17 | import org.slf4j.Logger; |
| 11 | import org.slf4j.LoggerFactory; | 18 | import org.slf4j.LoggerFactory; |
| 12 | import org.springframework.beans.factory.annotation.Autowired; | 19 | import org.springframework.beans.factory.annotation.Autowired; |
| 20 | +import org.springframework.util.ObjectUtils; | ||
| 13 | import org.springframework.util.StringUtils; | 21 | import org.springframework.util.StringUtils; |
| 14 | -import org.springframework.web.bind.annotation.*; | 22 | +import org.springframework.web.bind.annotation.RequestMapping; |
| 23 | +import org.springframework.web.bind.annotation.RequestParam; | ||
| 24 | +import org.springframework.web.bind.annotation.RestController; | ||
| 25 | +import org.springframework.web.context.request.async.DeferredResult; | ||
| 15 | 26 | ||
| 16 | -import java.util.Arrays; | ||
| 17 | -import java.util.List; | 27 | +import javax.sip.InvalidArgumentException; |
| 28 | +import javax.sip.SipException; | ||
| 29 | +import java.text.ParseException; | ||
| 30 | +import java.util.*; | ||
| 18 | 31 | ||
| 19 | /** | 32 | /** |
| 20 | * API兼容:设备信息 | 33 | * API兼容:设备信息 |
| 21 | */ | 34 | */ |
| 22 | @SuppressWarnings("unchecked") | 35 | @SuppressWarnings("unchecked") |
| 23 | -@CrossOrigin | 36 | + |
| 24 | @RestController | 37 | @RestController |
| 25 | @RequestMapping(value = "/api/v1/device") | 38 | @RequestMapping(value = "/api/v1/device") |
| 26 | public class ApiDeviceController { | 39 | public class ApiDeviceController { |
| @@ -29,17 +42,15 @@ public class ApiDeviceController { | @@ -29,17 +42,15 @@ public class ApiDeviceController { | ||
| 29 | 42 | ||
| 30 | @Autowired | 43 | @Autowired |
| 31 | private IVideoManagerStorage storager; | 44 | private IVideoManagerStorage storager; |
| 45 | + | ||
| 46 | + @Autowired | ||
| 47 | + private SIPCommander cmder; | ||
| 32 | @Autowired | 48 | @Autowired |
| 33 | private IDeviceService deviceService; | 49 | private IDeviceService deviceService; |
| 34 | 50 | ||
| 35 | - // @Autowired | ||
| 36 | - // private SIPCommander cmder; | ||
| 37 | - | ||
| 38 | - // @Autowired | ||
| 39 | - // private DeferredResultHolder resultHolder; | 51 | + @Autowired |
| 52 | + private DeferredResultHolder resultHolder; | ||
| 40 | 53 | ||
| 41 | - // @Autowired | ||
| 42 | - // private DeviceOffLineDetector offLineDetector; | ||
| 43 | 54 | ||
| 44 | /** | 55 | /** |
| 45 | * 分页获取设备列表 现在直接返回,尚未实现分页 | 56 | * 分页获取设备列表 现在直接返回,尚未实现分页 |
| @@ -96,8 +107,8 @@ public class ApiDeviceController { | @@ -96,8 +107,8 @@ public class ApiDeviceController { | ||
| 96 | 107 | ||
| 97 | @RequestMapping(value = "/channellist") | 108 | @RequestMapping(value = "/channellist") |
| 98 | public JSONObject channellist( String serial, | 109 | public JSONObject channellist( String serial, |
| 99 | - @RequestParam(required = false)String code, | ||
| 100 | @RequestParam(required = false)String channel_type, | 110 | @RequestParam(required = false)String channel_type, |
| 111 | + @RequestParam(required = false)String code , | ||
| 101 | @RequestParam(required = false)String dir_serial , | 112 | @RequestParam(required = false)String dir_serial , |
| 102 | @RequestParam(required = false)Integer start, | 113 | @RequestParam(required = false)Integer start, |
| 103 | @RequestParam(required = false)Integer limit, | 114 | @RequestParam(required = false)Integer limit, |
| @@ -109,64 +120,138 @@ public class ApiDeviceController { | @@ -109,64 +120,138 @@ public class ApiDeviceController { | ||
| 109 | // } | 120 | // } |
| 110 | JSONObject result = new JSONObject(); | 121 | JSONObject result = new JSONObject(); |
| 111 | // 查询设备是否存在 | 122 | // 查询设备是否存在 |
| 112 | - Device device = storager.queryVideoDevice(serial); | ||
| 113 | - if (device == null) { | ||
| 114 | - result.put("ChannelCount", 0); | ||
| 115 | - result.put("ChannelList", "[]"); | ||
| 116 | - return result; | ||
| 117 | - } | ||
| 118 | - List<DeviceChannel> deviceChannels; | 123 | +// Device device = storager.queryVideoDevice(serial); |
| 124 | +// if (device == null) { | ||
| 125 | +// result.put("ChannelCount", 0); | ||
| 126 | +// result.put("ChannelList", "[]"); | ||
| 127 | +// return result; | ||
| 128 | +// } | ||
| 129 | + List<DeviceChannelExtend> deviceChannels; | ||
| 119 | List<String> channelIds = null; | 130 | List<String> channelIds = null; |
| 120 | if (!StringUtils.isEmpty(code)) { | 131 | if (!StringUtils.isEmpty(code)) { |
| 121 | String[] split = code.trim().split(","); | 132 | String[] split = code.trim().split(","); |
| 122 | channelIds = Arrays.asList(split); | 133 | channelIds = Arrays.asList(split); |
| 123 | } | 134 | } |
| 124 | - List<DeviceChannel> allDeviceChannelList = storager.queryChannelsByDeviceId(serial,online,channelIds); | 135 | + List<DeviceChannelExtend> allDeviceChannelList = storager.queryChannelsByDeviceId(serial,channelIds,online); |
| 125 | if (start == null || limit ==null) { | 136 | if (start == null || limit ==null) { |
| 126 | deviceChannels = allDeviceChannelList; | 137 | deviceChannels = allDeviceChannelList; |
| 127 | result.put("ChannelCount", deviceChannels.size()); | 138 | result.put("ChannelCount", deviceChannels.size()); |
| 128 | }else { | 139 | }else { |
| 129 | - deviceChannels = storager.queryChannelsByDeviceIdWithStartAndLimit(serial, null, null, online,start, limit,channelIds); | 140 | + deviceChannels = storager.queryChannelsByDeviceIdWithStartAndLimit(serial,channelIds, null, null, online,start, limit); |
| 130 | int total = allDeviceChannelList.size(); | 141 | int total = allDeviceChannelList.size(); |
| 131 | result.put("ChannelCount", total); | 142 | result.put("ChannelCount", total); |
| 132 | } | 143 | } |
| 133 | 144 | ||
| 134 | JSONArray channleJSONList = new JSONArray(); | 145 | JSONArray channleJSONList = new JSONArray(); |
| 135 | - for (DeviceChannel deviceChannel : deviceChannels) { | 146 | + for (DeviceChannelExtend deviceChannelExtend : deviceChannels) { |
| 136 | JSONObject deviceJOSNChannel = new JSONObject(); | 147 | JSONObject deviceJOSNChannel = new JSONObject(); |
| 137 | - deviceJOSNChannel.put("ID", deviceChannel.getChannelId()); | ||
| 138 | - deviceJOSNChannel.put("DeviceID", device.getDeviceId()); | ||
| 139 | - deviceJOSNChannel.put("DeviceName", device.getName()); | ||
| 140 | - deviceJOSNChannel.put("DeviceOnline", device.getOnline() == 1); | ||
| 141 | - deviceJOSNChannel.put("Channel", 0); // 自定义序号 | ||
| 142 | - deviceJOSNChannel.put("Name", deviceChannel.getName()); | 148 | + deviceJOSNChannel.put("ID", deviceChannelExtend.getChannelId()); |
| 149 | + deviceJOSNChannel.put("DeviceID", deviceChannelExtend.getDeviceId()); | ||
| 150 | + deviceJOSNChannel.put("DeviceName", deviceChannelExtend.getDeviceName()); | ||
| 151 | + deviceJOSNChannel.put("DeviceOnline", deviceChannelExtend.getDeviceOnline() == 1); | ||
| 152 | + deviceJOSNChannel.put("Channel", 0); // TODO 自定义序号 | ||
| 153 | + deviceJOSNChannel.put("Name", deviceChannelExtend.getName()); | ||
| 143 | deviceJOSNChannel.put("Custom", false); | 154 | deviceJOSNChannel.put("Custom", false); |
| 144 | deviceJOSNChannel.put("CustomName", ""); | 155 | deviceJOSNChannel.put("CustomName", ""); |
| 145 | - deviceJOSNChannel.put("SubCount", deviceChannel.getSubCount()); // 子节点数, SubCount > 0 表示该通道为子目录 | 156 | + deviceJOSNChannel.put("SubCount", deviceChannelExtend.getSubCount()); // TODO ? 子节点数, SubCount > 0 表示该通道为子目录 |
| 146 | deviceJOSNChannel.put("SnapURL", ""); | 157 | deviceJOSNChannel.put("SnapURL", ""); |
| 147 | - deviceJOSNChannel.put("Manufacturer ", deviceChannel.getManufacture()); | ||
| 148 | - deviceJOSNChannel.put("Model", deviceChannel.getModel()); | ||
| 149 | - deviceJOSNChannel.put("Owner", deviceChannel.getOwner()); | ||
| 150 | - deviceJOSNChannel.put("CivilCode", deviceChannel.getCivilCode()); | ||
| 151 | - deviceJOSNChannel.put("Address", deviceChannel.getAddress()); | ||
| 152 | - deviceJOSNChannel.put("Parental", deviceChannel.getParental()); // 当为通道设备时, 是否有通道子设备, 1-有,0-没有 | ||
| 153 | - deviceJOSNChannel.put("ParentID", deviceChannel.getParentId()); // 直接上级编号 | ||
| 154 | - deviceJOSNChannel.put("Secrecy", deviceChannel.getSecrecy()); | 158 | + deviceJOSNChannel.put("Manufacturer ", deviceChannelExtend.getManufacture()); |
| 159 | + deviceJOSNChannel.put("Model", deviceChannelExtend.getModel()); | ||
| 160 | + deviceJOSNChannel.put("Owner", deviceChannelExtend.getOwner()); | ||
| 161 | + deviceJOSNChannel.put("CivilCode", deviceChannelExtend.getCivilCode()); | ||
| 162 | + deviceJOSNChannel.put("Address", deviceChannelExtend.getAddress()); | ||
| 163 | + deviceJOSNChannel.put("Parental", deviceChannelExtend.getParental()); // 当为通道设备时, 是否有通道子设备, 1-有,0-没有 | ||
| 164 | + deviceJOSNChannel.put("ParentID", deviceChannelExtend.getParentId()); // 直接上级编号 | ||
| 165 | + deviceJOSNChannel.put("Secrecy", deviceChannelExtend.getSecrecy()); | ||
| 155 | deviceJOSNChannel.put("RegisterWay", 1); // 注册方式, 缺省为1, 允许值: 1, 2, 3 | 166 | deviceJOSNChannel.put("RegisterWay", 1); // 注册方式, 缺省为1, 允许值: 1, 2, 3 |
| 156 | - // 1-IETF RFC3261, | ||
| 157 | - // 2-基于口令的双向认证, | ||
| 158 | - // 3-基于数字证书的双向认证 | ||
| 159 | - deviceJOSNChannel.put("Status", deviceChannel.getStatus() == 1 ? "ON":"OFF"); | ||
| 160 | - deviceJOSNChannel.put("Longitude", deviceChannel.getLongitude()); | ||
| 161 | - deviceJOSNChannel.put("Latitude", deviceChannel.getLatitude()); | ||
| 162 | - deviceJOSNChannel.put("PTZType ", deviceChannel.getPTZType()); // 云台类型, 0 - 未知, 1 - 球机, 2 - 半球, | ||
| 163 | - // 3 - 固定枪机, 4 - 遥控枪机 | 167 | + // 1-IETF RFC3261, |
| 168 | + // 2-基于口令的双向认证, | ||
| 169 | + // 3-基于数字证书的双向认证 | ||
| 170 | + deviceJOSNChannel.put("Status", deviceChannelExtend.getStatus() == 1 ? "ON":"OFF"); | ||
| 171 | + deviceJOSNChannel.put("Longitude", deviceChannelExtend.getLongitude()); | ||
| 172 | + deviceJOSNChannel.put("Latitude", deviceChannelExtend.getLatitude()); | ||
| 173 | + deviceJOSNChannel.put("PTZType ", deviceChannelExtend.getPTZType()); // 云台类型, 0 - 未知, 1 - 球机, 2 - 半球, | ||
| 174 | + // 3 - 固定枪机, 4 - 遥控枪机 | ||
| 164 | deviceJOSNChannel.put("CustomPTZType", ""); | 175 | deviceJOSNChannel.put("CustomPTZType", ""); |
| 165 | - deviceJOSNChannel.put("StreamID", deviceChannel.getStreamId()); // StreamID 直播流ID, 有值表示正在直播 | 176 | + deviceJOSNChannel.put("StreamID", deviceChannelExtend.getStreamId()); // StreamID 直播流ID, 有值表示正在直播 |
| 166 | deviceJOSNChannel.put("NumOutputs ", -1); // 直播在线人数 | 177 | deviceJOSNChannel.put("NumOutputs ", -1); // 直播在线人数 |
| 167 | channleJSONList.add(deviceJOSNChannel); | 178 | channleJSONList.add(deviceJOSNChannel); |
| 168 | } | 179 | } |
| 169 | result.put("ChannelList", channleJSONList); | 180 | result.put("ChannelList", channleJSONList); |
| 170 | return result; | 181 | return result; |
| 171 | } | 182 | } |
| 183 | + | ||
| 184 | + /** | ||
| 185 | + * 设备信息 - 获取下级通道预置位 | ||
| 186 | + * @param serial 设备编号 | ||
| 187 | + * @param code 通道编号,通过 /api/v1/device/channellist 获取的 ChannelList.ID, 该参数和 channel 二选一传递即可 | ||
| 188 | + * @param channel 通道序号, 默认值: 1 | ||
| 189 | + * @param fill 是否填充空置预置位,当下级返回预置位,但不够255个时,自动填充空置预置位到255个, 默认值: true, 允许值: true, false | ||
| 190 | + * @param timeout 超时时间(秒) 默认值: 15 | ||
| 191 | + * @return | ||
| 192 | + */ | ||
| 193 | + @RequestMapping(value = "/fetchpreset") | ||
| 194 | + private DeferredResult<Object> list(String serial, | ||
| 195 | + @RequestParam(required = false)Integer channel, | ||
| 196 | + @RequestParam(required = false)String code, | ||
| 197 | + @RequestParam(required = false)Boolean fill, | ||
| 198 | + @RequestParam(required = false)Integer timeout){ | ||
| 199 | + | ||
| 200 | + if (logger.isDebugEnabled()) { | ||
| 201 | + logger.debug("<模拟接口> 获取下级通道预置位 API调用,deviceId:{} ,channel:{} ,code:{} ,fill:{} ,timeout:{} ", | ||
| 202 | + serial, channel, code, fill, timeout); | ||
| 203 | + } | ||
| 204 | + | ||
| 205 | + Device device = storager.queryVideoDevice(serial); | ||
| 206 | + String uuid = UUID.randomUUID().toString(); | ||
| 207 | + String key = DeferredResultHolder.CALLBACK_CMD_PRESETQUERY + (ObjectUtils.isEmpty(code) ? serial : code); | ||
| 208 | + DeferredResult<Object> result = new DeferredResult<> (timeout * 1000L); | ||
| 209 | + DeferredResultEx<Object> deferredResultEx = new DeferredResultEx<>(result); | ||
| 210 | + result.onTimeout(()->{ | ||
| 211 | + logger.warn("<模拟接口> 获取设备预置位超时"); | ||
| 212 | + // 释放rtpserver | ||
| 213 | + RequestMessage msg = new RequestMessage(); | ||
| 214 | + msg.setId(uuid); | ||
| 215 | + msg.setKey(key); | ||
| 216 | + msg.setData("wait for presetquery timeout["+timeout+"s]"); | ||
| 217 | + resultHolder.invokeResult(msg); | ||
| 218 | + }); | ||
| 219 | + if (resultHolder.exist(key, null)) { | ||
| 220 | + return result; | ||
| 221 | + } | ||
| 222 | + | ||
| 223 | + deferredResultEx.setFilter(filterResult->{ | ||
| 224 | + List<PresetQuerySipReq> presetQuerySipReqList = (List<PresetQuerySipReq>)filterResult; | ||
| 225 | + HashMap<String, Object> resultMap = new HashMap<>(); | ||
| 226 | + resultMap.put("DeviceID", code); | ||
| 227 | + resultMap.put("Result", "OK"); | ||
| 228 | + resultMap.put("SumNum", presetQuerySipReqList.size()); | ||
| 229 | + ArrayList<Map<String, Object>> presetItemList = new ArrayList<>(presetQuerySipReqList.size()); | ||
| 230 | + for (PresetQuerySipReq presetQuerySipReq : presetQuerySipReqList) { | ||
| 231 | + Map<String, Object> item = new HashMap<>(); | ||
| 232 | + item.put("PresetID", presetQuerySipReq.getPresetId()); | ||
| 233 | + item.put("PresetName", presetQuerySipReq.getPresetName()); | ||
| 234 | + item.put("PresetEnable", true); | ||
| 235 | + presetItemList.add(item); | ||
| 236 | + } | ||
| 237 | + resultMap.put("PresetItemList",presetItemList ); | ||
| 238 | + return resultMap; | ||
| 239 | + }); | ||
| 240 | + | ||
| 241 | + resultHolder.put(key, uuid, deferredResultEx); | ||
| 242 | + | ||
| 243 | + try { | ||
| 244 | + cmder.presetQuery(device, code, event -> { | ||
| 245 | + RequestMessage msg = new RequestMessage(); | ||
| 246 | + msg.setId(uuid); | ||
| 247 | + msg.setKey(key); | ||
| 248 | + msg.setData(String.format("获取设备预置位失败,错误码: %s, %s", event.statusCode, event.msg)); | ||
| 249 | + resultHolder.invokeResult(msg); | ||
| 250 | + }); | ||
| 251 | + } catch (InvalidArgumentException | SipException | ParseException e) { | ||
| 252 | + logger.error("[命令发送失败] 获取设备预置位: {}", e.getMessage()); | ||
| 253 | + throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage()); | ||
| 254 | + } | ||
| 255 | + return result; | ||
| 256 | + } | ||
| 172 | } | 257 | } |
src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiStreamController.java
| @@ -26,7 +26,7 @@ import java.text.ParseException; | @@ -26,7 +26,7 @@ import java.text.ParseException; | ||
| 26 | * API兼容:实时直播 | 26 | * API兼容:实时直播 |
| 27 | */ | 27 | */ |
| 28 | @SuppressWarnings(value = {"rawtypes", "unchecked"}) | 28 | @SuppressWarnings(value = {"rawtypes", "unchecked"}) |
| 29 | -@CrossOrigin | 29 | + |
| 30 | @RestController | 30 | @RestController |
| 31 | @RequestMapping(value = "/api/v1/stream") | 31 | @RequestMapping(value = "/api/v1/stream") |
| 32 | public class ApiStreamController { | 32 | public class ApiStreamController { |
src/main/java/com/genersoft/iot/vmp/web/gb28181/AuthController.java
| @@ -5,7 +5,7 @@ import com.genersoft.iot.vmp.storager.dao.dto.User; | @@ -5,7 +5,7 @@ import com.genersoft.iot.vmp.storager.dao.dto.User; | ||
| 5 | import org.springframework.beans.factory.annotation.Autowired; | 5 | import org.springframework.beans.factory.annotation.Autowired; |
| 6 | import org.springframework.web.bind.annotation.*; | 6 | import org.springframework.web.bind.annotation.*; |
| 7 | 7 | ||
| 8 | -@CrossOrigin | 8 | + |
| 9 | @RestController | 9 | @RestController |
| 10 | @RequestMapping(value = "/auth") | 10 | @RequestMapping(value = "/auth") |
| 11 | public class AuthController { | 11 | public class AuthController { |
src/main/java/com/genersoft/iot/vmp/web/gb28181/dto/DeviceChannelExtend.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.web.gb28181.dto; | ||
| 2 | + | ||
| 3 | +public class DeviceChannelExtend { | ||
| 4 | + | ||
| 5 | + | ||
| 6 | + /** | ||
| 7 | + * 数据库自增ID | ||
| 8 | + */ | ||
| 9 | + private int id; | ||
| 10 | + | ||
| 11 | + /** | ||
| 12 | + * 通道id | ||
| 13 | + */ | ||
| 14 | + private String channelId; | ||
| 15 | + | ||
| 16 | + /** | ||
| 17 | + * 设备id | ||
| 18 | + */ | ||
| 19 | + private String deviceId; | ||
| 20 | + | ||
| 21 | + /** | ||
| 22 | + * 通道名 | ||
| 23 | + */ | ||
| 24 | + private String name; | ||
| 25 | + | ||
| 26 | + private String deviceName; | ||
| 27 | + | ||
| 28 | + private int deviceOnline; | ||
| 29 | + | ||
| 30 | + /** | ||
| 31 | + * 生产厂商 | ||
| 32 | + */ | ||
| 33 | + private String manufacture; | ||
| 34 | + | ||
| 35 | + /** | ||
| 36 | + * 型号 | ||
| 37 | + */ | ||
| 38 | + private String model; | ||
| 39 | + | ||
| 40 | + /** | ||
| 41 | + * 设备归属 | ||
| 42 | + */ | ||
| 43 | + private String owner; | ||
| 44 | + | ||
| 45 | + /** | ||
| 46 | + * 行政区域 | ||
| 47 | + */ | ||
| 48 | + private String civilCode; | ||
| 49 | + | ||
| 50 | + /** | ||
| 51 | + * 警区 | ||
| 52 | + */ | ||
| 53 | + private String block; | ||
| 54 | + | ||
| 55 | + /** | ||
| 56 | + * 安装地址 | ||
| 57 | + */ | ||
| 58 | + private String address; | ||
| 59 | + | ||
| 60 | + /** | ||
| 61 | + * 是否有子设备 1有, 0没有 | ||
| 62 | + */ | ||
| 63 | + private int parental; | ||
| 64 | + | ||
| 65 | + /** | ||
| 66 | + * 父级id | ||
| 67 | + */ | ||
| 68 | + private String parentId; | ||
| 69 | + | ||
| 70 | + /** | ||
| 71 | + * 信令安全模式 缺省为0; 0:不采用; 2: S/MIME签名方式; 3: S/ MIME加密签名同时采用方式; 4:数字摘要方式 | ||
| 72 | + */ | ||
| 73 | + private int safetyWay; | ||
| 74 | + | ||
| 75 | + /** | ||
| 76 | + * 注册方式 缺省为1;1:符合IETFRFC3261标准的认证注册模 式; 2:基于口令的双向认证注册模式; 3:基于数字证书的双向认证注册模式 | ||
| 77 | + */ | ||
| 78 | + private int registerWay; | ||
| 79 | + | ||
| 80 | + /** | ||
| 81 | + * 证书序列号 | ||
| 82 | + */ | ||
| 83 | + private String certNum; | ||
| 84 | + | ||
| 85 | + /** | ||
| 86 | + * 证书有效标识 缺省为0;证书有效标识:0:无效1: 有效 | ||
| 87 | + */ | ||
| 88 | + private int certifiable; | ||
| 89 | + | ||
| 90 | + /** | ||
| 91 | + * 证书无效原因码 | ||
| 92 | + */ | ||
| 93 | + private int errCode; | ||
| 94 | + | ||
| 95 | + /** | ||
| 96 | + * 证书终止有效期 | ||
| 97 | + */ | ||
| 98 | + private String endTime; | ||
| 99 | + | ||
| 100 | + /** | ||
| 101 | + * 保密属性 缺省为0; 0:不涉密, 1:涉密 | ||
| 102 | + */ | ||
| 103 | + private String secrecy; | ||
| 104 | + | ||
| 105 | + /** | ||
| 106 | + * IP地址 | ||
| 107 | + */ | ||
| 108 | + private String ipAddress; | ||
| 109 | + | ||
| 110 | + /** | ||
| 111 | + * 端口号 | ||
| 112 | + */ | ||
| 113 | + private int port; | ||
| 114 | + | ||
| 115 | + /** | ||
| 116 | + * 密码 | ||
| 117 | + */ | ||
| 118 | + private String password; | ||
| 119 | + | ||
| 120 | + /** | ||
| 121 | + * 云台类型 | ||
| 122 | + */ | ||
| 123 | + private int PTZType; | ||
| 124 | + | ||
| 125 | + /** | ||
| 126 | + * 云台类型描述字符串 | ||
| 127 | + */ | ||
| 128 | + private String PTZTypeText; | ||
| 129 | + | ||
| 130 | + /** | ||
| 131 | + * 创建时间 | ||
| 132 | + */ | ||
| 133 | + private String createTime; | ||
| 134 | + | ||
| 135 | + /** | ||
| 136 | + * 更新时间 | ||
| 137 | + */ | ||
| 138 | + private String updateTime; | ||
| 139 | + | ||
| 140 | + /** | ||
| 141 | + * 在线/离线 | ||
| 142 | + * 1在线,0离线 | ||
| 143 | + * 默认在线 | ||
| 144 | + * 信令: | ||
| 145 | + * <Status>ON</Status> | ||
| 146 | + * <Status>OFF</Status> | ||
| 147 | + * 遇到过NVR下的IPC下发信令可以推流, 但是 Status 响应 OFF | ||
| 148 | + */ | ||
| 149 | + private int status; | ||
| 150 | + | ||
| 151 | + /** | ||
| 152 | + * 经度 | ||
| 153 | + */ | ||
| 154 | + private double longitude; | ||
| 155 | + | ||
| 156 | + /** | ||
| 157 | + * 纬度 | ||
| 158 | + */ | ||
| 159 | + private double latitude; | ||
| 160 | + | ||
| 161 | + /** | ||
| 162 | + * 经度 GCJ02 | ||
| 163 | + */ | ||
| 164 | + private double longitudeGcj02; | ||
| 165 | + | ||
| 166 | + /** | ||
| 167 | + * 纬度 GCJ02 | ||
| 168 | + */ | ||
| 169 | + private double latitudeGcj02; | ||
| 170 | + | ||
| 171 | + /** | ||
| 172 | + * 经度 WGS84 | ||
| 173 | + */ | ||
| 174 | + private double longitudeWgs84; | ||
| 175 | + | ||
| 176 | + /** | ||
| 177 | + * 纬度 WGS84 | ||
| 178 | + */ | ||
| 179 | + private double latitudeWgs84; | ||
| 180 | + | ||
| 181 | + /** | ||
| 182 | + * 子设备数 | ||
| 183 | + */ | ||
| 184 | + private int subCount; | ||
| 185 | + | ||
| 186 | + /** | ||
| 187 | + * 流唯一编号,存在表示正在直播 | ||
| 188 | + */ | ||
| 189 | + private String streamId; | ||
| 190 | + | ||
| 191 | + /** | ||
| 192 | + * 是否含有音频 | ||
| 193 | + */ | ||
| 194 | + private boolean hasAudio; | ||
| 195 | + | ||
| 196 | + /** | ||
| 197 | + * 标记通道的类型,0->国标通道 1->直播流通道 2->业务分组/虚拟组织/行政区划 | ||
| 198 | + */ | ||
| 199 | + private int channelType; | ||
| 200 | + | ||
| 201 | + /** | ||
| 202 | + * 业务分组 | ||
| 203 | + */ | ||
| 204 | + private String businessGroupId; | ||
| 205 | + | ||
| 206 | + /** | ||
| 207 | + * GPS的更新时间 | ||
| 208 | + */ | ||
| 209 | + private String gpsTime; | ||
| 210 | + | ||
| 211 | + public int getId() { | ||
| 212 | + return id; | ||
| 213 | + } | ||
| 214 | + | ||
| 215 | + public void setId(int id) { | ||
| 216 | + this.id = id; | ||
| 217 | + } | ||
| 218 | + | ||
| 219 | + public String getDeviceId() { | ||
| 220 | + return deviceId; | ||
| 221 | + } | ||
| 222 | + | ||
| 223 | + public void setDeviceId(String deviceId) { | ||
| 224 | + this.deviceId = deviceId; | ||
| 225 | + } | ||
| 226 | + | ||
| 227 | + public void setPTZType(int PTZType) { | ||
| 228 | + this.PTZType = PTZType; | ||
| 229 | + switch (PTZType) { | ||
| 230 | + case 0: | ||
| 231 | + this.PTZTypeText = "未知"; | ||
| 232 | + break; | ||
| 233 | + case 1: | ||
| 234 | + this.PTZTypeText = "球机"; | ||
| 235 | + break; | ||
| 236 | + case 2: | ||
| 237 | + this.PTZTypeText = "半球"; | ||
| 238 | + break; | ||
| 239 | + case 3: | ||
| 240 | + this.PTZTypeText = "固定枪机"; | ||
| 241 | + break; | ||
| 242 | + case 4: | ||
| 243 | + this.PTZTypeText = "遥控枪机"; | ||
| 244 | + break; | ||
| 245 | + } | ||
| 246 | + } | ||
| 247 | + | ||
| 248 | + public String getChannelId() { | ||
| 249 | + return channelId; | ||
| 250 | + } | ||
| 251 | + | ||
| 252 | + public void setChannelId(String channelId) { | ||
| 253 | + this.channelId = channelId; | ||
| 254 | + } | ||
| 255 | + | ||
| 256 | + public String getName() { | ||
| 257 | + return name; | ||
| 258 | + } | ||
| 259 | + | ||
| 260 | + public void setName(String name) { | ||
| 261 | + this.name = name; | ||
| 262 | + } | ||
| 263 | + | ||
| 264 | + public String getManufacture() { | ||
| 265 | + return manufacture; | ||
| 266 | + } | ||
| 267 | + | ||
| 268 | + public void setManufacture(String manufacture) { | ||
| 269 | + this.manufacture = manufacture; | ||
| 270 | + } | ||
| 271 | + | ||
| 272 | + public String getModel() { | ||
| 273 | + return model; | ||
| 274 | + } | ||
| 275 | + | ||
| 276 | + public void setModel(String model) { | ||
| 277 | + this.model = model; | ||
| 278 | + } | ||
| 279 | + | ||
| 280 | + public String getOwner() { | ||
| 281 | + return owner; | ||
| 282 | + } | ||
| 283 | + | ||
| 284 | + public void setOwner(String owner) { | ||
| 285 | + this.owner = owner; | ||
| 286 | + } | ||
| 287 | + | ||
| 288 | + public String getCivilCode() { | ||
| 289 | + return civilCode; | ||
| 290 | + } | ||
| 291 | + | ||
| 292 | + public void setCivilCode(String civilCode) { | ||
| 293 | + this.civilCode = civilCode; | ||
| 294 | + } | ||
| 295 | + | ||
| 296 | + public String getBlock() { | ||
| 297 | + return block; | ||
| 298 | + } | ||
| 299 | + | ||
| 300 | + public void setBlock(String block) { | ||
| 301 | + this.block = block; | ||
| 302 | + } | ||
| 303 | + | ||
| 304 | + public String getAddress() { | ||
| 305 | + return address; | ||
| 306 | + } | ||
| 307 | + | ||
| 308 | + public void setAddress(String address) { | ||
| 309 | + this.address = address; | ||
| 310 | + } | ||
| 311 | + | ||
| 312 | + public int getParental() { | ||
| 313 | + return parental; | ||
| 314 | + } | ||
| 315 | + | ||
| 316 | + public void setParental(int parental) { | ||
| 317 | + this.parental = parental; | ||
| 318 | + } | ||
| 319 | + | ||
| 320 | + public String getParentId() { | ||
| 321 | + return parentId; | ||
| 322 | + } | ||
| 323 | + | ||
| 324 | + public void setParentId(String parentId) { | ||
| 325 | + this.parentId = parentId; | ||
| 326 | + } | ||
| 327 | + | ||
| 328 | + public int getSafetyWay() { | ||
| 329 | + return safetyWay; | ||
| 330 | + } | ||
| 331 | + | ||
| 332 | + public void setSafetyWay(int safetyWay) { | ||
| 333 | + this.safetyWay = safetyWay; | ||
| 334 | + } | ||
| 335 | + | ||
| 336 | + public int getRegisterWay() { | ||
| 337 | + return registerWay; | ||
| 338 | + } | ||
| 339 | + | ||
| 340 | + public void setRegisterWay(int registerWay) { | ||
| 341 | + this.registerWay = registerWay; | ||
| 342 | + } | ||
| 343 | + | ||
| 344 | + public String getCertNum() { | ||
| 345 | + return certNum; | ||
| 346 | + } | ||
| 347 | + | ||
| 348 | + public void setCertNum(String certNum) { | ||
| 349 | + this.certNum = certNum; | ||
| 350 | + } | ||
| 351 | + | ||
| 352 | + public int getCertifiable() { | ||
| 353 | + return certifiable; | ||
| 354 | + } | ||
| 355 | + | ||
| 356 | + public void setCertifiable(int certifiable) { | ||
| 357 | + this.certifiable = certifiable; | ||
| 358 | + } | ||
| 359 | + | ||
| 360 | + public int getErrCode() { | ||
| 361 | + return errCode; | ||
| 362 | + } | ||
| 363 | + | ||
| 364 | + public void setErrCode(int errCode) { | ||
| 365 | + this.errCode = errCode; | ||
| 366 | + } | ||
| 367 | + | ||
| 368 | + public String getEndTime() { | ||
| 369 | + return endTime; | ||
| 370 | + } | ||
| 371 | + | ||
| 372 | + public void setEndTime(String endTime) { | ||
| 373 | + this.endTime = endTime; | ||
| 374 | + } | ||
| 375 | + | ||
| 376 | + public String getSecrecy() { | ||
| 377 | + return secrecy; | ||
| 378 | + } | ||
| 379 | + | ||
| 380 | + public void setSecrecy(String secrecy) { | ||
| 381 | + this.secrecy = secrecy; | ||
| 382 | + } | ||
| 383 | + | ||
| 384 | + public String getIpAddress() { | ||
| 385 | + return ipAddress; | ||
| 386 | + } | ||
| 387 | + | ||
| 388 | + public void setIpAddress(String ipAddress) { | ||
| 389 | + this.ipAddress = ipAddress; | ||
| 390 | + } | ||
| 391 | + | ||
| 392 | + public int getPort() { | ||
| 393 | + return port; | ||
| 394 | + } | ||
| 395 | + | ||
| 396 | + public void setPort(int port) { | ||
| 397 | + this.port = port; | ||
| 398 | + } | ||
| 399 | + | ||
| 400 | + public String getPassword() { | ||
| 401 | + return password; | ||
| 402 | + } | ||
| 403 | + | ||
| 404 | + public void setPassword(String password) { | ||
| 405 | + this.password = password; | ||
| 406 | + } | ||
| 407 | + | ||
| 408 | + public int getPTZType() { | ||
| 409 | + return PTZType; | ||
| 410 | + } | ||
| 411 | + | ||
| 412 | + public String getPTZTypeText() { | ||
| 413 | + return PTZTypeText; | ||
| 414 | + } | ||
| 415 | + | ||
| 416 | + public void setPTZTypeText(String PTZTypeText) { | ||
| 417 | + this.PTZTypeText = PTZTypeText; | ||
| 418 | + } | ||
| 419 | + | ||
| 420 | + public int getStatus() { | ||
| 421 | + return status; | ||
| 422 | + } | ||
| 423 | + | ||
| 424 | + public void setStatus(int status) { | ||
| 425 | + this.status = status; | ||
| 426 | + } | ||
| 427 | + | ||
| 428 | + public double getLongitude() { | ||
| 429 | + return longitude; | ||
| 430 | + } | ||
| 431 | + | ||
| 432 | + public void setLongitude(double longitude) { | ||
| 433 | + this.longitude = longitude; | ||
| 434 | + } | ||
| 435 | + | ||
| 436 | + public double getLatitude() { | ||
| 437 | + return latitude; | ||
| 438 | + } | ||
| 439 | + | ||
| 440 | + public void setLatitude(double latitude) { | ||
| 441 | + this.latitude = latitude; | ||
| 442 | + } | ||
| 443 | + | ||
| 444 | + public double getLongitudeGcj02() { | ||
| 445 | + return longitudeGcj02; | ||
| 446 | + } | ||
| 447 | + | ||
| 448 | + public void setLongitudeGcj02(double longitudeGcj02) { | ||
| 449 | + this.longitudeGcj02 = longitudeGcj02; | ||
| 450 | + } | ||
| 451 | + | ||
| 452 | + public double getLatitudeGcj02() { | ||
| 453 | + return latitudeGcj02; | ||
| 454 | + } | ||
| 455 | + | ||
| 456 | + public void setLatitudeGcj02(double latitudeGcj02) { | ||
| 457 | + this.latitudeGcj02 = latitudeGcj02; | ||
| 458 | + } | ||
| 459 | + | ||
| 460 | + public double getLongitudeWgs84() { | ||
| 461 | + return longitudeWgs84; | ||
| 462 | + } | ||
| 463 | + | ||
| 464 | + public void setLongitudeWgs84(double longitudeWgs84) { | ||
| 465 | + this.longitudeWgs84 = longitudeWgs84; | ||
| 466 | + } | ||
| 467 | + | ||
| 468 | + public double getLatitudeWgs84() { | ||
| 469 | + return latitudeWgs84; | ||
| 470 | + } | ||
| 471 | + | ||
| 472 | + public void setLatitudeWgs84(double latitudeWgs84) { | ||
| 473 | + this.latitudeWgs84 = latitudeWgs84; | ||
| 474 | + } | ||
| 475 | + | ||
| 476 | + public int getSubCount() { | ||
| 477 | + return subCount; | ||
| 478 | + } | ||
| 479 | + | ||
| 480 | + public void setSubCount(int subCount) { | ||
| 481 | + this.subCount = subCount; | ||
| 482 | + } | ||
| 483 | + | ||
| 484 | + public boolean isHasAudio() { | ||
| 485 | + return hasAudio; | ||
| 486 | + } | ||
| 487 | + | ||
| 488 | + public void setHasAudio(boolean hasAudio) { | ||
| 489 | + this.hasAudio = hasAudio; | ||
| 490 | + } | ||
| 491 | + | ||
| 492 | + public String getStreamId() { | ||
| 493 | + return streamId; | ||
| 494 | + } | ||
| 495 | + | ||
| 496 | + public void setStreamId(String streamId) { | ||
| 497 | + this.streamId = streamId; | ||
| 498 | + } | ||
| 499 | + | ||
| 500 | + public String getCreateTime() { | ||
| 501 | + return createTime; | ||
| 502 | + } | ||
| 503 | + | ||
| 504 | + public void setCreateTime(String createTime) { | ||
| 505 | + this.createTime = createTime; | ||
| 506 | + } | ||
| 507 | + | ||
| 508 | + public String getUpdateTime() { | ||
| 509 | + return updateTime; | ||
| 510 | + } | ||
| 511 | + | ||
| 512 | + public void setUpdateTime(String updateTime) { | ||
| 513 | + this.updateTime = updateTime; | ||
| 514 | + } | ||
| 515 | + | ||
| 516 | + public int getChannelType() { | ||
| 517 | + return channelType; | ||
| 518 | + } | ||
| 519 | + | ||
| 520 | + public void setChannelType(int channelType) { | ||
| 521 | + this.channelType = channelType; | ||
| 522 | + } | ||
| 523 | + | ||
| 524 | + public String getBusinessGroupId() { | ||
| 525 | + return businessGroupId; | ||
| 526 | + } | ||
| 527 | + | ||
| 528 | + public void setBusinessGroupId(String businessGroupId) { | ||
| 529 | + this.businessGroupId = businessGroupId; | ||
| 530 | + } | ||
| 531 | + | ||
| 532 | + public String getGpsTime() { | ||
| 533 | + return gpsTime; | ||
| 534 | + } | ||
| 535 | + | ||
| 536 | + public void setGpsTime(String gpsTime) { | ||
| 537 | + this.gpsTime = gpsTime; | ||
| 538 | + } | ||
| 539 | + | ||
| 540 | + public String getDeviceName() { | ||
| 541 | + return deviceName; | ||
| 542 | + } | ||
| 543 | + | ||
| 544 | + public void setDeviceName(String deviceName) { | ||
| 545 | + this.deviceName = deviceName; | ||
| 546 | + } | ||
| 547 | + | ||
| 548 | + public int getDeviceOnline() { | ||
| 549 | + return deviceOnline; | ||
| 550 | + } | ||
| 551 | + | ||
| 552 | + public void setDeviceOnline(int deviceOnline) { | ||
| 553 | + this.deviceOnline = deviceOnline; | ||
| 554 | + } | ||
| 555 | +} |
src/main/resources/all-application.yml
| @@ -30,44 +30,19 @@ spring: | @@ -30,44 +30,19 @@ spring: | ||
| 30 | poolMaxWait: 5 | 30 | poolMaxWait: 5 |
| 31 | # [必选] jdbc数据库配置 | 31 | # [必选] jdbc数据库配置 |
| 32 | datasource: | 32 | datasource: |
| 33 | - type: com.alibaba.druid.pool.DruidDataSource | 33 | + type: com.zaxxer.hikari.HikariDataSource |
| 34 | driver-class-name: com.mysql.cj.jdbc.Driver | 34 | driver-class-name: com.mysql.cj.jdbc.Driver |
| 35 | url: jdbc:mysql://127.0.0.1:3306/wvp2?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&serverTimezone=PRC&useSSL=false&allowMultiQueries=true | 35 | url: jdbc:mysql://127.0.0.1:3306/wvp2?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&serverTimezone=PRC&useSSL=false&allowMultiQueries=true |
| 36 | username: root | 36 | username: root |
| 37 | password: root123 | 37 | password: root123 |
| 38 | - druid: | 38 | + hikari: |
| 39 | + connection-timeout: 20000 # 是客户端等待连接池连接的最大毫秒数 | ||
| 39 | initialSize: 10 # 连接池初始化连接数 | 40 | initialSize: 10 # 连接池初始化连接数 |
| 40 | - maxActive: 200 # 连接池最大连接数 | ||
| 41 | - minIdle: 5 # 连接池最小空闲连接数 | ||
| 42 | - maxWait: 60000 # 获取连接时最大等待时间,单位毫秒。配置了maxWait之后,缺省启用公平锁,并发效率会有所下降,如果需要可以通过配置useUnfairLock属性为true使用非公平锁。 | ||
| 43 | - keepAlive: true # 连接池中的minIdle数量以内的连接,空闲时间超过minEvictableIdleTimeMillis,则会执行keepAlive操作。 | ||
| 44 | - validationQuery: select 1 # 检测连接是否有效sql,要求是查询语句,常用select 'x'。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会起作用。 | ||
| 45 | - testWhileIdle: true # 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。 | ||
| 46 | - testOnBorrow: false # 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。 | ||
| 47 | - testOnReturn: false # 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。 | ||
| 48 | - poolPreparedStatements: false # 是否開啟PSCache,並且指定每個連線上PSCache的大小 | ||
| 49 | - timeBetweenEvictionRunsMillis: 60000 # 配置間隔多久才進行一次檢測,檢測需要關閉的空閒連線,單位是毫秒 | ||
| 50 | - minEvictableIdleTimeMillis: 300000 # 配置一個連線在池中最小生存的時間,單位是毫秒 | ||
| 51 | - filters: stat,slf4j # 配置监控统计拦截的filters,监控统计用的filter:sta, 日志用的filter:log4j | ||
| 52 | - useGlobalDataSourceStat: true # 合并多个DruidDataSource的监控数据 | ||
| 53 | - # 通过connectProperties属性来打开mergeSql功能;慢SQL记录 | ||
| 54 | - connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=1000 | ||
| 55 | - #stat-view-servlet.url-pattern: /admin/druid/* | 41 | + maximum-pool-size: 200 # 连接池最大连接数 |
| 42 | + minimum-idle: 5 # 连接池最小空闲连接数 | ||
| 43 | + idle-timeout: 300000 # 允许连接在连接池中空闲的最长时间(以毫秒为单位) | ||
| 44 | + max-lifetime: 1200000 # 是池中连接关闭后的最长生命周期(以毫秒为单位) | ||
| 56 | 45 | ||
| 57 | -# druid管理监控页面的一些配置 | ||
| 58 | -rj-druid-manage: | ||
| 59 | - allow: # 访问druid监控页面的IP白名单 | ||
| 60 | - deny: 192.168.1.100 # 访问druid监控页面IP黑名单 | ||
| 61 | - loginUsername: rjAdmin # 访问druid监控页面账号 | ||
| 62 | - loginPassword: rj@2022 # 访问druid监控页面密码 | ||
| 63 | - | ||
| 64 | -#mybatis: | ||
| 65 | -# configuration: | ||
| 66 | -# # 这个配置会将执行的sql打印出来,在开发或测试的时候可以用 | ||
| 67 | -# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl | ||
| 68 | -# # 返回类型为Map,显示null对应的字段 | ||
| 69 | -# call-setters-on-nulls: true | ||
| 70 | -## [可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口 | ||
| 71 | 46 | ||
| 72 | # [可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口 | 47 | # [可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口 |
| 73 | server: | 48 | server: |
| @@ -90,10 +65,10 @@ server: | @@ -90,10 +65,10 @@ server: | ||
| 90 | 65 | ||
| 91 | # 作为28181服务器的配置 | 66 | # 作为28181服务器的配置 |
| 92 | sip: | 67 | sip: |
| 93 | - # [必须修改] 本机的IP, 必须是网卡上的IP,用于sip下协议栈监听ip,如果监听所有设置为0.0.0.0 | ||
| 94 | - monitor-ip: 0.0.0.0 | ||
| 95 | # [必须修改] 本机的IP | 68 | # [必须修改] 本机的IP |
| 96 | ip: 192.168.0.100 | 69 | ip: 192.168.0.100 |
| 70 | + # [可选] 没有任何业务需求,仅仅是在前端展示的时候用 | ||
| 71 | + show-ip: 192.168.0.100 | ||
| 97 | # [可选] 28181服务监听的端口 | 72 | # [可选] 28181服务监听的端口 |
| 98 | port: 5060 | 73 | port: 5060 |
| 99 | # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) | 74 | # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) |
| @@ -203,6 +178,14 @@ user-settings: | @@ -203,6 +178,14 @@ user-settings: | ||
| 203 | sip-log: true | 178 | sip-log: true |
| 204 | # 收到ack消息后开始发流,默认false, 回复200ok后直接开始发流 | 179 | # 收到ack消息后开始发流,默认false, 回复200ok后直接开始发流 |
| 205 | push-stream-after-ack: false | 180 | push-stream-after-ack: false |
| 181 | + # 消息通道功能-缺少国标ID是否给所有上级发送消息 | ||
| 182 | + send-to-platforms-when-id-lost: true | ||
| 183 | + # 保持通道状态,不接受notify通道状态变化, 兼容海康平台发送错误消息 | ||
| 184 | + refuse-channel-status-channel-form-notify: false | ||
| 185 | + # 跨域配置,配置你访问前端页面的地址即可, 可以配置多个 | ||
| 186 | + allowed-origins: | ||
| 187 | + - http://localhost:8008 | ||
| 188 | + - http://192.168.1.3:8008 | ||
| 206 | 189 | ||
| 207 | # 关闭在线文档(生产环境建议关闭) | 190 | # 关闭在线文档(生产环境建议关闭) |
| 208 | springdoc: | 191 | springdoc: |
web_src/build/utils.js
| @@ -47,8 +47,7 @@ exports.cssLoaders = function (options) { | @@ -47,8 +47,7 @@ exports.cssLoaders = function (options) { | ||
| 47 | if (options.extract) { | 47 | if (options.extract) { |
| 48 | return ExtractTextPlugin.extract({ | 48 | return ExtractTextPlugin.extract({ |
| 49 | use: loaders, | 49 | use: loaders, |
| 50 | - fallback: 'vue-style-loader', | ||
| 51 | - publicPath: '../../' | 50 | + fallback: 'vue-style-loader' |
| 52 | }) | 51 | }) |
| 53 | } else { | 52 | } else { |
| 54 | return ['vue-style-loader'].concat(loaders) | 53 | return ['vue-style-loader'].concat(loaders) |
web_src/config/index.js
| @@ -8,8 +8,8 @@ module.exports = { | @@ -8,8 +8,8 @@ module.exports = { | ||
| 8 | dev: { | 8 | dev: { |
| 9 | 9 | ||
| 10 | // Paths | 10 | // Paths |
| 11 | - assetsSubDirectory: './static', | ||
| 12 | - assetsPublicPath: './', | 11 | + assetsSubDirectory: 'static', |
| 12 | + assetsPublicPath: '/', | ||
| 13 | proxyTable: { | 13 | proxyTable: { |
| 14 | '/debug': { | 14 | '/debug': { |
| 15 | target: 'https://default.wvp-pro.cn:18082', | 15 | target: 'https://default.wvp-pro.cn:18082', |
| @@ -61,7 +61,7 @@ module.exports = { | @@ -61,7 +61,7 @@ module.exports = { | ||
| 61 | // Paths | 61 | // Paths |
| 62 | assetsRoot: path.resolve(__dirname, '../../src/main/resources/static/'), | 62 | assetsRoot: path.resolve(__dirname, '../../src/main/resources/static/'), |
| 63 | assetsSubDirectory: './static', | 63 | assetsSubDirectory: './static', |
| 64 | - assetsPublicPath: './', | 64 | + assetsPublicPath: '/', |
| 65 | 65 | ||
| 66 | /** | 66 | /** |
| 67 | * Source Maps | 67 | * Source Maps |
web_src/index.html
| @@ -13,7 +13,8 @@ | @@ -13,7 +13,8 @@ | ||
| 13 | <script type="text/javascript" src="./static/js/EasyWasmPlayer.js"></script> | 13 | <script type="text/javascript" src="./static/js/EasyWasmPlayer.js"></script> |
| 14 | <script type="text/javascript" src="./static/js/liveplayer-lib.min.js"></script> | 14 | <script type="text/javascript" src="./static/js/liveplayer-lib.min.js"></script> |
| 15 | <script type="text/javascript" src="./static/js/ZLMRTCClient.js"></script> | 15 | <script type="text/javascript" src="./static/js/ZLMRTCClient.js"></script> |
| 16 | - <script type="text/javascript" src="./static/js/mapConfig.js"></script> | 16 | + <script type="text/javascript" src="./static/js/config.js"></script> |
| 17 | <div id="app"></div> | 17 | <div id="app"></div> |
| 18 | + | ||
| 18 | </body> | 19 | </body> |
| 19 | </html> | 20 | </html> |
web_src/package-lock.json
| @@ -23,7 +23,7 @@ | @@ -23,7 +23,7 @@ | ||
| 23 | "vue-clipboard2": "^0.3.1", | 23 | "vue-clipboard2": "^0.3.1", |
| 24 | "vue-clipboards": "^1.3.0", | 24 | "vue-clipboards": "^1.3.0", |
| 25 | "vue-contextmenujs": "^1.3.13", | 25 | "vue-contextmenujs": "^1.3.13", |
| 26 | - "vue-cookies": "^1.7.4", | 26 | + "vue-cookies": "^1.8.3", |
| 27 | "vue-giant-tree": "^0.1.5", | 27 | "vue-giant-tree": "^0.1.5", |
| 28 | "vue-router": "^3.1.6", | 28 | "vue-router": "^3.1.6", |
| 29 | "vue-ztree-2.0": "^1.0.4" | 29 | "vue-ztree-2.0": "^1.0.4" |
| @@ -13135,9 +13135,9 @@ | @@ -13135,9 +13135,9 @@ | ||
| 13135 | "integrity": "sha1-O9rgI8e9QgleeNpCWAACUNUKuO8=" | 13135 | "integrity": "sha1-O9rgI8e9QgleeNpCWAACUNUKuO8=" |
| 13136 | }, | 13136 | }, |
| 13137 | "node_modules/vue-cookies": { | 13137 | "node_modules/vue-cookies": { |
| 13138 | - "version": "1.7.4", | ||
| 13139 | - "resolved": "https://registry.npm.taobao.org/vue-cookies/download/vue-cookies-1.7.4.tgz?cache=0&sync_timestamp=1598941352058&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue-cookies%2Fdownload%2Fvue-cookies-1.7.4.tgz", | ||
| 13140 | - "integrity": "sha1-0kHQoEMdoHlYN2UdELTXPnyNPo0=" | 13138 | + "version": "1.8.3", |
| 13139 | + "resolved": "https://registry.npmmirror.com/vue-cookies/-/vue-cookies-1.8.3.tgz", | ||
| 13140 | + "integrity": "sha512-VBRsyRMVdahBgFfh389TMHPmDdr4URDJNMk4FKSCfuNITs7+jitBDhwyL4RJd3WUsfOYNNjPAkfbehyH9AFuoA==" | ||
| 13141 | }, | 13141 | }, |
| 13142 | "node_modules/vue-giant-tree": { | 13142 | "node_modules/vue-giant-tree": { |
| 13143 | "version": "0.1.5", | 13143 | "version": "0.1.5", |
| @@ -25489,9 +25489,9 @@ | @@ -25489,9 +25489,9 @@ | ||
| 25489 | "integrity": "sha1-O9rgI8e9QgleeNpCWAACUNUKuO8=" | 25489 | "integrity": "sha1-O9rgI8e9QgleeNpCWAACUNUKuO8=" |
| 25490 | }, | 25490 | }, |
| 25491 | "vue-cookies": { | 25491 | "vue-cookies": { |
| 25492 | - "version": "1.7.4", | ||
| 25493 | - "resolved": "https://registry.npm.taobao.org/vue-cookies/download/vue-cookies-1.7.4.tgz?cache=0&sync_timestamp=1598941352058&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue-cookies%2Fdownload%2Fvue-cookies-1.7.4.tgz", | ||
| 25494 | - "integrity": "sha1-0kHQoEMdoHlYN2UdELTXPnyNPo0=" | 25492 | + "version": "1.8.3", |
| 25493 | + "resolved": "https://registry.npmmirror.com/vue-cookies/-/vue-cookies-1.8.3.tgz", | ||
| 25494 | + "integrity": "sha512-VBRsyRMVdahBgFfh389TMHPmDdr4URDJNMk4FKSCfuNITs7+jitBDhwyL4RJd3WUsfOYNNjPAkfbehyH9AFuoA==" | ||
| 25495 | }, | 25495 | }, |
| 25496 | "vue-giant-tree": { | 25496 | "vue-giant-tree": { |
| 25497 | "version": "0.1.5", | 25497 | "version": "0.1.5", |
web_src/package.json
| @@ -25,7 +25,7 @@ | @@ -25,7 +25,7 @@ | ||
| 25 | "vue-clipboard2": "^0.3.1", | 25 | "vue-clipboard2": "^0.3.1", |
| 26 | "vue-clipboards": "^1.3.0", | 26 | "vue-clipboards": "^1.3.0", |
| 27 | "vue-contextmenujs": "^1.3.13", | 27 | "vue-contextmenujs": "^1.3.13", |
| 28 | - "vue-cookies": "^1.7.4", | 28 | + "vue-cookies": "^1.8.3", |
| 29 | "vue-giant-tree": "^0.1.5", | 29 | "vue-giant-tree": "^0.1.5", |
| 30 | "vue-router": "^3.1.6", | 30 | "vue-router": "^3.1.6", |
| 31 | "vue-ztree-2.0": "^1.0.4" | 31 | "vue-ztree-2.0": "^1.0.4" |
web_src/src/App.vue
| @@ -5,6 +5,7 @@ | @@ -5,6 +5,7 @@ | ||
| 5 | </template> | 5 | </template> |
| 6 | 6 | ||
| 7 | <script> | 7 | <script> |
| 8 | +import userService from './components/service/UserService' | ||
| 8 | export default { | 9 | export default { |
| 9 | name: 'app', | 10 | name: 'app', |
| 10 | data(){ | 11 | data(){ |
| @@ -19,7 +20,7 @@ export default { | @@ -19,7 +20,7 @@ export default { | ||
| 19 | } | 20 | } |
| 20 | }, | 21 | }, |
| 21 | created() { | 22 | created() { |
| 22 | - if(!this.$cookies.get("session")){ | 23 | + if (userService.getToken() == null){ |
| 23 | //如果没有登录状态则跳转到登录页 | 24 | //如果没有登录状态则跳转到登录页 |
| 24 | this.$router.push('/login'); | 25 | this.$router.push('/login'); |
| 25 | } | 26 | } |
| @@ -33,28 +34,14 @@ export default { | @@ -33,28 +34,14 @@ export default { | ||
| 33 | // this.getUserInfo(); | 34 | // this.getUserInfo(); |
| 34 | }, | 35 | }, |
| 35 | methods: { | 36 | methods: { |
| 36 | - //请求用户的一些信息 | ||
| 37 | - getUserInfo(){ | ||
| 38 | - var userinfo = this.$cookies.get("session"); | ||
| 39 | - }, | ||
| 40 | checkLogin(){ | 37 | checkLogin(){ |
| 41 | //检查是否存在session | 38 | //检查是否存在session |
| 42 | - //cookie操作方法在源码里有或者参考网上的即可 | ||
| 43 | - if(!this.$cookies.get("session")){ | 39 | + if (userService.getToken() == null){ |
| 44 | //如果没有登录状态则跳转到登录页 | 40 | //如果没有登录状态则跳转到登录页 |
| 45 | - this.$router.push('/login'); | 41 | + // this.$router.push('/login'); |
| 46 | } | 42 | } |
| 43 | + | ||
| 47 | }, | 44 | }, |
| 48 | - getCookie: function (cname) { | ||
| 49 | - var name = cname + "="; | ||
| 50 | - var ca = document.cookie.split(';'); | ||
| 51 | - for (var i = 0; i < ca.length; i++) { | ||
| 52 | - var c = ca[i]; | ||
| 53 | - while (c.charAt(0) == ' ') c = c.substring(1); | ||
| 54 | - if (c.indexOf(name) != -1) return c.substring(name.length, c.length); | ||
| 55 | - } | ||
| 56 | - return ""; | ||
| 57 | - } | ||
| 58 | }, | 45 | }, |
| 59 | components: {} | 46 | components: {} |
| 60 | }; | 47 | }; |
web_src/src/components/CloudRecord.vue
| @@ -133,7 +133,7 @@ | @@ -133,7 +133,7 @@ | ||
| 133 | let that = this; | 133 | let that = this; |
| 134 | this.$axios({ | 134 | this.$axios({ |
| 135 | method: 'get', | 135 | method: 'get', |
| 136 | - url:`./record_proxy/${that.mediaServerId}/api/record/list`, | 136 | + url:`/record_proxy/${that.mediaServerId}/api/record/list`, |
| 137 | params: { | 137 | params: { |
| 138 | page: that.currentPage, | 138 | page: that.currentPage, |
| 139 | count: that.count | 139 | count: that.count |
| @@ -185,7 +185,7 @@ | @@ -185,7 +185,7 @@ | ||
| 185 | let that = this; | 185 | let that = this; |
| 186 | this.$axios({ | 186 | this.$axios({ |
| 187 | method: 'delete', | 187 | method: 'delete', |
| 188 | - url:`./record_proxy/api/record/delete`, | 188 | + url:`/record_proxy/api/record/delete`, |
| 189 | params: { | 189 | params: { |
| 190 | page: that.currentPage, | 190 | page: that.currentPage, |
| 191 | count: that.count | 191 | count: that.count |
web_src/src/components/CloudRecordDetail.vue
| @@ -18,7 +18,7 @@ | @@ -18,7 +18,7 @@ | ||
| 18 | <i class="el-icon-video-camera" ></i> | 18 | <i class="el-icon-video-camera" ></i> |
| 19 | {{ item.substring(0,17)}} | 19 | {{ item.substring(0,17)}} |
| 20 | </el-tag> | 20 | </el-tag> |
| 21 | - <a class="el-icon-download" style="color: #409EFF;font-weight: 600;margin-left: 10px;" :href="`${basePath}/download.html?url=record/${recordFile.app}/${recordFile.stream}/${chooseDate}/${item}`" target="_blank" /> | 21 | + <a class="el-icon-download" style="color: #409EFF;font-weight: 600;margin-left: 10px;" :href="`${getFileBasePath()}/download.html?url=download/${recordFile.app}/${recordFile.stream}/${chooseDate}/${item}`" target="_blank" /> |
| 22 | </li> | 22 | </li> |
| 23 | </ul> | 23 | </ul> |
| 24 | </div> | 24 | </div> |
| @@ -76,7 +76,7 @@ | @@ -76,7 +76,7 @@ | ||
| 76 | <li class="task-list-item" v-for="(item, index) in taskListEnded" :key="index"> | 76 | <li class="task-list-item" v-for="(item, index) in taskListEnded" :key="index"> |
| 77 | <div class="task-list-item-box" style="height: 2rem;line-height: 2rem;"> | 77 | <div class="task-list-item-box" style="height: 2rem;line-height: 2rem;"> |
| 78 | <span>{{ item.startTime.substr(10) }}-{{item.endTime.substr(10)}}</span> | 78 | <span>{{ item.startTime.substr(10) }}-{{item.endTime.substr(10)}}</span> |
| 79 | - <a class="el-icon-download download-btn" :href="mediaServerPath + '/download.html?url=../' + item.recordFile" target="_blank"> | 79 | + <a class="el-icon-download download-btn" :href="getFileBasePath() + '/download.html?url=download/' + item.recordFile" target="_blank"> |
| 80 | </a> | 80 | </a> |
| 81 | </div> | 81 | </div> |
| 82 | </li> | 82 | </li> |
| @@ -107,15 +107,15 @@ | @@ -107,15 +107,15 @@ | ||
| 107 | import uiHeader from '../layout/UiHeader.vue' | 107 | import uiHeader from '../layout/UiHeader.vue' |
| 108 | import player from './dialog/easyPlayer.vue' | 108 | import player from './dialog/easyPlayer.vue' |
| 109 | import moment from 'moment' | 109 | import moment from 'moment' |
| 110 | + import axios from "axios"; | ||
| 110 | export default { | 111 | export default { |
| 111 | name: 'app', | 112 | name: 'app', |
| 112 | components: { | 113 | components: { |
| 113 | uiHeader, player | 114 | uiHeader, player |
| 114 | }, | 115 | }, |
| 115 | - props: ['recordFile', 'mediaServerId', 'dateFiles', 'mediaServerPath'], | 116 | + props: ['recordFile', 'mediaServerId', 'dateFiles'], |
| 116 | data() { | 117 | data() { |
| 117 | return { | 118 | return { |
| 118 | - basePath: `${this.mediaServerPath}`, | ||
| 119 | dateFilesObj: [], | 119 | dateFilesObj: [], |
| 120 | detailFiles: [], | 120 | detailFiles: [], |
| 121 | chooseDate: null, | 121 | chooseDate: null, |
| @@ -220,14 +220,18 @@ | @@ -220,14 +220,18 @@ | ||
| 220 | } | 220 | } |
| 221 | this.queryRecordDetails(()=>{ | 221 | this.queryRecordDetails(()=>{ |
| 222 | if (this.detailFiles.length > 0){ | 222 | if (this.detailFiles.length > 0){ |
| 223 | + console.log(this.detailFiles) | ||
| 223 | let timeForFile = this.getTimeForFile(this.detailFiles[0]); | 224 | let timeForFile = this.getTimeForFile(this.detailFiles[0]); |
| 224 | let lastTimeForFile = this.getTimeForFile(this.detailFiles[this.detailFiles.length - 1]); | 225 | let lastTimeForFile = this.getTimeForFile(this.detailFiles[this.detailFiles.length - 1]); |
| 225 | let timeNum = timeForFile[0].getTime() - new Date(this.chooseDate + " " + this.timeFormat).getTime() | 226 | let timeNum = timeForFile[0].getTime() - new Date(this.chooseDate + " " + this.timeFormat).getTime() |
| 227 | + console.log(timeNum) | ||
| 226 | let lastTimeNum = lastTimeForFile[1].getTime() - new Date(this.chooseDate + " " + this.timeFormat).getTime() | 228 | let lastTimeNum = lastTimeForFile[1].getTime() - new Date(this.chooseDate + " " + this.timeFormat).getTime() |
| 227 | 229 | ||
| 228 | this.playTime = parseInt(timeNum/1000) | 230 | this.playTime = parseInt(timeNum/1000) |
| 229 | this.sliderMIn = parseInt(timeNum/1000 - timeNum/1000%(60*60)) | 231 | this.sliderMIn = parseInt(timeNum/1000 - timeNum/1000%(60*60)) |
| 232 | + console.log(this.sliderMIn ) | ||
| 230 | this.sliderMax = parseInt(lastTimeNum/1000 - lastTimeNum/1000%(60*60)) + 60*60 | 233 | this.sliderMax = parseInt(lastTimeNum/1000 - lastTimeNum/1000%(60*60)) + 60*60 |
| 234 | + console.log(this.sliderMax ) | ||
| 231 | } | 235 | } |
| 232 | }); | 236 | }); |
| 233 | }, | 237 | }, |
| @@ -241,7 +245,7 @@ | @@ -241,7 +245,7 @@ | ||
| 241 | let that = this; | 245 | let that = this; |
| 242 | that.$axios({ | 246 | that.$axios({ |
| 243 | method: 'get', | 247 | method: 'get', |
| 244 | - url:`./record_proxy/${that.mediaServerId}/api/record/file/list`, | 248 | + url:`/record_proxy/${that.mediaServerId}/api/record/file/list`, |
| 245 | params: { | 249 | params: { |
| 246 | app: that.recordFile.app, | 250 | app: that.recordFile.app, |
| 247 | stream: that.recordFile.stream, | 251 | stream: that.recordFile.stream, |
| @@ -267,13 +271,23 @@ | @@ -267,13 +271,23 @@ | ||
| 267 | if (file == null) { | 271 | if (file == null) { |
| 268 | this.videoUrl = ""; | 272 | this.videoUrl = ""; |
| 269 | }else { | 273 | }else { |
| 270 | - // TODO 控制列表滚动条 | ||
| 271 | - this.videoUrl = `${this.basePath}/record/${this.recordFile.app}/${this.recordFile.stream}/${this.chooseDate}/${this.choosedFile}` | 274 | + this.videoUrl = `${this.getFileBasePath()}/download/${this.recordFile.app}/${this.recordFile.stream}/${this.chooseDate}/${this.choosedFile}` |
| 275 | + | ||
| 272 | console.log(this.videoUrl) | 276 | console.log(this.videoUrl) |
| 273 | } | 277 | } |
| 274 | 278 | ||
| 275 | }, | 279 | }, |
| 276 | 280 | ||
| 281 | + getFileBasePath(){ | ||
| 282 | + let basePath = "" | ||
| 283 | + if (axios.defaults.baseURL.startsWith("http")) { | ||
| 284 | + basePath = `${axios.defaults.baseURL}/record_proxy/${this.mediaServerId}` | ||
| 285 | + }else { | ||
| 286 | + basePath = `${window.location.origin}${axios.defaults.baseURL}/record_proxy/${this.mediaServerId}` | ||
| 287 | + } | ||
| 288 | + return basePath; | ||
| 289 | + }, | ||
| 290 | + | ||
| 277 | getDataWidth(item){ | 291 | getDataWidth(item){ |
| 278 | let timeForFile = this.getTimeForFile(item); | 292 | let timeForFile = this.getTimeForFile(item); |
| 279 | let result = (timeForFile[2])/((this.sliderMax - this.sliderMIn)*1000) | 293 | let result = (timeForFile[2])/((this.sliderMax - this.sliderMIn)*1000) |
| @@ -301,11 +315,12 @@ | @@ -301,11 +315,12 @@ | ||
| 301 | } | 315 | } |
| 302 | }, | 316 | }, |
| 303 | getTimeForFile(file){ | 317 | getTimeForFile(file){ |
| 318 | + console.log(file) | ||
| 304 | let timeStr = file.substring(0,17); | 319 | let timeStr = file.substring(0,17); |
| 305 | if(timeStr.indexOf("~") > 0){ | 320 | if(timeStr.indexOf("~") > 0){ |
| 306 | timeStr = timeStr.replaceAll("-",":") | 321 | timeStr = timeStr.replaceAll("-",":") |
| 307 | } | 322 | } |
| 308 | - let timeArr = timeStr.split("~"); | 323 | + let timeArr = timeStr.split("-"); |
| 309 | let starTime = new Date(this.chooseDate + " " + timeArr[0]); | 324 | let starTime = new Date(this.chooseDate + " " + timeArr[0]); |
| 310 | let endTime = new Date(this.chooseDate + " " + timeArr[1]); | 325 | let endTime = new Date(this.chooseDate + " " + timeArr[1]); |
| 311 | if(this.checkIsOver24h(starTime,endTime)){ | 326 | if(this.checkIsOver24h(starTime,endTime)){ |
| @@ -340,7 +355,7 @@ | @@ -340,7 +355,7 @@ | ||
| 340 | let that = this; | 355 | let that = this; |
| 341 | this.$axios({ | 356 | this.$axios({ |
| 342 | method: 'delete', | 357 | method: 'delete', |
| 343 | - url:`./record_proxy/${that.mediaServerId}/api/record/delete`, | 358 | + url:`/record_proxy/${that.mediaServerId}/api/record/delete`, |
| 344 | params: { | 359 | params: { |
| 345 | page: that.currentPage, | 360 | page: that.currentPage, |
| 346 | count: that.count | 361 | count: that.count |
| @@ -359,7 +374,7 @@ | @@ -359,7 +374,7 @@ | ||
| 359 | that.dateFilesObj = {}; | 374 | that.dateFilesObj = {}; |
| 360 | this.$axios({ | 375 | this.$axios({ |
| 361 | method: 'get', | 376 | method: 'get', |
| 362 | - url:`./record_proxy/${that.mediaServerId}/api/record/date/list`, | 377 | + url:`/record_proxy/${that.mediaServerId}/api/record/date/list`, |
| 363 | params: { | 378 | params: { |
| 364 | app: that.recordFile.app, | 379 | app: that.recordFile.app, |
| 365 | stream: that.recordFile.stream | 380 | stream: that.recordFile.stream |
| @@ -408,7 +423,7 @@ | @@ -408,7 +423,7 @@ | ||
| 408 | let that = this; | 423 | let that = this; |
| 409 | this.$axios({ | 424 | this.$axios({ |
| 410 | method: 'get', | 425 | method: 'get', |
| 411 | - url:`./record_proxy/${that.mediaServerId}/api/record/file/download/task/add`, | 426 | + url:`/record_proxy/${that.mediaServerId}/api/record/file/download/task/add`, |
| 412 | params: { | 427 | params: { |
| 413 | app: that.recordFile.app, | 428 | app: that.recordFile.app, |
| 414 | stream: that.recordFile.stream, | 429 | stream: that.recordFile.stream, |
| @@ -433,7 +448,7 @@ | @@ -433,7 +448,7 @@ | ||
| 433 | let that = this; | 448 | let that = this; |
| 434 | this.$axios({ | 449 | this.$axios({ |
| 435 | method: 'get', | 450 | method: 'get', |
| 436 | - url:`./record_proxy/${that.mediaServerId}/api/record/file/download/task/list`, | 451 | + url:`/record_proxy/${that.mediaServerId}/api/record/file/download/task/list`, |
| 437 | params: { | 452 | params: { |
| 438 | isEnd: isEnd, | 453 | isEnd: isEnd, |
| 439 | } | 454 | } |
web_src/src/components/DeviceList.vue
| @@ -152,7 +152,7 @@ export default { | @@ -152,7 +152,7 @@ export default { | ||
| 152 | this.getDeviceListLoading = true; | 152 | this.getDeviceListLoading = true; |
| 153 | this.$axios({ | 153 | this.$axios({ |
| 154 | method: 'get', | 154 | method: 'get', |
| 155 | - url: `./api/device/query/devices`, | 155 | + url: `/api/device/query/devices`, |
| 156 | params: { | 156 | params: { |
| 157 | page: this.currentPage, | 157 | page: this.currentPage, |
| 158 | count: this.count | 158 | count: this.count |
| @@ -182,7 +182,7 @@ export default { | @@ -182,7 +182,7 @@ export default { | ||
| 182 | }).then(() => { | 182 | }).then(() => { |
| 183 | this.$axios({ | 183 | this.$axios({ |
| 184 | method: 'delete', | 184 | method: 'delete', |
| 185 | - url: `./api/device/query/devices/${row.deviceId}/delete` | 185 | + url: `/api/device/query/devices/${row.deviceId}/delete` |
| 186 | }).then((res) => { | 186 | }).then((res) => { |
| 187 | this.getDeviceList(); | 187 | this.getDeviceList(); |
| 188 | }).catch((error) => { | 188 | }).catch((error) => { |
| @@ -208,7 +208,7 @@ export default { | @@ -208,7 +208,7 @@ export default { | ||
| 208 | let that = this; | 208 | let that = this; |
| 209 | this.$axios({ | 209 | this.$axios({ |
| 210 | method: 'get', | 210 | method: 'get', |
| 211 | - url: './api/device/query/devices/' + itemData.deviceId + '/sync' | 211 | + url: '/api/device/query/devices/' + itemData.deviceId + '/sync' |
| 212 | }).then((res) => { | 212 | }).then((res) => { |
| 213 | console.log("刷新设备结果:" + JSON.stringify(res)); | 213 | console.log("刷新设备结果:" + JSON.stringify(res)); |
| 214 | if (res.data.code !== 0) { | 214 | if (res.data.code !== 0) { |
| @@ -242,7 +242,7 @@ export default { | @@ -242,7 +242,7 @@ export default { | ||
| 242 | await this.$axios({ | 242 | await this.$axios({ |
| 243 | method: 'get', | 243 | method: 'get', |
| 244 | async: false, | 244 | async: false, |
| 245 | - url: `./api/device/query/${deviceId}/sync_status/`, | 245 | + url: `/api/device/query/${deviceId}/sync_status/`, |
| 246 | }).then((res) => { | 246 | }).then((res) => { |
| 247 | if (res.data.code == 0) { | 247 | if (res.data.code == 0) { |
| 248 | if (res.data.data.errorMsg !== null) { | 248 | if (res.data.data.errorMsg !== null) { |
| @@ -261,7 +261,7 @@ export default { | @@ -261,7 +261,7 @@ export default { | ||
| 261 | let that = this; | 261 | let that = this; |
| 262 | this.$axios({ | 262 | this.$axios({ |
| 263 | method: 'post', | 263 | method: 'post', |
| 264 | - url: './api/device/query/transport/' + row.deviceId + '/' + row.streamMode | 264 | + url: '/api/device/query/transport/' + row.deviceId + '/' + row.streamMode |
| 265 | }).then(function (res) { | 265 | }).then(function (res) { |
| 266 | 266 | ||
| 267 | }).catch(function (e) { | 267 | }).catch(function (e) { |
web_src/src/components/GBRecordDetail.vue
| @@ -197,7 +197,7 @@ | @@ -197,7 +197,7 @@ | ||
| 197 | this.detailFiles = []; | 197 | this.detailFiles = []; |
| 198 | this.$axios({ | 198 | this.$axios({ |
| 199 | method: 'get', | 199 | method: 'get', |
| 200 | - url: './api/gb_record/query/' + this.deviceId + '/' + this.channelId + '?startTime=' + this.startTime + '&endTime=' + this.endTime | 200 | + url: '/api/gb_record/query/' + this.deviceId + '/' + this.channelId + '?startTime=' + this.startTime + '&endTime=' + this.endTime |
| 201 | }).then((res)=>{ | 201 | }).then((res)=>{ |
| 202 | this.recordsLoading = false; | 202 | this.recordsLoading = false; |
| 203 | if(res.data.code === 0) { | 203 | if(res.data.code === 0) { |
| @@ -249,7 +249,7 @@ | @@ -249,7 +249,7 @@ | ||
| 249 | } else { | 249 | } else { |
| 250 | this.$axios({ | 250 | this.$axios({ |
| 251 | method: 'get', | 251 | method: 'get', |
| 252 | - url: './api/playback/start/' + this.deviceId + '/' + this.channelId + '?startTime=' + this.startTime + '&endTime=' + | 252 | + url: '/api/playback/start/' + this.deviceId + '/' + this.channelId + '?startTime=' + this.startTime + '&endTime=' + |
| 253 | this.endTime | 253 | this.endTime |
| 254 | }).then((res)=> { | 254 | }).then((res)=> { |
| 255 | if (res.data.code === 0) { | 255 | if (res.data.code === 0) { |
| @@ -273,7 +273,7 @@ | @@ -273,7 +273,7 @@ | ||
| 273 | console.log('前端控制:播放'); | 273 | console.log('前端控制:播放'); |
| 274 | this.$axios({ | 274 | this.$axios({ |
| 275 | method: 'get', | 275 | method: 'get', |
| 276 | - url: './api/playback/resume/' + this.streamId | 276 | + url: '/api/playback/resume/' + this.streamId |
| 277 | }).then((res)=> { | 277 | }).then((res)=> { |
| 278 | this.$refs["recordVideoPlayer"].play(this.videoUrl) | 278 | this.$refs["recordVideoPlayer"].play(this.videoUrl) |
| 279 | }); | 279 | }); |
| @@ -282,14 +282,14 @@ | @@ -282,14 +282,14 @@ | ||
| 282 | console.log('前端控制:暂停'); | 282 | console.log('前端控制:暂停'); |
| 283 | this.$axios({ | 283 | this.$axios({ |
| 284 | method: 'get', | 284 | method: 'get', |
| 285 | - url: './api/playback/pause/' + this.streamId | 285 | + url: '/api/playback/pause/' + this.streamId |
| 286 | }).then(function (res) {}); | 286 | }).then(function (res) {}); |
| 287 | }, | 287 | }, |
| 288 | gbScale(command){ | 288 | gbScale(command){ |
| 289 | console.log('前端控制:倍速 ' + command); | 289 | console.log('前端控制:倍速 ' + command); |
| 290 | this.$axios({ | 290 | this.$axios({ |
| 291 | method: 'get', | 291 | method: 'get', |
| 292 | - url: `./api/playback/speed/${this.streamId }/${command}` | 292 | + url: `/api/playback/speed/${this.streamId }/${command}` |
| 293 | }).then(function (res) {}); | 293 | }).then(function (res) {}); |
| 294 | }, | 294 | }, |
| 295 | downloadRecord: function (row) { | 295 | downloadRecord: function (row) { |
| @@ -311,7 +311,7 @@ | @@ -311,7 +311,7 @@ | ||
| 311 | }else { | 311 | }else { |
| 312 | this.$axios({ | 312 | this.$axios({ |
| 313 | method: 'get', | 313 | method: 'get', |
| 314 | - url: './api/gb_record/download/start/' + this.deviceId + '/' + this.channelId + '?startTime=' + row.startTime + '&endTime=' + | 314 | + url: '/api/gb_record/download/start/' + this.deviceId + '/' + this.channelId + '?startTime=' + row.startTime + '&endTime=' + |
| 315 | row.endTime + '&downloadSpeed=4' | 315 | row.endTime + '&downloadSpeed=4' |
| 316 | }).then( (res)=> { | 316 | }).then( (res)=> { |
| 317 | if (res.data.code === 0) { | 317 | if (res.data.code === 0) { |
| @@ -332,7 +332,7 @@ | @@ -332,7 +332,7 @@ | ||
| 332 | this.videoUrl = ''; | 332 | this.videoUrl = ''; |
| 333 | this.$axios({ | 333 | this.$axios({ |
| 334 | method: 'get', | 334 | method: 'get', |
| 335 | - url: './api/gb_record/download/stop/' + this.deviceId + "/" + this.channelId+ "/" + this.streamId | 335 | + url: '/api/gb_record/download/stop/' + this.deviceId + "/" + this.channelId+ "/" + this.streamId |
| 336 | }).then((res)=> { | 336 | }).then((res)=> { |
| 337 | if (callback) callback(res) | 337 | if (callback) callback(res) |
| 338 | }); | 338 | }); |
| @@ -342,7 +342,7 @@ | @@ -342,7 +342,7 @@ | ||
| 342 | this.videoUrl = ''; | 342 | this.videoUrl = ''; |
| 343 | this.$axios({ | 343 | this.$axios({ |
| 344 | method: 'get', | 344 | method: 'get', |
| 345 | - url: './api/playback/stop/' + this.deviceId + "/" + this.channelId + "/" + this.streamId | 345 | + url: '/api/playback/stop/' + this.deviceId + "/" + this.channelId + "/" + this.streamId |
| 346 | }).then(function (res) { | 346 | }).then(function (res) { |
| 347 | if (callback) callback() | 347 | if (callback) callback() |
| 348 | }); | 348 | }); |
web_src/src/components/Login.vue
| @@ -35,6 +35,7 @@ | @@ -35,6 +35,7 @@ | ||
| 35 | 35 | ||
| 36 | <script> | 36 | <script> |
| 37 | import crypto from 'crypto' | 37 | import crypto from 'crypto' |
| 38 | +import userService from "./service/UserService"; | ||
| 38 | export default { | 39 | export default { |
| 39 | name: 'Login', | 40 | name: 'Login', |
| 40 | data(){ | 41 | data(){ |
| @@ -81,13 +82,14 @@ export default { | @@ -81,13 +82,14 @@ export default { | ||
| 81 | 82 | ||
| 82 | this.$axios({ | 83 | this.$axios({ |
| 83 | method: 'get', | 84 | method: 'get', |
| 84 | - url:"./api/user/login", | 85 | + url:"/api/user/login", |
| 85 | params: loginParam | 86 | params: loginParam |
| 86 | }).then(function (res) { | 87 | }).then(function (res) { |
| 87 | window.clearTimeout(timeoutTask) | 88 | window.clearTimeout(timeoutTask) |
| 88 | - console.log(JSON.stringify(res)); | 89 | + console.log(res); |
| 90 | + console.log("登录成功"); | ||
| 89 | if (res.data.code === 0 ) { | 91 | if (res.data.code === 0 ) { |
| 90 | - that.$cookies.set("session", {"username": that.username,"roleId":res.data.data.role.id}) ; | 92 | + userService.setUser(res.data.data) |
| 91 | //登录成功后 | 93 | //登录成功后 |
| 92 | that.cancelEnterkeyDefaultAction(); | 94 | that.cancelEnterkeyDefaultAction(); |
| 93 | that.$router.push('/'); | 95 | that.$router.push('/'); |
| @@ -106,14 +108,6 @@ export default { | @@ -106,14 +108,6 @@ export default { | ||
| 106 | that.isLoging = false; | 108 | that.isLoging = false; |
| 107 | }); | 109 | }); |
| 108 | }, | 110 | }, |
| 109 | - setCookie: function (cname, cvalue, exdays) { | ||
| 110 | - var d = new Date(); | ||
| 111 | - d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000)); | ||
| 112 | - var expires = "expires=" + d.toUTCString(); | ||
| 113 | - console.info(cname + "=" + cvalue + "; " + expires); | ||
| 114 | - document.cookie = cname + "=" + cvalue + "; " + expires; | ||
| 115 | - console.info(document.cookie); | ||
| 116 | - }, | ||
| 117 | cancelEnterkeyDefaultAction: function() { | 111 | cancelEnterkeyDefaultAction: function() { |
| 118 | document.onkeydown = function(e) { | 112 | document.onkeydown = function(e) { |
| 119 | var key = window.event.keyCode; | 113 | var key = window.event.keyCode; |
web_src/src/components/ParentPlatformList.vue
| @@ -128,7 +128,7 @@ export default { | @@ -128,7 +128,7 @@ export default { | ||
| 128 | var that = this; | 128 | var that = this; |
| 129 | that.$axios({ | 129 | that.$axios({ |
| 130 | method: 'delete', | 130 | method: 'delete', |
| 131 | - url:`./api/platform/delete/${platform.serverGBId}` | 131 | + url:`/api/platform/delete/${platform.serverGBId}` |
| 132 | }).then(function (res) { | 132 | }).then(function (res) { |
| 133 | if (res.data.code === 0) { | 133 | if (res.data.code === 0) { |
| 134 | that.$message({ | 134 | that.$message({ |
| @@ -162,7 +162,7 @@ export default { | @@ -162,7 +162,7 @@ export default { | ||
| 162 | 162 | ||
| 163 | this.$axios({ | 163 | this.$axios({ |
| 164 | method: 'get', | 164 | method: 'get', |
| 165 | - url:`./api/platform/query/${that.count}/${that.currentPage}` | 165 | + url:`/api/platform/query/${that.count}/${that.currentPage}` |
| 166 | }).then(function (res) { | 166 | }).then(function (res) { |
| 167 | if (res.data.code === 0) { | 167 | if (res.data.code === 0) { |
| 168 | that.total = res.data.data.total; | 168 | that.total = res.data.data.total; |
web_src/src/components/PushVideoList.vue
| @@ -171,7 +171,7 @@ export default { | @@ -171,7 +171,7 @@ export default { | ||
| 171 | this.getDeviceListLoading = true; | 171 | this.getDeviceListLoading = true; |
| 172 | this.$axios({ | 172 | this.$axios({ |
| 173 | method: 'get', | 173 | method: 'get', |
| 174 | - url: `./api/push/list`, | 174 | + url: `/api/push/list`, |
| 175 | params: { | 175 | params: { |
| 176 | page: that.currentPage, | 176 | page: that.currentPage, |
| 177 | count: that.count, | 177 | count: that.count, |
| @@ -197,7 +197,7 @@ export default { | @@ -197,7 +197,7 @@ export default { | ||
| 197 | this.getListLoading = true; | 197 | this.getListLoading = true; |
| 198 | this.$axios({ | 198 | this.$axios({ |
| 199 | method: 'get', | 199 | method: 'get', |
| 200 | - url: './api/push/getPlayUrl', | 200 | + url: '/api/push/getPlayUrl', |
| 201 | params: { | 201 | params: { |
| 202 | app: row.app, | 202 | app: row.app, |
| 203 | stream: row.stream, | 203 | stream: row.stream, |
| @@ -223,7 +223,7 @@ export default { | @@ -223,7 +223,7 @@ export default { | ||
| 223 | let that = this; | 223 | let that = this; |
| 224 | that.$axios({ | 224 | that.$axios({ |
| 225 | method: "post", | 225 | method: "post", |
| 226 | - url: "./api/push/stop", | 226 | + url: "/api/push/stop", |
| 227 | params: { | 227 | params: { |
| 228 | app: row.app, | 228 | app: row.app, |
| 229 | streamId: row.stream | 229 | streamId: row.stream |
| @@ -247,7 +247,7 @@ export default { | @@ -247,7 +247,7 @@ export default { | ||
| 247 | let that = this; | 247 | let that = this; |
| 248 | that.$axios({ | 248 | that.$axios({ |
| 249 | method: "delete", | 249 | method: "delete", |
| 250 | - url: "./api/push/remove_form_gb", | 250 | + url: "/api/push/remove_form_gb", |
| 251 | data: row | 251 | data: row |
| 252 | }).then((res) => { | 252 | }).then((res) => { |
| 253 | if (res.data.code === 0) { | 253 | if (res.data.code === 0) { |
| @@ -274,7 +274,7 @@ export default { | @@ -274,7 +274,7 @@ export default { | ||
| 274 | let that = this; | 274 | let that = this; |
| 275 | that.$axios({ | 275 | that.$axios({ |
| 276 | method: "delete", | 276 | method: "delete", |
| 277 | - url: "./api/push/batchStop", | 277 | + url: "/api/push/batchStop", |
| 278 | data: { | 278 | data: { |
| 279 | gbStreams: this.multipleSelection | 279 | gbStreams: this.multipleSelection |
| 280 | } | 280 | } |
web_src/src/components/StreamProxyList.vue
| @@ -167,7 +167,7 @@ | @@ -167,7 +167,7 @@ | ||
| 167 | let that = this; | 167 | let that = this; |
| 168 | this.$axios({ | 168 | this.$axios({ |
| 169 | method: 'get', | 169 | method: 'get', |
| 170 | - url:`./api/proxy/list`, | 170 | + url:`/api/proxy/list`, |
| 171 | params: { | 171 | params: { |
| 172 | page: that.currentPage, | 172 | page: that.currentPage, |
| 173 | count: that.count | 173 | count: that.count |
| @@ -190,7 +190,7 @@ | @@ -190,7 +190,7 @@ | ||
| 190 | addOnvif: function(){ | 190 | addOnvif: function(){ |
| 191 | this.$axios({ | 191 | this.$axios({ |
| 192 | method: 'get', | 192 | method: 'get', |
| 193 | - url:`./api/onvif/search?timeout=3000`, | 193 | + url:`/api/onvif/search?timeout=3000`, |
| 194 | }).then((res) =>{ | 194 | }).then((res) =>{ |
| 195 | if (res.data.code === 0 ){ | 195 | if (res.data.code === 0 ){ |
| 196 | if (res.data.data.length > 0) { | 196 | if (res.data.data.length > 0) { |
| @@ -218,7 +218,7 @@ | @@ -218,7 +218,7 @@ | ||
| 218 | let that = this; | 218 | let that = this; |
| 219 | this.$axios({ | 219 | this.$axios({ |
| 220 | method: 'get', | 220 | method: 'get', |
| 221 | - url:`./api/push/getPlayUrl`, | 221 | + url:`/api/push/getPlayUrl`, |
| 222 | params: { | 222 | params: { |
| 223 | app: row.app, | 223 | app: row.app, |
| 224 | stream: row.stream, | 224 | stream: row.stream, |
| @@ -247,7 +247,7 @@ | @@ -247,7 +247,7 @@ | ||
| 247 | let that = this; | 247 | let that = this; |
| 248 | that.$axios({ | 248 | that.$axios({ |
| 249 | method:"delete", | 249 | method:"delete", |
| 250 | - url:"./api/proxy/del", | 250 | + url:"/api/proxy/del", |
| 251 | params:{ | 251 | params:{ |
| 252 | app: row.app, | 252 | app: row.app, |
| 253 | stream: row.stream | 253 | stream: row.stream |
| @@ -263,7 +263,7 @@ | @@ -263,7 +263,7 @@ | ||
| 263 | this.$set(row, 'startBtnLoading', true) | 263 | this.$set(row, 'startBtnLoading', true) |
| 264 | this.$axios({ | 264 | this.$axios({ |
| 265 | method: 'get', | 265 | method: 'get', |
| 266 | - url:`./api/proxy/start`, | 266 | + url:`/api/proxy/start`, |
| 267 | params: { | 267 | params: { |
| 268 | app: row.app, | 268 | app: row.app, |
| 269 | stream: row.stream | 269 | stream: row.stream |
| @@ -295,7 +295,7 @@ | @@ -295,7 +295,7 @@ | ||
| 295 | let that = this; | 295 | let that = this; |
| 296 | this.$axios({ | 296 | this.$axios({ |
| 297 | method: 'get', | 297 | method: 'get', |
| 298 | - url:`./api/proxy/stop`, | 298 | + url:`/api/proxy/stop`, |
| 299 | params: { | 299 | params: { |
| 300 | app: row.app, | 300 | app: row.app, |
| 301 | stream: row.stream | 301 | stream: row.stream |
web_src/src/components/UserManager.vue
| @@ -99,7 +99,7 @@ export default { | @@ -99,7 +99,7 @@ export default { | ||
| 99 | this.getUserListLoading = true; | 99 | this.getUserListLoading = true; |
| 100 | this.$axios({ | 100 | this.$axios({ |
| 101 | method: 'get', | 101 | method: 'get', |
| 102 | - url: `./api/user/users`, | 102 | + url: `/api/user/users`, |
| 103 | params: { | 103 | params: { |
| 104 | page: that.currentPage, | 104 | page: that.currentPage, |
| 105 | count: that.count | 105 | count: that.count |
| @@ -141,7 +141,7 @@ export default { | @@ -141,7 +141,7 @@ export default { | ||
| 141 | }).then(() => { | 141 | }).then(() => { |
| 142 | this.$axios({ | 142 | this.$axios({ |
| 143 | method: 'delete', | 143 | method: 'delete', |
| 144 | - url: `./api/user/delete?id=${row.id}` | 144 | + url: `/api/user/delete?id=${row.id}` |
| 145 | }).then((res) => { | 145 | }).then((res) => { |
| 146 | this.getUserList(); | 146 | this.getUserList(); |
| 147 | }).catch((error) => { | 147 | }).catch((error) => { |
web_src/src/components/channelList.vue
| @@ -69,7 +69,7 @@ | @@ -69,7 +69,7 @@ | ||
| 69 | <span v-if="scope.row.longitude*scope.row.latitude === 0">无</span> | 69 | <span v-if="scope.row.longitude*scope.row.latitude === 0">无</span> |
| 70 | </template> | 70 | </template> |
| 71 | </el-table-column> | 71 | </el-table-column> |
| 72 | - <el-table-column prop="ptztypeText" label="云台类型" min-width="120"/> | 72 | + <el-table-column prop="PTZTypeText" label="云台类型" min-width="120"/> |
| 73 | <el-table-column label="开启音频" min-width="120"> | 73 | <el-table-column label="开启音频" min-width="120"> |
| 74 | <template slot-scope="scope"> | 74 | <template slot-scope="scope"> |
| 75 | <el-switch @change="updateChannel(scope.row)" v-model="scope.row.hasAudio" active-color="#409EFF"> | 75 | <el-switch @change="updateChannel(scope.row)" v-model="scope.row.hasAudio" active-color="#409EFF"> |
| @@ -206,7 +206,7 @@ export default { | @@ -206,7 +206,7 @@ export default { | ||
| 206 | if (typeof (this.$route.params.deviceId) == "undefined") return; | 206 | if (typeof (this.$route.params.deviceId) == "undefined") return; |
| 207 | this.$axios({ | 207 | this.$axios({ |
| 208 | method: 'get', | 208 | method: 'get', |
| 209 | - url: `./api/device/query/devices/${this.$route.params.deviceId}/channels`, | 209 | + url: `/api/device/query/devices/${this.$route.params.deviceId}/channels`, |
| 210 | params: { | 210 | params: { |
| 211 | page: that.currentPage, | 211 | page: that.currentPage, |
| 212 | count: that.count, | 212 | count: that.count, |
| @@ -238,7 +238,7 @@ export default { | @@ -238,7 +238,7 @@ export default { | ||
| 238 | let that = this; | 238 | let that = this; |
| 239 | this.$axios({ | 239 | this.$axios({ |
| 240 | method: 'get', | 240 | method: 'get', |
| 241 | - url: './api/play/start/' + deviceId + '/' + channelId | 241 | + url: '/api/play/start/' + deviceId + '/' + channelId |
| 242 | }).then(function (res) { | 242 | }).then(function (res) { |
| 243 | console.log(res) | 243 | console.log(res) |
| 244 | that.isLoging = false; | 244 | that.isLoging = false; |
| @@ -278,7 +278,7 @@ export default { | @@ -278,7 +278,7 @@ export default { | ||
| 278 | var that = this; | 278 | var that = this; |
| 279 | this.$axios({ | 279 | this.$axios({ |
| 280 | method: 'get', | 280 | method: 'get', |
| 281 | - url: './api/play/stop/' + this.deviceId + "/" + itemData.channelId | 281 | + url: '/api/play/stop/' + this.deviceId + "/" + itemData.channelId |
| 282 | }).then(function (res) { | 282 | }).then(function (res) { |
| 283 | that.initData(); | 283 | that.initData(); |
| 284 | }).catch(function (error) { | 284 | }).catch(function (error) { |
| @@ -334,7 +334,7 @@ export default { | @@ -334,7 +334,7 @@ export default { | ||
| 334 | if (!this.showTree) { | 334 | if (!this.showTree) { |
| 335 | this.$axios({ | 335 | this.$axios({ |
| 336 | method: 'get', | 336 | method: 'get', |
| 337 | - url: `./api/device/query/sub_channels/${this.deviceId}/${this.parentChannelId}/channels`, | 337 | + url: `/api/device/query/sub_channels/${this.deviceId}/${this.parentChannelId}/channels`, |
| 338 | params: { | 338 | params: { |
| 339 | page: this.currentPage, | 339 | page: this.currentPage, |
| 340 | count: this.count, | 340 | count: this.count, |
| @@ -358,7 +358,7 @@ export default { | @@ -358,7 +358,7 @@ export default { | ||
| 358 | }else { | 358 | }else { |
| 359 | this.$axios({ | 359 | this.$axios({ |
| 360 | method: 'get', | 360 | method: 'get', |
| 361 | - url: `./api/device/query/tree/channel/${this.deviceId}`, | 361 | + url: `/api/device/query/tree/channel/${this.deviceId}`, |
| 362 | params: { | 362 | params: { |
| 363 | parentId: this.parentChannelId, | 363 | parentId: this.parentChannelId, |
| 364 | page: this.currentPage, | 364 | page: this.currentPage, |
| @@ -387,7 +387,7 @@ export default { | @@ -387,7 +387,7 @@ export default { | ||
| 387 | updateChannel: function (row) { | 387 | updateChannel: function (row) { |
| 388 | this.$axios({ | 388 | this.$axios({ |
| 389 | method: 'post', | 389 | method: 'post', |
| 390 | - url: `./api/device/query/channel/update/${this.deviceId}`, | 390 | + url: `/api/device/query/channel/update/${this.deviceId}`, |
| 391 | params: row | 391 | params: row |
| 392 | }).then(function (res) { | 392 | }).then(function (res) { |
| 393 | console.log(JSON.stringify(res)); | 393 | console.log(JSON.stringify(res)); |
web_src/src/components/common/jessibuca.vue
| 1 | <template> | 1 | <template> |
| 2 | - <div ref="container" @dblclick="fullscreenSwich" style="width:100%;height:100%;background-color: #000000;margin:0 auto;"> | 2 | + <div ref="container" @dblclick="fullscreenSwich" |
| 3 | + style="width:100%;height:100%;background-color: #000000;margin:0 auto;"> | ||
| 3 | <div class="buttons-box" id="buttonsBox"> | 4 | <div class="buttons-box" id="buttonsBox"> |
| 4 | <div class="buttons-box-left"> | 5 | <div class="buttons-box-left"> |
| 5 | <i v-if="!playing" class="iconfont icon-play jessibuca-btn" @click="playBtnClick"></i> | 6 | <i v-if="!playing" class="iconfont icon-play jessibuca-btn" @click="playBtnClick"></i> |
| @@ -12,7 +13,7 @@ | @@ -12,7 +13,7 @@ | ||
| 12 | <span class="jessibuca-btn">{{ kBps }} kb/s</span> | 13 | <span class="jessibuca-btn">{{ kBps }} kb/s</span> |
| 13 | <!-- <i class="iconfont icon-file-record1 jessibuca-btn"></i>--> | 14 | <!-- <i class="iconfont icon-file-record1 jessibuca-btn"></i>--> |
| 14 | <!-- <i class="iconfont icon-xiangqing2 jessibuca-btn" ></i>--> | 15 | <!-- <i class="iconfont icon-xiangqing2 jessibuca-btn" ></i>--> |
| 15 | - <i class="iconfont icon-camera1196054easyiconnet jessibuca-btn" @click="jessibuca.screenshot('截图','png',0.5)" | 16 | + <i class="iconfont icon-camera1196054easyiconnet jessibuca-btn" @click="screenshot" |
| 16 | style="font-size: 1rem !important"></i> | 17 | style="font-size: 1rem !important"></i> |
| 17 | <i class="iconfont icon-shuaxin11 jessibuca-btn" @click="playBtnClick"></i> | 18 | <i class="iconfont icon-shuaxin11 jessibuca-btn" @click="playBtnClick"></i> |
| 18 | <i v-if="!fullscreen" class="iconfont icon-weibiaoti10 jessibuca-btn" @click="fullscreenSwich"></i> | 19 | <i v-if="!fullscreen" class="iconfont icon-weibiaoti10 jessibuca-btn" @click="fullscreenSwich"></i> |
| @@ -92,29 +93,49 @@ export default { | @@ -92,29 +93,49 @@ export default { | ||
| 92 | jessibucaPlayer[this._uid] = new window.Jessibuca(Object.assign( | 93 | jessibucaPlayer[this._uid] = new window.Jessibuca(Object.assign( |
| 93 | { | 94 | { |
| 94 | container: this.$refs.container, | 95 | container: this.$refs.container, |
| 95 | - videoBuffer: 0.2, // 最大缓冲时长,单位秒 | ||
| 96 | - isResize: true, | 96 | + autoWasm: true, |
| 97 | + background: "", | ||
| 98 | + controlAutoHide: false, | ||
| 99 | + debug: false, | ||
| 97 | decoder: "static/js/jessibuca/decoder.js", | 100 | decoder: "static/js/jessibuca/decoder.js", |
| 98 | - useMSE: false, | ||
| 99 | - showBandwidth: false, | ||
| 100 | - isFlv: true, | ||
| 101 | - // text: "WVP-PRO", | ||
| 102 | - // background: "static/images/zlm-logo.png", | ||
| 103 | - loadingText: "加载中", | 101 | + forceNoOffscreen: true, |
| 104 | hasAudio: typeof (this.hasAudio) == "undefined" ? true : this.hasAudio, | 102 | hasAudio: typeof (this.hasAudio) == "undefined" ? true : this.hasAudio, |
| 105 | - debug: false, | ||
| 106 | - supportDblclickFullscreen: false, // 是否支持屏幕的双击事件,触发全屏,取消全屏事件。 | 103 | + hasVideo: true, |
| 104 | + heartTimeout: 5, | ||
| 105 | + heartTimeoutReplay: true, | ||
| 106 | + heartTimeoutReplayTimes: 3, | ||
| 107 | + hiddenAutoPause: false, | ||
| 108 | + hotKey: false, | ||
| 109 | + isFlv: false, | ||
| 110 | + isFullResize: false, | ||
| 111 | + isNotMute: this.isNotMute, | ||
| 112 | + isResize: false, | ||
| 113 | + keepScreenOn: false, | ||
| 114 | + loadingText: "请稍等, 视频加载中......", | ||
| 115 | + loadingTimeout: 10, | ||
| 116 | + loadingTimeoutReplay: true, | ||
| 117 | + loadingTimeoutReplayTimes: 3, | ||
| 118 | + openWebglAlignment: false, | ||
| 107 | operateBtns: { | 119 | operateBtns: { |
| 108 | fullscreen: false, | 120 | fullscreen: false, |
| 109 | screenshot: false, | 121 | screenshot: false, |
| 110 | play: false, | 122 | play: false, |
| 111 | audio: false, | 123 | audio: false, |
| 112 | - recorder: false, | 124 | + record: false |
| 113 | }, | 125 | }, |
| 114 | - record: "record", | ||
| 115 | - vod: this.vod, | ||
| 116 | - forceNoOffscreen: this.forceNoOffscreen, | ||
| 117 | - isNotMute: this.isNotMute, | 126 | + recordType: "webm", |
| 127 | + rotate: 0, | ||
| 128 | + showBandwidth: false, | ||
| 129 | + supportDblclickFullscreen: false, | ||
| 130 | + timeout: 10, | ||
| 131 | + useMSE: location.hostname !== "localhost" && location.protocol !== "https:", | ||
| 132 | + useOffscreen: false, | ||
| 133 | + useWCS: location.hostname === "localhost" || location.protocol === "https", | ||
| 134 | + useWebFullScreen: false, | ||
| 135 | + videoBuffer: 0, | ||
| 136 | + wasmDecodeAudioSyncVideo: true, | ||
| 137 | + wasmDecodeErrorReplay: true, | ||
| 138 | + wcsUseVideoRender: true | ||
| 118 | }, | 139 | }, |
| 119 | options | 140 | options |
| 120 | )); | 141 | )); |
| @@ -146,13 +167,7 @@ export default { | @@ -146,13 +167,7 @@ export default { | ||
| 146 | _this.isNotMute = !msg; | 167 | _this.isNotMute = !msg; |
| 147 | }); | 168 | }); |
| 148 | jessibuca.on("audioInfo", function (msg) { | 169 | jessibuca.on("audioInfo", function (msg) { |
| 149 | - // console.log("audioInfo", msg); | ||
| 150 | - }); | ||
| 151 | - | ||
| 152 | - jessibuca.on("videoInfo", function (msg) { | ||
| 153 | - // this.videoInfo = msg; | ||
| 154 | - console.log("videoInfo", msg); | ||
| 155 | - | 170 | + console.log("audioInfo", msg); |
| 156 | }); | 171 | }); |
| 157 | 172 | ||
| 158 | jessibuca.on("bps", function (bps) { | 173 | jessibuca.on("bps", function (bps) { |
| @@ -243,6 +258,11 @@ export default { | @@ -243,6 +258,11 @@ export default { | ||
| 243 | this.err = ""; | 258 | this.err = ""; |
| 244 | this.performance = ""; | 259 | this.performance = ""; |
| 245 | }, | 260 | }, |
| 261 | + screenshot: function () { | ||
| 262 | + if (jessibucaPlayer[this._uid]) { | ||
| 263 | + jessibucaPlayer[this._uid].screenshot(); | ||
| 264 | + } | ||
| 265 | + }, | ||
| 246 | mute: function () { | 266 | mute: function () { |
| 247 | if (jessibucaPlayer[this._uid]) { | 267 | if (jessibucaPlayer[this._uid]) { |
| 248 | jessibucaPlayer[this._uid].mute(); | 268 | jessibucaPlayer[this._uid].mute(); |
web_src/src/components/console.vue
| @@ -114,7 +114,7 @@ export default { | @@ -114,7 +114,7 @@ export default { | ||
| 114 | getSystemInfo: function (){ | 114 | getSystemInfo: function (){ |
| 115 | this.$axios({ | 115 | this.$axios({ |
| 116 | method: 'get', | 116 | method: 'get', |
| 117 | - url: `./api/server/system/info`, | 117 | + url: `/api/server/system/info`, |
| 118 | }).then( (res)=> { | 118 | }).then( (res)=> { |
| 119 | if (res.data.code === 0) { | 119 | if (res.data.code === 0) { |
| 120 | this.$refs.consoleCPU.setData(res.data.data.cpu) | 120 | this.$refs.consoleCPU.setData(res.data.data.cpu) |
| @@ -128,7 +128,7 @@ export default { | @@ -128,7 +128,7 @@ export default { | ||
| 128 | getLoad: function (){ | 128 | getLoad: function (){ |
| 129 | this.$axios({ | 129 | this.$axios({ |
| 130 | method: 'get', | 130 | method: 'get', |
| 131 | - url: `./api/server/media_server/load`, | 131 | + url: `/api/server/media_server/load`, |
| 132 | }).then( (res)=> { | 132 | }).then( (res)=> { |
| 133 | if (res.data.code === 0) { | 133 | if (res.data.code === 0) { |
| 134 | this.$refs.consoleNodeLoad.setData(res.data.data) | 134 | this.$refs.consoleNodeLoad.setData(res.data.data) |
| @@ -139,7 +139,7 @@ export default { | @@ -139,7 +139,7 @@ export default { | ||
| 139 | getResourceInfo: function (){ | 139 | getResourceInfo: function (){ |
| 140 | this.$axios({ | 140 | this.$axios({ |
| 141 | method: 'get', | 141 | method: 'get', |
| 142 | - url: `./api/server/resource/info`, | 142 | + url: `/api/server/resource/info`, |
| 143 | }).then( (res)=> { | 143 | }).then( (res)=> { |
| 144 | if (res.data.code === 0) { | 144 | if (res.data.code === 0) { |
| 145 | this.$refs.consoleResource.setData(res.data.data) | 145 | this.$refs.consoleResource.setData(res.data.data) |
| @@ -151,7 +151,7 @@ export default { | @@ -151,7 +151,7 @@ export default { | ||
| 151 | 151 | ||
| 152 | this.$axios({ | 152 | this.$axios({ |
| 153 | method: 'get', | 153 | method: 'get', |
| 154 | - url: `./api/server/system/configInfo`, | 154 | + url: `/api/server/system/configInfo`, |
| 155 | }).then( (res)=> { | 155 | }).then( (res)=> { |
| 156 | console.log(res) | 156 | console.log(res) |
| 157 | if (res.data.code === 0) { | 157 | if (res.data.code === 0) { |
web_src/src/components/dialog/MediaServerEdit.vue
| @@ -78,7 +78,7 @@ | @@ -78,7 +78,7 @@ | ||
| 78 | <el-switch v-model="mediaServerForm.autoConfig" :disabled="mediaServerForm.defaultServer"></el-switch> | 78 | <el-switch v-model="mediaServerForm.autoConfig" :disabled="mediaServerForm.defaultServer"></el-switch> |
| 79 | </el-form-item> | 79 | </el-form-item> |
| 80 | <el-form-item label="收流端口模式" > | 80 | <el-form-item label="收流端口模式" > |
| 81 | - <el-switch active-text="多端口" inactive-text="单端口" v-model="mediaServerForm.rtpEnable" :disabled="mediaServerForm.defaultServer"></el-switch> | 81 | + <el-switch active-text="多端口" inactive-text="单端口" @change="portRangeChange" v-model="mediaServerForm.rtpEnable" :disabled="mediaServerForm.defaultServer"></el-switch> |
| 82 | </el-form-item> | 82 | </el-form-item> |
| 83 | 83 | ||
| 84 | <el-form-item v-if="!mediaServerForm.rtpEnable" label="收流端口" prop="rtpProxyPort"> | 84 | <el-form-item v-if="!mediaServerForm.rtpEnable" label="收流端口" prop="rtpProxyPort"> |
| @@ -335,7 +335,7 @@ export default { | @@ -335,7 +335,7 @@ export default { | ||
| 335 | var that = this; | 335 | var that = this; |
| 336 | await that.$axios({ | 336 | await that.$axios({ |
| 337 | method: 'get', | 337 | method: 'get', |
| 338 | - url:`./api/platform/exit/${deviceGbId}` | 338 | + url:`/api/platform/exit/${deviceGbId}` |
| 339 | }).then(function (res) { | 339 | }).then(function (res) { |
| 340 | result = res.data; | 340 | result = res.data; |
| 341 | }).catch(function (error) { | 341 | }).catch(function (error) { |
| @@ -349,8 +349,10 @@ export default { | @@ -349,8 +349,10 @@ export default { | ||
| 349 | } | 349 | } |
| 350 | }, | 350 | }, |
| 351 | portRangeChange: function() { | 351 | portRangeChange: function() { |
| 352 | - this.mediaServerForm.rtpPortRange = this.rtpPortRange1 + "," + this.rtpPortRange2 | ||
| 353 | - console.log(this.mediaServerForm.rtpPortRange) | 352 | + if (this.mediaServerForm.rtpEnable) { |
| 353 | + this.mediaServerForm.rtpPortRange = this.rtpPortRange1 + "," + this.rtpPortRange2 | ||
| 354 | + console.log(this.mediaServerForm.rtpPortRange) | ||
| 355 | + } | ||
| 354 | } | 356 | } |
| 355 | }, | 357 | }, |
| 356 | }; | 358 | }; |
web_src/src/components/dialog/StreamProxyEdit.vue
| @@ -195,7 +195,7 @@ export default { | @@ -195,7 +195,7 @@ export default { | ||
| 195 | let that = this; | 195 | let that = this; |
| 196 | this.$axios({ | 196 | this.$axios({ |
| 197 | method: 'get', | 197 | method: 'get', |
| 198 | - url:`./api/platform/query/10000/1` | 198 | + url:`/api/platform/query/10000/1` |
| 199 | }).then(function (res) { | 199 | }).then(function (res) { |
| 200 | that.platformList = res.data.data.list; | 200 | that.platformList = res.data.data.list; |
| 201 | }).catch(function (error) { | 201 | }).catch(function (error) { |
| @@ -212,7 +212,7 @@ export default { | @@ -212,7 +212,7 @@ export default { | ||
| 212 | if (that.proxyParam.mediaServerId !== "auto"){ | 212 | if (that.proxyParam.mediaServerId !== "auto"){ |
| 213 | that.$axios({ | 213 | that.$axios({ |
| 214 | method: 'get', | 214 | method: 'get', |
| 215 | - url:`./api/proxy/ffmpeg_cmd/list`, | 215 | + url:`/api/proxy/ffmpeg_cmd/list`, |
| 216 | params: { | 216 | params: { |
| 217 | mediaServerId: that.proxyParam.mediaServerId | 217 | mediaServerId: that.proxyParam.mediaServerId |
| 218 | } | 218 | } |
| @@ -230,7 +230,7 @@ export default { | @@ -230,7 +230,7 @@ export default { | ||
| 230 | this.noneReaderHandler(); | 230 | this.noneReaderHandler(); |
| 231 | this.$axios({ | 231 | this.$axios({ |
| 232 | method: 'post', | 232 | method: 'post', |
| 233 | - url:`./api/proxy/save`, | 233 | + url:`/api/proxy/save`, |
| 234 | data: this.proxyParam | 234 | data: this.proxyParam |
| 235 | }).then((res)=> { | 235 | }).then((res)=> { |
| 236 | this.dialogLoading = false; | 236 | this.dialogLoading = false; |
| @@ -261,7 +261,7 @@ export default { | @@ -261,7 +261,7 @@ export default { | ||
| 261 | var that = this; | 261 | var that = this; |
| 262 | await that.$axios({ | 262 | await that.$axios({ |
| 263 | method: 'get', | 263 | method: 'get', |
| 264 | - url:`./api/platform/exit/${deviceGbId}` | 264 | + url:`/api/platform/exit/${deviceGbId}` |
| 265 | }).then(function (res) { | 265 | }).then(function (res) { |
| 266 | result = res.data; | 266 | result = res.data; |
| 267 | }).catch(function (error) { | 267 | }).catch(function (error) { |
web_src/src/components/dialog/SyncChannelProgress.vue
| @@ -55,7 +55,7 @@ export default { | @@ -55,7 +55,7 @@ export default { | ||
| 55 | getProgress(){ | 55 | getProgress(){ |
| 56 | this.$axios({ | 56 | this.$axios({ |
| 57 | method: 'get', | 57 | method: 'get', |
| 58 | - url:`./api/device/query/${this.deviceId}/sync_status/`, | 58 | + url:`/api/device/query/${this.deviceId}/sync_status/`, |
| 59 | }).then((res) => { | 59 | }).then((res) => { |
| 60 | if (res.data.code === 0) { | 60 | if (res.data.code === 0) { |
| 61 | if (!this.syncFlag) { | 61 | if (!this.syncFlag) { |
web_src/src/components/dialog/addUser.vue
| @@ -100,7 +100,7 @@ export default { | @@ -100,7 +100,7 @@ export default { | ||
| 100 | onSubmit: function () { | 100 | onSubmit: function () { |
| 101 | this.$axios({ | 101 | this.$axios({ |
| 102 | method: 'post', | 102 | method: 'post', |
| 103 | - url: "./api/user/add", | 103 | + url: "/api/user/add", |
| 104 | params: { | 104 | params: { |
| 105 | username: this.username, | 105 | username: this.username, |
| 106 | password: this.password, | 106 | password: this.password, |
| @@ -139,7 +139,7 @@ export default { | @@ -139,7 +139,7 @@ export default { | ||
| 139 | 139 | ||
| 140 | this.$axios({ | 140 | this.$axios({ |
| 141 | method: 'get', | 141 | method: 'get', |
| 142 | - url: "./api/role/all" | 142 | + url: "/api/role/all" |
| 143 | }).then((res) => { | 143 | }).then((res) => { |
| 144 | this.loading = true; | 144 | this.loading = true; |
| 145 | if (res.data.code === 0) { | 145 | if (res.data.code === 0) { |
web_src/src/components/dialog/catalogEdit.vue
| @@ -116,7 +116,7 @@ export default { | @@ -116,7 +116,7 @@ export default { | ||
| 116 | console.log(this.form); | 116 | console.log(this.form); |
| 117 | this.$axios({ | 117 | this.$axios({ |
| 118 | method:"post", | 118 | method:"post", |
| 119 | - url:`./api/platform/catalog/${!this.isEdit? "add":"edit"}`, | 119 | + url:`/api/platform/catalog/${!this.isEdit? "add":"edit"}`, |
| 120 | data: this.form | 120 | data: this.form |
| 121 | }).then((res)=> { | 121 | }).then((res)=> { |
| 122 | if (res.data.code === 0) { | 122 | if (res.data.code === 0) { |
web_src/src/components/dialog/changePassword.vue
| @@ -35,6 +35,7 @@ | @@ -35,6 +35,7 @@ | ||
| 35 | 35 | ||
| 36 | <script> | 36 | <script> |
| 37 | import crypto from 'crypto' | 37 | import crypto from 'crypto' |
| 38 | +import userService from "../service/UserService"; | ||
| 38 | export default { | 39 | export default { |
| 39 | name: "changePassword", | 40 | name: "changePassword", |
| 40 | props: {}, | 41 | props: {}, |
| @@ -90,7 +91,7 @@ export default { | @@ -90,7 +91,7 @@ export default { | ||
| 90 | onSubmit: function () { | 91 | onSubmit: function () { |
| 91 | this.$axios({ | 92 | this.$axios({ |
| 92 | method: 'post', | 93 | method: 'post', |
| 93 | - url:"./api/user/changePassword", | 94 | + url:"/api/user/changePassword", |
| 94 | params: { | 95 | params: { |
| 95 | oldPassword: crypto.createHash('md5').update(this.oldPassword, "utf8").digest('hex'), | 96 | oldPassword: crypto.createHash('md5').update(this.oldPassword, "utf8").digest('hex'), |
| 96 | password: this.newPassword | 97 | password: this.newPassword |
| @@ -105,7 +106,7 @@ export default { | @@ -105,7 +106,7 @@ export default { | ||
| 105 | this.showDialog = false; | 106 | this.showDialog = false; |
| 106 | setTimeout(()=>{ | 107 | setTimeout(()=>{ |
| 107 | // 删除cookie,回到登录页面 | 108 | // 删除cookie,回到登录页面 |
| 108 | - this.$cookies.remove("session"); | 109 | + userService.clearUserInfo(); |
| 109 | this.$router.push('/login'); | 110 | this.$router.push('/login'); |
| 110 | this.sseSource.close(); | 111 | this.sseSource.close(); |
| 111 | },800) | 112 | },800) |
web_src/src/components/dialog/changePasswordForAdmin.vue
| @@ -85,7 +85,7 @@ export default { | @@ -85,7 +85,7 @@ export default { | ||
| 85 | onSubmit: function () { | 85 | onSubmit: function () { |
| 86 | this.$axios({ | 86 | this.$axios({ |
| 87 | method: 'post', | 87 | method: 'post', |
| 88 | - url:"./api/user/changePasswordForAdmin", | 88 | + url:"/api/user/changePasswordForAdmin", |
| 89 | params: { | 89 | params: { |
| 90 | password: this.newPassword, | 90 | password: this.newPassword, |
| 91 | userId: this.form.id, | 91 | userId: this.form.id, |
web_src/src/components/dialog/changePushKey.vue
| @@ -65,7 +65,7 @@ export default { | @@ -65,7 +65,7 @@ export default { | ||
| 65 | onSubmit: function () { | 65 | onSubmit: function () { |
| 66 | this.$axios({ | 66 | this.$axios({ |
| 67 | method: 'post', | 67 | method: 'post', |
| 68 | - url:"./api/user/changePushKey", | 68 | + url:"/api/user/changePushKey", |
| 69 | params: { | 69 | params: { |
| 70 | pushKey: this.newPushKey, | 70 | pushKey: this.newPushKey, |
| 71 | userId: this.form.id, | 71 | userId: this.form.id, |
web_src/src/components/dialog/channelMapInfobox.vue
| @@ -44,7 +44,7 @@ export default { | @@ -44,7 +44,7 @@ export default { | ||
| 44 | let that = this; | 44 | let that = this; |
| 45 | this.$axios({ | 45 | this.$axios({ |
| 46 | method: 'get', | 46 | method: 'get', |
| 47 | - url: './api/play/start/' + deviceId + '/' + channelId | 47 | + url: '/api/play/start/' + deviceId + '/' + channelId |
| 48 | }).then(function (res) { | 48 | }).then(function (res) { |
| 49 | that.isLoging = false; | 49 | that.isLoging = false; |
| 50 | if (res.data.code === 0) { | 50 | if (res.data.code === 0) { |
web_src/src/components/dialog/chooseChannel.vue
| 1 | <template> | 1 | <template> |
| 2 | -<div id="chooseChannel" v-loading="isLoging"> | 2 | +<div id="chooseChannel" > |
| 3 | 3 | ||
| 4 | - <el-dialog title="选择通道" v-if="showDialog" top="2rem" width="90%" :close-on-click-modal="false" :visible.sync="showDialog" :destroy-on-close="true" @close="close()"> | 4 | + <el-dialog title="选择通道" v-loading="loading" v-if="showDialog" top="2rem" width="90%" :close-on-click-modal="false" :visible.sync="showDialog" :destroy-on-close="true" @close="close()"> |
| 5 | <el-row> | 5 | <el-row> |
| 6 | <el-col :span="10"> | 6 | <el-col :span="10"> |
| 7 | <el-tabs v-model="catalogTabActiveName" > | 7 | <el-tabs v-model="catalogTabActiveName" > |
| @@ -56,7 +56,7 @@ export default { | @@ -56,7 +56,7 @@ export default { | ||
| 56 | }, | 56 | }, |
| 57 | data() { | 57 | data() { |
| 58 | return { | 58 | return { |
| 59 | - isLoging: false, | 59 | + loading: false, |
| 60 | tabActiveName: "gbChannel", | 60 | tabActiveName: "gbChannel", |
| 61 | catalogTabActiveName: "catalog", | 61 | catalogTabActiveName: "catalog", |
| 62 | platformId: "", | 62 | platformId: "", |
| @@ -94,18 +94,17 @@ export default { | @@ -94,18 +94,17 @@ export default { | ||
| 94 | 94 | ||
| 95 | }, | 95 | }, |
| 96 | save: function() { | 96 | save: function() { |
| 97 | - var that = this; | ||
| 98 | 97 | ||
| 99 | this.$axios({ | 98 | this.$axios({ |
| 100 | method:"post", | 99 | method:"post", |
| 101 | - url:"./api/platform/update_channel_for_gb", | 100 | + url:"/api/platform/update_channel_for_gb", |
| 102 | data:{ | 101 | data:{ |
| 103 | - platformId: that.platformId, | ||
| 104 | - channelReduces: that.chooseData | 102 | + platformId: this.platformId, |
| 103 | + channelReduces: this.chooseData | ||
| 105 | } | 104 | } |
| 106 | }).then((res)=>{ | 105 | }).then((res)=>{ |
| 107 | if (res.data.code === 0) { | 106 | if (res.data.code === 0) { |
| 108 | - that.$message({ | 107 | + this.$message({ |
| 109 | showClose: true, | 108 | showClose: true, |
| 110 | message: '保存成功,', | 109 | message: '保存成功,', |
| 111 | type: 'success' | 110 | type: 'success' |
| @@ -114,6 +113,7 @@ export default { | @@ -114,6 +113,7 @@ export default { | ||
| 114 | }).catch(function (error) { | 113 | }).catch(function (error) { |
| 115 | console.log(error); | 114 | console.log(error); |
| 116 | }); | 115 | }); |
| 116 | + | ||
| 117 | }, | 117 | }, |
| 118 | catalogIdChange: function (id, name) { | 118 | catalogIdChange: function (id, name) { |
| 119 | this.catalogId = id; | 119 | this.catalogId = id; |
web_src/src/components/dialog/chooseChannelForCatalog.vue
| @@ -82,7 +82,7 @@ export default { | @@ -82,7 +82,7 @@ export default { | ||
| 82 | let that = this; | 82 | let that = this; |
| 83 | this.$axios({ | 83 | this.$axios({ |
| 84 | method:"get", | 84 | method:"get", |
| 85 | - url:`./api/platform/catalog`, | 85 | + url:`/api/platform/catalog`, |
| 86 | params: { | 86 | params: { |
| 87 | platformId: that.platformId, | 87 | platformId: that.platformId, |
| 88 | parentId: parentId | 88 | parentId: parentId |
| @@ -134,7 +134,7 @@ export default { | @@ -134,7 +134,7 @@ export default { | ||
| 134 | removeCatalog: function (id, node){ | 134 | removeCatalog: function (id, node){ |
| 135 | this.$axios({ | 135 | this.$axios({ |
| 136 | method:"delete", | 136 | method:"delete", |
| 137 | - url:`./api/platform/catalog/del`, | 137 | + url:`/api/platform/catalog/del`, |
| 138 | params: { | 138 | params: { |
| 139 | id: id, | 139 | id: id, |
| 140 | platformId: this.platformId, | 140 | platformId: this.platformId, |
| @@ -156,7 +156,7 @@ export default { | @@ -156,7 +156,7 @@ export default { | ||
| 156 | setDefaultCatalog: function (id){ | 156 | setDefaultCatalog: function (id){ |
| 157 | this.$axios({ | 157 | this.$axios({ |
| 158 | method:"post", | 158 | method:"post", |
| 159 | - url:`./api/platform/catalog/default/update`, | 159 | + url:`/api/platform/catalog/default/update`, |
| 160 | params: { | 160 | params: { |
| 161 | platformId: this.platformId, | 161 | platformId: this.platformId, |
| 162 | catalogId: id, | 162 | catalogId: id, |
| @@ -201,7 +201,7 @@ export default { | @@ -201,7 +201,7 @@ export default { | ||
| 201 | onClick: () => { | 201 | onClick: () => { |
| 202 | this.$axios({ | 202 | this.$axios({ |
| 203 | method:"delete", | 203 | method:"delete", |
| 204 | - url:"./api/platform/catalog/relation/del", | 204 | + url:"/api/platform/catalog/relation/del", |
| 205 | data: data | 205 | data: data |
| 206 | }).then((res)=>{ | 206 | }).then((res)=>{ |
| 207 | console.log("移除成功") | 207 | console.log("移除成功") |
web_src/src/components/dialog/chooseChannelForGb.vue
| 1 | <template> | 1 | <template> |
| 2 | -<div id="chooseChannelForGb" > | 2 | +<div id="chooseChannelForGb" v-loading="loading"> |
| 3 | <div style="font-size: 17px; color: #606060; white-space: nowrap; line-height: 30px; font-family: monospace;"> | 3 | <div style="font-size: 17px; color: #606060; white-space: nowrap; line-height: 30px; font-family: monospace;"> |
| 4 | <span v-if="catalogId == null">{{catalogName}}的国标通道</span> | 4 | <span v-if="catalogId == null">{{catalogName}}的国标通道</span> |
| 5 | <span v-if="catalogId != null">{{catalogName}}({{catalogId}})的国标通道</span> | 5 | <span v-if="catalogId != null">{{catalogName}}({{catalogId}})的国标通道</span> |
| @@ -79,6 +79,7 @@ export default { | @@ -79,6 +79,7 @@ export default { | ||
| 79 | }, | 79 | }, |
| 80 | data() { | 80 | data() { |
| 81 | return { | 81 | return { |
| 82 | + loading: false, | ||
| 82 | gbChannels: [], | 83 | gbChannels: [], |
| 83 | gbChoosechannel:{}, | 84 | gbChoosechannel:{}, |
| 84 | searchSrt: "", | 85 | searchSrt: "", |
| @@ -118,10 +119,12 @@ export default { | @@ -118,10 +119,12 @@ export default { | ||
| 118 | }, | 119 | }, |
| 119 | add: function (row) { | 120 | add: function (row) { |
| 120 | let all = typeof(row) === "undefined" | 121 | let all = typeof(row) === "undefined" |
| 122 | + | ||
| 121 | this.getCatalogFromUser((catalogId)=> { | 123 | this.getCatalogFromUser((catalogId)=> { |
| 124 | + let task = null; | ||
| 122 | this.$axios({ | 125 | this.$axios({ |
| 123 | method:"post", | 126 | method:"post", |
| 124 | - url:"./api/platform/update_channel_for_gb", | 127 | + url:"/api/platform/update_channel_for_gb", |
| 125 | data:{ | 128 | data:{ |
| 126 | platformId: this.platformId, | 129 | platformId: this.platformId, |
| 127 | all: all, | 130 | all: all, |
| @@ -130,12 +133,20 @@ export default { | @@ -130,12 +133,20 @@ export default { | ||
| 130 | } | 133 | } |
| 131 | }).then((res)=>{ | 134 | }).then((res)=>{ |
| 132 | console.log("保存成功") | 135 | console.log("保存成功") |
| 136 | + window.clearTimeout(task); | ||
| 137 | + this.loading = false; | ||
| 133 | this.getChannelList(); | 138 | this.getChannelList(); |
| 134 | - }).catch(function (error) { | 139 | + }).catch((error)=> { |
| 140 | + window.clearTimeout(task); | ||
| 141 | + this.loading = false; | ||
| 135 | console.log(error); | 142 | console.log(error); |
| 136 | }); | 143 | }); |
| 144 | + task= setTimeout(()=>{ | ||
| 145 | + this.loading = true; | ||
| 146 | + }, 200) | ||
| 137 | }) | 147 | }) |
| 138 | 148 | ||
| 149 | + | ||
| 139 | }, | 150 | }, |
| 140 | remove: function (row) { | 151 | remove: function (row) { |
| 141 | let all = typeof(row) === "undefined" | 152 | let all = typeof(row) === "undefined" |
| @@ -149,7 +160,7 @@ export default { | @@ -149,7 +160,7 @@ export default { | ||
| 149 | 160 | ||
| 150 | this.$axios({ | 161 | this.$axios({ |
| 151 | method:"delete", | 162 | method:"delete", |
| 152 | - url:"./api/platform/del_channel_for_gb", | 163 | + url:"/api/platform/del_channel_for_gb", |
| 153 | data:{ | 164 | data:{ |
| 154 | platformId: this.platformId, | 165 | platformId: this.platformId, |
| 155 | all: all, | 166 | all: all, |
| @@ -248,7 +259,7 @@ export default { | @@ -248,7 +259,7 @@ export default { | ||
| 248 | 259 | ||
| 249 | this.$axios({ | 260 | this.$axios({ |
| 250 | method:"get", | 261 | method:"get", |
| 251 | - url:`./api/platform/channel_list`, | 262 | + url:`/api/platform/channel_list`, |
| 252 | params: { | 263 | params: { |
| 253 | page: that.currentPage, | 264 | page: that.currentPage, |
| 254 | count: that.count, | 265 | count: that.count, |
| @@ -290,7 +301,7 @@ export default { | @@ -290,7 +301,7 @@ export default { | ||
| 290 | }).then(() => { | 301 | }).then(() => { |
| 291 | this.$axios({ | 302 | this.$axios({ |
| 292 | method:"delete", | 303 | method:"delete", |
| 293 | - url:"./api/platform/del_channel_for_gb", | 304 | + url:"/api/platform/del_channel_for_gb", |
| 294 | data:{ | 305 | data:{ |
| 295 | platformId: this.platformId, | 306 | platformId: this.platformId, |
| 296 | channelReduces: this.multipleSelection | 307 | channelReduces: this.multipleSelection |
| @@ -310,7 +321,7 @@ export default { | @@ -310,7 +321,7 @@ export default { | ||
| 310 | 321 | ||
| 311 | this.$axios({ | 322 | this.$axios({ |
| 312 | method: "post", | 323 | method: "post", |
| 313 | - url: "./api/platform/update_channel_for_gb", | 324 | + url: "/api/platform/update_channel_for_gb", |
| 314 | data: { | 325 | data: { |
| 315 | platformId: this.platformId, | 326 | platformId: this.platformId, |
| 316 | channelReduces: this.multipleSelection, | 327 | channelReduces: this.multipleSelection, |
web_src/src/components/dialog/chooseChannelForStream.vue
| 1 | <template> | 1 | <template> |
| 2 | -<div id="chooseChannelFoStream" > | 2 | +<div id="chooseChannelFoStream" v-loading="loading"> |
| 3 | <div style="font-size: 17px; color: #606060; white-space: nowrap; line-height: 30px; font-family: monospace;"> | 3 | <div style="font-size: 17px; color: #606060; white-space: nowrap; line-height: 30px; font-family: monospace;"> |
| 4 | <span v-if="catalogId == null">{{catalogName}}的直播通道</span> | 4 | <span v-if="catalogId == null">{{catalogName}}的直播通道</span> |
| 5 | <span v-if="catalogId != null">{{catalogName}}({{catalogId}})的直播通道</span> | 5 | <span v-if="catalogId != null">{{catalogName}}({{catalogId}})的直播通道</span> |
| @@ -85,6 +85,7 @@ export default { | @@ -85,6 +85,7 @@ export default { | ||
| 85 | }, | 85 | }, |
| 86 | data() { | 86 | data() { |
| 87 | return { | 87 | return { |
| 88 | + loading: false, | ||
| 88 | gbStreams: [], | 89 | gbStreams: [], |
| 89 | gbChoosechannel:{}, | 90 | gbChoosechannel:{}, |
| 90 | channelType: "", | 91 | channelType: "", |
| @@ -132,9 +133,10 @@ export default { | @@ -132,9 +133,10 @@ export default { | ||
| 132 | add: function (row, scope) { | 133 | add: function (row, scope) { |
| 133 | let all = typeof(row) === "undefined" | 134 | let all = typeof(row) === "undefined" |
| 134 | this.getCatalogFromUser((catalogId)=>{ | 135 | this.getCatalogFromUser((catalogId)=>{ |
| 136 | + let task = null; | ||
| 135 | this.$axios({ | 137 | this.$axios({ |
| 136 | method:"post", | 138 | method:"post", |
| 137 | - url:"./api/gbStream/add", | 139 | + url:"/api/gbStream/add", |
| 138 | data:{ | 140 | data:{ |
| 139 | platformId: this.platformId, | 141 | platformId: this.platformId, |
| 140 | catalogId: catalogId, | 142 | catalogId: catalogId, |
| @@ -143,11 +145,18 @@ export default { | @@ -143,11 +145,18 @@ export default { | ||
| 143 | } | 145 | } |
| 144 | }).then((res)=>{ | 146 | }).then((res)=>{ |
| 145 | console.log("保存成功") | 147 | console.log("保存成功") |
| 148 | + window.clearTimeout(task); | ||
| 149 | + this.loading = false; | ||
| 146 | // this.gbStreams.splice(scope.$index,1) | 150 | // this.gbStreams.splice(scope.$index,1) |
| 147 | this.getChannelList(); | 151 | this.getChannelList(); |
| 148 | }).catch(function (error) { | 152 | }).catch(function (error) { |
| 153 | + window.clearTimeout(task); | ||
| 154 | + this.loading = false; | ||
| 149 | console.log(error); | 155 | console.log(error); |
| 150 | }); | 156 | }); |
| 157 | + task= setTimeout(()=>{ | ||
| 158 | + this.loading = true; | ||
| 159 | + }, 200) | ||
| 151 | }) | 160 | }) |
| 152 | 161 | ||
| 153 | 162 | ||
| @@ -163,7 +172,7 @@ export default { | @@ -163,7 +172,7 @@ export default { | ||
| 163 | 172 | ||
| 164 | this.$axios({ | 173 | this.$axios({ |
| 165 | method:"delete", | 174 | method:"delete", |
| 166 | - url:"./api/gbStream/del", | 175 | + url:"/api/gbStream/del", |
| 167 | data:{ | 176 | data:{ |
| 168 | platformId: this.platformId, | 177 | platformId: this.platformId, |
| 169 | all: all, | 178 | all: all, |
| @@ -186,7 +195,7 @@ export default { | @@ -186,7 +195,7 @@ export default { | ||
| 186 | 195 | ||
| 187 | this.$axios({ | 196 | this.$axios({ |
| 188 | method: 'get', | 197 | method: 'get', |
| 189 | - url:`./api/gbStream/list`, | 198 | + url:`/api/gbStream/list`, |
| 190 | params: { | 199 | params: { |
| 191 | page: that.currentPage, | 200 | page: that.currentPage, |
| 192 | count: that.count, | 201 | count: that.count, |
| @@ -222,7 +231,7 @@ export default { | @@ -222,7 +231,7 @@ export default { | ||
| 222 | }).then(() => { | 231 | }).then(() => { |
| 223 | this.$axios({ | 232 | this.$axios({ |
| 224 | method:"delete", | 233 | method:"delete", |
| 225 | - url:"./api/gbStream/del", | 234 | + url:"/api/gbStream/del", |
| 226 | data:{ | 235 | data:{ |
| 227 | platformId: this.platformId, | 236 | platformId: this.platformId, |
| 228 | gbStreams: this.multipleSelection, | 237 | gbStreams: this.multipleSelection, |
| @@ -242,7 +251,7 @@ export default { | @@ -242,7 +251,7 @@ export default { | ||
| 242 | this.getCatalogFromUser((catalogId)=>{ | 251 | this.getCatalogFromUser((catalogId)=>{ |
| 243 | this.$axios({ | 252 | this.$axios({ |
| 244 | method:"post", | 253 | method:"post", |
| 245 | - url:"./api/gbStream/add", | 254 | + url:"/api/gbStream/add", |
| 246 | data:{ | 255 | data:{ |
| 247 | platformId: this.platformId, | 256 | platformId: this.platformId, |
| 248 | catalogId: catalogId, | 257 | catalogId: catalogId, |
web_src/src/components/dialog/configInfo.vue
| @@ -13,7 +13,7 @@ | @@ -13,7 +13,7 @@ | ||
| 13 | <el-descriptions title="国标服务信息" v-if="configInfoData.sip" :span="2"> | 13 | <el-descriptions title="国标服务信息" v-if="configInfoData.sip" :span="2"> |
| 14 | <el-descriptions-item label="编号" >{{configInfoData.sip.id}}</el-descriptions-item> | 14 | <el-descriptions-item label="编号" >{{configInfoData.sip.id}}</el-descriptions-item> |
| 15 | <el-descriptions-item label="域">{{configInfoData.sip.domain}}</el-descriptions-item> | 15 | <el-descriptions-item label="域">{{configInfoData.sip.domain}}</el-descriptions-item> |
| 16 | - <el-descriptions-item label="IP">{{configInfoData.sip.ip}}</el-descriptions-item> | 16 | + <el-descriptions-item label="IP">{{configInfoData.sip.showIp}}</el-descriptions-item> |
| 17 | <el-descriptions-item label="端口">{{configInfoData.sip.port}}</el-descriptions-item> | 17 | <el-descriptions-item label="端口">{{configInfoData.sip.port}}</el-descriptions-item> |
| 18 | <el-descriptions-item label="密码"> | 18 | <el-descriptions-item label="密码"> |
| 19 | <el-tag size="small">{{configInfoData.sip.password}}</el-tag> | 19 | <el-tag size="small">{{configInfoData.sip.password}}</el-tag> |
web_src/src/components/dialog/deviceEdit.vue
| @@ -69,6 +69,7 @@ | @@ -69,6 +69,7 @@ | ||
| 69 | </el-form-item> | 69 | </el-form-item> |
| 70 | <el-form-item label="其他选项"> | 70 | <el-form-item label="其他选项"> |
| 71 | <el-checkbox label="SSRC校验" v-model="form.ssrcCheck" style="float: left"></el-checkbox> | 71 | <el-checkbox label="SSRC校验" v-model="form.ssrcCheck" style="float: left"></el-checkbox> |
| 72 | + <el-checkbox label="作为消息通道" v-model="form.asMessageChannel" style="float: left"></el-checkbox> | ||
| 72 | </el-form-item> | 73 | </el-form-item> |
| 73 | <el-form-item> | 74 | <el-form-item> |
| 74 | <div style="float: right;"> | 75 | <div style="float: right;"> |
| @@ -134,7 +135,7 @@ export default { | @@ -134,7 +135,7 @@ export default { | ||
| 134 | this.form.mobilePositionSubmissionInterval = this.form.mobilePositionSubmissionInterval||0 | 135 | this.form.mobilePositionSubmissionInterval = this.form.mobilePositionSubmissionInterval||0 |
| 135 | this.$axios({ | 136 | this.$axios({ |
| 136 | method: 'post', | 137 | method: 'post', |
| 137 | - url:`./api/device/query/device/${this.isEdit?'update':'add'}/`, | 138 | + url:`/api/device/query/device/${this.isEdit?'update':'add'}/`, |
| 138 | params: this.form | 139 | params: this.form |
| 139 | }).then((res) => { | 140 | }).then((res) => { |
| 140 | console.log(res.data) | 141 | console.log(res.data) |
web_src/src/components/dialog/getCatalog.vue
| @@ -89,7 +89,7 @@ export default { | @@ -89,7 +89,7 @@ export default { | ||
| 89 | let that = this; | 89 | let that = this; |
| 90 | this.$axios({ | 90 | this.$axios({ |
| 91 | method:"get", | 91 | method:"get", |
| 92 | - url:`./api/platform/catalog`, | 92 | + url:`/api/platform/catalog`, |
| 93 | params: { | 93 | params: { |
| 94 | platformId: that.platformId, | 94 | platformId: that.platformId, |
| 95 | parentId: parentId | 95 | parentId: parentId |
| @@ -111,7 +111,7 @@ export default { | @@ -111,7 +111,7 @@ export default { | ||
| 111 | if (node.level === 0) { | 111 | if (node.level === 0) { |
| 112 | this.$axios({ | 112 | this.$axios({ |
| 113 | method:"get", | 113 | method:"get", |
| 114 | - url:`./api/platform/info/` + this.platformId, | 114 | + url:`/api/platform/info/` + this.platformId, |
| 115 | }) | 115 | }) |
| 116 | .then((res)=> { | 116 | .then((res)=> { |
| 117 | if (res.data.code === 0) { | 117 | if (res.data.code === 0) { |
web_src/src/components/dialog/importChannel.vue
| @@ -16,6 +16,7 @@ | @@ -16,6 +16,7 @@ | ||
| 16 | drag | 16 | drag |
| 17 | :action="uploadUrl" | 17 | :action="uploadUrl" |
| 18 | name="file" | 18 | name="file" |
| 19 | + :headers="headers" | ||
| 19 | :on-success="successHook" | 20 | :on-success="successHook" |
| 20 | :on-error="errorHook" | 21 | :on-error="errorHook" |
| 21 | > | 22 | > |
| @@ -33,6 +34,8 @@ | @@ -33,6 +34,8 @@ | ||
| 33 | 34 | ||
| 34 | import ShowErrorData from './importChannelShowErrorData.vue' | 35 | import ShowErrorData from './importChannelShowErrorData.vue' |
| 35 | 36 | ||
| 37 | +import userService from "../service/UserService"; | ||
| 38 | + | ||
| 36 | export default { | 39 | export default { |
| 37 | name: "importChannel", | 40 | name: "importChannel", |
| 38 | components: { | 41 | components: { |
| @@ -47,7 +50,10 @@ export default { | @@ -47,7 +50,10 @@ export default { | ||
| 47 | isEdit: false, | 50 | isEdit: false, |
| 48 | errorStreams: [], | 51 | errorStreams: [], |
| 49 | errorGBIds: [], | 52 | errorGBIds: [], |
| 50 | - uploadUrl: process.env.NODE_ENV === 'development'?`debug/api/push/upload`:`api/push/upload`, | 53 | + headers: { |
| 54 | + "access-token": userService.getToken() | ||
| 55 | + }, | ||
| 56 | + uploadUrl: process.env.NODE_ENV === 'development'? `http://127.0.0.1:8080/debug/api/push/upload`: (window.baseUrl ? window.baseUrl : "") + `/api/push/upload`, | ||
| 51 | }; | 57 | }; |
| 52 | }, | 58 | }, |
| 53 | methods: { | 59 | methods: { |
| @@ -60,7 +66,7 @@ export default { | @@ -60,7 +66,7 @@ export default { | ||
| 60 | console.log(this.form); | 66 | console.log(this.form); |
| 61 | this.$axios({ | 67 | this.$axios({ |
| 62 | method:"post", | 68 | method:"post", |
| 63 | - url:`./api/platform/catalog/${!this.isEdit? "add":"edit"}`, | 69 | + url:`/api/platform/catalog/${!this.isEdit? "add":"edit"}`, |
| 64 | data: this.form | 70 | data: this.form |
| 65 | }) | 71 | }) |
| 66 | .then((res)=> { | 72 | .then((res)=> { |
web_src/src/components/dialog/onvifEdit.vue
| @@ -81,7 +81,7 @@ export default { | @@ -81,7 +81,7 @@ export default { | ||
| 81 | console.log(this.form); | 81 | console.log(this.form); |
| 82 | this.$axios({ | 82 | this.$axios({ |
| 83 | method: 'get', | 83 | method: 'get', |
| 84 | - url:`./api/onvif/rtsp`, | 84 | + url:`/api/onvif/rtsp`, |
| 85 | params: { | 85 | params: { |
| 86 | hostname: this.form.hostName, | 86 | hostname: this.form.hostName, |
| 87 | timeout: 3000, | 87 | timeout: 3000, |
web_src/src/components/dialog/platformEdit.vue
| @@ -96,9 +96,10 @@ | @@ -96,9 +96,10 @@ | ||
| 96 | </el-form-item> | 96 | </el-form-item> |
| 97 | <el-form-item label="其他选项"> | 97 | <el-form-item label="其他选项"> |
| 98 | <el-checkbox label="启用" v-model="platform.enable" @change="checkExpires"></el-checkbox> | 98 | <el-checkbox label="启用" v-model="platform.enable" @change="checkExpires"></el-checkbox> |
| 99 | - <el-checkbox label="云台控制" v-model="platform.ptz"></el-checkbox> | 99 | +<!-- <el-checkbox label="云台控制" v-model="platform.ptz"></el-checkbox>--> |
| 100 | <el-checkbox label="拉起离线推流" v-model="platform.startOfflinePush"></el-checkbox> | 100 | <el-checkbox label="拉起离线推流" v-model="platform.startOfflinePush"></el-checkbox> |
| 101 | <el-checkbox label="RTCP保活" v-model="platform.rtcp" @change="rtcpCheckBoxChange"></el-checkbox> | 101 | <el-checkbox label="RTCP保活" v-model="platform.rtcp" @change="rtcpCheckBoxChange"></el-checkbox> |
| 102 | + <el-checkbox label="作为消息通道" v-model="platform.asMessageChannel" ></el-checkbox> | ||
| 102 | </el-form-item> | 103 | </el-form-item> |
| 103 | <el-form-item> | 104 | <el-form-item> |
| 104 | <el-button type="primary" @click="onSubmit">{{ | 105 | <el-button type="primary" @click="onSubmit">{{ |
| @@ -138,13 +139,14 @@ export default { | @@ -138,13 +139,14 @@ export default { | ||
| 138 | showDialog: false, | 139 | showDialog: false, |
| 139 | isLoging: false, | 140 | isLoging: false, |
| 140 | onSubmit_text: "立即创建", | 141 | onSubmit_text: "立即创建", |
| 141 | - saveUrl: "./api/platform/save", | 142 | + saveUrl: "/api/platform/save", |
| 142 | 143 | ||
| 143 | platform: { | 144 | platform: { |
| 144 | id: null, | 145 | id: null, |
| 145 | enable: true, | 146 | enable: true, |
| 146 | ptz: true, | 147 | ptz: true, |
| 147 | rtcp: false, | 148 | rtcp: false, |
| 149 | + asMessageChannel: false, | ||
| 148 | name: null, | 150 | name: null, |
| 149 | serverGBId: null, | 151 | serverGBId: null, |
| 150 | serverGBDomain: null, | 152 | serverGBDomain: null, |
| @@ -155,7 +157,7 @@ export default { | @@ -155,7 +157,7 @@ export default { | ||
| 155 | devicePort: null, | 157 | devicePort: null, |
| 156 | username: null, | 158 | username: null, |
| 157 | password: null, | 159 | password: null, |
| 158 | - expires: 300, | 160 | + expires: 3600, |
| 159 | keepTimeout: 60, | 161 | keepTimeout: 60, |
| 160 | transport: "UDP", | 162 | transport: "UDP", |
| 161 | characterSet: "GB2312", | 163 | characterSet: "GB2312", |
| @@ -192,7 +194,7 @@ export default { | @@ -192,7 +194,7 @@ export default { | ||
| 192 | this.saveUrl = "/api/platform/add"; | 194 | this.saveUrl = "/api/platform/add"; |
| 193 | this.$axios({ | 195 | this.$axios({ |
| 194 | method: 'get', | 196 | method: 'get', |
| 195 | - url:`./api/platform/server_config` | 197 | + url:`/api/platform/server_config` |
| 196 | }).then(function (res) { | 198 | }).then(function (res) { |
| 197 | console.log(res); | 199 | console.log(res); |
| 198 | if (res.data.code === 0) { | 200 | if (res.data.code === 0) { |
| @@ -213,6 +215,7 @@ export default { | @@ -213,6 +215,7 @@ export default { | ||
| 213 | this.platform.enable = platform.enable; | 215 | this.platform.enable = platform.enable; |
| 214 | this.platform.ptz = platform.ptz; | 216 | this.platform.ptz = platform.ptz; |
| 215 | this.platform.rtcp = platform.rtcp; | 217 | this.platform.rtcp = platform.rtcp; |
| 218 | + this.platform.asMessageChannel = platform.asMessageChannel; | ||
| 216 | this.platform.name = platform.name; | 219 | this.platform.name = platform.name; |
| 217 | this.platform.serverGBId = platform.serverGBId; | 220 | this.platform.serverGBId = platform.serverGBId; |
| 218 | this.platform.serverGBDomain = platform.serverGBDomain; | 221 | this.platform.serverGBDomain = platform.serverGBDomain; |
| @@ -290,6 +293,7 @@ export default { | @@ -290,6 +293,7 @@ export default { | ||
| 290 | enable: true, | 293 | enable: true, |
| 291 | ptz: true, | 294 | ptz: true, |
| 292 | rtcp: false, | 295 | rtcp: false, |
| 296 | + asMessageChannel: false, | ||
| 293 | name: null, | 297 | name: null, |
| 294 | serverGBId: null, | 298 | serverGBId: null, |
| 295 | administrativeDivision: null, | 299 | administrativeDivision: null, |
| @@ -301,7 +305,7 @@ export default { | @@ -301,7 +305,7 @@ export default { | ||
| 301 | devicePort: null, | 305 | devicePort: null, |
| 302 | username: null, | 306 | username: null, |
| 303 | password: null, | 307 | password: null, |
| 304 | - expires: 300, | 308 | + expires: 3600, |
| 305 | keepTimeout: 60, | 309 | keepTimeout: 60, |
| 306 | transport: "UDP", | 310 | transport: "UDP", |
| 307 | characterSet: "GB2312", | 311 | characterSet: "GB2312", |
| @@ -315,7 +319,7 @@ export default { | @@ -315,7 +319,7 @@ export default { | ||
| 315 | var that = this; | 319 | var that = this; |
| 316 | await that.$axios({ | 320 | await that.$axios({ |
| 317 | method: 'get', | 321 | method: 'get', |
| 318 | - url:`./api/platform/exit/${deviceGbId}`}) | 322 | + url:`/api/platform/exit/${deviceGbId}`}) |
| 319 | .then(function (res) { | 323 | .then(function (res) { |
| 320 | if (res.data.code === 0) { | 324 | if (res.data.code === 0) { |
| 321 | result = res.data.data; | 325 | result = res.data.data; |
| @@ -327,8 +331,8 @@ export default { | @@ -327,8 +331,8 @@ export default { | ||
| 327 | return result; | 331 | return result; |
| 328 | }, | 332 | }, |
| 329 | checkExpires: function() { | 333 | checkExpires: function() { |
| 330 | - if (this.platform.enable && this.platform.expires == "0") { | ||
| 331 | - this.platform.expires = "300"; | 334 | + if (this.platform.enable && this.platform.expires === "0") { |
| 335 | + this.platform.expires = "3600"; | ||
| 332 | } | 336 | } |
| 333 | }, | 337 | }, |
| 334 | rtcpCheckBoxChange: function (result){ | 338 | rtcpCheckBoxChange: function (result){ |
web_src/src/components/dialog/pushStreamEdit.vue
| @@ -109,7 +109,7 @@ export default { | @@ -109,7 +109,7 @@ export default { | ||
| 109 | if (this.edit) { | 109 | if (this.edit) { |
| 110 | this.$axios({ | 110 | this.$axios({ |
| 111 | method:"post", | 111 | method:"post", |
| 112 | - url:`./api/push/save_to_gb`, | 112 | + url:`/api/push/save_to_gb`, |
| 113 | data: this.proxyParam | 113 | data: this.proxyParam |
| 114 | }).then( (res) => { | 114 | }).then( (res) => { |
| 115 | if (res.data.code === 0) { | 115 | if (res.data.code === 0) { |
| @@ -129,7 +129,7 @@ export default { | @@ -129,7 +129,7 @@ export default { | ||
| 129 | }else { | 129 | }else { |
| 130 | this.$axios({ | 130 | this.$axios({ |
| 131 | method:"post", | 131 | method:"post", |
| 132 | - url:`./api/push/add`, | 132 | + url:`/api/push/add`, |
| 133 | data: this.proxyParam | 133 | data: this.proxyParam |
| 134 | }).then( (res) => { | 134 | }).then( (res) => { |
| 135 | if (res.data.code === 0) { | 135 | if (res.data.code === 0) { |
| @@ -159,7 +159,7 @@ export default { | @@ -159,7 +159,7 @@ export default { | ||
| 159 | var that = this; | 159 | var that = this; |
| 160 | await that.$axios({ | 160 | await that.$axios({ |
| 161 | method:"get", | 161 | method:"get", |
| 162 | - url:`./api/platform/exit/${deviceGbId}` | 162 | + url:`/api/platform/exit/${deviceGbId}` |
| 163 | }).then(function (res) { | 163 | }).then(function (res) { |
| 164 | result = res.data; | 164 | result = res.data; |
| 165 | }).catch(function (error) { | 165 | }).catch(function (error) { |
web_src/src/components/dialog/queryTrace.vue
| @@ -72,7 +72,7 @@ export default { | @@ -72,7 +72,7 @@ export default { | ||
| 72 | onSubmit: function () { | 72 | onSubmit: function () { |
| 73 | console.log("onSubmit"); | 73 | console.log("onSubmit"); |
| 74 | this.isLoging = true; | 74 | this.isLoging = true; |
| 75 | - let url = `./api/position/history/${this.channel.deviceId}?start=${this.searchFrom}&end=${this.searchTo}`; | 75 | + let url = `/api/position/history/${this.channel.deviceId}?start=${this.searchFrom}&end=${this.searchTo}`; |
| 76 | if (this.channel.channelId) { | 76 | if (this.channel.channelId) { |
| 77 | url+="&channelId=${this.channel.channelId}" | 77 | url+="&channelId=${this.channel.channelId}" |
| 78 | } | 78 | } |
web_src/src/components/dialog/recordDownload.vue
| @@ -71,7 +71,7 @@ export default { | @@ -71,7 +71,7 @@ export default { | ||
| 71 | getProgress: function (callback){ | 71 | getProgress: function (callback){ |
| 72 | this.$axios({ | 72 | this.$axios({ |
| 73 | method: 'get', | 73 | method: 'get', |
| 74 | - url: `./api/gb_record/download/progress/${this.deviceId}/${this.channelId}/${this.stream}` | 74 | + url: `/api/gb_record/download/progress/${this.deviceId}/${this.channelId}/${this.stream}` |
| 75 | }).then((res)=> { | 75 | }).then((res)=> { |
| 76 | console.log(res) | 76 | console.log(res) |
| 77 | if (res.data.code === 0) { | 77 | if (res.data.code === 0) { |
| @@ -124,7 +124,7 @@ export default { | @@ -124,7 +124,7 @@ export default { | ||
| 124 | stopDownloadRecord: function (callback) { | 124 | stopDownloadRecord: function (callback) { |
| 125 | this.$axios({ | 125 | this.$axios({ |
| 126 | method: 'get', | 126 | method: 'get', |
| 127 | - url: './api/gb_record/download/stop/' + this.deviceId + "/" + this.channelId+ "/" + this.stream | 127 | + url: '/api/gb_record/download/stop/' + this.deviceId + "/" + this.channelId+ "/" + this.stream |
| 128 | }).then((res)=> { | 128 | }).then((res)=> { |
| 129 | if (callback) callback(res) | 129 | if (callback) callback(res) |
| 130 | }); | 130 | }); |
| @@ -132,7 +132,7 @@ export default { | @@ -132,7 +132,7 @@ export default { | ||
| 132 | getFileDownload: function (){ | 132 | getFileDownload: function (){ |
| 133 | this.$axios({ | 133 | this.$axios({ |
| 134 | method: 'get', | 134 | method: 'get', |
| 135 | - url:`./record_proxy/${this.mediaServerId}/api/record/file/download/task/add`, | 135 | + url:`/record_proxy/${this.mediaServerId}/api/record/file/download/task/add`, |
| 136 | params: { | 136 | params: { |
| 137 | app: this.app, | 137 | app: this.app, |
| 138 | stream: this.stream, | 138 | stream: this.stream, |
| @@ -164,7 +164,7 @@ export default { | @@ -164,7 +164,7 @@ export default { | ||
| 164 | getProgressForFile: function (callback){ | 164 | getProgressForFile: function (callback){ |
| 165 | this.$axios({ | 165 | this.$axios({ |
| 166 | method: 'get', | 166 | method: 'get', |
| 167 | - url:`./record_proxy/${this.mediaServerId}/api/record/file/download/task/list`, | 167 | + url:`/record_proxy/${this.mediaServerId}/api/record/file/download/task/list`, |
| 168 | params: { | 168 | params: { |
| 169 | app: this.app, | 169 | app: this.app, |
| 170 | stream: this.stream, | 170 | stream: this.stream, |
web_src/src/components/live.vue
| @@ -135,7 +135,7 @@ export default { | @@ -135,7 +135,7 @@ export default { | ||
| 135 | this.loading = true | 135 | this.loading = true |
| 136 | this.$axios({ | 136 | this.$axios({ |
| 137 | method: 'get', | 137 | method: 'get', |
| 138 | - url: './api/play/start/' + deviceId + '/' + channelId | 138 | + url: '/api/play/start/' + deviceId + '/' + channelId |
| 139 | }).then(function (res) { | 139 | }).then(function (res) { |
| 140 | if (res.data.code === 0 && res.data.data) { | 140 | if (res.data.code === 0 && res.data.data) { |
| 141 | let videoUrl; | 141 | let videoUrl; |
web_src/src/components/map.vue
| @@ -298,7 +298,7 @@ export default { | @@ -298,7 +298,7 @@ export default { | ||
| 298 | let that = this; | 298 | let that = this; |
| 299 | this.$axios({ | 299 | this.$axios({ |
| 300 | method: 'get', | 300 | method: 'get', |
| 301 | - url: './api/play/start/' + deviceId + '/' + channelId | 301 | + url: '/api/play/start/' + deviceId + '/' + channelId |
| 302 | }).then(function (res) { | 302 | }).then(function (res) { |
| 303 | that.isLoging = false; | 303 | that.isLoging = false; |
| 304 | if (res.data.code === 0) { | 304 | if (res.data.code === 0) { |
web_src/src/components/service/DeviceService.js
| @@ -9,7 +9,7 @@ class DeviceService{ | @@ -9,7 +9,7 @@ class DeviceService{ | ||
| 9 | getDeviceList(currentPage, count, callback, errorCallback){ | 9 | getDeviceList(currentPage, count, callback, errorCallback){ |
| 10 | this.$axios({ | 10 | this.$axios({ |
| 11 | method: 'get', | 11 | method: 'get', |
| 12 | - url:`./api/device/query/devices`, | 12 | + url:`/api/device/query/devices`, |
| 13 | params: { | 13 | params: { |
| 14 | page: currentPage, | 14 | page: currentPage, |
| 15 | count: count | 15 | count: count |
| @@ -25,7 +25,7 @@ class DeviceService{ | @@ -25,7 +25,7 @@ class DeviceService{ | ||
| 25 | getDevice(deviceId, callback, errorCallback){ | 25 | getDevice(deviceId, callback, errorCallback){ |
| 26 | this.$axios({ | 26 | this.$axios({ |
| 27 | method: 'get', | 27 | method: 'get', |
| 28 | - url:`./api/device/query/devices/${deviceId}`, | 28 | + url:`/api/device/query/devices/${deviceId}`, |
| 29 | }).then((res) => { | 29 | }).then((res) => { |
| 30 | if (typeof (callback) == "function") callback(res.data) | 30 | if (typeof (callback) == "function") callback(res.data) |
| 31 | }).catch((error) => { | 31 | }).catch((error) => { |
| @@ -82,7 +82,7 @@ class DeviceService{ | @@ -82,7 +82,7 @@ class DeviceService{ | ||
| 82 | getChanel(isCatalog, catalogUnderDevice, deviceId, currentPage, count, callback, errorCallback) { | 82 | getChanel(isCatalog, catalogUnderDevice, deviceId, currentPage, count, callback, errorCallback) { |
| 83 | this.$axios({ | 83 | this.$axios({ |
| 84 | method: 'get', | 84 | method: 'get', |
| 85 | - url: `./api/device/query/devices/${deviceId}/channels`, | 85 | + url: `/api/device/query/devices/${deviceId}/channels`, |
| 86 | params:{ | 86 | params:{ |
| 87 | page: currentPage, | 87 | page: currentPage, |
| 88 | count: count, | 88 | count: count, |
| @@ -121,7 +121,7 @@ class DeviceService{ | @@ -121,7 +121,7 @@ class DeviceService{ | ||
| 121 | getSubChannel(isCatalog, deviceId, channelId, currentPage, count, callback, errorCallback) { | 121 | getSubChannel(isCatalog, deviceId, channelId, currentPage, count, callback, errorCallback) { |
| 122 | this.$axios({ | 122 | this.$axios({ |
| 123 | method: 'get', | 123 | method: 'get', |
| 124 | - url: `./api/device/query/sub_channels/${deviceId}/${channelId}/channels`, | 124 | + url: `/api/device/query/sub_channels/${deviceId}/${channelId}/channels`, |
| 125 | params:{ | 125 | params:{ |
| 126 | page: currentPage, | 126 | page: currentPage, |
| 127 | count: count, | 127 | count: count, |
| @@ -161,7 +161,7 @@ class DeviceService{ | @@ -161,7 +161,7 @@ class DeviceService{ | ||
| 161 | } | 161 | } |
| 162 | this.$axios({ | 162 | this.$axios({ |
| 163 | method: 'get', | 163 | method: 'get', |
| 164 | - url: `./api/device/query/tree/${deviceId}`, | 164 | + url: `/api/device/query/tree/${deviceId}`, |
| 165 | params:{ | 165 | params:{ |
| 166 | page: currentPage, | 166 | page: currentPage, |
| 167 | count: count, | 167 | count: count, |
web_src/src/components/service/MediaServer.js
| @@ -9,7 +9,7 @@ class MediaServer{ | @@ -9,7 +9,7 @@ class MediaServer{ | ||
| 9 | getOnlineMediaServerList(callback){ | 9 | getOnlineMediaServerList(callback){ |
| 10 | this.$axios({ | 10 | this.$axios({ |
| 11 | method: 'get', | 11 | method: 'get', |
| 12 | - url:`./api/server/media_server/online/list`, | 12 | + url:`/api/server/media_server/online/list`, |
| 13 | }).then((res) => { | 13 | }).then((res) => { |
| 14 | if (typeof (callback) == "function") callback(res.data) | 14 | if (typeof (callback) == "function") callback(res.data) |
| 15 | }).catch((error) => { | 15 | }).catch((error) => { |
| @@ -19,7 +19,7 @@ class MediaServer{ | @@ -19,7 +19,7 @@ class MediaServer{ | ||
| 19 | getMediaServerList(callback){ | 19 | getMediaServerList(callback){ |
| 20 | this.$axios({ | 20 | this.$axios({ |
| 21 | method: 'get', | 21 | method: 'get', |
| 22 | - url:`./api/server/media_server/list`, | 22 | + url:`/api/server/media_server/list`, |
| 23 | }).then(function (res) { | 23 | }).then(function (res) { |
| 24 | if (typeof (callback) == "function") callback(res.data) | 24 | if (typeof (callback) == "function") callback(res.data) |
| 25 | }).catch(function (error) { | 25 | }).catch(function (error) { |
| @@ -30,7 +30,7 @@ class MediaServer{ | @@ -30,7 +30,7 @@ class MediaServer{ | ||
| 30 | getMediaServer(id, callback){ | 30 | getMediaServer(id, callback){ |
| 31 | this.$axios({ | 31 | this.$axios({ |
| 32 | method: 'get', | 32 | method: 'get', |
| 33 | - url:`./api/server/media_server/one/` + id, | 33 | + url:`/api/server/media_server/one/` + id, |
| 34 | }).then(function (res) { | 34 | }).then(function (res) { |
| 35 | if (typeof (callback) == "function") callback(res.data) | 35 | if (typeof (callback) == "function") callback(res.data) |
| 36 | }).catch(function (error) { | 36 | }).catch(function (error) { |
| @@ -41,7 +41,7 @@ class MediaServer{ | @@ -41,7 +41,7 @@ class MediaServer{ | ||
| 41 | checkServer(param, callback){ | 41 | checkServer(param, callback){ |
| 42 | this.$axios({ | 42 | this.$axios({ |
| 43 | method: 'get', | 43 | method: 'get', |
| 44 | - url:`./api/server/media_server/check`, | 44 | + url:`/api/server/media_server/check`, |
| 45 | params: { | 45 | params: { |
| 46 | ip: param.ip, | 46 | ip: param.ip, |
| 47 | port: param.httpPort, | 47 | port: param.httpPort, |
| @@ -57,7 +57,7 @@ class MediaServer{ | @@ -57,7 +57,7 @@ class MediaServer{ | ||
| 57 | checkRecordServer(param, callback){ | 57 | checkRecordServer(param, callback){ |
| 58 | this.$axios({ | 58 | this.$axios({ |
| 59 | method: 'get', | 59 | method: 'get', |
| 60 | - url:`./api/server/media_server/record/check`, | 60 | + url:`/api/server/media_server/record/check`, |
| 61 | params: { | 61 | params: { |
| 62 | ip: param.ip, | 62 | ip: param.ip, |
| 63 | port: param.recordAssistPort | 63 | port: param.recordAssistPort |
| @@ -72,7 +72,7 @@ class MediaServer{ | @@ -72,7 +72,7 @@ class MediaServer{ | ||
| 72 | addServer(param, callback){ | 72 | addServer(param, callback){ |
| 73 | this.$axios({ | 73 | this.$axios({ |
| 74 | method: 'post', | 74 | method: 'post', |
| 75 | - url:`./api/server/media_server/save`, | 75 | + url:`/api/server/media_server/save`, |
| 76 | data: param | 76 | data: param |
| 77 | }).then(function (res) { | 77 | }).then(function (res) { |
| 78 | if (typeof (callback) == "function") callback(res.data) | 78 | if (typeof (callback) == "function") callback(res.data) |
| @@ -84,7 +84,7 @@ class MediaServer{ | @@ -84,7 +84,7 @@ class MediaServer{ | ||
| 84 | delete(id, callback) { | 84 | delete(id, callback) { |
| 85 | this.$axios({ | 85 | this.$axios({ |
| 86 | method: 'delete', | 86 | method: 'delete', |
| 87 | - url:`./api/server/media_server/delete`, | 87 | + url:`/api/server/media_server/delete`, |
| 88 | params: { | 88 | params: { |
| 89 | id: id | 89 | id: id |
| 90 | } | 90 | } |
web_src/src/components/service/UserService.js
0 → 100644
| 1 | + | ||
| 2 | +export default { | ||
| 3 | + | ||
| 4 | + /** | ||
| 5 | + * 存储用户信息 | ||
| 6 | + * @param username | ||
| 7 | + * @param token | ||
| 8 | + */ | ||
| 9 | + setUser(user){ | ||
| 10 | + localStorage.setItem("wvp-user", JSON.stringify(user)); | ||
| 11 | + }, | ||
| 12 | + | ||
| 13 | + /** | ||
| 14 | + * 获取用户 | ||
| 15 | + */ | ||
| 16 | + getUser(){ | ||
| 17 | + return JSON.parse(localStorage.getItem("wvp-user")); | ||
| 18 | + }, | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + /** | ||
| 22 | + * 获取登录token | ||
| 23 | + */ | ||
| 24 | + getToken(){ | ||
| 25 | + return localStorage.getItem("wvp-token"); | ||
| 26 | + }, | ||
| 27 | + | ||
| 28 | + /** | ||
| 29 | + * 清理用户信息 | ||
| 30 | + */ | ||
| 31 | + clearUserInfo(){ | ||
| 32 | + localStorage.removeItem("wvp-user"); | ||
| 33 | + localStorage.removeItem("wvp-token"); | ||
| 34 | + }, | ||
| 35 | + /** | ||
| 36 | + * 更新token | ||
| 37 | + * @param header | ||
| 38 | + */ | ||
| 39 | + setToken(token) { | ||
| 40 | + localStorage.setItem("wvp-token", token); | ||
| 41 | + } | ||
| 42 | +} |
web_src/src/layout/UiHeader.vue
| @@ -23,9 +23,9 @@ | @@ -23,9 +23,9 @@ | ||
| 23 | <!-- </el-submenu>--> | 23 | <!-- </el-submenu>--> |
| 24 | <!-- <el-menu-item style="float: right;" @click="loginout">退出</el-menu-item>--> | 24 | <!-- <el-menu-item style="float: right;" @click="loginout">退出</el-menu-item>--> |
| 25 | <el-submenu index="" style="float: right;"> | 25 | <el-submenu index="" style="float: right;"> |
| 26 | - <template slot="title">欢迎,{{ this.$cookies.get("session").username }}</template> | 26 | + <template slot="title">欢迎,{{ username }}</template> |
| 27 | <el-menu-item @click="openDoc">在线文档</el-menu-item> | 27 | <el-menu-item @click="openDoc">在线文档</el-menu-item> |
| 28 | - <el-menu-item > | 28 | + <el-menu-item> |
| 29 | <el-switch v-model="alarmNotify" inactive-text="报警信息推送" @change="alarmNotifyChannge"></el-switch> | 29 | <el-switch v-model="alarmNotify" inactive-text="报警信息推送" @change="alarmNotifyChannge"></el-switch> |
| 30 | </el-menu-item> | 30 | </el-menu-item> |
| 31 | <el-menu-item @click="changePassword">修改密码</el-menu-item> | 31 | <el-menu-item @click="changePassword">修改密码</el-menu-item> |
| @@ -39,6 +39,7 @@ | @@ -39,6 +39,7 @@ | ||
| 39 | <script> | 39 | <script> |
| 40 | 40 | ||
| 41 | import changePasswordDialog from '../components/dialog/changePassword.vue' | 41 | import changePasswordDialog from '../components/dialog/changePassword.vue' |
| 42 | +import userService from '../components/service/UserService' | ||
| 42 | 43 | ||
| 43 | export default { | 44 | export default { |
| 44 | name: "UiHeader", | 45 | name: "UiHeader", |
| @@ -47,14 +48,17 @@ export default { | @@ -47,14 +48,17 @@ export default { | ||
| 47 | return { | 48 | return { |
| 48 | alarmNotify: false, | 49 | alarmNotify: false, |
| 49 | sseSource: null, | 50 | sseSource: null, |
| 51 | + username: userService.getUser().username, | ||
| 50 | activeIndex: this.$route.path, | 52 | activeIndex: this.$route.path, |
| 51 | - editUser: this.$cookies.get("session").roleId==1 | 53 | + editUser: userService.getUser() ? userService.getUser().role.id === 1 : false |
| 52 | }; | 54 | }; |
| 53 | }, | 55 | }, |
| 54 | created() { | 56 | created() { |
| 55 | - console.log(this.$cookies.get("session")) | 57 | + console.log(4444) |
| 58 | + console.log(JSON.stringify(userService.getUser())) | ||
| 56 | if (this.$route.path.startsWith("/channelList")) { | 59 | if (this.$route.path.startsWith("/channelList")) { |
| 57 | this.activeIndex = "/deviceList" | 60 | this.activeIndex = "/deviceList" |
| 61 | + | ||
| 58 | } | 62 | } |
| 59 | }, | 63 | }, |
| 60 | mounted() { | 64 | mounted() { |
| @@ -69,10 +73,13 @@ export default { | @@ -69,10 +73,13 @@ export default { | ||
| 69 | method: 'get', | 73 | method: 'get', |
| 70 | url: "/api/user/logout" | 74 | url: "/api/user/logout" |
| 71 | }).then((res) => { | 75 | }).then((res) => { |
| 72 | - // 删除cookie,回到登录页面 | ||
| 73 | - this.$cookies.remove("session"); | 76 | + // 删除用户信息,回到登录页面 |
| 77 | + userService.clearUserInfo() | ||
| 74 | this.$router.push('/login'); | 78 | this.$router.push('/login'); |
| 75 | - this.sseSource.close(); | 79 | + if (this.sseSource != null) { |
| 80 | + this.sseSource.close(); | ||
| 81 | + } | ||
| 82 | + | ||
| 76 | }).catch((error) => { | 83 | }).catch((error) => { |
| 77 | console.error("登出失败") | 84 | console.error("登出失败") |
| 78 | console.error(error) | 85 | console.error(error) |
| @@ -151,16 +158,19 @@ export default { | @@ -151,16 +158,19 @@ export default { | ||
| 151 | </script> | 158 | </script> |
| 152 | <style> | 159 | <style> |
| 153 | #UiHeader .el-switch__label { | 160 | #UiHeader .el-switch__label { |
| 154 | - color: white ; | 161 | + color: white; |
| 155 | } | 162 | } |
| 163 | + | ||
| 156 | .el-menu--popup .el-menu-item .el-switch .el-switch__label { | 164 | .el-menu--popup .el-menu-item .el-switch .el-switch__label { |
| 157 | color: white !important; | 165 | color: white !important; |
| 158 | } | 166 | } |
| 159 | -#UiHeader .el-switch__label.is-active{ | 167 | + |
| 168 | +#UiHeader .el-switch__label.is-active { | ||
| 160 | color: #409EFF; | 169 | color: #409EFF; |
| 161 | } | 170 | } |
| 171 | + | ||
| 162 | #UiHeader .el-menu-item.is-active { | 172 | #UiHeader .el-menu-item.is-active { |
| 163 | - color: #fff!important; | ||
| 164 | - background-color: #1890ff!important; | 173 | + color: #fff !important; |
| 174 | + background-color: #1890ff !important; | ||
| 165 | } | 175 | } |
| 166 | </style> | 176 | </style> |
web_src/src/main.js
| 1 | import Vue from 'vue'; | 1 | import Vue from 'vue'; |
| 2 | import App from './App.vue'; | 2 | import App from './App.vue'; |
| 3 | + | ||
| 3 | Vue.config.productionTip = false; | 4 | Vue.config.productionTip = false; |
| 4 | import ElementUI from 'element-ui'; | 5 | import ElementUI from 'element-ui'; |
| 5 | import 'element-ui/lib/theme-chalk/index.css'; | 6 | import 'element-ui/lib/theme-chalk/index.css'; |
| @@ -10,15 +11,16 @@ import echarts from 'echarts'; | @@ -10,15 +11,16 @@ import echarts from 'echarts'; | ||
| 10 | import VCharts from 'v-charts'; | 11 | import VCharts from 'v-charts'; |
| 11 | 12 | ||
| 12 | import VueClipboard from 'vue-clipboard2'; | 13 | import VueClipboard from 'vue-clipboard2'; |
| 13 | -import { Notification } from 'element-ui'; | 14 | +import {Notification} from 'element-ui'; |
| 14 | import Fingerprint2 from 'fingerprintjs2'; | 15 | import Fingerprint2 from 'fingerprintjs2'; |
| 15 | import VueClipboards from 'vue-clipboards'; | 16 | import VueClipboards from 'vue-clipboards'; |
| 16 | import Contextmenu from "vue-contextmenujs" | 17 | import Contextmenu from "vue-contextmenujs" |
| 18 | +import userService from "./components/service/UserService" | ||
| 17 | 19 | ||
| 18 | 20 | ||
| 19 | // 生成唯一ID | 21 | // 生成唯一ID |
| 20 | -Fingerprint2.get(function(components) { | ||
| 21 | - const values = components.map(function(component,index) { | 22 | +Fingerprint2.get(function (components) { |
| 23 | + const values = components.map(function (component, index) { | ||
| 22 | if (index === 0) { //把微信浏览器里UA的wifi或4G等网络替换成空,不然切换网络会ID不一样 | 24 | if (index === 0) { //把微信浏览器里UA的wifi或4G等网络替换成空,不然切换网络会ID不一样 |
| 23 | return component.value.replace(/\bNetType\/\w+\b/, ''); | 25 | return component.value.replace(/\bNetType\/\w+\b/, ''); |
| 24 | } | 26 | } |
| @@ -37,18 +39,22 @@ Vue.use(VueClipboard); | @@ -37,18 +39,22 @@ Vue.use(VueClipboard); | ||
| 37 | Vue.use(ElementUI); | 39 | Vue.use(ElementUI); |
| 38 | Vue.use(VueCookies); | 40 | Vue.use(VueCookies); |
| 39 | Vue.use(VueClipboards); | 41 | Vue.use(VueClipboards); |
| 40 | -Vue.prototype.$axios = axios; | 42 | + |
| 41 | Vue.prototype.$notify = Notification; | 43 | Vue.prototype.$notify = Notification; |
| 42 | Vue.use(Contextmenu); | 44 | Vue.use(Contextmenu); |
| 43 | Vue.use(VCharts); | 45 | Vue.use(VCharts); |
| 44 | 46 | ||
| 45 | -axios.defaults.baseURL = (process.env.NODE_ENV === 'development') ? process.env.BASE_API : ""; | ||
| 46 | - | 47 | +axios.defaults.baseURL = (process.env.NODE_ENV === 'development') ? process.env.BASE_API : (window.baseUrl ? window.baseUrl : ""); |
| 48 | +axios.defaults.withCredentials = true; | ||
| 47 | // api 返回401自动回登陆页面 | 49 | // api 返回401自动回登陆页面 |
| 48 | -axios.interceptors.response.use(function (response) { | 50 | +axios.interceptors.response.use((response) => { |
| 49 | // 对响应数据做点什么 | 51 | // 对响应数据做点什么 |
| 52 | + let token = response.headers["access-token"]; | ||
| 53 | + if (token) { | ||
| 54 | + userService.setToken(token) | ||
| 55 | + } | ||
| 50 | return response; | 56 | return response; |
| 51 | -}, function (error) { | 57 | +}, (error) => { |
| 52 | // 对响应错误做点什么 | 58 | // 对响应错误做点什么 |
| 53 | if (error.response.status === 401) { | 59 | if (error.response.status === 401) { |
| 54 | console.log("Received 401 Response") | 60 | console.log("Received 401 Response") |
| @@ -56,10 +62,22 @@ axios.interceptors.response.use(function (response) { | @@ -56,10 +62,22 @@ axios.interceptors.response.use(function (response) { | ||
| 56 | } | 62 | } |
| 57 | return Promise.reject(error); | 63 | return Promise.reject(error); |
| 58 | }); | 64 | }); |
| 65 | +axios.interceptors.request.use( | ||
| 66 | + config => { | ||
| 67 | + if (userService.getToken() != null && config.url !== "/api/user/login") { | ||
| 68 | + config.headers['access-token'] = `${userService.getToken()}`; | ||
| 69 | + } | ||
| 70 | + return config; | ||
| 71 | + }, | ||
| 72 | + error => { | ||
| 73 | + return Promise.reject(error); | ||
| 74 | + } | ||
| 75 | +); | ||
| 59 | 76 | ||
| 77 | +Vue.prototype.$axios = axios; | ||
| 60 | Vue.prototype.$cookies.config(60*30); | 78 | Vue.prototype.$cookies.config(60*30); |
| 61 | 79 | ||
| 62 | new Vue({ | 80 | new Vue({ |
| 63 | - router: router, | ||
| 64 | - render: h => h(App), | 81 | + router: router, |
| 82 | + render: h => h(App), | ||
| 65 | }).$mount('#app') | 83 | }).$mount('#app') |
web_src/static/js/mapConfig.js renamed to web_src/static/js/config.js
web_src/static/js/jessibuca/decoder.js
| 1 | -!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?r(require("path"),require("fs"),require("crypto")):"function"==typeof define&&define.amd?define(["path","fs","crypto"],r):r((e="undefined"!=typeof globalThis?globalThis:e||self).path,e.fs,e.crypto$1)}(this,(function(e,r,t){"use strict";function n(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var o=n(e),a=n(r),i=n(t);var s=function(e,r){return e(r={exports:{}},r.exports),r.exports}((function(e){var r,t=void 0!==t?t:{},n=(t={print:function(e){console.log("Jessibuca: [worker]:",e)},printErr:function(e){console.warn("Jessibuca: [worker]:",e),postMessage({cmd:"wasmError",message:e})}},{});for(r in t)t.hasOwnProperty(r)&&(n[r]=t[r]);var s,u,c,f,l="./this.program";s="object"==typeof window,u="function"==typeof importScripts,c="object"==typeof process&&"object"==typeof process.versions&&"string"==typeof process.versions.node,f=!s&&!c&&!u;var d,p,h,m,v,g="";c?(g=u?o.default.dirname(g)+"/":__dirname+"/",d=function(e,r){return m||(m=a.default),v||(v=o.default),e=v.normalize(e),m.readFileSync(e,r?null:"utf8")},h=function(e){var r=d(e,!0);return r.buffer||(r=new Uint8Array(r)),T(r.buffer),r},process.argv.length>1&&(l=process.argv[1].replace(/\\/g,"/")),process.argv.slice(2),e.exports=t,process.on("uncaughtException",(function(e){if(!(e instanceof et))throw e})),process.on("unhandledRejection",te),t.inspect=function(){return"[Emscripten Module object]"}):f?("undefined"!=typeof read&&(d=function(e){return read(e)}),h=function(e){var r;return"function"==typeof readbuffer?new Uint8Array(readbuffer(e)):(T("object"==typeof(r=read(e,"binary"))),r)},"undefined"!=typeof scriptArgs&&scriptArgs,"undefined"!=typeof print&&("undefined"==typeof console&&(console={}),console.log=print,console.warn=console.error="undefined"!=typeof printErr?printErr:print)):(s||u)&&(u?g=self.location.href:"undefined"!=typeof document&&document.currentScript&&(g=document.currentScript.src),g=0!==g.indexOf("blob:")?g.substr(0,g.lastIndexOf("/")+1):"",d=function(e){var r=new XMLHttpRequest;return r.open("GET",e,!1),r.send(null),r.responseText},u&&(h=function(e){var r=new XMLHttpRequest;return r.open("GET",e,!1),r.responseType="arraybuffer",r.send(null),new Uint8Array(r.response)}),p=function(e,r,t){var n=new XMLHttpRequest;n.open("GET",e,!0),n.responseType="arraybuffer",n.onload=function(){200==n.status||0==n.status&&n.response?r(n.response):t()},n.onerror=t,n.send(null)});var y=t.print||console.log.bind(console),w=t.printErr||console.warn.bind(console);for(r in n)n.hasOwnProperty(r)&&(t[r]=n[r]);n=null,t.arguments,t.thisProgram&&(l=t.thisProgram),t.quit;var E,b;function _(e){_.shown||(_.shown={}),_.shown[e]||(_.shown[e]=1,w(e))}t.wasmBinary&&(E=t.wasmBinary),t.noExitRuntime,"object"!=typeof WebAssembly&&te("no native wasm support detected");var k=!1;function T(e,r){e||te("Assertion failed: "+r)}var P="undefined"!=typeof TextDecoder?new TextDecoder("utf8"):void 0;function C(e,r,t){for(var n=r+t,o=r;e[o]&&!(o>=n);)++o;if(o-r>16&&e.subarray&&P)return P.decode(e.subarray(r,o));for(var a="";r<o;){var i=e[r++];if(128&i){var s=63&e[r++];if(192!=(224&i)){var u=63&e[r++];if((i=224==(240&i)?(15&i)<<12|s<<6|u:(7&i)<<18|s<<12|u<<6|63&e[r++])<65536)a+=String.fromCharCode(i);else{var c=i-65536;a+=String.fromCharCode(55296|c>>10,56320|1023&c)}}else a+=String.fromCharCode((31&i)<<6|s)}else a+=String.fromCharCode(i)}return a}function A(e,r){return e?C(R,e,r):""}function D(e,r,t,n){if(!(n>0))return 0;for(var o=t,a=t+n-1,i=0;i<e.length;++i){var s=e.charCodeAt(i);if(s>=55296&&s<=57343)s=65536+((1023&s)<<10)|1023&e.charCodeAt(++i);if(s<=127){if(t>=a)break;r[t++]=s}else if(s<=2047){if(t+1>=a)break;r[t++]=192|s>>6,r[t++]=128|63&s}else if(s<=65535){if(t+2>=a)break;r[t++]=224|s>>12,r[t++]=128|s>>6&63,r[t++]=128|63&s}else{if(t+3>=a)break;r[t++]=240|s>>18,r[t++]=128|s>>12&63,r[t++]=128|s>>6&63,r[t++]=128|63&s}}return r[t]=0,t-o}function S(e,r,t){return D(e,R,r,t)}function F(e){for(var r=0,t=0;t<e.length;++t){var n=e.charCodeAt(t);n>=55296&&n<=57343&&(n=65536+((1023&n)<<10)|1023&e.charCodeAt(++t)),n<=127?++r:r+=n<=2047?2:n<=65535?3:4}return r}var x,$,R,M,O,I,j,U,N,B,W="undefined"!=typeof TextDecoder?new TextDecoder("utf-16le"):void 0;function L(e,r){for(var t=e,n=t>>1,o=n+r/2;!(n>=o)&&O[n];)++n;if((t=n<<1)-e>32&&W)return W.decode(R.subarray(e,t));for(var a="",i=0;!(i>=r/2);++i){var s=M[e+2*i>>1];if(0==s)break;a+=String.fromCharCode(s)}return a}function z(e,r,t){if(void 0===t&&(t=2147483647),t<2)return 0;for(var n=r,o=(t-=2)<2*e.length?t/2:e.length,a=0;a<o;++a){var i=e.charCodeAt(a);M[r>>1]=i,r+=2}return M[r>>1]=0,r-n}function H(e){return 2*e.length}function V(e,r){for(var t=0,n="";!(t>=r/4);){var o=I[e+4*t>>2];if(0==o)break;if(++t,o>=65536){var a=o-65536;n+=String.fromCharCode(55296|a>>10,56320|1023&a)}else n+=String.fromCharCode(o)}return n}function X(e,r,t){if(void 0===t&&(t=2147483647),t<4)return 0;for(var n=r,o=n+t-4,a=0;a<e.length;++a){var i=e.charCodeAt(a);if(i>=55296&&i<=57343)i=65536+((1023&i)<<10)|1023&e.charCodeAt(++a);if(I[r>>2]=i,(r+=4)+4>o)break}return I[r>>2]=0,r-n}function G(e){for(var r=0,t=0;t<e.length;++t){var n=e.charCodeAt(t);n>=55296&&n<=57343&&++t,r+=4}return r}t.INITIAL_MEMORY;var q=[],J=[],Y=[],K=[];var Q=0,Z=null;function ee(e){Q++,t.monitorRunDependencies&&t.monitorRunDependencies(Q)}function re(e){if(Q--,t.monitorRunDependencies&&t.monitorRunDependencies(Q),0==Q&&Z){var r=Z;Z=null,r()}}function te(e){throw t.onAbort&&t.onAbort(e),w(e+=""),k=!0,e="abort("+e+"). Build with -s ASSERTIONS=1 for more info.",new WebAssembly.RuntimeError(e)}function ne(e,r){return String.prototype.startsWith?e.startsWith(r):0===e.indexOf(r)}t.preloadedImages={},t.preloadedAudios={};function oe(e){return ne(e,"data:application/octet-stream;base64,")}function ae(e){return ne(e,"file://")}var ie,se,ue="decoder.wasm";function ce(e){try{if(e==ue&&E)return new Uint8Array(E);if(h)return h(e);throw"both async and sync fetching of the wasm failed"}catch(e){te(e)}}function fe(e){for(;e.length>0;){var r=e.shift();if("function"!=typeof r){var n=r.func;"number"==typeof n?void 0===r.arg?B.get(n)():B.get(n)(r.arg):n(void 0===r.arg?null:r.arg)}else r(t)}}function le(){var e=new Error;if(!e.stack){try{throw new Error}catch(r){e=r}if(!e.stack)return"(no stack trace available)"}return e.stack.toString()}oe(ue)||(ue=function(e){return t.locateFile?t.locateFile(e,g):g+e}(ue));var de={splitPath:function(e){return/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/.exec(e).slice(1)},normalizeArray:function(e,r){for(var t=0,n=e.length-1;n>=0;n--){var o=e[n];"."===o?e.splice(n,1):".."===o?(e.splice(n,1),t++):t&&(e.splice(n,1),t--)}if(r)for(;t;t--)e.unshift("..");return e},normalize:function(e){var r="/"===e.charAt(0),t="/"===e.substr(-1);return(e=de.normalizeArray(e.split("/").filter((function(e){return!!e})),!r).join("/"))||r||(e="."),e&&t&&(e+="/"),(r?"/":"")+e},dirname:function(e){var r=de.splitPath(e),t=r[0],n=r[1];return t||n?(n&&(n=n.substr(0,n.length-1)),t+n):"."},basename:function(e){if("/"===e)return"/";var r=(e=(e=de.normalize(e)).replace(/\/$/,"")).lastIndexOf("/");return-1===r?e:e.substr(r+1)},extname:function(e){return de.splitPath(e)[3]},join:function(){var e=Array.prototype.slice.call(arguments,0);return de.normalize(e.join("/"))},join2:function(e,r){return de.normalize(e+"/"+r)}};var pe={resolve:function(){for(var e="",r=!1,t=arguments.length-1;t>=-1&&!r;t--){var n=t>=0?arguments[t]:ge.cwd();if("string"!=typeof n)throw new TypeError("Arguments to path.resolve must be strings");if(!n)return"";e=n+"/"+e,r="/"===n.charAt(0)}return(r?"/":"")+(e=de.normalizeArray(e.split("/").filter((function(e){return!!e})),!r).join("/"))||"."},relative:function(e,r){function t(e){for(var r=0;r<e.length&&""===e[r];r++);for(var t=e.length-1;t>=0&&""===e[t];t--);return r>t?[]:e.slice(r,t-r+1)}e=pe.resolve(e).substr(1),r=pe.resolve(r).substr(1);for(var n=t(e.split("/")),o=t(r.split("/")),a=Math.min(n.length,o.length),i=a,s=0;s<a;s++)if(n[s]!==o[s]){i=s;break}var u=[];for(s=i;s<n.length;s++)u.push("..");return(u=u.concat(o.slice(i))).join("/")}},he={ttys:[],init:function(){},shutdown:function(){},register:function(e,r){he.ttys[e]={input:[],output:[],ops:r},ge.registerDevice(e,he.stream_ops)},stream_ops:{open:function(e){var r=he.ttys[e.node.rdev];if(!r)throw new ge.ErrnoError(43);e.tty=r,e.seekable=!1},close:function(e){e.tty.ops.flush(e.tty)},flush:function(e){e.tty.ops.flush(e.tty)},read:function(e,r,t,n,o){if(!e.tty||!e.tty.ops.get_char)throw new ge.ErrnoError(60);for(var a=0,i=0;i<n;i++){var s;try{s=e.tty.ops.get_char(e.tty)}catch(e){throw new ge.ErrnoError(29)}if(void 0===s&&0===a)throw new ge.ErrnoError(6);if(null==s)break;a++,r[t+i]=s}return a&&(e.node.timestamp=Date.now()),a},write:function(e,r,t,n,o){if(!e.tty||!e.tty.ops.put_char)throw new ge.ErrnoError(60);try{for(var a=0;a<n;a++)e.tty.ops.put_char(e.tty,r[t+a])}catch(e){throw new ge.ErrnoError(29)}return n&&(e.node.timestamp=Date.now()),a}},default_tty_ops:{get_char:function(e){if(!e.input.length){var r=null;if(c){var t=Buffer.alloc?Buffer.alloc(256):new Buffer(256),n=0;try{n=m.readSync(process.stdin.fd,t,0,256,null)}catch(e){if(-1==e.toString().indexOf("EOF"))throw e;n=0}r=n>0?t.slice(0,n).toString("utf-8"):null}else"undefined"!=typeof window&&"function"==typeof window.prompt?null!==(r=window.prompt("Input: "))&&(r+="\n"):"function"==typeof readline&&null!==(r=readline())&&(r+="\n");if(!r)return null;e.input=Xr(r,!0)}return e.input.shift()},put_char:function(e,r){null===r||10===r?(y(C(e.output,0)),e.output=[]):0!=r&&e.output.push(r)},flush:function(e){e.output&&e.output.length>0&&(y(C(e.output,0)),e.output=[])}},default_tty1_ops:{put_char:function(e,r){null===r||10===r?(w(C(e.output,0)),e.output=[]):0!=r&&e.output.push(r)},flush:function(e){e.output&&e.output.length>0&&(w(C(e.output,0)),e.output=[])}}};function me(e){for(var r=function(e,r){return r||(r=16),Math.ceil(e/r)*r}(e,16384),t=Yr(r);e<r;)$[t+e++]=0;return t}var ve={ops_table:null,mount:function(e){return ve.createNode(null,"/",16895,0)},createNode:function(e,r,t,n){if(ge.isBlkdev(t)||ge.isFIFO(t))throw new ge.ErrnoError(63);ve.ops_table||(ve.ops_table={dir:{node:{getattr:ve.node_ops.getattr,setattr:ve.node_ops.setattr,lookup:ve.node_ops.lookup,mknod:ve.node_ops.mknod,rename:ve.node_ops.rename,unlink:ve.node_ops.unlink,rmdir:ve.node_ops.rmdir,readdir:ve.node_ops.readdir,symlink:ve.node_ops.symlink},stream:{llseek:ve.stream_ops.llseek}},file:{node:{getattr:ve.node_ops.getattr,setattr:ve.node_ops.setattr},stream:{llseek:ve.stream_ops.llseek,read:ve.stream_ops.read,write:ve.stream_ops.write,allocate:ve.stream_ops.allocate,mmap:ve.stream_ops.mmap,msync:ve.stream_ops.msync}},link:{node:{getattr:ve.node_ops.getattr,setattr:ve.node_ops.setattr,readlink:ve.node_ops.readlink},stream:{}},chrdev:{node:{getattr:ve.node_ops.getattr,setattr:ve.node_ops.setattr},stream:ge.chrdev_stream_ops}});var o=ge.createNode(e,r,t,n);return ge.isDir(o.mode)?(o.node_ops=ve.ops_table.dir.node,o.stream_ops=ve.ops_table.dir.stream,o.contents={}):ge.isFile(o.mode)?(o.node_ops=ve.ops_table.file.node,o.stream_ops=ve.ops_table.file.stream,o.usedBytes=0,o.contents=null):ge.isLink(o.mode)?(o.node_ops=ve.ops_table.link.node,o.stream_ops=ve.ops_table.link.stream):ge.isChrdev(o.mode)&&(o.node_ops=ve.ops_table.chrdev.node,o.stream_ops=ve.ops_table.chrdev.stream),o.timestamp=Date.now(),e&&(e.contents[r]=o,e.timestamp=o.timestamp),o},getFileDataAsTypedArray:function(e){return e.contents?e.contents.subarray?e.contents.subarray(0,e.usedBytes):new Uint8Array(e.contents):new Uint8Array(0)},expandFileStorage:function(e,r){var t=e.contents?e.contents.length:0;if(!(t>=r)){r=Math.max(r,t*(t<1048576?2:1.125)>>>0),0!=t&&(r=Math.max(r,256));var n=e.contents;e.contents=new Uint8Array(r),e.usedBytes>0&&e.contents.set(n.subarray(0,e.usedBytes),0)}},resizeFileStorage:function(e,r){if(e.usedBytes!=r)if(0==r)e.contents=null,e.usedBytes=0;else{var t=e.contents;e.contents=new Uint8Array(r),t&&e.contents.set(t.subarray(0,Math.min(r,e.usedBytes))),e.usedBytes=r}},node_ops:{getattr:function(e){var r={};return r.dev=ge.isChrdev(e.mode)?e.id:1,r.ino=e.id,r.mode=e.mode,r.nlink=1,r.uid=0,r.gid=0,r.rdev=e.rdev,ge.isDir(e.mode)?r.size=4096:ge.isFile(e.mode)?r.size=e.usedBytes:ge.isLink(e.mode)?r.size=e.link.length:r.size=0,r.atime=new Date(e.timestamp),r.mtime=new Date(e.timestamp),r.ctime=new Date(e.timestamp),r.blksize=4096,r.blocks=Math.ceil(r.size/r.blksize),r},setattr:function(e,r){void 0!==r.mode&&(e.mode=r.mode),void 0!==r.timestamp&&(e.timestamp=r.timestamp),void 0!==r.size&&ve.resizeFileStorage(e,r.size)},lookup:function(e,r){throw ge.genericErrors[44]},mknod:function(e,r,t,n){return ve.createNode(e,r,t,n)},rename:function(e,r,t){if(ge.isDir(e.mode)){var n;try{n=ge.lookupNode(r,t)}catch(e){}if(n)for(var o in n.contents)throw new ge.ErrnoError(55)}delete e.parent.contents[e.name],e.parent.timestamp=Date.now(),e.name=t,r.contents[t]=e,r.timestamp=e.parent.timestamp,e.parent=r},unlink:function(e,r){delete e.contents[r],e.timestamp=Date.now()},rmdir:function(e,r){var t=ge.lookupNode(e,r);for(var n in t.contents)throw new ge.ErrnoError(55);delete e.contents[r],e.timestamp=Date.now()},readdir:function(e){var r=[".",".."];for(var t in e.contents)e.contents.hasOwnProperty(t)&&r.push(t);return r},symlink:function(e,r,t){var n=ve.createNode(e,r,41471,0);return n.link=t,n},readlink:function(e){if(!ge.isLink(e.mode))throw new ge.ErrnoError(28);return e.link}},stream_ops:{read:function(e,r,t,n,o){var a=e.node.contents;if(o>=e.node.usedBytes)return 0;var i=Math.min(e.node.usedBytes-o,n);if(i>8&&a.subarray)r.set(a.subarray(o,o+i),t);else for(var s=0;s<i;s++)r[t+s]=a[o+s];return i},write:function(e,r,t,n,o,a){if(!n)return 0;var i=e.node;if(i.timestamp=Date.now(),r.subarray&&(!i.contents||i.contents.subarray)){if(a)return i.contents=r.subarray(t,t+n),i.usedBytes=n,n;if(0===i.usedBytes&&0===o)return i.contents=r.slice(t,t+n),i.usedBytes=n,n;if(o+n<=i.usedBytes)return i.contents.set(r.subarray(t,t+n),o),n}if(ve.expandFileStorage(i,o+n),i.contents.subarray&&r.subarray)i.contents.set(r.subarray(t,t+n),o);else for(var s=0;s<n;s++)i.contents[o+s]=r[t+s];return i.usedBytes=Math.max(i.usedBytes,o+n),n},llseek:function(e,r,t){var n=r;if(1===t?n+=e.position:2===t&&ge.isFile(e.node.mode)&&(n+=e.node.usedBytes),n<0)throw new ge.ErrnoError(28);return n},allocate:function(e,r,t){ve.expandFileStorage(e.node,r+t),e.node.usedBytes=Math.max(e.node.usedBytes,r+t)},mmap:function(e,r,t,n,o,a){if(0!==r)throw new ge.ErrnoError(28);if(!ge.isFile(e.node.mode))throw new ge.ErrnoError(43);var i,s,u=e.node.contents;if(2&a||u.buffer!==x){if((n>0||n+t<u.length)&&(u=u.subarray?u.subarray(n,n+t):Array.prototype.slice.call(u,n,n+t)),s=!0,!(i=me(t)))throw new ge.ErrnoError(48);$.set(u,i)}else s=!1,i=u.byteOffset;return{ptr:i,allocated:s}},msync:function(e,r,t,n,o){if(!ge.isFile(e.node.mode))throw new ge.ErrnoError(43);return 2&o||ve.stream_ops.write(e,r,0,n,t,!1),0}}},ge={root:null,mounts:[],devices:{},streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:!1,ignorePermissions:!0,trackingDelegate:{},tracking:{openFlags:{READ:1,WRITE:2}},ErrnoError:null,genericErrors:{},filesystems:null,syncFSRequests:0,lookupPath:function(e,r){if(r=r||{},!(e=pe.resolve(ge.cwd(),e)))return{path:"",node:null};var t={follow_mount:!0,recurse_count:0};for(var n in t)void 0===r[n]&&(r[n]=t[n]);if(r.recurse_count>8)throw new ge.ErrnoError(32);for(var o=de.normalizeArray(e.split("/").filter((function(e){return!!e})),!1),a=ge.root,i="/",s=0;s<o.length;s++){var u=s===o.length-1;if(u&&r.parent)break;if(a=ge.lookupNode(a,o[s]),i=de.join2(i,o[s]),ge.isMountpoint(a)&&(!u||u&&r.follow_mount)&&(a=a.mounted.root),!u||r.follow)for(var c=0;ge.isLink(a.mode);){var f=ge.readlink(i);if(i=pe.resolve(de.dirname(i),f),a=ge.lookupPath(i,{recurse_count:r.recurse_count}).node,c++>40)throw new ge.ErrnoError(32)}}return{path:i,node:a}},getPath:function(e){for(var r;;){if(ge.isRoot(e)){var t=e.mount.mountpoint;return r?"/"!==t[t.length-1]?t+"/"+r:t+r:t}r=r?e.name+"/"+r:e.name,e=e.parent}},hashName:function(e,r){for(var t=0,n=0;n<r.length;n++)t=(t<<5)-t+r.charCodeAt(n)|0;return(e+t>>>0)%ge.nameTable.length},hashAddNode:function(e){var r=ge.hashName(e.parent.id,e.name);e.name_next=ge.nameTable[r],ge.nameTable[r]=e},hashRemoveNode:function(e){var r=ge.hashName(e.parent.id,e.name);if(ge.nameTable[r]===e)ge.nameTable[r]=e.name_next;else for(var t=ge.nameTable[r];t;){if(t.name_next===e){t.name_next=e.name_next;break}t=t.name_next}},lookupNode:function(e,r){var t=ge.mayLookup(e);if(t)throw new ge.ErrnoError(t,e);for(var n=ge.hashName(e.id,r),o=ge.nameTable[n];o;o=o.name_next){var a=o.name;if(o.parent.id===e.id&&a===r)return o}return ge.lookup(e,r)},createNode:function(e,r,t,n){var o=new ge.FSNode(e,r,t,n);return ge.hashAddNode(o),o},destroyNode:function(e){ge.hashRemoveNode(e)},isRoot:function(e){return e===e.parent},isMountpoint:function(e){return!!e.mounted},isFile:function(e){return 32768==(61440&e)},isDir:function(e){return 16384==(61440&e)},isLink:function(e){return 40960==(61440&e)},isChrdev:function(e){return 8192==(61440&e)},isBlkdev:function(e){return 24576==(61440&e)},isFIFO:function(e){return 4096==(61440&e)},isSocket:function(e){return 49152==(49152&e)},flagModes:{r:0,"r+":2,w:577,"w+":578,a:1089,"a+":1090},modeStringToFlags:function(e){var r=ge.flagModes[e];if(void 0===r)throw new Error("Unknown file open mode: "+e);return r},flagsToPermissionString:function(e){var r=["r","w","rw"][3&e];return 512&e&&(r+="w"),r},nodePermissions:function(e,r){return ge.ignorePermissions||(-1===r.indexOf("r")||292&e.mode)&&(-1===r.indexOf("w")||146&e.mode)&&(-1===r.indexOf("x")||73&e.mode)?0:2},mayLookup:function(e){var r=ge.nodePermissions(e,"x");return r||(e.node_ops.lookup?0:2)},mayCreate:function(e,r){try{ge.lookupNode(e,r);return 20}catch(e){}return ge.nodePermissions(e,"wx")},mayDelete:function(e,r,t){var n;try{n=ge.lookupNode(e,r)}catch(e){return e.errno}var o=ge.nodePermissions(e,"wx");if(o)return o;if(t){if(!ge.isDir(n.mode))return 54;if(ge.isRoot(n)||ge.getPath(n)===ge.cwd())return 10}else if(ge.isDir(n.mode))return 31;return 0},mayOpen:function(e,r){return e?ge.isLink(e.mode)?32:ge.isDir(e.mode)&&("r"!==ge.flagsToPermissionString(r)||512&r)?31:ge.nodePermissions(e,ge.flagsToPermissionString(r)):44},MAX_OPEN_FDS:4096,nextfd:function(e,r){e=e||0,r=r||ge.MAX_OPEN_FDS;for(var t=e;t<=r;t++)if(!ge.streams[t])return t;throw new ge.ErrnoError(33)},getStream:function(e){return ge.streams[e]},createStream:function(e,r,t){ge.FSStream||(ge.FSStream=function(){},ge.FSStream.prototype={object:{get:function(){return this.node},set:function(e){this.node=e}},isRead:{get:function(){return 1!=(2097155&this.flags)}},isWrite:{get:function(){return 0!=(2097155&this.flags)}},isAppend:{get:function(){return 1024&this.flags}}});var n=new ge.FSStream;for(var o in e)n[o]=e[o];e=n;var a=ge.nextfd(r,t);return e.fd=a,ge.streams[a]=e,e},closeStream:function(e){ge.streams[e]=null},chrdev_stream_ops:{open:function(e){var r=ge.getDevice(e.node.rdev);e.stream_ops=r.stream_ops,e.stream_ops.open&&e.stream_ops.open(e)},llseek:function(){throw new ge.ErrnoError(70)}},major:function(e){return e>>8},minor:function(e){return 255&e},makedev:function(e,r){return e<<8|r},registerDevice:function(e,r){ge.devices[e]={stream_ops:r}},getDevice:function(e){return ge.devices[e]},getMounts:function(e){for(var r=[],t=[e];t.length;){var n=t.pop();r.push(n),t.push.apply(t,n.mounts)}return r},syncfs:function(e,r){"function"==typeof e&&(r=e,e=!1),ge.syncFSRequests++,ge.syncFSRequests>1&&w("warning: "+ge.syncFSRequests+" FS.syncfs operations in flight at once, probably just doing extra work");var t=ge.getMounts(ge.root.mount),n=0;function o(e){return ge.syncFSRequests--,r(e)}function a(e){if(e)return a.errored?void 0:(a.errored=!0,o(e));++n>=t.length&&o(null)}t.forEach((function(r){if(!r.type.syncfs)return a(null);r.type.syncfs(r,e,a)}))},mount:function(e,r,t){var n,o="/"===t,a=!t;if(o&&ge.root)throw new ge.ErrnoError(10);if(!o&&!a){var i=ge.lookupPath(t,{follow_mount:!1});if(t=i.path,n=i.node,ge.isMountpoint(n))throw new ge.ErrnoError(10);if(!ge.isDir(n.mode))throw new ge.ErrnoError(54)}var s={type:e,opts:r,mountpoint:t,mounts:[]},u=e.mount(s);return u.mount=s,s.root=u,o?ge.root=u:n&&(n.mounted=s,n.mount&&n.mount.mounts.push(s)),u},unmount:function(e){var r=ge.lookupPath(e,{follow_mount:!1});if(!ge.isMountpoint(r.node))throw new ge.ErrnoError(28);var t=r.node,n=t.mounted,o=ge.getMounts(n);Object.keys(ge.nameTable).forEach((function(e){for(var r=ge.nameTable[e];r;){var t=r.name_next;-1!==o.indexOf(r.mount)&&ge.destroyNode(r),r=t}})),t.mounted=null;var a=t.mount.mounts.indexOf(n);t.mount.mounts.splice(a,1)},lookup:function(e,r){return e.node_ops.lookup(e,r)},mknod:function(e,r,t){var n=ge.lookupPath(e,{parent:!0}).node,o=de.basename(e);if(!o||"."===o||".."===o)throw new ge.ErrnoError(28);var a=ge.mayCreate(n,o);if(a)throw new ge.ErrnoError(a);if(!n.node_ops.mknod)throw new ge.ErrnoError(63);return n.node_ops.mknod(n,o,r,t)},create:function(e,r){return r=void 0!==r?r:438,r&=4095,r|=32768,ge.mknod(e,r,0)},mkdir:function(e,r){return r=void 0!==r?r:511,r&=1023,r|=16384,ge.mknod(e,r,0)},mkdirTree:function(e,r){for(var t=e.split("/"),n="",o=0;o<t.length;++o)if(t[o]){n+="/"+t[o];try{ge.mkdir(n,r)}catch(e){if(20!=e.errno)throw e}}},mkdev:function(e,r,t){return void 0===t&&(t=r,r=438),r|=8192,ge.mknod(e,r,t)},symlink:function(e,r){if(!pe.resolve(e))throw new ge.ErrnoError(44);var t=ge.lookupPath(r,{parent:!0}).node;if(!t)throw new ge.ErrnoError(44);var n=de.basename(r),o=ge.mayCreate(t,n);if(o)throw new ge.ErrnoError(o);if(!t.node_ops.symlink)throw new ge.ErrnoError(63);return t.node_ops.symlink(t,n,e)},rename:function(e,r){var t,n,o=de.dirname(e),a=de.dirname(r),i=de.basename(e),s=de.basename(r);if(t=ge.lookupPath(e,{parent:!0}).node,n=ge.lookupPath(r,{parent:!0}).node,!t||!n)throw new ge.ErrnoError(44);if(t.mount!==n.mount)throw new ge.ErrnoError(75);var u,c=ge.lookupNode(t,i),f=pe.relative(e,a);if("."!==f.charAt(0))throw new ge.ErrnoError(28);if("."!==(f=pe.relative(r,o)).charAt(0))throw new ge.ErrnoError(55);try{u=ge.lookupNode(n,s)}catch(e){}if(c!==u){var l=ge.isDir(c.mode),d=ge.mayDelete(t,i,l);if(d)throw new ge.ErrnoError(d);if(d=u?ge.mayDelete(n,s,l):ge.mayCreate(n,s))throw new ge.ErrnoError(d);if(!t.node_ops.rename)throw new ge.ErrnoError(63);if(ge.isMountpoint(c)||u&&ge.isMountpoint(u))throw new ge.ErrnoError(10);if(n!==t&&(d=ge.nodePermissions(t,"w")))throw new ge.ErrnoError(d);try{ge.trackingDelegate.willMovePath}catch(t){w("FS.trackingDelegate['willMovePath']('"+e+"', '"+r+"') threw an exception: "+t.message)}ge.hashRemoveNode(c);try{t.node_ops.rename(c,n,s)}catch(e){throw e}finally{ge.hashAddNode(c)}try{ge.trackingDelegate.onMovePath}catch(t){w("FS.trackingDelegate['onMovePath']('"+e+"', '"+r+"') threw an exception: "+t.message)}}},rmdir:function(e){var r=ge.lookupPath(e,{parent:!0}).node,t=de.basename(e),n=ge.lookupNode(r,t),o=ge.mayDelete(r,t,!0);if(o)throw new ge.ErrnoError(o);if(!r.node_ops.rmdir)throw new ge.ErrnoError(63);if(ge.isMountpoint(n))throw new ge.ErrnoError(10);try{ge.trackingDelegate.willDeletePath}catch(r){w("FS.trackingDelegate['willDeletePath']('"+e+"') threw an exception: "+r.message)}r.node_ops.rmdir(r,t),ge.destroyNode(n);try{ge.trackingDelegate.onDeletePath}catch(r){w("FS.trackingDelegate['onDeletePath']('"+e+"') threw an exception: "+r.message)}},readdir:function(e){var r=ge.lookupPath(e,{follow:!0}).node;if(!r.node_ops.readdir)throw new ge.ErrnoError(54);return r.node_ops.readdir(r)},unlink:function(e){var r=ge.lookupPath(e,{parent:!0}).node,t=de.basename(e),n=ge.lookupNode(r,t),o=ge.mayDelete(r,t,!1);if(o)throw new ge.ErrnoError(o);if(!r.node_ops.unlink)throw new ge.ErrnoError(63);if(ge.isMountpoint(n))throw new ge.ErrnoError(10);try{ge.trackingDelegate.willDeletePath}catch(r){w("FS.trackingDelegate['willDeletePath']('"+e+"') threw an exception: "+r.message)}r.node_ops.unlink(r,t),ge.destroyNode(n);try{ge.trackingDelegate.onDeletePath}catch(r){w("FS.trackingDelegate['onDeletePath']('"+e+"') threw an exception: "+r.message)}},readlink:function(e){var r=ge.lookupPath(e).node;if(!r)throw new ge.ErrnoError(44);if(!r.node_ops.readlink)throw new ge.ErrnoError(28);return pe.resolve(ge.getPath(r.parent),r.node_ops.readlink(r))},stat:function(e,r){var t=ge.lookupPath(e,{follow:!r}).node;if(!t)throw new ge.ErrnoError(44);if(!t.node_ops.getattr)throw new ge.ErrnoError(63);return t.node_ops.getattr(t)},lstat:function(e){return ge.stat(e,!0)},chmod:function(e,r,t){var n;"string"==typeof e?n=ge.lookupPath(e,{follow:!t}).node:n=e;if(!n.node_ops.setattr)throw new ge.ErrnoError(63);n.node_ops.setattr(n,{mode:4095&r|-4096&n.mode,timestamp:Date.now()})},lchmod:function(e,r){ge.chmod(e,r,!0)},fchmod:function(e,r){var t=ge.getStream(e);if(!t)throw new ge.ErrnoError(8);ge.chmod(t.node,r)},chown:function(e,r,t,n){var o;"string"==typeof e?o=ge.lookupPath(e,{follow:!n}).node:o=e;if(!o.node_ops.setattr)throw new ge.ErrnoError(63);o.node_ops.setattr(o,{timestamp:Date.now()})},lchown:function(e,r,t){ge.chown(e,r,t,!0)},fchown:function(e,r,t){var n=ge.getStream(e);if(!n)throw new ge.ErrnoError(8);ge.chown(n.node,r,t)},truncate:function(e,r){if(r<0)throw new ge.ErrnoError(28);var t;"string"==typeof e?t=ge.lookupPath(e,{follow:!0}).node:t=e;if(!t.node_ops.setattr)throw new ge.ErrnoError(63);if(ge.isDir(t.mode))throw new ge.ErrnoError(31);if(!ge.isFile(t.mode))throw new ge.ErrnoError(28);var n=ge.nodePermissions(t,"w");if(n)throw new ge.ErrnoError(n);t.node_ops.setattr(t,{size:r,timestamp:Date.now()})},ftruncate:function(e,r){var t=ge.getStream(e);if(!t)throw new ge.ErrnoError(8);if(0==(2097155&t.flags))throw new ge.ErrnoError(28);ge.truncate(t.node,r)},utime:function(e,r,t){var n=ge.lookupPath(e,{follow:!0}).node;n.node_ops.setattr(n,{timestamp:Math.max(r,t)})},open:function(e,r,n,o,a){if(""===e)throw new ge.ErrnoError(44);var i;if(n=void 0===n?438:n,n=64&(r="string"==typeof r?ge.modeStringToFlags(r):r)?4095&n|32768:0,"object"==typeof e)i=e;else{e=de.normalize(e);try{i=ge.lookupPath(e,{follow:!(131072&r)}).node}catch(e){}}var s=!1;if(64&r)if(i){if(128&r)throw new ge.ErrnoError(20)}else i=ge.mknod(e,n,0),s=!0;if(!i)throw new ge.ErrnoError(44);if(ge.isChrdev(i.mode)&&(r&=-513),65536&r&&!ge.isDir(i.mode))throw new ge.ErrnoError(54);if(!s){var u=ge.mayOpen(i,r);if(u)throw new ge.ErrnoError(u)}512&r&&ge.truncate(i,0),r&=-131713;var c=ge.createStream({node:i,path:ge.getPath(i),flags:r,seekable:!0,position:0,stream_ops:i.stream_ops,ungotten:[],error:!1},o,a);c.stream_ops.open&&c.stream_ops.open(c),!t.logReadFiles||1&r||(ge.readFiles||(ge.readFiles={}),e in ge.readFiles||(ge.readFiles[e]=1,w("FS.trackingDelegate error on read file: "+e)));try{ge.trackingDelegate.onOpenFile}catch(r){w("FS.trackingDelegate['onOpenFile']('"+e+"', flags) threw an exception: "+r.message)}return c},close:function(e){if(ge.isClosed(e))throw new ge.ErrnoError(8);e.getdents&&(e.getdents=null);try{e.stream_ops.close&&e.stream_ops.close(e)}catch(e){throw e}finally{ge.closeStream(e.fd)}e.fd=null},isClosed:function(e){return null===e.fd},llseek:function(e,r,t){if(ge.isClosed(e))throw new ge.ErrnoError(8);if(!e.seekable||!e.stream_ops.llseek)throw new ge.ErrnoError(70);if(0!=t&&1!=t&&2!=t)throw new ge.ErrnoError(28);return e.position=e.stream_ops.llseek(e,r,t),e.ungotten=[],e.position},read:function(e,r,t,n,o){if(n<0||o<0)throw new ge.ErrnoError(28);if(ge.isClosed(e))throw new ge.ErrnoError(8);if(1==(2097155&e.flags))throw new ge.ErrnoError(8);if(ge.isDir(e.node.mode))throw new ge.ErrnoError(31);if(!e.stream_ops.read)throw new ge.ErrnoError(28);var a=void 0!==o;if(a){if(!e.seekable)throw new ge.ErrnoError(70)}else o=e.position;var i=e.stream_ops.read(e,r,t,n,o);return a||(e.position+=i),i},write:function(e,r,t,n,o,a){if(n<0||o<0)throw new ge.ErrnoError(28);if(ge.isClosed(e))throw new ge.ErrnoError(8);if(0==(2097155&e.flags))throw new ge.ErrnoError(8);if(ge.isDir(e.node.mode))throw new ge.ErrnoError(31);if(!e.stream_ops.write)throw new ge.ErrnoError(28);e.seekable&&1024&e.flags&&ge.llseek(e,0,2);var i=void 0!==o;if(i){if(!e.seekable)throw new ge.ErrnoError(70)}else o=e.position;var s=e.stream_ops.write(e,r,t,n,o,a);i||(e.position+=s);try{e.path&&ge.trackingDelegate.onWriteToFile&&ge.trackingDelegate.onWriteToFile(e.path)}catch(r){w("FS.trackingDelegate['onWriteToFile']('"+e.path+"') threw an exception: "+r.message)}return s},allocate:function(e,r,t){if(ge.isClosed(e))throw new ge.ErrnoError(8);if(r<0||t<=0)throw new ge.ErrnoError(28);if(0==(2097155&e.flags))throw new ge.ErrnoError(8);if(!ge.isFile(e.node.mode)&&!ge.isDir(e.node.mode))throw new ge.ErrnoError(43);if(!e.stream_ops.allocate)throw new ge.ErrnoError(138);e.stream_ops.allocate(e,r,t)},mmap:function(e,r,t,n,o,a){if(0!=(2&o)&&0==(2&a)&&2!=(2097155&e.flags))throw new ge.ErrnoError(2);if(1==(2097155&e.flags))throw new ge.ErrnoError(2);if(!e.stream_ops.mmap)throw new ge.ErrnoError(43);return e.stream_ops.mmap(e,r,t,n,o,a)},msync:function(e,r,t,n,o){return e&&e.stream_ops.msync?e.stream_ops.msync(e,r,t,n,o):0},munmap:function(e){return 0},ioctl:function(e,r,t){if(!e.stream_ops.ioctl)throw new ge.ErrnoError(59);return e.stream_ops.ioctl(e,r,t)},readFile:function(e,r){if((r=r||{}).flags=r.flags||0,r.encoding=r.encoding||"binary","utf8"!==r.encoding&&"binary"!==r.encoding)throw new Error('Invalid encoding type "'+r.encoding+'"');var t,n=ge.open(e,r.flags),o=ge.stat(e).size,a=new Uint8Array(o);return ge.read(n,a,0,o,0),"utf8"===r.encoding?t=C(a,0):"binary"===r.encoding&&(t=a),ge.close(n),t},writeFile:function(e,r,t){(t=t||{}).flags=t.flags||577;var n=ge.open(e,t.flags,t.mode);if("string"==typeof r){var o=new Uint8Array(F(r)+1),a=D(r,o,0,o.length);ge.write(n,o,0,a,void 0,t.canOwn)}else{if(!ArrayBuffer.isView(r))throw new Error("Unsupported data type");ge.write(n,r,0,r.byteLength,void 0,t.canOwn)}ge.close(n)},cwd:function(){return ge.currentPath},chdir:function(e){var r=ge.lookupPath(e,{follow:!0});if(null===r.node)throw new ge.ErrnoError(44);if(!ge.isDir(r.node.mode))throw new ge.ErrnoError(54);var t=ge.nodePermissions(r.node,"x");if(t)throw new ge.ErrnoError(t);ge.currentPath=r.path},createDefaultDirectories:function(){ge.mkdir("/tmp"),ge.mkdir("/home"),ge.mkdir("/home/web_user")},createDefaultDevices:function(){ge.mkdir("/dev"),ge.registerDevice(ge.makedev(1,3),{read:function(){return 0},write:function(e,r,t,n,o){return n}}),ge.mkdev("/dev/null",ge.makedev(1,3)),he.register(ge.makedev(5,0),he.default_tty_ops),he.register(ge.makedev(6,0),he.default_tty1_ops),ge.mkdev("/dev/tty",ge.makedev(5,0)),ge.mkdev("/dev/tty1",ge.makedev(6,0));var e=function(){if("object"==typeof crypto&&"function"==typeof crypto.getRandomValues){var e=new Uint8Array(1);return function(){return crypto.getRandomValues(e),e[0]}}if(c)try{var r=i.default;return function(){return r.randomBytes(1)[0]}}catch(e){}return function(){te("randomDevice")}}();ge.createDevice("/dev","random",e),ge.createDevice("/dev","urandom",e),ge.mkdir("/dev/shm"),ge.mkdir("/dev/shm/tmp")},createSpecialDirectories:function(){ge.mkdir("/proc");var e=ge.mkdir("/proc/self");ge.mkdir("/proc/self/fd"),ge.mount({mount:function(){var r=ge.createNode(e,"fd",16895,73);return r.node_ops={lookup:function(e,r){var t=+r,n=ge.getStream(t);if(!n)throw new ge.ErrnoError(8);var o={parent:null,mount:{mountpoint:"fake"},node_ops:{readlink:function(){return n.path}}};return o.parent=o,o}},r}},{},"/proc/self/fd")},createStandardStreams:function(){t.stdin?ge.createDevice("/dev","stdin",t.stdin):ge.symlink("/dev/tty","/dev/stdin"),t.stdout?ge.createDevice("/dev","stdout",null,t.stdout):ge.symlink("/dev/tty","/dev/stdout"),t.stderr?ge.createDevice("/dev","stderr",null,t.stderr):ge.symlink("/dev/tty1","/dev/stderr"),ge.open("/dev/stdin",0),ge.open("/dev/stdout",1),ge.open("/dev/stderr",1)},ensureErrnoError:function(){ge.ErrnoError||(ge.ErrnoError=function(e,r){this.node=r,this.setErrno=function(e){this.errno=e},this.setErrno(e),this.message="FS error"},ge.ErrnoError.prototype=new Error,ge.ErrnoError.prototype.constructor=ge.ErrnoError,[44].forEach((function(e){ge.genericErrors[e]=new ge.ErrnoError(e),ge.genericErrors[e].stack="<generic error, no stack>"})))},staticInit:function(){ge.ensureErrnoError(),ge.nameTable=new Array(4096),ge.mount(ve,{},"/"),ge.createDefaultDirectories(),ge.createDefaultDevices(),ge.createSpecialDirectories(),ge.filesystems={MEMFS:ve}},init:function(e,r,n){ge.init.initialized=!0,ge.ensureErrnoError(),t.stdin=e||t.stdin,t.stdout=r||t.stdout,t.stderr=n||t.stderr,ge.createStandardStreams()},quit:function(){ge.init.initialized=!1;var e=t._fflush;e&&e(0);for(var r=0;r<ge.streams.length;r++){var n=ge.streams[r];n&&ge.close(n)}},getMode:function(e,r){var t=0;return e&&(t|=365),r&&(t|=146),t},findObject:function(e,r){var t=ge.analyzePath(e,r);return t.exists?t.object:null},analyzePath:function(e,r){try{e=(n=ge.lookupPath(e,{follow:!r})).path}catch(e){}var t={isRoot:!1,exists:!1,error:0,name:null,path:null,object:null,parentExists:!1,parentPath:null,parentObject:null};try{var n=ge.lookupPath(e,{parent:!0});t.parentExists=!0,t.parentPath=n.path,t.parentObject=n.node,t.name=de.basename(e),n=ge.lookupPath(e,{follow:!r}),t.exists=!0,t.path=n.path,t.object=n.node,t.name=n.node.name,t.isRoot="/"===n.path}catch(e){t.error=e.errno}return t},createPath:function(e,r,t,n){e="string"==typeof e?e:ge.getPath(e);for(var o=r.split("/").reverse();o.length;){var a=o.pop();if(a){var i=de.join2(e,a);try{ge.mkdir(i)}catch(e){}e=i}}return i},createFile:function(e,r,t,n,o){var a=de.join2("string"==typeof e?e:ge.getPath(e),r),i=ge.getMode(n,o);return ge.create(a,i)},createDataFile:function(e,r,t,n,o,a){var i=r?de.join2("string"==typeof e?e:ge.getPath(e),r):e,s=ge.getMode(n,o),u=ge.create(i,s);if(t){if("string"==typeof t){for(var c=new Array(t.length),f=0,l=t.length;f<l;++f)c[f]=t.charCodeAt(f);t=c}ge.chmod(u,146|s);var d=ge.open(u,577);ge.write(d,t,0,t.length,0,a),ge.close(d),ge.chmod(u,s)}return u},createDevice:function(e,r,t,n){var o=de.join2("string"==typeof e?e:ge.getPath(e),r),a=ge.getMode(!!t,!!n);ge.createDevice.major||(ge.createDevice.major=64);var i=ge.makedev(ge.createDevice.major++,0);return ge.registerDevice(i,{open:function(e){e.seekable=!1},close:function(e){n&&n.buffer&&n.buffer.length&&n(10)},read:function(e,r,n,o,a){for(var i=0,s=0;s<o;s++){var u;try{u=t()}catch(e){throw new ge.ErrnoError(29)}if(void 0===u&&0===i)throw new ge.ErrnoError(6);if(null==u)break;i++,r[n+s]=u}return i&&(e.node.timestamp=Date.now()),i},write:function(e,r,t,o,a){for(var i=0;i<o;i++)try{n(r[t+i])}catch(e){throw new ge.ErrnoError(29)}return o&&(e.node.timestamp=Date.now()),i}}),ge.mkdev(o,a,i)},forceLoadFile:function(e){if(e.isDevice||e.isFolder||e.link||e.contents)return!0;if("undefined"!=typeof XMLHttpRequest)throw new Error("Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread.");if(!d)throw new Error("Cannot load without read() or XMLHttpRequest.");try{e.contents=Xr(d(e.url),!0),e.usedBytes=e.contents.length}catch(e){throw new ge.ErrnoError(29)}},createLazyFile:function(e,r,t,n,o){function a(){this.lengthKnown=!1,this.chunks=[]}if(a.prototype.get=function(e){if(!(e>this.length-1||e<0)){var r=e%this.chunkSize,t=e/this.chunkSize|0;return this.getter(t)[r]}},a.prototype.setDataGetter=function(e){this.getter=e},a.prototype.cacheLength=function(){var e=new XMLHttpRequest;if(e.open("HEAD",t,!1),e.send(null),!(e.status>=200&&e.status<300||304===e.status))throw new Error("Couldn't load "+t+". Status: "+e.status);var r,n=Number(e.getResponseHeader("Content-length")),o=(r=e.getResponseHeader("Accept-Ranges"))&&"bytes"===r,a=(r=e.getResponseHeader("Content-Encoding"))&&"gzip"===r,i=1048576;o||(i=n);var s=this;s.setDataGetter((function(e){var r=e*i,o=(e+1)*i-1;if(o=Math.min(o,n-1),void 0===s.chunks[e]&&(s.chunks[e]=function(e,r){if(e>r)throw new Error("invalid range ("+e+", "+r+") or no bytes requested!");if(r>n-1)throw new Error("only "+n+" bytes available! programmer error!");var o=new XMLHttpRequest;if(o.open("GET",t,!1),n!==i&&o.setRequestHeader("Range","bytes="+e+"-"+r),"undefined"!=typeof Uint8Array&&(o.responseType="arraybuffer"),o.overrideMimeType&&o.overrideMimeType("text/plain; charset=x-user-defined"),o.send(null),!(o.status>=200&&o.status<300||304===o.status))throw new Error("Couldn't load "+t+". Status: "+o.status);return void 0!==o.response?new Uint8Array(o.response||[]):Xr(o.responseText||"",!0)}(r,o)),void 0===s.chunks[e])throw new Error("doXHR failed!");return s.chunks[e]})),!a&&n||(i=n=1,n=this.getter(0).length,i=n,y("LazyFiles on gzip forces download of the whole file when length is accessed")),this._length=n,this._chunkSize=i,this.lengthKnown=!0},"undefined"!=typeof XMLHttpRequest){if(!u)throw"Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc";var i=new a;Object.defineProperties(i,{length:{get:function(){return this.lengthKnown||this.cacheLength(),this._length}},chunkSize:{get:function(){return this.lengthKnown||this.cacheLength(),this._chunkSize}}});var s={isDevice:!1,contents:i}}else s={isDevice:!1,url:t};var c=ge.createFile(e,r,s,n,o);s.contents?c.contents=s.contents:s.url&&(c.contents=null,c.url=s.url),Object.defineProperties(c,{usedBytes:{get:function(){return this.contents.length}}});var f={};return Object.keys(c.stream_ops).forEach((function(e){var r=c.stream_ops[e];f[e]=function(){return ge.forceLoadFile(c),r.apply(null,arguments)}})),f.read=function(e,r,t,n,o){ge.forceLoadFile(c);var a=e.node.contents;if(o>=a.length)return 0;var i=Math.min(a.length-o,n);if(a.slice)for(var s=0;s<i;s++)r[t+s]=a[o+s];else for(s=0;s<i;s++)r[t+s]=a.get(o+s);return i},c.stream_ops=f,c},createPreloadedFile:function(e,r,n,o,a,i,s,u,c,f){Browser.init();var l=r?pe.resolve(de.join2(e,r)):e;function d(n){function d(t){f&&f(),u||ge.createDataFile(e,r,t,o,a,c),i&&i(),re()}var p=!1;t.preloadPlugins.forEach((function(e){p||e.canHandle(l)&&(e.handle(n,l,d,(function(){s&&s(),re()})),p=!0)})),p||d(n)}ee(),"string"==typeof n?Browser.asyncLoad(n,(function(e){d(e)}),s):d(n)},indexedDB:function(){return window.indexedDB||window.mozIndexedDB||window.webkitIndexedDB||window.msIndexedDB},DB_NAME:function(){return"EM_FS_"+window.location.pathname},DB_VERSION:20,DB_STORE_NAME:"FILE_DATA",saveFilesToDB:function(e,r,t){r=r||function(){},t=t||function(){};var n=ge.indexedDB();try{var o=n.open(ge.DB_NAME(),ge.DB_VERSION)}catch(e){return t(e)}o.onupgradeneeded=function(){y("creating db"),o.result.createObjectStore(ge.DB_STORE_NAME)},o.onsuccess=function(){var n=o.result.transaction([ge.DB_STORE_NAME],"readwrite"),a=n.objectStore(ge.DB_STORE_NAME),i=0,s=0,u=e.length;function c(){0==s?r():t()}e.forEach((function(e){var r=a.put(ge.analyzePath(e).object.contents,e);r.onsuccess=function(){++i+s==u&&c()},r.onerror=function(){s++,i+s==u&&c()}})),n.onerror=t},o.onerror=t},loadFilesFromDB:function(e,r,t){r=r||function(){},t=t||function(){};var n=ge.indexedDB();try{var o=n.open(ge.DB_NAME(),ge.DB_VERSION)}catch(e){return t(e)}o.onupgradeneeded=t,o.onsuccess=function(){var n=o.result;try{var a=n.transaction([ge.DB_STORE_NAME],"readonly")}catch(e){return void t(e)}var i=a.objectStore(ge.DB_STORE_NAME),s=0,u=0,c=e.length;function f(){0==u?r():t()}e.forEach((function(e){var r=i.get(e);r.onsuccess=function(){ge.analyzePath(e).exists&&ge.unlink(e),ge.createDataFile(de.dirname(e),de.basename(e),r.result,!0,!0,!0),++s+u==c&&f()},r.onerror=function(){u++,s+u==c&&f()}})),a.onerror=t},o.onerror=t}},ye={mappings:{},DEFAULT_POLLMASK:5,umask:511,calculateAt:function(e,r,t){if("/"===r[0])return r;var n;if(-100===e)n=ge.cwd();else{var o=ge.getStream(e);if(!o)throw new ge.ErrnoError(8);n=o.path}if(0==r.length){if(!t)throw new ge.ErrnoError(44);return n}return de.join2(n,r)},doStat:function(e,r,t){try{var n=e(r)}catch(e){if(e&&e.node&&de.normalize(r)!==de.normalize(ge.getPath(e.node)))return-54;throw e}return I[t>>2]=n.dev,I[t+4>>2]=0,I[t+8>>2]=n.ino,I[t+12>>2]=n.mode,I[t+16>>2]=n.nlink,I[t+20>>2]=n.uid,I[t+24>>2]=n.gid,I[t+28>>2]=n.rdev,I[t+32>>2]=0,se=[n.size>>>0,(ie=n.size,+Math.abs(ie)>=1?ie>0?(0|Math.min(+Math.floor(ie/4294967296),4294967295))>>>0:~~+Math.ceil((ie-+(~~ie>>>0))/4294967296)>>>0:0)],I[t+40>>2]=se[0],I[t+44>>2]=se[1],I[t+48>>2]=4096,I[t+52>>2]=n.blocks,I[t+56>>2]=n.atime.getTime()/1e3|0,I[t+60>>2]=0,I[t+64>>2]=n.mtime.getTime()/1e3|0,I[t+68>>2]=0,I[t+72>>2]=n.ctime.getTime()/1e3|0,I[t+76>>2]=0,se=[n.ino>>>0,(ie=n.ino,+Math.abs(ie)>=1?ie>0?(0|Math.min(+Math.floor(ie/4294967296),4294967295))>>>0:~~+Math.ceil((ie-+(~~ie>>>0))/4294967296)>>>0:0)],I[t+80>>2]=se[0],I[t+84>>2]=se[1],0},doMsync:function(e,r,t,n,o){var a=R.slice(e,e+t);ge.msync(r,a,o,t,n)},doMkdir:function(e,r){return"/"===(e=de.normalize(e))[e.length-1]&&(e=e.substr(0,e.length-1)),ge.mkdir(e,r,0),0},doMknod:function(e,r,t){switch(61440&r){case 32768:case 8192:case 24576:case 4096:case 49152:break;default:return-28}return ge.mknod(e,r,t),0},doReadlink:function(e,r,t){if(t<=0)return-28;var n=ge.readlink(e),o=Math.min(t,F(n)),a=$[r+o];return S(n,r,t+1),$[r+o]=a,o},doAccess:function(e,r){if(-8&r)return-28;var t;if(!(t=ge.lookupPath(e,{follow:!0}).node))return-44;var n="";return 4&r&&(n+="r"),2&r&&(n+="w"),1&r&&(n+="x"),n&&ge.nodePermissions(t,n)?-2:0},doDup:function(e,r,t){var n=ge.getStream(t);return n&&ge.close(n),ge.open(e,r,0,t,t).fd},doReadv:function(e,r,t,n){for(var o=0,a=0;a<t;a++){var i=I[r+8*a>>2],s=I[r+(8*a+4)>>2],u=ge.read(e,$,i,s,n);if(u<0)return-1;if(o+=u,u<s)break}return o},doWritev:function(e,r,t,n){for(var o=0,a=0;a<t;a++){var i=I[r+8*a>>2],s=I[r+(8*a+4)>>2],u=ge.write(e,$,i,s,n);if(u<0)return-1;o+=u}return o},varargs:void 0,get:function(){return ye.varargs+=4,I[ye.varargs-4>>2]},getStr:function(e){return A(e)},getStreamFromFD:function(e){var r=ge.getStream(e);if(!r)throw new ge.ErrnoError(8);return r},get64:function(e,r){return e}};function we(e){switch(e){case 1:return 0;case 2:return 1;case 4:return 2;case 8:return 3;default:throw new TypeError("Unknown type size: "+e)}}var Ee=void 0;function be(e){for(var r="",t=e;R[t];)r+=Ee[R[t++]];return r}var _e={},ke={},Te={};function Pe(e){if(void 0===e)return"_unknown";var r=(e=e.replace(/[^a-zA-Z0-9_]/g,"$")).charCodeAt(0);return r>=48&&r<=57?"_"+e:e}function Ce(e,r){return e=Pe(e),new Function("body","return function "+e+'() {\n "use strict"; return body.apply(this, arguments);\n};\n')(r)}function Ae(e,r){var t=Ce(r,(function(e){this.name=r,this.message=e;var t=new Error(e).stack;void 0!==t&&(this.stack=this.toString()+"\n"+t.replace(/^Error(:[^\n]*)?\n/,""))}));return t.prototype=Object.create(e.prototype),t.prototype.constructor=t,t.prototype.toString=function(){return void 0===this.message?this.name:this.name+": "+this.message},t}var De=void 0;function Se(e){throw new De(e)}var Fe=void 0;function xe(e){throw new Fe(e)}function $e(e,r,t){function n(r){var n=t(r);n.length!==e.length&&xe("Mismatched type converter count");for(var o=0;o<e.length;++o)Re(e[o],n[o])}e.forEach((function(e){Te[e]=r}));var o=new Array(r.length),a=[],i=0;r.forEach((function(e,r){ke.hasOwnProperty(e)?o[r]=ke[e]:(a.push(e),_e.hasOwnProperty(e)||(_e[e]=[]),_e[e].push((function(){o[r]=ke[e],++i===a.length&&n(o)})))})),0===a.length&&n(o)}function Re(e,r,t){if(t=t||{},!("argPackAdvance"in r))throw new TypeError("registerType registeredInstance requires argPackAdvance");var n=r.name;if(e||Se('type "'+n+'" must have a positive integer typeid pointer'),ke.hasOwnProperty(e)){if(t.ignoreDuplicateRegistrations)return;Se("Cannot register type '"+n+"' twice")}if(ke[e]=r,delete Te[e],_e.hasOwnProperty(e)){var o=_e[e];delete _e[e],o.forEach((function(e){e()}))}}function Me(e){if(!(this instanceof Ge))return!1;if(!(e instanceof Ge))return!1;for(var r=this.$$.ptrType.registeredClass,t=this.$$.ptr,n=e.$$.ptrType.registeredClass,o=e.$$.ptr;r.baseClass;)t=r.upcast(t),r=r.baseClass;for(;n.baseClass;)o=n.upcast(o),n=n.baseClass;return r===n&&t===o}function Oe(e){Se(e.$$.ptrType.registeredClass.name+" instance already deleted")}var Ie=!1;function je(e){}function Ue(e){e.count.value-=1,0===e.count.value&&function(e){e.smartPtr?e.smartPtrType.rawDestructor(e.smartPtr):e.ptrType.registeredClass.rawDestructor(e.ptr)}(e)}function Ne(e){return"undefined"==typeof FinalizationGroup?(Ne=function(e){return e},e):(Ie=new FinalizationGroup((function(e){for(var r=e.next();!r.done;r=e.next()){var t=r.value;t.ptr?Ue(t):console.warn("object already deleted: "+t.ptr)}})),Ne=function(e){return Ie.register(e,e.$$,e.$$),e},je=function(e){Ie.unregister(e.$$)},Ne(e))}function Be(){if(this.$$.ptr||Oe(this),this.$$.preservePointerOnDelete)return this.$$.count.value+=1,this;var e,r=Ne(Object.create(Object.getPrototypeOf(this),{$$:{value:(e=this.$$,{count:e.count,deleteScheduled:e.deleteScheduled,preservePointerOnDelete:e.preservePointerOnDelete,ptr:e.ptr,ptrType:e.ptrType,smartPtr:e.smartPtr,smartPtrType:e.smartPtrType})}}));return r.$$.count.value+=1,r.$$.deleteScheduled=!1,r}function We(){this.$$.ptr||Oe(this),this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete&&Se("Object already scheduled for deletion"),je(this),Ue(this.$$),this.$$.preservePointerOnDelete||(this.$$.smartPtr=void 0,this.$$.ptr=void 0)}function Le(){return!this.$$.ptr}var ze=void 0,He=[];function Ve(){for(;He.length;){var e=He.pop();e.$$.deleteScheduled=!1,e.delete()}}function Xe(){return this.$$.ptr||Oe(this),this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete&&Se("Object already scheduled for deletion"),He.push(this),1===He.length&&ze&&ze(Ve),this.$$.deleteScheduled=!0,this}function Ge(){}var qe={};function Je(e,r,t){if(void 0===e[r].overloadTable){var n=e[r];e[r]=function(){return e[r].overloadTable.hasOwnProperty(arguments.length)||Se("Function '"+t+"' called with an invalid number of arguments ("+arguments.length+") - expects one of ("+e[r].overloadTable+")!"),e[r].overloadTable[arguments.length].apply(this,arguments)},e[r].overloadTable=[],e[r].overloadTable[n.argCount]=n}}function Ye(e,r,t,n,o,a,i,s){this.name=e,this.constructor=r,this.instancePrototype=t,this.rawDestructor=n,this.baseClass=o,this.getActualType=a,this.upcast=i,this.downcast=s,this.pureVirtualFunctions=[]}function Ke(e,r,t){for(;r!==t;)r.upcast||Se("Expected null or instance of "+t.name+", got an instance of "+r.name),e=r.upcast(e),r=r.baseClass;return e}function Qe(e,r){if(null===r)return this.isReference&&Se("null is not a valid "+this.name),0;r.$$||Se('Cannot pass "'+Sr(r)+'" as a '+this.name),r.$$.ptr||Se("Cannot pass deleted object as a pointer of type "+this.name);var t=r.$$.ptrType.registeredClass;return Ke(r.$$.ptr,t,this.registeredClass)}function Ze(e,r){var t;if(null===r)return this.isReference&&Se("null is not a valid "+this.name),this.isSmartPointer?(t=this.rawConstructor(),null!==e&&e.push(this.rawDestructor,t),t):0;r.$$||Se('Cannot pass "'+Sr(r)+'" as a '+this.name),r.$$.ptr||Se("Cannot pass deleted object as a pointer of type "+this.name),!this.isConst&&r.$$.ptrType.isConst&&Se("Cannot convert argument of type "+(r.$$.smartPtrType?r.$$.smartPtrType.name:r.$$.ptrType.name)+" to parameter type "+this.name);var n=r.$$.ptrType.registeredClass;if(t=Ke(r.$$.ptr,n,this.registeredClass),this.isSmartPointer)switch(void 0===r.$$.smartPtr&&Se("Passing raw pointer to smart pointer is illegal"),this.sharingPolicy){case 0:r.$$.smartPtrType===this?t=r.$$.smartPtr:Se("Cannot convert argument of type "+(r.$$.smartPtrType?r.$$.smartPtrType.name:r.$$.ptrType.name)+" to parameter type "+this.name);break;case 1:t=r.$$.smartPtr;break;case 2:if(r.$$.smartPtrType===this)t=r.$$.smartPtr;else{var o=r.clone();t=this.rawShare(t,Dr((function(){o.delete()}))),null!==e&&e.push(this.rawDestructor,t)}break;default:Se("Unsupporting sharing policy")}return t}function er(e,r){if(null===r)return this.isReference&&Se("null is not a valid "+this.name),0;r.$$||Se('Cannot pass "'+Sr(r)+'" as a '+this.name),r.$$.ptr||Se("Cannot pass deleted object as a pointer of type "+this.name),r.$$.ptrType.isConst&&Se("Cannot convert argument of type "+r.$$.ptrType.name+" to parameter type "+this.name);var t=r.$$.ptrType.registeredClass;return Ke(r.$$.ptr,t,this.registeredClass)}function rr(e){return this.fromWireType(j[e>>2])}function tr(e){return this.rawGetPointee&&(e=this.rawGetPointee(e)),e}function nr(e){this.rawDestructor&&this.rawDestructor(e)}function or(e){null!==e&&e.delete()}function ar(e,r,t){if(r===t)return e;if(void 0===t.baseClass)return null;var n=ar(e,r,t.baseClass);return null===n?null:t.downcast(n)}function ir(){return Object.keys(cr).length}function sr(){var e=[];for(var r in cr)cr.hasOwnProperty(r)&&e.push(cr[r]);return e}function ur(e){ze=e,He.length&&ze&&ze(Ve)}var cr={};function fr(e,r){return r=function(e,r){for(void 0===r&&Se("ptr should not be undefined");e.baseClass;)r=e.upcast(r),e=e.baseClass;return r}(e,r),cr[r]}function lr(e,r){return r.ptrType&&r.ptr||xe("makeClassHandle requires ptr and ptrType"),!!r.smartPtrType!==!!r.smartPtr&&xe("Both smartPtrType and smartPtr must be specified"),r.count={value:1},Ne(Object.create(e,{$$:{value:r}}))}function dr(e){var r=this.getPointee(e);if(!r)return this.destructor(e),null;var t=fr(this.registeredClass,r);if(void 0!==t){if(0===t.$$.count.value)return t.$$.ptr=r,t.$$.smartPtr=e,t.clone();var n=t.clone();return this.destructor(e),n}function o(){return this.isSmartPointer?lr(this.registeredClass.instancePrototype,{ptrType:this.pointeeType,ptr:r,smartPtrType:this,smartPtr:e}):lr(this.registeredClass.instancePrototype,{ptrType:this,ptr:e})}var a,i=this.registeredClass.getActualType(r),s=qe[i];if(!s)return o.call(this);a=this.isConst?s.constPointerType:s.pointerType;var u=ar(r,this.registeredClass,a.registeredClass);return null===u?o.call(this):this.isSmartPointer?lr(a.registeredClass.instancePrototype,{ptrType:a,ptr:u,smartPtrType:this,smartPtr:e}):lr(a.registeredClass.instancePrototype,{ptrType:a,ptr:u})}function pr(e,r,t,n,o,a,i,s,u,c,f){this.name=e,this.registeredClass=r,this.isReference=t,this.isConst=n,this.isSmartPointer=o,this.pointeeType=a,this.sharingPolicy=i,this.rawGetPointee=s,this.rawConstructor=u,this.rawShare=c,this.rawDestructor=f,o||void 0!==r.baseClass?this.toWireType=Ze:n?(this.toWireType=Qe,this.destructorFunction=null):(this.toWireType=er,this.destructorFunction=null)}function hr(e,r,n){return-1!=e.indexOf("j")?function(e,r,n){var o=t["dynCall_"+e];return n&&n.length?o.apply(null,[r].concat(n)):o.call(null,r)}(e,r,n):B.get(r).apply(null,n)}function mr(e,r){var t,n,o,a=-1!=(e=be(e)).indexOf("j")?(t=e,n=r,o=[],function(){o.length=arguments.length;for(var e=0;e<arguments.length;e++)o[e]=arguments[e];return hr(t,n,o)}):B.get(r);return"function"!=typeof a&&Se("unknown function pointer with signature "+e+": "+r),a}var vr=void 0;function gr(e){var r=Zr(e),t=be(r);return Jr(r),t}function yr(e,r){var t=[],n={};throw r.forEach((function e(r){n[r]||ke[r]||(Te[r]?Te[r].forEach(e):(t.push(r),n[r]=!0))})),new vr(e+": "+t.map(gr).join([", "]))}function wr(e,r){for(var t=[],n=0;n<e;n++)t.push(I[(r>>2)+n]);return t}function Er(e){for(;e.length;){var r=e.pop();e.pop()(r)}}function br(e,r){if(!(e instanceof Function))throw new TypeError("new_ called with constructor type "+typeof e+" which is not a function");var t=Ce(e.name||"unknownFunctionName",(function(){}));t.prototype=e.prototype;var n=new t,o=e.apply(n,r);return o instanceof Object?o:n}function _r(e,r,t){return e instanceof Object||Se(t+' with invalid "this": '+e),e instanceof r.registeredClass.constructor||Se(t+' incompatible with "this" of type '+e.constructor.name),e.$$.ptr||Se("cannot call emscripten binding method "+t+" on deleted object"),Ke(e.$$.ptr,e.$$.ptrType.registeredClass,r.registeredClass)}var kr=[],Tr=[{},{value:void 0},{value:null},{value:!0},{value:!1}];function Pr(e){e>4&&0==--Tr[e].refcount&&(Tr[e]=void 0,kr.push(e))}function Cr(){for(var e=0,r=5;r<Tr.length;++r)void 0!==Tr[r]&&++e;return e}function Ar(){for(var e=5;e<Tr.length;++e)if(void 0!==Tr[e])return Tr[e];return null}function Dr(e){switch(e){case void 0:return 1;case null:return 2;case!0:return 3;case!1:return 4;default:var r=kr.length?kr.pop():Tr.length;return Tr[r]={refcount:1,value:e},r}}function Sr(e){if(null===e)return"null";var r=typeof e;return"object"===r||"array"===r||"function"===r?e.toString():""+e}function Fr(e,r){switch(r){case 2:return function(e){return this.fromWireType(U[e>>2])};case 3:return function(e){return this.fromWireType(N[e>>3])};default:throw new TypeError("Unknown float type: "+e)}}function xr(e,r,t){switch(r){case 0:return t?function(e){return $[e]}:function(e){return R[e]};case 1:return t?function(e){return M[e>>1]}:function(e){return O[e>>1]};case 2:return t?function(e){return I[e>>2]}:function(e){return j[e>>2]};default:throw new TypeError("Unknown integer type: "+e)}}function $r(e){return e||Se("Cannot use deleted val. handle = "+e),Tr[e].value}function Rr(e,r){var t=ke[e];return void 0===t&&Se(r+" has unknown type "+gr(e)),t}var Mr={};var Or=[];function Ir(e,r){return(e>>>0)+4294967296*r}function jr(e,r){if(e<=0)return e;var t=r<=32?Math.abs(1<<r-1):Math.pow(2,r-1);return e>=t&&(r<=32||e>t)&&(e=-2*t+e),e}function Ur(e,r){return e>=0?e:r<=32?2*Math.abs(1<<r-1)+e:Math.pow(2,r)+e}function Nr(e){if(!e||!e.callee||!e.callee.name)return[null,"",""];e.callee.toString();var r=e.callee.name,t="(",n=!0;for(var o in e){var a=e[o];n||(t+=", "),n=!1,t+="number"==typeof a||"string"==typeof a?a:"("+typeof a+")"}t+=")";var i=e.callee.caller;return n&&(t=""),[e=i?i.arguments:[],r,t]}function Br(e,r){24&e&&(r=r.replace(/\s+$/,""),r+=(r.length>0?"\n":"")+function(e){var r=le(),t=r.lastIndexOf("_emscripten_log"),n=r.lastIndexOf("_emscripten_get_callstack"),o=r.indexOf("\n",Math.max(t,n))+1;r=r.slice(o),32&e&&_("EM_LOG_DEMANGLE is deprecated; ignoring"),8&e&&"undefined"==typeof emscripten_source_map&&(_('Source map information is not available, emscripten_log with EM_LOG_C_STACK will be ignored. Build with "--pre-js $EMSCRIPTEN/src/emscripten-source-map.min.js" linker flag to add source map loading to code.'),e^=8,e|=16);var a=null;if(128&e)for(a=Nr(arguments);a[1].indexOf("_emscripten_")>=0;)a=Nr(a[0]);var i=r.split("\n");r="";var s=new RegExp("\\s*(.*?)@(.*?):([0-9]+):([0-9]+)"),u=new RegExp("\\s*(.*?)@(.*):(.*)(:(.*))?"),c=new RegExp("\\s*at (.*?) \\((.*):(.*):(.*)\\)");for(var f in i){var l=i[f],d="",p="",h=0,m=0,v=c.exec(l);if(v&&5==v.length)d=v[1],p=v[2],h=v[3],m=v[4];else{if((v=s.exec(l))||(v=u.exec(l)),!(v&&v.length>=4)){r+=l+"\n";continue}d=v[1],p=v[2],h=v[3],m=0|v[4]}var g=!1;if(8&e){var y=emscripten_source_map.originalPositionFor({line:h,column:m});(g=y&&y.source)&&(64&e&&(y.source=y.source.substring(y.source.replace(/\\/g,"/").lastIndexOf("/")+1)),r+=" at "+d+" ("+y.source+":"+y.line+":"+y.column+")\n")}(16&e||!g)&&(64&e&&(p=p.substring(p.replace(/\\/g,"/").lastIndexOf("/")+1)),r+=(g?" = "+d:" at "+d)+" ("+p+":"+h+":"+m+")\n"),128&e&&a[0]&&(a[1]==d&&a[2].length>0&&(r=r.replace(/\s+$/,""),r+=" with values: "+a[1]+a[2]+"\n"),a=Nr(a[0]))}return r.replace(/\s+$/,"")}(e)),1&e?4&e?console.error(r):2&e?console.warn(r):512&e?console.info(r):256&e?console.debug(r):console.log(r):6&e?w(r):y(r)}var Wr={};function Lr(){if(!Lr.strings){var e={USER:"web_user",LOGNAME:"web_user",PATH:"/",PWD:"/",HOME:"/home/web_user",LANG:("object"==typeof navigator&&navigator.languages&&navigator.languages[0]||"C").replace("-","_")+".UTF-8",_:l||"./this.program"};for(var r in Wr)e[r]=Wr[r];var t=[];for(var r in e)t.push(r+"="+e[r]);Lr.strings=t}return Lr.strings}var zr=function(e,r,t,n){e||(e=this),this.parent=e,this.mount=e.mount,this.mounted=null,this.id=ge.nextInode++,this.name=r,this.mode=t,this.node_ops={},this.stream_ops={},this.rdev=n},Hr=365,Vr=146;function Xr(e,r,t){var n=t>0?t:F(e)+1,o=new Array(n),a=D(e,o,0,o.length);return r&&(o.length=a),o}Object.defineProperties(zr.prototype,{read:{get:function(){return(this.mode&Hr)===Hr},set:function(e){e?this.mode|=Hr:this.mode&=-366}},write:{get:function(){return(this.mode&Vr)===Vr},set:function(e){e?this.mode|=Vr:this.mode&=-147}},isFolder:{get:function(){return ge.isDir(this.mode)}},isDevice:{get:function(){return ge.isChrdev(this.mode)}}}),ge.FSNode=zr,ge.staticInit(),function(){for(var e=new Array(256),r=0;r<256;++r)e[r]=String.fromCharCode(r);Ee=e}(),De=t.BindingError=Ae(Error,"BindingError"),Fe=t.InternalError=Ae(Error,"InternalError"),Ge.prototype.isAliasOf=Me,Ge.prototype.clone=Be,Ge.prototype.delete=We,Ge.prototype.isDeleted=Le,Ge.prototype.deleteLater=Xe,pr.prototype.getPointee=tr,pr.prototype.destructor=nr,pr.prototype.argPackAdvance=8,pr.prototype.readValueFromPointer=rr,pr.prototype.deleteObject=or,pr.prototype.fromWireType=dr,t.getInheritedInstanceCount=ir,t.getLiveInheritedInstances=sr,t.flushPendingDeletes=Ve,t.setDelayFunction=ur,vr=t.UnboundTypeError=Ae(Error,"UnboundTypeError"),t.count_emval_handles=Cr,t.get_first_emval=Ar;var Gr={x:function(e,r,t){ye.varargs=t;try{var n=ye.getStreamFromFD(e);switch(r){case 0:return(o=ye.get())<0?-28:ge.open(n.path,n.flags,0,o).fd;case 1:case 2:case 13:case 14:return 0;case 3:return n.flags;case 4:var o=ye.get();return n.flags|=o,0;case 12:o=ye.get();return M[o+0>>1]=2,0;case 16:case 8:default:return-28;case 9:return a=28,I[Kr()>>2]=a,-1}}catch(e){return void 0!==ge&&e instanceof ge.ErrnoError||te(e),-e.errno}var a},w:function(e,r,t){ye.varargs=t;try{var n=ye.getStr(e),o=t?ye.get():0;return ge.open(n,r,o).fd}catch(e){return void 0!==ge&&e instanceof ge.ErrnoError||te(e),-e.errno}},C:function(e,r,t,n,o){var a=we(t);Re(e,{name:r=be(r),fromWireType:function(e){return!!e},toWireType:function(e,r){return r?n:o},argPackAdvance:8,readValueFromPointer:function(e){var n;if(1===t)n=$;else if(2===t)n=M;else{if(4!==t)throw new TypeError("Unknown boolean type size: "+r);n=I}return this.fromWireType(n[e>>a])},destructorFunction:null})},n:function(e,r,n,o,a,i,s,u,c,f,l,d,p){l=be(l),i=mr(a,i),u&&(u=mr(s,u)),f&&(f=mr(c,f)),p=mr(d,p);var h=Pe(l);!function(e,r,n){t.hasOwnProperty(e)?((void 0===n||void 0!==t[e].overloadTable&&void 0!==t[e].overloadTable[n])&&Se("Cannot register public name '"+e+"' twice"),Je(t,e,e),t.hasOwnProperty(n)&&Se("Cannot register multiple overloads of a function with the same number of arguments ("+n+")!"),t[e].overloadTable[n]=r):(t[e]=r,void 0!==n&&(t[e].numArguments=n))}(h,(function(){yr("Cannot construct "+l+" due to unbound types",[o])})),$e([e,r,n],o?[o]:[],(function(r){var n,a;r=r[0],a=o?(n=r.registeredClass).instancePrototype:Ge.prototype;var s=Ce(h,(function(){if(Object.getPrototypeOf(this)!==c)throw new De("Use 'new' to construct "+l);if(void 0===d.constructor_body)throw new De(l+" has no accessible constructor");var e=d.constructor_body[arguments.length];if(void 0===e)throw new De("Tried to invoke ctor of "+l+" with invalid number of parameters ("+arguments.length+") - expected ("+Object.keys(d.constructor_body).toString()+") parameters instead!");return e.apply(this,arguments)})),c=Object.create(a,{constructor:{value:s}});s.prototype=c;var d=new Ye(l,s,c,p,n,i,u,f),m=new pr(l,d,!0,!1,!1),v=new pr(l+"*",d,!1,!1,!1),g=new pr(l+" const*",d,!1,!0,!1);return qe[e]={pointerType:v,constPointerType:g},function(e,r,n){t.hasOwnProperty(e)||xe("Replacing nonexistant public symbol"),void 0!==t[e].overloadTable&&void 0!==n?t[e].overloadTable[n]=r:(t[e]=r,t[e].argCount=n)}(h,s),[m,v,g]}))},i:function(e,r,t,n,o,a){T(r>0);var i=wr(r,t);o=mr(n,o);var s=[a],u=[];$e([],[e],(function(e){var t="constructor "+(e=e[0]).name;if(void 0===e.registeredClass.constructor_body&&(e.registeredClass.constructor_body=[]),void 0!==e.registeredClass.constructor_body[r-1])throw new De("Cannot register multiple constructors with identical number of parameters ("+(r-1)+") for class '"+e.name+"'! Overload resolution is currently only performed using the parameter count, not actual type info!");return e.registeredClass.constructor_body[r-1]=function(){yr("Cannot construct "+e.name+" due to unbound types",i)},$e([],i,(function(n){return e.registeredClass.constructor_body[r-1]=function(){arguments.length!==r-1&&Se(t+" called with "+arguments.length+" arguments, expected "+(r-1)),u.length=0,s.length=r;for(var e=1;e<r;++e)s[e]=n[e].toWireType(u,arguments[e-1]);var a=o.apply(null,s);return Er(u),n[0].fromWireType(a)},[]})),[]}))},f:function(e,r,t,n,o,a,i,s){var u=wr(t,n);r=be(r),a=mr(o,a),$e([],[e],(function(e){var n=(e=e[0]).name+"."+r;function o(){yr("Cannot call "+n+" due to unbound types",u)}s&&e.registeredClass.pureVirtualFunctions.push(r);var c=e.registeredClass.instancePrototype,f=c[r];return void 0===f||void 0===f.overloadTable&&f.className!==e.name&&f.argCount===t-2?(o.argCount=t-2,o.className=e.name,c[r]=o):(Je(c,r,n),c[r].overloadTable[t-2]=o),$e([],u,(function(o){var s=function(e,r,t,n,o){var a=r.length;a<2&&Se("argTypes array size mismatch! Must at least get return value and 'this' types!");for(var i=null!==r[1]&&null!==t,s=!1,u=1;u<r.length;++u)if(null!==r[u]&&void 0===r[u].destructorFunction){s=!0;break}var c="void"!==r[0].name,f="",l="";for(u=0;u<a-2;++u)f+=(0!==u?", ":"")+"arg"+u,l+=(0!==u?", ":"")+"arg"+u+"Wired";var d="return function "+Pe(e)+"("+f+") {\nif (arguments.length !== "+(a-2)+") {\nthrowBindingError('function "+e+" called with ' + arguments.length + ' arguments, expected "+(a-2)+" args!');\n}\n";s&&(d+="var destructors = [];\n");var p=s?"destructors":"null",h=["throwBindingError","invoker","fn","runDestructors","retType","classParam"],m=[Se,n,o,Er,r[0],r[1]];for(i&&(d+="var thisWired = classParam.toWireType("+p+", this);\n"),u=0;u<a-2;++u)d+="var arg"+u+"Wired = argType"+u+".toWireType("+p+", arg"+u+"); // "+r[u+2].name+"\n",h.push("argType"+u),m.push(r[u+2]);if(i&&(l="thisWired"+(l.length>0?", ":"")+l),d+=(c?"var rv = ":"")+"invoker(fn"+(l.length>0?", ":"")+l+");\n",s)d+="runDestructors(destructors);\n";else for(u=i?1:2;u<r.length;++u){var v=1===u?"thisWired":"arg"+(u-2)+"Wired";null!==r[u].destructorFunction&&(d+=v+"_dtor("+v+"); // "+r[u].name+"\n",h.push(v+"_dtor"),m.push(r[u].destructorFunction))}return c&&(d+="var ret = retType.fromWireType(rv);\nreturn ret;\n"),d+="}\n",h.push(d),br(Function,h).apply(null,m)}(n,o,e,a,i);return void 0===c[r].overloadTable?(s.argCount=t-2,c[r]=s):c[r].overloadTable[t-2]=s,[]})),[]}))},H:function(e,r,t,n,o,a,i,s,u,c){r=be(r),o=mr(n,o),$e([],[e],(function(e){var n=(e=e[0]).name+"."+r,f={get:function(){yr("Cannot access "+n+" due to unbound types",[t,i])},enumerable:!0,configurable:!0};return f.set=u?function(){yr("Cannot access "+n+" due to unbound types",[t,i])}:function(e){Se(n+" is a read-only property")},Object.defineProperty(e.registeredClass.instancePrototype,r,f),$e([],u?[t,i]:[t],(function(t){var i=t[0],f={get:function(){var r=_r(this,e,n+" getter");return i.fromWireType(o(a,r))},enumerable:!0};if(u){u=mr(s,u);var l=t[1];f.set=function(r){var t=_r(this,e,n+" setter"),o=[];u(c,t,l.toWireType(o,r)),Er(o)}}return Object.defineProperty(e.registeredClass.instancePrototype,r,f),[]})),[]}))},B:function(e,r){Re(e,{name:r=be(r),fromWireType:function(e){var r=Tr[e].value;return Pr(e),r},toWireType:function(e,r){return Dr(r)},argPackAdvance:8,readValueFromPointer:rr,destructorFunction:null})},l:function(e,r,t){var n=we(t);Re(e,{name:r=be(r),fromWireType:function(e){return e},toWireType:function(e,r){if("number"!=typeof r&&"boolean"!=typeof r)throw new TypeError('Cannot convert "'+Sr(r)+'" to '+this.name);return r},argPackAdvance:8,readValueFromPointer:Fr(r,n),destructorFunction:null})},c:function(e,r,t,n,o){r=be(r),-1===o&&(o=4294967295);var a=we(t),i=function(e){return e};if(0===n){var s=32-8*t;i=function(e){return e<<s>>>s}}var u=-1!=r.indexOf("unsigned");Re(e,{name:r,fromWireType:i,toWireType:function(e,t){if("number"!=typeof t&&"boolean"!=typeof t)throw new TypeError('Cannot convert "'+Sr(t)+'" to '+this.name);if(t<n||t>o)throw new TypeError('Passing a number "'+Sr(t)+'" from JS side to C/C++ side to an argument of type "'+r+'", which is outside the valid range ['+n+", "+o+"]!");return u?t>>>0:0|t},argPackAdvance:8,readValueFromPointer:xr(r,a,0!==n),destructorFunction:null})},b:function(e,r,t){var n=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array][r];function o(e){var r=j,t=r[e>>=2],o=r[e+1];return new n(x,o,t)}Re(e,{name:t=be(t),fromWireType:o,argPackAdvance:8,readValueFromPointer:o},{ignoreDuplicateRegistrations:!0})},m:function(e,r){var t="std::string"===(r=be(r));Re(e,{name:r,fromWireType:function(e){var r,n=j[e>>2];if(t)for(var o=e+4,a=0;a<=n;++a){var i=e+4+a;if(a==n||0==R[i]){var s=A(o,i-o);void 0===r?r=s:(r+=String.fromCharCode(0),r+=s),o=i+1}}else{var u=new Array(n);for(a=0;a<n;++a)u[a]=String.fromCharCode(R[e+4+a]);r=u.join("")}return Jr(e),r},toWireType:function(e,r){r instanceof ArrayBuffer&&(r=new Uint8Array(r));var n="string"==typeof r;n||r instanceof Uint8Array||r instanceof Uint8ClampedArray||r instanceof Int8Array||Se("Cannot pass non-string to std::string");var o=(t&&n?function(){return F(r)}:function(){return r.length})(),a=Yr(4+o+1);if(j[a>>2]=o,t&&n)S(r,a+4,o+1);else if(n)for(var i=0;i<o;++i){var s=r.charCodeAt(i);s>255&&(Jr(a),Se("String has UTF-16 code units that do not fit in 8 bits")),R[a+4+i]=s}else for(i=0;i<o;++i)R[a+4+i]=r[i];return null!==e&&e.push(Jr,a),a},argPackAdvance:8,readValueFromPointer:rr,destructorFunction:function(e){Jr(e)}})},h:function(e,r,t){var n,o,a,i,s;t=be(t),2===r?(n=L,o=z,i=H,a=function(){return O},s=1):4===r&&(n=V,o=X,i=G,a=function(){return j},s=2),Re(e,{name:t,fromWireType:function(e){for(var t,o=j[e>>2],i=a(),u=e+4,c=0;c<=o;++c){var f=e+4+c*r;if(c==o||0==i[f>>s]){var l=n(u,f-u);void 0===t?t=l:(t+=String.fromCharCode(0),t+=l),u=f+r}}return Jr(e),t},toWireType:function(e,n){"string"!=typeof n&&Se("Cannot pass non-string to C++ string type "+t);var a=i(n),u=Yr(4+a+r);return j[u>>2]=a>>s,o(n,u+4,a+r),null!==e&&e.push(Jr,u),u},argPackAdvance:8,readValueFromPointer:rr,destructorFunction:function(e){Jr(e)}})},D:function(e,r){Re(e,{isVoid:!0,name:r=be(r),argPackAdvance:0,fromWireType:function(){},toWireType:function(e,r){}})},u:function(e,r,t){e=$r(e),r=Rr(r,"emval::as");var n=[],o=Dr(n);return I[t>>2]=o,r.toWireType(n,e)},e:function(e,r,t,n){var o,a;(e=Or[e])(r=$r(r),t=void 0===(a=Mr[o=t])?be(o):a,null,n)},p:Pr,d:function(e,r){for(var t=function(e,r){for(var t=new Array(e),n=0;n<e;++n)t[n]=Rr(I[(r>>2)+n],"parameter "+n);return t}(e,r),n=t[0],o=n.name+"_$"+t.slice(1).map((function(e){return e.name})).join("_")+"$",a=["retType"],i=[n],s="",u=0;u<e-1;++u)s+=(0!==u?", ":"")+"arg"+u,a.push("argType"+u),i.push(t[1+u]);var c="return function "+Pe("methodCaller_"+o)+"(handle, name, destructors, args) {\n",f=0;for(u=0;u<e-1;++u)c+=" var arg"+u+" = argType"+u+".readValueFromPointer(args"+(f?"+"+f:"")+");\n",f+=t[u+1].argPackAdvance;for(c+=" var rv = handle[name]("+s+");\n",u=0;u<e-1;++u)t[u+1].deleteObject&&(c+=" argType"+u+".deleteObject(arg"+u+");\n");n.isVoid||(c+=" return retType.toWireType(destructors, rv);\n"),c+="};\n",a.push(c);var l,d,p=br(Function,a).apply(null,i);return l=p,d=Or.length,Or.push(l),d},o:function(e){e>4&&(Tr[e].refcount+=1)},q:function(e){Er(Tr[e].value),Pr(e)},A:function(e,r){return Dr((e=Rr(e,"_emval_take_value")).readValueFromPointer(r))},a:function(){te()},F:function e(){return void 0===e.start&&(e.start=Date.now()),1e3*(Date.now()-e.start)|0},G:function(e,r,t){var n=function(e,r){var t=e,n=r;function o(e){var r;return n=function(e,r){return"double"!==r&&"i64"!==r||7&e&&(e+=4),e}(n,e),"double"===e?(r=N[n>>3],n+=8):"i64"==e?(r=[I[n>>2],I[n+4>>2]],n+=8):(e="i32",r=I[n>>2],n+=4),r}for(var a,i,s,u,c=[];;){var f=t;if(0===(a=$[t>>0]))break;if(i=$[t+1>>0],37==a){var l=!1,d=!1,p=!1,h=!1,m=!1;e:for(;;){switch(i){case 43:l=!0;break;case 45:d=!0;break;case 35:p=!0;break;case 48:if(h)break e;h=!0;break;case 32:m=!0;break;default:break e}t++,i=$[t+1>>0]}var v=0;if(42==i)v=o("i32"),t++,i=$[t+1>>0];else for(;i>=48&&i<=57;)v=10*v+(i-48),t++,i=$[t+1>>0];var g,y=!1,w=-1;if(46==i){if(w=0,y=!0,t++,42==(i=$[t+1>>0]))w=o("i32"),t++;else for(;;){var E=$[t+1>>0];if(E<48||E>57)break;w=10*w+(E-48),t++}i=$[t+1>>0]}switch(w<0&&(w=6,y=!1),String.fromCharCode(i)){case"h":104==$[t+2>>0]?(t++,g=1):g=2;break;case"l":108==$[t+2>>0]?(t++,g=8):g=4;break;case"L":case"q":case"j":g=8;break;case"z":case"t":case"I":g=4;break;default:g=null}switch(g&&t++,i=$[t+1>>0],String.fromCharCode(i)){case"d":case"i":case"u":case"o":case"x":case"X":case"p":var b=100==i||105==i;s=o("i"+8*(g=g||4)),8==g&&(s=117==i?(s[0]>>>0)+4294967296*(s[1]>>>0):Ir(s[0],s[1])),g<=4&&(s=(b?jr:Ur)(s&Math.pow(256,g)-1,8*g));var _=Math.abs(s),k="";if(100==i||105==i)C=jr(s,8*g).toString(10);else if(117==i)C=Ur(s,8*g).toString(10),s=Math.abs(s);else if(111==i)C=(p?"0":"")+_.toString(8);else if(120==i||88==i){if(k=p&&0!=s?"0x":"",s<0){s=-s,C=(_-1).toString(16);for(var T=[],P=0;P<C.length;P++)T.push((15-parseInt(C[P],16)).toString(16));for(C=T.join("");C.length<2*g;)C="f"+C}else C=_.toString(16);88==i&&(k=k.toUpperCase(),C=C.toUpperCase())}else 112==i&&(0===_?C="(nil)":(k="0x",C=_.toString(16)));if(y)for(;C.length<w;)C="0"+C;for(s>=0&&(l?k="+"+k:m&&(k=" "+k)),"-"==C.charAt(0)&&(k="-"+k,C=C.substr(1));k.length+C.length<v;)d?C+=" ":h?C="0"+C:k=" "+k;(C=k+C).split("").forEach((function(e){c.push(e.charCodeAt(0))}));break;case"f":case"F":case"e":case"E":case"g":case"G":var C;if(s=o("double"),isNaN(s))C="nan",h=!1;else if(isFinite(s)){var A=!1,D=Math.min(w,20);if(103==i||71==i){A=!0,w=w||1;var S=parseInt(s.toExponential(D).split("e")[1],10);w>S&&S>=-4?(i=(103==i?"f":"F").charCodeAt(0),w-=S+1):(i=(103==i?"e":"E").charCodeAt(0),w--),D=Math.min(w,20)}101==i||69==i?(C=s.toExponential(D),/[eE][-+]\d$/.test(C)&&(C=C.slice(0,-1)+"0"+C.slice(-1))):102!=i&&70!=i||(C=s.toFixed(D),0===s&&((u=s)<0||0===u&&1/u==-1/0)&&(C="-"+C));var F=C.split("e");if(A&&!p)for(;F[0].length>1&&-1!=F[0].indexOf(".")&&("0"==F[0].slice(-1)||"."==F[0].slice(-1));)F[0]=F[0].slice(0,-1);else for(p&&-1==C.indexOf(".")&&(F[0]+=".");w>D++;)F[0]+="0";C=F[0]+(F.length>1?"e"+F[1]:""),69==i&&(C=C.toUpperCase()),s>=0&&(l?C="+"+C:m&&(C=" "+C))}else C=(s<0?"-":"")+"inf",h=!1;for(;C.length<v;)d?C+=" ":C=!h||"-"!=C[0]&&"+"!=C[0]?(h?"0":" ")+C:C[0]+"0"+C.slice(1);i<97&&(C=C.toUpperCase()),C.split("").forEach((function(e){c.push(e.charCodeAt(0))}));break;case"s":var x=o("i8*"),M=x?Qr(x):"(null)".length;if(y&&(M=Math.min(M,w)),!d)for(;M<v--;)c.push(32);if(x)for(P=0;P<M;P++)c.push(R[x++>>0]);else c=c.concat(Xr("(null)".substr(0,M),!0));if(d)for(;M<v--;)c.push(32);break;case"c":for(d&&c.push(o("i8"));--v>0;)c.push(32);d||c.push(o("i8"));break;case"n":var O=o("i32*");I[O>>2]=c.length;break;case"%":c.push(a);break;default:for(P=f;P<t+2;P++)c.push($[P>>0])}t+=2}else c.push(a),t+=1}return c}(r,t);Br(e,C(n,0))},s:function(e){R.length,te("OOM")},t:function(e,r){try{var t=0;return Lr().forEach((function(n,o){var a=r+t;I[e+4*o>>2]=a,function(e,r,t){for(var n=0;n<e.length;++n)$[r++>>0]=e.charCodeAt(n);t||($[r>>0]=0)}(n,a),t+=n.length+1})),0}catch(e){return void 0!==ge&&e instanceof ge.ErrnoError||te(e),e.errno}},v:function(e,r){try{var t=Lr();I[e>>2]=t.length;var n=0;return t.forEach((function(e){n+=e.length+1})),I[r>>2]=n,0}catch(e){return void 0!==ge&&e instanceof ge.ErrnoError||te(e),e.errno}},k:function(e){try{var r=ye.getStreamFromFD(e);return ge.close(r),0}catch(e){return void 0!==ge&&e instanceof ge.ErrnoError||te(e),e.errno}},y:function(e,r){try{var t=ye.getStreamFromFD(e),n=t.tty?2:ge.isDir(t.mode)?3:ge.isLink(t.mode)?7:4;return $[r>>0]=n,0}catch(e){return void 0!==ge&&e instanceof ge.ErrnoError||te(e),e.errno}},z:function(e,r,t,n){try{var o=ye.getStreamFromFD(e),a=ye.doReadv(o,r,t);return I[n>>2]=a,0}catch(e){return void 0!==ge&&e instanceof ge.ErrnoError||te(e),e.errno}},r:function(e,r,t,n,o){try{var a=ye.getStreamFromFD(e),i=4294967296*t+(r>>>0),s=9007199254740992;return i<=-s||i>=s?-61:(ge.llseek(a,i,n),se=[a.position>>>0,(ie=a.position,+Math.abs(ie)>=1?ie>0?(0|Math.min(+Math.floor(ie/4294967296),4294967295))>>>0:~~+Math.ceil((ie-+(~~ie>>>0))/4294967296)>>>0:0)],I[o>>2]=se[0],I[o+4>>2]=se[1],a.getdents&&0===i&&0===n&&(a.getdents=null),0)}catch(e){return void 0!==ge&&e instanceof ge.ErrnoError||te(e),e.errno}},j:function(e,r,t,n){try{var o=ye.getStreamFromFD(e),a=ye.doWritev(o,r,t);return I[n>>2]=a,0}catch(e){return void 0!==ge&&e instanceof ge.ErrnoError||te(e),e.errno}},E:function(e){var r=Date.now();return I[e>>2]=r/1e3|0,I[e+4>>2]=r%1e3*1e3|0,0},g:function(e){}};!function(){var e={a:Gr};function r(e,r){var n,o,a=e.exports;t.asm=a,b=t.asm.I,n=b.buffer,x=n,t.HEAP8=$=new Int8Array(n),t.HEAP16=M=new Int16Array(n),t.HEAP32=I=new Int32Array(n),t.HEAPU8=R=new Uint8Array(n),t.HEAPU16=O=new Uint16Array(n),t.HEAPU32=j=new Uint32Array(n),t.HEAPF32=U=new Float32Array(n),t.HEAPF64=N=new Float64Array(n),B=t.asm.M,o=t.asm.J,J.unshift(o),re()}function n(e){r(e.instance)}function o(r){return function(){if(!E&&(s||u)){if("function"==typeof fetch&&!ae(ue))return fetch(ue,{credentials:"same-origin"}).then((function(e){if(!e.ok)throw"failed to load wasm binary file at '"+ue+"'";return e.arrayBuffer()})).catch((function(){return ce(ue)}));if(p)return new Promise((function(e,r){p(ue,(function(r){e(new Uint8Array(r))}),r)}))}return Promise.resolve().then((function(){return ce(ue)}))}().then((function(r){return WebAssembly.instantiate(r,e)})).then(r,(function(e){w("failed to asynchronously prepare wasm: "+e),te(e)}))}if(ee(),t.instantiateWasm)try{return t.instantiateWasm(e,r)}catch(e){return w("Module.instantiateWasm callback failed with error: "+e),!1}E||"function"!=typeof WebAssembly.instantiateStreaming||oe(ue)||ae(ue)||"function"!=typeof fetch?o(n):fetch(ue,{credentials:"same-origin"}).then((function(r){return WebAssembly.instantiateStreaming(r,e).then(n,(function(e){return w("wasm streaming compile failed: "+e),w("falling back to ArrayBuffer instantiation"),o(n)}))}))}(),t.___wasm_call_ctors=function(){return(t.___wasm_call_ctors=t.asm.J).apply(null,arguments)};var qr,Jr=t._free=function(){return(Jr=t._free=t.asm.K).apply(null,arguments)},Yr=t._malloc=function(){return(Yr=t._malloc=t.asm.L).apply(null,arguments)},Kr=t.___errno_location=function(){return(Kr=t.___errno_location=t.asm.N).apply(null,arguments)},Qr=t._strlen=function(){return(Qr=t._strlen=t.asm.O).apply(null,arguments)},Zr=t.___getTypeName=function(){return(Zr=t.___getTypeName=t.asm.P).apply(null,arguments)};function et(e){this.name="ExitStatus",this.message="Program terminated with exit("+e+")",this.status=e}function rt(e){function r(){qr||(qr=!0,t.calledRun=!0,k||(t.noFSInit||ge.init.initialized||ge.init(),fe(J),ge.ignorePermissions=!1,fe(Y),t.onRuntimeInitialized&&t.onRuntimeInitialized(),function(){if(t.postRun)for("function"==typeof t.postRun&&(t.postRun=[t.postRun]);t.postRun.length;)e=t.postRun.shift(),K.unshift(e);var e;fe(K)}()))}Q>0||(!function(){if(t.preRun)for("function"==typeof t.preRun&&(t.preRun=[t.preRun]);t.preRun.length;)e=t.preRun.shift(),q.unshift(e);var e;fe(q)}(),Q>0||(t.setStatus?(t.setStatus("Running..."),setTimeout((function(){setTimeout((function(){t.setStatus("")}),1),r()}),1)):r()))}if(t.___embind_register_native_and_builtin_types=function(){return(t.___embind_register_native_and_builtin_types=t.asm.Q).apply(null,arguments)},t.dynCall_ijiii=function(){return(t.dynCall_ijiii=t.asm.R).apply(null,arguments)},t.dynCall_viiijj=function(){return(t.dynCall_viiijj=t.asm.S).apply(null,arguments)},t.dynCall_jij=function(){return(t.dynCall_jij=t.asm.T).apply(null,arguments)},t.dynCall_jii=function(){return(t.dynCall_jii=t.asm.U).apply(null,arguments)},t.dynCall_jiji=function(){return(t.dynCall_jiji=t.asm.V).apply(null,arguments)},t._ff_h264_cabac_tables=82789,Z=function e(){qr||rt(),qr||(Z=e)},t.run=rt,t.preInit)for("function"==typeof t.preInit&&(t.preInit=[t.preInit]);t.preInit.length>0;)t.preInit.pop()();rt(),e.exports=t}));const u=1e3,c=!1,f=!0,l=!1,d=!1,p="initVideo",h="render",m="playAudio",v="initAudio",g="audioCode",y="videoCode",w=1,E=2,b="init",_="decode",k="audioDecode",T="videoDecode",P="close",C="updateConfig",A="key",D="delta";(()=>{try{if("object"==typeof WebAssembly&&"function"==typeof WebAssembly.instantiate){const e=new WebAssembly.Module(Uint8Array.of(0,97,115,109,1,0,0,0));if(e instanceof WebAssembly.Module)return new WebAssembly.Instance(e)instanceof WebAssembly.Instance}}catch(e){}})(),Date.now||(Date.now=function(){return(new Date).getTime()}),s.postRun=function(){var e=[],r=[],t={};"VideoEncoder"in self&&(t={hasInit:!1,isEmitInfo:!1,offscreenCanvas:null,offscreenCanvasCtx:null,decoder:new VideoDecoder({output:function(e){t.isEmitInfo||(n.opt.debug&&console.log("Jessibuca: [worker] Webcodecs Video Decoder initSize"),postMessage({cmd:p,w:e.codedWidth,h:e.codedHeight}),t.isEmitInfo=!0,t.offscreenCanvas=new OffscreenCanvas(e.codedWidth,e.codedHeight),t.offscreenCanvasCtx=t.offscreenCanvas.getContext("2d")),t.offscreenCanvasCtx.drawImage(e,0,0,e.codedWidth,e.codedHeight);let r=t.offscreenCanvas.transferToImageBitmap();postMessage({cmd:h,buffer:r,delay:n.delay,ts:0},[r]),setTimeout((function(){e.close?e.close():e.destroy()}),100)},error:function(e){console.error(e)}}),decode:function(e,r){const o=e[0]>>4==1;if(t.hasInit){const n=new EncodedVideoChunk({data:e.slice(5),timestamp:r,type:o?A:D});t.decoder.decode(n)}else if(o&&0===e[1]){const r=15&e[0];n.setVideoCodec(r);const o=function(e){let r=e.subarray(1,4),t="avc1.";for(let e=0;e<3;e++){let n=r[e].toString(16);n.length<2&&(n="0"+n),t+=n}return{codec:t,description:e}}(e.slice(5));t.decoder.configure(o),t.hasInit=!0}},reset(){t.hasInit=!1,t.isEmitInfo=!1,t.offscreenCanvas=null,t.offscreenCanvasCtx=null}});var n={opt:{debug:c,forceNoOffscreen:f,useWCS:l,videoBuffer:u,openWebglAlignment:d},useOffscreen:function(){return!n.opt.forceNoOffscreen&&"undefined"!=typeof OffscreenCanvas},initAudioPlanar:function(e,t){postMessage({cmd:v,sampleRate:t,channels:e});var n=[],o=0;this.playAudioPlanar=function(t,a,i){for(var u=a,c=[],f=0,l=0;l<2;l++){var d=s.HEAPU32[(t>>2)+l]>>2;c[l]=s.HEAPF32.subarray(d,d+u)}if(o){if(!(u>=(a=1024-o)))return o+=u,r[0]=Float32Array.of(...r[0],...c[0]),void(2==e&&(r[1]=Float32Array.of(...r[1],...c[1])));n[0]=Float32Array.of(...r[0],...c[0].subarray(0,a)),2==e&&(n[1]=Float32Array.of(...r[1],...c[1].subarray(0,a))),postMessage({cmd:m,buffer:n,ts:i},n.map((e=>e.buffer))),f=a,u-=a}for(o=u;o>=1024;o-=1024)n[0]=c[0].slice(f,f+=1024),2==e&&(n[1]=c[1].slice(f-1024,f)),postMessage({cmd:m,buffer:n,ts:i},n.map((e=>e.buffer)));o&&(r[0]=c[0].slice(f),2==e&&(r[1]=c[1].slice(f)))}},setVideoCodec:function(e){postMessage({cmd:y,code:e})},setAudioCodec:function(e){postMessage({cmd:g,code:e})},setVideoSize:function(e,r){postMessage({cmd:p,w:e,h:r});var t=e*r,o=t>>2;n.useOffscreen()?(this.offscreenCanvas=new OffscreenCanvas(e,r),this.offscreenCanvasGL=this.offscreenCanvas.getContext("webgl"),this.webglObj=((e,r)=>{var t=["attribute vec4 vertexPos;","attribute vec4 texturePos;","varying vec2 textureCoord;","void main()","{","gl_Position = vertexPos;","textureCoord = texturePos.xy;","}"].join("\n"),n=["precision highp float;","varying highp vec2 textureCoord;","uniform sampler2D ySampler;","uniform sampler2D uSampler;","uniform sampler2D vSampler;","const mat4 YUV2RGB = mat4","(","1.1643828125, 0, 1.59602734375, -.87078515625,","1.1643828125, -.39176171875, -.81296875, .52959375,","1.1643828125, 2.017234375, 0, -1.081390625,","0, 0, 0, 1",");","void main(void) {","highp float y = texture2D(ySampler, textureCoord).r;","highp float u = texture2D(uSampler, textureCoord).r;","highp float v = texture2D(vSampler, textureCoord).r;","gl_FragColor = vec4(y, u, v, 1) * YUV2RGB;","}"].join("\n");r&&e.pixelStorei(e.UNPACK_ALIGNMENT,1);var o=e.createShader(e.VERTEX_SHADER);e.shaderSource(o,t),e.compileShader(o),e.getShaderParameter(o,e.COMPILE_STATUS)||console.log("Vertex shader failed to compile: "+e.getShaderInfoLog(o));var a=e.createShader(e.FRAGMENT_SHADER);e.shaderSource(a,n),e.compileShader(a),e.getShaderParameter(a,e.COMPILE_STATUS)||console.log("Fragment shader failed to compile: "+e.getShaderInfoLog(a));var i=e.createProgram();e.attachShader(i,o),e.attachShader(i,a),e.linkProgram(i),e.getProgramParameter(i,e.LINK_STATUS)||console.log("Program failed to compile: "+e.getProgramInfoLog(i)),e.useProgram(i);var s=e.createBuffer();e.bindBuffer(e.ARRAY_BUFFER,s),e.bufferData(e.ARRAY_BUFFER,new Float32Array([1,1,-1,1,1,-1,-1,-1]),e.STATIC_DRAW);var u=e.getAttribLocation(i,"vertexPos");e.enableVertexAttribArray(u),e.vertexAttribPointer(u,2,e.FLOAT,!1,0,0);var c=e.createBuffer();e.bindBuffer(e.ARRAY_BUFFER,c),e.bufferData(e.ARRAY_BUFFER,new Float32Array([1,0,0,0,1,1,0,1]),e.STATIC_DRAW);var f=e.getAttribLocation(i,"texturePos");function l(r,t){var n=e.createTexture();return e.bindTexture(e.TEXTURE_2D,n),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.bindTexture(e.TEXTURE_2D,null),e.uniform1i(e.getUniformLocation(i,r),t),n}e.enableVertexAttribArray(f),e.vertexAttribPointer(f,2,e.FLOAT,!1,0,0);var d=l("ySampler",0),p=l("uSampler",1),h=l("vSampler",2);return{render:function(r,t,n,o,a){e.viewport(0,0,r,t),e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,d),e.texImage2D(e.TEXTURE_2D,0,e.LUMINANCE,r,t,0,e.LUMINANCE,e.UNSIGNED_BYTE,n),e.activeTexture(e.TEXTURE1),e.bindTexture(e.TEXTURE_2D,p),e.texImage2D(e.TEXTURE_2D,0,e.LUMINANCE,r/2,t/2,0,e.LUMINANCE,e.UNSIGNED_BYTE,o),e.activeTexture(e.TEXTURE2),e.bindTexture(e.TEXTURE_2D,h),e.texImage2D(e.TEXTURE_2D,0,e.LUMINANCE,r/2,t/2,0,e.LUMINANCE,e.UNSIGNED_BYTE,a),e.drawArrays(e.TRIANGLE_STRIP,0,4)},destroy:function(){try{e.deleteProgram(i),e.deleteBuffer(s),e.deleteBuffer(c),e.deleteTexture(d),e.deleteTexture(p),e.deleteBuffer(h)}catch(e){}}}})(this.offscreenCanvasGL,n.opt.openWebglAlignment),this.draw=function(n,a,i,u){this.webglObj.render(e,r,s.HEAPU8.subarray(a,a+t),s.HEAPU8.subarray(i,i+o),s.HEAPU8.subarray(u,u+o));let c=this.offscreenCanvas.transferToImageBitmap();postMessage({cmd:h,buffer:c,delay:this.delay,ts:n},[c])}):this.draw=function(e,r,n,a){var i=[s.HEAPU8.subarray(r,r+t),s.HEAPU8.subarray(n,n+o),s.HEAPU8.subarray(a,a+o)].map((e=>Uint8Array.from(e)));postMessage({cmd:h,output:i,delay:this.delay,ts:e},i.map((e=>e.buffer)))}},getDelay:function(e){return e?(this.firstTimestamp?e&&(this.delay=Date.now()-this.startTimestamp-(e-this.firstTimestamp)):(this.firstTimestamp=e,this.startTimestamp=Date.now(),this.delay=-1),this.delay):-1},resetDelay:function(){this.firstTimestamp=null,this.startTimestamp=null,this.delay=-1},init:function(){n.opt.debug&&console.log("Jessibuca: [worker] init");const r=e=>{n.opt.useWCS&&n.useOffscreen()&&e.type===E&&t.decode?t.decode(e.payload,e.ts):e.decoder.decode(e.payload,e.ts)};this.stopId=setInterval((()=>{if(e.length)if(this.dropping){for((t=e.shift()).type===w&&0===t.payload[1]&&r(t);!t.isIFrame&&e.length;)(t=e.shift()).type===w&&0===t.payload[1]&&r(t);t.isIFrame&&(this.dropping=!1,r(t))}else{var t=e[0];if(-1===this.getDelay(t.ts))n.opt.debug&&console.log("Jessibuca: [worker]: common dumex delay is -1"),e.shift(),r(t);else if(this.delay>n.opt.videoBuffer+1e3)n.opt.debug&&console.log("Jessibuca: [worker]:",`delay is ${this.delay}, set dropping is true`),this.resetDelay(),this.dropping=!0;else for(;e.length&&(t=e[0],this.getDelay(t.ts)>n.opt.videoBuffer);)e.shift(),r(t)}}),10)},close:function(){n.opt.debug&&console.log("Jessibuca: [worker]: close"),clearInterval(this.stopId),this.stopId=null,o.clear(),a.clear(),t.reset&&t.reset(),this.firstTimestamp=null,this.startTimestamp=null,this.delay=-1,this.dropping=!1,this.webglObj&&(this.webglObj.destroy(),this.offscreenCanvas=null,this.offscreenCanvasGL=null,this.offscreenCanvasCtx=null),e=[],r=[],delete this.playAudioPlanar,delete this.draw},pushBuffer:function(r,t){t.type===w?e.push({ts:t.ts,payload:r,decoder:o,type:w}):t.type===E&&e.push({ts:t.ts,payload:r,decoder:a,type:E,isIFrame:t.isIFrame})}},o=new s.AudioDecoder(n),a=new s.VideoDecoder(n);postMessage({cmd:b}),self.onmessage=function(e){var r=e.data;switch(r.cmd){case b:try{n.opt=Object.assign(n.opt,JSON.parse(r.opt))}catch(e){}o.sample_rate=r.sampleRate,n.init();break;case _:n.pushBuffer(r.buffer,r.options);break;case k:o.decode(r.buffer,r.ts);break;case T:a.decode(r.buffer,r.ts);break;case P:n.close();break;case C:n.opt[r.key]=r.value}}}})); | 1 | +!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?r(require("path"),require("fs"),require("crypto")):"function"==typeof define&&define.amd?define(["path","fs","crypto"],r):r((e="undefined"!=typeof globalThis?globalThis:e||self).path,e.fs,e.crypto$1)}(this,(function(e,r,t){"use strict";function n(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var o=n(e),i=n(r),a=n(t);function s(e,r){return e(r={exports:{}},r.exports),r.exports}var l=s((function(e){var r=void 0!==r?r:{},t=(r={print:function(e){console.log("Jessibuca: [worker]:",e)},printErr:function(e){console.warn("Jessibuca: [worker]:",e),postMessage({cmd:"wasmError",message:e})}},Object.assign({},r)),n="./this.program",s="object"==typeof window,l="function"==typeof importScripts,u="object"==typeof process&&"object"==typeof process.versions&&"string"==typeof process.versions.node,c=!s&&!u&&!l;if(r.ENVIRONMENT)throw new Error("Module.ENVIRONMENT has been deprecated. To force the environment, use the ENVIRONMENT compile-time option (for example, -sENVIRONMENT=web or -sENVIRONMENT=node)");var d,f,p,m,h,g,v="";if(u){if("object"!=typeof process)throw new Error("not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)");v=l?o.default.dirname(v)+"/":__dirname+"/",g=()=>{h||(m=i.default,h=o.default)},d=function(e,r){return g(),e=h.normalize(e),m.readFileSync(e,r?void 0:"utf8")},p=e=>{var r=d(e,!0);return r.buffer||(r=new Uint8Array(r)),F(r.buffer),r},f=(e,r,t)=>{g(),e=h.normalize(e),m.readFile(e,(function(e,n){e?t(e):r(n.buffer)}))},process.argv.length>1&&(n=process.argv[1].replace(/\\/g,"/")),process.argv.slice(2),e.exports=r,process.on("uncaughtException",(function(e){if(!(e instanceof St))throw e})),process.on("unhandledRejection",(function(e){throw e})),r.inspect=function(){return"[Emscripten Module object]"}}else if(c){if("object"==typeof process||"object"==typeof window||"function"==typeof importScripts)throw new Error("not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)");"undefined"!=typeof read&&(d=function(e){return read(e)}),p=function(e){let r;return"function"==typeof readbuffer?new Uint8Array(readbuffer(e)):(r=read(e,"binary"),F("object"==typeof r),r)},f=function(e,r,t){setTimeout((()=>r(p(e))),0)},"undefined"!=typeof scriptArgs&&scriptArgs,"undefined"!=typeof print&&("undefined"==typeof console&&(console={}),console.log=print,console.warn=console.error="undefined"!=typeof printErr?printErr:print)}else{if(!s&&!l)throw new Error("environment detection error");if(l?v=self.location.href:"undefined"!=typeof document&&document.currentScript&&(v=document.currentScript.src),v=0!==v.indexOf("blob:")?v.substr(0,v.replace(/[?#].*/,"").lastIndexOf("/")+1):"","object"!=typeof window&&"function"!=typeof importScripts)throw new Error("not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)");d=e=>{var r=new XMLHttpRequest;return r.open("GET",e,!1),r.send(null),r.responseText},l&&(p=e=>{var r=new XMLHttpRequest;return r.open("GET",e,!1),r.responseType="arraybuffer",r.send(null),new Uint8Array(r.response)}),f=(e,r,t)=>{var n=new XMLHttpRequest;n.open("GET",e,!0),n.responseType="arraybuffer",n.onload=()=>{200==n.status||0==n.status&&n.response?r(n.response):t()},n.onerror=t,n.send(null)}}var y,E,w,b=r.print||console.log.bind(console),_=r.printErr||console.warn.bind(console);function T(e){T.shown||(T.shown={}),T.shown[e]||(T.shown[e]=1,_(e))}function k(e,t){Object.getOwnPropertyDescriptor(r,e)||Object.defineProperty(r,e,{configurable:!0,get:function(){ge("Module."+e+" has been replaced with plain "+t+" (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)")}})}function S(e,r){var t="'"+e+"' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)";return r&&(t+=". Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you"),t}function C(e,t){Object.getOwnPropertyDescriptor(r,e)||Object.defineProperty(r,e,{configurable:!0,get:function(){ge(S(e,t))}})}function P(e,t){Object.getOwnPropertyDescriptor(r,e)||(r[e]=()=>ge(S(e,t)))}Object.assign(r,t),t=null,y="fetchSettings",Object.getOwnPropertyDescriptor(r,y)&&ge("`Module."+y+"` was supplied but `"+y+"` not included in INCOMING_MODULE_JS_API"),r.arguments,k("arguments","arguments_"),r.thisProgram&&(n=r.thisProgram),k("thisProgram","thisProgram"),r.quit,k("quit","quit_"),F(void 0===r.memoryInitializerPrefixURL,"Module.memoryInitializerPrefixURL option was removed, use Module.locateFile instead"),F(void 0===r.pthreadMainPrefixURL,"Module.pthreadMainPrefixURL option was removed, use Module.locateFile instead"),F(void 0===r.cdInitializerPrefixURL,"Module.cdInitializerPrefixURL option was removed, use Module.locateFile instead"),F(void 0===r.filePackagePrefixURL,"Module.filePackagePrefixURL option was removed, use Module.locateFile instead"),F(void 0===r.read,"Module.read option was removed (modify read_ in JS)"),F(void 0===r.readAsync,"Module.readAsync option was removed (modify readAsync in JS)"),F(void 0===r.readBinary,"Module.readBinary option was removed (modify readBinary in JS)"),F(void 0===r.setWindowTitle,"Module.setWindowTitle option was removed (modify setWindowTitle in JS)"),F(void 0===r.TOTAL_MEMORY,"Module.TOTAL_MEMORY has been renamed Module.INITIAL_MEMORY"),k("read","read_"),k("readAsync","readAsync"),k("readBinary","readBinary"),k("setWindowTitle","setWindowTitle"),F(!c,"shell environment detected but not enabled at build time. Add 'shell' to `-sENVIRONMENT` to enable."),r.wasmBinary&&(E=r.wasmBinary),k("wasmBinary","wasmBinary"),r.noExitRuntime,k("noExitRuntime","noExitRuntime"),"object"!=typeof WebAssembly&&ge("no native wasm support detected");var A=!1;function F(e,r){e||ge("Assertion failed"+(r?": "+r:""))}var D="undefined"!=typeof TextDecoder?new TextDecoder("utf8"):void 0;function O(e,r,t){for(var n=r+t,o=r;e[o]&&!(o>=n);)++o;if(o-r>16&&e.buffer&&D)return D.decode(e.subarray(r,o));for(var i="";r<o;){var a=e[r++];if(128&a){var s=63&e[r++];if(192!=(224&a)){var l=63&e[r++];if(224==(240&a)?a=(15&a)<<12|s<<6|l:(240!=(248&a)&&T("Invalid UTF-8 leading byte 0x"+a.toString(16)+" encountered when deserializing a UTF-8 string in wasm memory to a JS string!"),a=(7&a)<<18|s<<12|l<<6|63&e[r++]),a<65536)i+=String.fromCharCode(a);else{var u=a-65536;i+=String.fromCharCode(55296|u>>10,56320|1023&u)}}else i+=String.fromCharCode((31&a)<<6|s)}else i+=String.fromCharCode(a)}return i}function R(e,r){return e?O(U,e,r):""}function M(e,r,t,n){if(!(n>0))return 0;for(var o=t,i=t+n-1,a=0;a<e.length;++a){var s=e.charCodeAt(a);if(s>=55296&&s<=57343)s=65536+((1023&s)<<10)|1023&e.charCodeAt(++a);if(s<=127){if(t>=i)break;r[t++]=s}else if(s<=2047){if(t+1>=i)break;r[t++]=192|s>>6,r[t++]=128|63&s}else if(s<=65535){if(t+2>=i)break;r[t++]=224|s>>12,r[t++]=128|s>>6&63,r[t++]=128|63&s}else{if(t+3>=i)break;s>1114111&&T("Invalid Unicode code point 0x"+s.toString(16)+" encountered when serializing a JS string to a UTF-8 string in wasm memory! (Valid unicode code points should be in range 0-0x10FFFF)."),r[t++]=240|s>>18,r[t++]=128|s>>12&63,r[t++]=128|s>>6&63,r[t++]=128|63&s}}return r[t]=0,t-o}function N(e,r,t){return F("number"==typeof t,"stringToUTF8(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!"),M(e,U,r,t)}function I(e){for(var r=0,t=0;t<e.length;++t){var n=e.charCodeAt(t);n>=55296&&n<=57343&&(n=65536+((1023&n)<<10)|1023&e.charCodeAt(++t)),n<=127?++r:r+=n<=2047?2:n<=65535?3:4}return r}var L,x,U,B,j,$,W,z,H,G="undefined"!=typeof TextDecoder?new TextDecoder("utf-16le"):void 0;function V(e,r){F(e%2==0,"Pointer passed to UTF16ToString must be aligned to two bytes!");for(var t=e,n=t>>1,o=n+r/2;!(n>=o)&&j[n];)++n;if((t=n<<1)-e>32&&G)return G.decode(U.subarray(e,t));for(var i="",a=0;!(a>=r/2);++a){var s=B[e+2*a>>1];if(0==s)break;i+=String.fromCharCode(s)}return i}function Y(e,r,t){if(F(r%2==0,"Pointer passed to stringToUTF16 must be aligned to two bytes!"),F("number"==typeof t,"stringToUTF16(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!"),void 0===t&&(t=2147483647),t<2)return 0;for(var n=r,o=(t-=2)<2*e.length?t/2:e.length,i=0;i<o;++i){var a=e.charCodeAt(i);B[r>>1]=a,r+=2}return B[r>>1]=0,r-n}function q(e){return 2*e.length}function X(e,r){F(e%4==0,"Pointer passed to UTF32ToString must be aligned to four bytes!");for(var t=0,n="";!(t>=r/4);){var o=$[e+4*t>>2];if(0==o)break;if(++t,o>=65536){var i=o-65536;n+=String.fromCharCode(55296|i>>10,56320|1023&i)}else n+=String.fromCharCode(o)}return n}function K(e,r,t){if(F(r%4==0,"Pointer passed to stringToUTF32 must be aligned to four bytes!"),F("number"==typeof t,"stringToUTF32(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!"),void 0===t&&(t=2147483647),t<4)return 0;for(var n=r,o=n+t-4,i=0;i<e.length;++i){var a=e.charCodeAt(i);if(a>=55296&&a<=57343)a=65536+((1023&a)<<10)|1023&e.charCodeAt(++i);if($[r>>2]=a,(r+=4)+4>o)break}return $[r>>2]=0,r-n}function J(e){for(var r=0,t=0;t<e.length;++t){var n=e.charCodeAt(t);n>=55296&&n<=57343&&++t,r+=4}return r}function Q(e){var r=I(e)+1,t=gt(r);return t&&M(e,x,t,r),t}function Z(e){L=e,r.HEAP8=x=new Int8Array(e),r.HEAP16=B=new Int16Array(e),r.HEAP32=$=new Int32Array(e),r.HEAPU8=U=new Uint8Array(e),r.HEAPU16=j=new Uint16Array(e),r.HEAPU32=W=new Uint32Array(e),r.HEAPF32=z=new Float32Array(e),r.HEAPF64=H=new Float64Array(e)}var ee=5242880;r.TOTAL_STACK&&F(ee===r.TOTAL_STACK,"the stack size can no longer be determined at runtime");var re,te=r.INITIAL_MEMORY||67108864;function ne(){var e=kt();F(0==(3&e)),$[e>>2]=34821223,$[e+4>>2]=2310721022,$[0]=1668509029}function oe(){if(!A){var e=kt(),r=W[e>>2],t=W[e+4>>2];34821223==r&&2310721022==t||ge("Stack overflow! Stack cookie has been overwritten, expected hex dwords 0x89BACDFE and 0x2135467, but received 0x"+t.toString(16)+" 0x"+r.toString(16)),1668509029!==$[0]&&ge("Runtime error: The application has corrupted its heap memory area (address zero)!")}}k("INITIAL_MEMORY","INITIAL_MEMORY"),F(te>=ee,"INITIAL_MEMORY should be larger than TOTAL_STACK, was "+te+"! (TOTAL_STACK="+"5242880)"),F("undefined"!=typeof Int32Array&&"undefined"!=typeof Float64Array&&null!=Int32Array.prototype.subarray&&null!=Int32Array.prototype.set,"JS engine does not provide full typed array support"),F(!r.wasmMemory,"Use of `wasmMemory` detected. Use -sIMPORTED_MEMORY to define wasmMemory externally"),F(67108864==te,"Detected runtime INITIAL_MEMORY setting. Use -sIMPORTED_MEMORY to define wasmMemory dynamically"),function(){var e=new Int16Array(1),r=new Int8Array(e.buffer);if(e[0]=25459,115!==r[0]||99!==r[1])throw"Runtime error: expected the system to be little-endian! (Run with -sSUPPORT_BIG_ENDIAN to bypass)"}();var ie=[],ae=[],se=[],le=!1;F(Math.imul,"This browser does not support Math.imul(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill"),F(Math.fround,"This browser does not support Math.fround(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill"),F(Math.clz32,"This browser does not support Math.clz32(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill"),F(Math.trunc,"This browser does not support Math.trunc(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill");var ue=0,ce=null,de=null,fe={};function pe(e){for(var r=e;;){if(!fe[e])return e;e=r+Math.random()}}function me(e){ue++,r.monitorRunDependencies&&r.monitorRunDependencies(ue),e?(F(!fe[e]),fe[e]=1,null===ce&&"undefined"!=typeof setInterval&&(ce=setInterval((function(){if(A)return clearInterval(ce),void(ce=null);var e=!1;for(var r in fe)e||(e=!0,_("still waiting on run dependencies:")),_("dependency: "+r);e&&_("(end of list)")}),1e4))):_("warning: run dependency added without ID")}function he(e){if(ue--,r.monitorRunDependencies&&r.monitorRunDependencies(ue),e?(F(fe[e]),delete fe[e]):_("warning: run dependency removed without ID"),0==ue&&(null!==ce&&(clearInterval(ce),ce=null),de)){var t=de;de=null,t()}}function ge(e){throw r.onAbort&&r.onAbort(e),_(e="Aborted("+e+")"),A=!0,new WebAssembly.RuntimeError(e)}var ve,ye,Ee;function we(e){return e.startsWith("data:application/octet-stream;base64,")}function be(e){return e.startsWith("file://")}function _e(e,t){return function(){var n=e,o=t;return t||(o=r.asm),F(le,"native function `"+n+"` called before runtime initialization"),o[e]||F(o[e],"exported native function `"+n+"` not found"),o[e].apply(null,arguments)}}function Te(e){try{if(e==ve&&E)return new Uint8Array(E);if(p)return p(e);throw"both async and sync fetching of the wasm failed"}catch(e){ge(e)}}function ke(e){for(;e.length>0;){var t=e.shift();if("function"!=typeof t){var n=t.func;"number"==typeof n?void 0===t.arg?Ce(n)():Ce(n)(t.arg):n(void 0===t.arg?null:t.arg)}else t(r)}}function Se(e){return e.replace(/\b_Z[\w\d_]+/g,(function(e){var r,t=(r=e,T("warning: build with -sDEMANGLE_SUPPORT to link in libcxxabi demangling"),r);return e===t?e:t+" ["+e+"]"}))}function Ce(e){return re.get(e)}function Pe(){var e=new Error;if(!e.stack){try{throw new Error}catch(r){e=r}if(!e.stack)return"(no stack trace available)"}return e.stack.toString()}we(ve="decoder.wasm")||(ve=function(e){return r.locateFile?r.locateFile(e,v):v+e}(ve));var Ae={isAbs:e=>"/"===e.charAt(0),splitPath:e=>/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/.exec(e).slice(1),normalizeArray:(e,r)=>{for(var t=0,n=e.length-1;n>=0;n--){var o=e[n];"."===o?e.splice(n,1):".."===o?(e.splice(n,1),t++):t&&(e.splice(n,1),t--)}if(r)for(;t;t--)e.unshift("..");return e},normalize:e=>{var r=Ae.isAbs(e),t="/"===e.substr(-1);return(e=Ae.normalizeArray(e.split("/").filter((e=>!!e)),!r).join("/"))||r||(e="."),e&&t&&(e+="/"),(r?"/":"")+e},dirname:e=>{var r=Ae.splitPath(e),t=r[0],n=r[1];return t||n?(n&&(n=n.substr(0,n.length-1)),t+n):"."},basename:e=>{if("/"===e)return"/";var r=(e=(e=Ae.normalize(e)).replace(/\/$/,"")).lastIndexOf("/");return-1===r?e:e.substr(r+1)},join:function(){var e=Array.prototype.slice.call(arguments,0);return Ae.normalize(e.join("/"))},join2:(e,r)=>Ae.normalize(e+"/"+r)};var Fe={resolve:function(){for(var e="",r=!1,t=arguments.length-1;t>=-1&&!r;t--){var n=t>=0?arguments[t]:Ie.cwd();if("string"!=typeof n)throw new TypeError("Arguments to path.resolve must be strings");if(!n)return"";e=n+"/"+e,r=Ae.isAbs(n)}return(r?"/":"")+(e=Ae.normalizeArray(e.split("/").filter((e=>!!e)),!r).join("/"))||"."},relative:(e,r)=>{function t(e){for(var r=0;r<e.length&&""===e[r];r++);for(var t=e.length-1;t>=0&&""===e[t];t--);return r>t?[]:e.slice(r,t-r+1)}e=Fe.resolve(e).substr(1),r=Fe.resolve(r).substr(1);for(var n=t(e.split("/")),o=t(r.split("/")),i=Math.min(n.length,o.length),a=i,s=0;s<i;s++)if(n[s]!==o[s]){a=s;break}var l=[];for(s=a;s<n.length;s++)l.push("..");return(l=l.concat(o.slice(a))).join("/")}},De={ttys:[],init:function(){},shutdown:function(){},register:function(e,r){De.ttys[e]={input:[],output:[],ops:r},Ie.registerDevice(e,De.stream_ops)},stream_ops:{open:function(e){var r=De.ttys[e.node.rdev];if(!r)throw new Ie.ErrnoError(43);e.tty=r,e.seekable=!1},close:function(e){e.tty.ops.flush(e.tty)},flush:function(e){e.tty.ops.flush(e.tty)},read:function(e,r,t,n,o){if(!e.tty||!e.tty.ops.get_char)throw new Ie.ErrnoError(60);for(var i=0,a=0;a<n;a++){var s;try{s=e.tty.ops.get_char(e.tty)}catch(e){throw new Ie.ErrnoError(29)}if(void 0===s&&0===i)throw new Ie.ErrnoError(6);if(null==s)break;i++,r[t+a]=s}return i&&(e.node.timestamp=Date.now()),i},write:function(e,r,t,n,o){if(!e.tty||!e.tty.ops.put_char)throw new Ie.ErrnoError(60);try{for(var i=0;i<n;i++)e.tty.ops.put_char(e.tty,r[t+i])}catch(e){throw new Ie.ErrnoError(29)}return n&&(e.node.timestamp=Date.now()),i}},default_tty_ops:{get_char:function(e){if(!e.input.length){var r=null;if(u){var t=Buffer.alloc(256),n=0;try{n=m.readSync(process.stdin.fd,t,0,256,-1)}catch(e){if(!e.toString().includes("EOF"))throw e;n=0}r=n>0?t.slice(0,n).toString("utf-8"):null}else"undefined"!=typeof window&&"function"==typeof window.prompt?null!==(r=window.prompt("Input: "))&&(r+="\n"):"function"==typeof readline&&null!==(r=readline())&&(r+="\n");if(!r)return null;e.input=pt(r,!0)}return e.input.shift()},put_char:function(e,r){null===r||10===r?(b(O(e.output,0)),e.output=[]):0!=r&&e.output.push(r)},flush:function(e){e.output&&e.output.length>0&&(b(O(e.output,0)),e.output=[])}},default_tty1_ops:{put_char:function(e,r){null===r||10===r?(_(O(e.output,0)),e.output=[]):0!=r&&e.output.push(r)},flush:function(e){e.output&&e.output.length>0&&(_(O(e.output,0)),e.output=[])}}};function Oe(e){e=function(e,r){return F(r,"alignment argument is required"),Math.ceil(e/r)*r}(e,65536);var r=bt(65536,e);return r?(function(e,r){U.fill(0,e,e+r)}(r,e),r):0}var Re={ops_table:null,mount:function(e){return Re.createNode(null,"/",16895,0)},createNode:function(e,r,t,n){if(Ie.isBlkdev(t)||Ie.isFIFO(t))throw new Ie.ErrnoError(63);Re.ops_table||(Re.ops_table={dir:{node:{getattr:Re.node_ops.getattr,setattr:Re.node_ops.setattr,lookup:Re.node_ops.lookup,mknod:Re.node_ops.mknod,rename:Re.node_ops.rename,unlink:Re.node_ops.unlink,rmdir:Re.node_ops.rmdir,readdir:Re.node_ops.readdir,symlink:Re.node_ops.symlink},stream:{llseek:Re.stream_ops.llseek}},file:{node:{getattr:Re.node_ops.getattr,setattr:Re.node_ops.setattr},stream:{llseek:Re.stream_ops.llseek,read:Re.stream_ops.read,write:Re.stream_ops.write,allocate:Re.stream_ops.allocate,mmap:Re.stream_ops.mmap,msync:Re.stream_ops.msync}},link:{node:{getattr:Re.node_ops.getattr,setattr:Re.node_ops.setattr,readlink:Re.node_ops.readlink},stream:{}},chrdev:{node:{getattr:Re.node_ops.getattr,setattr:Re.node_ops.setattr},stream:Ie.chrdev_stream_ops}});var o=Ie.createNode(e,r,t,n);return Ie.isDir(o.mode)?(o.node_ops=Re.ops_table.dir.node,o.stream_ops=Re.ops_table.dir.stream,o.contents={}):Ie.isFile(o.mode)?(o.node_ops=Re.ops_table.file.node,o.stream_ops=Re.ops_table.file.stream,o.usedBytes=0,o.contents=null):Ie.isLink(o.mode)?(o.node_ops=Re.ops_table.link.node,o.stream_ops=Re.ops_table.link.stream):Ie.isChrdev(o.mode)&&(o.node_ops=Re.ops_table.chrdev.node,o.stream_ops=Re.ops_table.chrdev.stream),o.timestamp=Date.now(),e&&(e.contents[r]=o,e.timestamp=o.timestamp),o},getFileDataAsTypedArray:function(e){return e.contents?e.contents.subarray?e.contents.subarray(0,e.usedBytes):new Uint8Array(e.contents):new Uint8Array(0)},expandFileStorage:function(e,r){var t=e.contents?e.contents.length:0;if(!(t>=r)){r=Math.max(r,t*(t<1048576?2:1.125)>>>0),0!=t&&(r=Math.max(r,256));var n=e.contents;e.contents=new Uint8Array(r),e.usedBytes>0&&e.contents.set(n.subarray(0,e.usedBytes),0)}},resizeFileStorage:function(e,r){if(e.usedBytes!=r)if(0==r)e.contents=null,e.usedBytes=0;else{var t=e.contents;e.contents=new Uint8Array(r),t&&e.contents.set(t.subarray(0,Math.min(r,e.usedBytes))),e.usedBytes=r}},node_ops:{getattr:function(e){var r={};return r.dev=Ie.isChrdev(e.mode)?e.id:1,r.ino=e.id,r.mode=e.mode,r.nlink=1,r.uid=0,r.gid=0,r.rdev=e.rdev,Ie.isDir(e.mode)?r.size=4096:Ie.isFile(e.mode)?r.size=e.usedBytes:Ie.isLink(e.mode)?r.size=e.link.length:r.size=0,r.atime=new Date(e.timestamp),r.mtime=new Date(e.timestamp),r.ctime=new Date(e.timestamp),r.blksize=4096,r.blocks=Math.ceil(r.size/r.blksize),r},setattr:function(e,r){void 0!==r.mode&&(e.mode=r.mode),void 0!==r.timestamp&&(e.timestamp=r.timestamp),void 0!==r.size&&Re.resizeFileStorage(e,r.size)},lookup:function(e,r){throw Ie.genericErrors[44]},mknod:function(e,r,t,n){return Re.createNode(e,r,t,n)},rename:function(e,r,t){if(Ie.isDir(e.mode)){var n;try{n=Ie.lookupNode(r,t)}catch(e){}if(n)for(var o in n.contents)throw new Ie.ErrnoError(55)}delete e.parent.contents[e.name],e.parent.timestamp=Date.now(),e.name=t,r.contents[t]=e,r.timestamp=e.parent.timestamp,e.parent=r},unlink:function(e,r){delete e.contents[r],e.timestamp=Date.now()},rmdir:function(e,r){var t=Ie.lookupNode(e,r);for(var n in t.contents)throw new Ie.ErrnoError(55);delete e.contents[r],e.timestamp=Date.now()},readdir:function(e){var r=[".",".."];for(var t in e.contents)e.contents.hasOwnProperty(t)&&r.push(t);return r},symlink:function(e,r,t){var n=Re.createNode(e,r,41471,0);return n.link=t,n},readlink:function(e){if(!Ie.isLink(e.mode))throw new Ie.ErrnoError(28);return e.link}},stream_ops:{read:function(e,r,t,n,o){var i=e.node.contents;if(o>=e.node.usedBytes)return 0;var a=Math.min(e.node.usedBytes-o,n);if(F(a>=0),a>8&&i.subarray)r.set(i.subarray(o,o+a),t);else for(var s=0;s<a;s++)r[t+s]=i[o+s];return a},write:function(e,r,t,n,o,i){if(F(!(r instanceof ArrayBuffer)),r.buffer===x.buffer&&(i=!1),!n)return 0;var a=e.node;if(a.timestamp=Date.now(),r.subarray&&(!a.contents||a.contents.subarray)){if(i)return F(0===o,"canOwn must imply no weird position inside the file"),a.contents=r.subarray(t,t+n),a.usedBytes=n,n;if(0===a.usedBytes&&0===o)return a.contents=r.slice(t,t+n),a.usedBytes=n,n;if(o+n<=a.usedBytes)return a.contents.set(r.subarray(t,t+n),o),n}if(Re.expandFileStorage(a,o+n),a.contents.subarray&&r.subarray)a.contents.set(r.subarray(t,t+n),o);else for(var s=0;s<n;s++)a.contents[o+s]=r[t+s];return a.usedBytes=Math.max(a.usedBytes,o+n),n},llseek:function(e,r,t){var n=r;if(1===t?n+=e.position:2===t&&Ie.isFile(e.node.mode)&&(n+=e.node.usedBytes),n<0)throw new Ie.ErrnoError(28);return n},allocate:function(e,r,t){Re.expandFileStorage(e.node,r+t),e.node.usedBytes=Math.max(e.node.usedBytes,r+t)},mmap:function(e,r,t,n,o,i){if(0!==r)throw new Ie.ErrnoError(28);if(!Ie.isFile(e.node.mode))throw new Ie.ErrnoError(43);var a,s,l=e.node.contents;if(2&i||l.buffer!==L){if((n>0||n+t<l.length)&&(l=l.subarray?l.subarray(n,n+t):Array.prototype.slice.call(l,n,n+t)),s=!0,!(a=Oe(t)))throw new Ie.ErrnoError(48);x.set(l,a)}else s=!1,a=l.byteOffset;return{ptr:a,allocated:s}},msync:function(e,r,t,n,o){if(!Ie.isFile(e.node.mode))throw new Ie.ErrnoError(43);return 2&o||Re.stream_ops.write(e,r,0,n,t,!1),0}}};var Me={0:"Success",1:"Arg list too long",2:"Permission denied",3:"Address already in use",4:"Address not available",5:"Address family not supported by protocol family",6:"No more processes",7:"Socket already connected",8:"Bad file number",9:"Trying to read unreadable message",10:"Mount device busy",11:"Operation canceled",12:"No children",13:"Connection aborted",14:"Connection refused",15:"Connection reset by peer",16:"File locking deadlock error",17:"Destination address required",18:"Math arg out of domain of func",19:"Quota exceeded",20:"File exists",21:"Bad address",22:"File too large",23:"Host is unreachable",24:"Identifier removed",25:"Illegal byte sequence",26:"Connection already in progress",27:"Interrupted system call",28:"Invalid argument",29:"I/O error",30:"Socket is already connected",31:"Is a directory",32:"Too many symbolic links",33:"Too many open files",34:"Too many links",35:"Message too long",36:"Multihop attempted",37:"File or path name too long",38:"Network interface is not configured",39:"Connection reset by network",40:"Network is unreachable",41:"Too many open files in system",42:"No buffer space available",43:"No such device",44:"No such file or directory",45:"Exec format error",46:"No record locks available",47:"The link has been severed",48:"Not enough core",49:"No message of desired type",50:"Protocol not available",51:"No space left on device",52:"Function not implemented",53:"Socket is not connected",54:"Not a directory",55:"Directory not empty",56:"State not recoverable",57:"Socket operation on non-socket",59:"Not a typewriter",60:"No such device or address",61:"Value too large for defined data type",62:"Previous owner died",63:"Not super-user",64:"Broken pipe",65:"Protocol error",66:"Unknown protocol",67:"Protocol wrong type for socket",68:"Math result not representable",69:"Read only file system",70:"Illegal seek",71:"No such process",72:"Stale file handle",73:"Connection timed out",74:"Text file busy",75:"Cross-device link",100:"Device not a stream",101:"Bad font file fmt",102:"Invalid slot",103:"Invalid request code",104:"No anode",105:"Block device required",106:"Channel number out of range",107:"Level 3 halted",108:"Level 3 reset",109:"Link number out of range",110:"Protocol driver not attached",111:"No CSI structure available",112:"Level 2 halted",113:"Invalid exchange",114:"Invalid request descriptor",115:"Exchange full",116:"No data (for no delay io)",117:"Timer expired",118:"Out of streams resources",119:"Machine is not on the network",120:"Package not installed",121:"The object is remote",122:"Advertise error",123:"Srmount error",124:"Communication error on send",125:"Cross mount point (not really error)",126:"Given log. name not unique",127:"f.d. invalid for this operation",128:"Remote address changed",129:"Can access a needed shared lib",130:"Accessing a corrupted shared lib",131:".lib section in a.out corrupted",132:"Attempting to link in too many libs",133:"Attempting to exec a shared library",135:"Streams pipe error",136:"Too many users",137:"Socket type not supported",138:"Not supported",139:"Protocol family not supported",140:"Can't send after socket shutdown",141:"Too many references",142:"Host is down",148:"No medium (in tape drive)",156:"Level 2 not synchronized"},Ne={},Ie={root:null,mounts:[],devices:{},streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:!1,ignorePermissions:!0,ErrnoError:null,genericErrors:{},filesystems:null,syncFSRequests:0,lookupPath:function(e){let r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(!(e=Fe.resolve(Ie.cwd(),e)))return{path:"",node:null};var t={follow_mount:!0,recurse_count:0};if(r=Object.assign(t,r),r.recurse_count>8)throw new Ie.ErrnoError(32);for(var n=Ae.normalizeArray(e.split("/").filter((e=>!!e)),!1),o=Ie.root,i="/",a=0;a<n.length;a++){var s=a===n.length-1;if(s&&r.parent)break;if(o=Ie.lookupNode(o,n[a]),i=Ae.join2(i,n[a]),Ie.isMountpoint(o)&&(!s||s&&r.follow_mount)&&(o=o.mounted.root),!s||r.follow)for(var l=0;Ie.isLink(o.mode);){var u=Ie.readlink(i);i=Fe.resolve(Ae.dirname(i),u);var c=Ie.lookupPath(i,{recurse_count:r.recurse_count+1});if(o=c.node,l++>40)throw new Ie.ErrnoError(32)}}return{path:i,node:o}},getPath:e=>{for(var r;;){if(Ie.isRoot(e)){var t=e.mount.mountpoint;return r?"/"!==t[t.length-1]?t+"/"+r:t+r:t}r=r?e.name+"/"+r:e.name,e=e.parent}},hashName:(e,r)=>{for(var t=0,n=0;n<r.length;n++)t=(t<<5)-t+r.charCodeAt(n)|0;return(e+t>>>0)%Ie.nameTable.length},hashAddNode:e=>{var r=Ie.hashName(e.parent.id,e.name);e.name_next=Ie.nameTable[r],Ie.nameTable[r]=e},hashRemoveNode:e=>{var r=Ie.hashName(e.parent.id,e.name);if(Ie.nameTable[r]===e)Ie.nameTable[r]=e.name_next;else for(var t=Ie.nameTable[r];t;){if(t.name_next===e){t.name_next=e.name_next;break}t=t.name_next}},lookupNode:(e,r)=>{var t=Ie.mayLookup(e);if(t)throw new Ie.ErrnoError(t,e);for(var n=Ie.hashName(e.id,r),o=Ie.nameTable[n];o;o=o.name_next){var i=o.name;if(o.parent.id===e.id&&i===r)return o}return Ie.lookup(e,r)},createNode:(e,r,t,n)=>{F("object"==typeof e);var o=new Ie.FSNode(e,r,t,n);return Ie.hashAddNode(o),o},destroyNode:e=>{Ie.hashRemoveNode(e)},isRoot:e=>e===e.parent,isMountpoint:e=>!!e.mounted,isFile:e=>32768==(61440&e),isDir:e=>16384==(61440&e),isLink:e=>40960==(61440&e),isChrdev:e=>8192==(61440&e),isBlkdev:e=>24576==(61440&e),isFIFO:e=>4096==(61440&e),isSocket:e=>49152==(49152&e),flagModes:{r:0,"r+":2,w:577,"w+":578,a:1089,"a+":1090},modeStringToFlags:e=>{var r=Ie.flagModes[e];if(void 0===r)throw new Error("Unknown file open mode: "+e);return r},flagsToPermissionString:e=>{var r=["r","w","rw"][3&e];return 512&e&&(r+="w"),r},nodePermissions:(e,r)=>Ie.ignorePermissions||(!r.includes("r")||292&e.mode)&&(!r.includes("w")||146&e.mode)&&(!r.includes("x")||73&e.mode)?0:2,mayLookup:e=>{var r=Ie.nodePermissions(e,"x");return r||(e.node_ops.lookup?0:2)},mayCreate:(e,r)=>{try{Ie.lookupNode(e,r);return 20}catch(e){}return Ie.nodePermissions(e,"wx")},mayDelete:(e,r,t)=>{var n;try{n=Ie.lookupNode(e,r)}catch(e){return e.errno}var o=Ie.nodePermissions(e,"wx");if(o)return o;if(t){if(!Ie.isDir(n.mode))return 54;if(Ie.isRoot(n)||Ie.getPath(n)===Ie.cwd())return 10}else if(Ie.isDir(n.mode))return 31;return 0},mayOpen:(e,r)=>e?Ie.isLink(e.mode)?32:Ie.isDir(e.mode)&&("r"!==Ie.flagsToPermissionString(r)||512&r)?31:Ie.nodePermissions(e,Ie.flagsToPermissionString(r)):44,MAX_OPEN_FDS:4096,nextfd:function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:Ie.MAX_OPEN_FDS;for(var t=e;t<=r;t++)if(!Ie.streams[t])return t;throw new Ie.ErrnoError(33)},getStream:e=>Ie.streams[e],createStream:(e,r,t)=>{Ie.FSStream||(Ie.FSStream=function(){this.shared={}},Ie.FSStream.prototype={object:{get:function(){return this.node},set:function(e){this.node=e}},isRead:{get:function(){return 1!=(2097155&this.flags)}},isWrite:{get:function(){return 0!=(2097155&this.flags)}},isAppend:{get:function(){return 1024&this.flags}},flags:{get:function(){return this.shared.flags},set:function(e){this.shared.flags=e}},position:{get function(){return this.shared.position},set:function(e){this.shared.position=e}}}),e=Object.assign(new Ie.FSStream,e);var n=Ie.nextfd(r,t);return e.fd=n,Ie.streams[n]=e,e},closeStream:e=>{Ie.streams[e]=null},chrdev_stream_ops:{open:e=>{var r=Ie.getDevice(e.node.rdev);e.stream_ops=r.stream_ops,e.stream_ops.open&&e.stream_ops.open(e)},llseek:()=>{throw new Ie.ErrnoError(70)}},major:e=>e>>8,minor:e=>255&e,makedev:(e,r)=>e<<8|r,registerDevice:(e,r)=>{Ie.devices[e]={stream_ops:r}},getDevice:e=>Ie.devices[e],getMounts:e=>{for(var r=[],t=[e];t.length;){var n=t.pop();r.push(n),t.push.apply(t,n.mounts)}return r},syncfs:(e,r)=>{"function"==typeof e&&(r=e,e=!1),Ie.syncFSRequests++,Ie.syncFSRequests>1&&_("warning: "+Ie.syncFSRequests+" FS.syncfs operations in flight at once, probably just doing extra work");var t=Ie.getMounts(Ie.root.mount),n=0;function o(e){return F(Ie.syncFSRequests>0),Ie.syncFSRequests--,r(e)}function i(e){if(e)return i.errored?void 0:(i.errored=!0,o(e));++n>=t.length&&o(null)}t.forEach((r=>{if(!r.type.syncfs)return i(null);r.type.syncfs(r,e,i)}))},mount:(e,r,t)=>{if("string"==typeof e)throw e;var n,o="/"===t,i=!t;if(o&&Ie.root)throw new Ie.ErrnoError(10);if(!o&&!i){var a=Ie.lookupPath(t,{follow_mount:!1});if(t=a.path,n=a.node,Ie.isMountpoint(n))throw new Ie.ErrnoError(10);if(!Ie.isDir(n.mode))throw new Ie.ErrnoError(54)}var s={type:e,opts:r,mountpoint:t,mounts:[]},l=e.mount(s);return l.mount=s,s.root=l,o?Ie.root=l:n&&(n.mounted=s,n.mount&&n.mount.mounts.push(s)),l},unmount:e=>{var r=Ie.lookupPath(e,{follow_mount:!1});if(!Ie.isMountpoint(r.node))throw new Ie.ErrnoError(28);var t=r.node,n=t.mounted,o=Ie.getMounts(n);Object.keys(Ie.nameTable).forEach((e=>{for(var r=Ie.nameTable[e];r;){var t=r.name_next;o.includes(r.mount)&&Ie.destroyNode(r),r=t}})),t.mounted=null;var i=t.mount.mounts.indexOf(n);F(-1!==i),t.mount.mounts.splice(i,1)},lookup:(e,r)=>e.node_ops.lookup(e,r),mknod:(e,r,t)=>{var n=Ie.lookupPath(e,{parent:!0}).node,o=Ae.basename(e);if(!o||"."===o||".."===o)throw new Ie.ErrnoError(28);var i=Ie.mayCreate(n,o);if(i)throw new Ie.ErrnoError(i);if(!n.node_ops.mknod)throw new Ie.ErrnoError(63);return n.node_ops.mknod(n,o,r,t)},create:(e,r)=>(r=void 0!==r?r:438,r&=4095,r|=32768,Ie.mknod(e,r,0)),mkdir:(e,r)=>(r=void 0!==r?r:511,r&=1023,r|=16384,Ie.mknod(e,r,0)),mkdirTree:(e,r)=>{for(var t=e.split("/"),n="",o=0;o<t.length;++o)if(t[o]){n+="/"+t[o];try{Ie.mkdir(n,r)}catch(e){if(20!=e.errno)throw e}}},mkdev:(e,r,t)=>(void 0===t&&(t=r,r=438),r|=8192,Ie.mknod(e,r,t)),symlink:(e,r)=>{if(!Fe.resolve(e))throw new Ie.ErrnoError(44);var t=Ie.lookupPath(r,{parent:!0}).node;if(!t)throw new Ie.ErrnoError(44);var n=Ae.basename(r),o=Ie.mayCreate(t,n);if(o)throw new Ie.ErrnoError(o);if(!t.node_ops.symlink)throw new Ie.ErrnoError(63);return t.node_ops.symlink(t,n,e)},rename:(e,r)=>{var t,n,o=Ae.dirname(e),i=Ae.dirname(r),a=Ae.basename(e),s=Ae.basename(r);if(t=Ie.lookupPath(e,{parent:!0}).node,n=Ie.lookupPath(r,{parent:!0}).node,!t||!n)throw new Ie.ErrnoError(44);if(t.mount!==n.mount)throw new Ie.ErrnoError(75);var l,u=Ie.lookupNode(t,a),c=Fe.relative(e,i);if("."!==c.charAt(0))throw new Ie.ErrnoError(28);if("."!==(c=Fe.relative(r,o)).charAt(0))throw new Ie.ErrnoError(55);try{l=Ie.lookupNode(n,s)}catch(e){}if(u!==l){var d=Ie.isDir(u.mode),f=Ie.mayDelete(t,a,d);if(f)throw new Ie.ErrnoError(f);if(f=l?Ie.mayDelete(n,s,d):Ie.mayCreate(n,s))throw new Ie.ErrnoError(f);if(!t.node_ops.rename)throw new Ie.ErrnoError(63);if(Ie.isMountpoint(u)||l&&Ie.isMountpoint(l))throw new Ie.ErrnoError(10);if(n!==t&&(f=Ie.nodePermissions(t,"w")))throw new Ie.ErrnoError(f);Ie.hashRemoveNode(u);try{t.node_ops.rename(u,n,s)}catch(e){throw e}finally{Ie.hashAddNode(u)}}},rmdir:e=>{var r=Ie.lookupPath(e,{parent:!0}).node,t=Ae.basename(e),n=Ie.lookupNode(r,t),o=Ie.mayDelete(r,t,!0);if(o)throw new Ie.ErrnoError(o);if(!r.node_ops.rmdir)throw new Ie.ErrnoError(63);if(Ie.isMountpoint(n))throw new Ie.ErrnoError(10);r.node_ops.rmdir(r,t),Ie.destroyNode(n)},readdir:e=>{var r=Ie.lookupPath(e,{follow:!0}).node;if(!r.node_ops.readdir)throw new Ie.ErrnoError(54);return r.node_ops.readdir(r)},unlink:e=>{var r=Ie.lookupPath(e,{parent:!0}).node;if(!r)throw new Ie.ErrnoError(44);var t=Ae.basename(e),n=Ie.lookupNode(r,t),o=Ie.mayDelete(r,t,!1);if(o)throw new Ie.ErrnoError(o);if(!r.node_ops.unlink)throw new Ie.ErrnoError(63);if(Ie.isMountpoint(n))throw new Ie.ErrnoError(10);r.node_ops.unlink(r,t),Ie.destroyNode(n)},readlink:e=>{var r=Ie.lookupPath(e).node;if(!r)throw new Ie.ErrnoError(44);if(!r.node_ops.readlink)throw new Ie.ErrnoError(28);return Fe.resolve(Ie.getPath(r.parent),r.node_ops.readlink(r))},stat:(e,r)=>{var t=Ie.lookupPath(e,{follow:!r}).node;if(!t)throw new Ie.ErrnoError(44);if(!t.node_ops.getattr)throw new Ie.ErrnoError(63);return t.node_ops.getattr(t)},lstat:e=>Ie.stat(e,!0),chmod:(e,r,t)=>{var n;"string"==typeof e?n=Ie.lookupPath(e,{follow:!t}).node:n=e;if(!n.node_ops.setattr)throw new Ie.ErrnoError(63);n.node_ops.setattr(n,{mode:4095&r|-4096&n.mode,timestamp:Date.now()})},lchmod:(e,r)=>{Ie.chmod(e,r,!0)},fchmod:(e,r)=>{var t=Ie.getStream(e);if(!t)throw new Ie.ErrnoError(8);Ie.chmod(t.node,r)},chown:(e,r,t,n)=>{var o;"string"==typeof e?o=Ie.lookupPath(e,{follow:!n}).node:o=e;if(!o.node_ops.setattr)throw new Ie.ErrnoError(63);o.node_ops.setattr(o,{timestamp:Date.now()})},lchown:(e,r,t)=>{Ie.chown(e,r,t,!0)},fchown:(e,r,t)=>{var n=Ie.getStream(e);if(!n)throw new Ie.ErrnoError(8);Ie.chown(n.node,r,t)},truncate:(e,r)=>{if(r<0)throw new Ie.ErrnoError(28);var t;"string"==typeof e?t=Ie.lookupPath(e,{follow:!0}).node:t=e;if(!t.node_ops.setattr)throw new Ie.ErrnoError(63);if(Ie.isDir(t.mode))throw new Ie.ErrnoError(31);if(!Ie.isFile(t.mode))throw new Ie.ErrnoError(28);var n=Ie.nodePermissions(t,"w");if(n)throw new Ie.ErrnoError(n);t.node_ops.setattr(t,{size:r,timestamp:Date.now()})},ftruncate:(e,r)=>{var t=Ie.getStream(e);if(!t)throw new Ie.ErrnoError(8);if(0==(2097155&t.flags))throw new Ie.ErrnoError(28);Ie.truncate(t.node,r)},utime:(e,r,t)=>{var n=Ie.lookupPath(e,{follow:!0}).node;n.node_ops.setattr(n,{timestamp:Math.max(r,t)})},open:(e,t,n,o,i)=>{if(""===e)throw new Ie.ErrnoError(44);var a;if(n=void 0===n?438:n,n=64&(t="string"==typeof t?Ie.modeStringToFlags(t):t)?4095&n|32768:0,"object"==typeof e)a=e;else{e=Ae.normalize(e);try{a=Ie.lookupPath(e,{follow:!(131072&t)}).node}catch(e){}}var s=!1;if(64&t)if(a){if(128&t)throw new Ie.ErrnoError(20)}else a=Ie.mknod(e,n,0),s=!0;if(!a)throw new Ie.ErrnoError(44);if(Ie.isChrdev(a.mode)&&(t&=-513),65536&t&&!Ie.isDir(a.mode))throw new Ie.ErrnoError(54);if(!s){var l=Ie.mayOpen(a,t);if(l)throw new Ie.ErrnoError(l)}512&t&&Ie.truncate(a,0),t&=-131713;var u=Ie.createStream({node:a,path:Ie.getPath(a),flags:t,seekable:!0,position:0,stream_ops:a.stream_ops,ungotten:[],error:!1},o,i);return u.stream_ops.open&&u.stream_ops.open(u),!r.logReadFiles||1&t||(Ie.readFiles||(Ie.readFiles={}),e in Ie.readFiles||(Ie.readFiles[e]=1)),u},close:e=>{if(Ie.isClosed(e))throw new Ie.ErrnoError(8);e.getdents&&(e.getdents=null);try{e.stream_ops.close&&e.stream_ops.close(e)}catch(e){throw e}finally{Ie.closeStream(e.fd)}e.fd=null},isClosed:e=>null===e.fd,llseek:(e,r,t)=>{if(Ie.isClosed(e))throw new Ie.ErrnoError(8);if(!e.seekable||!e.stream_ops.llseek)throw new Ie.ErrnoError(70);if(0!=t&&1!=t&&2!=t)throw new Ie.ErrnoError(28);return e.position=e.stream_ops.llseek(e,r,t),e.ungotten=[],e.position},read:(e,r,t,n,o)=>{if(n<0||o<0)throw new Ie.ErrnoError(28);if(Ie.isClosed(e))throw new Ie.ErrnoError(8);if(1==(2097155&e.flags))throw new Ie.ErrnoError(8);if(Ie.isDir(e.node.mode))throw new Ie.ErrnoError(31);if(!e.stream_ops.read)throw new Ie.ErrnoError(28);var i=void 0!==o;if(i){if(!e.seekable)throw new Ie.ErrnoError(70)}else o=e.position;var a=e.stream_ops.read(e,r,t,n,o);return i||(e.position+=a),a},write:(e,r,t,n,o,i)=>{if(n<0||o<0)throw new Ie.ErrnoError(28);if(Ie.isClosed(e))throw new Ie.ErrnoError(8);if(0==(2097155&e.flags))throw new Ie.ErrnoError(8);if(Ie.isDir(e.node.mode))throw new Ie.ErrnoError(31);if(!e.stream_ops.write)throw new Ie.ErrnoError(28);e.seekable&&1024&e.flags&&Ie.llseek(e,0,2);var a=void 0!==o;if(a){if(!e.seekable)throw new Ie.ErrnoError(70)}else o=e.position;var s=e.stream_ops.write(e,r,t,n,o,i);return a||(e.position+=s),s},allocate:(e,r,t)=>{if(Ie.isClosed(e))throw new Ie.ErrnoError(8);if(r<0||t<=0)throw new Ie.ErrnoError(28);if(0==(2097155&e.flags))throw new Ie.ErrnoError(8);if(!Ie.isFile(e.node.mode)&&!Ie.isDir(e.node.mode))throw new Ie.ErrnoError(43);if(!e.stream_ops.allocate)throw new Ie.ErrnoError(138);e.stream_ops.allocate(e,r,t)},mmap:(e,r,t,n,o,i)=>{if(0!=(2&o)&&0==(2&i)&&2!=(2097155&e.flags))throw new Ie.ErrnoError(2);if(1==(2097155&e.flags))throw new Ie.ErrnoError(2);if(!e.stream_ops.mmap)throw new Ie.ErrnoError(43);return e.stream_ops.mmap(e,r,t,n,o,i)},msync:(e,r,t,n,o)=>e&&e.stream_ops.msync?e.stream_ops.msync(e,r,t,n,o):0,munmap:e=>0,ioctl:(e,r,t)=>{if(!e.stream_ops.ioctl)throw new Ie.ErrnoError(59);return e.stream_ops.ioctl(e,r,t)},readFile:function(e){let r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(r.flags=r.flags||0,r.encoding=r.encoding||"binary","utf8"!==r.encoding&&"binary"!==r.encoding)throw new Error('Invalid encoding type "'+r.encoding+'"');var t,n=Ie.open(e,r.flags),o=Ie.stat(e),i=o.size,a=new Uint8Array(i);return Ie.read(n,a,0,i,0),"utf8"===r.encoding?t=O(a,0):"binary"===r.encoding&&(t=a),Ie.close(n),t},writeFile:function(e,r){let t=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};t.flags=t.flags||577;var n=Ie.open(e,t.flags,t.mode);if("string"==typeof r){var o=new Uint8Array(I(r)+1),i=M(r,o,0,o.length);Ie.write(n,o,0,i,void 0,t.canOwn)}else{if(!ArrayBuffer.isView(r))throw new Error("Unsupported data type");Ie.write(n,r,0,r.byteLength,void 0,t.canOwn)}Ie.close(n)},cwd:()=>Ie.currentPath,chdir:e=>{var r=Ie.lookupPath(e,{follow:!0});if(null===r.node)throw new Ie.ErrnoError(44);if(!Ie.isDir(r.node.mode))throw new Ie.ErrnoError(54);var t=Ie.nodePermissions(r.node,"x");if(t)throw new Ie.ErrnoError(t);Ie.currentPath=r.path},createDefaultDirectories:()=>{Ie.mkdir("/tmp"),Ie.mkdir("/home"),Ie.mkdir("/home/web_user")},createDefaultDevices:()=>{Ie.mkdir("/dev"),Ie.registerDevice(Ie.makedev(1,3),{read:()=>0,write:(e,r,t,n,o)=>n}),Ie.mkdev("/dev/null",Ie.makedev(1,3)),De.register(Ie.makedev(5,0),De.default_tty_ops),De.register(Ie.makedev(6,0),De.default_tty1_ops),Ie.mkdev("/dev/tty",Ie.makedev(5,0)),Ie.mkdev("/dev/tty1",Ie.makedev(6,0));var e=function(){if("object"==typeof crypto&&"function"==typeof crypto.getRandomValues){var e=new Uint8Array(1);return function(){return crypto.getRandomValues(e),e[0]}}if(u)try{var r=a.default;return function(){return r.randomBytes(1)[0]}}catch(e){}return function(){ge("no cryptographic support found for randomDevice. consider polyfilling it if you want to use something insecure like Math.random(), e.g. put this in a --pre-js: var crypto = { getRandomValues: function(array) { for (var i = 0; i < array.length; i++) array[i] = (Math.random()*256)|0 } };")}}();Ie.createDevice("/dev","random",e),Ie.createDevice("/dev","urandom",e),Ie.mkdir("/dev/shm"),Ie.mkdir("/dev/shm/tmp")},createSpecialDirectories:()=>{Ie.mkdir("/proc");var e=Ie.mkdir("/proc/self");Ie.mkdir("/proc/self/fd"),Ie.mount({mount:()=>{var r=Ie.createNode(e,"fd",16895,73);return r.node_ops={lookup:(e,r)=>{var t=+r,n=Ie.getStream(t);if(!n)throw new Ie.ErrnoError(8);var o={parent:null,mount:{mountpoint:"fake"},node_ops:{readlink:()=>n.path}};return o.parent=o,o}},r}},{},"/proc/self/fd")},createStandardStreams:()=>{r.stdin?Ie.createDevice("/dev","stdin",r.stdin):Ie.symlink("/dev/tty","/dev/stdin"),r.stdout?Ie.createDevice("/dev","stdout",null,r.stdout):Ie.symlink("/dev/tty","/dev/stdout"),r.stderr?Ie.createDevice("/dev","stderr",null,r.stderr):Ie.symlink("/dev/tty1","/dev/stderr");var e=Ie.open("/dev/stdin",0),t=Ie.open("/dev/stdout",1),n=Ie.open("/dev/stderr",1);F(0===e.fd,"invalid handle for stdin ("+e.fd+")"),F(1===t.fd,"invalid handle for stdout ("+t.fd+")"),F(2===n.fd,"invalid handle for stderr ("+n.fd+")")},ensureErrnoError:()=>{Ie.ErrnoError||(Ie.ErrnoError=function(e,r){this.node=r,this.setErrno=function(e){for(var r in this.errno=e,Ne)if(Ne[r]===e){this.code=r;break}},this.setErrno(e),this.message=Me[e],this.stack&&(Object.defineProperty(this,"stack",{value:(new Error).stack,writable:!0}),this.stack=Se(this.stack))},Ie.ErrnoError.prototype=new Error,Ie.ErrnoError.prototype.constructor=Ie.ErrnoError,[44].forEach((e=>{Ie.genericErrors[e]=new Ie.ErrnoError(e),Ie.genericErrors[e].stack="<generic error, no stack>"})))},staticInit:()=>{Ie.ensureErrnoError(),Ie.nameTable=new Array(4096),Ie.mount(Re,{},"/"),Ie.createDefaultDirectories(),Ie.createDefaultDevices(),Ie.createSpecialDirectories(),Ie.filesystems={MEMFS:Re}},init:(e,t,n)=>{F(!Ie.init.initialized,"FS.init was previously called. If you want to initialize later with custom parameters, remove any earlier calls (note that one is automatically added to the generated code)"),Ie.init.initialized=!0,Ie.ensureErrnoError(),r.stdin=e||r.stdin,r.stdout=t||r.stdout,r.stderr=n||r.stderr,Ie.createStandardStreams()},quit:()=>{Ie.init.initialized=!1,wt();for(var e=0;e<Ie.streams.length;e++){var r=Ie.streams[e];r&&Ie.close(r)}},getMode:(e,r)=>{var t=0;return e&&(t|=365),r&&(t|=146),t},findObject:(e,r)=>{var t=Ie.analyzePath(e,r);return t.exists?t.object:null},analyzePath:(e,r)=>{try{e=(n=Ie.lookupPath(e,{follow:!r})).path}catch(e){}var t={isRoot:!1,exists:!1,error:0,name:null,path:null,object:null,parentExists:!1,parentPath:null,parentObject:null};try{var n=Ie.lookupPath(e,{parent:!0});t.parentExists=!0,t.parentPath=n.path,t.parentObject=n.node,t.name=Ae.basename(e),n=Ie.lookupPath(e,{follow:!r}),t.exists=!0,t.path=n.path,t.object=n.node,t.name=n.node.name,t.isRoot="/"===n.path}catch(e){t.error=e.errno}return t},createPath:(e,r,t,n)=>{e="string"==typeof e?e:Ie.getPath(e);for(var o=r.split("/").reverse();o.length;){var i=o.pop();if(i){var a=Ae.join2(e,i);try{Ie.mkdir(a)}catch(e){}e=a}}return a},createFile:(e,r,t,n,o)=>{var i=Ae.join2("string"==typeof e?e:Ie.getPath(e),r),a=Ie.getMode(n,o);return Ie.create(i,a)},createDataFile:(e,r,t,n,o,i)=>{var a=r;e&&(e="string"==typeof e?e:Ie.getPath(e),a=r?Ae.join2(e,r):e);var s=Ie.getMode(n,o),l=Ie.create(a,s);if(t){if("string"==typeof t){for(var u=new Array(t.length),c=0,d=t.length;c<d;++c)u[c]=t.charCodeAt(c);t=u}Ie.chmod(l,146|s);var f=Ie.open(l,577);Ie.write(f,t,0,t.length,0,i),Ie.close(f),Ie.chmod(l,s)}return l},createDevice:(e,r,t,n)=>{var o=Ae.join2("string"==typeof e?e:Ie.getPath(e),r),i=Ie.getMode(!!t,!!n);Ie.createDevice.major||(Ie.createDevice.major=64);var a=Ie.makedev(Ie.createDevice.major++,0);return Ie.registerDevice(a,{open:e=>{e.seekable=!1},close:e=>{n&&n.buffer&&n.buffer.length&&n(10)},read:(e,r,n,o,i)=>{for(var a=0,s=0;s<o;s++){var l;try{l=t()}catch(e){throw new Ie.ErrnoError(29)}if(void 0===l&&0===a)throw new Ie.ErrnoError(6);if(null==l)break;a++,r[n+s]=l}return a&&(e.node.timestamp=Date.now()),a},write:(e,r,t,o,i)=>{for(var a=0;a<o;a++)try{n(r[t+a])}catch(e){throw new Ie.ErrnoError(29)}return o&&(e.node.timestamp=Date.now()),a}}),Ie.mkdev(o,i,a)},forceLoadFile:e=>{if(e.isDevice||e.isFolder||e.link||e.contents)return!0;if("undefined"!=typeof XMLHttpRequest)throw new Error("Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread.");if(!d)throw new Error("Cannot load without read() or XMLHttpRequest.");try{e.contents=pt(d(e.url),!0),e.usedBytes=e.contents.length}catch(e){throw new Ie.ErrnoError(29)}},createLazyFile:(e,r,t,n,o)=>{function i(){this.lengthKnown=!1,this.chunks=[]}if(i.prototype.get=function(e){if(!(e>this.length-1||e<0)){var r=e%this.chunkSize,t=e/this.chunkSize|0;return this.getter(t)[r]}},i.prototype.setDataGetter=function(e){this.getter=e},i.prototype.cacheLength=function(){var e=new XMLHttpRequest;if(e.open("HEAD",t,!1),e.send(null),!(e.status>=200&&e.status<300||304===e.status))throw new Error("Couldn't load "+t+". Status: "+e.status);var r,n=Number(e.getResponseHeader("Content-length")),o=(r=e.getResponseHeader("Accept-Ranges"))&&"bytes"===r,i=(r=e.getResponseHeader("Content-Encoding"))&&"gzip"===r,a=1048576;o||(a=n);var s=this;s.setDataGetter((e=>{var r=e*a,o=(e+1)*a-1;if(o=Math.min(o,n-1),void 0===s.chunks[e]&&(s.chunks[e]=((e,r)=>{if(e>r)throw new Error("invalid range ("+e+", "+r+") or no bytes requested!");if(r>n-1)throw new Error("only "+n+" bytes available! programmer error!");var o=new XMLHttpRequest;if(o.open("GET",t,!1),n!==a&&o.setRequestHeader("Range","bytes="+e+"-"+r),o.responseType="arraybuffer",o.overrideMimeType&&o.overrideMimeType("text/plain; charset=x-user-defined"),o.send(null),!(o.status>=200&&o.status<300||304===o.status))throw new Error("Couldn't load "+t+". Status: "+o.status);return void 0!==o.response?new Uint8Array(o.response||[]):pt(o.responseText||"",!0)})(r,o)),void 0===s.chunks[e])throw new Error("doXHR failed!");return s.chunks[e]})),!i&&n||(a=n=1,n=this.getter(0).length,a=n,b("LazyFiles on gzip forces download of the whole file when length is accessed")),this._length=n,this._chunkSize=a,this.lengthKnown=!0},"undefined"!=typeof XMLHttpRequest){if(!l)throw"Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc";var a=new i;Object.defineProperties(a,{length:{get:function(){return this.lengthKnown||this.cacheLength(),this._length}},chunkSize:{get:function(){return this.lengthKnown||this.cacheLength(),this._chunkSize}}});var s={isDevice:!1,contents:a}}else s={isDevice:!1,url:t};var u=Ie.createFile(e,r,s,n,o);s.contents?u.contents=s.contents:s.url&&(u.contents=null,u.url=s.url),Object.defineProperties(u,{usedBytes:{get:function(){return this.contents.length}}});var c={};return Object.keys(u.stream_ops).forEach((e=>{var r=u.stream_ops[e];c[e]=function(){return Ie.forceLoadFile(u),r.apply(null,arguments)}})),c.read=(e,r,t,n,o)=>{Ie.forceLoadFile(u);var i=e.node.contents;if(o>=i.length)return 0;var a=Math.min(i.length-o,n);if(F(a>=0),i.slice)for(var s=0;s<a;s++)r[t+s]=i[o+s];else for(s=0;s<a;s++)r[t+s]=i.get(o+s);return a},u.stream_ops=c,u},createPreloadedFile:(e,r,t,n,o,i,a,s,l,u)=>{var c=r?Fe.resolve(Ae.join2(e,r)):e,d=pe("cp "+c);function p(t){function f(t){u&&u(),s||Ie.createDataFile(e,r,t,n,o,l),i&&i(),he(d)}Browser.handledByPreloadPlugin(t,c,f,(()=>{a&&a(),he(d)}))||f(t)}me(d),"string"==typeof t?function(e,r,t,n){var o=n?"":pe("al "+e);f(e,(function(t){F(t,'Loading data file "'+e+'" failed (no arrayBuffer).'),r(new Uint8Array(t)),o&&he(o)}),(function(r){if(!t)throw'Loading data file "'+e+'" failed.';t()})),o&&me(o)}(t,(e=>p(e)),a):p(t)},indexedDB:()=>window.indexedDB||window.mozIndexedDB||window.webkitIndexedDB||window.msIndexedDB,DB_NAME:()=>"EM_FS_"+window.location.pathname,DB_VERSION:20,DB_STORE_NAME:"FILE_DATA",saveFilesToDB:(e,r,t)=>{r=r||(()=>{}),t=t||(()=>{});var n=Ie.indexedDB();try{var o=n.open(Ie.DB_NAME(),Ie.DB_VERSION)}catch(e){return t(e)}o.onupgradeneeded=()=>{b("creating db"),o.result.createObjectStore(Ie.DB_STORE_NAME)},o.onsuccess=()=>{var n=o.result.transaction([Ie.DB_STORE_NAME],"readwrite"),i=n.objectStore(Ie.DB_STORE_NAME),a=0,s=0,l=e.length;function u(){0==s?r():t()}e.forEach((e=>{var r=i.put(Ie.analyzePath(e).object.contents,e);r.onsuccess=()=>{++a+s==l&&u()},r.onerror=()=>{s++,a+s==l&&u()}})),n.onerror=t},o.onerror=t},loadFilesFromDB:(e,r,t)=>{r=r||(()=>{}),t=t||(()=>{});var n=Ie.indexedDB();try{var o=n.open(Ie.DB_NAME(),Ie.DB_VERSION)}catch(e){return t(e)}o.onupgradeneeded=t,o.onsuccess=()=>{var n=o.result;try{var i=n.transaction([Ie.DB_STORE_NAME],"readonly")}catch(e){return void t(e)}var a=i.objectStore(Ie.DB_STORE_NAME),s=0,l=0,u=e.length;function c(){0==l?r():t()}e.forEach((e=>{var r=a.get(e);r.onsuccess=()=>{Ie.analyzePath(e).exists&&Ie.unlink(e),Ie.createDataFile(Ae.dirname(e),Ae.basename(e),r.result,!0,!0,!0),++s+l==u&&c()},r.onerror=()=>{l++,s+l==u&&c()}})),i.onerror=t},o.onerror=t},absolutePath:()=>{ge("FS.absolutePath has been removed; use PATH_FS.resolve instead")},createFolder:()=>{ge("FS.createFolder has been removed; use FS.mkdir instead")},createLink:()=>{ge("FS.createLink has been removed; use FS.symlink instead")},joinPath:()=>{ge("FS.joinPath has been removed; use PATH.join instead")},mmapAlloc:()=>{ge("FS.mmapAlloc has been replaced by the top level function mmapAlloc")},standardizePath:()=>{ge("FS.standardizePath has been removed; use PATH.normalize instead")}},Le={DEFAULT_POLLMASK:5,calculateAt:function(e,r,t){if(Ae.isAbs(r))return r;var n;if(-100===e)n=Ie.cwd();else{var o=Ie.getStream(e);if(!o)throw new Ie.ErrnoError(8);n=o.path}if(0==r.length){if(!t)throw new Ie.ErrnoError(44);return n}return Ae.join2(n,r)},doStat:function(e,r,t){try{var n=e(r)}catch(e){if(e&&e.node&&Ae.normalize(r)!==Ae.normalize(Ie.getPath(e.node)))return-54;throw e}return $[t>>2]=n.dev,$[t+4>>2]=0,$[t+8>>2]=n.ino,$[t+12>>2]=n.mode,$[t+16>>2]=n.nlink,$[t+20>>2]=n.uid,$[t+24>>2]=n.gid,$[t+28>>2]=n.rdev,$[t+32>>2]=0,Ee=[n.size>>>0,(ye=n.size,+Math.abs(ye)>=1?ye>0?(0|Math.min(+Math.floor(ye/4294967296),4294967295))>>>0:~~+Math.ceil((ye-+(~~ye>>>0))/4294967296)>>>0:0)],$[t+40>>2]=Ee[0],$[t+44>>2]=Ee[1],$[t+48>>2]=4096,$[t+52>>2]=n.blocks,$[t+56>>2]=n.atime.getTime()/1e3|0,$[t+60>>2]=0,$[t+64>>2]=n.mtime.getTime()/1e3|0,$[t+68>>2]=0,$[t+72>>2]=n.ctime.getTime()/1e3|0,$[t+76>>2]=0,Ee=[n.ino>>>0,(ye=n.ino,+Math.abs(ye)>=1?ye>0?(0|Math.min(+Math.floor(ye/4294967296),4294967295))>>>0:~~+Math.ceil((ye-+(~~ye>>>0))/4294967296)>>>0:0)],$[t+80>>2]=Ee[0],$[t+84>>2]=Ee[1],0},doMsync:function(e,r,t,n,o){var i=U.slice(e,e+t);Ie.msync(r,i,o,t,n)},doMknod:function(e,r,t){switch(61440&r){case 32768:case 8192:case 24576:case 4096:case 49152:break;default:return-28}return Ie.mknod(e,r,t),0},doReadlink:function(e,r,t){if(t<=0)return-28;var n=Ie.readlink(e),o=Math.min(t,I(n)),i=x[r+o];return N(n,r,t+1),x[r+o]=i,o},doAccess:function(e,r){if(-8&r)return-28;var t=Ie.lookupPath(e,{follow:!0}).node;if(!t)return-44;var n="";return 4&r&&(n+="r"),2&r&&(n+="w"),1&r&&(n+="x"),n&&Ie.nodePermissions(t,n)?-2:0},doReadv:function(e,r,t,n){for(var o=0,i=0;i<t;i++){var a=$[r>>2],s=$[r+4>>2];r+=8;var l=Ie.read(e,x,a,s,n);if(l<0)return-1;if(o+=l,l<s)break}return o},doWritev:function(e,r,t,n){for(var o=0,i=0;i<t;i++){var a=$[r>>2],s=$[r+4>>2];r+=8;var l=Ie.write(e,x,a,s,n);if(l<0)return-1;o+=l}return o},varargs:void 0,get:function(){return F(null!=Le.varargs),Le.varargs+=4,$[Le.varargs-4>>2]},getStr:function(e){return R(e)},getStreamFromFD:function(e){var r=Ie.getStream(e);if(!r)throw new Ie.ErrnoError(8);return r}};function xe(e){switch(e){case 1:return 0;case 2:return 1;case 4:return 2;case 8:return 3;default:throw new TypeError("Unknown type size: "+e)}}var Ue=void 0;function Be(e){for(var r="",t=e;U[t];)r+=Ue[U[t++]];return r}var je={},$e={},We={};function ze(e){if(void 0===e)return"_unknown";var r=(e=e.replace(/[^a-zA-Z0-9_]/g,"$")).charCodeAt(0);return r>=48&&r<=57?"_"+e:e}function He(e,r){return e=ze(e),new Function("body","return function "+e+'() {\n "use strict"; return body.apply(this, arguments);\n};\n')(r)}function Ge(e,r){var t=He(r,(function(e){this.name=r,this.message=e;var t=new Error(e).stack;void 0!==t&&(this.stack=this.toString()+"\n"+t.replace(/^Error(:[^\n]*)?\n/,""))}));return t.prototype=Object.create(e.prototype),t.prototype.constructor=t,t.prototype.toString=function(){return void 0===this.message?this.name:this.name+": "+this.message},t}var Ve=void 0;function Ye(e){throw new Ve(e)}var qe=void 0;function Xe(e){throw new qe(e)}function Ke(e,r,t){function n(r){var n=t(r);n.length!==e.length&&Xe("Mismatched type converter count");for(var o=0;o<e.length;++o)Je(e[o],n[o])}e.forEach((function(e){We[e]=r}));var o=new Array(r.length),i=[],a=0;r.forEach(((e,r)=>{$e.hasOwnProperty(e)?o[r]=$e[e]:(i.push(e),je.hasOwnProperty(e)||(je[e]=[]),je[e].push((()=>{o[r]=$e[e],++a===i.length&&n(o)})))})),0===i.length&&n(o)}function Je(e,r){let t=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};if(!("argPackAdvance"in r))throw new TypeError("registerType registeredInstance requires argPackAdvance");var n=r.name;if(e||Ye('type "'+n+'" must have a positive integer typeid pointer'),$e.hasOwnProperty(e)){if(t.ignoreDuplicateRegistrations)return;Ye("Cannot register type '"+n+"' twice")}if($e[e]=r,delete We[e],je.hasOwnProperty(e)){var o=je[e];delete je[e],o.forEach((e=>e()))}}function Qe(e){if(!(this instanceof wr))return!1;if(!(e instanceof wr))return!1;for(var r=this.$$.ptrType.registeredClass,t=this.$$.ptr,n=e.$$.ptrType.registeredClass,o=e.$$.ptr;r.baseClass;)t=r.upcast(t),r=r.baseClass;for(;n.baseClass;)o=n.upcast(o),n=n.baseClass;return r===n&&t===o}function Ze(e){Ye(e.$$.ptrType.registeredClass.name+" instance already deleted")}var er=!1;function rr(e){}function tr(e){e.count.value-=1,0===e.count.value&&function(e){e.smartPtr?e.smartPtrType.rawDestructor(e.smartPtr):e.ptrType.registeredClass.rawDestructor(e.ptr)}(e)}function nr(e,r,t){if(r===t)return e;if(void 0===t.baseClass)return null;var n=nr(e,r,t.baseClass);return null===n?null:t.downcast(n)}var or={};function ir(){return Object.keys(dr).length}function ar(){var e=[];for(var r in dr)dr.hasOwnProperty(r)&&e.push(dr[r]);return e}var sr=[];function lr(){for(;sr.length;){var e=sr.pop();e.$$.deleteScheduled=!1,e.delete()}}var ur=void 0;function cr(e){ur=e,sr.length&&ur&&ur(lr)}var dr={};function fr(e,r){return r=function(e,r){for(void 0===r&&Ye("ptr should not be undefined");e.baseClass;)r=e.upcast(r),e=e.baseClass;return r}(e,r),dr[r]}function pr(e,r){return r.ptrType&&r.ptr||Xe("makeClassHandle requires ptr and ptrType"),!!r.smartPtrType!==!!r.smartPtr&&Xe("Both smartPtrType and smartPtr must be specified"),r.count={value:1},hr(Object.create(e,{$$:{value:r}}))}function mr(e){var r=this.getPointee(e);if(!r)return this.destructor(e),null;var t=fr(this.registeredClass,r);if(void 0!==t){if(0===t.$$.count.value)return t.$$.ptr=r,t.$$.smartPtr=e,t.clone();var n=t.clone();return this.destructor(e),n}function o(){return this.isSmartPointer?pr(this.registeredClass.instancePrototype,{ptrType:this.pointeeType,ptr:r,smartPtrType:this,smartPtr:e}):pr(this.registeredClass.instancePrototype,{ptrType:this,ptr:e})}var i,a=this.registeredClass.getActualType(r),s=or[a];if(!s)return o.call(this);i=this.isConst?s.constPointerType:s.pointerType;var l=nr(r,this.registeredClass,i.registeredClass);return null===l?o.call(this):this.isSmartPointer?pr(i.registeredClass.instancePrototype,{ptrType:i,ptr:l,smartPtrType:this,smartPtr:e}):pr(i.registeredClass.instancePrototype,{ptrType:i,ptr:l})}function hr(e){return"undefined"==typeof FinalizationRegistry?(hr=e=>e,e):(er=new FinalizationRegistry((e=>{console.warn(e.leakWarning.stack.replace(/^Error: /,"")),tr(e.$$)})),hr=e=>{var r=e.$$;if(!!r.smartPtr){var t={$$:r},n=r.ptrType.registeredClass;t.leakWarning=new Error("Embind found a leaked C++ instance "+n.name+" <0x"+r.ptr.toString(16)+">.\nWe'll free it automatically in this case, but this functionality is not reliable across various environments.\nMake sure to invoke .delete() manually once you're done with the instance instead.\nOriginally allocated"),"captureStackTrace"in Error&&Error.captureStackTrace(t.leakWarning,mr),er.register(e,t,e)}return e},rr=e=>er.unregister(e),hr(e))}function gr(){if(this.$$.ptr||Ze(this),this.$$.preservePointerOnDelete)return this.$$.count.value+=1,this;var e,r=hr(Object.create(Object.getPrototypeOf(this),{$$:{value:(e=this.$$,{count:e.count,deleteScheduled:e.deleteScheduled,preservePointerOnDelete:e.preservePointerOnDelete,ptr:e.ptr,ptrType:e.ptrType,smartPtr:e.smartPtr,smartPtrType:e.smartPtrType})}}));return r.$$.count.value+=1,r.$$.deleteScheduled=!1,r}function vr(){this.$$.ptr||Ze(this),this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete&&Ye("Object already scheduled for deletion"),rr(this),tr(this.$$),this.$$.preservePointerOnDelete||(this.$$.smartPtr=void 0,this.$$.ptr=void 0)}function yr(){return!this.$$.ptr}function Er(){return this.$$.ptr||Ze(this),this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete&&Ye("Object already scheduled for deletion"),sr.push(this),1===sr.length&&ur&&ur(lr),this.$$.deleteScheduled=!0,this}function wr(){}function br(e,r,t){if(void 0===e[r].overloadTable){var n=e[r];e[r]=function(){return e[r].overloadTable.hasOwnProperty(arguments.length)||Ye("Function '"+t+"' called with an invalid number of arguments ("+arguments.length+") - expects one of ("+e[r].overloadTable+")!"),e[r].overloadTable[arguments.length].apply(this,arguments)},e[r].overloadTable=[],e[r].overloadTable[n.argCount]=n}}function _r(e,r,t,n,o,i,a,s){this.name=e,this.constructor=r,this.instancePrototype=t,this.rawDestructor=n,this.baseClass=o,this.getActualType=i,this.upcast=a,this.downcast=s,this.pureVirtualFunctions=[]}function Tr(e,r,t){for(;r!==t;)r.upcast||Ye("Expected null or instance of "+t.name+", got an instance of "+r.name),e=r.upcast(e),r=r.baseClass;return e}function kr(e,r){if(null===r)return this.isReference&&Ye("null is not a valid "+this.name),0;r.$$||Ye('Cannot pass "'+qr(r)+'" as a '+this.name),r.$$.ptr||Ye("Cannot pass deleted object as a pointer of type "+this.name);var t=r.$$.ptrType.registeredClass;return Tr(r.$$.ptr,t,this.registeredClass)}function Sr(e,r){var t;if(null===r)return this.isReference&&Ye("null is not a valid "+this.name),this.isSmartPointer?(t=this.rawConstructor(),null!==e&&e.push(this.rawDestructor,t),t):0;r.$$||Ye('Cannot pass "'+qr(r)+'" as a '+this.name),r.$$.ptr||Ye("Cannot pass deleted object as a pointer of type "+this.name),!this.isConst&&r.$$.ptrType.isConst&&Ye("Cannot convert argument of type "+(r.$$.smartPtrType?r.$$.smartPtrType.name:r.$$.ptrType.name)+" to parameter type "+this.name);var n=r.$$.ptrType.registeredClass;if(t=Tr(r.$$.ptr,n,this.registeredClass),this.isSmartPointer)switch(void 0===r.$$.smartPtr&&Ye("Passing raw pointer to smart pointer is illegal"),this.sharingPolicy){case 0:r.$$.smartPtrType===this?t=r.$$.smartPtr:Ye("Cannot convert argument of type "+(r.$$.smartPtrType?r.$$.smartPtrType.name:r.$$.ptrType.name)+" to parameter type "+this.name);break;case 1:t=r.$$.smartPtr;break;case 2:if(r.$$.smartPtrType===this)t=r.$$.smartPtr;else{var o=r.clone();t=this.rawShare(t,Yr.toHandle((function(){o.delete()}))),null!==e&&e.push(this.rawDestructor,t)}break;default:Ye("Unsupporting sharing policy")}return t}function Cr(e,r){if(null===r)return this.isReference&&Ye("null is not a valid "+this.name),0;r.$$||Ye('Cannot pass "'+qr(r)+'" as a '+this.name),r.$$.ptr||Ye("Cannot pass deleted object as a pointer of type "+this.name),r.$$.ptrType.isConst&&Ye("Cannot convert argument of type "+r.$$.ptrType.name+" to parameter type "+this.name);var t=r.$$.ptrType.registeredClass;return Tr(r.$$.ptr,t,this.registeredClass)}function Pr(e){return this.fromWireType(W[e>>2])}function Ar(e){return this.rawGetPointee&&(e=this.rawGetPointee(e)),e}function Fr(e){this.rawDestructor&&this.rawDestructor(e)}function Dr(e){null!==e&&e.delete()}function Or(e,r,t,n,o,i,a,s,l,u,c){this.name=e,this.registeredClass=r,this.isReference=t,this.isConst=n,this.isSmartPointer=o,this.pointeeType=i,this.sharingPolicy=a,this.rawGetPointee=s,this.rawConstructor=l,this.rawShare=u,this.rawDestructor=c,o||void 0!==r.baseClass?this.toWireType=Sr:n?(this.toWireType=kr,this.destructorFunction=null):(this.toWireType=Cr,this.destructorFunction=null)}function Rr(e,t,n){return e.includes("j")?function(e,t,n){F("dynCall_"+e in r,"bad function pointer type - no table for sig '"+e+"'"),n&&n.length?F(n.length===e.substring(1).replace(/j/g,"--").length):F(1==e.length);var o=r["dynCall_"+e];return n&&n.length?o.apply(null,[t].concat(n)):o.call(null,t)}(e,t,n):(F(Ce(t),"missing table entry in dynCall: "+t),Ce(t).apply(null,n))}function Mr(e,r){var t=(e=Be(e)).includes("j")?function(e,r){F(e.includes("j"),"getDynCaller should only be called with i64 sigs");var t=[];return function(){return t.length=0,Object.assign(t,arguments),Rr(e,r,t)}}(e,r):Ce(r);return"function"!=typeof t&&Ye("unknown function pointer with signature "+e+": "+r),t}var Nr=void 0;function Ir(e){var r=Et(e),t=Be(r);return ht(r),t}function Lr(e,r){var t=[],n={};throw r.forEach((function e(r){n[r]||$e[r]||(We[r]?We[r].forEach(e):(t.push(r),n[r]=!0))})),new Nr(e+": "+t.map(Ir).join([", "]))}function xr(e,r){for(var t=[],n=0;n<e;n++)t.push($[(r>>2)+n]);return t}function Ur(e){for(;e.length;){var r=e.pop();e.pop()(r)}}function Br(e,r){if(!(e instanceof Function))throw new TypeError("new_ called with constructor type "+typeof e+" which is not a function");var t=He(e.name||"unknownFunctionName",(function(){}));t.prototype=e.prototype;var n=new t,o=e.apply(n,r);return o instanceof Object?o:n}function jr(e,r,t,n,o){var i=r.length;i<2&&Ye("argTypes array size mismatch! Must at least get return value and 'this' types!");for(var a=null!==r[1]&&null!==t,s=!1,l=1;l<r.length;++l)if(null!==r[l]&&void 0===r[l].destructorFunction){s=!0;break}var u="void"!==r[0].name,c="",d="";for(l=0;l<i-2;++l)c+=(0!==l?", ":"")+"arg"+l,d+=(0!==l?", ":"")+"arg"+l+"Wired";var f="return function "+ze(e)+"("+c+") {\nif (arguments.length !== "+(i-2)+") {\nthrowBindingError('function "+e+" called with ' + arguments.length + ' arguments, expected "+(i-2)+" args!');\n}\n";s&&(f+="var destructors = [];\n");var p=s?"destructors":"null",m=["throwBindingError","invoker","fn","runDestructors","retType","classParam"],h=[Ye,n,o,Ur,r[0],r[1]];a&&(f+="var thisWired = classParam.toWireType("+p+", this);\n");for(l=0;l<i-2;++l)f+="var arg"+l+"Wired = argType"+l+".toWireType("+p+", arg"+l+"); // "+r[l+2].name+"\n",m.push("argType"+l),h.push(r[l+2]);if(a&&(d="thisWired"+(d.length>0?", ":"")+d),f+=(u?"var rv = ":"")+"invoker(fn"+(d.length>0?", ":"")+d+");\n",s)f+="runDestructors(destructors);\n";else for(l=a?1:2;l<r.length;++l){var g=1===l?"thisWired":"arg"+(l-2)+"Wired";null!==r[l].destructorFunction&&(f+=g+"_dtor("+g+"); // "+r[l].name+"\n",m.push(g+"_dtor"),h.push(r[l].destructorFunction))}return u&&(f+="var ret = retType.fromWireType(rv);\nreturn ret;\n"),f+="}\n",m.push(f),Br(Function,m).apply(null,h)}function $r(e,r,t){return e instanceof Object||Ye(t+' with invalid "this": '+e),e instanceof r.registeredClass.constructor||Ye(t+' incompatible with "this" of type '+e.constructor.name),e.$$.ptr||Ye("cannot call emscripten binding method "+t+" on deleted object"),Tr(e.$$.ptr,e.$$.ptrType.registeredClass,r.registeredClass)}var Wr=[],zr=[{},{value:void 0},{value:null},{value:!0},{value:!1}];function Hr(e){e>4&&0==--zr[e].refcount&&(zr[e]=void 0,Wr.push(e))}function Gr(){for(var e=0,r=5;r<zr.length;++r)void 0!==zr[r]&&++e;return e}function Vr(){for(var e=5;e<zr.length;++e)if(void 0!==zr[e])return zr[e];return null}var Yr={toValue:e=>(e||Ye("Cannot use deleted val. handle = "+e),zr[e].value),toHandle:e=>{switch(e){case void 0:return 1;case null:return 2;case!0:return 3;case!1:return 4;default:var r=Wr.length?Wr.pop():zr.length;return zr[r]={refcount:1,value:e},r}}};function qr(e){if(null===e)return"null";var r=typeof e;return"object"===r||"array"===r||"function"===r?e.toString():""+e}function Xr(e,r){switch(r){case 2:return function(e){return this.fromWireType(z[e>>2])};case 3:return function(e){return this.fromWireType(H[e>>3])};default:throw new TypeError("Unknown float type: "+e)}}function Kr(e,r,t){switch(r){case 0:return t?function(e){return x[e]}:function(e){return U[e]};case 1:return t?function(e){return B[e>>1]}:function(e){return j[e>>1]};case 2:return t?function(e){return $[e>>2]}:function(e){return W[e>>2]};default:throw new TypeError("Unknown integer type: "+e)}}function Jr(e,r){var t=$e[e];return void 0===t&&Ye(r+" has unknown type "+Ir(e)),t}var Qr={};var Zr=[];var et=[];function rt(e,r){return F(r===(0|r)),(e>>>0)+4294967296*r}function tt(e,r){if(e<=0)return e;var t=r<=32?Math.abs(1<<r-1):Math.pow(2,r-1);return e>=t&&(r<=32||e>t)&&(e=-2*t+e),e}function nt(e,r){return e>=0?e:r<=32?2*Math.abs(1<<r-1)+e:Math.pow(2,r)+e}function ot(e,r){F(0==(3&r));var t=e,n=r;function o(e){var r;return n=function(e,r){return"double"===r||"i64"===r?7&e&&(F(4==(7&e)),e+=4):F(0==(3&e)),e}(n,e),"double"===e?(r=Number(H[n>>3]),n+=8):"i64"==e?(r=[$[n>>2],$[n+4>>2]],n+=8):(F(0==(3&n)),e="i32",r=$[n>>2],n+=4),r}for(var i,a,s,l,u,c,d=[];;){var f=t;if(0===(i=x[t>>0]))break;if(a=x[t+1>>0],37==i){var p=!1,m=!1,h=!1,g=!1,v=!1;e:for(;;){switch(a){case 43:p=!0;break;case 45:m=!0;break;case 35:h=!0;break;case 48:if(g)break e;g=!0;break;case 32:v=!0;break;default:break e}t++,a=x[t+1>>0]}var y=0;if(42==a)y=o("i32"),t++,a=x[t+1>>0];else for(;a>=48&&a<=57;)y=10*y+(a-48),t++,a=x[t+1>>0];var E,w=!1,b=-1;if(46==a){if(b=0,w=!0,t++,42==(a=x[t+1>>0]))b=o("i32"),t++;else for(;;){var _=x[t+1>>0];if(_<48||_>57)break;b=10*b+(_-48),t++}a=x[t+1>>0]}switch(b<0&&(b=6,w=!1),String.fromCharCode(a)){case"h":104==x[t+2>>0]?(t++,E=1):E=2;break;case"l":108==x[t+2>>0]?(t++,E=8):E=4;break;case"L":case"q":case"j":E=8;break;case"z":case"t":case"I":E=4;break;default:E=null}switch(E&&t++,a=x[t+1>>0],String.fromCharCode(a)){case"d":case"i":case"u":case"o":case"x":case"X":case"p":var T=100==a||105==a;if(s=o("i"+8*(E=E||4)),8==E&&(s=117==a?(u=s[0],c=s[1],(u>>>0)+4294967296*(c>>>0)):rt(s[0],s[1])),E<=4)s=(T?tt:nt)(s&Math.pow(256,E)-1,8*E);var k=Math.abs(s),S="";if(100==a||105==a)A=tt(s,8*E).toString(10);else if(117==a)A=nt(s,8*E).toString(10),s=Math.abs(s);else if(111==a)A=(h?"0":"")+k.toString(8);else if(120==a||88==a){if(S=h&&0!=s?"0x":"",s<0){s=-s,A=(k-1).toString(16);for(var C=[],P=0;P<A.length;P++)C.push((15-parseInt(A[P],16)).toString(16));for(A=C.join("");A.length<2*E;)A="f"+A}else A=k.toString(16);88==a&&(S=S.toUpperCase(),A=A.toUpperCase())}else 112==a&&(0===k?A="(nil)":(S="0x",A=k.toString(16)));if(w)for(;A.length<b;)A="0"+A;for(s>=0&&(p?S="+"+S:v&&(S=" "+S)),"-"==A.charAt(0)&&(S="-"+S,A=A.substr(1));S.length+A.length<y;)m?A+=" ":g?A="0"+A:S=" "+S;(A=S+A).split("").forEach((function(e){d.push(e.charCodeAt(0))}));break;case"f":case"F":case"e":case"E":case"g":case"G":var A;if(s=o("double"),isNaN(s))A="nan",g=!1;else if(isFinite(s)){var D=!1,O=Math.min(b,20);if(103==a||71==a){D=!0,b=b||1;var R=parseInt(s.toExponential(O).split("e")[1],10);b>R&&R>=-4?(a=(103==a?"f":"F").charCodeAt(0),b-=R+1):(a=(103==a?"e":"E").charCodeAt(0),b--),O=Math.min(b,20)}101==a||69==a?(A=s.toExponential(O),/[eE][-+]\d$/.test(A)&&(A=A.slice(0,-1)+"0"+A.slice(-1))):102!=a&&70!=a||(A=s.toFixed(O),0===s&&((l=s)<0||0===l&&1/l==-1/0)&&(A="-"+A));var M=A.split("e");if(D&&!h)for(;M[0].length>1&&M[0].includes(".")&&("0"==M[0].slice(-1)||"."==M[0].slice(-1));)M[0]=M[0].slice(0,-1);else for(h&&-1==A.indexOf(".")&&(M[0]+=".");b>O++;)M[0]+="0";A=M[0]+(M.length>1?"e"+M[1]:""),69==a&&(A=A.toUpperCase()),s>=0&&(p?A="+"+A:v&&(A=" "+A))}else A=(s<0?"-":"")+"inf",g=!1;for(;A.length<y;)m?A+=" ":A=!g||"-"!=A[0]&&"+"!=A[0]?(g?"0":" ")+A:A[0]+"0"+A.slice(1);a<97&&(A=A.toUpperCase()),A.split("").forEach((function(e){d.push(e.charCodeAt(0))}));break;case"s":var N=o("i8*"),I=N?vt(N):"(null)".length;if(w&&(I=Math.min(I,b)),!m)for(;I<y--;)d.push(32);if(N)for(P=0;P<I;P++)d.push(U[N++>>0]);else d=d.concat(pt("(null)".substr(0,I),!0));if(m)for(;I<y--;)d.push(32);break;case"c":for(m&&d.push(o("i8"));--y>0;)d.push(32);m||d.push(o("i8"));break;case"n":var L=o("i32*");$[L>>2]=d.length;break;case"%":d.push(i);break;default:for(P=f;P<t+2;P++)d.push(x[P>>0])}t+=2}else d.push(i),t+=1}return d}function it(e){if(!e||!e.callee||!e.callee.name)return[null,"",""];e.callee.toString();var r=e.callee.name,t="(",n=!0;for(var o in e){var i=e[o];n||(t+=", "),n=!1,t+="number"==typeof i||"string"==typeof i?i:"("+typeof i+")"}t+=")";var a=e.callee.caller;return n&&(t=""),[e=a?a.arguments:[],r,t]}function at(e,r){24&e&&(r=r.replace(/\s+$/,""),r+=(r.length>0?"\n":"")+function(e){var r=Pe(),t=r.lastIndexOf("_emscripten_log"),n=r.lastIndexOf("_emscripten_get_callstack"),o=r.indexOf("\n",Math.max(t,n))+1;r=r.slice(o),32&e&&T("EM_LOG_DEMANGLE is deprecated; ignoring"),8&e&&"undefined"==typeof emscripten_source_map&&(T('Source map information is not available, emscripten_log with EM_LOG_C_STACK will be ignored. Build with "--pre-js $EMSCRIPTEN/src/emscripten-source-map.min.js" linker flag to add source map loading to code.'),e^=8,e|=16);var i=null;if(128&e)for(i=it(arguments);i[1].includes("_emscripten_");)i=it(i[0]);var a=r.split("\n");r="";var s=new RegExp("\\s*(.*?)@(.*?):([0-9]+):([0-9]+)"),l=new RegExp("\\s*(.*?)@(.*):(.*)(:(.*))?"),u=new RegExp("\\s*at (.*?) \\((.*):(.*):(.*)\\)");for(var c in a){var d=a[c],f="",p="",m=0,h=0,g=u.exec(d);if(g&&5==g.length)f=g[1],p=g[2],m=g[3],h=g[4];else{if((g=s.exec(d))||(g=l.exec(d)),!(g&&g.length>=4)){r+=d+"\n";continue}f=g[1],p=g[2],m=g[3],h=0|g[4]}var v=!1;if(8&e){var y=emscripten_source_map.originalPositionFor({line:m,column:h});(v=y&&y.source)&&(64&e&&(y.source=y.source.substring(y.source.replace(/\\/g,"/").lastIndexOf("/")+1)),r+=" at "+f+" ("+y.source+":"+y.line+":"+y.column+")\n")}(16&e||!v)&&(64&e&&(p=p.substring(p.replace(/\\/g,"/").lastIndexOf("/")+1)),r+=(v?" = "+f:" at "+f)+" ("+p+":"+m+":"+h+")\n"),128&e&&i[0]&&(i[1]==f&&i[2].length>0&&(r=r.replace(/\s+$/,""),r+=" with values: "+i[1]+i[2]+"\n"),i=it(i[0]))}return r.replace(/\s+$/,"")}(e)),1&e?4&e?console.error(r):2&e?console.warn(r):512&e?console.info(r):256&e?console.debug(r):console.log(r):6&e?_(r):b(r)}function st(e){try{return w.grow(e-L.byteLength+65535>>>16),Z(w.buffer),1}catch(r){_("emscripten_realloc_buffer: Attempted to grow heap from "+L.byteLength+" bytes to "+e+" bytes, but got error: "+r)}}var lt={};function ut(){if(!ut.strings){var e={USER:"web_user",LOGNAME:"web_user",PATH:"/",PWD:"/",HOME:"/home/web_user",LANG:("object"==typeof navigator&&navigator.languages&&navigator.languages[0]||"C").replace("-","_")+".UTF-8",_:n||"./this.program"};for(var r in lt)void 0===lt[r]?delete e[r]:e[r]=lt[r];var t=[];for(var r in e)t.push(r+"="+e[r]);ut.strings=t}return ut.strings}var ct=function(e,r,t,n){e||(e=this),this.parent=e,this.mount=e.mount,this.mounted=null,this.id=Ie.nextInode++,this.name=r,this.mode=t,this.node_ops={},this.stream_ops={},this.rdev=n},dt=365,ft=146;function pt(e,r,t){var n=t>0?t:I(e)+1,o=new Array(n),i=M(e,o,0,o.length);return r&&(o.length=i),o}Object.defineProperties(ct.prototype,{read:{get:function(){return(this.mode&dt)===dt},set:function(e){e?this.mode|=dt:this.mode&=-366}},write:{get:function(){return(this.mode&ft)===ft},set:function(e){e?this.mode|=ft:this.mode&=-147}},isFolder:{get:function(){return Ie.isDir(this.mode)}},isDevice:{get:function(){return Ie.isChrdev(this.mode)}}}),Ie.FSNode=ct,Ie.staticInit(),Ne={EPERM:63,ENOENT:44,ESRCH:71,EINTR:27,EIO:29,ENXIO:60,E2BIG:1,ENOEXEC:45,EBADF:8,ECHILD:12,EAGAIN:6,EWOULDBLOCK:6,ENOMEM:48,EACCES:2,EFAULT:21,ENOTBLK:105,EBUSY:10,EEXIST:20,EXDEV:75,ENODEV:43,ENOTDIR:54,EISDIR:31,EINVAL:28,ENFILE:41,EMFILE:33,ENOTTY:59,ETXTBSY:74,EFBIG:22,ENOSPC:51,ESPIPE:70,EROFS:69,EMLINK:34,EPIPE:64,EDOM:18,ERANGE:68,ENOMSG:49,EIDRM:24,ECHRNG:106,EL2NSYNC:156,EL3HLT:107,EL3RST:108,ELNRNG:109,EUNATCH:110,ENOCSI:111,EL2HLT:112,EDEADLK:16,ENOLCK:46,EBADE:113,EBADR:114,EXFULL:115,ENOANO:104,EBADRQC:103,EBADSLT:102,EDEADLOCK:16,EBFONT:101,ENOSTR:100,ENODATA:116,ETIME:117,ENOSR:118,ENONET:119,ENOPKG:120,EREMOTE:121,ENOLINK:47,EADV:122,ESRMNT:123,ECOMM:124,EPROTO:65,EMULTIHOP:36,EDOTDOT:125,EBADMSG:9,ENOTUNIQ:126,EBADFD:127,EREMCHG:128,ELIBACC:129,ELIBBAD:130,ELIBSCN:131,ELIBMAX:132,ELIBEXEC:133,ENOSYS:52,ENOTEMPTY:55,ENAMETOOLONG:37,ELOOP:32,EOPNOTSUPP:138,EPFNOSUPPORT:139,ECONNRESET:15,ENOBUFS:42,EAFNOSUPPORT:5,EPROTOTYPE:67,ENOTSOCK:57,ENOPROTOOPT:50,ESHUTDOWN:140,ECONNREFUSED:14,EADDRINUSE:3,ECONNABORTED:13,ENETUNREACH:40,ENETDOWN:38,ETIMEDOUT:73,EHOSTDOWN:142,EHOSTUNREACH:23,EINPROGRESS:26,EALREADY:7,EDESTADDRREQ:17,EMSGSIZE:35,EPROTONOSUPPORT:66,ESOCKTNOSUPPORT:137,EADDRNOTAVAIL:4,ENETRESET:39,EISCONN:30,ENOTCONN:53,ETOOMANYREFS:141,EUSERS:136,EDQUOT:19,ESTALE:72,ENOTSUP:138,ENOMEDIUM:148,EILSEQ:25,EOVERFLOW:61,ECANCELED:11,ENOTRECOVERABLE:56,EOWNERDEAD:62,ESTRPIPE:135},function(){for(var e=new Array(256),r=0;r<256;++r)e[r]=String.fromCharCode(r);Ue=e}(),Ve=r.BindingError=Ge(Error,"BindingError"),qe=r.InternalError=Ge(Error,"InternalError"),wr.prototype.isAliasOf=Qe,wr.prototype.clone=gr,wr.prototype.delete=vr,wr.prototype.isDeleted=yr,wr.prototype.deleteLater=Er,r.getInheritedInstanceCount=ir,r.getLiveInheritedInstances=ar,r.flushPendingDeletes=lr,r.setDelayFunction=cr,Or.prototype.getPointee=Ar,Or.prototype.destructor=Fr,Or.prototype.argPackAdvance=8,Or.prototype.readValueFromPointer=Pr,Or.prototype.deleteObject=Dr,Or.prototype.fromWireType=mr,Nr=r.UnboundTypeError=Ge(Error,"UnboundTypeError"),r.count_emval_handles=Gr,r.get_first_emval=Vr;var mt={__syscall_fcntl64:function(e,r,t){Le.varargs=t;try{var n=Le.getStreamFromFD(e);switch(r){case 0:return(o=Le.get())<0?-28:Ie.createStream(n,o).fd;case 1:case 2:case 6:case 7:return 0;case 3:return n.flags;case 4:var o=Le.get();return n.flags|=o,0;case 5:o=Le.get();return B[o+0>>1]=2,0;case 16:case 8:default:return-28;case 9:return i=28,$[yt()>>2]=i,-1}}catch(e){if(void 0===Ie||!(e instanceof Ie.ErrnoError))throw e;return-e.errno}var i},__syscall_openat:function(e,r,t,n){Le.varargs=n;try{r=Le.getStr(r),r=Le.calculateAt(e,r);var o=n?Le.get():0;return Ie.open(r,t,o).fd}catch(e){if(void 0===Ie||!(e instanceof Ie.ErrnoError))throw e;return-e.errno}},_embind_register_bigint:function(e,r,t,n,o){},_embind_register_bool:function(e,r,t,n,o){var i=xe(t);Je(e,{name:r=Be(r),fromWireType:function(e){return!!e},toWireType:function(e,r){return r?n:o},argPackAdvance:8,readValueFromPointer:function(e){var n;if(1===t)n=x;else if(2===t)n=B;else{if(4!==t)throw new TypeError("Unknown boolean type size: "+r);n=$}return this.fromWireType(n[e>>i])},destructorFunction:null})},_embind_register_class:function(e,t,n,o,i,a,s,l,u,c,d,f,p){d=Be(d),a=Mr(i,a),l&&(l=Mr(s,l)),c&&(c=Mr(u,c)),p=Mr(f,p);var m=ze(d);!function(e,t,n){r.hasOwnProperty(e)?((void 0===n||void 0!==r[e].overloadTable&&void 0!==r[e].overloadTable[n])&&Ye("Cannot register public name '"+e+"' twice"),br(r,e,e),r.hasOwnProperty(n)&&Ye("Cannot register multiple overloads of a function with the same number of arguments ("+n+")!"),r[e].overloadTable[n]=t):(r[e]=t,void 0!==n&&(r[e].numArguments=n))}(m,(function(){Lr("Cannot construct "+d+" due to unbound types",[o])})),Ke([e,t,n],o?[o]:[],(function(t){var n,i;t=t[0],i=o?(n=t.registeredClass).instancePrototype:wr.prototype;var s=He(m,(function(){if(Object.getPrototypeOf(this)!==u)throw new Ve("Use 'new' to construct "+d);if(void 0===f.constructor_body)throw new Ve(d+" has no accessible constructor");var e=f.constructor_body[arguments.length];if(void 0===e)throw new Ve("Tried to invoke ctor of "+d+" with invalid number of parameters ("+arguments.length+") - expected ("+Object.keys(f.constructor_body).toString()+") parameters instead!");return e.apply(this,arguments)})),u=Object.create(i,{constructor:{value:s}});s.prototype=u;var f=new _r(d,s,u,p,n,a,l,c),h=new Or(d,f,!0,!1,!1),g=new Or(d+"*",f,!1,!1,!1),v=new Or(d+" const*",f,!1,!0,!1);return or[e]={pointerType:g,constPointerType:v},function(e,t,n){r.hasOwnProperty(e)||Xe("Replacing nonexistant public symbol"),void 0!==r[e].overloadTable&&void 0!==n?r[e].overloadTable[n]=t:(r[e]=t,r[e].argCount=n)}(m,s),[h,g,v]}))},_embind_register_class_constructor:function(e,r,t,n,o,i){F(r>0);var a=xr(r,t);o=Mr(n,o),Ke([],[e],(function(e){var t="constructor "+(e=e[0]).name;if(void 0===e.registeredClass.constructor_body&&(e.registeredClass.constructor_body=[]),void 0!==e.registeredClass.constructor_body[r-1])throw new Ve("Cannot register multiple constructors with identical number of parameters ("+(r-1)+") for class '"+e.name+"'! Overload resolution is currently only performed using the parameter count, not actual type info!");return e.registeredClass.constructor_body[r-1]=()=>{Lr("Cannot construct "+e.name+" due to unbound types",a)},Ke([],a,(function(n){return n.splice(1,0,null),e.registeredClass.constructor_body[r-1]=jr(t,n,null,o,i),[]})),[]}))},_embind_register_class_function:function(e,r,t,n,o,i,a,s){var l=xr(t,n);r=Be(r),i=Mr(o,i),Ke([],[e],(function(e){var n=(e=e[0]).name+"."+r;function o(){Lr("Cannot call "+n+" due to unbound types",l)}r.startsWith("@@")&&(r=Symbol[r.substring(2)]),s&&e.registeredClass.pureVirtualFunctions.push(r);var u=e.registeredClass.instancePrototype,c=u[r];return void 0===c||void 0===c.overloadTable&&c.className!==e.name&&c.argCount===t-2?(o.argCount=t-2,o.className=e.name,u[r]=o):(br(u,r,n),u[r].overloadTable[t-2]=o),Ke([],l,(function(o){var s=jr(n,o,e,i,a);return void 0===u[r].overloadTable?(s.argCount=t-2,u[r]=s):u[r].overloadTable[t-2]=s,[]})),[]}))},_embind_register_class_property:function(e,r,t,n,o,i,a,s,l,u){r=Be(r),o=Mr(n,o),Ke([],[e],(function(e){var n=(e=e[0]).name+"."+r,c={get:function(){Lr("Cannot access "+n+" due to unbound types",[t,a])},enumerable:!0,configurable:!0};return c.set=l?()=>{Lr("Cannot access "+n+" due to unbound types",[t,a])}:e=>{Ye(n+" is a read-only property")},Object.defineProperty(e.registeredClass.instancePrototype,r,c),Ke([],l?[t,a]:[t],(function(t){var a=t[0],c={get:function(){var r=$r(this,e,n+" getter");return a.fromWireType(o(i,r))},enumerable:!0};if(l){l=Mr(s,l);var d=t[1];c.set=function(r){var t=$r(this,e,n+" setter"),o=[];l(u,t,d.toWireType(o,r)),Ur(o)}}return Object.defineProperty(e.registeredClass.instancePrototype,r,c),[]})),[]}))},_embind_register_emval:function(e,r){Je(e,{name:r=Be(r),fromWireType:function(e){var r=Yr.toValue(e);return Hr(e),r},toWireType:function(e,r){return Yr.toHandle(r)},argPackAdvance:8,readValueFromPointer:Pr,destructorFunction:null})},_embind_register_float:function(e,r,t){var n=xe(t);Je(e,{name:r=Be(r),fromWireType:function(e){return e},toWireType:function(e,r){if("number"!=typeof r&&"boolean"!=typeof r)throw new TypeError('Cannot convert "'+qr(r)+'" to '+this.name);return r},argPackAdvance:8,readValueFromPointer:Xr(r,n),destructorFunction:null})},_embind_register_integer:function(e,r,t,n,o){r=Be(r),-1===o&&(o=4294967295);var i=xe(t),a=e=>e;if(0===n){var s=32-8*t;a=e=>e<<s>>>s}var l=r.includes("unsigned"),u=(e,t)=>{if("number"!=typeof e&&"boolean"!=typeof e)throw new TypeError('Cannot convert "'+qr(e)+'" to '+t);if(e<n||e>o)throw new TypeError('Passing a number "'+qr(e)+'" from JS side to C/C++ side to an argument of type "'+r+'", which is outside the valid range ['+n+", "+o+"]!")};Je(e,{name:r,fromWireType:a,toWireType:l?function(e,r){return u(r,this.name),r>>>0}:function(e,r){return u(r,this.name),r},argPackAdvance:8,readValueFromPointer:Kr(r,i,0!==n),destructorFunction:null})},_embind_register_memory_view:function(e,r,t){var n=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array][r];function o(e){var r=W,t=r[e>>=2],o=r[e+1];return new n(L,o,t)}Je(e,{name:t=Be(t),fromWireType:o,argPackAdvance:8,readValueFromPointer:o},{ignoreDuplicateRegistrations:!0})},_embind_register_std_string:function(e,r){var t="std::string"===(r=Be(r));Je(e,{name:r,fromWireType:function(e){var r,n=W[e>>2];if(t)for(var o=e+4,i=0;i<=n;++i){var a=e+4+i;if(i==n||0==U[a]){var s=R(o,a-o);void 0===r?r=s:(r+=String.fromCharCode(0),r+=s),o=a+1}}else{var l=new Array(n);for(i=0;i<n;++i)l[i]=String.fromCharCode(U[e+4+i]);r=l.join("")}return ht(e),r},toWireType:function(e,r){r instanceof ArrayBuffer&&(r=new Uint8Array(r));var n="string"==typeof r;n||r instanceof Uint8Array||r instanceof Uint8ClampedArray||r instanceof Int8Array||Ye("Cannot pass non-string to std::string");var o=(t&&n?()=>I(r):()=>r.length)(),i=gt(4+o+1);if(W[i>>2]=o,t&&n)N(r,i+4,o+1);else if(n)for(var a=0;a<o;++a){var s=r.charCodeAt(a);s>255&&(ht(i),Ye("String has UTF-16 code units that do not fit in 8 bits")),U[i+4+a]=s}else for(a=0;a<o;++a)U[i+4+a]=r[a];return null!==e&&e.push(ht,i),i},argPackAdvance:8,readValueFromPointer:Pr,destructorFunction:function(e){ht(e)}})},_embind_register_std_wstring:function(e,r,t){var n,o,i,a,s;t=Be(t),2===r?(n=V,o=Y,a=q,i=()=>j,s=1):4===r&&(n=X,o=K,a=J,i=()=>W,s=2),Je(e,{name:t,fromWireType:function(e){for(var t,o=W[e>>2],a=i(),l=e+4,u=0;u<=o;++u){var c=e+4+u*r;if(u==o||0==a[c>>s]){var d=n(l,c-l);void 0===t?t=d:(t+=String.fromCharCode(0),t+=d),l=c+r}}return ht(e),t},toWireType:function(e,n){"string"!=typeof n&&Ye("Cannot pass non-string to C++ string type "+t);var i=a(n),l=gt(4+i+r);return W[l>>2]=i>>s,o(n,l+4,i+r),null!==e&&e.push(ht,l),l},argPackAdvance:8,readValueFromPointer:Pr,destructorFunction:function(e){ht(e)}})},_embind_register_void:function(e,r){Je(e,{isVoid:!0,name:r=Be(r),argPackAdvance:0,fromWireType:function(){},toWireType:function(e,r){}})},_emscripten_date_now:function(){return Date.now()},_emval_as:function(e,r,t){e=Yr.toValue(e),r=Jr(r,"emval::as");var n=[],o=Yr.toHandle(n);return $[t>>2]=o,r.toWireType(n,e)},_emval_call_void_method:function(e,r,t,n){var o,i;(e=Zr[e])(r=Yr.toValue(r),t=void 0===(i=Qr[o=t])?Be(o):i,null,n)},_emval_decref:Hr,_emval_get_method_caller:function(e,r){var t=function(e,r){for(var t=new Array(e),n=0;n<e;++n)t[n]=Jr($[(r>>2)+n],"parameter "+n);return t}(e,r),n=t[0],o=n.name+"_$"+t.slice(1).map((function(e){return e.name})).join("_")+"$",i=et[o];if(void 0!==i)return i;for(var a=["retType"],s=[n],l="",u=0;u<e-1;++u)l+=(0!==u?", ":"")+"arg"+u,a.push("argType"+u),s.push(t[1+u]);var c="return function "+ze("methodCaller_"+o)+"(handle, name, destructors, args) {\n",d=0;for(u=0;u<e-1;++u)c+=" var arg"+u+" = argType"+u+".readValueFromPointer(args"+(d?"+"+d:"")+");\n",d+=t[u+1].argPackAdvance;for(c+=" var rv = handle[name]("+l+");\n",u=0;u<e-1;++u)t[u+1].deleteObject&&(c+=" argType"+u+".deleteObject(arg"+u+");\n");n.isVoid||(c+=" return retType.toWireType(destructors, rv);\n"),c+="};\n",a.push(c);var f,p,m=Br(Function,a).apply(null,s);return f=m,p=Zr.length,Zr.push(f),i=p,et[o]=i,i},_emval_incref:function(e){e>4&&(zr[e].refcount+=1)},_emval_run_destructors:function(e){Ur(Yr.toValue(e)),Hr(e)},_emval_take_value:function(e,r){var t=(e=Jr(e,"_emval_take_value")).readValueFromPointer(r);return Yr.toHandle(t)},_gmtime_js:function(e,r){var t=new Date(1e3*$[e>>2]);$[r>>2]=t.getUTCSeconds(),$[r+4>>2]=t.getUTCMinutes(),$[r+8>>2]=t.getUTCHours(),$[r+12>>2]=t.getUTCDate(),$[r+16>>2]=t.getUTCMonth(),$[r+20>>2]=t.getUTCFullYear()-1900,$[r+24>>2]=t.getUTCDay();var n=Date.UTC(t.getUTCFullYear(),0,1,0,0,0,0),o=(t.getTime()-n)/864e5|0;$[r+28>>2]=o},_localtime_js:function(e,r){var t=new Date(1e3*$[e>>2]);$[r>>2]=t.getSeconds(),$[r+4>>2]=t.getMinutes(),$[r+8>>2]=t.getHours(),$[r+12>>2]=t.getDate(),$[r+16>>2]=t.getMonth(),$[r+20>>2]=t.getFullYear()-1900,$[r+24>>2]=t.getDay();var n=new Date(t.getFullYear(),0,1),o=(t.getTime()-n.getTime())/864e5|0;$[r+28>>2]=o,$[r+36>>2]=-60*t.getTimezoneOffset();var i=new Date(t.getFullYear(),6,1).getTimezoneOffset(),a=n.getTimezoneOffset(),s=0|(i!=a&&t.getTimezoneOffset()==Math.min(a,i));$[r+32>>2]=s},_mktime_js:function(e){var r=new Date($[e+20>>2]+1900,$[e+16>>2],$[e+12>>2],$[e+8>>2],$[e+4>>2],$[e>>2],0),t=$[e+32>>2],n=r.getTimezoneOffset(),o=new Date(r.getFullYear(),0,1),i=new Date(r.getFullYear(),6,1).getTimezoneOffset(),a=o.getTimezoneOffset(),s=Math.min(a,i);if(t<0)$[e+32>>2]=Number(i!=a&&s==n);else if(t>0!=(s==n)){var l=Math.max(a,i),u=t>0?s:l;r.setTime(r.getTime()+6e4*(u-n))}$[e+24>>2]=r.getDay();var c=(r.getTime()-o.getTime())/864e5|0;return $[e+28>>2]=c,$[e>>2]=r.getSeconds(),$[e+4>>2]=r.getMinutes(),$[e+8>>2]=r.getHours(),$[e+12>>2]=r.getDate(),$[e+16>>2]=r.getMonth(),r.getTime()/1e3|0},_tzset_js:function e(r,t,n){e.called||(e.called=!0,function(e,r,t){var n=(new Date).getFullYear(),o=new Date(n,0,1),i=new Date(n,6,1),a=o.getTimezoneOffset(),s=i.getTimezoneOffset(),l=Math.max(a,s);function u(e){var r=e.toTimeString().match(/\(([A-Za-z ]+)\)$/);return r?r[1]:"GMT"}$[e>>2]=60*l,$[r>>2]=Number(a!=s);var c=u(o),d=u(i),f=Q(c),p=Q(d);s<a?($[t>>2]=f,$[t+4>>2]=p):($[t>>2]=p,$[t+4>>2]=f)}(r,t,n))},abort:function(){ge("native code called abort()")},emscripten_log:function(e,r,t){at(e,O(ot(r,t),0))},emscripten_resize_heap:function(e){var r=U.length;F((e>>>=0)>r);var t,n,o=2147483648;if(e>o)return _("Cannot enlarge memory, asked to go up to "+e+" bytes, but the limit is "+"2147483648 bytes!"),!1;for(var i=1;i<=4;i*=2){var a=r*(1+.2/i);a=Math.min(a,e+100663296);var s=Math.min(o,(t=Math.max(e,a))+((n=65536)-t%n)%n);if(st(s))return!0}return _("Failed to grow the heap from "+r+" bytes to "+s+" bytes, not enough memory!"),!1},environ_get:function(e,r){var t=0;return ut().forEach((function(n,o){var i=r+t;$[e+4*o>>2]=i,function(e,r,t){for(var n=0;n<e.length;++n)F(e.charCodeAt(n)===(255&e.charCodeAt(n))),x[r++>>0]=e.charCodeAt(n);t||(x[r>>0]=0)}(n,i),t+=n.length+1})),0},environ_sizes_get:function(e,r){var t=ut();$[e>>2]=t.length;var n=0;return t.forEach((function(e){n+=e.length+1})),$[r>>2]=n,0},fd_close:function(e){try{var r=Le.getStreamFromFD(e);return Ie.close(r),0}catch(e){if(void 0===Ie||!(e instanceof Ie.ErrnoError))throw e;return e.errno}},fd_fdstat_get:function(e,r){try{var t=Le.getStreamFromFD(e),n=t.tty?2:Ie.isDir(t.mode)?3:Ie.isLink(t.mode)?7:4;return x[r>>0]=n,0}catch(e){if(void 0===Ie||!(e instanceof Ie.ErrnoError))throw e;return e.errno}},fd_read:function(e,r,t,n){try{var o=Le.getStreamFromFD(e),i=Le.doReadv(o,r,t);return $[n>>2]=i,0}catch(e){if(void 0===Ie||!(e instanceof Ie.ErrnoError))throw e;return e.errno}},fd_seek:function(e,r,t,n,o){try{var i=Le.getStreamFromFD(e),a=4294967296*t+(r>>>0),s=9007199254740992;return a<=-s||a>=s?-61:(Ie.llseek(i,a,n),Ee=[i.position>>>0,(ye=i.position,+Math.abs(ye)>=1?ye>0?(0|Math.min(+Math.floor(ye/4294967296),4294967295))>>>0:~~+Math.ceil((ye-+(~~ye>>>0))/4294967296)>>>0:0)],$[o>>2]=Ee[0],$[o+4>>2]=Ee[1],i.getdents&&0===a&&0===n&&(i.getdents=null),0)}catch(e){if(void 0===Ie||!(e instanceof Ie.ErrnoError))throw e;return e.errno}},fd_write:function(e,r,t,n){try{var o=Le.getStreamFromFD(e),i=Le.doWritev(o,r,t);return $[n>>2]=i,0}catch(e){if(void 0===Ie||!(e instanceof Ie.ErrnoError))throw e;return e.errno}},setTempRet0:function(e){}};!function(){var e={env:mt,wasi_snapshot_preview1:mt};function t(e,t){var n,o=e.exports;r.asm=o,F(w=r.asm.memory,"memory not found in wasm exports"),Z(w.buffer),F(re=r.asm.__indirect_function_table,"table not found in wasm exports"),n=r.asm.__wasm_call_ctors,ae.unshift(n),he("wasm-instantiate")}me("wasm-instantiate");var n=r;function o(e){F(r===n,"the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?"),n=null,t(e.instance)}function i(r){return function(){if(!E&&(s||l)){if("function"==typeof fetch&&!be(ve))return fetch(ve,{credentials:"same-origin"}).then((function(e){if(!e.ok)throw"failed to load wasm binary file at '"+ve+"'";return e.arrayBuffer()})).catch((function(){return Te(ve)}));if(f)return new Promise((function(e,r){f(ve,(function(r){e(new Uint8Array(r))}),r)}))}return Promise.resolve().then((function(){return Te(ve)}))}().then((function(r){return WebAssembly.instantiate(r,e)})).then((function(e){return e})).then(r,(function(e){_("failed to asynchronously prepare wasm: "+e),be(ve)&&_("warning: Loading from a file URI ("+ve+") is not supported in most browsers. See https://emscripten.org/docs/getting_started/FAQ.html#how-do-i-run-a-local-webserver-for-testing-why-does-my-program-stall-in-downloading-or-preparing"),ge(e)}))}if(r.instantiateWasm)try{return r.instantiateWasm(e,t)}catch(e){return _("Module.instantiateWasm callback failed with error: "+e),!1}E||"function"!=typeof WebAssembly.instantiateStreaming||we(ve)||be(ve)||"function"!=typeof fetch?i(o):fetch(ve,{credentials:"same-origin"}).then((function(r){return WebAssembly.instantiateStreaming(r,e).then(o,(function(e){return _("wasm streaming compile failed: "+e),_("falling back to ArrayBuffer instantiation"),i(o)}))}))}(),r.___wasm_call_ctors=_e("__wasm_call_ctors");var ht=r._free=_e("free"),gt=r._malloc=_e("malloc"),vt=r._strlen=_e("strlen"),yt=r.___errno_location=_e("__errno_location"),Et=r.___getTypeName=_e("__getTypeName");r.___embind_register_native_and_builtin_types=_e("__embind_register_native_and_builtin_types");var wt=r.___stdio_exit=_e("__stdio_exit"),bt=r._emscripten_builtin_memalign=_e("emscripten_builtin_memalign"),_t=r._emscripten_stack_init=function(){return(_t=r._emscripten_stack_init=r.asm.emscripten_stack_init).apply(null,arguments)};r._emscripten_stack_get_free=function(){return(r._emscripten_stack_get_free=r.asm.emscripten_stack_get_free).apply(null,arguments)},r._emscripten_stack_get_base=function(){return(r._emscripten_stack_get_base=r.asm.emscripten_stack_get_base).apply(null,arguments)};var Tt,kt=r._emscripten_stack_get_end=function(){return(kt=r._emscripten_stack_get_end=r.asm.emscripten_stack_get_end).apply(null,arguments)};function St(e){this.name="ExitStatus",this.message="Program terminated with exit("+e+")",this.status=e}function Ct(e){function t(){Tt||(Tt=!0,r.calledRun=!0,A||(oe(),F(!le),le=!0,r.noFSInit||Ie.init.initialized||Ie.init(),Ie.ignorePermissions=!1,ke(ae),r.onRuntimeInitialized&&r.onRuntimeInitialized(),F(!r._main,'compiled without a main, but one is present. if you added it from JS, use Module["onRuntimeInitialized"]'),function(){if(oe(),r.postRun)for("function"==typeof r.postRun&&(r.postRun=[r.postRun]);r.postRun.length;)e=r.postRun.shift(),se.unshift(e);var e;ke(se)}()))}ue>0||(_t(),ne(),function(){if(r.preRun)for("function"==typeof r.preRun&&(r.preRun=[r.preRun]);r.preRun.length;)e=r.preRun.shift(),ie.unshift(e);var e;ke(ie)}(),ue>0||(r.setStatus?(r.setStatus("Running..."),setTimeout((function(){setTimeout((function(){r.setStatus("")}),1),t()}),1)):t(),oe()))}if(r.stackSave=_e("stackSave"),r.stackRestore=_e("stackRestore"),r.stackAlloc=_e("stackAlloc"),r.dynCall_ijiii=_e("dynCall_ijiii"),r.dynCall_viiijj=_e("dynCall_viiijj"),r.dynCall_jij=_e("dynCall_jij"),r.dynCall_jii=_e("dynCall_jii"),r.dynCall_jiji=_e("dynCall_jiji"),r._ff_h264_cabac_tables=112940,P("intArrayFromString",!1),P("intArrayToString",!1),P("ccall",!1),P("cwrap",!1),P("setValue",!1),P("getValue",!1),P("allocate",!1),P("UTF8ArrayToString",!1),P("UTF8ToString",!1),P("stringToUTF8Array",!1),P("stringToUTF8",!1),P("lengthBytesUTF8",!1),P("stackTrace",!1),P("addOnPreRun",!1),P("addOnInit",!1),P("addOnPreMain",!1),P("addOnExit",!1),P("addOnPostRun",!1),P("writeStringToMemory",!1),P("writeArrayToMemory",!1),P("writeAsciiToMemory",!1),P("addRunDependency",!0),P("removeRunDependency",!0),P("FS_createFolder",!1),P("FS_createPath",!0),P("FS_createDataFile",!0),P("FS_createPreloadedFile",!0),P("FS_createLazyFile",!0),P("FS_createLink",!1),P("FS_createDevice",!0),P("FS_unlink",!0),P("getLEB",!1),P("getFunctionTables",!1),P("alignFunctionTables",!1),P("registerFunctions",!1),P("addFunction",!1),P("removeFunction",!1),P("prettyPrint",!1),P("dynCall",!1),P("getCompilerSetting",!1),P("print",!1),P("printErr",!1),P("getTempRet0",!1),P("setTempRet0",!1),P("callMain",!1),P("abort",!1),P("keepRuntimeAlive",!1),P("ptrToString",!1),P("zeroMemory",!1),P("stringToNewUTF8",!1),P("emscripten_realloc_buffer",!1),P("ENV",!1),P("ERRNO_CODES",!1),P("ERRNO_MESSAGES",!1),P("setErrNo",!1),P("inetPton4",!1),P("inetNtop4",!1),P("inetPton6",!1),P("inetNtop6",!1),P("readSockaddr",!1),P("writeSockaddr",!1),P("DNS",!1),P("getHostByName",!1),P("Protocols",!1),P("Sockets",!1),P("getRandomDevice",!1),P("traverseStack",!1),P("UNWIND_CACHE",!1),P("convertPCtoSourceLocation",!1),P("readAsmConstArgsArray",!1),P("readAsmConstArgs",!1),P("mainThreadEM_ASM",!1),P("jstoi_q",!1),P("jstoi_s",!1),P("getExecutableName",!1),P("listenOnce",!1),P("autoResumeAudioContext",!1),P("dynCallLegacy",!1),P("getDynCaller",!1),P("dynCall",!1),P("setWasmTableEntry",!1),P("getWasmTableEntry",!1),P("handleException",!1),P("runtimeKeepalivePush",!1),P("runtimeKeepalivePop",!1),P("callUserCallback",!1),P("maybeExit",!1),P("safeSetTimeout",!1),P("asmjsMangle",!1),P("asyncLoad",!1),P("alignMemory",!1),P("mmapAlloc",!1),P("reallyNegative",!1),P("unSign",!1),P("reSign",!1),P("formatString",!1),P("PATH",!1),P("PATH_FS",!1),P("SYSCALLS",!1),P("getSocketFromFD",!1),P("getSocketAddress",!1),P("JSEvents",!1),P("registerKeyEventCallback",!1),P("specialHTMLTargets",!1),P("maybeCStringToJsString",!1),P("findEventTarget",!1),P("findCanvasEventTarget",!1),P("getBoundingClientRect",!1),P("fillMouseEventData",!1),P("registerMouseEventCallback",!1),P("registerWheelEventCallback",!1),P("registerUiEventCallback",!1),P("registerFocusEventCallback",!1),P("fillDeviceOrientationEventData",!1),P("registerDeviceOrientationEventCallback",!1),P("fillDeviceMotionEventData",!1),P("registerDeviceMotionEventCallback",!1),P("screenOrientation",!1),P("fillOrientationChangeEventData",!1),P("registerOrientationChangeEventCallback",!1),P("fillFullscreenChangeEventData",!1),P("registerFullscreenChangeEventCallback",!1),P("registerRestoreOldStyle",!1),P("hideEverythingExceptGivenElement",!1),P("restoreHiddenElements",!1),P("setLetterbox",!1),P("currentFullscreenStrategy",!1),P("restoreOldWindowedStyle",!1),P("softFullscreenResizeWebGLRenderTarget",!1),P("doRequestFullscreen",!1),P("fillPointerlockChangeEventData",!1),P("registerPointerlockChangeEventCallback",!1),P("registerPointerlockErrorEventCallback",!1),P("requestPointerLock",!1),P("fillVisibilityChangeEventData",!1),P("registerVisibilityChangeEventCallback",!1),P("registerTouchEventCallback",!1),P("fillGamepadEventData",!1),P("registerGamepadEventCallback",!1),P("registerBeforeUnloadEventCallback",!1),P("fillBatteryEventData",!1),P("battery",!1),P("registerBatteryEventCallback",!1),P("setCanvasElementSize",!1),P("getCanvasElementSize",!1),P("demangle",!1),P("demangleAll",!1),P("jsStackTrace",!1),P("stackTrace",!1),P("getEnvStrings",!1),P("checkWasiClock",!1),P("writeI53ToI64",!1),P("writeI53ToI64Clamped",!1),P("writeI53ToI64Signaling",!1),P("writeI53ToU64Clamped",!1),P("writeI53ToU64Signaling",!1),P("readI53FromI64",!1),P("readI53FromU64",!1),P("convertI32PairToI53",!1),P("convertU32PairToI53",!1),P("dlopenMissingError",!1),P("setImmediateWrapped",!1),P("clearImmediateWrapped",!1),P("polyfillSetImmediate",!1),P("uncaughtExceptionCount",!1),P("exceptionLast",!1),P("exceptionCaught",!1),P("ExceptionInfo",!1),P("exception_addRef",!1),P("exception_decRef",!1),P("Browser",!1),P("setMainLoop",!1),P("wget",!1),P("FS",!1),P("MEMFS",!1),P("TTY",!1),P("PIPEFS",!1),P("SOCKFS",!1),P("_setNetworkCallback",!1),P("tempFixedLengthArray",!1),P("miniTempWebGLFloatBuffers",!1),P("heapObjectForWebGLType",!1),P("heapAccessShiftForWebGLHeap",!1),P("GL",!1),P("emscriptenWebGLGet",!1),P("computeUnpackAlignedImageSize",!1),P("emscriptenWebGLGetTexPixelData",!1),P("emscriptenWebGLGetUniform",!1),P("webglGetUniformLocation",!1),P("webglPrepareUniformLocationsBeforeFirstUse",!1),P("webglGetLeftBracePos",!1),P("emscriptenWebGLGetVertexAttrib",!1),P("writeGLArray",!1),P("AL",!1),P("SDL_unicode",!1),P("SDL_ttfContext",!1),P("SDL_audio",!1),P("SDL",!1),P("SDL_gfx",!1),P("GLUT",!1),P("EGL",!1),P("GLFW_Window",!1),P("GLFW",!1),P("GLEW",!1),P("IDBStore",!1),P("runAndAbortIfError",!1),P("InternalError",!1),P("BindingError",!1),P("UnboundTypeError",!1),P("PureVirtualError",!1),P("init_embind",!1),P("throwInternalError",!1),P("throwBindingError",!1),P("throwUnboundTypeError",!1),P("ensureOverloadTable",!1),P("exposePublicSymbol",!1),P("replacePublicSymbol",!1),P("extendError",!1),P("createNamedFunction",!1),P("registeredInstances",!1),P("getBasestPointer",!1),P("registerInheritedInstance",!1),P("unregisterInheritedInstance",!1),P("getInheritedInstance",!1),P("getInheritedInstanceCount",!1),P("getLiveInheritedInstances",!1),P("registeredTypes",!1),P("awaitingDependencies",!1),P("typeDependencies",!1),P("registeredPointers",!1),P("registerType",!1),P("whenDependentTypesAreResolved",!1),P("embind_charCodes",!1),P("embind_init_charCodes",!1),P("readLatin1String",!1),P("getTypeName",!1),P("heap32VectorToArray",!1),P("requireRegisteredType",!1),P("getShiftFromSize",!1),P("integerReadValueFromPointer",!1),P("enumReadValueFromPointer",!1),P("floatReadValueFromPointer",!1),P("simpleReadValueFromPointer",!1),P("runDestructors",!1),P("new_",!1),P("craftInvokerFunction",!1),P("embind__requireFunction",!1),P("tupleRegistrations",!1),P("structRegistrations",!1),P("genericPointerToWireType",!1),P("constNoSmartPtrRawPointerToWireType",!1),P("nonConstNoSmartPtrRawPointerToWireType",!1),P("init_RegisteredPointer",!1),P("RegisteredPointer",!1),P("RegisteredPointer_getPointee",!1),P("RegisteredPointer_destructor",!1),P("RegisteredPointer_deleteObject",!1),P("RegisteredPointer_fromWireType",!1),P("runDestructor",!1),P("releaseClassHandle",!1),P("finalizationRegistry",!1),P("detachFinalizer_deps",!1),P("detachFinalizer",!1),P("attachFinalizer",!1),P("makeClassHandle",!1),P("init_ClassHandle",!1),P("ClassHandle",!1),P("ClassHandle_isAliasOf",!1),P("throwInstanceAlreadyDeleted",!1),P("ClassHandle_clone",!1),P("ClassHandle_delete",!1),P("deletionQueue",!1),P("ClassHandle_isDeleted",!1),P("ClassHandle_deleteLater",!1),P("flushPendingDeletes",!1),P("delayFunction",!1),P("setDelayFunction",!1),P("RegisteredClass",!1),P("shallowCopyInternalPointer",!1),P("downcastPointer",!1),P("upcastPointer",!1),P("validateThis",!1),P("char_0",!1),P("char_9",!1),P("makeLegalFunctionName",!1),P("emval_handle_array",!1),P("emval_free_list",!1),P("emval_symbols",!1),P("init_emval",!1),P("count_emval_handles",!1),P("get_first_emval",!1),P("getStringOrSymbol",!1),P("Emval",!1),P("emval_newers",!1),P("craftEmvalAllocator",!1),P("emval_get_global",!1),P("emval_methodCallers",!1),P("emval_registeredMethods",!1),P("warnOnce",!1),P("stackSave",!1),P("stackRestore",!1),P("stackAlloc",!1),P("AsciiToString",!1),P("stringToAscii",!1),P("UTF16ToString",!1),P("stringToUTF16",!1),P("lengthBytesUTF16",!1),P("UTF32ToString",!1),P("stringToUTF32",!1),P("lengthBytesUTF32",!1),P("allocateUTF8",!1),P("allocateUTF8OnStack",!1),r.writeStackCookie=ne,r.checkStackCookie=oe,C("ALLOC_NORMAL",!1),C("ALLOC_STACK",!1),de=function e(){Tt||Ct(),Tt||(de=e)},r.run=Ct,r.preInit)for("function"==typeof r.preInit&&(r.preInit=[r.preInit]);r.preInit.length>0;)r.preInit.pop()();Ct(),e.exports=r}));const u=1e3,c=1e3,d=!1,f=!1,p=!1,m=!1,h="initVideo",g="render",v="playAudio",y="initAudio",E="audioCode",w="videoCode",b=1,_=2,T="init",k="decode",S="audioDecode",C="videoDecode",P="close",A="updateConfig",F="key",D="delta";s((function(e){!function(){var r="undefined"!=typeof window&&void 0!==window.document?window.document:{},t=e.exports,n=function(){for(var e,t=[["requestFullscreen","exitFullscreen","fullscreenElement","fullscreenEnabled","fullscreenchange","fullscreenerror"],["webkitRequestFullscreen","webkitExitFullscreen","webkitFullscreenElement","webkitFullscreenEnabled","webkitfullscreenchange","webkitfullscreenerror"],["webkitRequestFullScreen","webkitCancelFullScreen","webkitCurrentFullScreenElement","webkitCancelFullScreen","webkitfullscreenchange","webkitfullscreenerror"],["mozRequestFullScreen","mozCancelFullScreen","mozFullScreenElement","mozFullScreenEnabled","mozfullscreenchange","mozfullscreenerror"],["msRequestFullscreen","msExitFullscreen","msFullscreenElement","msFullscreenEnabled","MSFullscreenChange","MSFullscreenError"]],n=0,o=t.length,i={};n<o;n++)if((e=t[n])&&e[1]in r){for(n=0;n<e.length;n++)i[t[0][n]]=e[n];return i}return!1}(),o={change:n.fullscreenchange,error:n.fullscreenerror},i={request:function(e,t){return new Promise(function(o,i){var a=function(){this.off("change",a),o()}.bind(this);this.on("change",a);var s=(e=e||r.documentElement)[n.requestFullscreen](t);s instanceof Promise&&s.then(a).catch(i)}.bind(this))},exit:function(){return new Promise(function(e,t){if(this.isFullscreen){var o=function(){this.off("change",o),e()}.bind(this);this.on("change",o);var i=r[n.exitFullscreen]();i instanceof Promise&&i.then(o).catch(t)}else e()}.bind(this))},toggle:function(e,r){return this.isFullscreen?this.exit():this.request(e,r)},onchange:function(e){this.on("change",e)},onerror:function(e){this.on("error",e)},on:function(e,t){var n=o[e];n&&r.addEventListener(n,t,!1)},off:function(e,t){var n=o[e];n&&r.removeEventListener(n,t,!1)},raw:n};n?(Object.defineProperties(i,{isFullscreen:{get:function(){return Boolean(r[n.fullscreenElement])}},element:{enumerable:!0,get:function(){return r[n.fullscreenElement]}},isEnabled:{enumerable:!0,get:function(){return Boolean(r[n.fullscreenEnabled])}}}),t?e.exports=i:window.screenfull=i):t?e.exports={isEnabled:!1}:window.screenfull={isEnabled:!1}}()})).isEnabled,(()=>{try{if("object"==typeof WebAssembly&&"function"==typeof WebAssembly.instantiate){const e=new WebAssembly.Module(Uint8Array.of(0,97,115,109,1,0,0,0));if(e instanceof WebAssembly.Module)return new WebAssembly.Instance(e)instanceof WebAssembly.Instance}}catch(e){}})(),Date.now||(Date.now=function(){return(new Date).getTime()}),l.postRun=function(){var e=[],r=[],t={};"VideoEncoder"in self&&(t={hasInit:!1,isEmitInfo:!1,offscreenCanvas:null,offscreenCanvasCtx:null,decoder:new VideoDecoder({output:function(e){t.isEmitInfo||(n.opt.debug&&console.log("Jessibuca: [worker] Webcodecs Video Decoder initSize"),postMessage({cmd:h,w:e.codedWidth,h:e.codedHeight}),t.isEmitInfo=!0,t.offscreenCanvas=new OffscreenCanvas(e.codedWidth,e.codedHeight),t.offscreenCanvasCtx=t.offscreenCanvas.getContext("2d")),t.offscreenCanvasCtx.drawImage(e,0,0,e.codedWidth,e.codedHeight);let r=t.offscreenCanvas.transferToImageBitmap();postMessage({cmd:g,buffer:r,delay:n.delay,ts:0},[r]),setTimeout((function(){e.close?e.close():e.destroy()}),100)},error:function(e){console.error(e)}}),decode:function(e,r){const o=e[0]>>4==1;if(t.hasInit){const n=new EncodedVideoChunk({data:e.slice(5),timestamp:r,type:o?F:D});t.decoder.decode(n)}else if(o&&0===e[1]){const r=15&e[0];n.setVideoCodec(r);const o=function(e){let r=e.subarray(1,4),t="avc1.";for(let e=0;e<3;e++){let n=r[e].toString(16);n.length<2&&(n="0"+n),t+=n}return{codec:t,description:e}}(e.slice(5));t.decoder.configure(o),t.hasInit=!0}},reset(){t.hasInit=!1,t.isEmitInfo=!1,t.offscreenCanvas=null,t.offscreenCanvasCtx=null}});var n={opt:{debug:d,useOffscreen:p,useWCS:f,videoBuffer:u,openWebglAlignment:m,videoBufferDelay:c},useOffscreen:function(){return n.opt.useOffscreen&&"undefined"!=typeof OffscreenCanvas},initAudioPlanar:function(e,t){postMessage({cmd:y,sampleRate:t,channels:e});var n=[],o=0;this.playAudioPlanar=function(t,i,a){for(var s=i,u=[],c=0,d=0;d<2;d++){var f=l.HEAPU32[(t>>2)+d]>>2;u[d]=l.HEAPF32.subarray(f,f+s)}if(o){if(!(s>=(i=1024-o)))return o+=s,r[0]=Float32Array.of(...r[0],...u[0]),void(2==e&&(r[1]=Float32Array.of(...r[1],...u[1])));n[0]=Float32Array.of(...r[0],...u[0].subarray(0,i)),2==e&&(n[1]=Float32Array.of(...r[1],...u[1].subarray(0,i))),postMessage({cmd:v,buffer:n,ts:a},n.map((e=>e.buffer))),c=i,s-=i}for(o=s;o>=1024;o-=1024)n[0]=u[0].slice(c,c+=1024),2==e&&(n[1]=u[1].slice(c-1024,c)),postMessage({cmd:v,buffer:n,ts:a},n.map((e=>e.buffer)));o&&(r[0]=u[0].slice(c),2==e&&(r[1]=u[1].slice(c)))}},setVideoCodec:function(e){postMessage({cmd:w,code:e})},setAudioCodec:function(e){postMessage({cmd:E,code:e})},setVideoSize:function(e,r){postMessage({cmd:h,w:e,h:r});var t=e*r,o=t>>2;n.useOffscreen()?(this.offscreenCanvas=new OffscreenCanvas(e,r),this.offscreenCanvasGL=this.offscreenCanvas.getContext("webgl"),this.webglObj=((e,r)=>{var t=["attribute vec4 vertexPos;","attribute vec4 texturePos;","varying vec2 textureCoord;","void main()","{","gl_Position = vertexPos;","textureCoord = texturePos.xy;","}"].join("\n"),n=["precision highp float;","varying highp vec2 textureCoord;","uniform sampler2D ySampler;","uniform sampler2D uSampler;","uniform sampler2D vSampler;","const mat4 YUV2RGB = mat4","(","1.1643828125, 0, 1.59602734375, -.87078515625,","1.1643828125, -.39176171875, -.81296875, .52959375,","1.1643828125, 2.017234375, 0, -1.081390625,","0, 0, 0, 1",");","void main(void) {","highp float y = texture2D(ySampler, textureCoord).r;","highp float u = texture2D(uSampler, textureCoord).r;","highp float v = texture2D(vSampler, textureCoord).r;","gl_FragColor = vec4(y, u, v, 1) * YUV2RGB;","}"].join("\n");r&&e.pixelStorei(e.UNPACK_ALIGNMENT,1);var o=e.createShader(e.VERTEX_SHADER);e.shaderSource(o,t),e.compileShader(o),e.getShaderParameter(o,e.COMPILE_STATUS)||console.log("Vertex shader failed to compile: "+e.getShaderInfoLog(o));var i=e.createShader(e.FRAGMENT_SHADER);e.shaderSource(i,n),e.compileShader(i),e.getShaderParameter(i,e.COMPILE_STATUS)||console.log("Fragment shader failed to compile: "+e.getShaderInfoLog(i));var a=e.createProgram();e.attachShader(a,o),e.attachShader(a,i),e.linkProgram(a),e.getProgramParameter(a,e.LINK_STATUS)||console.log("Program failed to compile: "+e.getProgramInfoLog(a)),e.useProgram(a);var s=e.createBuffer();e.bindBuffer(e.ARRAY_BUFFER,s),e.bufferData(e.ARRAY_BUFFER,new Float32Array([1,1,-1,1,1,-1,-1,-1]),e.STATIC_DRAW);var l=e.getAttribLocation(a,"vertexPos");e.enableVertexAttribArray(l),e.vertexAttribPointer(l,2,e.FLOAT,!1,0,0);var u=e.createBuffer();e.bindBuffer(e.ARRAY_BUFFER,u),e.bufferData(e.ARRAY_BUFFER,new Float32Array([1,0,0,0,1,1,0,1]),e.STATIC_DRAW);var c=e.getAttribLocation(a,"texturePos");function d(r,t){var n=e.createTexture();return e.bindTexture(e.TEXTURE_2D,n),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.bindTexture(e.TEXTURE_2D,null),e.uniform1i(e.getUniformLocation(a,r),t),n}e.enableVertexAttribArray(c),e.vertexAttribPointer(c,2,e.FLOAT,!1,0,0);var f=d("ySampler",0),p=d("uSampler",1),m=d("vSampler",2);return{render:function(r,t,n,o,i){e.viewport(0,0,r,t),e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,f),e.texImage2D(e.TEXTURE_2D,0,e.LUMINANCE,r,t,0,e.LUMINANCE,e.UNSIGNED_BYTE,n),e.activeTexture(e.TEXTURE1),e.bindTexture(e.TEXTURE_2D,p),e.texImage2D(e.TEXTURE_2D,0,e.LUMINANCE,r/2,t/2,0,e.LUMINANCE,e.UNSIGNED_BYTE,o),e.activeTexture(e.TEXTURE2),e.bindTexture(e.TEXTURE_2D,m),e.texImage2D(e.TEXTURE_2D,0,e.LUMINANCE,r/2,t/2,0,e.LUMINANCE,e.UNSIGNED_BYTE,i),e.drawArrays(e.TRIANGLE_STRIP,0,4)},destroy:function(){try{e.deleteProgram(a),e.deleteBuffer(s),e.deleteBuffer(u),e.deleteTexture(f),e.deleteTexture(p),e.deleteTexture(m)}catch(e){}}}})(this.offscreenCanvasGL,n.opt.openWebglAlignment),this.draw=function(n,i,a,s){const u=l.HEAPU8.subarray(i,i+t),c=l.HEAPU8.subarray(a,a+o),d=l.HEAPU8.subarray(s,s+o);this.webglObj.render(e,r,u,c,d);let f=this.offscreenCanvas.transferToImageBitmap();postMessage({cmd:g,buffer:f,delay:this.delay,ts:n},[f])}):this.draw=function(e,r,n,i){const a=[Uint8Array.from(l.HEAPU8.subarray(r,r+t)),Uint8Array.from(l.HEAPU8.subarray(n,n+o)),Uint8Array.from(l.HEAPU8.subarray(i,i+o))];postMessage({cmd:g,output:a,delay:this.delay,ts:e},a.map((e=>e.buffer)))}},getDelay:function(e){if(!e)return-1;if(this.firstTimestamp){if(e){const r=Date.now()-this.startTimestamp,t=e-this.firstTimestamp;this.delay=r>=t?r-t:t-r}}else this.firstTimestamp=e,this.startTimestamp=Date.now(),this.delay=-1;return this.delay},resetDelay:function(){this.firstTimestamp=null,this.startTimestamp=null,this.delay=-1},init:function(){n.opt.debug&&console.log("Jessibuca: [worker] init");const r=e=>{n.opt.useWCS&&n.useOffscreen()&&e.type===_&&t.decode?t.decode(e.payload,e.ts):e.decoder.decode(e.payload,e.ts)};this.stopId=setInterval((()=>{if(e.length)if(this.dropping){for((t=e.shift()).type===b&&0===t.payload[1]&&r(t);!t.isIFrame&&e.length;)(t=e.shift()).type===b&&0===t.payload[1]&&r(t);t.isIFrame&&(this.dropping=!1,r(t))}else{var t=e[0];if(-1===this.getDelay(t.ts))e.shift(),r(t);else if(this.delay>n.opt.videoBuffer+n.opt.videoBufferDelay)this.resetDelay(),this.dropping=!0;else for(;e.length&&(t=e[0],this.getDelay(t.ts)>n.opt.videoBuffer);)e.shift(),r(t)}}),10)},close:function(){n.opt.debug&&console.log("Jessibuca: [worker]: close"),clearInterval(this.stopId),this.stopId=null,o.clear&&o.clear(),i.clear&&i.clear(),t.reset&&t.reset(),this.firstTimestamp=null,this.startTimestamp=null,this.delay=-1,this.dropping=!1,this.webglObj&&(this.webglObj.destroy(),this.offscreenCanvas=null,this.offscreenCanvasGL=null,this.offscreenCanvasCtx=null),e=[],r=[],delete this.playAudioPlanar,delete this.draw},pushBuffer:function(r,t){t.type===b?e.push({ts:t.ts,payload:r,decoder:o,type:b}):t.type===_&&e.push({ts:t.ts,payload:r,decoder:i,type:_,isIFrame:t.isIFrame})}},o=new l.AudioDecoder(n),i=new l.VideoDecoder(n);postMessage({cmd:T}),self.onmessage=function(e){var r=e.data;switch(r.cmd){case T:try{n.opt=Object.assign(n.opt,JSON.parse(r.opt))}catch(e){}o.sample_rate=r.sampleRate,n.init();break;case k:n.pushBuffer(r.buffer,r.options);break;case S:o.decode(r.buffer,r.ts);break;case C:i.decode(r.buffer,r.ts);break;case P:n.close();break;case A:n.opt[r.key]=r.value}}}})); |
web_src/static/js/jessibuca/decoder.wasm
No preview for this file type
web_src/static/js/jessibuca/jessibuca.d.ts
| @@ -62,7 +62,7 @@ declare namespace Jessibuca { | @@ -62,7 +62,7 @@ declare namespace Jessibuca { | ||
| 62 | /** | 62 | /** |
| 63 | * 1. 当为`true`的时候:视频画面做等比缩放后,完全填充canvas区域,画面不被拉伸,没有黑边,但画面显示不全。等同于 `setScaleMode(2)` | 63 | * 1. 当为`true`的时候:视频画面做等比缩放后,完全填充canvas区域,画面不被拉伸,没有黑边,但画面显示不全。等同于 `setScaleMode(2)` |
| 64 | */ | 64 | */ |
| 65 | - isFullSize?: boolean; | 65 | + isFullResize?: boolean; |
| 66 | /** | 66 | /** |
| 67 | * 1. 当为`true`的时候:ws协议不检验是否以.flv为依据,进行协议解析。 | 67 | * 1. 当为`true`的时候:ws协议不检验是否以.flv为依据,进行协议解析。 |
| 68 | */ | 68 | */ |
| @@ -120,7 +120,7 @@ declare namespace Jessibuca { | @@ -120,7 +120,7 @@ declare namespace Jessibuca { | ||
| 120 | /** | 120 | /** |
| 121 | * 加载过程中文案 | 121 | * 加载过程中文案 |
| 122 | */ | 122 | */ |
| 123 | - loadingText?: boolean; | 123 | + loadingText?: string; |
| 124 | /** | 124 | /** |
| 125 | * 背景图片 | 125 | * 背景图片 |
| 126 | */ | 126 | */ |
web_src/static/js/jessibuca/jessibuca.js
| 1 | -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).jessibuca=t()}(this,(function(){"use strict";var e="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function t(e,t){return e(t={exports:{}},t.exports),t.exports}var i,o=t((function(e){e.exports=function(e,t,i){return t in e?Object.defineProperty(e,t,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[t]=i,e},e.exports.__esModule=!0,e.exports.default=e.exports})),r=(i=o)&&i.__esModule&&Object.prototype.hasOwnProperty.call(i,"default")?i.default:i;const A=0,s=1,n="flv",a="m7s",d={videoBuffer:1e3,isResize:!0,isFullResize:!1,isFlv:!1,debug:!1,hotKey:!1,loadingTimeout:10,heartTimeout:5,timeout:10,loadingTimeoutReplay:!1,heartTimeoutReplay:!1,loadingTimeoutReplayTimes:3,heartTimeoutReplayTimes:3,supportDblclickFullscreen:!1,showBandwidth:!1,keepScreenOn:!1,isNotMute:!1,hasAudio:!0,hasVideo:!0,operateBtns:{fullscreen:!1,screenshot:!1,play:!1,audio:!1,record:!1},controlAutoHide:!1,hasControl:!1,loadingText:"",background:"",decoder:"decoder.js",url:"",rotate:0,forceNoOffscreen:!0,hiddenAutoPause:!1,protocol:s,demuxType:n,useWCS:!1,useMSE:!1,useOffscreen:!1,autoWasm:!0,wasmDecodeErrorReplay:!0,openWebglAlignment:!1},c="init",l="initVideo",u="render",h="playAudio",p="initAudio",m="audioCode",g="videoCode",f="wasmError",b="Invalid NAL unit size",y=1,v=2,w=8,S=9,E="init",B="decode",C="audioDecode",R="close",k="updateConfig",T={fullscreen:"fullscreen$2",webFullscreen:"webFullscreen",decoderWorkerInit:"decoderWorkerInit",play:"play",playing:"playing",pause:"pause",mute:"mute",load:"load",loading:"loading",videoInfo:"videoInfo",timeUpdate:"timeUpdate",audioInfo:"audioInfo",log:"log",error:"error",kBps:"kBps",timeout:"timeout",delayTimeout:"delayTimeout",loadingTimeout:"loadingTimeout",stats:"stats",performance:"performance",record:"record",recording:"recording",recordingTimestamp:"recordingTimestamp",recordStart:"recordStart",recordEnd:"recordEnd",recordCreateError:"recordCreateError",buffer:"buffer",videoFrame:"videoFrame",start:"start",metadata:"metadata",resize:"resize",streamEnd:"streamEnd",streamSuccess:"streamSuccess",streamMessage:"streamMessage",streamError:"streamError",volumechange:"volumechange",destroy:"destroy",mseSourceOpen:"mseSourceOpen",mseSourceClose:"mseSourceClose",mseSourceBufferError:"mseSourceBufferError",mseSourceBufferBusy:"mseSourceBufferBusy",videoWaiting:"videoWaiting",videoTimeUpdate:"videoTimeUpdate",videoSyncAudio:"videoSyncAudio",playToRenderTimes:"playToRenderTimes"},I={load:T.load,timeUpdate:T.timeUpdate,videoInfo:T.videoInfo,audioInfo:T.audioInfo,error:T.error,kBps:T.kBps,log:T.log,start:T.start,timeout:T.timeout,loadingTimeout:T.loadingTimeout,delayTimeout:T.delayTimeout,fullscreen:"fullscreen",play:T.play,pause:T.pause,mute:T.mute,stats:T.stats,performance:T.performance,recordingTimestamp:T.recordingTimestamp,recordStart:T.recordStart,recordEnd:T.recordEnd,playToRenderTimes:T.playToRenderTimes},x={playError:"playIsNotPauseOrUrlIsNull",fetchError:"fetchError",websocketError:"websocketError",webcodecsH265NotSupport:"webcodecsH265NotSupport",mediaSourceH265NotSupport:"mediaSourceH265NotSupport",wasmDecodeError:"wasmDecodeError"},D="notConnect",j="open",L="close",U="error",F={download:"download",base64:"base64",blob:"blob"},V={7:"H264(AVC)",12:"H265(HEVC)"},O=7,M=12,Q={10:"AAC",7:"ALAW",8:"MULAW"},W=32,G=33,J=34,N=0,P=1,z=2,Y="mp4",H="webm",X="webcodecs",Z="webgl",q="offscreen",K="key",_="delta",$='video/mp4; codecs="avc1.64002A"',ee="ended",te="open",ie="closed",oe=1e3,re=27,Ae=38,se=40;class ne{constructor(e){this.log=function(t){if(e._opt.debug){for(var i=arguments.length,o=new Array(i>1?i-1:0),r=1;r<i;r++)o[r-1]=arguments[r];console.log(`Jessibuca: [${t}]`,...o)}},this.warn=function(t){if(e._opt.debug){for(var i=arguments.length,o=new Array(i>1?i-1:0),r=1;r<i;r++)o[r-1]=arguments[r];console.warn(`Jessibuca: [${t}]`,...o)}},this.error=function(t){if(e._opt.debug){for(var i=arguments.length,o=new Array(i>1?i-1:0),r=1;r<i;r++)o[r-1]=arguments[r];console.error(`Jessibuca: [${t}]`,...o)}}}}class ae{constructor(e){this.destroys=[],this.proxy=this.proxy.bind(this),this.master=e}proxy(e,t,i){let o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};if(!e)return;if(Array.isArray(t))return t.map((t=>this.proxy(e,t,i,o)));e.addEventListener(t,i,o);const r=()=>e.removeEventListener(t,i,o);return this.destroys.push(r),r}destroy(){this.master.debug&&this.master.debug.log("Events","destroy"),this.destroys.forEach((e=>e()))}}var de=t((function(e){!function(){var t="undefined"!=typeof window&&void 0!==window.document?window.document:{},i=e.exports,o=function(){for(var e,i=[["requestFullscreen","exitFullscreen","fullscreenElement","fullscreenEnabled","fullscreenchange","fullscreenerror"],["webkitRequestFullscreen","webkitExitFullscreen","webkitFullscreenElement","webkitFullscreenEnabled","webkitfullscreenchange","webkitfullscreenerror"],["webkitRequestFullScreen","webkitCancelFullScreen","webkitCurrentFullScreenElement","webkitCancelFullScreen","webkitfullscreenchange","webkitfullscreenerror"],["mozRequestFullScreen","mozCancelFullScreen","mozFullScreenElement","mozFullScreenEnabled","mozfullscreenchange","mozfullscreenerror"],["msRequestFullscreen","msExitFullscreen","msFullscreenElement","msFullscreenEnabled","MSFullscreenChange","MSFullscreenError"]],o=0,r=i.length,A={};o<r;o++)if((e=i[o])&&e[1]in t){for(o=0;o<e.length;o++)A[i[0][o]]=e[o];return A}return!1}(),r={change:o.fullscreenchange,error:o.fullscreenerror},A={request:function(e,i){return new Promise(function(r,A){var s=function(){this.off("change",s),r()}.bind(this);this.on("change",s);var n=(e=e||t.documentElement)[o.requestFullscreen](i);n instanceof Promise&&n.then(s).catch(A)}.bind(this))},exit:function(){return new Promise(function(e,i){if(this.isFullscreen){var r=function(){this.off("change",r),e()}.bind(this);this.on("change",r);var A=t[o.exitFullscreen]();A instanceof Promise&&A.then(r).catch(i)}else e()}.bind(this))},toggle:function(e,t){return this.isFullscreen?this.exit():this.request(e,t)},onchange:function(e){this.on("change",e)},onerror:function(e){this.on("error",e)},on:function(e,i){var o=r[e];o&&t.addEventListener(o,i,!1)},off:function(e,i){var o=r[e];o&&t.removeEventListener(o,i,!1)},raw:o};o?(Object.defineProperties(A,{isFullscreen:{get:function(){return Boolean(t[o.fullscreenElement])}},element:{enumerable:!0,get:function(){return t[o.fullscreenElement]}},isEnabled:{enumerable:!0,get:function(){return Boolean(t[o.fullscreenEnabled])}}}),i?e.exports=A:window.screenfull=A):i?e.exports={isEnabled:!1}:window.screenfull={isEnabled:!1}}()}));function ce(){}function le(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";const t=e.split(","),i=atob(t[1]),o=t[0].replace("data:","").replace(";base64","");let r=i.length,A=new Uint8Array(r);for(;r--;)A[r]=i.charCodeAt(r);return new File([A],"file",{type:o})}function ue(e,t){const i=document.createElement("a");i.download=t,i.href=URL.createObjectURL(e),i.click(),setTimeout((()=>{URL.revokeObjectURL(e)}),ve()?1e3:0)}function he(){return(new Date).getTime()}function pe(e,t,i){return Math.max(Math.min(e,Math.max(t,i)),Math.min(t,i))}function me(e,t,i){if(e)return"object"==typeof t&&Object.keys(t).forEach((i=>{me(e,i,t[i])})),e.style[t]=i,e}function ge(e,t){let i=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];if(!e)return 0;const o=getComputedStyle(e,null).getPropertyValue(t);return i?parseFloat(o):o}function fe(){return performance&&"function"==typeof performance.now?performance.now():Date.now()}function be(e){let t=0,i=fe();return o=>{t+=o;const r=fe(),A=r-i;A>=1e3&&(e(t/A*1e3),i=r,t=0)}}function ye(){return/iphone|ipod|android.*mobile|windows.*phone|blackberry.*mobile/i.test(window.navigator.userAgent.toLowerCase())}function ve(){const e=window.navigator.userAgent.toLowerCase();return e&&/iphone|ipad|ipod|ios/.test(e)}function we(e){if(null==e||""===e)return"0 KB/S";let t=parseFloat(e);return t=t.toFixed(2),t+"KB/S"}function Se(e){return null==e}function Ee(e){return!Se(e)}de.isEnabled,(()=>{try{if("object"==typeof WebAssembly&&"function"==typeof WebAssembly.instantiate){const e=new WebAssembly.Module(Uint8Array.of(0,97,115,109,1,0,0,0));if(e instanceof WebAssembly.Module)return new WebAssembly.Instance(e)instanceof WebAssembly.Instance}}catch(e){}})();class Be{on(e,t,i){const o=this.e||(this.e={});return(o[e]||(o[e]=[])).push({fn:t,ctx:i}),this}once(e,t,i){const o=this;function r(){o.off(e,r);for(var A=arguments.length,s=new Array(A),n=0;n<A;n++)s[n]=arguments[n];t.apply(i,s)}return r._=t,this.on(e,r,i)}emit(e){const t=((this.e||(this.e={}))[e]||[]).slice();for(var i=arguments.length,o=new Array(i>1?i-1:0),r=1;r<i;r++)o[r-1]=arguments[r];for(let e=0;e<t.length;e+=1)t[e].fn.apply(t[e].ctx,o);return this}off(e,t){const i=this.e||(this.e={});if(!e)return Object.keys(i).forEach((e=>{delete i[e]})),void delete this.e;const o=i[e],r=[];if(o&&t)for(let e=0,i=o.length;e<i;e+=1)o[e].fn!==t&&o[e].fn._!==t&&r.push(o[e]);return r.length?i[e]=r:delete i[e],this}}class Ce extends Be{constructor(){super(),this.init=!1}updateVideoInfo(e){e.encTypeCode&&(this.videoInfo.encType=V[e.encTypeCode]),e.width&&(this.videoInfo.width=e.width),e.height&&(this.videoInfo.height=e.height),this.videoInfo.encType&&this.videoInfo.height&&this.videoInfo.width&&!this.init&&(this.player.emit(T.videoInfo,this.videoInfo),this.init=!0)}}class Re extends Ce{constructor(e){super(),this.player=e;const t=document.createElement("canvas");t.style.position="absolute",t.style.top=0,t.style.left=0,this.$videoElement=t,e.$container.appendChild(this.$videoElement),this.context2D=null,this.contextGl=null,this.contextGlRender=null,this.contextGlDestroy=null,this.bitmaprenderer=null,this.renderType=null,this.videoInfo={width:"",height:"",encType:""},this._initCanvasRender(),this.player.debug.log("CanvasVideo","init")}destroy(){this.contextGl&&(this.contextGl=null),this.context2D&&(this.context2D=null),this.contextGlRender&&(this.contextGlDestroy&&this.contextGlDestroy(),this.contextGlDestroy=null,this.contextGlRender=null),this.bitmaprenderer&&(this.bitmaprenderer=null),this.renderType=null,this.videoInfo={width:"",height:"",encType:"",encTypeCode:""},this.player.$container.removeChild(this.$videoElement),this.init=!1,this.off(),this.player.debug.log("CanvasVideoLoader","destroy")}_initContextGl(){this.contextGl=function(e){let t=null;const i=["webgl","experimental-webgl","moz-webgl","webkit-3d"];let o=0;for(;!t&&o<i.length;){const r=i[o];try{let i={preserveDrawingBuffer:!0};t=e.getContext(r,i)}catch(e){t=null}t&&"function"==typeof t.getParameter||(t=null),++o}return t}(this.$videoElement);const e=((e,t)=>{var i=["attribute vec4 vertexPos;","attribute vec4 texturePos;","varying vec2 textureCoord;","void main()","{","gl_Position = vertexPos;","textureCoord = texturePos.xy;","}"].join("\n"),o=["precision highp float;","varying highp vec2 textureCoord;","uniform sampler2D ySampler;","uniform sampler2D uSampler;","uniform sampler2D vSampler;","const mat4 YUV2RGB = mat4","(","1.1643828125, 0, 1.59602734375, -.87078515625,","1.1643828125, -.39176171875, -.81296875, .52959375,","1.1643828125, 2.017234375, 0, -1.081390625,","0, 0, 0, 1",");","void main(void) {","highp float y = texture2D(ySampler, textureCoord).r;","highp float u = texture2D(uSampler, textureCoord).r;","highp float v = texture2D(vSampler, textureCoord).r;","gl_FragColor = vec4(y, u, v, 1) * YUV2RGB;","}"].join("\n");t&&e.pixelStorei(e.UNPACK_ALIGNMENT,1);var r=e.createShader(e.VERTEX_SHADER);e.shaderSource(r,i),e.compileShader(r),e.getShaderParameter(r,e.COMPILE_STATUS)||console.log("Vertex shader failed to compile: "+e.getShaderInfoLog(r));var A=e.createShader(e.FRAGMENT_SHADER);e.shaderSource(A,o),e.compileShader(A),e.getShaderParameter(A,e.COMPILE_STATUS)||console.log("Fragment shader failed to compile: "+e.getShaderInfoLog(A));var s=e.createProgram();e.attachShader(s,r),e.attachShader(s,A),e.linkProgram(s),e.getProgramParameter(s,e.LINK_STATUS)||console.log("Program failed to compile: "+e.getProgramInfoLog(s)),e.useProgram(s);var n=e.createBuffer();e.bindBuffer(e.ARRAY_BUFFER,n),e.bufferData(e.ARRAY_BUFFER,new Float32Array([1,1,-1,1,1,-1,-1,-1]),e.STATIC_DRAW);var a=e.getAttribLocation(s,"vertexPos");e.enableVertexAttribArray(a),e.vertexAttribPointer(a,2,e.FLOAT,!1,0,0);var d=e.createBuffer();e.bindBuffer(e.ARRAY_BUFFER,d),e.bufferData(e.ARRAY_BUFFER,new Float32Array([1,0,0,0,1,1,0,1]),e.STATIC_DRAW);var c=e.getAttribLocation(s,"texturePos");function l(t,i){var o=e.createTexture();return e.bindTexture(e.TEXTURE_2D,o),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.bindTexture(e.TEXTURE_2D,null),e.uniform1i(e.getUniformLocation(s,t),i),o}e.enableVertexAttribArray(c),e.vertexAttribPointer(c,2,e.FLOAT,!1,0,0);var u=l("ySampler",0),h=l("uSampler",1),p=l("vSampler",2);return{render:function(t,i,o,r,A){e.viewport(0,0,t,i),e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,u),e.texImage2D(e.TEXTURE_2D,0,e.LUMINANCE,t,i,0,e.LUMINANCE,e.UNSIGNED_BYTE,o),e.activeTexture(e.TEXTURE1),e.bindTexture(e.TEXTURE_2D,h),e.texImage2D(e.TEXTURE_2D,0,e.LUMINANCE,t/2,i/2,0,e.LUMINANCE,e.UNSIGNED_BYTE,r),e.activeTexture(e.TEXTURE2),e.bindTexture(e.TEXTURE_2D,p),e.texImage2D(e.TEXTURE_2D,0,e.LUMINANCE,t/2,i/2,0,e.LUMINANCE,e.UNSIGNED_BYTE,A),e.drawArrays(e.TRIANGLE_STRIP,0,4)},destroy:function(){try{e.deleteProgram(s),e.deleteBuffer(n),e.deleteBuffer(d),e.deleteTexture(u),e.deleteTexture(h),e.deleteBuffer(p)}catch(e){}}}})(this.contextGl,this.player._opt.openWebglAlignment);this.contextGlRender=e.render,this.contextGlDestroy=e.destroy}_initContext2D(){this.context2D=this.$videoElement.getContext("2d")}_initCanvasRender(){this.player._opt.useWCS&&!this._supportOffscreen()?(this.renderType=X,this._initContext2D()):this._supportOffscreen()?(this.renderType=q,this._bindOffscreen()):(this.renderType=Z,this._initContextGl())}_supportOffscreen(){return"function"==typeof this.$videoElement.transferControlToOffscreen&&this.player._opt.useOffscreen}_bindOffscreen(){this.bitmaprenderer=this.$videoElement.getContext("bitmaprenderer")}initCanvasViewSize(){this.$videoElement.width=this.videoInfo.width,this.$videoElement.height=this.videoInfo.height,this.resize()}render(e){switch(this.player.videoTimestamp=e.ts,this.renderType){case q:this.bitmaprenderer.transferFromImageBitmap(e.buffer);break;case Z:this.contextGlRender(this.$videoElement.width,this.$videoElement.height,e.output[0],e.output[1],e.output[2]);break;case X:this.context2D.drawImage(e.videoFrame,0,0,this.$videoElement.width,this.$videoElement.height)}}screenshot(e,t,i,o){e=e||he(),o=o||F.download;const r={png:"image/png",jpeg:"image/jpeg",webp:"image/webp"};let A=.92;!r[t]&&F[t]&&(o=t,t="png",i=void 0),"string"==typeof i&&(o=i,i=void 0),void 0!==i&&(A=Number(i));const s=this.$videoElement.toDataURL(r[t]||r.png,A),n=le(s);return o===F.base64?s:o===F.blob?n:void(o===F.download&&ue(n,e))}clearView(){switch(this.renderType){case q:(function(e,t){const i=document.createElement("canvas");return i.width=e,i.height=t,createImageBitmap(i,0,0,e,t)})(this.$videoElement.width,this.$videoElement.height).then((e=>{this.bitmaprenderer.transferFromImageBitmap(e)}));break;case Z:this.contextGl.clear(this.contextGl.COLOR_BUFFER_BIT);break;case X:this.context2D.clearRect(0,0,this.$videoElement.width,this.$videoElement.height)}}resize(){this.player.debug.log("canvasVideo","resize");const e=this.player._opt;let t=this.player.width,i=this.player.height;e.hasControl&&!e.controlAutoHide&&(ye()&&this.player.fullscreen?t-=38:i-=38);let o=this.$videoElement.width,r=this.$videoElement.height;const A=e.rotate;let s=(t-o)/2,n=(i-r)/2;270!==A&&90!==A||(o=this.$videoElement.height,r=this.$videoElement.width);const a=t/o,d=i/r;let c=a>d?d:a;e.isResize||a!==d&&(c=a+","+d),e.isFullResize&&(c=a>d?a:d);let l="scale("+c+")";A&&(l+=" rotate("+A+"deg)"),this.$videoElement.style.transform=l,this.$videoElement.style.left=s+"px",this.$videoElement.style.top=n+"px"}}class ke extends Ce{constructor(e){super(),this.player=e;const t=document.createElement("video");t.muted=!0,t.style.position="absolute",t.style.top=0,t.style.left=0,e.$container.appendChild(t),this.$videoElement=t,this.videoInfo={width:"",height:"",encType:""},this.resize();const{proxy:i}=this.player.events;i(this.$videoElement,"canplay",(()=>{this.player.debug.log("Video","canplay")})),i(this.$videoElement,"waiting",(()=>{this.player.emit(T.videoWaiting)})),i(this.$videoElement,"timeupdate",(e=>{})),this.player.debug.log("Video","init")}destroy(){this.player.$container.removeChild(this.$videoElement),this.$videoElement=null,this.init=!1,this.off(),this.player.debug.log("Video","destroy")}play(){this.$videoElement.play()}clearView(){}screenshot(e,t,i,o){e=e||he(),o=o||F.download;let r=.92;!{png:"image/png",jpeg:"image/jpeg",webp:"image/webp"}[t]&&F[t]&&(o=t,t="png",i=void 0),"string"==typeof i&&(o=i,i=void 0),void 0!==i&&(r=Number(i));const A=this.$videoElement;let s=document.createElement("canvas");s.width=A.videoWidth,s.height=A.videoHeight;s.getContext("2d").drawImage(A,0,0,s.width,s.height);const n=s.toDataURL(F[t]||F.png,r),a=le(n);return o===F.base64?n:o===F.blob?a:void(o===F.download&&ue(a,e))}initCanvasViewSize(){this.resize()}resize(){let e=this.player.width,t=this.player.height;const i=this.player._opt,o=i.rotate;i.hasControl&&!i.controlAutoHide&&(ye()&&this.player.fullscreen?e-=38:t-=38),this.$videoElement.width=e,this.$videoElement.height=t,270!==o&&90!==o||(this.$videoElement.width=t,this.$videoElement.height=e);let r=(e-this.$videoElement.width)/2,A=(t-this.$videoElement.height)/2,s="contain";i.isResize||(s="fill"),i.isFullResize&&(s="none"),this.$videoElement.style.objectFit=s,this.$videoElement.style.transform="rotate("+o+"deg)",this.$videoElement.style.left=r+"px",this.$videoElement.style.top=A+"px"}}class Te{constructor(e){return new(Te.getLoaderFactory(e._opt))(e)}static getLoaderFactory(e){return e.useMSE?ke:Re}}class Ie extends Be{constructor(e){super(),this.bufferList=[],this.player=e,this.scriptNode=null,this.hasInitScriptNode=!1,this.audioContextChannel=null,this.audioContext=new(window.AudioContext||window.webkitAudioContext),this.gainNode=this.audioContext.createGain();const t=this.audioContext.createBufferSource();t.buffer=this.audioContext.createBuffer(1,1,22050),t.connect(this.audioContext.destination),t.noteOn?t.noteOn(0):t.start(0),this.audioBufferSourceNode=t,this.mediaStreamAudioDestinationNode=this.audioContext.createMediaStreamDestination(),this.audioEnabled(!0),this.gainNode.gain.value=0,this.playing=!1,this.audioSyncVideoOption={diff:null},this.audioInfo={encType:"",channels:"",sampleRate:""},this.init=!1,this.hasAudio=!1,this.on(T.videoSyncAudio,(e=>{this.audioSyncVideoOption=e})),this.player.debug.log("AudioContext","init")}destroy(){this.closeAudio(),this.audioContext.close(),this.audioContext=null,this.gainNode=null,this.init=!1,this.hasAudio=!1,this.playing=!1,this.scriptNode&&(this.scriptNode.onaudioprocess=ce,this.scriptNode=null),this.audioBufferSourceNode=null,this.mediaStreamAudioDestinationNode=null,this.hasInitScriptNode=!1,this.audioSyncVideoOption={diff:null},this.audioInfo={encType:"",channels:"",sampleRate:""},this.off(),this.player.debug.log("AudioContext","destroy")}updateAudioInfo(e){e.encTypeCode&&(this.audioInfo.encType=Q[e.encTypeCode]),e.channels&&(this.audioInfo.channels=e.channels),e.sampleRate&&(this.audioInfo.sampleRate=e.sampleRate),this.audioInfo.sampleRate&&this.audioInfo.channels&&this.audioInfo.encType&&!this.init&&(this.player.emit(T.audioInfo,this.audioInfo),this.init=!0)}get isPlaying(){return this.playing}get isMute(){return 0===this.gainNode.gain.value||this.isStateSuspended()}get volume(){return this.gainNode.gain.value}get bufferSize(){return this.bufferList.length}initScriptNode(){if(this.playing=!0,this.hasInitScriptNode)return;const e=this.audioInfo.channels,t=this.audioContext.createScriptProcessor(1024,0,e);t.onaudioprocess=t=>{const i=t.outputBuffer;if(this.bufferList.length&&this.playing){if(!this.player._opt.useWCS&&!this.player._opt.useMSE){if(this.audioSyncVideoOption.diff>oe)return void this.player.debug.warn("AudioContext",`audioSyncVideoOption more than diff :${this.audioSyncVideoOption.diff}, waiting`);if(this.audioSyncVideoOption.diff<-1e3){this.player.debug.warn("AudioContext",`audioSyncVideoOption less than diff :${this.audioSyncVideoOption.diff}, dropping`);let e=this.bufferList.shift();for(;e.ts-this.player.videoTimestamp<-1e3&&this.bufferList.length>0;)e=this.bufferList.shift();if(0===this.bufferList.length)return}}if(0===this.bufferList.length)return;const t=this.bufferList.shift();t&&t.ts&&(this.player.audioTimestamp=t.ts);for(let o=0;o<e;o++){const e=t.buffer[o],r=i.getChannelData(o);for(let t=0;t<1024;t++)r[t]=e[t]||0}}},t.connect(this.gainNode),this.scriptNode=t,this.gainNode.connect(this.audioContext.destination),this.gainNode.connect(this.mediaStreamAudioDestinationNode),this.hasInitScriptNode=!0}mute(e){e?(this.isMute||this.player.emit(T.mute,e),this.setVolume(0),this.audioEnabled(!1),this.clear()):(this.isMute&&this.player.emit(T.mute,e),this.setVolume(.5),this.audioEnabled(!0))}setVolume(e){e=parseFloat(e).toFixed(2),isNaN(e)||(this.audioEnabled(!0),e=pe(e,0,1),this.gainNode.gain.value=e,this.gainNode.gain.setValueAtTime(e,this.audioContext.currentTime),this.player.emit(T.volumechange,this.player.volume))}closeAudio(){this.hasInitScriptNode&&(this.scriptNode&&this.scriptNode.disconnect(this.gainNode),this.gainNode&&this.gainNode.disconnect(this.audioContext.destination),this.gainNode&&this.gainNode.disconnect(this.mediaStreamAudioDestinationNode)),this.clear()}audioEnabled(e){e?"suspended"===this.audioContext.state&&this.audioContext.resume():"running"===this.audioContext.state&&this.audioContext.suspend()}isStateRunning(){return"running"===this.audioContext.state}isStateSuspended(){return"suspended"===this.audioContext.state}clear(){this.bufferList=[]}play(e,t){this.isMute||(this.hasAudio=!0,this.bufferList.push({buffer:e,ts:t}),this.bufferList.length>20&&(this.player.debug.warn("AudioContext",`bufferList is large: ${this.bufferList.length}`),this.bufferList.length>50&&this.bufferList.shift()))}pause(){this.audioSyncVideoOption={diff:null},this.playing=!1,this.clear()}resume(){this.playing=!0}}class xe{constructor(e){return new(xe.getLoaderFactory())(e)}static getLoaderFactory(){return Ie}}class De extends Be{constructor(e){super(),this.player=e,this.playing=!1,this.abortController=new AbortController,this.streamRate=be((t=>{e.emit(T.kBps,(t/1024).toFixed(2))})),e.debug.log("FetchStream","init")}destroy(){this.abort(),this.off(),this.streamRate=null,this.player.debug.log("FetchStream","destroy")}fetchStream(e){const{demux:t}=this.player;this.player._times.streamStart=he(),fetch(e,{signal:this.abortController.signal}).then((e=>{const i=e.body.getReader();this.emit(T.streamSuccess);const o=()=>{i.read().then((e=>{let{done:i,value:r}=e;i?t.close():(this.streamRate&&this.streamRate(r.byteLength),t.dispatch(r),o())})).catch((e=>{t.close(),this.emit(x.fetchError,e),this.player.emit(T.error,x.fetchError),this.abort()}))};o()})).catch((e=>{this.abort(),this.emit(x.fetchError,e),this.player.emit(T.error,x.fetchError)}))}abort(){this.abortController&&(this.abortController.abort(),this.abortController=null)}}class je extends Be{constructor(e){super(),this.player=e,this.socket=null,this.socketStatus=D,this.wsUrl=null,this.streamRate=be((t=>{e.emit(T.kBps,(t/1024).toFixed(2))}))}destroy(){this.socket&&(this.socket.close(),this.socket=null),this.socketStatus=D,this.streamRate=null,this.wsUrl=null,this.off(),this.player.debug.log("websocketLoader","destroy")}_createWebSocket(){const e=this.player,{debug:t,events:{proxy:i},demux:o}=e;this.socket=new WebSocket(this.wsUrl),this.socket.binaryType="arraybuffer",i(this.socket,"open",(()=>{this.emit(T.streamSuccess),t.log("websocketLoader","socket open"),this.socketStatus=j})),i(this.socket,"message",(e=>{this.streamRate&&this.streamRate(e.data.byteLength),this._handleMessage(e.data)})),i(this.socket,"close",(()=>{t.log("websocketLoader","socket close"),this.emit(T.streamEnd),this.socketStatus=L})),i(this.socket,"error",(e=>{t.log("websocketLoader","socket error"),this.emit(x.websocketError,e),this.player.emit(T.error,x.websocketError),this.socketStatus=U,o.close(),t.log("websocketLoader","socket error:",e)}))}_handleMessage(e){const{demux:t}=this.player;t?t.dispatch(e):this.player.debug.warn("websocketLoader","websocket handle message demux is null")}fetchStream(e){this.player._times.streamStart=he(),this.wsUrl=e,this._createWebSocket()}}class Le{constructor(e){return new(Le.getLoaderFactory(e._opt.protocol))(e)}static getLoaderFactory(e){return e===s?De:e===A?je:void 0}}var Ue=t((function(t){function i(e,t){if(!e)throw"First parameter is required.";t=new o(e,t=t||{type:"video"});var A=this;function s(i){i&&(t.initCallback=function(){i(),i=t.initCallback=null});var o=new r(e,t);(h=new o(e,t)).record(),u("recording"),t.disableLogs||console.log("Initialized recorderType:",h.constructor.name,"for output-type:",t.type)}function n(e){if(e=e||function(){},h){if("paused"===A.state)return A.resumeRecording(),void setTimeout((function(){n(e)}),1);"recording"===A.state||t.disableLogs||console.warn('Recording state should be: "recording", however current state is: ',A.state),t.disableLogs||console.log("Stopped recording "+t.type+" stream."),"gif"!==t.type?h.stop(i):(h.stop(),i()),u("stopped")}else m();function i(i){if(h){Object.keys(h).forEach((function(e){"function"!=typeof h[e]&&(A[e]=h[e])}));var o=h.blob;if(!o){if(!i)throw"Recording failed.";h.blob=o=i}if(o&&!t.disableLogs&&console.log(o.type,"->",b(o.size)),e){var r;try{r=l.createObjectURL(o)}catch(e){}"function"==typeof e.call?e.call(A,r):e(r)}t.autoWriteToDisk&&d((function(e){var i={};i[t.type+"Blob"]=e,x.Store(i)}))}else"function"==typeof e.call?e.call(A,""):e("")}}function a(e){postMessage((new FileReaderSync).readAsDataURL(e))}function d(e,i){if(!e)throw"Pass a callback function over getDataURL.";var o=i?i.blob:(h||{}).blob;if(!o)return t.disableLogs||console.warn("Blob encoder did not finish its job yet."),void setTimeout((function(){d(e,i)}),1e3);if("undefined"==typeof Worker||navigator.mozGetUserMedia){var r=new FileReader;r.readAsDataURL(o),r.onload=function(t){e(t.target.result)}}else{var A=function(e){try{var t=l.createObjectURL(new Blob([e.toString(),"this.onmessage = function (eee) {"+e.name+"(eee.data);}"],{type:"application/javascript"})),i=new Worker(t);return l.revokeObjectURL(t),i}catch(e){}}(a);A.onmessage=function(t){e(t.data)},A.postMessage(o)}}function c(e){e=e||0,"paused"!==A.state?"stopped"!==A.state&&(e>=A.recordingDuration?n(A.onRecordingStopped):(e+=1e3,setTimeout((function(){c(e)}),1e3))):setTimeout((function(){c(e)}),1e3)}function u(e){A&&(A.state=e,"function"==typeof A.onStateChanged.call?A.onStateChanged.call(A,e):A.onStateChanged(e))}var h,p='It seems that recorder is destroyed or "startRecording" is not invoked for '+t.type+" recorder.";function m(){!0!==t.disableLogs&&console.warn(p)}var g={startRecording:function(i){return t.disableLogs||console.log("RecordRTC version: ",A.version),i&&(t=new o(e,i)),t.disableLogs||console.log("started recording "+t.type+" stream."),h?(h.clearRecordedData(),h.record(),u("recording"),A.recordingDuration&&c(),A):(s((function(){A.recordingDuration&&c()})),A)},stopRecording:n,pauseRecording:function(){h?"recording"===A.state?(u("paused"),h.pause(),t.disableLogs||console.log("Paused recording.")):t.disableLogs||console.warn("Unable to pause the recording. Recording state: ",A.state):m()},resumeRecording:function(){h?"paused"===A.state?(u("recording"),h.resume(),t.disableLogs||console.log("Resumed recording.")):t.disableLogs||console.warn("Unable to resume the recording. Recording state: ",A.state):m()},initRecorder:s,setRecordingDuration:function(e,t){if(void 0===e)throw"recordingDuration is required.";if("number"!=typeof e)throw"recordingDuration must be a number.";return A.recordingDuration=e,A.onRecordingStopped=t||function(){},{onRecordingStopped:function(e){A.onRecordingStopped=e}}},clearRecordedData:function(){h?(h.clearRecordedData(),t.disableLogs||console.log("Cleared old recorded data.")):m()},getBlob:function(){if(h)return h.blob;m()},getDataURL:d,toURL:function(){if(h)return l.createObjectURL(h.blob);m()},getInternalRecorder:function(){return h},save:function(e){h?y(h.blob,e):m()},getFromDisk:function(e){h?i.getFromDisk(t.type,e):m()},setAdvertisementArray:function(e){t.advertisement=[];for(var i=e.length,o=0;o<i;o++)t.advertisement.push({duration:o,image:e[o]})},blob:null,bufferSize:0,sampleRate:0,buffer:null,reset:function(){"recording"!==A.state||t.disableLogs||console.warn("Stop an active recorder."),h&&"function"==typeof h.clearRecordedData&&h.clearRecordedData(),h=null,u("inactive"),A.blob=null},onStateChanged:function(e){t.disableLogs||console.log("Recorder state changed:",e)},state:"inactive",getState:function(){return A.state},destroy:function(){var e=t.disableLogs;t={disableLogs:!0},A.reset(),u("destroyed"),g=A=null,E.AudioContextConstructor&&(E.AudioContextConstructor.close(),E.AudioContextConstructor=null),t.disableLogs=e,t.disableLogs||console.log("RecordRTC is destroyed.")},version:"5.6.2"};if(!this)return A=g,g;for(var f in g)this[f]=g[f];return A=this,g}function o(e,t){return t.recorderType||t.type||(t.audio&&t.video?t.type="video":t.audio&&!t.video&&(t.type="audio")),t.recorderType&&!t.type&&(t.recorderType===T||t.recorderType===k||t.recorderType===U?t.type="video":t.recorderType===D?t.type="gif":t.recorderType===R?t.type="audio":t.recorderType===C&&(w(e,"audio").length&&w(e,"video").length||!w(e,"audio").length&&w(e,"video").length?t.type="video":w(e,"audio").length&&!w(e,"video").length&&(t.type="audio"))),"undefined"!=typeof MediaRecorder&&"requestData"in MediaRecorder.prototype&&(t.mimeType||(t.mimeType="video/webm"),t.type||(t.type=t.mimeType.split("/")[0]),t.bitsPerSecond),t.type||(t.mimeType&&(t.type=t.mimeType.split("/")[0]),t.type||(t.type="audio")),t}function r(e,t){var i;return(m||u||h)&&(i=R),"undefined"!=typeof MediaRecorder&&"requestData"in MediaRecorder.prototype&&!m&&(i=C),"video"===t.type&&(m||h)&&(i=T,"undefined"!=typeof ReadableStream&&(i=U)),"gif"===t.type&&(i=D),"canvas"===t.type&&(i=k),B()&&i!==k&&i!==D&&"undefined"!=typeof MediaRecorder&&"requestData"in MediaRecorder.prototype&&(w(e,"video").length||w(e,"audio").length)&&("audio"===t.type?"function"==typeof MediaRecorder.isTypeSupported&&MediaRecorder.isTypeSupported("audio/webm")&&(i=C):"function"==typeof MediaRecorder.isTypeSupported&&MediaRecorder.isTypeSupported("video/webm")&&(i=C)),e instanceof Array&&e.length&&(i=L),t.recorderType&&(i=t.recorderType),!t.disableLogs&&i&&i.name&&console.log("Using recorderType:",i.name||i.constructor.name),!i&&g&&(i=C),i}function A(e){this.addStream=function(t){t&&(e=t)},this.mediaType={audio:!0,video:!0},this.startRecording=function(){var t,o=this.mediaType,r=this.mimeType||{audio:null,video:null,gif:null};if("function"!=typeof o.audio&&B()&&!w(e,"audio").length&&(o.audio=!1),"function"!=typeof o.video&&B()&&!w(e,"video").length&&(o.video=!1),"function"!=typeof o.gif&&B()&&!w(e,"video").length&&(o.gif=!1),!o.audio&&!o.video&&!o.gif)throw"MediaStream must have either audio or video tracks.";if(o.audio&&(t=null,"function"==typeof o.audio&&(t=o.audio),this.audioRecorder=new i(e,{type:"audio",bufferSize:this.bufferSize,sampleRate:this.sampleRate,numberOfAudioChannels:this.numberOfAudioChannels||2,disableLogs:this.disableLogs,recorderType:t,mimeType:r.audio,timeSlice:this.timeSlice,onTimeStamp:this.onTimeStamp}),o.video||this.audioRecorder.startRecording()),o.video){t=null,"function"==typeof o.video&&(t=o.video);var A=e;if(B()&&o.audio&&"function"==typeof o.audio){var s=w(e,"video")[0];p?((A=new f).addTrack(s),t&&t===T&&(t=C)):(A=new f).addTrack(s)}this.videoRecorder=new i(A,{type:"video",video:this.video,canvas:this.canvas,frameInterval:this.frameInterval||10,disableLogs:this.disableLogs,recorderType:t,mimeType:r.video,timeSlice:this.timeSlice,onTimeStamp:this.onTimeStamp,workerPath:this.workerPath,webAssemblyPath:this.webAssemblyPath,frameRate:this.frameRate,bitrate:this.bitrate}),o.audio||this.videoRecorder.startRecording()}if(o.audio&&o.video){var n=this,a=!0===B();(o.audio instanceof R&&o.video||!0!==o.audio&&!0!==o.video&&o.audio!==o.video)&&(a=!1),!0===a?(n.audioRecorder=null,n.videoRecorder.startRecording()):n.videoRecorder.initRecorder((function(){n.audioRecorder.initRecorder((function(){n.videoRecorder.startRecording(),n.audioRecorder.startRecording()}))}))}o.gif&&(t=null,"function"==typeof o.gif&&(t=o.gif),this.gifRecorder=new i(e,{type:"gif",frameRate:this.frameRate||200,quality:this.quality||10,disableLogs:this.disableLogs,recorderType:t,mimeType:r.gif}),this.gifRecorder.startRecording())},this.stopRecording=function(e){e=e||function(){},this.audioRecorder&&this.audioRecorder.stopRecording((function(t){e(t,"audio")})),this.videoRecorder&&this.videoRecorder.stopRecording((function(t){e(t,"video")})),this.gifRecorder&&this.gifRecorder.stopRecording((function(t){e(t,"gif")}))},this.pauseRecording=function(){this.audioRecorder&&this.audioRecorder.pauseRecording(),this.videoRecorder&&this.videoRecorder.pauseRecording(),this.gifRecorder&&this.gifRecorder.pauseRecording()},this.resumeRecording=function(){this.audioRecorder&&this.audioRecorder.resumeRecording(),this.videoRecorder&&this.videoRecorder.resumeRecording(),this.gifRecorder&&this.gifRecorder.resumeRecording()},this.getBlob=function(e){var t={};return this.audioRecorder&&(t.audio=this.audioRecorder.getBlob()),this.videoRecorder&&(t.video=this.videoRecorder.getBlob()),this.gifRecorder&&(t.gif=this.gifRecorder.getBlob()),e&&e(t),t},this.destroy=function(){this.audioRecorder&&(this.audioRecorder.destroy(),this.audioRecorder=null),this.videoRecorder&&(this.videoRecorder.destroy(),this.videoRecorder=null),this.gifRecorder&&(this.gifRecorder.destroy(),this.gifRecorder=null)},this.getDataURL=function(e){function t(e,t){if("undefined"!=typeof Worker){var i=function(e){var t,i=l.createObjectURL(new Blob([e.toString(),"this.onmessage = function (eee) {"+e.name+"(eee.data);}"],{type:"application/javascript"})),o=new Worker(i);if(void 0!==l)t=l;else{if("undefined"==typeof webkitURL)throw"Neither URL nor webkitURL detected.";t=webkitURL}return t.revokeObjectURL(i),o}((function(e){postMessage((new FileReaderSync).readAsDataURL(e))}));i.onmessage=function(e){t(e.data)},i.postMessage(e)}else{var o=new FileReader;o.readAsDataURL(e),o.onload=function(e){t(e.target.result)}}}this.getBlob((function(i){i.audio&&i.video?t(i.audio,(function(o){t(i.video,(function(t){e({audio:o,video:t})}))})):i.audio?t(i.audio,(function(t){e({audio:t})})):i.video&&t(i.video,(function(t){e({video:t})}))}))},this.writeToDisk=function(){i.writeToDisk({audio:this.audioRecorder,video:this.videoRecorder,gif:this.gifRecorder})},this.save=function(e){(e=e||{audio:!0,video:!0,gif:!0}).audio&&this.audioRecorder&&this.audioRecorder.save("string"==typeof e.audio?e.audio:""),e.video&&this.videoRecorder&&this.videoRecorder.save("string"==typeof e.video?e.video:""),e.gif&&this.gifRecorder&&this.gifRecorder.save("string"==typeof e.gif?e.gif:"")}}i.version="5.6.2",t.exports=i,i.getFromDisk=function(e,t){if(!t)throw"callback is mandatory.";console.log("Getting recorded "+("all"===e?"blobs":e+" blob ")+" from disk!"),x.Fetch((function(i,o){"all"!==e&&o===e+"Blob"&&t&&t(i),"all"===e&&t&&t(i,o.replace("Blob",""))}))},i.writeToDisk=function(e){console.log("Writing recorded blob(s) to disk!"),(e=e||{}).audio&&e.video&&e.gif?e.audio.getDataURL((function(t){e.video.getDataURL((function(i){e.gif.getDataURL((function(e){x.Store({audioBlob:t,videoBlob:i,gifBlob:e})}))}))})):e.audio&&e.video?e.audio.getDataURL((function(t){e.video.getDataURL((function(e){x.Store({audioBlob:t,videoBlob:e})}))})):e.audio&&e.gif?e.audio.getDataURL((function(t){e.gif.getDataURL((function(e){x.Store({audioBlob:t,gifBlob:e})}))})):e.video&&e.gif?e.video.getDataURL((function(t){e.gif.getDataURL((function(e){x.Store({videoBlob:t,gifBlob:e})}))})):e.audio?e.audio.getDataURL((function(e){x.Store({audioBlob:e})})):e.video?e.video.getDataURL((function(e){x.Store({videoBlob:e})})):e.gif&&e.gif.getDataURL((function(e){x.Store({gifBlob:e})}))},A.getFromDisk=i.getFromDisk,A.writeToDisk=i.writeToDisk,i.MRecordRTC=A;var s;(s=void 0!==e?e:null)&&"undefined"==typeof window&&void 0!==e&&(e.navigator={userAgent:"Fake/5.0 (FakeOS) AppleWebKit/123 (KHTML, like Gecko) Fake/12.3.4567.89 Fake/123.45",getUserMedia:function(){}},e.console||(e.console={}),void 0!==e.console.log&&void 0!==e.console.error||(e.console.error=e.console.log=e.console.log||function(){console.log(arguments)}),"undefined"==typeof document&&(s.document={documentElement:{appendChild:function(){return""}}},document.createElement=document.captureStream=document.mozCaptureStream=function(){var e={getContext:function(){return e},play:function(){},pause:function(){},drawImage:function(){},toDataURL:function(){return""},style:{}};return e},s.HTMLVideoElement=function(){}),"undefined"==typeof location&&(s.location={protocol:"file:",href:"",hash:""}),"undefined"==typeof screen&&(s.screen={width:0,height:0}),void 0===l&&(s.URL={createObjectURL:function(){return""},revokeObjectURL:function(){return""}}),s.window=e);var n=window.requestAnimationFrame;if(void 0===n)if("undefined"!=typeof webkitRequestAnimationFrame)n=webkitRequestAnimationFrame;else if("undefined"!=typeof mozRequestAnimationFrame)n=mozRequestAnimationFrame;else if("undefined"!=typeof msRequestAnimationFrame)n=msRequestAnimationFrame;else if(void 0===n){var a=0;n=function(e,t){var i=(new Date).getTime(),o=Math.max(0,16-(i-a)),r=setTimeout((function(){e(i+o)}),o);return a=i+o,r}}var d=window.cancelAnimationFrame;void 0===d&&("undefined"!=typeof webkitCancelAnimationFrame?d=webkitCancelAnimationFrame:"undefined"!=typeof mozCancelAnimationFrame?d=mozCancelAnimationFrame:"undefined"!=typeof msCancelAnimationFrame?d=msCancelAnimationFrame:void 0===d&&(d=function(e){clearTimeout(e)}));var c=window.AudioContext;void 0===c&&("undefined"!=typeof webkitAudioContext&&(c=webkitAudioContext),"undefined"!=typeof mozAudioContext&&(c=mozAudioContext));var l=window.URL;void 0===l&&"undefined"!=typeof webkitURL&&(l=webkitURL),"undefined"!=typeof navigator&&void 0===navigator.getUserMedia&&(void 0!==navigator.webkitGetUserMedia&&(navigator.getUserMedia=navigator.webkitGetUserMedia),void 0!==navigator.mozGetUserMedia&&(navigator.getUserMedia=navigator.mozGetUserMedia));var u=!(-1===navigator.userAgent.indexOf("Edge")||!navigator.msSaveBlob&&!navigator.msSaveOrOpenBlob),h=!!window.opera||-1!==navigator.userAgent.indexOf("OPR/"),p=navigator.userAgent.toLowerCase().indexOf("firefox")>-1&&"netscape"in window&&/ rv:/.test(navigator.userAgent),m=!h&&!u&&!!navigator.webkitGetUserMedia||v()||-1!==navigator.userAgent.toLowerCase().indexOf("chrome/"),g=/^((?!chrome|android).)*safari/i.test(navigator.userAgent);g&&!m&&-1!==navigator.userAgent.indexOf("CriOS")&&(g=!1,m=!0);var f=window.MediaStream;function b(e){if(0===e)return"0 Bytes";var t=parseInt(Math.floor(Math.log(e)/Math.log(1e3)),10);return(e/Math.pow(1e3,t)).toPrecision(3)+" "+["Bytes","KB","MB","GB","TB"][t]}function y(e,t){if(!e)throw"Blob object is required.";if(!e.type)try{e.type="video/webm"}catch(e){}var i=(e.type||"video/webm").split("/")[1];if(-1!==i.indexOf(";")&&(i=i.split(";")[0]),t&&-1!==t.indexOf(".")){var o=t.split(".");t=o[0],i=o[1]}var r=(t||Math.round(9999999999*Math.random())+888888888)+"."+i;if(void 0!==navigator.msSaveOrOpenBlob)return navigator.msSaveOrOpenBlob(e,r);if(void 0!==navigator.msSaveBlob)return navigator.msSaveBlob(e,r);var A=document.createElement("a");A.href=l.createObjectURL(e),A.download=r,A.style="display:none;opacity:0;color:transparent;",(document.body||document.documentElement).appendChild(A),"function"==typeof A.click?A.click():(A.target="_blank",A.dispatchEvent(new MouseEvent("click",{view:window,bubbles:!0,cancelable:!0}))),l.revokeObjectURL(A.href)}function v(){return"undefined"!=typeof window&&"object"==typeof window.process&&"renderer"===window.process.type||(!("undefined"==typeof process||"object"!=typeof process.versions||!process.versions.electron)||"object"==typeof navigator&&"string"==typeof navigator.userAgent&&navigator.userAgent.indexOf("Electron")>=0)}function w(e,t){return e&&e.getTracks?e.getTracks().filter((function(e){return e.kind===(t||"audio")})):[]}function S(e,t){"srcObject"in t?t.srcObject=e:"mozSrcObject"in t?t.mozSrcObject=e:t.srcObject=e}void 0===f&&"undefined"!=typeof webkitMediaStream&&(f=webkitMediaStream),void 0!==f&&void 0===f.prototype.stop&&(f.prototype.stop=function(){this.getTracks().forEach((function(e){e.stop()}))}),i.invokeSaveAsDialog=y,i.getTracks=w,i.getSeekableBlob=function(e,t){if("undefined"==typeof EBML)throw new Error("Please link: https://www.webrtc-experiment.com/EBML.js");var i=new EBML.Reader,o=new EBML.Decoder,r=EBML.tools,A=new FileReader;A.onload=function(e){o.decode(this.result).forEach((function(e){i.read(e)})),i.stop();var A=r.makeMetadataSeekable(i.metadatas,i.duration,i.cues),s=this.result.slice(i.metadataSize),n=new Blob([A,s],{type:"video/webm"});t(n)},A.readAsArrayBuffer(e)},i.bytesToSize=b,i.isElectron=v;var E={};function B(){if(p||g||u)return!0;var e,t,i=navigator.userAgent,o=""+parseFloat(navigator.appVersion),r=parseInt(navigator.appVersion,10);return(m||h)&&(e=i.indexOf("Chrome"),o=i.substring(e+7)),-1!==(t=o.indexOf(";"))&&(o=o.substring(0,t)),-1!==(t=o.indexOf(" "))&&(o=o.substring(0,t)),r=parseInt(""+o,10),isNaN(r)&&(o=""+parseFloat(navigator.appVersion),r=parseInt(navigator.appVersion,10)),r>=49}function C(e,t){var i=this;if(void 0===e)throw'First argument "MediaStream" is required.';if("undefined"==typeof MediaRecorder)throw"Your browser does not support the Media Recorder API. Please try other modules e.g. WhammyRecorder or StereoAudioRecorder.";if("audio"===(t=t||{mimeType:"video/webm"}).type){var o;if(w(e,"video").length&&w(e,"audio").length)navigator.mozGetUserMedia?(o=new f).addTrack(w(e,"audio")[0]):o=new f(w(e,"audio")),e=o;t.mimeType&&-1!==t.mimeType.toString().toLowerCase().indexOf("audio")||(t.mimeType=m?"audio/webm":"audio/ogg"),t.mimeType&&"audio/ogg"!==t.mimeType.toString().toLowerCase()&&navigator.mozGetUserMedia&&(t.mimeType="audio/ogg")}var r,A=[];function s(){i.timestamps.push((new Date).getTime()),"function"==typeof t.onTimeStamp&&t.onTimeStamp(i.timestamps[i.timestamps.length-1],i.timestamps)}function n(e){return r&&r.mimeType?r.mimeType:e.mimeType||"video/webm"}function a(){A=[],r=null,i.timestamps=[]}this.getArrayOfBlobs=function(){return A},this.record=function(){i.blob=null,i.clearRecordedData(),i.timestamps=[],d=[],A=[];var o=t;t.disableLogs||console.log("Passing following config over MediaRecorder API.",o),r&&(r=null),m&&!B()&&(o="video/vp8"),"function"==typeof MediaRecorder.isTypeSupported&&o.mimeType&&(MediaRecorder.isTypeSupported(o.mimeType)||(t.disableLogs||console.warn("MediaRecorder API seems unable to record mimeType:",o.mimeType),o.mimeType="audio"===t.type?"audio/webm":"video/webm"));try{r=new MediaRecorder(e,o),t.mimeType=o.mimeType}catch(t){r=new MediaRecorder(e)}o.mimeType&&!MediaRecorder.isTypeSupported&&"canRecordMimeType"in r&&!1===r.canRecordMimeType(o.mimeType)&&(t.disableLogs||console.warn("MediaRecorder API seems unable to record mimeType:",o.mimeType)),r.ondataavailable=function(e){if(e.data&&d.push("ondataavailable: "+b(e.data.size)),"number"!=typeof t.timeSlice)!e.data||!e.data.size||e.data.size<100||i.blob?i.recordingCallback&&(i.recordingCallback(new Blob([],{type:n(o)})),i.recordingCallback=null):(i.blob=t.getNativeBlob?e.data:new Blob([e.data],{type:n(o)}),i.recordingCallback&&(i.recordingCallback(i.blob),i.recordingCallback=null));else if(e.data&&e.data.size&&(A.push(e.data),s(),"function"==typeof t.ondataavailable)){var r=t.getNativeBlob?e.data:new Blob([e.data],{type:n(o)});t.ondataavailable(r)}},r.onstart=function(){d.push("started")},r.onpause=function(){d.push("paused")},r.onresume=function(){d.push("resumed")},r.onstop=function(){d.push("stopped")},r.onerror=function(e){e&&(e.name||(e.name="UnknownError"),d.push("error: "+e),t.disableLogs||(-1!==e.name.toString().toLowerCase().indexOf("invalidstate")?console.error("The MediaRecorder is not in a state in which the proposed operation is allowed to be executed.",e):-1!==e.name.toString().toLowerCase().indexOf("notsupported")?console.error("MIME type (",o.mimeType,") is not supported.",e):-1!==e.name.toString().toLowerCase().indexOf("security")?console.error("MediaRecorder security error",e):"OutOfMemory"===e.name?console.error("The UA has exhaused the available memory. User agents SHOULD provide as much additional information as possible in the message attribute.",e):"IllegalStreamModification"===e.name?console.error("A modification to the stream has occurred that makes it impossible to continue recording. An example would be the addition of a Track while recording is occurring. User agents SHOULD provide as much additional information as possible in the message attribute.",e):"OtherRecordingError"===e.name?console.error("Used for an fatal error other than those listed above. User agents SHOULD provide as much additional information as possible in the message attribute.",e):"GenericError"===e.name?console.error("The UA cannot provide the codec or recording option that has been requested.",e):console.error("MediaRecorder Error",e)),function(e){if(!i.manuallyStopped&&r&&"inactive"===r.state)return delete t.timeslice,void r.start(6e5);setTimeout(void 0,1e3)}(),"inactive"!==r.state&&"stopped"!==r.state&&r.stop())},"number"==typeof t.timeSlice?(s(),r.start(t.timeSlice)):r.start(36e5),t.initCallback&&t.initCallback()},this.timestamps=[],this.stop=function(e){e=e||function(){},i.manuallyStopped=!0,r&&(this.recordingCallback=e,"recording"===r.state&&r.stop(),"number"==typeof t.timeSlice&&setTimeout((function(){i.blob=new Blob(A,{type:n(t)}),i.recordingCallback(i.blob)}),100))},this.pause=function(){r&&"recording"===r.state&&r.pause()},this.resume=function(){r&&"paused"===r.state&&r.resume()},this.clearRecordedData=function(){r&&"recording"===r.state&&i.stop(a),a()},this.getInternalRecorder=function(){return r},this.blob=null,this.getState=function(){return r&&r.state||"inactive"};var d=[];this.getAllStates=function(){return d},void 0===t.checkForInactiveTracks&&(t.checkForInactiveTracks=!1);i=this;!function o(){if(r&&!1!==t.checkForInactiveTracks)return!1===function(){if("active"in e){if(!e.active)return!1}else if("ended"in e&&e.ended)return!1;return!0}()?(t.disableLogs||console.log("MediaStream seems stopped."),void i.stop()):void setTimeout(o,1e3)}(),this.name="MediaStreamRecorder",this.toString=function(){return this.name}}function R(e,t){if(!w(e,"audio").length)throw"Your stream has no audio tracks.";var o,r=this,A=[],s=[],n=!1,a=0,d=2,c=(t=t||{}).desiredSampRate;function u(){if(!1===t.checkForInactiveTracks)return!0;if("active"in e){if(!e.active)return!1}else if("ended"in e&&e.ended)return!1;return!0}function h(e,t){function i(e,t){var i,o=e.numberOfAudioChannels,r=e.leftBuffers.slice(0),A=e.rightBuffers.slice(0),s=e.sampleRate,n=e.internalInterleavedLength,a=e.desiredSampRate;function d(e,t,i){var o=Math.round(e.length*(t/i)),r=[],A=Number((e.length-1)/(o-1));r[0]=e[0];for(var s=1;s<o-1;s++){var n=s*A,a=Number(Math.floor(n)).toFixed(),d=Number(Math.ceil(n)).toFixed(),l=n-a;r[s]=c(e[a],e[d],l)}return r[o-1]=e[e.length-1],r}function c(e,t,i){return e+(t-e)*i}function l(e,t){for(var i=new Float64Array(t),o=0,r=e.length,A=0;A<r;A++){var s=e[A];i.set(s,o),o+=s.length}return i}function u(e,t,i){for(var o=i.length,r=0;r<o;r++)e.setUint8(t+r,i.charCodeAt(r))}2===o&&(r=l(r,n),A=l(A,n),a&&(r=d(r,a,s),A=d(A,a,s))),1===o&&(r=l(r,n),a&&(r=d(r,a,s))),a&&(s=a),2===o&&(i=function(e,t){for(var i=e.length+t.length,o=new Float64Array(i),r=0,A=0;A<i;)o[A++]=e[r],o[A++]=t[r],r++;return o}(r,A)),1===o&&(i=r);var h=i.length,p=new ArrayBuffer(44+2*h),m=new DataView(p);u(m,0,"RIFF"),m.setUint32(4,36+2*h,!0),u(m,8,"WAVE"),u(m,12,"fmt "),m.setUint32(16,16,!0),m.setUint16(20,1,!0),m.setUint16(22,o,!0),m.setUint32(24,s,!0),m.setUint32(28,s*o*2,!0),m.setUint16(32,2*o,!0),m.setUint16(34,16,!0),u(m,36,"data"),m.setUint32(40,2*h,!0);for(var g=h,f=44,b=0;b<g;b++)m.setInt16(f,32767*i[b],!0),f+=2;if(t)return t({buffer:p,view:m});postMessage({buffer:p,view:m})}if(e.noWorker)i(e,(function(e){t(e.buffer,e.view)}));else{var o,r,A,s=(o=i,r=l.createObjectURL(new Blob([o.toString(),";this.onmessage = function (eee) {"+o.name+"(eee.data);}"],{type:"application/javascript"})),(A=new Worker(r)).workerURL=r,A);s.onmessage=function(e){t(e.data.buffer,e.data.view),l.revokeObjectURL(s.workerURL),s.terminate()},s.postMessage(e)}}!0===t.leftChannel&&(d=1),1===t.numberOfAudioChannels&&(d=1),(!d||d<1)&&(d=2),t.disableLogs||console.log("StereoAudioRecorder is set to record number of channels: "+d),void 0===t.checkForInactiveTracks&&(t.checkForInactiveTracks=!0),this.record=function(){if(!1===u())throw"Please make sure MediaStream is active.";v(),E=y=!1,n=!0,void 0!==t.timeSlice&&C()},this.stop=function(e){e=e||function(){},n=!1,h({desiredSampRate:c,sampleRate:b,numberOfAudioChannels:d,internalInterleavedLength:a,leftBuffers:A,rightBuffers:1===d?[]:s,noWorker:t.noWorker},(function(t,i){r.blob=new Blob([i],{type:"audio/wav"}),r.buffer=new ArrayBuffer(i.buffer.byteLength),r.view=i,r.sampleRate=c||b,r.bufferSize=f,r.length=a,E=!1,e&&e(r.blob)}))},void 0===i.Storage&&(i.Storage={AudioContextConstructor:null,AudioContext:window.AudioContext||window.webkitAudioContext}),i.Storage.AudioContextConstructor&&"closed"!==i.Storage.AudioContextConstructor.state||(i.Storage.AudioContextConstructor=new i.Storage.AudioContext);var p=i.Storage.AudioContextConstructor,m=p.createMediaStreamSource(e),g=[0,256,512,1024,2048,4096,8192,16384],f=void 0===t.bufferSize?4096:t.bufferSize;if(-1===g.indexOf(f)&&(t.disableLogs||console.log("Legal values for buffer-size are "+JSON.stringify(g,null,"\t"))),p.createJavaScriptNode)o=p.createJavaScriptNode(f,d,d);else{if(!p.createScriptProcessor)throw"WebAudio API has no support on this browser.";o=p.createScriptProcessor(f,d,d)}m.connect(o),t.bufferSize||(f=o.bufferSize);var b=void 0!==t.sampleRate?t.sampleRate:p.sampleRate||44100;(b<22050||b>96e3)&&(t.disableLogs||console.log("sample-rate must be under range 22050 and 96000.")),t.disableLogs||t.desiredSampRate&&console.log("Desired sample-rate: "+t.desiredSampRate);var y=!1;function v(){A=[],s=[],a=0,E=!1,n=!1,y=!1,p=null,r.leftchannel=A,r.rightchannel=s,r.numberOfAudioChannels=d,r.desiredSampRate=c,r.sampleRate=b,r.recordingLength=a,B={left:[],right:[],recordingLength:0}}function S(){o&&(o.onaudioprocess=null,o.disconnect(),o=null),m&&(m.disconnect(),m=null),v()}this.pause=function(){y=!0},this.resume=function(){if(!1===u())throw"Please make sure MediaStream is active.";if(!n)return t.disableLogs||console.log("Seems recording has been restarted."),void this.record();y=!1},this.clearRecordedData=function(){t.checkForInactiveTracks=!1,n&&this.stop(S),S()},this.name="StereoAudioRecorder",this.toString=function(){return this.name};var E=!1;o.onaudioprocess=function(e){if(!y)if(!1===u()&&(t.disableLogs||console.log("MediaStream seems stopped."),o.disconnect(),n=!1),n){E||(E=!0,t.onAudioProcessStarted&&t.onAudioProcessStarted(),t.initCallback&&t.initCallback());var i=e.inputBuffer.getChannelData(0),c=new Float32Array(i);if(A.push(c),2===d){var l=e.inputBuffer.getChannelData(1),h=new Float32Array(l);s.push(h)}a+=f,r.recordingLength=a,void 0!==t.timeSlice&&(B.recordingLength+=f,B.left.push(c),2===d&&B.right.push(h))}else m&&(m.disconnect(),m=null)},p.createMediaStreamDestination?o.connect(p.createMediaStreamDestination()):o.connect(p.destination),this.leftchannel=A,this.rightchannel=s,this.numberOfAudioChannels=d,this.desiredSampRate=c,this.sampleRate=b,r.recordingLength=a;var B={left:[],right:[],recordingLength:0};function C(){n&&"function"==typeof t.ondataavailable&&void 0!==t.timeSlice&&(B.left.length?(h({desiredSampRate:c,sampleRate:b,numberOfAudioChannels:d,internalInterleavedLength:B.recordingLength,leftBuffers:B.left,rightBuffers:1===d?[]:B.right},(function(e,i){var o=new Blob([i],{type:"audio/wav"});t.ondataavailable(o),setTimeout(C,t.timeSlice)})),B={left:[],right:[],recordingLength:0}):setTimeout(C,t.timeSlice))}}function k(e,t){if("undefined"==typeof html2canvas)throw"Please link: https://www.webrtc-experiment.com/screenshot.js";(t=t||{}).frameInterval||(t.frameInterval=10);var i=!1;["captureStream","mozCaptureStream","webkitCaptureStream"].forEach((function(e){e in document.createElement("canvas")&&(i=!0)}));var o,r,A,s=!(!window.webkitRTCPeerConnection&&!window.webkitGetUserMedia||!window.chrome),n=50,a=navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./);if(s&&a&&a[2]&&(n=parseInt(a[2],10)),s&&n<52&&(i=!1),t.useWhammyRecorder&&(i=!1),i)if(t.disableLogs||console.log("Your browser supports both MediRecorder API and canvas.captureStream!"),e instanceof HTMLCanvasElement)o=e;else{if(!(e instanceof CanvasRenderingContext2D))throw"Please pass either HTMLCanvasElement or CanvasRenderingContext2D.";o=e.canvas}else navigator.mozGetUserMedia&&(t.disableLogs||console.error("Canvas recording is NOT supported in Firefox."));this.record=function(){if(A=!0,i&&!t.useWhammyRecorder){var e;"captureStream"in o?e=o.captureStream(25):"mozCaptureStream"in o?e=o.mozCaptureStream(25):"webkitCaptureStream"in o&&(e=o.webkitCaptureStream(25));try{var s=new f;s.addTrack(w(e,"video")[0]),e=s}catch(e){}if(!e)throw"captureStream API are NOT available.";(r=new C(e,{mimeType:t.mimeType||"video/webm"})).record()}else h.frames=[],u=(new Date).getTime(),l();t.initCallback&&t.initCallback()},this.getWebPImages=function(i){if("canvas"===e.nodeName.toLowerCase()){var o=h.frames.length;h.frames.forEach((function(e,i){var r=o-i;t.disableLogs||console.log(r+"/"+o+" frames remaining"),t.onEncodingCallback&&t.onEncodingCallback(r,o);var A=e.image.toDataURL("image/webp",1);h.frames[i].image=A})),t.disableLogs||console.log("Generating WebM"),i()}else i()},this.stop=function(e){A=!1;var o=this;i&&r?r.stop(e):this.getWebPImages((function(){h.compile((function(i){t.disableLogs||console.log("Recording finished!"),o.blob=i,o.blob.forEach&&(o.blob=new Blob([],{type:"video/webm"})),e&&e(o.blob),h.frames=[]}))}))};var d=!1;function c(){h.frames=[],A=!1,d=!1}function l(){if(d)return u=(new Date).getTime(),setTimeout(l,500);if("canvas"===e.nodeName.toLowerCase()){var i=(new Date).getTime()-u;return u=(new Date).getTime(),h.frames.push({image:(o=document.createElement("canvas"),r=o.getContext("2d"),o.width=e.width,o.height=e.height,r.drawImage(e,0,0),o),duration:i}),void(A&&setTimeout(l,t.frameInterval))}var o,r;html2canvas(e,{grabMouse:void 0===t.showMousePointer||t.showMousePointer,onrendered:function(e){var i=(new Date).getTime()-u;if(!i)return setTimeout(l,t.frameInterval);u=(new Date).getTime(),h.frames.push({image:e.toDataURL("image/webp",1),duration:i}),A&&setTimeout(l,t.frameInterval)}})}this.pause=function(){d=!0,r instanceof C&&r.pause()},this.resume=function(){d=!1,r instanceof C?r.resume():A||this.record()},this.clearRecordedData=function(){A&&this.stop(c),c()},this.name="CanvasRecorder",this.toString=function(){return this.name};var u=(new Date).getTime(),h=new I.Video(100)}function T(e,t){function i(e){e=void 0!==e?e:10;var t=(new Date).getTime()-a;return t?A?(a=(new Date).getTime(),setTimeout(i,100)):(a=(new Date).getTime(),n.paused&&n.play(),l.drawImage(n,0,0,c.width,c.height),d.frames.push({duration:t,image:c.toDataURL("image/webp")}),void(r||setTimeout(i,e,e))):setTimeout(i,e,e)}function o(e,t,i,o,r){var A=document.createElement("canvas");A.width=c.width,A.height=c.height;var s,n,a,d=A.getContext("2d"),l=[],u=-1===t,h=t&&t>0&&t<=e.length?t:e.length,p=0,m=0,g=0,f=Math.sqrt(Math.pow(255,2)+Math.pow(255,2)+Math.pow(255,2)),b=i&&i>=0&&i<=1?i:0,y=o&&o>=0&&o<=1?o:0,v=!1;n=-1,a=(s={length:h,functionToLoop:function(t,i){var o,r,A,s=function(){!v&&A-o<=A*y||(u&&(v=!0),l.push(e[i])),t()};if(v)s();else{var n=new Image;n.onload=function(){d.drawImage(n,0,0,c.width,c.height);var e=d.getImageData(0,0,c.width,c.height);o=0,r=e.data.length,A=e.data.length/4;for(var t=0;t<r;t+=4){var i={r:e.data[t],g:e.data[t+1],b:e.data[t+2]};Math.sqrt(Math.pow(i.r-p,2)+Math.pow(i.g-m,2)+Math.pow(i.b-g,2))<=f*b&&o++}s()},n.src=e[i].image}},callback:function(){(l=l.concat(e.slice(h))).length<=0&&l.push(e[e.length-1]),r(l)}}).length,function e(){++n!==a?setTimeout((function(){s.functionToLoop(e,n)}),1):s.callback()}()}(t=t||{}).frameInterval||(t.frameInterval=10),t.disableLogs||console.log("Using frames-interval:",t.frameInterval),this.record=function(){t.width||(t.width=320),t.height||(t.height=240),t.video||(t.video={width:t.width,height:t.height}),t.canvas||(t.canvas={width:t.width,height:t.height}),c.width=t.canvas.width||320,c.height=t.canvas.height||240,l=c.getContext("2d"),t.video&&t.video instanceof HTMLVideoElement?(n=t.video.cloneNode(),t.initCallback&&t.initCallback()):(n=document.createElement("video"),S(e,n),n.onloadedmetadata=function(){t.initCallback&&t.initCallback()},n.width=t.video.width,n.height=t.video.height),n.muted=!0,n.play(),a=(new Date).getTime(),d=new I.Video,t.disableLogs||(console.log("canvas resolutions",c.width,"*",c.height),console.log("video width/height",n.width||c.width,"*",n.height||c.height)),i(t.frameInterval)};var r=!1;this.stop=function(e){e=e||function(){},r=!0;var i=this;setTimeout((function(){o(d.frames,-1,null,null,(function(o){d.frames=o,t.advertisement&&t.advertisement.length&&(d.frames=t.advertisement.concat(d.frames)),d.compile((function(t){i.blob=t,i.blob.forEach&&(i.blob=new Blob([],{type:"video/webm"})),e&&e(i.blob)}))}))}),10)};var A=!1;function s(){d.frames=[],r=!0,A=!1}this.pause=function(){A=!0},this.resume=function(){A=!1,r&&this.record()},this.clearRecordedData=function(){r||this.stop(s),s()},this.name="WhammyRecorder",this.toString=function(){return this.name};var n,a,d,c=document.createElement("canvas"),l=c.getContext("2d")}void 0!==c?E.AudioContext=c:"undefined"!=typeof webkitAudioContext&&(E.AudioContext=webkitAudioContext),i.Storage=E,i.MediaStreamRecorder=C,i.StereoAudioRecorder=R,i.CanvasRecorder=k,i.WhammyRecorder=T;var I=function(){function e(e){this.frames=[],this.duration=e||1,this.quality=.8}function t(e){function t(e,t,i){return[{data:e,id:231}].concat(i.map((function(e){var i=function(e){var t=0;e.keyframe&&(t|=128);e.invisible&&(t|=8);e.lacing&&(t|=e.lacing<<1);e.discardable&&(t|=1);if(e.trackNum>127)throw"TrackNumber > 127 not supported";return[128|e.trackNum,e.timecode>>8,255&e.timecode,t].map((function(e){return String.fromCharCode(e)})).join("")+e.frame}({discardable:0,frame:e.data.slice(4),invisible:0,keyframe:1,lacing:0,trackNum:1,timecode:Math.round(t)});return t+=e.duration,{data:i,id:163}})))}function i(e){for(var t=[];e>0;)t.push(255&e),e>>=8;return new Uint8Array(t.reverse())}function o(e){var t=[];e=(e.length%8?new Array(9-e.length%8).join("0"):"")+e;for(var i=0;i<e.length;i+=8)t.push(parseInt(e.substr(i,8),2));return new Uint8Array(t)}function r(e){for(var t=[],A=0;A<e.length;A++){var s=e[A].data;"object"==typeof s&&(s=r(s)),"number"==typeof s&&(s=o(s.toString(2))),"string"==typeof s&&(s=new Uint8Array(s.split("").map((function(e){return e.charCodeAt(0)}))));var n=s.size||s.byteLength||s.length,a=Math.ceil(Math.ceil(Math.log(n)/Math.log(2))/8),d=n.toString(2),c=new Array(7*a+7+1-d.length).join("0")+d,l=new Array(a).join("0")+"1"+c;t.push(i(e[A].id)),t.push(o(l)),t.push(s)}return new Blob(t,{type:"video/webm"})}function A(e,t){return parseInt(e.substr(t+4,4).split("").map((function(e){var t=e.charCodeAt(0).toString(2);return new Array(8-t.length+1).join("0")+t})).join(""),2)}function s(e){for(var t=0,i={};t<e.length;){var o=e.substr(t,4),r=A(e,t),n=e.substr(t+4+4,r);t+=8+r,i[o]=i[o]||[],"RIFF"===o||"LIST"===o?i[o].push(s(n)):i[o].push(n)}return i}var n=new function(e){var i=function(e){if(!e[0])return void postMessage({error:"Something went wrong. Maybe WebP format is not supported in the current browser."});for(var t=e[0].width,i=e[0].height,o=e[0].duration,r=1;r<e.length;r++)o+=e[r].duration;return{duration:o,width:t,height:i}}(e);if(!i)return[];for(var o,A=[{id:440786851,data:[{data:1,id:17030},{data:1,id:17143},{data:4,id:17138},{data:8,id:17139},{data:"webm",id:17026},{data:2,id:17031},{data:2,id:17029}]},{id:408125543,data:[{id:357149030,data:[{data:1e6,id:2807729},{data:"whammy",id:19840},{data:"whammy",id:22337},{data:(o=i.duration,[].slice.call(new Uint8Array(new Float64Array([o]).buffer),0).map((function(e){return String.fromCharCode(e)})).reverse().join("")),id:17545}]},{id:374648427,data:[{id:174,data:[{data:1,id:215},{data:1,id:29637},{data:0,id:156},{data:"und",id:2274716},{data:"V_VP8",id:134},{data:"VP8",id:2459272},{data:1,id:131},{id:224,data:[{data:i.width,id:176},{data:i.height,id:186}]}]}]}]}],s=0,n=0;s<e.length;){var a=[],d=0;do{a.push(e[s]),d+=e[s].duration,s++}while(s<e.length&&d<3e4);var c={id:524531317,data:t(n,0,a)};A[1].data.push(c),n+=d}return r(A)}(e.map((function(e){var t=function(e){for(var t=e.RIFF[0].WEBP[0],i=t.indexOf("*"),o=0,r=[];o<4;o++)r[o]=t.charCodeAt(i+3+o);return{width:16383&(r[1]<<8|r[0]),height:16383&(r[3]<<8|r[2]),data:t,riff:e}}(s(atob(e.image.slice(23))));return t.duration=e.duration,t})));postMessage(n)}return e.prototype.add=function(e,t){if("canvas"in e&&(e=e.canvas),"toDataURL"in e&&(e=e.toDataURL("image/webp",this.quality)),!/^data:image\/webp;base64,/gi.test(e))throw"Input must be formatted properly as a base64 encoded DataURI of type image/webp";this.frames.push({image:e,duration:t||this.duration})},e.prototype.compile=function(e){var i,o,r,A=(i=t,o=l.createObjectURL(new Blob([i.toString(),"this.onmessage = function (eee) {"+i.name+"(eee.data);}"],{type:"application/javascript"})),r=new Worker(o),l.revokeObjectURL(o),r);A.onmessage=function(t){t.data.error?console.error(t.data.error):e(t.data)},A.postMessage(this.frames)},{Video:e}}();i.Whammy=I;var x={init:function(){var e=this;if("undefined"!=typeof indexedDB&&void 0!==indexedDB.open){var t,i=this.dbName||location.href.replace(/\/|:|#|%|\.|\[|\]/g,""),o=indexedDB.open(i,1);o.onerror=e.onError,o.onsuccess=function(){((t=o.result).onerror=e.onError,t.setVersion)?1!==t.version?t.setVersion(1).onsuccess=function(){r(t),A()}:A():A()},o.onupgradeneeded=function(e){r(e.target.result)}}else console.error("IndexedDB API are not available in this browser.");function r(t){t.createObjectStore(e.dataStoreName)}function A(){var i=t.transaction([e.dataStoreName],"readwrite");function o(t){i.objectStore(e.dataStoreName).get(t).onsuccess=function(i){e.callback&&e.callback(i.target.result,t)}}e.videoBlob&&i.objectStore(e.dataStoreName).put(e.videoBlob,"videoBlob"),e.gifBlob&&i.objectStore(e.dataStoreName).put(e.gifBlob,"gifBlob"),e.audioBlob&&i.objectStore(e.dataStoreName).put(e.audioBlob,"audioBlob"),o("audioBlob"),o("videoBlob"),o("gifBlob")}},Fetch:function(e){return this.callback=e,this.init(),this},Store:function(e){return this.audioBlob=e.audioBlob,this.videoBlob=e.videoBlob,this.gifBlob=e.gifBlob,this.init(),this},onError:function(e){console.error(JSON.stringify(e,null,"\t"))},dataStoreName:"recordRTC",dbName:null};function D(e,t){if("undefined"==typeof GIFEncoder){var i=document.createElement("script");i.src="https://www.webrtc-experiment.com/gif-recorder.js",(document.body||document.documentElement).appendChild(i)}t=t||{};var o=e instanceof CanvasRenderingContext2D||e instanceof HTMLCanvasElement;this.record=function(){"undefined"!=typeof GIFEncoder&&a?(o||(t.width||(t.width=c.offsetWidth||320),t.height||(t.height=c.offsetHeight||240),t.video||(t.video={width:t.width,height:t.height}),t.canvas||(t.canvas={width:t.width,height:t.height}),A.width=t.canvas.width||320,A.height=t.canvas.height||240,c.width=t.video.width||320,c.height=t.video.height||240),(u=new GIFEncoder).setRepeat(0),u.setDelay(t.frameRate||200),u.setQuality(t.quality||10),u.start(),"function"==typeof t.onGifRecordingStarted&&t.onGifRecordingStarted(),h=n((function e(i){if(!0!==p.clearedRecordedData){if(r)return setTimeout((function(){e(i)}),100);h=n(e),void 0===typeof l&&(l=i),i-l<90||(!o&&c.paused&&c.play(),o||s.drawImage(c,0,0,A.width,A.height),t.onGifPreview&&t.onGifPreview(A.toDataURL("image/png")),u.addFrame(s),l=i)}})),t.initCallback&&t.initCallback()):setTimeout(p.record,1e3)},this.stop=function(e){e=e||function(){},h&&d(h),this.blob=new Blob([new Uint8Array(u.stream().bin)],{type:"image/gif"}),e(this.blob),u.stream().bin=[]};var r=!1;this.pause=function(){r=!0},this.resume=function(){r=!1},this.clearRecordedData=function(){p.clearedRecordedData=!0,u&&(u.stream().bin=[])},this.name="GifRecorder",this.toString=function(){return this.name};var A=document.createElement("canvas"),s=A.getContext("2d");o&&(e instanceof CanvasRenderingContext2D?A=(s=e).canvas:e instanceof HTMLCanvasElement&&(s=e.getContext("2d"),A=e));var a=!0;if(!o){var c=document.createElement("video");c.muted=!0,c.autoplay=!0,c.playsInline=!0,a=!1,c.onloadedmetadata=function(){a=!0},S(e,c),c.play()}var l,u,h=null,p=this}function j(e,t){t=t||"multi-streams-mixer";var i=[],o=!1,r=document.createElement("canvas"),A=r.getContext("2d");r.style.opacity=0,r.style.position="absolute",r.style.zIndex=-1,r.style.top="-1000em",r.style.left="-1000em",r.className=t,(document.body||document.documentElement).appendChild(r),this.disableLogs=!1,this.frameInterval=10,this.width=360,this.height=240,this.useGainNode=!0;var s=this,n=window.AudioContext;void 0===n&&("undefined"!=typeof webkitAudioContext&&(n=webkitAudioContext),"undefined"!=typeof mozAudioContext&&(n=mozAudioContext));var a=window.URL;void 0===a&&"undefined"!=typeof webkitURL&&(a=webkitURL),"undefined"!=typeof navigator&&void 0===navigator.getUserMedia&&(void 0!==navigator.webkitGetUserMedia&&(navigator.getUserMedia=navigator.webkitGetUserMedia),void 0!==navigator.mozGetUserMedia&&(navigator.getUserMedia=navigator.mozGetUserMedia));var d=window.MediaStream;void 0===d&&"undefined"!=typeof webkitMediaStream&&(d=webkitMediaStream),void 0!==d&&void 0===d.prototype.stop&&(d.prototype.stop=function(){this.getTracks().forEach((function(e){e.stop()}))});var c={};function l(){if(!o){var e=i.length,t=!1,A=[];if(i.forEach((function(e){e.stream||(e.stream={}),e.stream.fullcanvas?t=e:A.push(e)})),t)r.width=t.stream.width,r.height=t.stream.height;else if(A.length){r.width=e>1?2*A[0].width:A[0].width;var n=1;3!==e&&4!==e||(n=2),5!==e&&6!==e||(n=3),7!==e&&8!==e||(n=4),9!==e&&10!==e||(n=5),r.height=A[0].height*n}else r.width=s.width||360,r.height=s.height||240;t&&t instanceof HTMLVideoElement&&u(t),A.forEach((function(e,t){u(e,t)})),setTimeout(l,s.frameInterval)}}function u(e,t){if(!o){var i=0,r=0,s=e.width,n=e.height;1===t&&(i=e.width),2===t&&(r=e.height),3===t&&(i=e.width,r=e.height),4===t&&(r=2*e.height),5===t&&(i=e.width,r=2*e.height),6===t&&(r=3*e.height),7===t&&(i=e.width,r=3*e.height),void 0!==e.stream.left&&(i=e.stream.left),void 0!==e.stream.top&&(r=e.stream.top),void 0!==e.stream.width&&(s=e.stream.width),void 0!==e.stream.height&&(n=e.stream.height),A.drawImage(e,i,r,s,n),"function"==typeof e.stream.onRender&&e.stream.onRender(A,i,r,s,n,t)}}function h(e){var i=document.createElement("video");return function(e,t){"srcObject"in t?t.srcObject=e:"mozSrcObject"in t?t.mozSrcObject=e:t.srcObject=e}(e,i),i.className=t,i.muted=!0,i.volume=0,i.width=e.width||s.width||360,i.height=e.height||s.height||240,i.play(),i}function p(t){i=[],(t=t||e).forEach((function(e){if(e.getTracks().filter((function(e){return"video"===e.kind})).length){var t=h(e);t.stream=e,i.push(t)}}))}void 0!==n?c.AudioContext=n:"undefined"!=typeof webkitAudioContext&&(c.AudioContext=webkitAudioContext),this.startDrawingFrames=function(){l()},this.appendStreams=function(t){if(!t)throw"First parameter is required.";t instanceof Array||(t=[t]),t.forEach((function(t){var o=new d;if(t.getTracks().filter((function(e){return"video"===e.kind})).length){var r=h(t);r.stream=t,i.push(r),o.addTrack(t.getTracks().filter((function(e){return"video"===e.kind}))[0])}if(t.getTracks().filter((function(e){return"audio"===e.kind})).length){var A=s.audioContext.createMediaStreamSource(t);s.audioDestination=s.audioContext.createMediaStreamDestination(),A.connect(s.audioDestination),o.addTrack(s.audioDestination.stream.getTracks().filter((function(e){return"audio"===e.kind}))[0])}e.push(o)}))},this.releaseStreams=function(){i=[],o=!0,s.gainNode&&(s.gainNode.disconnect(),s.gainNode=null),s.audioSources.length&&(s.audioSources.forEach((function(e){e.disconnect()})),s.audioSources=[]),s.audioDestination&&(s.audioDestination.disconnect(),s.audioDestination=null),s.audioContext&&s.audioContext.close(),s.audioContext=null,A.clearRect(0,0,r.width,r.height),r.stream&&(r.stream.stop(),r.stream=null)},this.resetVideoStreams=function(e){!e||e instanceof Array||(e=[e]),p(e)},this.name="MultiStreamsMixer",this.toString=function(){return this.name},this.getMixedStream=function(){o=!1;var t=function(){var e;p(),"captureStream"in r?e=r.captureStream():"mozCaptureStream"in r?e=r.mozCaptureStream():s.disableLogs||console.error("Upgrade to latest Chrome or otherwise enable this flag: chrome://flags/#enable-experimental-web-platform-features");var t=new d;return e.getTracks().filter((function(e){return"video"===e.kind})).forEach((function(e){t.addTrack(e)})),r.stream=t,t}(),i=function(){c.AudioContextConstructor||(c.AudioContextConstructor=new c.AudioContext);s.audioContext=c.AudioContextConstructor,s.audioSources=[],!0===s.useGainNode&&(s.gainNode=s.audioContext.createGain(),s.gainNode.connect(s.audioContext.destination),s.gainNode.gain.value=0);var t=0;if(e.forEach((function(e){if(e.getTracks().filter((function(e){return"audio"===e.kind})).length){t++;var i=s.audioContext.createMediaStreamSource(e);!0===s.useGainNode&&i.connect(s.gainNode),s.audioSources.push(i)}})),!t)return;return s.audioDestination=s.audioContext.createMediaStreamDestination(),s.audioSources.forEach((function(e){e.connect(s.audioDestination)})),s.audioDestination.stream}();return i&&i.getTracks().filter((function(e){return"audio"===e.kind})).forEach((function(e){t.addTrack(e)})),e.forEach((function(e){e.fullcanvas})),t}}function L(e,t){e=e||[];var i,o,r=this;(t=t||{elementClass:"multi-streams-mixer",mimeType:"video/webm",video:{width:360,height:240}}).frameInterval||(t.frameInterval=10),t.video||(t.video={}),t.video.width||(t.video.width=360),t.video.height||(t.video.height=240),this.record=function(){var r;i=new j(e,t.elementClass||"multi-streams-mixer"),(r=[],e.forEach((function(e){w(e,"video").forEach((function(e){r.push(e)}))})),r).length&&(i.frameInterval=t.frameInterval||10,i.width=t.video.width||360,i.height=t.video.height||240,i.startDrawingFrames()),t.previewStream&&"function"==typeof t.previewStream&&t.previewStream(i.getMixedStream()),(o=new C(i.getMixedStream(),t)).record()},this.stop=function(e){o&&o.stop((function(t){r.blob=t,e(t),r.clearRecordedData()}))},this.pause=function(){o&&o.pause()},this.resume=function(){o&&o.resume()},this.clearRecordedData=function(){o&&(o.clearRecordedData(),o=null),i&&(i.releaseStreams(),i=null)},this.addStreams=function(r){if(!r)throw"First parameter is required.";r instanceof Array||(r=[r]),e.concat(r),o&&i&&(i.appendStreams(r),t.previewStream&&"function"==typeof t.previewStream&&t.previewStream(i.getMixedStream()))},this.resetVideoStreams=function(e){i&&(!e||e instanceof Array||(e=[e]),i.resetVideoStreams(e))},this.getMixer=function(){return i},this.name="MultiStreamRecorder",this.toString=function(){return this.name}}function U(e,t){var i,o,r;function A(){return new ReadableStream({start:function(o){var r=document.createElement("canvas"),A=document.createElement("video"),s=!0;A.srcObject=e,A.muted=!0,A.height=t.height,A.width=t.width,A.volume=0,A.onplaying=function(){r.width=t.width,r.height=t.height;var e=r.getContext("2d"),n=1e3/t.frameRate,a=setInterval((function(){if(i&&(clearInterval(a),o.close()),s&&(s=!1,t.onVideoProcessStarted&&t.onVideoProcessStarted()),e.drawImage(A,0,0),"closed"!==o._controlledReadableStream.state)try{o.enqueue(e.getImageData(0,0,t.width,t.height))}catch(e){}}),n)},A.play()}})}function s(e,a){if(!t.workerPath&&!a)return i=!1,void fetch("https://unpkg.com/webm-wasm@latest/dist/webm-worker.js").then((function(t){t.arrayBuffer().then((function(t){s(e,t)}))}));if(!t.workerPath&&a instanceof ArrayBuffer){var d=new Blob([a],{type:"text/javascript"});t.workerPath=l.createObjectURL(d)}t.workerPath||console.error("workerPath parameter is missing."),(o=new Worker(t.workerPath)).postMessage(t.webAssemblyPath||"https://unpkg.com/webm-wasm@latest/dist/webm-wasm.wasm"),o.addEventListener("message",(function(e){"READY"===e.data?(o.postMessage({width:t.width,height:t.height,bitrate:t.bitrate||1200,timebaseDen:t.frameRate||30,realtime:t.realtime}),A().pipeTo(new WritableStream({write:function(e){i?console.error("Got image, but recorder is finished!"):o.postMessage(e.data.buffer,[e.data.buffer])}}))):e.data&&(r||n.push(e.data))}))}"undefined"!=typeof ReadableStream&&"undefined"!=typeof WritableStream||console.error("Following polyfill is strongly recommended: https://unpkg.com/@mattiasbuelens/web-streams-polyfill/dist/polyfill.min.js"),(t=t||{}).width=t.width||640,t.height=t.height||480,t.frameRate=t.frameRate||30,t.bitrate=t.bitrate||1200,t.realtime=t.realtime||!0,this.record=function(){n=[],r=!1,this.blob=null,s(e),"function"==typeof t.initCallback&&t.initCallback()},this.pause=function(){r=!0},this.resume=function(){r=!1};var n=[];this.stop=function(e){i=!0;var t=this;!function(e){o?(o.addEventListener("message",(function(t){null===t.data&&(o.terminate(),o=null,e&&e())})),o.postMessage(null)):e&&e()}((function(){t.blob=new Blob(n,{type:"video/webm"}),e(t.blob)}))},this.name="WebAssemblyRecorder",this.toString=function(){return this.name},this.clearRecordedData=function(){n=[],r=!1,this.blob=null},this.blob=null}i.DiskStorage=x,i.GifRecorder=D,i.MultiStreamRecorder=L,i.RecordRTCPromisesHandler=function(e,t){if(!this)throw'Use "new RecordRTCPromisesHandler()"';if(void 0===e)throw'First argument "MediaStream" is required.';var o=this;o.recordRTC=new i(e,t),this.startRecording=function(){return new Promise((function(e,t){try{o.recordRTC.startRecording(),e()}catch(e){t(e)}}))},this.stopRecording=function(){return new Promise((function(e,t){try{o.recordRTC.stopRecording((function(i){o.blob=o.recordRTC.getBlob(),o.blob&&o.blob.size?e(i):t("Empty blob.",o.blob)}))}catch(e){t(e)}}))},this.pauseRecording=function(){return new Promise((function(e,t){try{o.recordRTC.pauseRecording(),e()}catch(e){t(e)}}))},this.resumeRecording=function(){return new Promise((function(e,t){try{o.recordRTC.resumeRecording(),e()}catch(e){t(e)}}))},this.getDataURL=function(e){return new Promise((function(e,t){try{o.recordRTC.getDataURL((function(t){e(t)}))}catch(e){t(e)}}))},this.getBlob=function(){return new Promise((function(e,t){try{e(o.recordRTC.getBlob())}catch(e){t(e)}}))},this.getInternalRecorder=function(){return new Promise((function(e,t){try{e(o.recordRTC.getInternalRecorder())}catch(e){t(e)}}))},this.reset=function(){return new Promise((function(e,t){try{e(o.recordRTC.reset())}catch(e){t(e)}}))},this.destroy=function(){return new Promise((function(e,t){try{e(o.recordRTC.destroy())}catch(e){t(e)}}))},this.getState=function(){return new Promise((function(e,t){try{e(o.recordRTC.getState())}catch(e){t(e)}}))},this.blob=null,this.version="5.6.2"},i.WebAssemblyRecorder=U}));class Fe extends Be{constructor(e){super(),this.player=e,this.fileName="",this.fileType=H,this.isRecording=!1,this.recordingTimestamp=0,this.recordingInterval=null,e.debug.log("Recorder","init")}destroy(){this._reset(),this.player.debug.log("Recorder","destroy")}setFileName(e,t){this.fileName=e,Y!==t&&H!==t||(this.fileType=t)}get recording(){return this.isRecording}get recordTime(){return this.recordingTimestamp}startRecord(){const e=this.player.debug,t={type:"video",mimeType:"video/webm;codecs=h264",onTimeStamp:t=>{e.log("Recorder","record timestamp :"+t)},disableLogs:!this.player._opt.debug};try{const e=this.player.video.$videoElement.captureStream(25);if(this.player.audio&&this.player.audio.mediaStreamAudioDestinationNode&&this.player.audio.mediaStreamAudioDestinationNode.stream&&!this.player.audio.isStateSuspended()&&this.player.audio.hasAudio&&this.player._opt.hasAudio){const t=this.player.audio.mediaStreamAudioDestinationNode.stream;if(t.getAudioTracks().length>0){const i=t.getAudioTracks()[0];i&&i.enabled&&e.addTrack(i)}}this.recorder=Ue(e,t)}catch(t){e.error("Recorder",t),this.emit(T.recordCreateError)}this.recorder&&(this.isRecording=!0,this.emit(T.recording,!0),this.recorder.startRecording(),e.log("Recorder","start recording"),this.player.emit(T.recordStart),this.recordingInterval=window.setInterval((()=>{this.recordingTimestamp+=1,this.player.emit(T.recordingTimestamp,this.recordingTimestamp)}),1e3))}stopRecordAndSave(){this.recorder&&this.isRecording&&this.recorder.stopRecording((()=>{this.player.debug.log("Recorder","stop recording"),this.player.emit(T.recordEnd),function(e,t,i){const o=window.URL.createObjectURL(e),r=document.createElement("a");r.href=o,r.download=(t||he())+"."+(i||H),r.click(),setTimeout((()=>{window.URL.revokeObjectURL(o)}),ve()?1e3:0)}(this.recorder.getBlob(),this.fileName,this.fileType),this._reset(),this.emit(T.recording,!1)}))}_reset(){this.isRecording=!1,this.recordingTimestamp=0,this.recorder&&(this.recorder.destroy(),this.recorder=null),this.fileName=null,this.recordingInterval&&clearInterval(this.recordingInterval),this.recordingInterval=null}}class Ve{constructor(e){return new(Ve.getLoaderFactory())(e)}static getLoaderFactory(){return Fe}}class Oe{constructor(e){this.player=e,this.decoderWorker=new Worker(e._opt.decoder),this._initDecoderWorker(),e.debug.log("decoderWorker","init")}destroy(){this.decoderWorker.postMessage({cmd:R}),this.decoderWorker.terminate(),this.decoderWorker=null,this.player.debug.log("decoderWorker","destroy")}_initDecoderWorker(){const{debug:e,events:{proxy:t}}=this.player;this.decoderWorker.onmessage=t=>{const i=t.data;switch(i.cmd){case c:e.log("decoderWorker","onmessage:",c),this.player.loaded||this.player.emit(T.load),this.player.emit(T.decoderWorkerInit),this._initWork();break;case g:e.log("decoderWorker","onmessage:",g,i.code),this.player._times.decodeStart||(this.player._times.decodeStart=he()),this.player.video.updateVideoInfo({encTypeCode:i.code});break;case m:e.log("decoderWorker","onmessage:",m,i.code),this.player.audio&&this.player.audio.updateAudioInfo({encTypeCode:i.code});break;case l:e.log("decoderWorker","onmessage:",l,`width:${i.w},height:${i.h}`),this.player.video.updateVideoInfo({width:i.w,height:i.h}),this.player.video.initCanvasViewSize();break;case p:e.log("decoderWorker","onmessage:",p,`channels:${i.channels},sampleRate:${i.sampleRate}`),this.player.audio&&(this.player.audio.updateAudioInfo(i),this.player.audio.initScriptNode(i));break;case u:this.player.handleRender(),this.player.video.render(i),this.player.emit(T.timeUpdate,i.ts),this.player.updateStats({fps:!0,ts:i.ts,buf:i.delay}),this.player._times.videoStart||(this.player._times.videoStart=he(),this.player.handlePlayToRenderTimes());break;case h:this.player.playing&&this.player.audio&&this.player.audio.play(i.buffer,i.ts);break;case f:i.message&&-1!==i.message.indexOf(b)&&(this.player.emit(T.error,x.wasmDecodeError),this.player.emit(x.wasmDecodeError));break;default:this.player[i.cmd]&&this.player[i.cmd](i)}}}_initWork(){const e={debug:this.player._opt.debug,forceNoOffscreen:this.player._opt.forceNoOffscreen,useWCS:this.player._opt.useWCS,videoBuffer:this.player._opt.videoBuffer,openWebglAlignment:this.player._opt.openWebglAlignment};this.decoderWorker.postMessage({cmd:E,opt:JSON.stringify(e),sampleRate:this.player.audio&&this.player.audio.audioContext.sampleRate||0})}decodeVideo(e,t,i){const o={type:v,ts:Math.max(t,0),isIFrame:i};this.decoderWorker.postMessage({cmd:B,buffer:e,options:o},[e.buffer])}decodeAudio(e,t){this.player._opt.useWCS&&!this.player._opt.useOffscreen||this.player._opt.useMSE?this._decodeAudioNoDelay(e,t):this._decodeAudio(e,t)}_decodeAudio(e,t){const i={type:y,ts:Math.max(t,0)};this.decoderWorker.postMessage({cmd:B,buffer:e,options:i},[e.buffer])}_decodeAudioNoDelay(e,t){this.decoderWorker.postMessage({cmd:C,buffer:e,ts:Math.max(t,0)},[e.buffer])}updateWorkConfig(e){this.decoderWorker.postMessage({cmd:k,key:e.key,value:e.value})}}class Me extends Be{constructor(e){super(),this.player=e,this.stopId=null,this.firstTimestamp=null,this.startTimestamp=null,this.delay=-1,this.bufferList=[],this.dropping=!1,this.initInterval()}destroy(){this.stopId&&(clearInterval(this.stopId),this.stopId=null),this.firstTimestamp=null,this.startTimestamp=null,this.delay=-1,this.bufferList=[],this.dropping=!1,this.off()}getDelay(e){return e?(this.firstTimestamp?e&&(this.delay=Date.now()-this.startTimestamp-(e-this.firstTimestamp)):(this.firstTimestamp=e,this.startTimestamp=Date.now(),this.delay=-1),this.delay):-1}resetDelay(){this.firstTimestamp=null,this.startTimestamp=null,this.delay=-1,this.dropping=!1}initInterval(){this.player.debug.log("common dumex","init Interval");let e=()=>{let e;const t=this.player._opt.videoBuffer;if(this.bufferList.length)if(this.dropping){for(e=this.bufferList.shift(),e.type===y&&0===e.payload[1]&&this._doDecoderDecode(e);!e.isIFrame&&this.bufferList.length;)e=this.bufferList.shift(),e.type===y&&0===e.payload[1]&&this._doDecoderDecode(e);e.isIFrame&&(this.dropping=!1,this._doDecoderDecode(e))}else if(e=this.bufferList[0],-1===this.getDelay(e.ts))this.bufferList.shift(),this._doDecoderDecode(e);else if(this.delay>t+1e3)this.resetDelay(),this.dropping=!0;else for(;this.bufferList.length&&(e=this.bufferList[0],this.getDelay(e.ts)>t);)this.bufferList.shift(),this._doDecoderDecode(e)};e(),this.stopId=setInterval(e,10)}_doDecode(e,t,i,o){const r=this.player;let A={ts:i,type:t,isIFrame:!1};r._opt.useWCS&&!r._opt.useOffscreen||r._opt.useMSE?(t===v&&(A.isIFrame=o),this.pushBuffer(e,A)):t===v?r.decoderWorker&&r.decoderWorker.decodeVideo(e,i,o):t===y&&r._opt.hasAudio&&r.decoderWorker&&r.decoderWorker.decodeAudio(e,i)}_doDecoderDecode(e){const t=this.player,{webcodecsDecoder:i,mseDecoder:o}=t;e.type===y?t._opt.hasAudio&&t.decoderWorker&&t.decoderWorker.decodeAudio(e.payload,e.ts):e.type===v&&(t._opt.useWCS&&!t._opt.useOffscreen?i.decodeVideo(e.payload,e.ts,e.isIFrame):t._opt.useMSE&&o.decodeVideo(e.payload,e.ts,e.isIFrame))}pushBuffer(e,t){t.type===y?this.bufferList.push({ts:t.ts,payload:e,type:y}):t.type===v&&this.bufferList.push({ts:t.ts,payload:e,type:v,isIFrame:t.isIFrame})}close(){}}class Qe extends Me{constructor(e){super(e),this.input=this._inputFlv(),this.flvDemux=this.dispatchFlvData(this.input),e.debug.log("FlvDemux","init")}destroy(){super.destroy(),this.input=null,this.flvDemux=null,this.player.debug.log("FlvDemux","destroy")}dispatch(e){this.flvDemux(e)}*_inputFlv(){yield 9;const e=new ArrayBuffer(4),t=new Uint8Array(e),i=new Uint32Array(e),o=this.player;for(;;){t[3]=0;const e=yield 15,r=e[4];t[0]=e[7],t[1]=e[6],t[2]=e[5];const A=i[0];t[0]=e[10],t[1]=e[9],t[2]=e[8];let s=i[0];16777215===s&&(t[3]=e[11],s=i[0]);const n=yield A;switch(r){case w:o._opt.hasAudio&&(o.updateStats({abps:n.byteLength}),n.byteLength>0&&this._doDecode(n,y,s));break;case S:if(o._times.demuxStart||(o._times.demuxStart=he()),o._opt.hasVideo){o.updateStats({vbps:n.byteLength});const e=n[0]>>4==1;n.byteLength>0&&this._doDecode(n,v,s,e)}}}}dispatchFlvData(e){let t=e.next(),i=null;return o=>{let r=new Uint8Array(o);if(i){let e=new Uint8Array(i.length+r.length);e.set(i),e.set(r,i.length),r=e,i=null}for(;r.length>=t.value;){let i=r.slice(t.value);t=e.next(r.slice(0,t.value)),r=i}r.length>0&&(i=r)}}close(){this.input&&this.input.return(null)}}class We extends Me{constructor(e){super(e),e.debug.log("M7sDemux","init")}destroy(){super.destroy(),this.player.debug.log("M7sDemux","destroy")}dispatch(e){const t=this.player,i=new DataView(e),o=i.getUint8(0),r=i.getUint32(1,!1);switch(o){case y:if(t._opt.hasAudio){const i=new Uint8Array(e,5);t.updateStats({abps:i.byteLength}),i.byteLength>0&&this._doDecode(i,o,r)}break;case v:if(t._opt.hasVideo&&(t._times.demuxStart||(t._times.demuxStart=he()),i.byteLength>5)){const A=new Uint8Array(e,5),s=i.getUint8(5)>>4==1;t.updateStats({vbps:A.byteLength}),A.byteLength>0&&this._doDecode(A,o,r,s)}}}}class Ge{constructor(e){return new(Ge.getLoaderFactory(e._opt.demuxType))(e)}static getLoaderFactory(e){return e===a?We:e===n?Qe:void 0}}class Je extends Be{constructor(e){super(),this.player=e,this.hasInit=!1,this.isInitInfo=!1,this.decoder=null,this.initDecoder(),e.debug.log("Webcodecs","init")}destroy(){this.decoder&&(this.decoder.close(),this.decoder=null),this.hasInit=!1,this.isInitInfo=!1,this.off(),this.player.debug.log("Webcodecs","destroy")}initDecoder(){const e=this;this.decoder=new VideoDecoder({output(t){e.handleDecode(t)},error(t){e.handleError(t)}})}handleDecode(e){this.isInitInfo||(this.player.video.updateVideoInfo({width:e.codedWidth,height:e.codedHeight}),this.player.video.initCanvasViewSize(),this.isInitInfo=!0),this.player._times.videoStart||(this.player._times.videoStart=he(),this.player.handlePlayToRenderTimes()),this.player.handleRender(),this.player.video.render({videoFrame:e}),this.player.updateStats({fps:!0,ts:0,buf:this.player.demux.delay}),setTimeout((function(){e.close?e.close():e.destroy()}),100)}handleError(e){this.player.debug.log("Webcodecs","VideoDecoder handleError",e)}decodeVideo(e,t,i){if(this.hasInit){const o=new EncodedVideoChunk({data:e.slice(5),timestamp:t,type:i?K:_});this.decoder.decode(o)}else if(i&&0===e[1]){const t=15&e[0];if(this.player.video.updateVideoInfo({encTypeCode:t}),t===M)return void this.emit(x.webcodecsH265NotSupport);this.player._times.decodeStart||(this.player._times.decodeStart=he());const i=function(e){let t=e.subarray(1,4),i="avc1.";for(let e=0;e<3;e++){let o=t[e].toString(16);o.length<2&&(o="0"+o),i+=o}return{codec:i,description:e}}(e.slice(5));this.decoder.configure(i),this.hasInit=!0}}}const Ne={play:"播放",pause:"暂停",audio:"",mute:"",screenshot:"截图",loading:"加载",fullscreen:"全屏",fullscreenExit:"退出全屏",record:"录制",recordStop:"停止录制"};var Pe=Object.keys(Ne).reduce(((e,t)=>(e[t]=`\n <i class="jessibuca-icon jessibuca-icon-${t}"></i>\n ${Ne[t]?`<span class="icon-title-tips"><span class="icon-title">${Ne[t]}</span></span>`:""}\n`,e)),{}),ze=(e,t)=>{const{events:{proxy:i}}=e,o=document.createElement("object");o.setAttribute("aria-hidden","true"),o.setAttribute("tabindex",-1),o.type="text/html",o.data="about:blank",me(o,{display:"block",position:"absolute",top:"0",left:"0",height:"100%",width:"100%",overflow:"hidden",pointerEvents:"none",zIndex:"-1"});let r=e.width,A=e.height;i(o,"load",(()=>{i(o.contentDocument.defaultView,"resize",(()=>{e.width===r&&e.height===A||(r=e.width,A=e.height,e.emit(T.resize))}))})),e.$container.appendChild(o),e.on(T.destroy,(()=>{e.$container.removeChild(o)})),e.on(T.volumechange,(()=>{!function(e){if(0===e)me(t.$volumeOn,"display","none"),me(t.$volumeOff,"display","flex"),me(t.$volumeHandle,"top","48px");else if(t.$volumeHandle&&t.$volumePanel){const i=ge(t.$volumePanel,"height")||60,o=ge(t.$volumeHandle,"height"),r=i-(i-o)*e-o;me(t.$volumeHandle,"top",`${r}px`),me(t.$volumeOn,"display","flex"),me(t.$volumeOff,"display","none")}t.$volumePanelText&&(t.$volumePanelText.innerHTML=parseInt(100*e))}(e.volume)})),e.on(T.loading,(e=>{me(t.$loading,"display",e?"flex":"none"),me(t.$poster,"display","none"),e&&me(t.$playBig,"display","none")}));const s=i=>{let o=!0===(r=i)||!1===r?i:e.fullscreen;var r;me(t.$fullscreenExit,"display",o?"flex":"none"),me(t.$fullscreen,"display",o?"none":"flex")};try{de.on("change",s),e.events.destroys.push((()=>{de.off("change",s)}))}catch(e){}e.on(T.webFullscreen,(e=>{s(e)})),e.on(T.recording,(()=>{me(t.$record,"display",e.recording?"none":"flex"),me(t.$recordStop,"display",e.recording?"flex":"none")})),e.on(T.recordingTimestamp,(e=>{})),e.on(T.playing,(e=>{me(t.$play,"display",e?"none":"flex"),me(t.$playBig,"display",e?"none":"block"),me(t.$pause,"display",e?"flex":"none"),me(t.$screenshot,"display",e?"flex":"none"),me(t.$record,"display",e?"flex":"none"),me(t.$fullscreen,"display",e?"flex":"none"),e||t.$speed&&(t.$speed.innerHTML=we(""))})),e.on(T.kBps,(e=>{const i=we(e);t.$speed&&(t.$speed.innerHTML=i)}))};function Ye(e,t){void 0===t&&(t={});var i=t.insertAt;if(e&&"undefined"!=typeof document){var o=document.head||document.getElementsByTagName("head")[0],r=document.createElement("style");r.type="text/css","top"===i&&o.firstChild?o.insertBefore(r,o.firstChild):o.appendChild(r),r.styleSheet?r.styleSheet.cssText=e:r.appendChild(document.createTextNode(e))}}Ye('@keyframes rotation{0%{-webkit-transform:rotate(0deg)}to{-webkit-transform:rotate(1turn)}}.jessibuca-container .jessibuca-icon{cursor:pointer;width:16px;height:16px}.jessibuca-container .jessibuca-poster{position:absolute;z-index:10;left:0;top:0;right:0;bottom:0;height:100%;width:100%;background-position:50%;background-repeat:no-repeat;background-size:contain;pointer-events:none}.jessibuca-container .jessibuca-play-big{position:absolute;display:none;height:100%;width:100%;background:rgba(0,0,0,.4)}.jessibuca-container .jessibuca-play-big:after{cursor:pointer;content:"";position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);display:block;width:48px;height:48px;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAACgklEQVRoQ+3ZPYsTQRjA8eeZZCFlWttAwCIkZOaZJt8hlvkeHrlccuAFT6wEG0FQOeQQLCIWih6chQgKgkkKIyqKCVYip54IWmiQkTmyYhFvd3Zn3yDb7szu/7cv7GaDkPEFM94PK0DSZ9DzDAyHw7uI2HRDlVJX5/N5r9FoHCYdr/fvCRiNRmpJ6AEidoUQ15NG+AH8BgD2n9AHANAmohdJQfwAfgGA4xF4bjabnW21Whob62ILoKNfAsAGEd2PU2ATcNSNiDf0/cE5/xAHxDpgEf0NADaJ6HLUiKgAbvcjpdSGlPJZVJCoAUfdSqkLxWLxTLlc/mkbEgtgET1TSnWklLdtIuIEuN23crlcp16vv7cBSQKgu38AwBYRXQyLSArg3hsjRDxNRE+CQhIF/BN9qVAobFYqle+mkLQAdLd+8K0T0U0TRJoAbvc9fVkJId75gaQRoLv1C2STiPTb7rFLWgE6+g0RncwyYEJEtawCvjDGmpzzp5kD6NfxfD7frtVqB17xen2a7oG3ALBm+oMoFQBEPD+dTvtBfpImDXjIGFvjnD/3c7ksG5MU4HDxWeZa0HB3XhKAXcdxOn5vUi9gnIDXSqm2lHLPK8pkfVyAbSLqm4T5HRs1YB8RO0KIid8g03FRAT4rpbpSyh3TINPxUQB2GGM9zvkn05gg420CJovLZT9ISNA5tgB9ItoOGhFmnh/AcZ/X9xhj65zzV2Eiwsz1A1j2B8dHAOgS0W6YnduY6wkYj8d3lFKn/j66Ea84jtOrVqtfbQSE3YYnYDAY5Eql0hYAnNDv6kKIx2F3anO+J8DmzqLY1goQxVE12ebqDJgcrSjGrs5AFEfVZJt/AF0m+jHzUTtnAAAAAElFTkSuQmCC");background-repeat:no-repeat;background-position:50%}.jessibuca-container .jessibuca-play-big:hover:after{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAACEElEQVRoQ+2ZXStEQRjH/3/yIXwDdz7J+i7kvdisXCk3SiFJW27kglBcSFFKbqwQSa4krykuKB09Naf2Yndn5jgzc06d53Znd36/mWfeniVyHsw5PwqB0DOonYEoijYBlOpAFwCMkHwLDS/9mwhEDUCfAAyTXA4tYSLwC6CtCegegH6S56FETAR+AHRoACcBTJAUWa+RloBAXwAYIrnt0yBNgZi7qtbHgw8RFwLC/QFglOScawlXAjH3gUqrE1cirgVi7mkAYyS/0xbxJSDcdwAGSa6nKeFTIOZeUyL3aYiEEBDuLwDjJGf+KxFKIOY+BdBL8iipSGiBmHtWbbuftiJZERBuOfgGSK7aSGRJIObeUml1ayKSRQHhlgtkiaTcdltGVgUE+ppkV54FaiS78yrwqlLoOI8Cch2XV548W7WRpTVwA6DP9kGUFYEpAOUkT9LQAvtq1M+0udKkQSgBqSlJWWYxKXj8vRACK+o6bbRIdYI+Ba7U7rKjg7L53JdAhWTZBsy0rWuBXZUuNVMg23auBF7UIl2yBbJt70JAoKV6/WwLk6R9mgKSJlJ1kLTxFmkJyCla8UZd15GJQKvyumyJ8gy8DAEvfZoINPqD41EtUjmUgoaJwAaAnjrKebVI34OSq85NBNqlCAWgE0CV5GEWwI3vQlmCbcSinYFCwPEIFDPgeIC1P1/MgHaIHDf4Aydx2TF7wnKeAAAAAElFTkSuQmCC")}.jessibuca-container .jessibuca-loading{display:none;flex-direction:column;justify-content:center;align-items:center;position:absolute;z-index:20;left:0;top:0;right:0;bottom:0;width:100%;height:100%;pointer-events:none}.jessibuca-container .jessibuca-loading-text{line-height:20px;font-size:13px;color:#fff;margin-top:10px}.jessibuca-container .jessibuca-controls{background-color:#161616;box-sizing:border-box;display:flex;flex-direction:column;justify-content:flex-end;position:absolute;z-index:40;left:0;right:0;bottom:0;height:38px;padding-left:13px;padding-right:13px;font-size:14px;color:#fff;opacity:0;visibility:hidden;transition:all .2s ease-in-out;-webkit-user-select:none;user-select:none;transition:width .5s ease-in}.jessibuca-container .jessibuca-controls .jessibuca-controls-item{position:relative;display:flex;justify-content:center;padding:0 8px}.jessibuca-container .jessibuca-controls .jessibuca-controls-item:hover .icon-title-tips{visibility:visible;opacity:1}.jessibuca-container .jessibuca-controls .jessibuca-fullscreen,.jessibuca-container .jessibuca-controls .jessibuca-fullscreen-exit,.jessibuca-container .jessibuca-controls .jessibuca-icon-audio,.jessibuca-container .jessibuca-controls .jessibuca-microphone-close,.jessibuca-container .jessibuca-controls .jessibuca-pause,.jessibuca-container .jessibuca-controls .jessibuca-play,.jessibuca-container .jessibuca-controls .jessibuca-record,.jessibuca-container .jessibuca-controls .jessibuca-record-stop,.jessibuca-container .jessibuca-controls .jessibuca-screenshot{display:none}.jessibuca-container .jessibuca-controls .jessibuca-icon-audio,.jessibuca-container .jessibuca-controls .jessibuca-icon-mute{z-index:1}.jessibuca-container .jessibuca-controls .jessibuca-controls-bottom{display:flex;justify-content:space-between;height:100%}.jessibuca-container .jessibuca-controls .jessibuca-controls-bottom .jessibuca-controls-left,.jessibuca-container .jessibuca-controls .jessibuca-controls-bottom .jessibuca-controls-right{display:flex;align-items:center}.jessibuca-container.jessibuca-controls-show .jessibuca-controls{opacity:1;visibility:visible}.jessibuca-container.jessibuca-controls-show-auto-hide .jessibuca-controls{opacity:.8;visibility:visible;display:none}.jessibuca-container.jessibuca-hide-cursor *{cursor:none!important}.jessibuca-container .jessibuca-icon-loading{width:50px;height:50px;background:url("data:image/png;base64,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") no-repeat 50%;background-size:100% 100%;animation:rotation 1s linear infinite}.jessibuca-container .jessibuca-icon-screenshot{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAE5UlEQVRoQ+1YW2sdVRT+1s7JxbsoVkEUrIIX0ouz15zYNA+N1RdtQfCltlUfvLbqL/BCwZ8grbHtizQqPojgBSr0JkiMmT2nxgapqBURtPVCq7HxJCeZJVPmxDlzZubMmXOSEsnAvOy917fXt9e39tp7E5b4R0vcfywTuNgRbBgBx3HuJqLVzPzmYjprjHkcwAlmLqXNm4XAISLaSESPaq2HF4OE67rbRGRYRA7btn1fbgLGmKsA/Azg0gBkGzO/vZAkHMd5hIiqc5wHcCMz/5k0Z2oExsfHV1QqldPAf8lORNu11m8tBAljzFYAYWxRSl1vWdZvuQj4RsYYF4AVBlgIOVVlE55HRIxt23ZuCfmGjuOsJ6LPoiAistW27XfaEYmIbOYhPc9bXywWR1oiEJDYQkR1zrYjEjGyqfqbKd8a7kJVtLgQ+30i8pht2wfyRKIdmJkJBPkQTbILfudJ7CTZNBvVpggEcgpvc/ML38zESbLJsxBNE/A9biX0rdjGyTQXgbxyapdsarb0PMlXtWnGoXbKpm0Essqp3bJpK4E0OXmed3+hUBDP8w5FI91M0rdcyLLILElOCbaZilSWeXMncRx4klTCY1spfG3dhZJWx3GcDUR0EEB3ZMw0ET2gtT6SZWWzjmlrBIJCl0hAKfWgZVmHszqXZVxbCSxpCS2JJA6umIhe8ZKKVLPbaBJ+S9toqVRa53nedgAbAKwIwH4FcAzAa0R0l4i8F7PPz189k6RFRA+LyNcAXojDV0oNW5b1eW4Cxpg9AHZkSaaa6hhzb065uDSCH2LmRB8Sk9gY4293g43Qo/1pV80m8yQMfZSZ781cB1zXHRKRZ2IMpgD8A+DamL4ZItqitX4/jbQx5iEA7wLoihn3V/ACckWMJN/QWj9b1x5tGBsbW6uUOh5pPy0iL3Z2dn6ilJqanp5ep5TaJSLhF4NppdRNaU8gPmapVLrO87yfIoXuWyJ6uVKp+HmFjo6OQSJ6FcBtYT+UUmstyxqvkWuUgDFmP4AnQu2/e563qlgs+u9DNZ8xZhRAX7VRRPbath0XuXk7Y8xeAE+FgL6fnJzsHRwcLIfBR0ZGLunq6poAsDLUvp+Zw7b1r9PGmJMAbg8Z7WDmoThZuK67WkS+DD18fcPMdzSQUBR/EzN/nIC/SUQ+DPXV4dclsTHmHAD/SfHCNzc3t7Kvr++HJKeMMacA3BL0nyuXyzcPDAxMxo0fHR29slAo/Ajg6qD/fE9Pzw29vb1/x42fmJi4vFwu+5G/LOg/y8zXNJLQ2dAES5JANMQ7mfn1jBI6ycx3NiMhItqstf4oAX+ziHwQ6qvDj5NQNIn/ALCKmX+JSeIvABRD7fuY+ekGBPYBeDI05tTMzExvf3+/vz2Hk91/ET8RSeI6/DoCpVJpjed5fmKGvzMAXpqdnT3oed5Ud3d3v4jsAqBr9Ei0Rmv9VRqBBPzvROQVETnq2xJRdRu9tRF+bCVOKWT+Kvl/TSIFk6SW/LAjKfjV5K8rZABi8dOOEv7FI7Z8x6zwEWbemLbyMfJr5qiSiJ96oclymBOR3bZtP9+M89WxxpjdAHY2sN3DzM8ljWl4I3Nd9x7/OE1ENcdpETnmH3e11n41zv0l4J8RkU+J6AAz+xtF4teQQG7PFslwmcAiLfSyhC72Qv9/I/Avns2OT7QJskoAAAAASUVORK5CYII=") no-repeat 50%;background-size:100% 100%}.jessibuca-container .jessibuca-icon-screenshot:hover{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAED0lEQVRoQ+2ZycsdRRTFf2ejqHFAMQqiYBTUoElUHLNx3GgCgpuYRF2o0UT9CxwQ/BMkMSbZSKLiQgQHUDCJgjiAxiEiESdEcJbEedgcKaj3UV+/6q7u/jovPPkK3qbr1ql76p5bt6qemPKmKfefeQKHOoLFCNg+H1gi6fFJOmv7VmCvpD1N87Yh8ApwNXCzpB2TIGF7DRDm2inpmt4EbB8LfAMcGUHWSHryYJKwfRMwmuMP4BRJv9TN2RgB2wuB72BWsq+V9MTBIGF7NZBiGzhJ0o+9CIRBtt8FLqgADC6nRDbpVO9Iuqi3hCKB5cDrGZDVkp4aIhIV2aSQyyW9MScCkcQqIOfsnCORkc3I31b5VtyFRmg1IQ7dt0ja3icSQ2C2JhAjUU2ykd+dE7tBNp2i2olAJJFuc+nCt564QTadF6IzgUhiVGiqyinKaQjZpJP2ItBXTkPJZhACXeU0pGwGI9BWTkPLZlACBTldG4o5EA6E1dY66edcyNrs8Q36zg1vVaTazNs7iXPgDVJJzYs7VRvHRzaDEohyugJ4CTi84sg/wHWSdnVxsGQ7aQLXS9pZcqpL/6AEplpCU5HE8YpJ9YrXUKQ6baN1+HPaRm1fBqwFQnKGK2ZoPwCvAo8Ai4FnMpPMHMwapHUj8DFwbw3+Dklv9iZgexOwvktSRduxU2VDlErwmyXV+lCbxLbDdndlCT3TX3vV7JgnKfRuSVflfMkSsL0ZuDMz4E/gL+CETN+/wCpJzzaRtn0D8DRwWMbu1/gCcnSm7zFJd1W/jxGwvQx4r2IYnlbuA14GAomQFw8B6YtBKFSnNj2BxEJ3IvB1pdB9CjwQ8yqYhcg/DJxZ8WOZpA/SbzkC24DbEqOfgPMkBRKzmu23gEuSj1sk5SI3Y2J7C3BHMuZz4FxJf6fgto8APgIWJd+3SUrHjr9O294HnJUMWi8pSGqs2V4CvJ88fH0i6eyChKr4KyS9WIO/Ang+6RvDz0XgABCeFEdtkaQv65yy/QVweuwPY0+T9FuNQ8cAXwHHxf7wdHiypN9r7BfEl8GjYv9+SceXJLQ/mSDYTh2Baog3SHq0pYT2STqno4RWSnqhBn8l8FzSN4bfJol/jkn8bXUS228DFyfft0paVyCwFbg9sQkSDEkctueZZju8iO+tJPEYfo7A0piYKd73wP3xnB+20cvjNnphxdmlkj4sEMjhfwY8COyOY0fb6Bkl/K6FLKxS+M1KpDhJY8mvrG5doRwlf66QZfGbjhLh4pEt35kV3iUp/IvTunU8qtTil/7gaHOY2yjpntaez9b5RmBDYewmSXfX2RRvZLYvbThOh+NuqMa9Ww1+yLnXgO2SwkZR24oEens2oYHzBCa00PMSOtQL/f+NwH+Hg8hAnbrYgQAAAABJRU5ErkJggg==") no-repeat 50%;background-size:100% 100%}.jessibuca-container .jessibuca-icon-play{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAACgklEQVRoQ+3ZPYsTQRjA8eeZZCFlWttAwCIkZOaZJt8hlvkeHrlccuAFT6wEG0FQOeQQLCIWih6chQgKgkkKIyqKCVYip54IWmiQkTmyYhFvd3Zn3yDb7szu/7cv7GaDkPEFM94PK0DSZ9DzDAyHw7uI2HRDlVJX5/N5r9FoHCYdr/fvCRiNRmpJ6AEidoUQ15NG+AH8BgD2n9AHANAmohdJQfwAfgGA4xF4bjabnW21Whob62ILoKNfAsAGEd2PU2ATcNSNiDf0/cE5/xAHxDpgEf0NADaJ6HLUiKgAbvcjpdSGlPJZVJCoAUfdSqkLxWLxTLlc/mkbEgtgET1TSnWklLdtIuIEuN23crlcp16vv7cBSQKgu38AwBYRXQyLSArg3hsjRDxNRE+CQhIF/BN9qVAobFYqle+mkLQAdLd+8K0T0U0TRJoAbvc9fVkJId75gaQRoLv1C2STiPTb7rFLWgE6+g0RncwyYEJEtawCvjDGmpzzp5kD6NfxfD7frtVqB17xen2a7oG3ALBm+oMoFQBEPD+dTvtBfpImDXjIGFvjnD/3c7ksG5MU4HDxWeZa0HB3XhKAXcdxOn5vUi9gnIDXSqm2lHLPK8pkfVyAbSLqm4T5HRs1YB8RO0KIid8g03FRAT4rpbpSyh3TINPxUQB2GGM9zvkn05gg420CJovLZT9ISNA5tgB9ItoOGhFmnh/AcZ/X9xhj65zzV2Eiwsz1A1j2B8dHAOgS0W6YnduY6wkYj8d3lFKn/j66Ea84jtOrVqtfbQSE3YYnYDAY5Eql0hYAnNDv6kKIx2F3anO+J8DmzqLY1goQxVE12ebqDJgcrSjGrs5AFEfVZJt/AF0m+jHzUTtnAAAAAElFTkSuQmCC") no-repeat 50%;background-size:100% 100%}.jessibuca-container .jessibuca-icon-play:hover{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAACEElEQVRoQ+2ZXStEQRjH/3/yIXwDdz7J+i7kvdisXCk3SiFJW27kglBcSFFKbqwQSa4krykuKB09Naf2Yndn5jgzc06d53Znd36/mWfeniVyHsw5PwqB0DOonYEoijYBlOpAFwCMkHwLDS/9mwhEDUCfAAyTXA4tYSLwC6CtCegegH6S56FETAR+AHRoACcBTJAUWa+RloBAXwAYIrnt0yBNgZi7qtbHgw8RFwLC/QFglOScawlXAjH3gUqrE1cirgVi7mkAYyS/0xbxJSDcdwAGSa6nKeFTIOZeUyL3aYiEEBDuLwDjJGf+KxFKIOY+BdBL8iipSGiBmHtWbbuftiJZERBuOfgGSK7aSGRJIObeUml1ayKSRQHhlgtkiaTcdltGVgUE+ppkV54FaiS78yrwqlLoOI8Cch2XV548W7WRpTVwA6DP9kGUFYEpAOUkT9LQAvtq1M+0udKkQSgBqSlJWWYxKXj8vRACK+o6bbRIdYI+Ba7U7rKjg7L53JdAhWTZBsy0rWuBXZUuNVMg23auBF7UIl2yBbJt70JAoKV6/WwLk6R9mgKSJlJ1kLTxFmkJyCla8UZd15GJQKvyumyJ8gy8DAEvfZoINPqD41EtUjmUgoaJwAaAnjrKebVI34OSq85NBNqlCAWgE0CV5GEWwI3vQlmCbcSinYFCwPEIFDPgeIC1P1/MgHaIHDf4Aydx2TF7wnKeAAAAAElFTkSuQmCC") no-repeat 50%;background-size:100% 100%}.jessibuca-container .jessibuca-icon-pause{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAABA0lEQVRoQ+1YwQqCUBAcfWXXsLr2AXWTPXno8yVB8AP6Aa3oHI+kCDqYaawJljSe133uzO44bx0M/HEG/v1gAd9mkAyQgY4I/F8LJUlyrQFtD2AtIkcNoFEU+Z7n7QD4DfFHEVlocrVmgAUAIAOl3mILPcDgEFcUhyrUKMGUUcroc3NQRimj9XJBGaWMvvPydKN0o6/9QTdKN6rZANxj6EbpRulGuZnjYqs8BbyR8Ub2Izeys+u6yyAIDpo/ehzHM2NMDsA0xFsRmWhyfTIDWSXxCEBmrd2EYXjSHJqm6bQoii2AOYBL5Z0xgFxEVppcrQvQJO0zhgX0iXbdWWSADHRE4AZQ731AhEUeNwAAAABJRU5ErkJggg==") no-repeat 50%;background-size:100% 100%}.jessibuca-container .jessibuca-icon-pause:hover{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAA7klEQVRoQ+2YSwrCQBBEX6HiVvxsPYDewfN7By/gD9ciQkvERQwJdBSiYs0mEDo96aruombEjy/9+P/jAj7NoBkwA28i8H8tFBFRA9oeWEo6ZgCNiDGwAYpn3TpKmmVytWbABQBmoNRbbqEHGB7iiuJYhRol2DJqGX1uDsuoZdRmLuNZSzGWUcuoZdRHSp/IylNgK2ErYSthK3FHwLcSvpXIjoLt9Jfa6TMwl3TIMBkRE2AH9BriL5KGmVyvWIltJXEfKN6tJJ0ym0bECFgDU+Ba+WZQFCdpkcnVuoBM0i5jXECXaNftZQbMwJsI3AAPN3dAQflHegAAAABJRU5ErkJggg==") no-repeat 50%;background-size:100% 100%}.jessibuca-container .jessibuca-icon-record{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAC+UlEQVRoQ+1ZS2sTURT+zlDJYE3XSq219QHVuEjnJDT+Bff9Abqw2voAEfGxqygUqWhVFHGl/yMLu9BwByxk5SNI66ML6U7axjhHbmhgWiftncxoOiV3FcI53z3f/e65594zhIQPSnj86BBot4IdBToKRFyBnbeFlFIScVEiuYvIWC6Xe2YK8pcC7SYA4CMzH4mDQBXAqilQBDsLQLfPf9FxnF4i8kwwmypARI+Wl5dvmIBEsUmlUkNE9NaHsVCpVAZGR0d/m+A2JSAid3K53E0TkCg2pVKpz7KseR/GfKVSGYxMAMA0M1+JEpyJb6lUOm5ZVnkrAsVisaunp+esiByr1Wp3R0ZGvmifzZK4XQQWHMc52MgBpdQuAOcAXABwuB400ZTjONdaIjA7O5u2bVsnWU1EujzP+5nP5xdMVjvIJkCBD8x8VCm1G8AYgAkAAxt8Z5j5YmgCSqlTAJ4D2OcD/AXgATNfbYVEAIFPIvKKiE4D6GuCea8xX6gtpJT6DmBvECgRFRzHeROWRAABE4iWCbwHEFhkPM/L5vP5dyaz+23+KwHXdR3P854S0YG1ILSCuthNMfNM2OC1/RYENLY+ygcBnPfht6ZAA6BYLNr6dyqVokKhsGpaNQ2TWJstreXaE2aed133sojcj41AKyvdzCdAgSXLsk4MDw9/a/i4rntbRPxFNZoC/5jAV2be759DKTUJ4FZSFFi0bbs/k8noy2R9dAjEuWU2YgXkQOK3kD6BMsysi2Z9JC2Jdcw/ALzwPO+xvmcl7Rj177JVEbkO4BARjSflFDJJuW1dBxJPoCIiL4noDIB1BS0pW6j+oJmbm+uuVqvjRKQfLr0bZHnIzJf0f6HeAybahrUJqAPruhLlcnnPysqKfpXp11n/Gv62zoHAroS+AafT6QkiGrIsazKbzX7eVIHEt1US39gCkOzWYthkjNE+tuZujDGZQ8XRXn8N4KT5lLFZ6uaYPt+nwyDuvC80YdhvB9uOAu1WoaNAR4GIK/AHvdr+QAexB7EAAAAASUVORK5CYII=") no-repeat 50%;background-size:100% 100%}.jessibuca-container .jessibuca-icon-record:hover{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAACfUlEQVRoQ+2ZSYsUQRCFvycK4nJXXEbHBdwO4kn/gv9CD467ICIutxEFkREdFUU86T/xojcPntyQcT2INw+uISFVkD1Wd2dWlU7nUHlqisiX+fJFZGREi8yHMt8/HYG5VrBToFOg4QnMPxcyM2t4KE2nT0i6EwvylwIjQOCFpE1tEPgGfI0FamC3AFgazP8IrJL0KwZzkAI3gLMxIA1ttgCPA4w3wHpJP2NwBxG4KOlcDEgTGzNbA8wEGP57vA0CU5JONtlczFwz2wY8HUbAzBYCB4CtwCVJb33OIAXmioC70LoyBsxsEXAQOApsLIhelnS6FgEzW+5BBvwA/FS+SPJFa40KBZ5L2mxmS4AJ4IjHxCzwaUnHkgmY2V7gLrAyAPwOXJN0qg6DCgIvgQfAPsDjo2pcKddLciEz+wCs6AO6W9KjVBIVBGIgahN4BvRLMjslPYlZPbT53wR2AbeBtcUmXEFPdh5U06mbd/shBBzbr/Jx4FCAX0+BEsDMFocEYrNmFcE+BD4XsXZL0oyZnQCutkagzkn3m1NBwDe/Q9L74MAuFEqUn5op8I8JvJO0elacTALnc1HAH3Njkvwx+WeYWUegTa/pwaqIgexdyIN4uyRPmqULZRXEvulPwD3gpr+zcrtGQxfzRHYG2AAczuUWiom3kc4D2RN4BdwH9gM9CS0XFyoLGu9UuN974eIFVDiuSzruH5LqgRhtU20q8kBPV8LMlhVVmVdnYwX+SMdAZVeieAF7eeltmElJr4cpkH1bJfvGVvatxdR4bMu+teZuWxtKxWncXn8I7EldtQV7vz79fp9KwZp//9CksB8F206BuVahU6BToOEJ/Ab7+KdABdTt8AAAAABJRU5ErkJggg==") no-repeat 50%;background-size:100% 100%}.jessibuca-container .jessibuca-icon-recordStop{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAGDElEQVRoQ82ZaahVVRTHf//moKKggQawcmg0olGl0awvRoMVBRGFlQ1YQZIZqRVKmJmFgVk59EFQykYjgmajbJ7n2WiAbKKCBq0Vfznndd723Lvvve/5bMH9cvfaa63/2WuvaYteoIjYHDgEOAAYDOwIbA/4f9PvwHfAt8DbwGvAS5L8f49Ine6OCO89CTgFOBrYqU1Z3wBPAUskPdDm3i72jgBExCXAWGBQp4qTfR8CMyXd0a68tgBExEjgBmCfdhW1yP8eMFHS/S3y0xKAiNgQmA2MaUHwB8DnwNfAbwX/FsDOwG7Ani3I8ElcLOnvHG8WQET0Ax4C9msi7BHgbuAFSXaHhhQRewBDgZOBE5qwvuV1SSuayWsKICIcVZ4Atq4R8mdxKnMkfZT7UnXrEeE7dD7gO7VpDc/PwAhJrzaS3xBAROzrUFcJhVUZjhrjJX3cieHpnogYUNytUTXy/gAOlvROna5aABHhGG5f3qZmk33ztt4wvAbIBcCcBicxSNLKdK0RgNeB/RPmVcBxkp5eF8aXMiPiKODRGpd6XZJduhutBSAipgNX1Bg/tJkv9iao4u4tBzZJ5N4oaXz1v24AImIvwLE4peGSnDX7jCLC2f3JGoV7S3q//D8F8DJwULJpgiQnrz6niLgSmJYofkXSwWsBiIgRwGPNmPscARARDqGp7zu0Orz/l4kjYhlweGLk4Ebhq8oXEc6wGwH/tAhyA2C1JGfsphQRTqBvJkzLJB3ZBaBIKGkGXSqpWab013FWvacooXO21K07256WS4QRsRQ4PhHgsPrxmjsQEZOB6xKGIZJebGZVRDwOHNOJ5ZU9j0s6NqPnUJcpCc9kSVNKAA5ZQyoMn0gamDMsIj4rCrQca7P1zyT1zwmIiE+AKt9yScNUFGuuZaoxd7okR4Ccfzq997S0fleSy5acrjQ//QUMNADXH/cmu0dKcoWZE+r2MKs8I+YdSW5Dc7rcizycMI0ygKuA6ysLjiT9JX3RgtC+BLArYJet5q4JBuBG5aKKsV/ZryWt/p8BcJj2R3VjVNJsA1gEnFH5821JzZqXLtaI6LMTsNIafYsM4L6iOyoNe1FSNSI1PIj1AMCh1CG1pPsNYEkxGin/fFVSWg/VglgPAF4BDqwYs8QAFgDnVP78SJIzbJbWAwBXC9VRzgIDcLVXjfm/AP0kuR/NhbY+uwMR4e7QDf6WFaOmGYBHJbcnlh7USvPSlycQEXYdu1CVxhiARxzPJwsXSarrTbux9TEAh3qH/CqtKSU2Az5NZpsPSTqxBRdy49/SfWki60NJ2WFXTUXqwdmAsphbCJxZUeIGfltJvg8NKSIMfPcc0Mx6tpiLiK2AH4qeoxS3UNJZJYC6emicpJkZAOOAGT0EcLmkmzvQM8oz1BLAxsX8vjqBWynJ86FcJDoLGO4OC8jOMgthnrX696Qkn35Oh+dB21aYfgJ2kLSqqzCKiGuAaxNJkyRNzSlYl+sNmq2pkiZZbxWAJ8g/Aj6NksI+3kplui5AFL2271m1AvVJb1fmqXSsMhGYkhjznqSeNi0d4YsIz3/SCNXNK+omcy5ZPVKv0r2STu3Iig431dRolrRCkvuCLqoD4BlM3Th7nqTzOrSnrW0RcSdQp+tASX4gbAzAK8Ub2KwarQ8Cp0vy20CvU5FUFwN1SfRSSbemSpu9D9wCXFZjpacDoyU925sIIuIw4K5k8lCqmCWpzpbmb2QRMRc4t4GhfiOYJunLngCJiF2Aq4ELG8iZL6mRDflHvohwpnXGrSM/VM8DFkt6rh0gxRd3K3s24BBeRzMkpaP+bnzZR77iTvgLuOR29mxEDnmer7rk9dPT98CvBbNreGdSD8s8WT4i81rpjD5G0vzcR2kJQAHCs5ubgKZjwERhednrHvAa2eaPMFaSm6UstQyglBQRDm92qWwJnNXencGnZpdp67W+bQAVIKOLCz6sTUNTdjdTcyW5N2+bOgZQAeLHQLuV5/UeM6ZZPDXKfa1nqs/4QUXSG21bXdnQYwBV5RHhy2rXcmh0E+5GxOTGyCWwp34fSCovd09sX7P3X2uzPXCoLsVMAAAAAElFTkSuQmCC") no-repeat 50%;background-size:100% 100%}.jessibuca-container .jessibuca-icon-recordStop:hover{background:url("data:image/png;base64,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") no-repeat 50%;background-size:100% 100%}.jessibuca-container .jessibuca-icon-fullscreen{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAHTElEQVRoQ+1Zb4xcVRX/nZl5u2/LrrO0EFKoBYpVaRu3u/e+3WlDZJdIRLQhNLIiEggxqURIjGmqTTAmWiRpjH4wghq+KIQYupYQEvEDmEVdyu7OfbPbzQaEYqtSwTb4Z3aV7s6b9445mzvm7XRm3oy7oanZ82ny5txzz++ec8+/S7jIiS5y/bEG4EJbcJkFpqenryqXy6cbKBUB+AeANIBuAG8AuAzAn06ePOkNDw+H9dZOTU11h2H4EwB7ALwL4FIA7wFw7O9aSxkAE9H9SqnHazGc50LGGFFQlGuW/pbNZq/aunXrYtICY8xmAD8C8HEAnUn8sf9/oLX+SiKAQqFweRRFvwewvgbzmwA+BOAkgEsAZAG85rpubseOHaVmlTHGfBTAYwA6gKU7WCaiOWaWPT9mv1eLO6S1/mYiAGPMddYtUtXMRPRVx3F+FkXRup07d/7FGDMEYExrHTSrfIVvfHx8Uy6XO22MWae1fu/IkSPpbdu2pRcWFmpakYgeVEo92gyAdQCKADI1HZL581rrp4lIfHPV6Pjx45cEQfCvBgL3a62/nwhgZmbm0lKp9OeYf56rMqmc9v4oikb6+/v/uhoIGigvAUGChdBBrfXhRAD5fL6XiCZsZDhHRAeY+VBVlIiYeTQMw725XG5uJSDqKc/M9xDR1wFsF/lEdKdS6ulEABMTExvS6fQMgCsBhPPz825nZ+dnieinANrjApj5mSAI7t61a9fC/+JSDZS/t62t7WgQBH+0IVoA7GsqjDIz+b4vCyXcnSuXy9fmcrkz+Xz+TgB3ENHeqlN43HXdB7dv3x60AqKR8p7nPXHixIn2YrEo7itRipn5057n/SrRAhbA320eEAGbtdbvyvfJycn16XR6BIBEnzg9PD8//63BwcGwGRBJylcEG2MkbEtUFAS3NgVAmI0xkl23Wt/bppR6rSK0UChcGUXRcwBUFYjDWuuDSffBHpBk82XEzPfKyVc+Wlf+HQDJGQLgDs/zjiZawJrudQBXAzirlNpIRMs2nJiY+HA6nRYQH4kJ7NZaS/htSBLlgiB4jJnFJZeoWnn7jYwxDxCRJK/LmXnI87yXEgHEzHs2m81urlce5PP5fiL6BYAPAmhrJZmNjo5murq6ngdwcy3lK0rKYc7Nze1n5gNE9Cml1HgiAGviguu6A0nlge/7N83Nzf12aGionHTy1f+Pjo5KdBuOu00tGZKpmfmHAJ5oygJjY2Nd3d3di0nKt6rwSvjFK6Iocnp7e/+ZaIGVbHSh1q51ZBfq5Cv7rllgzQIrPIGLwoUkqdVLqssASCKbnp6+ure3VyrSRGLmVHWpkbioRYbx8fErHMcZbKofsGMVKRHu01pLc1+XJMGUSqXPEdGTrZQSIlAycVdX1+FSqXRw9+7dUvXWJFE+k8lI53e71vrZphKZMeYPMvvJZDK3SfNea1GsZpoH8EWl1NFmLTE7O9u2sLDwNoANAA65rvtwrcw/NTV1TRiGp2w/8AXP836eCMAWWicAXENEvymXy/sGBgakvP4v1ajnzzDzl7TWzyX1A1KquK4r7hkf2xxQSn2vem2sHwijKLqlv7//xUQAtpyW6YBMJUJm3hNvJBo0I3XL3fim1kVfAHB9/Dsz3+95nkztlsgClYr1BgBRKpW6oa+v75VEAMJgjDkrNbj8jndCzXZSSXfU930l/bRtWyvsC+KKAEYq98kYIzy3W4abtNajiQCsBQTAByzzsNZ6ZLWUrygwOTl5YyqVEgXjriQjzVcdx9nb09Nz1vf9F5j5EzK5Y+ZBz/NeTgRw7Nixjra2NpkLycBW5jK3OY7zUq2hU6NmJMkK8r/v+3uYWXrsZdMOAM86jnN3EAS/BjAgjgDgy1rrHycCsBNkCZ9X2DtwIxGNVS9cqfLWPalQKNzFzN8GcK2dQCxtRUTSxPQx827L+13P876WCMA27W8BOG82Wlm8GsrHZNHIyEhqy5YtvwTwyXqWI6KHlFKPJAKwYVSiULVZl9aupvJxZexIU+J8TRBE9B2l1DcSAdjLKneg1nh9fzabfbRYLG4qlUpvd3R0bCqXy7tOnTr1VKOHjVqb2jC5j4gmwzAM0+l0OgzDVCqVkvGhuO8yYuZHPM97KBGA7/vXM/O0TBpqMMvo+x17waWGkhLgMrGK1vrJpCRWkRcrD+STvCvIXiJLhgNdddzoAa21vCmcR8uKOWPMRgBSPrRSpcpY8T6l1FNJ0UfeBTKZjNyxlqg60cUXL1PUupBsIO9XMkqX96v4mFvcS0Z+Mg86TUTtzCxvCh1E9BmllPxXk+zrzxQRzTBzJxG5zCzuIjJ32DG+WCOuk1hFqoKlfNSMBWSU5zDzFnEPInqLmSWpbZANARzRWr8jQHt6ev4tAuX34uLi+iiKiknjdskzlepzdna2s729PSgWi24YhuszmYxn99sYRdHSGx0RnUmlUqf7+vqO1zuYVlylJbO/X8xrAN6vk15zoQt90v+3FvgPXUePXrKTg9MAAAAASUVORK5CYII=") no-repeat 50%;background-size:100% 100%}.jessibuca-container .jessibuca-icon-fullscreen:hover{background:url("data:image/png;base64,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") no-repeat 50%;background-size:100% 100%}.jessibuca-container .jessibuca-icon-fullscreenExit{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAADd0lEQVRoQ+2Zz2sdVRTHv+fJBDW6anDVXen6wZszYxYBiYgtFGst3VSDunKjpS0GpUlqfjVpsVVs6aaL0or4YxMVFCJZ2ZLdPUP+gq5bQnTxtNAkfTnlhnnlkmQy9yV9780rudt77tzv5/y4v4bQ4Y06XD/2ANodwec/AiJygJnvtdvTWfPnRkBEJAiCN8rl8kMfiPn5+Ve7u7v3rays0Orq6lJfX99/PuN2auMDoAD+BvA2M6/mTWSMOUtE48D6AjHGzN/kjdlNvy+AnWOOmQ/lTSYiEwDOWzsimgrDcCRvzG76GwGw8/zJzO9sN6GInAMwbW1UdSSKoqndCMwb6wNwGsB39Q+p6h/M/C4R2dTa1AoHYBWKyCkA1+pqiWi2Wq0e7e/vf7yRoJAAKcQggMtuJKIoOtoxACnE0/xOi/SXMAxPuhCFjUBdpIjYVWXSEf0TM3/g9BeriDMKdSPEz8z8vrU1xgwT0YXCrEJZy1iSJKOqOub0/8jMA0mSfKKqNwoPkHp7ioiGHIhRIvpHVa93BEBa2JcAfOlALAHo6RgAKzRJkk9V1S6xL7kpV4idOM31taxaIKJHqmpPnMMA9hcOQES2PDJkAT1XAAC+ZebPfWB3auNzmLObVsNRUNUXVHUujuM7OxXnMy4XwOcj29mIyOuq+lapVGrYCelKpkEQ3CyXy4tbzdN0AGPMxr2iYZ+sra3FcRybtgCIiK2BKw2rdgaUSqWoUqlIkQAepFDdAF7cBq5ERI9rtdr1OI7tmE2t6SmUEYFHAEaexYW/1QC2EF+ru5GIvg7D0D2GNJxprQY4o6qv1I/b6SpzOYqiLxpWng5oOQAzXxWRWwA+dkRfYOb1p5hGW6sBJpn5KytSRG4D+KguWFXHoyhy7xdeLC0F2ChSRL4H8OFuINoKYIUbY34gogHH3eeZef1K6tPaDpCm068A3nMEDzHzxY4BUNWSiPxORO6z5aDPPlGICNQ9bYyZIaLjjudzIQoFkKbTbwCO+UI0HcB9J/LdeY0xs0R02IGYYObRrWqiFQCfEZEtSHsfmGZm+4qxbbM/hQD8BeBNa0hEM2EYnmgLgP3lFARBT1dXly4vL//b29tbzQNIU+llAHeJaLFSqRzJes5vegR8xGbZLCwsHKzVav8z8/0sm0ID+MDvAfh4qZk2exFopnd9vv0ELrXBQO7fD10AAAAASUVORK5CYII=") no-repeat 50%;background-size:100% 100%}.jessibuca-container .jessibuca-icon-fullscreenExit:hover{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAC/ElEQVRoQ+2Zy49NQRCHvx+ReK6IlZ34E7CUiCAR4xEbTLCyQRATYswwb2IQZDYWgojHZpCQECts+ResiQwLj0RClNSkb9Lu3HtPz7mZc8+V6eXt6tP1VVV3VdcVbT7U5vozC9BqD/7/HjCzlZLet9rS9fbP9ICZvQPWSfqRAmFmS4ClMHm+JiR9S1mXVyYFwIBXwEZJv7I2MrPjQH8A6JN0OWtNM/OpAL7HS0mbsjYzswGgN8gNS+rJWtPM/HQAfJ9nkrY22tDMTgMjQaZH0nAzCmatTQE4ClyNPvQU2CbJQ2vKKB2Aa2hmR4DrkbbPgQ5Jv6sJSgkQILqA0dgTkjraBiBAxPHtPz2UtDuGKK0HKkqamd8qg5HS9yXtjebLdYjrHNRqiAeS9gQvnQGGSnML1bvGzOwc0BfN35PUaWYHgRulBwjW9ju+O4JwqM/AWFsABIgLwKkIYgJY1jYAAeJQuGIXVIVcKTKxh8WfBin9J+AVpx/eFWUEqFkyNACKp0rhgWYArkg6kQibSyylmPOklQdibijBX+fSLHFRJkDid+qKmdlaYENOI0zeEcBNSZ9qbVIEQHWuyGOTNZLetgrAz8ClPFpHa1ZL8rf5lFGEB2oBfAxQi4D5DeDmAP7mGJPka0oD4LnDr9imH/xFe8AP4vLIjBclxWXItCOtaIBjwOKo3HaFRyWdnLbmYUHhAJKumdkt4ECk9JCkSitmWixFAwxKOjt5uZvdBvZH2vZLit8XSSBFA/yjpJndAfY1A9FSgOCJu0BnBNErqfIkzfRCywECxCNgR6Rtt6TzmdqHBmyKXG4ZM4sTWc04NzNPWE+AuG3ZlZInSuGBinXMbBzYGVkrE6JUACGcHgPbUyGKAIj7REmZ18y897o5ghiQ5E/bltRChwE/kF7Xj0jyLkbDYWbzgBfA+iA4LmlXqwD8LydvszjAF0lfswBCKC0E3gBeP22p186f8RBKUbaejJmtAr5L+lBPptQAKfCzAClWmkmZWQ/MpHVTvv0X9iFAQGQyevIAAAAASUVORK5CYII=") no-repeat 50%;background-size:100% 100%}.jessibuca-container .jessibuca-icon-audio{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAACrUlEQVRoQ+2ZPYgTURCAZzbBXJnCeL2Cnb87b9MEtPBUrrMQFAtrtT5/ClGs9LBWWz0RtbBUFCF4oJDsbO68wsLA2YqQSmLlvpEHu7IuMdlLcus+yUKKhJfZ+ebnvZl5CJY/aLn+MAP41x7M1QPMfFtr/crzvHfTAs8FoNPp1LTWzwHgqIg0lFLvrQHwfX8BER8DwC6jNCIecF13wwoA3/dvIuKNpLJa60Oe560XGoCZd4rICiKeTCtaeABmPg4AJmRqg6xcaABmvg4At4aFRyEBhoVM4UMoCplHADCfJTEL5YEsIVNID5iQAYCHALCYxeq5b6PMfF5EBAAEESthGK7W6/XPRpFWq7W3VCqtZg2ZcT3g+/6i4zjzIlLSWn/yPO/DIGMNLCWY2Sj/+xGRK0qpZfNDEASnROTFVi0fr8+aA8z8Ld6KEfGt67oLYwMAwEUium8EREn7OgeAjwCwPyo/nrque3YSgAtE9GDaAM1mc65arc4Zuf1+P2w0Gt9jJZl5DQAORt+fENG5wgEw8zUAMB/zbBBRwyqAIAjuiMjlSOlNItpjFUCqWl0josMzgChR/9hGAWBbknjmAdPhDdqa0gfZzAMJKyVP4v8hhJYRcSni+0JEu63ahZj5anyQici6UuqIVQDdbrfS6/UqRulyufyTiH5sF8AlIro37VpoWEHIzGZ2tM+sEZFnSqkzk9RCS0R01wjIsZz+mug53hDRia0AnI4bGgDYISItz/M2jYC8Gpp2u30MEWuO4zha665Sqp0ZYFStX/iWchRAItFGzoHSsrJ2ZFl1mHg6bfVYJeGJv85CC++BpIJZ5kSFC6G0ha0e7mYJqcJ7IOkRay84UhD2XjHFIFZf8iW9YcYoYRi+tO6aNeupOs66iU/icV46zf/MAKZpzXFk/QL+JG1PUPhRiQAAAABJRU5ErkJggg==") no-repeat 50%;background-size:100% 100%}.jessibuca-container .jessibuca-icon-audio:hover{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAACSElEQVRoQ+2Zu4sUQRCHf5+C+gf4yBXMfMYHGvjCzEBQDIzV+HwEohipGKupD0QNDE8UEwUFTe68wEDhTMVUMFJ+0tArzbjs9u3Ojt0wBR0M9MzUV1XdXVWNKhcq1189wP/2YKcesH1d0nPgdVvgnQDY3iTpqaT9kuaAt9UA2D4o6aGkzVHpXcByFQC2r0q60lB2D7BUNIDtjZIeSDoyRNGyAWwfiiET4n6YlAtg+7Kka2PCozyAMSHT5CkLIIbMfUlbMhdmOQCZIVOeB2LI3JN0NNPq6bTZe8D2aUmOY72kN8DnoIXt7eF5FSEzkQdsB+OEsFwr6RPwbpixhqYStoPyqVwAbkaAY5KeTWD5wStZHrD9XdJgK34FhBP9H8kFOAvciQBhn3/RAcBHSTvjfx4DJ6cBOAPcbRvA9gZJYQT5DfwYKGl7UdLu+PwIOFUiwCVJYQRZBuZqA7gh6XxUegXYVhtAmq0uAnt7gLhQm9vorBZx74Hcc6D3QLKH/z2JGyVnlYs4pCfzEe4rsLW2XehicpAtAftqAwiZbhhBfgE/ZwVwDrjddi40KiG0HXpHO+KcJ8CJaXKheeBWBOgqnf6W1BwvgcOrATieFDTrJL0HViJAVwXNgVgPrJH0BfiQDTDKtREiNK7KLSnHASQLLacP1PxcVkWWq8PU3emq2yqJJ0b1Qsv2QKpdZp+orBBqmrfq5m5mSJXtgUZI1XnB0YCo94opCal6L/ka3ghtlIXqrllzT9VJ5k19Ek/y0zbf6QHatOYk3/oDujC8QMWgjf4AAAAASUVORK5CYII=") no-repeat 50%;background-size:100% 100%}.jessibuca-container .jessibuca-icon-mute{background:url("data:image/png;base64,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") no-repeat 50%;background-size:100% 100%}.jessibuca-container .jessibuca-icon-mute:hover{background:url("data:image/png;base64,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") no-repeat 50%;background-size:100% 100%}.jessibuca-container .jessibuca-icon-text{font-size:14px;width:30px}.jessibuca-container .jessibuca-speed{font-size:14px;color:#fff}.jessibuca-container .jessibuca-quality-menu-list{position:absolute;left:50%;bottom:100%;visibility:hidden;opacity:0;transform:translateX(-50%);transition:visibility .3s,opacity .3s;background-color:rgba(0,0,0,.5);border-radius:4px}.jessibuca-container .jessibuca-quality-menu-list.jessibuca-quality-menu-shown{visibility:visible;opacity:1}.jessibuca-container .icon-title-tips{pointer-events:none;position:absolute;left:50%;bottom:100%;visibility:hidden;opacity:0;transform:translateX(-50%);transition:visibility .3s ease 0s,opacity .3s ease 0s;background-color:rgba(0,0,0,.5);border-radius:4px}.jessibuca-container .icon-title{display:inline-block;padding:5px 10px;font-size:12px;white-space:nowrap;color:#fff}.jessibuca-container .jessibuca-quality-menu{padding:8px 0}.jessibuca-container .jessibuca-quality-menu-item{display:block;height:25px;margin:0;padding:0 10px;cursor:pointer;font-size:14px;text-align:center;width:50px;color:hsla(0,0%,100%,.5);transition:color .3s,background-color .3s}.jessibuca-container .jessibuca-quality-menu-item:hover{background-color:hsla(0,0%,100%,.2)}.jessibuca-container .jessibuca-quality-menu-item:focus{outline:none}.jessibuca-container .jessibuca-quality-menu-item.jessibuca-quality-menu-item-active{color:#2298fc}.jessibuca-container .jessibuca-volume-panel-wrap{position:absolute;left:50%;bottom:100%;visibility:hidden;opacity:0;transform:translateX(-50%) translateY(22%);transition:visibility .3s,opacity .3s;background-color:rgba(0,0,0,.5);border-radius:4px;height:120px;width:50px;overflow:hidden}.jessibuca-container .jessibuca-volume-panel-wrap.jessibuca-volume-panel-wrap-show{visibility:visible;opacity:1}.jessibuca-container .jessibuca-volume-panel{cursor:pointer;position:absolute;top:21px;height:60px;width:50px;overflow:hidden}.jessibuca-container .jessibuca-volume-panel-text{position:absolute;left:0;top:0;width:50px;height:20px;line-height:20px;text-align:center;color:#fff;font-size:12px}.jessibuca-container .jessibuca-volume-panel-handle{position:absolute;top:48px;left:50%;width:12px;height:12px;border-radius:12px;margin-left:-6px;background:#fff}.jessibuca-container .jessibuca-volume-panel-handle:before{bottom:-54px;background:#fff}.jessibuca-container .jessibuca-volume-panel-handle:after{bottom:6px;background:hsla(0,0%,100%,.2)}.jessibuca-container .jessibuca-volume-panel-handle:after,.jessibuca-container .jessibuca-volume-panel-handle:before{content:"";position:absolute;display:block;left:50%;width:3px;margin-left:-1px;height:60px}.jessibuca-container.jessibuca-fullscreen-web .jessibuca-controls{width:100vh;transform:translateX(-13vw) translateY(-47.8vh) rotate(270deg);transition:width .5s ease-in}.jessibuca-container.jessibuca-fullscreen-web .jessibuca-play-big:after{transform:rotate(270deg)}.jessibuca-container.jessibuca-fullscreen-web .jessibuca-loading{flex-direction:row}.jessibuca-container.jessibuca-fullscreen-web .jessibuca-loading-text{transform:rotate(270deg)}');class He{constructor(e){var t;this.player=e,((e,t)=>{e._opt.hasControl&&e._opt.controlAutoHide?e.$container.classList.add("jessibuca-controls-show-auto-hide"):e.$container.classList.add("jessibuca-controls-show");const i=e._opt,o=i.operateBtns;e.$container.insertAdjacentHTML("beforeend",`\n ${i.background?`<div class="jessibuca-poster" style="background-image: url(${i.background})"></div>`:""}\n <div class="jessibuca-loading">\n ${Pe.loading}\n ${i.loadingText?`<div class="jessibuca-loading-text">${i.loadingText}</div>`:""}\n </div>\n ${i.hasControl&&o.play?'<div class="jessibuca-play-big"></div>':""}\n ${i.hasControl?`\n <div class="jessibuca-controls">\n <div class="jessibuca-controls-bottom">\n <div class="jessibuca-controls-left">\n ${i.showBandwidth?'<div class="jessibuca-controls-item jessibuca-speed"></div>':""}\n </div>\n <div class="jessibuca-controls-right">\n ${o.audio?`\n <div class="jessibuca-controls-item jessibuca-volume">\n ${Pe.audio}\n ${Pe.mute}\n <div class="jessibuca-volume-panel-wrap">\n <div class="jessibuca-volume-panel">\n <div class="jessibuca-volume-panel-handle"></div>\n </div>\n <div class="jessibuca-volume-panel-text"></div>\n </div>\n </div>\n `:""}\n ${o.play?`<div class="jessibuca-controls-item jessibuca-play">${Pe.play}</div><div class="jessibuca-controls-item jessibuca-pause">${Pe.pause}</div>`:""}\n ${o.screenshot?`<div class="jessibuca-controls-item jessibuca-screenshot">${Pe.screenshot}</div>`:""}\n ${o.record?` <div class="jessibuca-controls-item jessibuca-record">${Pe.record}</div><div class="jessibuca-controls-item jessibuca-record-stop">${Pe.recordStop}</div>`:""}\n ${o.fullscreen?`<div class="jessibuca-controls-item jessibuca-fullscreen">${Pe.fullscreen}</div><div class="jessibuca-controls-item jessibuca-fullscreen-exit">${Pe.fullscreenExit}</div>`:""}\n </div>\n </div>\n </div>\n `:""}\n\n `),Object.defineProperty(t,"$poster",{value:e.$container.querySelector(".jessibuca-poster")}),Object.defineProperty(t,"$loading",{value:e.$container.querySelector(".jessibuca-loading")}),Object.defineProperty(t,"$play",{value:e.$container.querySelector(".jessibuca-play")}),Object.defineProperty(t,"$playBig",{value:e.$container.querySelector(".jessibuca-play-big")}),Object.defineProperty(t,"$pause",{value:e.$container.querySelector(".jessibuca-pause")}),Object.defineProperty(t,"$controls",{value:e.$container.querySelector(".jessibuca-controls")}),Object.defineProperty(t,"$fullscreen",{value:e.$container.querySelector(".jessibuca-fullscreen")}),Object.defineProperty(t,"$fullscreen",{value:e.$container.querySelector(".jessibuca-fullscreen")}),Object.defineProperty(t,"$volume",{value:e.$container.querySelector(".jessibuca-volume")}),Object.defineProperty(t,"$volumePanelWrap",{value:e.$container.querySelector(".jessibuca-volume-panel-wrap")}),Object.defineProperty(t,"$volumePanelText",{value:e.$container.querySelector(".jessibuca-volume-panel-text")}),Object.defineProperty(t,"$volumePanel",{value:e.$container.querySelector(".jessibuca-volume-panel")}),Object.defineProperty(t,"$volumeHandle",{value:e.$container.querySelector(".jessibuca-volume-panel-handle")}),Object.defineProperty(t,"$volumeOn",{value:e.$container.querySelector(".jessibuca-icon-audio")}),Object.defineProperty(t,"$volumeOff",{value:e.$container.querySelector(".jessibuca-icon-mute")}),Object.defineProperty(t,"$fullscreen",{value:e.$container.querySelector(".jessibuca-fullscreen")}),Object.defineProperty(t,"$fullscreenExit",{value:e.$container.querySelector(".jessibuca-fullscreen-exit")}),Object.defineProperty(t,"$record",{value:e.$container.querySelector(".jessibuca-record")}),Object.defineProperty(t,"$recordStop",{value:e.$container.querySelector(".jessibuca-record-stop")}),Object.defineProperty(t,"$screenshot",{value:e.$container.querySelector(".jessibuca-screenshot")}),Object.defineProperty(t,"$speed",{value:e.$container.querySelector(".jessibuca-speed")})})(e,this),ze(e,this),t=this,Object.defineProperty(t,"controlsRect",{get:()=>t.$controls.getBoundingClientRect()}),((e,t)=>{const{events:{proxy:i},debug:o}=e;function r(e){const{bottom:i,height:o}=t.$volumePanel.getBoundingClientRect(),{height:r}=t.$volumeHandle.getBoundingClientRect();return pe(i-e.y-r/2,0,o-r/2)/(o-r)}i(window,["click","contextmenu"],(i=>{i.composedPath().indexOf(e.$container)>-1?t.isFocus=!0:t.isFocus=!1})),i(window,"orientationchange",(()=>{setTimeout((()=>{e.resize()}),300)})),i(t.$controls,"click",(e=>{e.stopPropagation()})),i(t.$pause,"click",(t=>{e.pause()})),i(t.$play,"click",(t=>{e.play()})),i(t.$playBig,"click",(t=>{e.play()})),i(t.$volume,"mouseover",(()=>{t.$volumePanelWrap.classList.add("jessibuca-volume-panel-wrap-show")})),i(t.$volume,"mouseout",(()=>{t.$volumePanelWrap.classList.remove("jessibuca-volume-panel-wrap-show")})),i(t.$volumeOn,"click",(i=>{i.stopPropagation(),me(t.$volumeOn,"display","none"),me(t.$volumeOff,"display","block"),e.lastVolume=e.volume,e.volume=0})),i(t.$volumeOff,"click",(i=>{i.stopPropagation(),me(t.$volumeOn,"display","block"),me(t.$volumeOff,"display","none"),e.volume=e.lastVolume||.5})),i(t.$screenshot,"click",(t=>{t.stopPropagation(),e.video.screenshot()})),i(t.$volumePanel,"click",(t=>{t.stopPropagation(),e.volume=r(t)})),i(t.$volumeHandle,"mousedown",(()=>{t.isVolumeDroging=!0})),i(t.$volumeHandle,"mousemove",(i=>{t.isVolumeDroging&&(e.volume=r(i))})),i(document,"mouseup",(()=>{t.isVolumeDroging&&(t.isVolumeDroging=!1)})),i(t.$record,"click",(t=>{t.stopPropagation(),e.recording=!0})),i(t.$recordStop,"click",(t=>{t.stopPropagation(),e.recording=!1})),i(t.$fullscreen,"click",(t=>{t.stopPropagation(),e.fullscreen=!0})),i(t.$fullscreenExit,"click",(t=>{t.stopPropagation(),e.fullscreen=!1})),e._opt.hasControl&&e._opt.controlAutoHide&&(i(e.$container,"mouseover",(()=>{e.fullscreen||me(t.$controls,"display","block")})),i(e.$container,"mouseout",(()=>{me(t.$controls,"display","none")})))})(e,this),e._opt.hotKey&&((e,t)=>{const{events:{proxy:i}}=e,o={};function r(e,t){o[e]?o[e].push(t):o[e]=[t]}r(re,(()=>{e.fullscreen&&(e.fullscreen=!1)})),r(Ae,(()=>{e.volume+=.05})),r(se,(()=>{e.volume-=.05})),i(window,"keydown",(e=>{if(t.isFocus){const t=document.activeElement.tagName.toUpperCase(),i=document.activeElement.getAttribute("contenteditable");if("INPUT"!==t&&"TEXTAREA"!==t&&""!==i&&"true"!==i){const t=o[e.keyCode];t&&(e.preventDefault(),t.forEach((e=>e())))}}}))})(e,this),this.player.debug.log("Control","init")}destroy(){this.$poster&&this.player.$container.removeChild(this.$poster),this.$loading&&this.player.$container.removeChild(this.$loading),this.$controls&&this.player.$container.removeChild(this.$controls),this.$playBig&&this.player.$container.removeChild(this.$playBig),this.player.debug.log("control","destroy")}autoSize(){const e=this.player;e.$container.style.padding="0 0";const t=e.width,i=e.height,o=t/i,r=e.video.$videoElement.width/e.video.$videoElement.height;if(o>r){const o=(t-i*r)/2;e.$container.style.padding=`0 ${o}px`}else{const o=(i-t/r)/2;e.$container.style.padding=`${o}px 0`}}}Ye(".jessibuca-container{position:relative;width:100%;height:100%;overflow:hidden}.jessibuca-container.jessibuca-fullscreen-web{position:fixed;z-index:9999;left:0;top:0;right:0;bottom:0;width:100vw!important;height:100vh!important;background:#000}");class Xe{static init(){Xe.types={avc1:[],avcC:[],hvc1:[],hvcC:[],btrt:[],dinf:[],dref:[],esds:[],ftyp:[],hdlr:[],mdat:[],mdhd:[],mdia:[],mfhd:[],minf:[],moof:[],moov:[],mp4a:[],mvex:[],mvhd:[],sdtp:[],stbl:[],stco:[],stsc:[],stsd:[],stsz:[],stts:[],tfdt:[],tfhd:[],traf:[],trak:[],trun:[],trex:[],tkhd:[],vmhd:[],smhd:[]};for(let e in Xe.types)Xe.types.hasOwnProperty(e)&&(Xe.types[e]=[e.charCodeAt(0),e.charCodeAt(1),e.charCodeAt(2),e.charCodeAt(3)]);let e=Xe.constants={};e.FTYP=new Uint8Array([105,115,111,109,0,0,0,1,105,115,111,109,97,118,99,49]),e.STSD_PREFIX=new Uint8Array([0,0,0,0,0,0,0,1]),e.STTS=new Uint8Array([0,0,0,0,0,0,0,0]),e.STSC=e.STCO=e.STTS,e.STSZ=new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0]),e.HDLR_VIDEO=new Uint8Array([0,0,0,0,0,0,0,0,118,105,100,101,0,0,0,0,0,0,0,0,0,0,0,0,86,105,100,101,111,72,97,110,100,108,101,114,0]),e.HDLR_AUDIO=new Uint8Array([0,0,0,0,0,0,0,0,115,111,117,110,0,0,0,0,0,0,0,0,0,0,0,0,83,111,117,110,100,72,97,110,100,108,101,114,0]),e.DREF=new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,12,117,114,108,32,0,0,0,1]),e.SMHD=new Uint8Array([0,0,0,0,0,0,0,0]),e.VMHD=new Uint8Array([0,0,0,1,0,0,0,0,0,0,0,0])}static box(e){let t=8,i=null,o=Array.prototype.slice.call(arguments,1),r=o.length;for(let e=0;e<r;e++)t+=o[e].byteLength;i=new Uint8Array(t),i[0]=t>>>24&255,i[1]=t>>>16&255,i[2]=t>>>8&255,i[3]=255&t,i.set(e,4);let A=8;for(let e=0;e<r;e++)i.set(o[e],A),A+=o[e].byteLength;return i}static generateInitSegment(e){let t=Xe.box(Xe.types.ftyp,Xe.constants.FTYP),i=Xe.moov(e),o=new Uint8Array(t.byteLength+i.byteLength);return o.set(t,0),o.set(i,t.byteLength),o}static moov(e){let t=Xe.mvhd(e.timescale,e.duration),i=Xe.trak(e),o=Xe.mvex(e);return Xe.box(Xe.types.moov,t,i,o)}static mvhd(e,t){return Xe.box(Xe.types.mvhd,new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0,e>>>24&255,e>>>16&255,e>>>8&255,255&e,t>>>24&255,t>>>16&255,t>>>8&255,255&t,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255]))}static trak(e){return Xe.box(Xe.types.trak,Xe.tkhd(e),Xe.mdia(e))}static tkhd(e){let t=e.id,i=e.duration,o=e.presentWidth,r=e.presentHeight;return Xe.box(Xe.types.tkhd,new Uint8Array([0,0,0,7,0,0,0,0,0,0,0,0,t>>>24&255,t>>>16&255,t>>>8&255,255&t,0,0,0,0,i>>>24&255,i>>>16&255,i>>>8&255,255&i,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,o>>>8&255,255&o,0,0,r>>>8&255,255&r,0,0]))}static mdia(e){return Xe.box(Xe.types.mdia,Xe.mdhd(e),Xe.hdlr(e),Xe.minf(e))}static mdhd(e){let t=e.timescale,i=e.duration;return Xe.box(Xe.types.mdhd,new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0,t>>>24&255,t>>>16&255,t>>>8&255,255&t,i>>>24&255,i>>>16&255,i>>>8&255,255&i,85,196,0,0]))}static hdlr(e){let t=null;return t="audio"===e.type?Xe.constants.HDLR_AUDIO:Xe.constants.HDLR_VIDEO,Xe.box(Xe.types.hdlr,t)}static minf(e){let t=null;return t="audio"===e.type?Xe.box(Xe.types.smhd,Xe.constants.SMHD):Xe.box(Xe.types.vmhd,Xe.constants.VMHD),Xe.box(Xe.types.minf,t,Xe.dinf(),Xe.stbl(e))}static dinf(){return Xe.box(Xe.types.dinf,Xe.box(Xe.types.dref,Xe.constants.DREF))}static stbl(e){return Xe.box(Xe.types.stbl,Xe.stsd(e),Xe.box(Xe.types.stts,Xe.constants.STTS),Xe.box(Xe.types.stsc,Xe.constants.STSC),Xe.box(Xe.types.stsz,Xe.constants.STSZ),Xe.box(Xe.types.stco,Xe.constants.STCO))}static stsd(e){return"audio"===e.type?Xe.box(Xe.types.stsd,Xe.constants.STSD_PREFIX,Xe.mp4a(e)):"avc"===e.videoType?Xe.box(Xe.types.stsd,Xe.constants.STSD_PREFIX,Xe.avc1(e)):Xe.box(Xe.types.stsd,Xe.constants.STSD_PREFIX,Xe.hvc1(e))}static mp4a(e){let t=e.channelCount,i=e.audioSampleRate,o=new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,t,0,16,0,0,0,0,i>>>8&255,255&i,0,0]);return Xe.box(Xe.types.mp4a,o,Xe.esds(e))}static esds(e){let t=e.config||[],i=t.length,o=new Uint8Array([0,0,0,0,3,23+i,0,1,0,4,15+i,64,21,0,0,0,0,0,0,0,0,0,0,0,5].concat([i]).concat(t).concat([6,1,2]));return Xe.box(Xe.types.esds,o)}static avc1(e){let t=e.avcc;const i=e.codecWidth,o=e.codecHeight;let r=new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,i>>>8&255,255&i,o>>>8&255,255&o,0,72,0,0,0,72,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,255,255]);return Xe.box(Xe.types.avc1,r,Xe.box(Xe.types.avcC,t))}static hvc1(e){let t=e.avcc;const i=e.codecWidth,o=e.codecHeight;let r=new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,i>>>8&255,255&i,o>>>8&255,255&o,0,72,0,0,0,72,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,255,255]);return Xe.box(Xe.types.hvc1,r,Xe.box(Xe.types.hvcC,t))}static mvex(e){return Xe.box(Xe.types.mvex,Xe.trex(e))}static trex(e){let t=e.id,i=new Uint8Array([0,0,0,0,t>>>24&255,t>>>16&255,t>>>8&255,255&t,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1]);return Xe.box(Xe.types.trex,i)}static moof(e,t){return Xe.box(Xe.types.moof,Xe.mfhd(e.sequenceNumber),Xe.traf(e,t))}static mfhd(e){let t=new Uint8Array([0,0,0,0,e>>>24&255,e>>>16&255,e>>>8&255,255&e]);return Xe.box(Xe.types.mfhd,t)}static traf(e,t){let i=e.id,o=Xe.box(Xe.types.tfhd,new Uint8Array([0,0,0,0,i>>>24&255,i>>>16&255,i>>>8&255,255&i])),r=Xe.box(Xe.types.tfdt,new Uint8Array([0,0,0,0,t>>>24&255,t>>>16&255,t>>>8&255,255&t])),A=Xe.sdtp(e),s=Xe.trun(e,A.byteLength+16+16+8+16+8+8);return Xe.box(Xe.types.traf,o,r,s,A)}static sdtp(e){let t=new Uint8Array(5),i=e.flags;return t[4]=i.isLeading<<6|i.dependsOn<<4|i.isDependedOn<<2|i.hasRedundancy,Xe.box(Xe.types.sdtp,t)}static trun(e,t){let i=new Uint8Array(28);t+=36,i.set([0,0,15,1,0,0,0,1,t>>>24&255,t>>>16&255,t>>>8&255,255&t],0);let o=e.duration,r=e.size,A=e.flags,s=e.cts;return i.set([o>>>24&255,o>>>16&255,o>>>8&255,255&o,r>>>24&255,r>>>16&255,r>>>8&255,255&r,A.isLeading<<2|A.dependsOn,A.isDependedOn<<6|A.hasRedundancy<<4|A.isNonSync,0,0,s>>>24&255,s>>>16&255,s>>>8&255,255&s],12),Xe.box(Xe.types.trun,i)}static mdat(e){return Xe.box(Xe.types.mdat,e)}}Xe.init();class Ze{constructor(e){this.TAG="ExpGolomb",this._buffer=e,this._buffer_index=0,this._total_bytes=e.byteLength,this._total_bits=8*e.byteLength,this._current_word=0,this._current_word_bits_left=0}destroy(){this._buffer=null}_fillCurrentWord(){let e=this._total_bytes-this._buffer_index,t=Math.min(4,e),i=new Uint8Array(4);i.set(this._buffer.subarray(this._buffer_index,this._buffer_index+t)),this._current_word=new DataView(i.buffer).getUint32(0,!1),this._buffer_index+=t,this._current_word_bits_left=8*t}readBits(e){if(e<=this._current_word_bits_left){let t=this._current_word>>>32-e;return this._current_word<<=e,this._current_word_bits_left-=e,t}let t=this._current_word_bits_left?this._current_word:0;t>>>=32-this._current_word_bits_left;let i=e-this._current_word_bits_left;this._fillCurrentWord();let o=Math.min(i,this._current_word_bits_left),r=this._current_word>>>32-o;return this._current_word<<=o,this._current_word_bits_left-=o,t=t<<o|r,t}readBool(){return 1===this.readBits(1)}readByte(){return this.readBits(8)}_skipLeadingZero(){let e;for(e=0;e<this._current_word_bits_left;e++)if(0!=(this._current_word&2147483648>>>e))return this._current_word<<=e,this._current_word_bits_left-=e,e;return this._fillCurrentWord(),e+this._skipLeadingZero()}readUEG(){let e=this._skipLeadingZero();return this.readBits(e+1)-1}readSEG(){let e=this.readUEG();return 1&e?e+1>>>1:-1*(e>>>1)}}class qe{static _ebsp2rbsp(e){let t=e,i=t.byteLength,o=new Uint8Array(i),r=0;for(let e=0;e<i;e++)e>=2&&3===t[e]&&0===t[e-1]&&0===t[e-2]||(o[r]=t[e],r++);return new Uint8Array(o.buffer,0,r)}static parseSPS(e){let t=qe._ebsp2rbsp(e),i=new Ze(t);i.readByte();let o=i.readByte();i.readByte();let r=i.readByte();i.readUEG();let A=qe.getProfileString(o),s=qe.getLevelString(r),n=1,a=420,d=[0,420,422,444],c=8;if((100===o||110===o||122===o||244===o||44===o||83===o||86===o||118===o||128===o||138===o||144===o)&&(n=i.readUEG(),3===n&&i.readBits(1),n<=3&&(a=d[n]),c=i.readUEG()+8,i.readUEG(),i.readBits(1),i.readBool())){let e=3!==n?8:12;for(let t=0;t<e;t++)i.readBool()&&(t<6?qe._skipScalingList(i,16):qe._skipScalingList(i,64))}i.readUEG();let l=i.readUEG();if(0===l)i.readUEG();else if(1===l){i.readBits(1),i.readSEG(),i.readSEG();let e=i.readUEG();for(let t=0;t<e;t++)i.readSEG()}let u=i.readUEG();i.readBits(1);let h=i.readUEG(),p=i.readUEG(),m=i.readBits(1);0===m&&i.readBits(1),i.readBits(1);let g=0,f=0,b=0,y=0;i.readBool()&&(g=i.readUEG(),f=i.readUEG(),b=i.readUEG(),y=i.readUEG());let v=1,w=1,S=0,E=!0,B=0,C=0;if(i.readBool()){if(i.readBool()){let e=i.readByte(),t=[1,12,10,16,40,24,20,32,80,18,15,64,160,4,3,2],o=[1,11,11,11,33,11,11,11,33,11,11,33,99,3,2,1];e>0&&e<16?(v=t[e-1],w=o[e-1]):255===e&&(v=i.readByte()<<8|i.readByte(),w=i.readByte()<<8|i.readByte())}if(i.readBool()&&i.readBool(),i.readBool()&&(i.readBits(4),i.readBool()&&i.readBits(24)),i.readBool()&&(i.readUEG(),i.readUEG()),i.readBool()){let e=i.readBits(32),t=i.readBits(32);E=i.readBool(),B=t,C=2*e,S=B/C}}let R=1;1===v&&1===w||(R=v/w);let k=0,T=0;if(0===n)k=1,T=2-m;else{k=3===n?1:2,T=(1===n?2:1)*(2-m)}let I=16*(h+1),x=16*(p+1)*(2-m);I-=(g+f)*k,x-=(b+y)*T;let D=Math.ceil(I*R);return i.destroy(),i=null,{profile_string:A,level_string:s,bit_depth:c,ref_frames:u,chroma_format:a,chroma_format_string:qe.getChromaFormatString(a),frame_rate:{fixed:E,fps:S,fps_den:C,fps_num:B},sar_ratio:{width:v,height:w},codec_size:{width:I,height:x},present_size:{width:D,height:x}}}static _skipScalingList(e,t){let i=8,o=8,r=0;for(let A=0;A<t;A++)0!==o&&(r=e.readSEG(),o=(i+r+256)%256),i=0===o?i:o}static getProfileString(e){switch(e){case 66:return"Baseline";case 77:return"Main";case 88:return"Extended";case 100:return"High";case 110:return"High10";case 122:return"High422";case 244:return"High444";default:return"Unknown"}}static getLevelString(e){return(e/10).toFixed(1)}static getChromaFormatString(e){switch(e){case 420:return"4:2:0";case 422:return"4:2:2";case 444:return"4:4:4";default:return"Unknown"}}}class Ke extends Be{constructor(e){super(),this.player=e,this.isAvc=!0,this.mediaSource=new window.MediaSource,this.sourceBuffer=null,this.hasInit=!1,this.isInitInfo=!1,this.cacheTrack={},this.timeInit=!1,this.sequenceNumber=0,this.mediaSourceOpen=!1,this.bufferList=[],this.dropping=!1,this.player.video.$videoElement.src=window.URL.createObjectURL(this.mediaSource);const{debug:t,events:{proxy:i}}=e;i(this.mediaSource,"sourceopen",(()=>{this.mediaSourceOpen=!0,this.player.emit(T.mseSourceOpen)})),i(this.mediaSource,"sourceclose",(()=>{this.player.emit(T.mseSourceClose)})),e.debug.log("MediaSource","init")}destroy(){this.stop(),this.bufferList=[],this.mediaSource=null,this.mediaSourceOpen=!1,this.sourceBuffer=null,this.hasInit=!1,this.isInitInfo=!1,this.sequenceNumber=0,this.cacheTrack=null,this.timeInit=!1,this.off(),this.player.debug.log("MediaSource","destroy")}get state(){return this.mediaSource.readyState}get isStateOpen(){return this.state===te}get isStateClosed(){return this.state===ie}get isStateEnded(){return this.state===ee}get duration(){return this.mediaSource.duration}set duration(e){this.mediaSource.duration=e}decodeVideo(e,t,i){const o=this.player;if(this.hasInit)this._decodeVideo(e,t,i);else if(i&&0===e[1]){const r=15&e[0];if(o.video.updateVideoInfo({encTypeCode:r}),r===M)return void this.emit(x.mediaSourceH265NotSupport);o._times.decodeStart||(o._times.decodeStart=he()),this._decodeConfigurationRecord(e,t,i,r),this.hasInit=!0}}_doDecode(){const e=this.bufferList.shift();e&&this._decodeVideo(e.payload,e.ts,e.isIframe)}_decodeConfigurationRecord(e,t,i,o){let r=e.slice(5),A={};o===O?A=function(e){const t={},i=new DataView(e.buffer);let o=i.getUint8(0),r=i.getUint8(1);if(i.getUint8(2),i.getUint8(3),1!==o||0===r)return;const A=1+(3&i.getUint8(4));if(3!==A&&4!==A)return;let s=31&i.getUint8(5);if(0===s)return;let n=6;for(let o=0;o<s;o++){let r=i.getUint16(n,!1);if(n+=2,0===r)continue;let A=new Uint8Array(e.buffer,n,r);n+=r;let s=qe.parseSPS(A);if(0!==o)continue;t.codecWidth=s.codec_size.width,t.codecHeight=s.codec_size.height,t.presentWidth=s.present_size.width,t.presentHeight=s.present_size.height,t.profile=s.profile_string,t.level=s.level_string,t.bitDepth=s.bit_depth,t.chromaFormat=s.chroma_format,t.sarRatio=s.sar_ratio,t.frameRate=s.frame_rate,!1!==s.frame_rate.fixed&&0!==s.frame_rate.fps_num&&0!==s.frame_rate.fps_den||(t.frameRate={});let a=t.frameRate.fps_den,d=t.frameRate.fps_num;t.refSampleDuration=t.timescale*(a/d);let c=A.subarray(1,4),l="avc1.";for(let e=0;e<3;e++){let t=c[e].toString(16);t.length<2&&(t="0"+t),l+=t}t.codec=l}let a=i.getUint8(n);if(0!==a){n++;for(let t=0;t<a;t++){let t=i.getUint16(n,!1);n+=2,0!==t&&(new Uint8Array(e.buffer,n,t),n+=t)}return t.videoType="avc",t}}(r):o===M&&(A=function(e){const t={videoType:"hevc"};let i=23;if(e[i]!==W)return t;i+=2,i+=1;const o=e[i+1]|e[i]<<8;i+=2;const r=e.slice(i,i+o);if(console.log(Uint8Array.from(r)),i+=o,e[i]!==G)return t;i+=2,i+=1;const A=e[i+1]|e[i]<<8;i+=2;const s=e.slice(i,i+A);if(console.log(Uint8Array.from(s)),i+=A,e[i]!==J)return t;i+=2,i+=1;const n=e[i+1]|e[i]<<8;i+=2;const a=e.slice(i,i+n);console.log(Uint8Array.from(a));let d=Uint8Array.from(s),c=class{static parseSPS(e){}}.parseSPS(d);return t.codecWidth=c.codec_size.width,t.codecHeight=c.codec_size.height,t.presentWidth=c.present_size.width,t.presentHeight=c.present_size.height,t.profile=c.profile_string,t.level=c.level_string,t.bitDepth=c.bit_depth,t.chromaFormat=c.chroma_format,t.sarRatio=c.sar_ratio,t}(r));const s={id:1,type:"video",timescale:1e3,duration:0,avcc:r,codecWidth:A.codecWidth,codecHeight:A.codecHeight,videoType:A.videoType},n=Xe.generateInitSegment(s);this.isAvc=!0,this.appendBuffer(n.buffer),this.sequenceNumber=0,this.cacheTrack=null,this.timeInit=!1}_decodeVideo(e,t,i){const o=this.player;let r=e.slice(5),A=r.byteLength,s=t;const n=o.video.$videoElement;if(n.buffered.length>1&&(this.removeBuffer(n.buffered.start(0),n.buffered.end(0)),this.timeInit=!1),this.dropping&&s-this.cacheTrack.dts>1e3)this.dropping=!1,this.cacheTrack={};else if(this.cacheTrack&&s>this.cacheTrack.dts){let e=8+this.cacheTrack.size,i=new Uint8Array(e);i[0]=e>>>24&255,i[1]=e>>>16&255,i[2]=e>>>8&255,i[3]=255&e,i.set(Xe.types.mdat,4),i.set(this.cacheTrack.data,8),this.cacheTrack.duration=s-this.cacheTrack.dts;let r=Xe.moof(this.cacheTrack,this.cacheTrack.dts),A=new Uint8Array(r.byteLength+i.byteLength);A.set(r,0),A.set(i,r.byteLength),this.appendBuffer(A.buffer),o.handleRender(),o.updateStats({fps:!0,ts:t,buf:o.demux.delay}),o._times.videoStart||(o._times.videoStart=he(),o.handlePlayToRenderTimes())}else o.debug.log("MediaSource","timeInit set false , cacheTrack = {}"),this.timeInit=!1,this.cacheTrack={};this.cacheTrack.id=1,this.cacheTrack.sequenceNumber=++this.sequenceNumber,this.cacheTrack.size=A,this.cacheTrack.dts=s,this.cacheTrack.cts=0,this.cacheTrack.isKeyframe=i,this.cacheTrack.data=r,this.cacheTrack.flags={isLeading:0,dependsOn:i?2:1,isDependedOn:i?1:0,hasRedundancy:0,isNonSync:i?0:1},this.timeInit||1!==n.buffered.length||(o.debug.log("MediaSource","timeInit set true"),this.timeInit=!0,n.currentTime=n.buffered.end(0)),!this.isInitInfo&&n.videoWidth>0&&n.videoHeight>0&&(o.debug.log("MediaSource",`updateVideoInfo: ${n.videoWidth},${n.videoHeight}`),o.video.updateVideoInfo({width:n.videoWidth,height:n.videoHeight}),o.video.initCanvasViewSize(),this.isInitInfo=!0)}appendBuffer(e){const{debug:t,events:{proxy:i}}=this.player;null===this.sourceBuffer&&(this.sourceBuffer=this.mediaSource.addSourceBuffer($),i(this.sourceBuffer,"error",(e=>{this.player.emit(T.mseSourceBufferError,e)}))),!1===this.sourceBuffer.updating&&this.isStateOpen?this.sourceBuffer.appendBuffer(e):this.isStateClosed?this.player.emit(T.mseSourceBufferError,"mediaSource is not attached to video or mediaSource is closed"):this.isStateEnded?this.player.emit(T.mseSourceBufferError,"mediaSource is closed"):!0===this.sourceBuffer.updating&&this.player.emit(T.mseSourceBufferBusy)}stop(){this.isStateOpen&&this.sourceBuffer&&this.sourceBuffer.abort(),this.endOfStream()}dropSourceBuffer(e){const t=this.player.video.$videoElement;this.dropping=e,t.buffered.length>0&&t.buffered.end(0)-t.currentTime>1&&(t.currentTime=t.buffered.end(0))}removeBuffer(e,t){if(this.isStateOpen&&!1===this.sourceBuffer.updating)try{this.sourceBuffer.remove(e,t)}catch(e){console.error(e)}}endOfStream(){this.isStateOpen&&this.mediaSource.endOfStream()}}const _e=()=>"undefined"!=typeof navigator&&parseFloat((""+(/CPU.*OS ([0-9_]{3,4})[0-9_]{0,1}|(CPU like).*AppleWebKit.*Mobile/i.exec(navigator.userAgent)||[0,""])[1]).replace("undefined","3_2").replace("_",".").replace("_",""))<10&&!window.MSStream,$e=()=>"wakeLock"in navigator;class et{constructor(e){if(this.player=e,this.enabled=!1,$e()){this._wakeLock=null;const e=()=>{null!==this._wakeLock&&"visible"===document.visibilityState&&this.enable()};document.addEventListener("visibilitychange",e),document.addEventListener("fullscreenchange",e)}else _e()?this.noSleepTimer=null:(this.noSleepVideo=document.createElement("video"),this.noSleepVideo.setAttribute("title","No Sleep"),this.noSleepVideo.setAttribute("playsinline",""),this._addSourceToVideo(this.noSleepVideo,"webm","data:video/webm;base64,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"),this._addSourceToVideo(this.noSleepVideo,"mp4","data:video/mp4;base64,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"),this.noSleepVideo.addEventListener("loadedmetadata",(()=>{this.noSleepVideo.duration<=1?this.noSleepVideo.setAttribute("loop",""):this.noSleepVideo.addEventListener("timeupdate",(()=>{this.noSleepVideo.currentTime>.5&&(this.noSleepVideo.currentTime=Math.random())}))})))}_addSourceToVideo(e,t,i){var o=document.createElement("source");o.src=i,o.type=`video/${t}`,e.appendChild(o)}get isEnabled(){return this.enabled}enable(){const e=this.player.debug;if($e())return navigator.wakeLock.request("screen").then((t=>{this._wakeLock=t,this.enabled=!0,e.log("wakeLock","Wake Lock active."),this._wakeLock.addEventListener("release",(()=>{e.log("wakeLock","Wake Lock released.")}))})).catch((t=>{throw this.enabled=!1,e.error("wakeLock",`${t.name}, ${t.message}`),t}));if(_e())return this.disable(),this.noSleepTimer=window.setInterval((()=>{document.hidden||(window.location.href=window.location.href.split("#")[0],window.setTimeout(window.stop,0))}),15e3),this.enabled=!0,Promise.resolve();return this.noSleepVideo.play().then((e=>(this.enabled=!0,e))).catch((e=>{throw this.enabled=!1,e}))}disable(){const e=this.player.debug;$e()?(this._wakeLock&&this._wakeLock.release(),this._wakeLock=null):_e()?this.noSleepTimer&&(e.warn("wakeLock","NoSleep now disabled for older iOS devices."),window.clearInterval(this.noSleepTimer),this.noSleepTimer=null):this.noSleepVideo.pause(),this.enabled=!1}}class tt extends Be{constructor(e,t){var i;super(),this.$container=e,this._opt=Object.assign({},d,t),this.debug=new ne(this),this._opt.useWCS&&(this._opt.useWCS="VideoEncoder"in window),this._opt.useMSE&&(this._opt.useMSE=window.MediaSource&&window.MediaSource.isTypeSupported($)),this._opt.useMSE?(this._opt.useWCS&&this.debug.log("Player","useWCS set true->false"),this._opt.forceNoOffscreen||this.debug.log("Player","forceNoOffscreen set false->true"),this._opt.useWCS=!1,this._opt.forceNoOffscreen=!0):this._opt.useWCS,this._opt.forceNoOffscreen||("undefined"==typeof OffscreenCanvas?(this._opt.forceNoOffscreen=!0,this._opt.useOffscreen=!1):this._opt.useOffscreen=!0),this._opt.hasAudio||(this._opt.operateBtns.audio=!1),this._opt.hasControl=this._hasControl(),this._loading=!1,this._playing=!1,this._hasLoaded=!1,this._checkHeartTimeout=null,this._checkLoadingTimeout=null,this._startBpsTime=null,this._isPlayingBeforePageHidden=!1,this._stats={buf:0,fps:0,abps:0,vbps:0,ts:0},this._times={playInitStart:"",playStart:"",streamStart:"",streamResponse:"",demuxStart:"",decodeStart:"",videoStart:"",playTimestamp:"",streamTimestamp:"",streamResponseTimestamp:"",demuxTimestamp:"",decodeTimestamp:"",videoTimestamp:"",allTimestamp:""},this._videoTimestamp=0,this._audioTimestamp=0,i=this,Object.defineProperty(i,"rect",{get:()=>{const e=i.$container.getBoundingClientRect();return e.width=Math.max(e.width,i.$container.clientWidth),e.height=Math.max(e.height,i.$container.clientHeight),e}}),["bottom","height","left","right","top","width"].forEach((e=>{Object.defineProperty(i,e,{get:()=>i.rect[e]})})),this.events=new ae(this),this.video=new Te(this),this._opt.hasAudio&&(this.audio=new xe(this)),this.recorder=new Ve(this),this._onlyMseOrWcsVideo()?this.loaded=!0:this.decoderWorker=new Oe(this),this.stream=null,this.demux=null,this._opt.useWCS&&(this.webcodecsDecoder=new Je(this)),this._opt.useMSE&&(this.mseDecoder=new Ke(this)),this.control=new He(this),this.keepScreenOn=new et(this),(e=>{try{const t=()=>{e.emit(I.fullscreen,e.fullscreen),e.fullscreen?e._opt.useMSE&&e.resize():e.resize()};de.on("change",t),e.events.destroys.push((()=>{de.off("change",t)}))}catch(e){}if(e.on(T.decoderWorkerInit,(()=>{e.debug.log("player","has loaded"),e.loaded=!0})),e.on(T.play,(()=>{e.loading=!1})),e.on(T.fullscreen,(t=>{if(t)try{de.request(e.$container).then((()=>{})).catch((t=>{e.webFullscreen=!0}))}catch(t){e.webFullscreen=!0}else try{de.exit().then((()=>{})).catch((()=>{e.webFullscreen=!1}))}catch(t){e.webFullscreen=!1}})),e.on(T.webFullscreen,(t=>{t?e.$container.classList.add("jessibuca-fullscreen-web"):e.$container.classList.remove("jessibuca-fullscreen-web")})),e.on(T.resize,(()=>{e.video.resize()})),e._opt.debug){const t=[T.timeUpdate];Object.keys(T).forEach((i=>{e.on(T[i],(o=>{t.includes(i)||e.debug.log("player events",T[i],o)}))})),Object.keys(x).forEach((t=>{e.on(x[t],(i=>{e.debug.log("player event error",x[t],i)}))}))}})(this),(e=>{const{_opt:t,debug:i,events:{proxy:o}}=e;t.supportDblclickFullscreen&&o(e.$container,"dblclick",(()=>{e.fullscreen=!e.fullscreen})),o(document,"visibilitychange",(()=>{t.hiddenAutoPause&&(i.log("visibilitychange",document.visibilityState,e._isPlayingBeforePageHidden),"visible"===document.visibilityState?e._isPlayingBeforePageHidden&&e.play():(e._isPlayingBeforePageHidden=e.playing,e.playing&&e.pause()))})),o(window,"fullscreenchange",(()=>{null!==e.keepScreenOn&&"visible"===document.visibilityState&&e.enableWakeLock()}))})(this),this._opt.useWCS&&this.debug.log("Player","use WCS"),this._opt.useMSE&&this.debug.log("Player","use MSE"),this._opt.useOffscreen&&this.debug.log("Player","use offscreen"),this.debug.log("Player options",this._opt)}destroy(){this._loading=!1,this._playing=!1,this._hasLoaded=!1,this._times={playInitStart:"",playStart:"",streamStart:"",streamResponse:"",demuxStart:"",decodeStart:"",videoStart:"",playTimestamp:"",streamTimestamp:"",streamResponseTimestamp:"",demuxTimestamp:"",decodeTimestamp:"",videoTimestamp:"",allTimestamp:""},this.decoderWorker&&(this.decoderWorker.destroy(),this.decoderWorker=null),this.video&&(this.video.destroy(),this.video=null),this.audio&&(this.audio.destroy(),this.audio=null),this.stream&&(this.stream.destroy(),this.stream=null),this.recorder&&(this.recorder.destroy(),this.recorder=null),this.control&&(this.control.destroy(),this.control=null),this.webcodecsDecoder&&(this.webcodecsDecoder.destroy(),this.webcodecsDecoder=null),this.mseDecoder&&(this.mseDecoder.destroy(),this.mseDecoder=null),this.demux&&(this.demux.destroy(),this.demux=null),this.events&&(this.events.destroy(),this.events=null),this.clearCheckHeartTimeout(),this.clearCheckLoadingTimeout(),this.releaseWakeLock(),this.keepScreenOn=null,this.resetStats(),this._audioTimestamp=0,this._videoTimestamp=0,this.emit("destroy"),this.off(),this.debug.log("play","destroy end")}set fullscreen(e){ye()?(this.emit(T.webFullscreen,e),setTimeout((()=>{this.updateOption({rotate:e?270:0}),this.resize()}),10)):this.emit(T.fullscreen,e)}get fullscreen(){return document.isFullScreen||document.mozIsFullScreen||document.webkitIsFullScreen||this.webFullscreen}set webFullscreen(e){this.emit(T.webFullscreen,e)}get webFullscreen(){return this.$container.classList.contains("jessibuca-fullscreen-web")}set loaded(e){this._hasLoaded=e}get loaded(){return this._hasLoaded}set playing(e){e&&(this.loading=!1),this.playing!==e&&(this._playing=e,this.emit(T.playing,e),this.emit(T.volumechange,this.volume),e?this.emit(T.play):this.emit(T.pause))}get playing(){return this._playing}get volume(){return this.audio&&this.audio.volume||0}set volume(e){this.audio&&this.audio.setVolume(e)}set loading(e){this.loading!==e&&(this._loading=e,this.emit(T.loading,this._loading))}get loading(){return this._loading}set recording(e){this.playing&&(e?this.recorder.startRecord():this.recorder.stopRecordAndSave())}get recording(){return this.recorder&&this.recorder.recording}set audioTimestamp(e){null!==e&&(this._audioTimestamp=e)}get audioTimestamp(){return this._audioTimestamp}set videoTimestamp(e){null!==e&&(this._videoTimestamp=e,this._opt.useWCS||this._opt.useMSE||this.audioTimestamp&&this.videoTimestamp&&this.audio&&this.audio.emit(T.videoSyncAudio,{audioTimestamp:this.audioTimestamp,videoTimestamp:this.videoTimestamp,diff:this.audioTimestamp-this.videoTimestamp}))}get videoTimestamp(){return this._videoTimestamp}updateOption(e){this._opt=Object.assign({},this._opt,e)}init(){return new Promise(((e,t)=>{this.stream||(this.stream=new Le(this)),this.demux||(this.demux=new Ge(this)),this._opt.useWCS&&(this.webcodecsDecoder||(this.webcodecsDecoder=new Je(this))),this._opt.useMSE&&(this.mseDecoder||(this.mseDecoder=new Ke(this))),this.decoderWorker||this._onlyMseOrWcsVideo()?e():(this.decoderWorker=new Oe(this),this.once(T.decoderWorkerInit,(()=>{e()})))}))}play(e){return new Promise(((t,i)=>{if(!e&&!this._opt.url)return i();this.loading=!0,this.playing=!1,this._times.playInitStart=he(),e||(e=this._opt.url),this._opt.url=e,this.clearCheckHeartTimeout(),this.init().then((()=>{this._times.playStart=he(),this._opt.isNotMute&&this.mute(!1),this.webcodecsDecoder&&this.webcodecsDecoder.once(x.webcodecsH265NotSupport,(()=>{this.emit(x.webcodecsH265NotSupport),this._opt.autoWasm||this.emit(T.error,x.webcodecsH265NotSupport)})),this.mseDecoder&&this.mseDecoder.once(x.mediaSourceH265NotSupport,(()=>{this.emit(x.mediaSourceH265NotSupport),this._opt.autoWasm||this.emit(T.error,x.mediaSourceH265NotSupport)})),this.enableWakeLock(),this.stream.fetchStream(e),this.checkLoadingTimeout(),this.stream.once(x.fetchError,(e=>{i(e)})),this.stream.once(x.websocketError,(e=>{i(e)})),this.stream.once(T.streamSuccess,(()=>{t(),this._times.streamResponse=he(),this._opt.useMSE&&this.video.play()}))})).catch((e=>{i(e)}))}))}close(){return new Promise(((e,t)=>{this._close().then((()=>{this.video.clearView(),e()}))}))}_close(){return new Promise(((e,t)=>{this.stream&&(this.stream.destroy(),this.stream=null),this.demux&&(this.demux.destroy(),this.demux=null),this.decoderWorker&&(this.decoderWorker.destroy(),this.decoderWorker=null),this.webcodecsDecoder&&(this.webcodecsDecoder.destroy(),this.webcodecsDecoder=null),this.mseDecoder&&(this.mseDecoder.destroy(),this.mseDecoder=null),this.clearCheckHeartTimeout(),this.clearCheckLoadingTimeout(),this.playing=!1,this.loading=!1,this.recording=!1,this.audio&&this.audio.pause(),this.releaseWakeLock(),this.resetStats(),this._audioTimestamp=0,this._videoTimestamp=0,this._times={playInitStart:"",playStart:"",streamStart:"",streamResponse:"",demuxStart:"",decodeStart:"",videoStart:"",playTimestamp:"",streamTimestamp:"",streamResponseTimestamp:"",demuxTimestamp:"",decodeTimestamp:"",videoTimestamp:"",allTimestamp:""},setTimeout((()=>{e()}),0)}))}pause(e){return e?this.close():this._close()}mute(e){this.audio&&this.audio.mute(e)}resize(){this.video.resize()}startRecord(e,t){this.recording||(this.recorder.setFileName(e,t),this.recording=!0)}stopRecordAndSave(){this.recording&&(this.recording=!1)}_hasControl(){let e=!1,t=!1;return Object.keys(this._opt.operateBtns).forEach((e=>{this._opt.operateBtns[e]&&(t=!0)})),(this._opt.showBandwidth||this._opt.text||t)&&(e=!0),e}_onlyMseOrWcsVideo(){return!1===this._opt.hasAudio&&(this._opt.useMSE||this._opt.useWCS&&!this._opt.useOffscreen)}checkHeart(){this.clearCheckHeartTimeout(),this.checkHeartTimeout()}checkHeartTimeout(){this._checkHeartTimeout=setTimeout((()=>{this.pause(!1).then((()=>{this.emit(T.timeout,T.delayTimeout),this.emit(T.delayTimeout)}))}),1e3*this._opt.heartTimeout)}clearCheckHeartTimeout(){this._checkHeartTimeout&&(clearTimeout(this._checkHeartTimeout),this._checkHeartTimeout=null)}checkLoadingTimeout(){this._checkLoadingTimeout=setTimeout((()=>{this.pause(!1).then((()=>{this.emit(T.timeout,T.loadingTimeout),this.emit(T.loadingTimeout)}))}),1e3*this._opt.loadingTimeout)}clearCheckLoadingTimeout(){this._checkLoadingTimeout&&(clearTimeout(this._checkLoadingTimeout),this._checkLoadingTimeout=null)}handleRender(){this.loading&&(this.emit(T.start),this.loading=!1,this.clearCheckLoadingTimeout()),this.playing||(this.playing=!0),this.checkHeart()}updateStats(e){e=e||{},this._startBpsTime||(this._startBpsTime=he()),Ee(e.ts)&&(this._stats.ts=e.ts),Ee(e.buf)&&(this._stats.buf=e.buf),e.fps&&(this._stats.fps+=1),e.abps&&(this._stats.abps+=e.abps),e.vbps&&(this._stats.vbps+=e.vbps);const t=he();t-this._startBpsTime<1e3||(this.emit(T.stats,this._stats),this.emit(T.performance,function(e){let t=0;return e>=24?t=2:e>=15&&(t=1),t}(this._stats.fps)),this._stats.fps=0,this._stats.abps=0,this._stats.vbps=0,this._startBpsTime=t)}resetStats(){this._startBpsTime=null,this._stats={buf:0,fps:0,abps:0,vbps:0,ts:0}}enableWakeLock(){this._opt.keepScreenOn&&this.keepScreenOn.enable()}releaseWakeLock(){this._opt.keepScreenOn&&this.keepScreenOn.disable()}handlePlayToRenderTimes(){const e=this._times;e.playTimestamp=e.playStart-e.playInitStart,e.streamTimestamp=e.streamStart-e.playStart,e.streamResponseTimestamp=e.streamResponse-e.streamStart,e.demuxTimestamp=e.demuxStart-e.streamResponse,e.decodeTimestamp=e.decodeStart-e.demuxStart,e.videoTimestamp=e.videoStart-e.decodeStart,e.allTimestamp=e.videoStart-e.playInitStart,this.emit(T.playToRenderTimes,e)}}class it extends Be{constructor(e){super();let t=e,i=e.container;if("string"==typeof e.container&&(i=document.querySelector(e.container)),!i)throw new Error("Jessibuca need container option");i.classList.add("jessibuca-container"),delete t.container,Ee(t.videoBuffer)&&(t.videoBuffer=1e3*Number(t.videoBuffer)),Ee(t.timeout)&&(Se(t.loadingTimeout)&&(t.loadingTimeout=t.timeout),Se(t.heartTimeout)&&(t.heartTimeout=t.timeout)),this._opt=t,this.$container=i,this._loadingTimeoutReplayTimes=0,this._heartTimeoutReplayTimes=0,this.events=new ae(this),this._initPlayer(i,t)}destroy(){this.events&&(this.events.destroy(),this.events=null),this.player&&(this.player.destroy(),this.player=null),this.$container=null,this._opt=null,this._loadingTimeoutReplayTimes=0,this._heartTimeoutReplayTimes=0,this.off()}_initPlayer(e,t){this.player=new tt(e,t),this._bindEvents()}_resetPlayer(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this.player.destroy(),this.player=null;const t=Object.assign(this._opt,e);this._initPlayer(this.$container,t)}_bindEvents(){Object.keys(I).forEach((e=>{this.player.on(I[e],(t=>{this.emit(e,t)}))}))}setDebug(e){this.player.updateOption({isDebug:!!e})}mute(){this.player.mute(!0)}cancelMute(){this.player.mute(!1)}setVolume(e){this.player.volume=e}audioResume(){this.player.audio&&this.player.audio.audioEnabled(!0)}setTimeout(e){e=Number(e),this.player.updateOption({timeout:e,loadingTimeout:e,heartTimeout:e})}setScaleMode(e){let t={isFullResize:!1,isResize:!1};switch(e=Number(e)){case N:t.isFullResize=!1,t.isResize=!1;break;case P:t.isFullResize=!1,t.isResize=!0;break;case z:t.isFullResize=!0,t.isResize=!0}this.player.updateOption(t),this.resize()}pause(){return this.player.pause()}close(){return this._opt.url="",this.player.close()}clearView(){this.player.video.clearView()}play(e){return new Promise(((t,i)=>{if(!e&&!this._opt.url)return this.emit(T.error,x.playError),void i();if(e){if(!this._opt.url)return this._play(e);e===this._opt.url?this.player.playing?t():(this.clearView(),this.player.play(this._opt.url).then((()=>{t()})).catch((()=>{this.player.pause().then((()=>{i()}))}))):this.player.pause().then((()=>(this.clearView(),this._play(e)))).catch((()=>{i()}))}else this.player.play(this._opt.url).then((()=>{t()})).catch((()=>{this.player.pause().then((()=>{i()}))}))}))}_play(e){return new Promise(((t,i)=>{this._opt.url=e;const o=0===e.indexOf("http"),r=o?s:A,d=o||-1!==e.indexOf(".flv")||this._opt.isFlv?n:a;this.player.updateOption({protocol:r,demuxType:d}),this.player.once(x.mediaSourceH265NotSupport,(()=>{this.close().then((()=>{this.player._opt.autoWasm&&(this.player.debug.log("Jessibuca","auto wasm [mse-> wasm] reset player and play"),this._resetPlayer({useMSE:!1}),this.play(e).then((()=>{this.player.debug.log("Jessibuca","auto wasm [mse-> wasm] reset player and play success")})).catch((()=>{this.player.debug.log("Jessibuca","auto wasm [mse-> wasm] reset player and play error")})))}))})),this.player.once(x.webcodecsH265NotSupport,(()=>{this.close().then((()=>{this.player._opt.autoWasm&&(this.player.debug.log("Jessibuca","auto wasm [wcs-> wasm] reset player and play"),this._resetPlayer({useWCS:!1}),this.play(e).then((()=>{this.player.debug.log("Jessibuca","auto wasm [wcs-> wasm] reset player and play success")})).catch((()=>{this.player.debug.log("Jessibuca","auto wasm [wcs-> wasm] reset player and play error")})))}))})),this.player.once(x.wasmDecodeError,(()=>{this.player._opt.wasmDecodeErrorReplay&&this.close().then((()=>{this.player.debug.log("Jessibuca","wasm decode error and reset player and play"),this._resetPlayer({useWCS:!1}),this.play(e).then((()=>{this.player.debug.log("Jessibuca","wasm decode error and reset player and play success")})).catch((()=>{this.player.debug.log("Jessibuca","wasm decode error and reset player and play error")}))}))})),this.player.once(T.delayTimeout,(()=>{this.player._opt.heartTimeoutReplay&&this._heartTimeoutReplayTimes<this.player._opt.heartTimeoutReplayTimes&&(this._heartTimeoutReplayTimes+=1,this.play(e).then((()=>{this._heartTimeoutReplayTimes=0})).catch((()=>{})))})),this.player.once(T.loadingTimeout,(()=>{this.player._opt.loadingTimeoutReplay&&this._loadingTimeoutReplayTimes<this.player._opt.loadingTimeoutReplayTimes&&(this._loadingTimeoutReplayTimes+=1,this.play(e).then((()=>{this._loadingTimeoutReplayTimes=0})).catch((()=>{})))})),this.hasLoaded()?this.player.play(e).then((()=>{t()})).catch((()=>{this.player.pause().then((()=>{i()}))})):this.player.once(T.decoderWorkerInit,(()=>{this.player.play(e).then((()=>{t()})).catch((()=>{this.player.pause().then((()=>{i()}))}))}))}))}resize(){this.player.resize()}setBufferTime(e){e=Number(e),this.player.updateOption({videoBuffer:1e3*e}),this.player.decoderWorker&&this.player.decoderWorker.updateWorkConfig({key:"videoBuffer",value:1e3*e})}setRotate(e){e=parseInt(e,10);this._opt.rotate!==e&&-1!==[0,90,270].indexOf(e)&&(this.player.updateOption({rotate:e}),this.resize())}hasLoaded(){return this.player.loaded}setKeepScreenOn(){this.player.updateOption({keepScreenOn:!0})}setFullscreen(e){const t=!!e;this.player.fullscreen!==t&&(this.player.fullscreen=t)}screenshot(e,t,i,o){return this.player.video.screenshot(e,t,i,o)}startRecord(e,t){return new Promise(((i,o)=>{this.player.playing?(this.player.startRecord(e,t),i()):o()}))}stopRecordAndSave(){this.player.recording&&this.player.stopRecordAndSave()}isPlaying(){return this.player.playing}isMute(){return!this.player.audio||this.player.audio.isMute}isRecording(){return this.player.recorder.recording}}return r(it,"ERROR",x),r(it,"TIMEOUT",{loadingTimeout:T.loadingTimeout,delayTimeout:T.delayTimeout}),window.Jessibuca=it,it})); | 1 | +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).jessibuca=t()}(this,(function(){"use strict";var e="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function t(e,t){return e(t={exports:{}},t.exports),t.exports}var i,o=t((function(e){e.exports=function(e,t,i){return t in e?Object.defineProperty(e,t,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[t]=i,e},e.exports.__esModule=!0,e.exports.default=e.exports})),r=(i=o)&&i.__esModule&&Object.prototype.hasOwnProperty.call(i,"default")?i.default:i;const s=0,a=1,n="flv",A="m7s",d="mp4",c="webm",l={videoBuffer:1e3,videoBufferDelay:1e3,isResize:!0,isFullResize:!1,isFlv:!1,debug:!1,hotKey:!1,loadingTimeout:10,heartTimeout:5,timeout:10,loadingTimeoutReplay:!0,heartTimeoutReplay:!1,loadingTimeoutReplayTimes:3,heartTimeoutReplayTimes:3,supportDblclickFullscreen:!1,showBandwidth:!1,keepScreenOn:!1,isNotMute:!1,hasAudio:!0,hasVideo:!0,operateBtns:{fullscreen:!1,screenshot:!1,play:!1,audio:!1,record:!1},controlAutoHide:!1,hasControl:!1,loadingText:"",background:"",decoder:"decoder.js",url:"",rotate:0,forceNoOffscreen:!0,hiddenAutoPause:!1,protocol:a,demuxType:n,useWCS:!1,wcsUseVideoRender:!0,useMSE:!1,useOffscreen:!1,autoWasm:!0,wasmDecodeErrorReplay:!0,openWebglAlignment:!1,wasmDecodeAudioSyncVideo:!1,recordType:c,useWebFullScreen:!1},u="init",h="initVideo",p="render",m="playAudio",g="initAudio",f="audioCode",b="videoCode",y="wasmError",v="Invalid NAL unit size",w=1,S=2,E=8,B=9,C="init",R="decode",k="audioDecode",T="close",I="updateConfig",x={fullscreen:"fullscreen$2",webFullscreen:"webFullscreen",decoderWorkerInit:"decoderWorkerInit",play:"play",playing:"playing",pause:"pause",mute:"mute",load:"load",loading:"loading",videoInfo:"videoInfo",timeUpdate:"timeUpdate",audioInfo:"audioInfo",log:"log",error:"error",kBps:"kBps",timeout:"timeout",delayTimeout:"delayTimeout",loadingTimeout:"loadingTimeout",stats:"stats",performance:"performance",record:"record",recording:"recording",recordingTimestamp:"recordingTimestamp",recordStart:"recordStart",recordEnd:"recordEnd",recordCreateError:"recordCreateError",buffer:"buffer",videoFrame:"videoFrame",start:"start",metadata:"metadata",resize:"resize",streamEnd:"streamEnd",streamSuccess:"streamSuccess",streamMessage:"streamMessage",streamError:"streamError",volumechange:"volumechange",destroy:"destroy",mseSourceOpen:"mseSourceOpen",mseSourceClose:"mseSourceClose",mseSourceBufferError:"mseSourceBufferError",mseSourceBufferBusy:"mseSourceBufferBusy",mseSourceBufferFull:"mseSourceBufferFull",videoWaiting:"videoWaiting",videoTimeUpdate:"videoTimeUpdate",videoSyncAudio:"videoSyncAudio",playToRenderTimes:"playToRenderTimes"},D={load:x.load,timeUpdate:x.timeUpdate,videoInfo:x.videoInfo,audioInfo:x.audioInfo,error:x.error,kBps:x.kBps,log:x.log,start:x.start,timeout:x.timeout,loadingTimeout:x.loadingTimeout,delayTimeout:x.delayTimeout,fullscreen:"fullscreen",webFullscreen:x.webFullscreen,play:x.play,pause:x.pause,mute:x.mute,stats:x.stats,performance:x.performance,recordingTimestamp:x.recordingTimestamp,recordStart:x.recordStart,recordEnd:x.recordEnd,playToRenderTimes:x.playToRenderTimes},j={playError:"playIsNotPauseOrUrlIsNull",fetchError:"fetchError",websocketError:"websocketError",webcodecsH265NotSupport:"webcodecsH265NotSupport",webcodecsDecodeError:"webcodecsDecodeError",webcodecsWidthOrHeightChange:"webcodecsWidthOrHeightChange",mediaSourceH265NotSupport:"mediaSourceH265NotSupport",mediaSourceFull:x.mseSourceBufferFull,mseSourceBufferError:x.mseSourceBufferError,mediaSourceAppendBufferError:"mediaSourceAppendBufferError",mediaSourceBufferListLarge:"mediaSourceBufferListLarge",mediaSourceAppendBufferEndTimeout:"mediaSourceAppendBufferEndTimeout",wasmDecodeError:"wasmDecodeError",webglAlignmentError:"webglAlignmentError"},L="notConnect",F="open",O="close",V="error",M={download:"download",base64:"base64",blob:"blob"},U={7:"H264(AVC)",12:"H265(HEVC)"},Q=12,W={10:"AAC",7:"ALAW",8:"MULAW"},J=38,P=0,G=1,N=2,z="webcodecs",H="webgl",Y="offscreen",X="key",q="delta",Z='video/mp4; codecs="avc1.64002A"',K="ended",_="open",$="closed",ee=1e3,te=27,ie=38,oe=40,re="A key frame is required after configure() or flush()",se="The user aborted a request",ae="AbortError",ne="AbortError";class Ae{constructor(e){this.log=function(t){if(e._opt.debug){for(var i=arguments.length,o=new Array(i>1?i-1:0),r=1;r<i;r++)o[r-1]=arguments[r];console.log(`Jessibuca: [${t}]`,...o)}},this.warn=function(t){if(e._opt.debug){for(var i=arguments.length,o=new Array(i>1?i-1:0),r=1;r<i;r++)o[r-1]=arguments[r];console.warn(`Jessibuca: [${t}]`,...o)}},this.error=function(e){for(var t=arguments.length,i=new Array(t>1?t-1:0),o=1;o<t;o++)i[o-1]=arguments[o];console.error(`Jessibuca: [${e}]`,...i)}}}class de{constructor(e){this.destroys=[],this.proxy=this.proxy.bind(this),this.master=e}proxy(e,t,i){let o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};if(!e)return;if(Array.isArray(t))return t.map((t=>this.proxy(e,t,i,o)));e.addEventListener(t,i,o);const r=()=>e.removeEventListener(t,i,o);return this.destroys.push(r),r}destroy(){this.master.debug&&this.master.debug.log("Events","destroy"),this.destroys.forEach((e=>e()))}}var ce=t((function(e){!function(){var t="undefined"!=typeof window&&void 0!==window.document?window.document:{},i=e.exports,o=function(){for(var e,i=[["requestFullscreen","exitFullscreen","fullscreenElement","fullscreenEnabled","fullscreenchange","fullscreenerror"],["webkitRequestFullscreen","webkitExitFullscreen","webkitFullscreenElement","webkitFullscreenEnabled","webkitfullscreenchange","webkitfullscreenerror"],["webkitRequestFullScreen","webkitCancelFullScreen","webkitCurrentFullScreenElement","webkitCancelFullScreen","webkitfullscreenchange","webkitfullscreenerror"],["mozRequestFullScreen","mozCancelFullScreen","mozFullScreenElement","mozFullScreenEnabled","mozfullscreenchange","mozfullscreenerror"],["msRequestFullscreen","msExitFullscreen","msFullscreenElement","msFullscreenEnabled","MSFullscreenChange","MSFullscreenError"]],o=0,r=i.length,s={};o<r;o++)if((e=i[o])&&e[1]in t){for(o=0;o<e.length;o++)s[i[0][o]]=e[o];return s}return!1}(),r={change:o.fullscreenchange,error:o.fullscreenerror},s={request:function(e,i){return new Promise(function(r,s){var a=function(){this.off("change",a),r()}.bind(this);this.on("change",a);var n=(e=e||t.documentElement)[o.requestFullscreen](i);n instanceof Promise&&n.then(a).catch(s)}.bind(this))},exit:function(){return new Promise(function(e,i){if(this.isFullscreen){var r=function(){this.off("change",r),e()}.bind(this);this.on("change",r);var s=t[o.exitFullscreen]();s instanceof Promise&&s.then(r).catch(i)}else e()}.bind(this))},toggle:function(e,t){return this.isFullscreen?this.exit():this.request(e,t)},onchange:function(e){this.on("change",e)},onerror:function(e){this.on("error",e)},on:function(e,i){var o=r[e];o&&t.addEventListener(o,i,!1)},off:function(e,i){var o=r[e];o&&t.removeEventListener(o,i,!1)},raw:o};o?(Object.defineProperties(s,{isFullscreen:{get:function(){return Boolean(t[o.fullscreenElement])}},element:{enumerable:!0,get:function(){return t[o.fullscreenElement]}},isEnabled:{enumerable:!0,get:function(){return Boolean(t[o.fullscreenEnabled])}}}),i?e.exports=s:window.screenfull=s):i?e.exports={isEnabled:!1}:window.screenfull={isEnabled:!1}}()}));function le(){}function ue(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";const t=e.split(","),i=atob(t[1]),o=t[0].replace("data:","").replace(";base64","");let r=i.length,s=new Uint8Array(r);for(;r--;)s[r]=i.charCodeAt(r);return new File([s],"file",{type:o})}function he(){return(new Date).getTime()}function pe(e,t,i){return Math.max(Math.min(e,Math.max(t,i)),Math.min(t,i))}function me(e,t,i){if(e)return"object"==typeof t&&Object.keys(t).forEach((i=>{me(e,i,t[i])})),e.style[t]=i,e}function ge(e,t){let i=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];if(!e)return 0;const o=getComputedStyle(e,null).getPropertyValue(t);return i?parseFloat(o):o}function fe(){return performance&&"function"==typeof performance.now?performance.now():Date.now()}function be(e){let t=0,i=fe();return o=>{t+=o;const r=fe(),s=r-i;s>=1e3&&(e(t/s*1e3),i=r,t=0)}}function ye(){return/iphone|ipod|android.*mobile|windows.*phone|blackberry.*mobile/i.test(window.navigator.userAgent.toLowerCase())}function ve(e){if(null==e||""===e||0===parseInt(e)||isNaN(parseInt(e)))return"0KB/s";let t=parseFloat(e);return t=t.toFixed(2),t+"KB/s"}function we(e){return null==e}function Se(e){return!we(e)}function Ee(e){const t=e||window.event;return t.target||t.srcElement}ce.isEnabled,(()=>{try{if("object"==typeof WebAssembly&&"function"==typeof WebAssembly.instantiate){const e=new WebAssembly.Module(Uint8Array.of(0,97,115,109,1,0,0,0));if(e instanceof WebAssembly.Module)return new WebAssembly.Instance(e)instanceof WebAssembly.Instance}}catch(e){}})();class Be{on(e,t,i){const o=this.e||(this.e={});return(o[e]||(o[e]=[])).push({fn:t,ctx:i}),this}once(e,t,i){const o=this;function r(){o.off(e,r);for(var s=arguments.length,a=new Array(s),n=0;n<s;n++)a[n]=arguments[n];t.apply(i,a)}return r._=t,this.on(e,r,i)}emit(e){const t=((this.e||(this.e={}))[e]||[]).slice();for(var i=arguments.length,o=new Array(i>1?i-1:0),r=1;r<i;r++)o[r-1]=arguments[r];for(let e=0;e<t.length;e+=1)t[e].fn.apply(t[e].ctx,o);return this}off(e,t){const i=this.e||(this.e={});if(!e)return Object.keys(i).forEach((e=>{delete i[e]})),void delete this.e;const o=i[e],r=[];if(o&&t)for(let e=0,i=o.length;e<i;e+=1)o[e].fn!==t&&o[e].fn._!==t&&r.push(o[e]);return r.length?i[e]=r:delete i[e],this}}class Ce extends Be{constructor(){super(),this.init=!1}resetInit(){this.init=!1,this.videoInfo={width:"",height:"",encType:"",encTypeCode:""}}destroy(){this.resetInit(),this.player.$container.removeChild(this.$videoElement),this.off()}updateVideoInfo(e){e.encTypeCode&&(this.videoInfo.encType=U[e.encTypeCode]),e.width&&(this.videoInfo.width=e.width),e.height&&(this.videoInfo.height=e.height),this.videoInfo.encType&&this.videoInfo.height&&this.videoInfo.width&&!this.init&&(this.player.emit(x.videoInfo,this.videoInfo),this.init=!0)}play(){}pause(){}clearView(){}}var Re="object"==typeof window&&window.window===window?window:"object"==typeof self&&self.self===self?self:"object"==typeof global&&global.global===global?global:void 0;function ke(e,t,i){var o=new XMLHttpRequest;o.open("GET",e),o.responseType="blob",o.onload=function(){De(o.response,t,i)},o.onerror=function(){console.error("could not download file")},o.send()}function Te(e){var t=new XMLHttpRequest;t.open("HEAD",e,!1);try{t.send()}catch(e){}return t.status>=200&&t.status<=299}function Ie(e){try{e.dispatchEvent(new MouseEvent("click"))}catch(i){var t=document.createEvent("MouseEvents");t.initMouseEvent("click",!0,!0,window,0,0,0,80,20,!1,!1,!1,!1,0,null),e.dispatchEvent(t)}}var xe=Re.navigator&&/Macintosh/.test(navigator.userAgent)&&/AppleWebKit/.test(navigator.userAgent)&&!/Safari/.test(navigator.userAgent),De="object"!=typeof window||window!==Re?function(){}:"download"in HTMLAnchorElement.prototype&&!xe?function(e,t,i){var o=Re.URL||Re.webkitURL,r=document.createElementNS("http://www.w3.org/1999/xhtml","a");t=t||e.name||"download",r.download=t,r.rel="noopener","string"==typeof e?(r.href=e,r.origin!==location.origin?Te(r.href)?ke(e,t,i):Ie(r,r.target="_blank"):Ie(r)):(r.href=o.createObjectURL(e),setTimeout((function(){o.revokeObjectURL(r.href)}),4e4),setTimeout((function(){Ie(r)}),0))}:"msSaveOrOpenBlob"in navigator?function(e,t,i){if(t=t||e.name||"download","string"==typeof e)if(Te(e))ke(e,t,i);else{var o=document.createElement("a");o.href=e,o.target="_blank",setTimeout((function(){Ie(o)}))}else navigator.msSaveOrOpenBlob(function(e,t){return void 0===t?t={autoBom:!1}:"object"!=typeof t&&(console.warn("Deprecated: Expected third argument to be a object"),t={autoBom:!t}),t.autoBom&&/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(e.type)?new Blob([String.fromCharCode(65279),e],{type:e.type}):e}(e,i),t)}:function(e,t,i,o){if((o=o||open("","_blank"))&&(o.document.title=o.document.body.innerText="downloading..."),"string"==typeof e)return ke(e,t,i);var r="application/octet-stream"===e.type,s=/constructor/i.test(Re.HTMLElement)||Re.safari,a=/CriOS\/[\d]+/.test(navigator.userAgent);if((a||r&&s||xe)&&"undefined"!=typeof FileReader){var n=new FileReader;n.onloadend=function(){var e=n.result;e=a?e:e.replace(/^data:[^;]*;/,"data:attachment/file;"),o?o.location.href=e:location=e,o=null},n.readAsDataURL(e)}else{var A=Re.URL||Re.webkitURL,d=A.createObjectURL(e);o?o.location=d:location.href=d,o=null,setTimeout((function(){A.revokeObjectURL(d)}),4e4)}};class je extends Ce{constructor(e){super(),this.player=e;const t=document.createElement("canvas");t.style.position="absolute",t.style.top=0,t.style.left=0,this.$videoElement=t,e.$container.appendChild(this.$videoElement),this.context2D=null,this.contextGl=null,this.contextGlRender=null,this.contextGlDestroy=null,this.bitmaprenderer=null,this.renderType=null,this.videoInfo={width:"",height:"",encType:""},this._initCanvasRender(),this.player.debug.log("CanvasVideo","init")}destroy(){super.destroy(),this.contextGl&&(this.contextGl=null),this.context2D&&(this.context2D=null),this.contextGlRender&&(this.contextGlDestroy&&this.contextGlDestroy(),this.contextGlDestroy=null,this.contextGlRender=null),this.bitmaprenderer&&(this.bitmaprenderer=null),this.renderType=null,this.player.debug.log("CanvasVideoLoader","destroy")}_initContextGl(){this.contextGl=function(e){let t=null;const i=["webgl","experimental-webgl","moz-webgl","webkit-3d"];let o=0;for(;!t&&o<i.length;){const r=i[o];try{let i={preserveDrawingBuffer:!0};t=e.getContext(r,i)}catch(e){t=null}t&&"function"==typeof t.getParameter||(t=null),++o}return t}(this.$videoElement);const e=((e,t)=>{var i=["attribute vec4 vertexPos;","attribute vec4 texturePos;","varying vec2 textureCoord;","void main()","{","gl_Position = vertexPos;","textureCoord = texturePos.xy;","}"].join("\n"),o=["precision highp float;","varying highp vec2 textureCoord;","uniform sampler2D ySampler;","uniform sampler2D uSampler;","uniform sampler2D vSampler;","const mat4 YUV2RGB = mat4","(","1.1643828125, 0, 1.59602734375, -.87078515625,","1.1643828125, -.39176171875, -.81296875, .52959375,","1.1643828125, 2.017234375, 0, -1.081390625,","0, 0, 0, 1",");","void main(void) {","highp float y = texture2D(ySampler, textureCoord).r;","highp float u = texture2D(uSampler, textureCoord).r;","highp float v = texture2D(vSampler, textureCoord).r;","gl_FragColor = vec4(y, u, v, 1) * YUV2RGB;","}"].join("\n");t&&e.pixelStorei(e.UNPACK_ALIGNMENT,1);var r=e.createShader(e.VERTEX_SHADER);e.shaderSource(r,i),e.compileShader(r),e.getShaderParameter(r,e.COMPILE_STATUS)||console.log("Vertex shader failed to compile: "+e.getShaderInfoLog(r));var s=e.createShader(e.FRAGMENT_SHADER);e.shaderSource(s,o),e.compileShader(s),e.getShaderParameter(s,e.COMPILE_STATUS)||console.log("Fragment shader failed to compile: "+e.getShaderInfoLog(s));var a=e.createProgram();e.attachShader(a,r),e.attachShader(a,s),e.linkProgram(a),e.getProgramParameter(a,e.LINK_STATUS)||console.log("Program failed to compile: "+e.getProgramInfoLog(a)),e.useProgram(a);var n=e.createBuffer();e.bindBuffer(e.ARRAY_BUFFER,n),e.bufferData(e.ARRAY_BUFFER,new Float32Array([1,1,-1,1,1,-1,-1,-1]),e.STATIC_DRAW);var A=e.getAttribLocation(a,"vertexPos");e.enableVertexAttribArray(A),e.vertexAttribPointer(A,2,e.FLOAT,!1,0,0);var d=e.createBuffer();e.bindBuffer(e.ARRAY_BUFFER,d),e.bufferData(e.ARRAY_BUFFER,new Float32Array([1,0,0,0,1,1,0,1]),e.STATIC_DRAW);var c=e.getAttribLocation(a,"texturePos");function l(t,i){var o=e.createTexture();return e.bindTexture(e.TEXTURE_2D,o),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.bindTexture(e.TEXTURE_2D,null),e.uniform1i(e.getUniformLocation(a,t),i),o}e.enableVertexAttribArray(c),e.vertexAttribPointer(c,2,e.FLOAT,!1,0,0);var u=l("ySampler",0),h=l("uSampler",1),p=l("vSampler",2);return{render:function(t,i,o,r,s){e.viewport(0,0,t,i),e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,u),e.texImage2D(e.TEXTURE_2D,0,e.LUMINANCE,t,i,0,e.LUMINANCE,e.UNSIGNED_BYTE,o),e.activeTexture(e.TEXTURE1),e.bindTexture(e.TEXTURE_2D,h),e.texImage2D(e.TEXTURE_2D,0,e.LUMINANCE,t/2,i/2,0,e.LUMINANCE,e.UNSIGNED_BYTE,r),e.activeTexture(e.TEXTURE2),e.bindTexture(e.TEXTURE_2D,p),e.texImage2D(e.TEXTURE_2D,0,e.LUMINANCE,t/2,i/2,0,e.LUMINANCE,e.UNSIGNED_BYTE,s),e.drawArrays(e.TRIANGLE_STRIP,0,4)},destroy:function(){try{e.deleteProgram(a),e.deleteBuffer(n),e.deleteBuffer(d),e.deleteTexture(u),e.deleteTexture(h),e.deleteTexture(p)}catch(e){}}}})(this.contextGl,this.player._opt.openWebglAlignment);this.contextGlRender=e.render,this.contextGlDestroy=e.destroy}_initContext2D(){this.context2D=this.$videoElement.getContext("2d")}_initCanvasRender(){this.player._opt.useWCS&&!this._supportOffscreen()?(this.renderType=z,this._initContext2D()):this._supportOffscreen()?(this.renderType=Y,this._bindOffscreen()):(this.renderType=H,this._initContextGl())}_supportOffscreen(){return"function"==typeof this.$videoElement.transferControlToOffscreen&&this.player._opt.useOffscreen}_bindOffscreen(){this.bitmaprenderer=this.$videoElement.getContext("bitmaprenderer")}initCanvasViewSize(){this.$videoElement.width=this.videoInfo.width,this.$videoElement.height=this.videoInfo.height,this.resize()}render(e){switch(this.player.videoTimestamp=e.ts,this.renderType){case Y:this.bitmaprenderer.transferFromImageBitmap(e.buffer);break;case H:this.contextGlRender(this.$videoElement.width,this.$videoElement.height,e.output[0],e.output[1],e.output[2]);break;case z:this.context2D.drawImage(e.videoFrame,0,0,this.$videoElement.width,this.$videoElement.height),(t=e.videoFrame).close?t.close():t.destroy&&t.destroy()}var t}screenshot(e,t,i,o){e=e||he(),o=o||M.download;const r={png:"image/png",jpeg:"image/jpeg",webp:"image/webp"};let s=.92;!r[t]&&M[t]&&(o=t,t="png",i=void 0),"string"==typeof i&&(o=i,i=void 0),void 0!==i&&(s=Number(i));const a=this.$videoElement.toDataURL(r[t]||r.png,s);if(o===M.base64)return a;{const t=ue(a);if(o===M.blob)return t;o===M.download&&De(t,e)}}clearView(){switch(this.renderType){case Y:(function(e,t){const i=document.createElement("canvas");return i.width=e,i.height=t,window.createImageBitmap(i,0,0,e,t)})(this.$videoElement.width,this.$videoElement.height).then((e=>{this.bitmaprenderer.transferFromImageBitmap(e)}));break;case H:this.contextGl.clear(this.contextGl.COLOR_BUFFER_BIT);break;case z:this.context2D.clearRect(0,0,this.$videoElement.width,this.$videoElement.height)}}resize(){this.player.debug.log("canvasVideo","resize");const e=this.player._opt;let t=this.player.width,i=this.player.height;e.hasControl&&!e.controlAutoHide&&(ye()&&this.player.fullscreen&&e.useWebFullScreen?t-=J:i-=J);let o=this.$videoElement.width,r=this.$videoElement.height;const s=e.rotate;let a=(t-o)/2,n=(i-r)/2;270!==s&&90!==s||(o=this.$videoElement.height,r=this.$videoElement.width);const A=t/o,d=i/r;let c=A>d?d:A;e.isResize||A!==d&&(c=A+","+d),e.isFullResize&&(c=A>d?A:d);let l="scale("+c+")";s&&(l+=" rotate("+s+"deg)"),this.$videoElement.style.transform=l,this.$videoElement.style.left=a+"px",this.$videoElement.style.top=n+"px"}}class Le extends Ce{constructor(e){super(),this.player=e;const t=document.createElement("video"),i=document.createElement("canvas");t.muted=!0,t.style.position="absolute",t.style.top=0,t.style.left=0,this._delayPlay=!1,e.$container.appendChild(t),this.videoInfo={width:"",height:"",encType:""};const o=this.player._opt;o.useWCS&&o.wcsUseVideoRender&&(this.trackGenerator=new MediaStreamTrackGenerator({kind:"video"}),t.srcObject=new MediaStream([this.trackGenerator]),this.vwriter=this.trackGenerator.writable.getWriter()),this.$videoElement=t,this.$canvasElement=i,this.canvasContext=i.getContext("2d"),this.fixChromeVideoFlashBug(),this.resize();const{proxy:r}=this.player.events;r(this.$videoElement,"canplay",(()=>{this.player.debug.log("Video","canplay"),this._delayPlay&&this._play()})),r(this.$videoElement,"waiting",(()=>{this.player.emit(x.videoWaiting)})),r(this.$videoElement,"timeupdate",(e=>{const t=parseInt(e.timeStamp,10);this.player.emit(x.timeUpdate,t),this.isPlaying()||this.$videoElement.play()})),this.player.debug.log("Video","init")}destroy(){super.destroy(),this.$canvasElement=null,this.canvasContext=null,this.$videoElement&&(this.$videoElement.pause(),this.$videoElement.currentTime=0,this.$videoElement.src="",this.$videoElement.removeAttribute("src"),this.$videoElement=null),this.trackGenerator&&(this.trackGenerator.stop(),this.trackGenerator=null),this.vwriter&&(this.vwriter.close(),this.vwriter=null),this.player.debug.log("Video","destroy")}fixChromeVideoFlashBug(){const e=function(){const e=navigator.userAgent.toLowerCase(),t={},i={IE:window.ActiveXObject||"ActiveXObject"in window,Chrome:e.indexOf("chrome")>-1&&e.indexOf("safari")>-1,Firefox:e.indexOf("firefox")>-1,Opera:e.indexOf("opera")>-1,Safari:e.indexOf("safari")>-1&&-1==e.indexOf("chrome"),Edge:e.indexOf("edge")>-1,QQBrowser:/qqbrowser/.test(e),WeixinBrowser:/MicroMessenger/i.test(e)};for(let o in i)if(i[o]){let i="";if("IE"===o)i=e.match(/(msie\s|trident.*rv:)([\w.]+)/)[2];else if("Chrome"===o){for(let e in navigator.mimeTypes)"application/360softmgrplugin"===navigator.mimeTypes[e].type&&(o="360");i=e.match(/chrome\/([\d.]+)/)[1]}else"Firefox"===o?i=e.match(/firefox\/([\d.]+)/)[1]:"Opera"===o?i=e.match(/opera\/([\d.]+)/)[1]:"Safari"===o?i=e.match(/version\/([\d.]+)/)[1]:"Edge"===o?i=e.match(/edge\/([\d.]+)/)[1]:"QQBrowser"===o&&(i=e.match(/qqbrowser\/([\d.]+)/)[1]);t.type=o,t.version=parseInt(i)}return t}().type.toLowerCase();if("chrome"===e||"edge"===e){const e=this.player.$container;e.style.backdropFilter="blur(0px)",e.style.translateZ="0"}}play(){if(this.$videoElement){const e=this._getVideoReadyState();if(this.player.debug.log("Video",`play and readyState: ${e}`),0===e)return this.player.debug.warn("Video","readyState is 0 and set _delayPlay to true"),void(this._delayPlay=!0);this._play()}}_getVideoReadyState(){let e=0;return this.$videoElement&&(e=this.$videoElement.readyState),e}_play(){this.$videoElement&&this.$videoElement.play().then((()=>{this._delayPlay=!1,this.player.debug.log("Video","_play success"),setTimeout((()=>{this.isPlaying()||(this.player.debug.warn("Video","play failed and retry play"),this._play())}),100)})).catch((e=>{this.player.debug.error("Video","_play error",e)}))}pause(e){e?this.$videoElement&&this.$videoElement.pause():setTimeout((()=>{this.$videoElement&&this.$videoElement.pause()}),100)}clearView(){}screenshot(e,t,i,o){e=e||he(),o=o||M.download;const r={png:"image/png",jpeg:"image/jpeg",webp:"image/webp"};let s=.92;!r[t]&&M[t]&&(o=t,t="png",i=void 0),"string"==typeof i&&(o=i,i=void 0),void 0!==i&&(s=Number(i));const a=this.$videoElement;let n=this.$canvasElement;n.width=a.videoWidth,n.height=a.videoHeight,this.canvasContext.drawImage(a,0,0,n.width,n.height);const A=n.toDataURL(r[t]||r.png,s);if(this.canvasContext.clearRect(0,0,n.width,n.height),n.width=0,n.height=0,o===M.base64)return A;{const t=ue(A);if(o===M.blob)return t;o===M.download&&De(t,e)}}initCanvasViewSize(){this.resize()}render(e){this.vwriter&&this.vwriter.write(e.videoFrame)}resize(){let e=this.player.width,t=this.player.height;const i=this.player._opt,o=i.rotate;i.hasControl&&!i.controlAutoHide&&(ye()&&this.player.fullscreen&&i.useWebFullScreen?e-=J:t-=J),this.$videoElement.width=e,this.$videoElement.height=t,270!==o&&90!==o||(this.$videoElement.width=t,this.$videoElement.height=e);let r=(e-this.$videoElement.width)/2,s=(t-this.$videoElement.height)/2,a="contain";i.isResize||(a="fill"),i.isFullResize&&(a="none"),this.$videoElement.style.objectFit=a,this.$videoElement.style.transform="rotate("+o+"deg)",this.$videoElement.style.left=r+"px",this.$videoElement.style.top=s+"px"}isPlaying(){return this.$videoElement&&!this.$videoElement.paused}}class Fe{constructor(e){return new(Fe.getLoaderFactory(e._opt))(e)}static getLoaderFactory(e){return e.useMSE||e.useWCS&&!e.useOffscreen&&e.wcsUseVideoRender?Le:je}}class Oe extends Be{constructor(e){super(),this.bufferList=[],this.player=e,this.scriptNode=null,this.hasInitScriptNode=!1,this.audioContextChannel=null,this.audioContext=new(window.AudioContext||window.webkitAudioContext),this.gainNode=this.audioContext.createGain();const t=this.audioContext.createBufferSource();t.buffer=this.audioContext.createBuffer(1,1,22050),t.connect(this.audioContext.destination),t.noteOn?t.noteOn(0):t.start(0),this.audioBufferSourceNode=t,this.mediaStreamAudioDestinationNode=this.audioContext.createMediaStreamDestination(),this.audioEnabled(!0),this.gainNode.gain.value=0,this.playing=!1,this.audioSyncVideoOption={diff:null},this.audioInfo={encType:"",channels:"",sampleRate:""},this.init=!1,this.hasAudio=!1,this.on(x.videoSyncAudio,(e=>{this.audioSyncVideoOption=e})),this.player.debug.log("AudioContext","init")}resetInit(){this.init=!1,this.audioInfo={encType:"",channels:"",sampleRate:""}}destroy(){this.closeAudio(),this.resetInit(),this.audioContext.close(),this.audioContext=null,this.gainNode=null,this.hasAudio=!1,this.playing=!1,this.scriptNode&&(this.scriptNode.onaudioprocess=le,this.scriptNode=null),this.audioBufferSourceNode=null,this.mediaStreamAudioDestinationNode=null,this.hasInitScriptNode=!1,this.audioSyncVideoOption={diff:null},this.off(),this.player.debug.log("AudioContext","destroy")}updateAudioInfo(e){e.encTypeCode&&(this.audioInfo.encType=W[e.encTypeCode]),e.channels&&(this.audioInfo.channels=e.channels),e.sampleRate&&(this.audioInfo.sampleRate=e.sampleRate),this.audioInfo.sampleRate&&this.audioInfo.channels&&this.audioInfo.encType&&!this.init&&(this.player.emit(x.audioInfo,this.audioInfo),this.init=!0)}get isPlaying(){return this.playing}get isMute(){return 0===this.gainNode.gain.value||this.isStateSuspended()}get volume(){return this.gainNode.gain.value}get bufferSize(){return this.bufferList.length}initScriptNode(){if(this.playing=!0,this.hasInitScriptNode)return;const e=this.audioInfo.channels,t=this.audioContext.createScriptProcessor(1024,0,e);t.onaudioprocess=t=>{const i=t.outputBuffer;if(this.bufferList.length&&this.playing){if(!this.player._opt.useWCS&&!this.player._opt.useMSE&&this.player._opt.wasmDecodeAudioSyncVideo){if(this.audioSyncVideoOption.diff>ee)return void this.player.debug.warn("AudioContext",`audioSyncVideoOption more than diff :${this.audioSyncVideoOption.diff}, waiting`);if(this.audioSyncVideoOption.diff<-1e3){this.player.debug.warn("AudioContext",`audioSyncVideoOption less than diff :${this.audioSyncVideoOption.diff}, dropping`);let e=this.bufferList.shift();for(;e.ts-this.player.videoTimestamp<-1e3&&this.bufferList.length>0;)e=this.bufferList.shift();if(0===this.bufferList.length)return}}if(0===this.bufferList.length)return;const t=this.bufferList.shift();t&&t.ts&&(this.player.audioTimestamp=t.ts);for(let o=0;o<e;o++){const e=t.buffer[o],r=i.getChannelData(o);for(let t=0;t<1024;t++)r[t]=e[t]||0}}},t.connect(this.gainNode),this.scriptNode=t,this.gainNode.connect(this.audioContext.destination),this.gainNode.connect(this.mediaStreamAudioDestinationNode),this.hasInitScriptNode=!0}mute(e){e?(this.isMute||this.player.emit(x.mute,e),this.setVolume(0),this.audioEnabled(!1),this.clear()):(this.isMute&&this.player.emit(x.mute,e),this.setVolume(.5),this.audioEnabled(!0))}setVolume(e){e=parseFloat(e).toFixed(2),isNaN(e)||(this.audioEnabled(!0),e=pe(e,0,1),this.gainNode.gain.value=e,this.gainNode.gain.setValueAtTime(e,this.audioContext.currentTime),this.player.emit(x.volumechange,this.player.volume))}closeAudio(){this.hasInitScriptNode&&(this.scriptNode&&this.scriptNode.disconnect(this.gainNode),this.gainNode&&this.gainNode.disconnect(this.audioContext.destination),this.gainNode&&this.gainNode.disconnect(this.mediaStreamAudioDestinationNode)),this.clear()}audioEnabled(e){e?"suspended"===this.audioContext.state&&this.audioContext.resume():"running"===this.audioContext.state&&this.audioContext.suspend()}isStateRunning(){return"running"===this.audioContext.state}isStateSuspended(){return"suspended"===this.audioContext.state}clear(){this.bufferList=[]}play(e,t){this.isMute||(this.hasAudio=!0,this.bufferList.push({buffer:e,ts:t}),this.bufferList.length>20&&(this.player.debug.warn("AudioContext",`bufferList is large: ${this.bufferList.length}`),this.bufferList.length>50&&this.bufferList.shift()))}pause(){this.audioSyncVideoOption={diff:null},this.playing=!1,this.clear()}resume(){this.playing=!0}}class Ve{constructor(e){return new(Ve.getLoaderFactory())(e)}static getLoaderFactory(){return Oe}}class Me extends Be{constructor(e){super(),this.player=e,this.playing=!1,this.abortController=new AbortController,this.streamRate=be((t=>{e.emit(x.kBps,(t/1024).toFixed(2))})),e.debug.log("FetchStream","init")}destroy(){this.abort(),this.off(),this.streamRate=null,this.player.debug.log("FetchStream","destroy")}fetchStream(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const{demux:i}=this.player;this.player._times.streamStart=he();const o=Object.assign({signal:this.abortController.signal},{headers:t.headers||{}});fetch(e,o).then((e=>{const t=e.body.getReader();this.emit(x.streamSuccess);const o=()=>{t.read().then((e=>{let{done:t,value:r}=e;t?i.close():(this.streamRate&&this.streamRate(r.byteLength),i.dispatch(r),o())})).catch((e=>{i.close();const t=e.toString();-1===t.indexOf(se)&&-1===t.indexOf(ae)&&e.name!==ne&&(this.abort(),this.emit(j.fetchError,e),this.player.emit(x.error,j.fetchError))}))};o()})).catch((e=>{"AbortError"!==e.name&&(i.close(),this.abort(),this.emit(j.fetchError,e),this.player.emit(x.error,j.fetchError))}))}abort(){this.abortController&&(this.abortController.abort(),this.abortController=null)}}class Ue extends Be{constructor(e){super(),this.player=e,this.socket=null,this.socketStatus=L,this.wsUrl=null,this.streamRate=be((t=>{e.emit(x.kBps,(t/1024).toFixed(2))})),e.debug.log("WebsocketLoader","init")}destroy(){this.socket&&(this.socket.close(),this.socket=null),this.socketStatus=L,this.streamRate=null,this.wsUrl=null,this.off(),this.player.debug.log("websocketLoader","destroy")}_createWebSocket(){const e=this.player,{debug:t,events:{proxy:i},demux:o}=e;this.socket=new WebSocket(this.wsUrl),this.socket.binaryType="arraybuffer",i(this.socket,"open",(()=>{this.emit(x.streamSuccess),t.log("websocketLoader","socket open"),this.socketStatus=F})),i(this.socket,"message",(e=>{this.streamRate&&this.streamRate(e.data.byteLength),this._handleMessage(e.data)})),i(this.socket,"close",(()=>{t.log("websocketLoader","socket close"),this.emit(x.streamEnd),this.socketStatus=O})),i(this.socket,"error",(e=>{t.log("websocketLoader","socket error"),this.emit(j.websocketError,e),this.player.emit(x.error,j.websocketError),this.socketStatus=V,o.close(),t.log("websocketLoader","socket error:",e)}))}_handleMessage(e){const{demux:t}=this.player;t?t.dispatch(e):this.player.debug.warn("websocketLoader","websocket handle message demux is null")}fetchStream(e,t){this.player._times.streamStart=he(),this.wsUrl=e,this._createWebSocket()}}class Qe{constructor(e){return new(Qe.getLoaderFactory(e._opt.protocol))(e)}static getLoaderFactory(e){return e===a?Me:e===s?Ue:void 0}}var We=t((function(t){function i(e,t){if(!e)throw"First parameter is required.";t=new o(e,t=t||{type:"video"});var s=this;function a(i){i&&(t.initCallback=function(){i(),i=t.initCallback=null});var o=new r(e,t);(h=new o(e,t)).record(),u("recording"),t.disableLogs||console.log("Initialized recorderType:",h.constructor.name,"for output-type:",t.type)}function n(e){if(e=e||function(){},h){if("paused"===s.state)return s.resumeRecording(),void setTimeout((function(){n(e)}),1);"recording"===s.state||t.disableLogs||console.warn('Recording state should be: "recording", however current state is: ',s.state),t.disableLogs||console.log("Stopped recording "+t.type+" stream."),"gif"!==t.type?h.stop(i):(h.stop(),i()),u("stopped")}else m();function i(i){if(h){Object.keys(h).forEach((function(e){"function"!=typeof h[e]&&(s[e]=h[e])}));var o=h.blob;if(!o){if(!i)throw"Recording failed.";h.blob=o=i}if(o&&!t.disableLogs&&console.log(o.type,"->",b(o.size)),e){var r;try{r=l.createObjectURL(o)}catch(e){}"function"==typeof e.call?e.call(s,r):e(r)}t.autoWriteToDisk&&d((function(e){var i={};i[t.type+"Blob"]=e,x.Store(i)}))}else"function"==typeof e.call?e.call(s,""):e("")}}function A(e){postMessage((new FileReaderSync).readAsDataURL(e))}function d(e,i){if(!e)throw"Pass a callback function over getDataURL.";var o=i?i.blob:(h||{}).blob;if(!o)return t.disableLogs||console.warn("Blob encoder did not finish its job yet."),void setTimeout((function(){d(e,i)}),1e3);if("undefined"==typeof Worker||navigator.mozGetUserMedia){var r=new FileReader;r.readAsDataURL(o),r.onload=function(t){e(t.target.result)}}else{var s=function(e){try{var t=l.createObjectURL(new Blob([e.toString(),"this.onmessage = function (eee) {"+e.name+"(eee.data);}"],{type:"application/javascript"})),i=new Worker(t);return l.revokeObjectURL(t),i}catch(e){}}(A);s.onmessage=function(t){e(t.data)},s.postMessage(o)}}function c(e){e=e||0,"paused"!==s.state?"stopped"!==s.state&&(e>=s.recordingDuration?n(s.onRecordingStopped):(e+=1e3,setTimeout((function(){c(e)}),1e3))):setTimeout((function(){c(e)}),1e3)}function u(e){s&&(s.state=e,"function"==typeof s.onStateChanged.call?s.onStateChanged.call(s,e):s.onStateChanged(e))}var h,p='It seems that recorder is destroyed or "startRecording" is not invoked for '+t.type+" recorder.";function m(){!0!==t.disableLogs&&console.warn(p)}var g={startRecording:function(i){return t.disableLogs||console.log("RecordRTC version: ",s.version),i&&(t=new o(e,i)),t.disableLogs||console.log("started recording "+t.type+" stream."),h?(h.clearRecordedData(),h.record(),u("recording"),s.recordingDuration&&c(),s):(a((function(){s.recordingDuration&&c()})),s)},stopRecording:n,pauseRecording:function(){h?"recording"===s.state?(u("paused"),h.pause(),t.disableLogs||console.log("Paused recording.")):t.disableLogs||console.warn("Unable to pause the recording. Recording state: ",s.state):m()},resumeRecording:function(){h?"paused"===s.state?(u("recording"),h.resume(),t.disableLogs||console.log("Resumed recording.")):t.disableLogs||console.warn("Unable to resume the recording. Recording state: ",s.state):m()},initRecorder:a,setRecordingDuration:function(e,t){if(void 0===e)throw"recordingDuration is required.";if("number"!=typeof e)throw"recordingDuration must be a number.";return s.recordingDuration=e,s.onRecordingStopped=t||function(){},{onRecordingStopped:function(e){s.onRecordingStopped=e}}},clearRecordedData:function(){h?(h.clearRecordedData(),t.disableLogs||console.log("Cleared old recorded data.")):m()},getBlob:function(){if(h)return h.blob;m()},getDataURL:d,toURL:function(){if(h)return l.createObjectURL(h.blob);m()},getInternalRecorder:function(){return h},save:function(e){h?y(h.blob,e):m()},getFromDisk:function(e){h?i.getFromDisk(t.type,e):m()},setAdvertisementArray:function(e){t.advertisement=[];for(var i=e.length,o=0;o<i;o++)t.advertisement.push({duration:o,image:e[o]})},blob:null,bufferSize:0,sampleRate:0,buffer:null,reset:function(){"recording"!==s.state||t.disableLogs||console.warn("Stop an active recorder."),h&&"function"==typeof h.clearRecordedData&&h.clearRecordedData(),h=null,u("inactive"),s.blob=null},onStateChanged:function(e){t.disableLogs||console.log("Recorder state changed:",e)},state:"inactive",getState:function(){return s.state},destroy:function(){var e=t.disableLogs;t={disableLogs:!0},s.reset(),u("destroyed"),g=s=null,E.AudioContextConstructor&&(E.AudioContextConstructor.close(),E.AudioContextConstructor=null),t.disableLogs=e,t.disableLogs||console.log("RecordRTC is destroyed.")},version:"5.6.2"};if(!this)return s=g,g;for(var f in g)this[f]=g[f];return s=this,g}function o(e,t){return t.recorderType||t.type||(t.audio&&t.video?t.type="video":t.audio&&!t.video&&(t.type="audio")),t.recorderType&&!t.type&&(t.recorderType===T||t.recorderType===k||t.recorderType===F?t.type="video":t.recorderType===D?t.type="gif":t.recorderType===R?t.type="audio":t.recorderType===C&&(w(e,"audio").length&&w(e,"video").length||!w(e,"audio").length&&w(e,"video").length?t.type="video":w(e,"audio").length&&!w(e,"video").length&&(t.type="audio"))),"undefined"!=typeof MediaRecorder&&"requestData"in MediaRecorder.prototype&&(t.mimeType||(t.mimeType="video/webm"),t.type||(t.type=t.mimeType.split("/")[0]),t.bitsPerSecond),t.type||(t.mimeType&&(t.type=t.mimeType.split("/")[0]),t.type||(t.type="audio")),t}function r(e,t){var i;return(m||u||h)&&(i=R),"undefined"!=typeof MediaRecorder&&"requestData"in MediaRecorder.prototype&&!m&&(i=C),"video"===t.type&&(m||h)&&(i=T,"undefined"!=typeof ReadableStream&&(i=F)),"gif"===t.type&&(i=D),"canvas"===t.type&&(i=k),B()&&i!==k&&i!==D&&"undefined"!=typeof MediaRecorder&&"requestData"in MediaRecorder.prototype&&(w(e,"video").length||w(e,"audio").length)&&("audio"===t.type?"function"==typeof MediaRecorder.isTypeSupported&&MediaRecorder.isTypeSupported("audio/webm")&&(i=C):"function"==typeof MediaRecorder.isTypeSupported&&MediaRecorder.isTypeSupported("video/webm")&&(i=C)),e instanceof Array&&e.length&&(i=L),t.recorderType&&(i=t.recorderType),!t.disableLogs&&i&&i.name&&console.log("Using recorderType:",i.name||i.constructor.name),!i&&g&&(i=C),i}function s(e){this.addStream=function(t){t&&(e=t)},this.mediaType={audio:!0,video:!0},this.startRecording=function(){var t,o=this.mediaType,r=this.mimeType||{audio:null,video:null,gif:null};if("function"!=typeof o.audio&&B()&&!w(e,"audio").length&&(o.audio=!1),"function"!=typeof o.video&&B()&&!w(e,"video").length&&(o.video=!1),"function"!=typeof o.gif&&B()&&!w(e,"video").length&&(o.gif=!1),!o.audio&&!o.video&&!o.gif)throw"MediaStream must have either audio or video tracks.";if(o.audio&&(t=null,"function"==typeof o.audio&&(t=o.audio),this.audioRecorder=new i(e,{type:"audio",bufferSize:this.bufferSize,sampleRate:this.sampleRate,numberOfAudioChannels:this.numberOfAudioChannels||2,disableLogs:this.disableLogs,recorderType:t,mimeType:r.audio,timeSlice:this.timeSlice,onTimeStamp:this.onTimeStamp}),o.video||this.audioRecorder.startRecording()),o.video){t=null,"function"==typeof o.video&&(t=o.video);var s=e;if(B()&&o.audio&&"function"==typeof o.audio){var a=w(e,"video")[0];p?((s=new f).addTrack(a),t&&t===T&&(t=C)):(s=new f).addTrack(a)}this.videoRecorder=new i(s,{type:"video",video:this.video,canvas:this.canvas,frameInterval:this.frameInterval||10,disableLogs:this.disableLogs,recorderType:t,mimeType:r.video,timeSlice:this.timeSlice,onTimeStamp:this.onTimeStamp,workerPath:this.workerPath,webAssemblyPath:this.webAssemblyPath,frameRate:this.frameRate,bitrate:this.bitrate}),o.audio||this.videoRecorder.startRecording()}if(o.audio&&o.video){var n=this,A=!0===B();(o.audio instanceof R&&o.video||!0!==o.audio&&!0!==o.video&&o.audio!==o.video)&&(A=!1),!0===A?(n.audioRecorder=null,n.videoRecorder.startRecording()):n.videoRecorder.initRecorder((function(){n.audioRecorder.initRecorder((function(){n.videoRecorder.startRecording(),n.audioRecorder.startRecording()}))}))}o.gif&&(t=null,"function"==typeof o.gif&&(t=o.gif),this.gifRecorder=new i(e,{type:"gif",frameRate:this.frameRate||200,quality:this.quality||10,disableLogs:this.disableLogs,recorderType:t,mimeType:r.gif}),this.gifRecorder.startRecording())},this.stopRecording=function(e){e=e||function(){},this.audioRecorder&&this.audioRecorder.stopRecording((function(t){e(t,"audio")})),this.videoRecorder&&this.videoRecorder.stopRecording((function(t){e(t,"video")})),this.gifRecorder&&this.gifRecorder.stopRecording((function(t){e(t,"gif")}))},this.pauseRecording=function(){this.audioRecorder&&this.audioRecorder.pauseRecording(),this.videoRecorder&&this.videoRecorder.pauseRecording(),this.gifRecorder&&this.gifRecorder.pauseRecording()},this.resumeRecording=function(){this.audioRecorder&&this.audioRecorder.resumeRecording(),this.videoRecorder&&this.videoRecorder.resumeRecording(),this.gifRecorder&&this.gifRecorder.resumeRecording()},this.getBlob=function(e){var t={};return this.audioRecorder&&(t.audio=this.audioRecorder.getBlob()),this.videoRecorder&&(t.video=this.videoRecorder.getBlob()),this.gifRecorder&&(t.gif=this.gifRecorder.getBlob()),e&&e(t),t},this.destroy=function(){this.audioRecorder&&(this.audioRecorder.destroy(),this.audioRecorder=null),this.videoRecorder&&(this.videoRecorder.destroy(),this.videoRecorder=null),this.gifRecorder&&(this.gifRecorder.destroy(),this.gifRecorder=null)},this.getDataURL=function(e){function t(e,t){if("undefined"!=typeof Worker){var i=function(e){var t,i=l.createObjectURL(new Blob([e.toString(),"this.onmessage = function (eee) {"+e.name+"(eee.data);}"],{type:"application/javascript"})),o=new Worker(i);if(void 0!==l)t=l;else{if("undefined"==typeof webkitURL)throw"Neither URL nor webkitURL detected.";t=webkitURL}return t.revokeObjectURL(i),o}((function(e){postMessage((new FileReaderSync).readAsDataURL(e))}));i.onmessage=function(e){t(e.data)},i.postMessage(e)}else{var o=new FileReader;o.readAsDataURL(e),o.onload=function(e){t(e.target.result)}}}this.getBlob((function(i){i.audio&&i.video?t(i.audio,(function(o){t(i.video,(function(t){e({audio:o,video:t})}))})):i.audio?t(i.audio,(function(t){e({audio:t})})):i.video&&t(i.video,(function(t){e({video:t})}))}))},this.writeToDisk=function(){i.writeToDisk({audio:this.audioRecorder,video:this.videoRecorder,gif:this.gifRecorder})},this.save=function(e){(e=e||{audio:!0,video:!0,gif:!0}).audio&&this.audioRecorder&&this.audioRecorder.save("string"==typeof e.audio?e.audio:""),e.video&&this.videoRecorder&&this.videoRecorder.save("string"==typeof e.video?e.video:""),e.gif&&this.gifRecorder&&this.gifRecorder.save("string"==typeof e.gif?e.gif:"")}}i.version="5.6.2",t.exports=i,i.getFromDisk=function(e,t){if(!t)throw"callback is mandatory.";console.log("Getting recorded "+("all"===e?"blobs":e+" blob ")+" from disk!"),x.Fetch((function(i,o){"all"!==e&&o===e+"Blob"&&t&&t(i),"all"===e&&t&&t(i,o.replace("Blob",""))}))},i.writeToDisk=function(e){console.log("Writing recorded blob(s) to disk!"),(e=e||{}).audio&&e.video&&e.gif?e.audio.getDataURL((function(t){e.video.getDataURL((function(i){e.gif.getDataURL((function(e){x.Store({audioBlob:t,videoBlob:i,gifBlob:e})}))}))})):e.audio&&e.video?e.audio.getDataURL((function(t){e.video.getDataURL((function(e){x.Store({audioBlob:t,videoBlob:e})}))})):e.audio&&e.gif?e.audio.getDataURL((function(t){e.gif.getDataURL((function(e){x.Store({audioBlob:t,gifBlob:e})}))})):e.video&&e.gif?e.video.getDataURL((function(t){e.gif.getDataURL((function(e){x.Store({videoBlob:t,gifBlob:e})}))})):e.audio?e.audio.getDataURL((function(e){x.Store({audioBlob:e})})):e.video?e.video.getDataURL((function(e){x.Store({videoBlob:e})})):e.gif&&e.gif.getDataURL((function(e){x.Store({gifBlob:e})}))},s.getFromDisk=i.getFromDisk,s.writeToDisk=i.writeToDisk,i.MRecordRTC=s;var a;(a=void 0!==e?e:null)&&"undefined"==typeof window&&void 0!==e&&(e.navigator={userAgent:"Fake/5.0 (FakeOS) AppleWebKit/123 (KHTML, like Gecko) Fake/12.3.4567.89 Fake/123.45",getUserMedia:function(){}},e.console||(e.console={}),void 0!==e.console.log&&void 0!==e.console.error||(e.console.error=e.console.log=e.console.log||function(){console.log(arguments)}),"undefined"==typeof document&&(a.document={documentElement:{appendChild:function(){return""}}},document.createElement=document.captureStream=document.mozCaptureStream=function(){var e={getContext:function(){return e},play:function(){},pause:function(){},drawImage:function(){},toDataURL:function(){return""},style:{}};return e},a.HTMLVideoElement=function(){}),"undefined"==typeof location&&(a.location={protocol:"file:",href:"",hash:""}),"undefined"==typeof screen&&(a.screen={width:0,height:0}),void 0===l&&(a.URL={createObjectURL:function(){return""},revokeObjectURL:function(){return""}}),a.window=e);var n=window.requestAnimationFrame;if(void 0===n)if("undefined"!=typeof webkitRequestAnimationFrame)n=webkitRequestAnimationFrame;else if("undefined"!=typeof mozRequestAnimationFrame)n=mozRequestAnimationFrame;else if("undefined"!=typeof msRequestAnimationFrame)n=msRequestAnimationFrame;else if(void 0===n){var A=0;n=function(e,t){var i=(new Date).getTime(),o=Math.max(0,16-(i-A)),r=setTimeout((function(){e(i+o)}),o);return A=i+o,r}}var d=window.cancelAnimationFrame;void 0===d&&("undefined"!=typeof webkitCancelAnimationFrame?d=webkitCancelAnimationFrame:"undefined"!=typeof mozCancelAnimationFrame?d=mozCancelAnimationFrame:"undefined"!=typeof msCancelAnimationFrame?d=msCancelAnimationFrame:void 0===d&&(d=function(e){clearTimeout(e)}));var c=window.AudioContext;void 0===c&&("undefined"!=typeof webkitAudioContext&&(c=webkitAudioContext),"undefined"!=typeof mozAudioContext&&(c=mozAudioContext));var l=window.URL;void 0===l&&"undefined"!=typeof webkitURL&&(l=webkitURL),"undefined"!=typeof navigator&&void 0===navigator.getUserMedia&&(void 0!==navigator.webkitGetUserMedia&&(navigator.getUserMedia=navigator.webkitGetUserMedia),void 0!==navigator.mozGetUserMedia&&(navigator.getUserMedia=navigator.mozGetUserMedia));var u=!(-1===navigator.userAgent.indexOf("Edge")||!navigator.msSaveBlob&&!navigator.msSaveOrOpenBlob),h=!!window.opera||-1!==navigator.userAgent.indexOf("OPR/"),p=navigator.userAgent.toLowerCase().indexOf("firefox")>-1&&"netscape"in window&&/ rv:/.test(navigator.userAgent),m=!h&&!u&&!!navigator.webkitGetUserMedia||v()||-1!==navigator.userAgent.toLowerCase().indexOf("chrome/"),g=/^((?!chrome|android).)*safari/i.test(navigator.userAgent);g&&!m&&-1!==navigator.userAgent.indexOf("CriOS")&&(g=!1,m=!0);var f=window.MediaStream;function b(e){if(0===e)return"0 Bytes";var t=parseInt(Math.floor(Math.log(e)/Math.log(1e3)),10);return(e/Math.pow(1e3,t)).toPrecision(3)+" "+["Bytes","KB","MB","GB","TB"][t]}function y(e,t){if(!e)throw"Blob object is required.";if(!e.type)try{e.type="video/webm"}catch(e){}var i=(e.type||"video/webm").split("/")[1];if(-1!==i.indexOf(";")&&(i=i.split(";")[0]),t&&-1!==t.indexOf(".")){var o=t.split(".");t=o[0],i=o[1]}var r=(t||Math.round(9999999999*Math.random())+888888888)+"."+i;if(void 0!==navigator.msSaveOrOpenBlob)return navigator.msSaveOrOpenBlob(e,r);if(void 0!==navigator.msSaveBlob)return navigator.msSaveBlob(e,r);var s=document.createElement("a");s.href=l.createObjectURL(e),s.download=r,s.style="display:none;opacity:0;color:transparent;",(document.body||document.documentElement).appendChild(s),"function"==typeof s.click?s.click():(s.target="_blank",s.dispatchEvent(new MouseEvent("click",{view:window,bubbles:!0,cancelable:!0}))),l.revokeObjectURL(s.href)}function v(){return"undefined"!=typeof window&&"object"==typeof window.process&&"renderer"===window.process.type||(!("undefined"==typeof process||"object"!=typeof process.versions||!process.versions.electron)||"object"==typeof navigator&&"string"==typeof navigator.userAgent&&navigator.userAgent.indexOf("Electron")>=0)}function w(e,t){return e&&e.getTracks?e.getTracks().filter((function(e){return e.kind===(t||"audio")})):[]}function S(e,t){"srcObject"in t?t.srcObject=e:"mozSrcObject"in t?t.mozSrcObject=e:t.srcObject=e}void 0===f&&"undefined"!=typeof webkitMediaStream&&(f=webkitMediaStream),void 0!==f&&void 0===f.prototype.stop&&(f.prototype.stop=function(){this.getTracks().forEach((function(e){e.stop()}))}),i.invokeSaveAsDialog=y,i.getTracks=w,i.getSeekableBlob=function(e,t){if("undefined"==typeof EBML)throw new Error("Please link: https://www.webrtc-experiment.com/EBML.js");var i=new EBML.Reader,o=new EBML.Decoder,r=EBML.tools,s=new FileReader;s.onload=function(e){o.decode(this.result).forEach((function(e){i.read(e)})),i.stop();var s=r.makeMetadataSeekable(i.metadatas,i.duration,i.cues),a=this.result.slice(i.metadataSize),n=new Blob([s,a],{type:"video/webm"});t(n)},s.readAsArrayBuffer(e)},i.bytesToSize=b,i.isElectron=v;var E={};function B(){if(p||g||u)return!0;var e,t,i=navigator.userAgent,o=""+parseFloat(navigator.appVersion),r=parseInt(navigator.appVersion,10);return(m||h)&&(e=i.indexOf("Chrome"),o=i.substring(e+7)),-1!==(t=o.indexOf(";"))&&(o=o.substring(0,t)),-1!==(t=o.indexOf(" "))&&(o=o.substring(0,t)),r=parseInt(""+o,10),isNaN(r)&&(o=""+parseFloat(navigator.appVersion),r=parseInt(navigator.appVersion,10)),r>=49}function C(e,t){var i=this;if(void 0===e)throw'First argument "MediaStream" is required.';if("undefined"==typeof MediaRecorder)throw"Your browser does not support the Media Recorder API. Please try other modules e.g. WhammyRecorder or StereoAudioRecorder.";if("audio"===(t=t||{mimeType:"video/webm"}).type){var o;if(w(e,"video").length&&w(e,"audio").length)navigator.mozGetUserMedia?(o=new f).addTrack(w(e,"audio")[0]):o=new f(w(e,"audio")),e=o;t.mimeType&&-1!==t.mimeType.toString().toLowerCase().indexOf("audio")||(t.mimeType=m?"audio/webm":"audio/ogg"),t.mimeType&&"audio/ogg"!==t.mimeType.toString().toLowerCase()&&navigator.mozGetUserMedia&&(t.mimeType="audio/ogg")}var r,s=[];function a(){i.timestamps.push((new Date).getTime()),"function"==typeof t.onTimeStamp&&t.onTimeStamp(i.timestamps[i.timestamps.length-1],i.timestamps)}function n(e){return r&&r.mimeType?r.mimeType:e.mimeType||"video/webm"}function A(){s=[],r=null,i.timestamps=[]}this.getArrayOfBlobs=function(){return s},this.record=function(){i.blob=null,i.clearRecordedData(),i.timestamps=[],d=[],s=[];var o=t;t.disableLogs||console.log("Passing following config over MediaRecorder API.",o),r&&(r=null),m&&!B()&&(o="video/vp8"),"function"==typeof MediaRecorder.isTypeSupported&&o.mimeType&&(MediaRecorder.isTypeSupported(o.mimeType)||(t.disableLogs||console.warn("MediaRecorder API seems unable to record mimeType:",o.mimeType),o.mimeType="audio"===t.type?"audio/webm":"video/webm"));try{r=new MediaRecorder(e,o),t.mimeType=o.mimeType}catch(t){r=new MediaRecorder(e)}o.mimeType&&!MediaRecorder.isTypeSupported&&"canRecordMimeType"in r&&!1===r.canRecordMimeType(o.mimeType)&&(t.disableLogs||console.warn("MediaRecorder API seems unable to record mimeType:",o.mimeType)),r.ondataavailable=function(e){if(e.data&&d.push("ondataavailable: "+b(e.data.size)),"number"!=typeof t.timeSlice)!e.data||!e.data.size||e.data.size<100||i.blob?i.recordingCallback&&(i.recordingCallback(new Blob([],{type:n(o)})),i.recordingCallback=null):(i.blob=t.getNativeBlob?e.data:new Blob([e.data],{type:n(o)}),i.recordingCallback&&(i.recordingCallback(i.blob),i.recordingCallback=null));else if(e.data&&e.data.size&&(s.push(e.data),a(),"function"==typeof t.ondataavailable)){var r=t.getNativeBlob?e.data:new Blob([e.data],{type:n(o)});t.ondataavailable(r)}},r.onstart=function(){d.push("started")},r.onpause=function(){d.push("paused")},r.onresume=function(){d.push("resumed")},r.onstop=function(){d.push("stopped")},r.onerror=function(e){e&&(e.name||(e.name="UnknownError"),d.push("error: "+e),t.disableLogs||(-1!==e.name.toString().toLowerCase().indexOf("invalidstate")?console.error("The MediaRecorder is not in a state in which the proposed operation is allowed to be executed.",e):-1!==e.name.toString().toLowerCase().indexOf("notsupported")?console.error("MIME type (",o.mimeType,") is not supported.",e):-1!==e.name.toString().toLowerCase().indexOf("security")?console.error("MediaRecorder security error",e):"OutOfMemory"===e.name?console.error("The UA has exhaused the available memory. User agents SHOULD provide as much additional information as possible in the message attribute.",e):"IllegalStreamModification"===e.name?console.error("A modification to the stream has occurred that makes it impossible to continue recording. An example would be the addition of a Track while recording is occurring. User agents SHOULD provide as much additional information as possible in the message attribute.",e):"OtherRecordingError"===e.name?console.error("Used for an fatal error other than those listed above. User agents SHOULD provide as much additional information as possible in the message attribute.",e):"GenericError"===e.name?console.error("The UA cannot provide the codec or recording option that has been requested.",e):console.error("MediaRecorder Error",e)),function(e){if(!i.manuallyStopped&&r&&"inactive"===r.state)return delete t.timeslice,void r.start(6e5);setTimeout(void 0,1e3)}(),"inactive"!==r.state&&"stopped"!==r.state&&r.stop())},"number"==typeof t.timeSlice?(a(),r.start(t.timeSlice)):r.start(36e5),t.initCallback&&t.initCallback()},this.timestamps=[],this.stop=function(e){e=e||function(){},i.manuallyStopped=!0,r&&(this.recordingCallback=e,"recording"===r.state&&r.stop(),"number"==typeof t.timeSlice&&setTimeout((function(){i.blob=new Blob(s,{type:n(t)}),i.recordingCallback(i.blob)}),100))},this.pause=function(){r&&"recording"===r.state&&r.pause()},this.resume=function(){r&&"paused"===r.state&&r.resume()},this.clearRecordedData=function(){r&&"recording"===r.state&&i.stop(A),A()},this.getInternalRecorder=function(){return r},this.blob=null,this.getState=function(){return r&&r.state||"inactive"};var d=[];this.getAllStates=function(){return d},void 0===t.checkForInactiveTracks&&(t.checkForInactiveTracks=!1);i=this;!function o(){if(r&&!1!==t.checkForInactiveTracks)return!1===function(){if("active"in e){if(!e.active)return!1}else if("ended"in e&&e.ended)return!1;return!0}()?(t.disableLogs||console.log("MediaStream seems stopped."),void i.stop()):void setTimeout(o,1e3)}(),this.name="MediaStreamRecorder",this.toString=function(){return this.name}}function R(e,t){if(!w(e,"audio").length)throw"Your stream has no audio tracks.";var o,r=this,s=[],a=[],n=!1,A=0,d=2,c=(t=t||{}).desiredSampRate;function u(){if(!1===t.checkForInactiveTracks)return!0;if("active"in e){if(!e.active)return!1}else if("ended"in e&&e.ended)return!1;return!0}function h(e,t){function i(e,t){var i,o=e.numberOfAudioChannels,r=e.leftBuffers.slice(0),s=e.rightBuffers.slice(0),a=e.sampleRate,n=e.internalInterleavedLength,A=e.desiredSampRate;function d(e,t,i){var o=Math.round(e.length*(t/i)),r=[],s=Number((e.length-1)/(o-1));r[0]=e[0];for(var a=1;a<o-1;a++){var n=a*s,A=Number(Math.floor(n)).toFixed(),d=Number(Math.ceil(n)).toFixed(),l=n-A;r[a]=c(e[A],e[d],l)}return r[o-1]=e[e.length-1],r}function c(e,t,i){return e+(t-e)*i}function l(e,t){for(var i=new Float64Array(t),o=0,r=e.length,s=0;s<r;s++){var a=e[s];i.set(a,o),o+=a.length}return i}function u(e,t,i){for(var o=i.length,r=0;r<o;r++)e.setUint8(t+r,i.charCodeAt(r))}2===o&&(r=l(r,n),s=l(s,n),A&&(r=d(r,A,a),s=d(s,A,a))),1===o&&(r=l(r,n),A&&(r=d(r,A,a))),A&&(a=A),2===o&&(i=function(e,t){for(var i=e.length+t.length,o=new Float64Array(i),r=0,s=0;s<i;)o[s++]=e[r],o[s++]=t[r],r++;return o}(r,s)),1===o&&(i=r);var h=i.length,p=new ArrayBuffer(44+2*h),m=new DataView(p);u(m,0,"RIFF"),m.setUint32(4,36+2*h,!0),u(m,8,"WAVE"),u(m,12,"fmt "),m.setUint32(16,16,!0),m.setUint16(20,1,!0),m.setUint16(22,o,!0),m.setUint32(24,a,!0),m.setUint32(28,a*o*2,!0),m.setUint16(32,2*o,!0),m.setUint16(34,16,!0),u(m,36,"data"),m.setUint32(40,2*h,!0);for(var g=h,f=44,b=0;b<g;b++)m.setInt16(f,32767*i[b],!0),f+=2;if(t)return t({buffer:p,view:m});postMessage({buffer:p,view:m})}if(e.noWorker)i(e,(function(e){t(e.buffer,e.view)}));else{var o,r,s,a=(o=i,r=l.createObjectURL(new Blob([o.toString(),";this.onmessage = function (eee) {"+o.name+"(eee.data);}"],{type:"application/javascript"})),(s=new Worker(r)).workerURL=r,s);a.onmessage=function(e){t(e.data.buffer,e.data.view),l.revokeObjectURL(a.workerURL),a.terminate()},a.postMessage(e)}}!0===t.leftChannel&&(d=1),1===t.numberOfAudioChannels&&(d=1),(!d||d<1)&&(d=2),t.disableLogs||console.log("StereoAudioRecorder is set to record number of channels: "+d),void 0===t.checkForInactiveTracks&&(t.checkForInactiveTracks=!0),this.record=function(){if(!1===u())throw"Please make sure MediaStream is active.";v(),E=y=!1,n=!0,void 0!==t.timeSlice&&C()},this.stop=function(e){e=e||function(){},n=!1,h({desiredSampRate:c,sampleRate:b,numberOfAudioChannels:d,internalInterleavedLength:A,leftBuffers:s,rightBuffers:1===d?[]:a,noWorker:t.noWorker},(function(t,i){r.blob=new Blob([i],{type:"audio/wav"}),r.buffer=new ArrayBuffer(i.buffer.byteLength),r.view=i,r.sampleRate=c||b,r.bufferSize=f,r.length=A,E=!1,e&&e(r.blob)}))},void 0===i.Storage&&(i.Storage={AudioContextConstructor:null,AudioContext:window.AudioContext||window.webkitAudioContext}),i.Storage.AudioContextConstructor&&"closed"!==i.Storage.AudioContextConstructor.state||(i.Storage.AudioContextConstructor=new i.Storage.AudioContext);var p=i.Storage.AudioContextConstructor,m=p.createMediaStreamSource(e),g=[0,256,512,1024,2048,4096,8192,16384],f=void 0===t.bufferSize?4096:t.bufferSize;if(-1===g.indexOf(f)&&(t.disableLogs||console.log("Legal values for buffer-size are "+JSON.stringify(g,null,"\t"))),p.createJavaScriptNode)o=p.createJavaScriptNode(f,d,d);else{if(!p.createScriptProcessor)throw"WebAudio API has no support on this browser.";o=p.createScriptProcessor(f,d,d)}m.connect(o),t.bufferSize||(f=o.bufferSize);var b=void 0!==t.sampleRate?t.sampleRate:p.sampleRate||44100;(b<22050||b>96e3)&&(t.disableLogs||console.log("sample-rate must be under range 22050 and 96000.")),t.disableLogs||t.desiredSampRate&&console.log("Desired sample-rate: "+t.desiredSampRate);var y=!1;function v(){s=[],a=[],A=0,E=!1,n=!1,y=!1,p=null,r.leftchannel=s,r.rightchannel=a,r.numberOfAudioChannels=d,r.desiredSampRate=c,r.sampleRate=b,r.recordingLength=A,B={left:[],right:[],recordingLength:0}}function S(){o&&(o.onaudioprocess=null,o.disconnect(),o=null),m&&(m.disconnect(),m=null),v()}this.pause=function(){y=!0},this.resume=function(){if(!1===u())throw"Please make sure MediaStream is active.";if(!n)return t.disableLogs||console.log("Seems recording has been restarted."),void this.record();y=!1},this.clearRecordedData=function(){t.checkForInactiveTracks=!1,n&&this.stop(S),S()},this.name="StereoAudioRecorder",this.toString=function(){return this.name};var E=!1;o.onaudioprocess=function(e){if(!y)if(!1===u()&&(t.disableLogs||console.log("MediaStream seems stopped."),o.disconnect(),n=!1),n){E||(E=!0,t.onAudioProcessStarted&&t.onAudioProcessStarted(),t.initCallback&&t.initCallback());var i=e.inputBuffer.getChannelData(0),c=new Float32Array(i);if(s.push(c),2===d){var l=e.inputBuffer.getChannelData(1),h=new Float32Array(l);a.push(h)}A+=f,r.recordingLength=A,void 0!==t.timeSlice&&(B.recordingLength+=f,B.left.push(c),2===d&&B.right.push(h))}else m&&(m.disconnect(),m=null)},p.createMediaStreamDestination?o.connect(p.createMediaStreamDestination()):o.connect(p.destination),this.leftchannel=s,this.rightchannel=a,this.numberOfAudioChannels=d,this.desiredSampRate=c,this.sampleRate=b,r.recordingLength=A;var B={left:[],right:[],recordingLength:0};function C(){n&&"function"==typeof t.ondataavailable&&void 0!==t.timeSlice&&(B.left.length?(h({desiredSampRate:c,sampleRate:b,numberOfAudioChannels:d,internalInterleavedLength:B.recordingLength,leftBuffers:B.left,rightBuffers:1===d?[]:B.right},(function(e,i){var o=new Blob([i],{type:"audio/wav"});t.ondataavailable(o),setTimeout(C,t.timeSlice)})),B={left:[],right:[],recordingLength:0}):setTimeout(C,t.timeSlice))}}function k(e,t){if("undefined"==typeof html2canvas)throw"Please link: https://www.webrtc-experiment.com/screenshot.js";(t=t||{}).frameInterval||(t.frameInterval=10);var i=!1;["captureStream","mozCaptureStream","webkitCaptureStream"].forEach((function(e){e in document.createElement("canvas")&&(i=!0)}));var o,r,s,a=!(!window.webkitRTCPeerConnection&&!window.webkitGetUserMedia||!window.chrome),n=50,A=navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./);if(a&&A&&A[2]&&(n=parseInt(A[2],10)),a&&n<52&&(i=!1),t.useWhammyRecorder&&(i=!1),i)if(t.disableLogs||console.log("Your browser supports both MediRecorder API and canvas.captureStream!"),e instanceof HTMLCanvasElement)o=e;else{if(!(e instanceof CanvasRenderingContext2D))throw"Please pass either HTMLCanvasElement or CanvasRenderingContext2D.";o=e.canvas}else navigator.mozGetUserMedia&&(t.disableLogs||console.error("Canvas recording is NOT supported in Firefox."));this.record=function(){if(s=!0,i&&!t.useWhammyRecorder){var e;"captureStream"in o?e=o.captureStream(25):"mozCaptureStream"in o?e=o.mozCaptureStream(25):"webkitCaptureStream"in o&&(e=o.webkitCaptureStream(25));try{var a=new f;a.addTrack(w(e,"video")[0]),e=a}catch(e){}if(!e)throw"captureStream API are NOT available.";(r=new C(e,{mimeType:t.mimeType||"video/webm"})).record()}else h.frames=[],u=(new Date).getTime(),l();t.initCallback&&t.initCallback()},this.getWebPImages=function(i){if("canvas"===e.nodeName.toLowerCase()){var o=h.frames.length;h.frames.forEach((function(e,i){var r=o-i;t.disableLogs||console.log(r+"/"+o+" frames remaining"),t.onEncodingCallback&&t.onEncodingCallback(r,o);var s=e.image.toDataURL("image/webp",1);h.frames[i].image=s})),t.disableLogs||console.log("Generating WebM"),i()}else i()},this.stop=function(e){s=!1;var o=this;i&&r?r.stop(e):this.getWebPImages((function(){h.compile((function(i){t.disableLogs||console.log("Recording finished!"),o.blob=i,o.blob.forEach&&(o.blob=new Blob([],{type:"video/webm"})),e&&e(o.blob),h.frames=[]}))}))};var d=!1;function c(){h.frames=[],s=!1,d=!1}function l(){if(d)return u=(new Date).getTime(),setTimeout(l,500);if("canvas"===e.nodeName.toLowerCase()){var i=(new Date).getTime()-u;return u=(new Date).getTime(),h.frames.push({image:(o=document.createElement("canvas"),r=o.getContext("2d"),o.width=e.width,o.height=e.height,r.drawImage(e,0,0),o),duration:i}),void(s&&setTimeout(l,t.frameInterval))}var o,r;html2canvas(e,{grabMouse:void 0===t.showMousePointer||t.showMousePointer,onrendered:function(e){var i=(new Date).getTime()-u;if(!i)return setTimeout(l,t.frameInterval);u=(new Date).getTime(),h.frames.push({image:e.toDataURL("image/webp",1),duration:i}),s&&setTimeout(l,t.frameInterval)}})}this.pause=function(){d=!0,r instanceof C&&r.pause()},this.resume=function(){d=!1,r instanceof C?r.resume():s||this.record()},this.clearRecordedData=function(){s&&this.stop(c),c()},this.name="CanvasRecorder",this.toString=function(){return this.name};var u=(new Date).getTime(),h=new I.Video(100)}function T(e,t){function i(e){e=void 0!==e?e:10;var t=(new Date).getTime()-A;return t?s?(A=(new Date).getTime(),setTimeout(i,100)):(A=(new Date).getTime(),n.paused&&n.play(),l.drawImage(n,0,0,c.width,c.height),d.frames.push({duration:t,image:c.toDataURL("image/webp")}),void(r||setTimeout(i,e,e))):setTimeout(i,e,e)}function o(e,t,i,o,r){var s=document.createElement("canvas");s.width=c.width,s.height=c.height;var a,n,A,d=s.getContext("2d"),l=[],u=-1===t,h=t&&t>0&&t<=e.length?t:e.length,p=0,m=0,g=0,f=Math.sqrt(Math.pow(255,2)+Math.pow(255,2)+Math.pow(255,2)),b=i&&i>=0&&i<=1?i:0,y=o&&o>=0&&o<=1?o:0,v=!1;n=-1,A=(a={length:h,functionToLoop:function(t,i){var o,r,s,a=function(){!v&&s-o<=s*y||(u&&(v=!0),l.push(e[i])),t()};if(v)a();else{var n=new Image;n.onload=function(){d.drawImage(n,0,0,c.width,c.height);var e=d.getImageData(0,0,c.width,c.height);o=0,r=e.data.length,s=e.data.length/4;for(var t=0;t<r;t+=4){var i={r:e.data[t],g:e.data[t+1],b:e.data[t+2]};Math.sqrt(Math.pow(i.r-p,2)+Math.pow(i.g-m,2)+Math.pow(i.b-g,2))<=f*b&&o++}a()},n.src=e[i].image}},callback:function(){(l=l.concat(e.slice(h))).length<=0&&l.push(e[e.length-1]),r(l)}}).length,function e(){++n!==A?setTimeout((function(){a.functionToLoop(e,n)}),1):a.callback()}()}(t=t||{}).frameInterval||(t.frameInterval=10),t.disableLogs||console.log("Using frames-interval:",t.frameInterval),this.record=function(){t.width||(t.width=320),t.height||(t.height=240),t.video||(t.video={width:t.width,height:t.height}),t.canvas||(t.canvas={width:t.width,height:t.height}),c.width=t.canvas.width||320,c.height=t.canvas.height||240,l=c.getContext("2d"),t.video&&t.video instanceof HTMLVideoElement?(n=t.video.cloneNode(),t.initCallback&&t.initCallback()):(n=document.createElement("video"),S(e,n),n.onloadedmetadata=function(){t.initCallback&&t.initCallback()},n.width=t.video.width,n.height=t.video.height),n.muted=!0,n.play(),A=(new Date).getTime(),d=new I.Video,t.disableLogs||(console.log("canvas resolutions",c.width,"*",c.height),console.log("video width/height",n.width||c.width,"*",n.height||c.height)),i(t.frameInterval)};var r=!1;this.stop=function(e){e=e||function(){},r=!0;var i=this;setTimeout((function(){o(d.frames,-1,null,null,(function(o){d.frames=o,t.advertisement&&t.advertisement.length&&(d.frames=t.advertisement.concat(d.frames)),d.compile((function(t){i.blob=t,i.blob.forEach&&(i.blob=new Blob([],{type:"video/webm"})),e&&e(i.blob)}))}))}),10)};var s=!1;function a(){d.frames=[],r=!0,s=!1}this.pause=function(){s=!0},this.resume=function(){s=!1,r&&this.record()},this.clearRecordedData=function(){r||this.stop(a),a()},this.name="WhammyRecorder",this.toString=function(){return this.name};var n,A,d,c=document.createElement("canvas"),l=c.getContext("2d")}void 0!==c?E.AudioContext=c:"undefined"!=typeof webkitAudioContext&&(E.AudioContext=webkitAudioContext),i.Storage=E,i.MediaStreamRecorder=C,i.StereoAudioRecorder=R,i.CanvasRecorder=k,i.WhammyRecorder=T;var I=function(){function e(e){this.frames=[],this.duration=e||1,this.quality=.8}function t(e){function t(e,t,i){return[{data:e,id:231}].concat(i.map((function(e){var i=function(e){var t=0;e.keyframe&&(t|=128);e.invisible&&(t|=8);e.lacing&&(t|=e.lacing<<1);e.discardable&&(t|=1);if(e.trackNum>127)throw"TrackNumber > 127 not supported";return[128|e.trackNum,e.timecode>>8,255&e.timecode,t].map((function(e){return String.fromCharCode(e)})).join("")+e.frame}({discardable:0,frame:e.data.slice(4),invisible:0,keyframe:1,lacing:0,trackNum:1,timecode:Math.round(t)});return t+=e.duration,{data:i,id:163}})))}function i(e){for(var t=[];e>0;)t.push(255&e),e>>=8;return new Uint8Array(t.reverse())}function o(e){var t=[];e=(e.length%8?new Array(9-e.length%8).join("0"):"")+e;for(var i=0;i<e.length;i+=8)t.push(parseInt(e.substr(i,8),2));return new Uint8Array(t)}function r(e){for(var t=[],s=0;s<e.length;s++){var a=e[s].data;"object"==typeof a&&(a=r(a)),"number"==typeof a&&(a=o(a.toString(2))),"string"==typeof a&&(a=new Uint8Array(a.split("").map((function(e){return e.charCodeAt(0)}))));var n=a.size||a.byteLength||a.length,A=Math.ceil(Math.ceil(Math.log(n)/Math.log(2))/8),d=n.toString(2),c=new Array(7*A+7+1-d.length).join("0")+d,l=new Array(A).join("0")+"1"+c;t.push(i(e[s].id)),t.push(o(l)),t.push(a)}return new Blob(t,{type:"video/webm"})}function s(e,t){return parseInt(e.substr(t+4,4).split("").map((function(e){var t=e.charCodeAt(0).toString(2);return new Array(8-t.length+1).join("0")+t})).join(""),2)}function a(e){for(var t=0,i={};t<e.length;){var o=e.substr(t,4),r=s(e,t),n=e.substr(t+4+4,r);t+=8+r,i[o]=i[o]||[],"RIFF"===o||"LIST"===o?i[o].push(a(n)):i[o].push(n)}return i}var n=new function(e){var i=function(e){if(!e[0])return void postMessage({error:"Something went wrong. Maybe WebP format is not supported in the current browser."});for(var t=e[0].width,i=e[0].height,o=e[0].duration,r=1;r<e.length;r++)o+=e[r].duration;return{duration:o,width:t,height:i}}(e);if(!i)return[];for(var o,s=[{id:440786851,data:[{data:1,id:17030},{data:1,id:17143},{data:4,id:17138},{data:8,id:17139},{data:"webm",id:17026},{data:2,id:17031},{data:2,id:17029}]},{id:408125543,data:[{id:357149030,data:[{data:1e6,id:2807729},{data:"whammy",id:19840},{data:"whammy",id:22337},{data:(o=i.duration,[].slice.call(new Uint8Array(new Float64Array([o]).buffer),0).map((function(e){return String.fromCharCode(e)})).reverse().join("")),id:17545}]},{id:374648427,data:[{id:174,data:[{data:1,id:215},{data:1,id:29637},{data:0,id:156},{data:"und",id:2274716},{data:"V_VP8",id:134},{data:"VP8",id:2459272},{data:1,id:131},{id:224,data:[{data:i.width,id:176},{data:i.height,id:186}]}]}]}]}],a=0,n=0;a<e.length;){var A=[],d=0;do{A.push(e[a]),d+=e[a].duration,a++}while(a<e.length&&d<3e4);var c={id:524531317,data:t(n,0,A)};s[1].data.push(c),n+=d}return r(s)}(e.map((function(e){var t=function(e){for(var t=e.RIFF[0].WEBP[0],i=t.indexOf("*"),o=0,r=[];o<4;o++)r[o]=t.charCodeAt(i+3+o);return{width:16383&(r[1]<<8|r[0]),height:16383&(r[3]<<8|r[2]),data:t,riff:e}}(a(atob(e.image.slice(23))));return t.duration=e.duration,t})));postMessage(n)}return e.prototype.add=function(e,t){if("canvas"in e&&(e=e.canvas),"toDataURL"in e&&(e=e.toDataURL("image/webp",this.quality)),!/^data:image\/webp;base64,/gi.test(e))throw"Input must be formatted properly as a base64 encoded DataURI of type image/webp";this.frames.push({image:e,duration:t||this.duration})},e.prototype.compile=function(e){var i,o,r,s=(i=t,o=l.createObjectURL(new Blob([i.toString(),"this.onmessage = function (eee) {"+i.name+"(eee.data);}"],{type:"application/javascript"})),r=new Worker(o),l.revokeObjectURL(o),r);s.onmessage=function(t){t.data.error?console.error(t.data.error):e(t.data)},s.postMessage(this.frames)},{Video:e}}();i.Whammy=I;var x={init:function(){var e=this;if("undefined"!=typeof indexedDB&&void 0!==indexedDB.open){var t,i=this.dbName||location.href.replace(/\/|:|#|%|\.|\[|\]/g,""),o=indexedDB.open(i,1);o.onerror=e.onError,o.onsuccess=function(){((t=o.result).onerror=e.onError,t.setVersion)?1!==t.version?t.setVersion(1).onsuccess=function(){r(t),s()}:s():s()},o.onupgradeneeded=function(e){r(e.target.result)}}else console.error("IndexedDB API are not available in this browser.");function r(t){t.createObjectStore(e.dataStoreName)}function s(){var i=t.transaction([e.dataStoreName],"readwrite");function o(t){i.objectStore(e.dataStoreName).get(t).onsuccess=function(i){e.callback&&e.callback(i.target.result,t)}}e.videoBlob&&i.objectStore(e.dataStoreName).put(e.videoBlob,"videoBlob"),e.gifBlob&&i.objectStore(e.dataStoreName).put(e.gifBlob,"gifBlob"),e.audioBlob&&i.objectStore(e.dataStoreName).put(e.audioBlob,"audioBlob"),o("audioBlob"),o("videoBlob"),o("gifBlob")}},Fetch:function(e){return this.callback=e,this.init(),this},Store:function(e){return this.audioBlob=e.audioBlob,this.videoBlob=e.videoBlob,this.gifBlob=e.gifBlob,this.init(),this},onError:function(e){console.error(JSON.stringify(e,null,"\t"))},dataStoreName:"recordRTC",dbName:null};function D(e,t){if("undefined"==typeof GIFEncoder){var i=document.createElement("script");i.src="https://www.webrtc-experiment.com/gif-recorder.js",(document.body||document.documentElement).appendChild(i)}t=t||{};var o=e instanceof CanvasRenderingContext2D||e instanceof HTMLCanvasElement;this.record=function(){"undefined"!=typeof GIFEncoder&&A?(o||(t.width||(t.width=c.offsetWidth||320),t.height||(t.height=c.offsetHeight||240),t.video||(t.video={width:t.width,height:t.height}),t.canvas||(t.canvas={width:t.width,height:t.height}),s.width=t.canvas.width||320,s.height=t.canvas.height||240,c.width=t.video.width||320,c.height=t.video.height||240),(u=new GIFEncoder).setRepeat(0),u.setDelay(t.frameRate||200),u.setQuality(t.quality||10),u.start(),"function"==typeof t.onGifRecordingStarted&&t.onGifRecordingStarted(),h=n((function e(i){if(!0!==p.clearedRecordedData){if(r)return setTimeout((function(){e(i)}),100);h=n(e),void 0===typeof l&&(l=i),i-l<90||(!o&&c.paused&&c.play(),o||a.drawImage(c,0,0,s.width,s.height),t.onGifPreview&&t.onGifPreview(s.toDataURL("image/png")),u.addFrame(a),l=i)}})),t.initCallback&&t.initCallback()):setTimeout(p.record,1e3)},this.stop=function(e){e=e||function(){},h&&d(h),this.blob=new Blob([new Uint8Array(u.stream().bin)],{type:"image/gif"}),e(this.blob),u.stream().bin=[]};var r=!1;this.pause=function(){r=!0},this.resume=function(){r=!1},this.clearRecordedData=function(){p.clearedRecordedData=!0,u&&(u.stream().bin=[])},this.name="GifRecorder",this.toString=function(){return this.name};var s=document.createElement("canvas"),a=s.getContext("2d");o&&(e instanceof CanvasRenderingContext2D?s=(a=e).canvas:e instanceof HTMLCanvasElement&&(a=e.getContext("2d"),s=e));var A=!0;if(!o){var c=document.createElement("video");c.muted=!0,c.autoplay=!0,c.playsInline=!0,A=!1,c.onloadedmetadata=function(){A=!0},S(e,c),c.play()}var l,u,h=null,p=this}function j(e,t){t=t||"multi-streams-mixer";var i=[],o=!1,r=document.createElement("canvas"),s=r.getContext("2d");r.style.opacity=0,r.style.position="absolute",r.style.zIndex=-1,r.style.top="-1000em",r.style.left="-1000em",r.className=t,(document.body||document.documentElement).appendChild(r),this.disableLogs=!1,this.frameInterval=10,this.width=360,this.height=240,this.useGainNode=!0;var a=this,n=window.AudioContext;void 0===n&&("undefined"!=typeof webkitAudioContext&&(n=webkitAudioContext),"undefined"!=typeof mozAudioContext&&(n=mozAudioContext));var A=window.URL;void 0===A&&"undefined"!=typeof webkitURL&&(A=webkitURL),"undefined"!=typeof navigator&&void 0===navigator.getUserMedia&&(void 0!==navigator.webkitGetUserMedia&&(navigator.getUserMedia=navigator.webkitGetUserMedia),void 0!==navigator.mozGetUserMedia&&(navigator.getUserMedia=navigator.mozGetUserMedia));var d=window.MediaStream;void 0===d&&"undefined"!=typeof webkitMediaStream&&(d=webkitMediaStream),void 0!==d&&void 0===d.prototype.stop&&(d.prototype.stop=function(){this.getTracks().forEach((function(e){e.stop()}))});var c={};function l(){if(!o){var e=i.length,t=!1,s=[];if(i.forEach((function(e){e.stream||(e.stream={}),e.stream.fullcanvas?t=e:s.push(e)})),t)r.width=t.stream.width,r.height=t.stream.height;else if(s.length){r.width=e>1?2*s[0].width:s[0].width;var n=1;3!==e&&4!==e||(n=2),5!==e&&6!==e||(n=3),7!==e&&8!==e||(n=4),9!==e&&10!==e||(n=5),r.height=s[0].height*n}else r.width=a.width||360,r.height=a.height||240;t&&t instanceof HTMLVideoElement&&u(t),s.forEach((function(e,t){u(e,t)})),setTimeout(l,a.frameInterval)}}function u(e,t){if(!o){var i=0,r=0,a=e.width,n=e.height;1===t&&(i=e.width),2===t&&(r=e.height),3===t&&(i=e.width,r=e.height),4===t&&(r=2*e.height),5===t&&(i=e.width,r=2*e.height),6===t&&(r=3*e.height),7===t&&(i=e.width,r=3*e.height),void 0!==e.stream.left&&(i=e.stream.left),void 0!==e.stream.top&&(r=e.stream.top),void 0!==e.stream.width&&(a=e.stream.width),void 0!==e.stream.height&&(n=e.stream.height),s.drawImage(e,i,r,a,n),"function"==typeof e.stream.onRender&&e.stream.onRender(s,i,r,a,n,t)}}function h(e){var i=document.createElement("video");return function(e,t){"srcObject"in t?t.srcObject=e:"mozSrcObject"in t?t.mozSrcObject=e:t.srcObject=e}(e,i),i.className=t,i.muted=!0,i.volume=0,i.width=e.width||a.width||360,i.height=e.height||a.height||240,i.play(),i}function p(t){i=[],(t=t||e).forEach((function(e){if(e.getTracks().filter((function(e){return"video"===e.kind})).length){var t=h(e);t.stream=e,i.push(t)}}))}void 0!==n?c.AudioContext=n:"undefined"!=typeof webkitAudioContext&&(c.AudioContext=webkitAudioContext),this.startDrawingFrames=function(){l()},this.appendStreams=function(t){if(!t)throw"First parameter is required.";t instanceof Array||(t=[t]),t.forEach((function(t){var o=new d;if(t.getTracks().filter((function(e){return"video"===e.kind})).length){var r=h(t);r.stream=t,i.push(r),o.addTrack(t.getTracks().filter((function(e){return"video"===e.kind}))[0])}if(t.getTracks().filter((function(e){return"audio"===e.kind})).length){var s=a.audioContext.createMediaStreamSource(t);a.audioDestination=a.audioContext.createMediaStreamDestination(),s.connect(a.audioDestination),o.addTrack(a.audioDestination.stream.getTracks().filter((function(e){return"audio"===e.kind}))[0])}e.push(o)}))},this.releaseStreams=function(){i=[],o=!0,a.gainNode&&(a.gainNode.disconnect(),a.gainNode=null),a.audioSources.length&&(a.audioSources.forEach((function(e){e.disconnect()})),a.audioSources=[]),a.audioDestination&&(a.audioDestination.disconnect(),a.audioDestination=null),a.audioContext&&a.audioContext.close(),a.audioContext=null,s.clearRect(0,0,r.width,r.height),r.stream&&(r.stream.stop(),r.stream=null)},this.resetVideoStreams=function(e){!e||e instanceof Array||(e=[e]),p(e)},this.name="MultiStreamsMixer",this.toString=function(){return this.name},this.getMixedStream=function(){o=!1;var t=function(){var e;p(),"captureStream"in r?e=r.captureStream():"mozCaptureStream"in r?e=r.mozCaptureStream():a.disableLogs||console.error("Upgrade to latest Chrome or otherwise enable this flag: chrome://flags/#enable-experimental-web-platform-features");var t=new d;return e.getTracks().filter((function(e){return"video"===e.kind})).forEach((function(e){t.addTrack(e)})),r.stream=t,t}(),i=function(){c.AudioContextConstructor||(c.AudioContextConstructor=new c.AudioContext);a.audioContext=c.AudioContextConstructor,a.audioSources=[],!0===a.useGainNode&&(a.gainNode=a.audioContext.createGain(),a.gainNode.connect(a.audioContext.destination),a.gainNode.gain.value=0);var t=0;if(e.forEach((function(e){if(e.getTracks().filter((function(e){return"audio"===e.kind})).length){t++;var i=a.audioContext.createMediaStreamSource(e);!0===a.useGainNode&&i.connect(a.gainNode),a.audioSources.push(i)}})),!t)return;return a.audioDestination=a.audioContext.createMediaStreamDestination(),a.audioSources.forEach((function(e){e.connect(a.audioDestination)})),a.audioDestination.stream}();return i&&i.getTracks().filter((function(e){return"audio"===e.kind})).forEach((function(e){t.addTrack(e)})),e.forEach((function(e){e.fullcanvas})),t}}function L(e,t){e=e||[];var i,o,r=this;(t=t||{elementClass:"multi-streams-mixer",mimeType:"video/webm",video:{width:360,height:240}}).frameInterval||(t.frameInterval=10),t.video||(t.video={}),t.video.width||(t.video.width=360),t.video.height||(t.video.height=240),this.record=function(){var r;i=new j(e,t.elementClass||"multi-streams-mixer"),(r=[],e.forEach((function(e){w(e,"video").forEach((function(e){r.push(e)}))})),r).length&&(i.frameInterval=t.frameInterval||10,i.width=t.video.width||360,i.height=t.video.height||240,i.startDrawingFrames()),t.previewStream&&"function"==typeof t.previewStream&&t.previewStream(i.getMixedStream()),(o=new C(i.getMixedStream(),t)).record()},this.stop=function(e){o&&o.stop((function(t){r.blob=t,e(t),r.clearRecordedData()}))},this.pause=function(){o&&o.pause()},this.resume=function(){o&&o.resume()},this.clearRecordedData=function(){o&&(o.clearRecordedData(),o=null),i&&(i.releaseStreams(),i=null)},this.addStreams=function(r){if(!r)throw"First parameter is required.";r instanceof Array||(r=[r]),e.concat(r),o&&i&&(i.appendStreams(r),t.previewStream&&"function"==typeof t.previewStream&&t.previewStream(i.getMixedStream()))},this.resetVideoStreams=function(e){i&&(!e||e instanceof Array||(e=[e]),i.resetVideoStreams(e))},this.getMixer=function(){return i},this.name="MultiStreamRecorder",this.toString=function(){return this.name}}function F(e,t){var i,o,r;function s(){return new ReadableStream({start:function(o){var r=document.createElement("canvas"),s=document.createElement("video"),a=!0;s.srcObject=e,s.muted=!0,s.height=t.height,s.width=t.width,s.volume=0,s.onplaying=function(){r.width=t.width,r.height=t.height;var e=r.getContext("2d"),n=1e3/t.frameRate,A=setInterval((function(){if(i&&(clearInterval(A),o.close()),a&&(a=!1,t.onVideoProcessStarted&&t.onVideoProcessStarted()),e.drawImage(s,0,0),"closed"!==o._controlledReadableStream.state)try{o.enqueue(e.getImageData(0,0,t.width,t.height))}catch(e){}}),n)},s.play()}})}function a(e,A){if(!t.workerPath&&!A)return i=!1,void fetch("https://unpkg.com/webm-wasm@latest/dist/webm-worker.js").then((function(t){t.arrayBuffer().then((function(t){a(e,t)}))}));if(!t.workerPath&&A instanceof ArrayBuffer){var d=new Blob([A],{type:"text/javascript"});t.workerPath=l.createObjectURL(d)}t.workerPath||console.error("workerPath parameter is missing."),(o=new Worker(t.workerPath)).postMessage(t.webAssemblyPath||"https://unpkg.com/webm-wasm@latest/dist/webm-wasm.wasm"),o.addEventListener("message",(function(e){"READY"===e.data?(o.postMessage({width:t.width,height:t.height,bitrate:t.bitrate||1200,timebaseDen:t.frameRate||30,realtime:t.realtime}),s().pipeTo(new WritableStream({write:function(e){i?console.error("Got image, but recorder is finished!"):o.postMessage(e.data.buffer,[e.data.buffer])}}))):e.data&&(r||n.push(e.data))}))}"undefined"!=typeof ReadableStream&&"undefined"!=typeof WritableStream||console.error("Following polyfill is strongly recommended: https://unpkg.com/@mattiasbuelens/web-streams-polyfill/dist/polyfill.min.js"),(t=t||{}).width=t.width||640,t.height=t.height||480,t.frameRate=t.frameRate||30,t.bitrate=t.bitrate||1200,t.realtime=t.realtime||!0,this.record=function(){n=[],r=!1,this.blob=null,a(e),"function"==typeof t.initCallback&&t.initCallback()},this.pause=function(){r=!0},this.resume=function(){r=!1};var n=[];this.stop=function(e){i=!0;var t=this;!function(e){o?(o.addEventListener("message",(function(t){null===t.data&&(o.terminate(),o=null,e&&e())})),o.postMessage(null)):e&&e()}((function(){t.blob=new Blob(n,{type:"video/webm"}),e(t.blob)}))},this.name="WebAssemblyRecorder",this.toString=function(){return this.name},this.clearRecordedData=function(){n=[],r=!1,this.blob=null},this.blob=null}i.DiskStorage=x,i.GifRecorder=D,i.MultiStreamRecorder=L,i.RecordRTCPromisesHandler=function(e,t){if(!this)throw'Use "new RecordRTCPromisesHandler()"';if(void 0===e)throw'First argument "MediaStream" is required.';var o=this;o.recordRTC=new i(e,t),this.startRecording=function(){return new Promise((function(e,t){try{o.recordRTC.startRecording(),e()}catch(e){t(e)}}))},this.stopRecording=function(){return new Promise((function(e,t){try{o.recordRTC.stopRecording((function(i){o.blob=o.recordRTC.getBlob(),o.blob&&o.blob.size?e(i):t("Empty blob.",o.blob)}))}catch(e){t(e)}}))},this.pauseRecording=function(){return new Promise((function(e,t){try{o.recordRTC.pauseRecording(),e()}catch(e){t(e)}}))},this.resumeRecording=function(){return new Promise((function(e,t){try{o.recordRTC.resumeRecording(),e()}catch(e){t(e)}}))},this.getDataURL=function(e){return new Promise((function(e,t){try{o.recordRTC.getDataURL((function(t){e(t)}))}catch(e){t(e)}}))},this.getBlob=function(){return new Promise((function(e,t){try{e(o.recordRTC.getBlob())}catch(e){t(e)}}))},this.getInternalRecorder=function(){return new Promise((function(e,t){try{e(o.recordRTC.getInternalRecorder())}catch(e){t(e)}}))},this.reset=function(){return new Promise((function(e,t){try{e(o.recordRTC.reset())}catch(e){t(e)}}))},this.destroy=function(){return new Promise((function(e,t){try{e(o.recordRTC.destroy())}catch(e){t(e)}}))},this.getState=function(){return new Promise((function(e,t){try{e(o.recordRTC.getState())}catch(e){t(e)}}))},this.blob=null,this.version="5.6.2"},i.WebAssemblyRecorder=F}));class Je extends Be{constructor(e){super(),this.player=e,this.fileName="",this.fileType=e._opt.recordType||c,this.isRecording=!1,this.recordingTimestamp=0,this.recordingInterval=null,e.debug.log("Recorder","init")}destroy(){this._reset(),this.player.debug.log("Recorder","destroy")}setFileName(e,t){this.fileName=e,d!==t&&c!==t||(this.fileType=t)}get recording(){return this.isRecording}get recordTime(){return this.recordingTimestamp}startRecord(){const e=this.player.debug,t={type:"video",mimeType:"video/webm;codecs=h264",onTimeStamp:t=>{e.log("Recorder","record timestamp :"+t)},disableLogs:!this.player._opt.debug};try{const e=this.player.video.$videoElement.captureStream(25);if(this.player.audio&&this.player.audio.mediaStreamAudioDestinationNode&&this.player.audio.mediaStreamAudioDestinationNode.stream&&!this.player.audio.isStateSuspended()&&this.player.audio.hasAudio&&this.player._opt.hasAudio){const t=this.player.audio.mediaStreamAudioDestinationNode.stream;if(t.getAudioTracks().length>0){const i=t.getAudioTracks()[0];i&&i.enabled&&e.addTrack(i)}}this.recorder=We(e,t)}catch(t){e.error("Recorder","startRecord error",t),this.emit(x.recordCreateError)}this.recorder&&(this.isRecording=!0,this.player.emit(x.recording,!0),this.recorder.startRecording(),e.log("Recorder","start recording"),this.player.emit(x.recordStart),this.recordingInterval=window.setInterval((()=>{this.recordingTimestamp+=1,this.player.emit(x.recordingTimestamp,this.recordingTimestamp)}),1e3))}stopRecordAndSave(){this.recorder&&this.isRecording&&this.recorder.stopRecording((()=>{this.player.debug.log("Recorder","stop recording"),this.player.emit(x.recordEnd);const e=(this.fileName||he())+"."+(this.fileType||c);De(this.recorder.getBlob(),e),this._reset(),this.player.emit(x.recording,!1)}))}_reset(){this.isRecording=!1,this.recordingTimestamp=0,this.recorder&&(this.recorder.destroy(),this.recorder=null),this.fileName=null,this.recordingInterval&&clearInterval(this.recordingInterval),this.recordingInterval=null}}class Pe{constructor(e){return new(Pe.getLoaderFactory())(e)}static getLoaderFactory(){return Je}}class Ge{constructor(e){this.player=e,this.decoderWorker=new Worker(e._opt.decoder),this._initDecoderWorker(),e.debug.log("decoderWorker","init")}destroy(){this.decoderWorker.postMessage({cmd:T}),this.decoderWorker.terminate(),this.decoderWorker=null,this.player.debug.log("decoderWorker","destroy")}_initDecoderWorker(){const{debug:e,events:{proxy:t}}=this.player;this.decoderWorker.onmessage=t=>{const i=t.data;switch(i.cmd){case u:e.log("decoderWorker","onmessage:",u),this.player.loaded||this.player.emit(x.load),this.player.emit(x.decoderWorkerInit),this._initWork();break;case b:e.log("decoderWorker","onmessage:",b,i.code),this.player._times.decodeStart||(this.player._times.decodeStart=he()),this.player.video.updateVideoInfo({encTypeCode:i.code});break;case f:e.log("decoderWorker","onmessage:",f,i.code),this.player.audio&&this.player.audio.updateAudioInfo({encTypeCode:i.code});break;case h:if(e.log("decoderWorker","onmessage:",h,`width:${i.w},height:${i.h}`),this.player.video.updateVideoInfo({width:i.w,height:i.h}),!this.player._opt.openWebglAlignment&&i.w/2%4!=0)return void this.player.emit(j.webglAlignmentError);this.player.video.initCanvasViewSize();break;case g:e.log("decoderWorker","onmessage:",g,`channels:${i.channels},sampleRate:${i.sampleRate}`),this.player.audio&&(this.player.audio.updateAudioInfo(i),this.player.audio.initScriptNode(i));break;case p:this.player.handleRender(),this.player.video.render(i),this.player.emit(x.timeUpdate,i.ts),this.player.updateStats({fps:!0,ts:i.ts,buf:i.delay}),this.player._times.videoStart||(this.player._times.videoStart=he(),this.player.handlePlayToRenderTimes());break;case m:this.player.playing&&this.player.audio&&this.player.audio.play(i.buffer,i.ts);break;case y:i.message&&-1!==i.message.indexOf(v)&&(this.player.emit(x.error,j.wasmDecodeError),this.player.emit(j.wasmDecodeError));break;default:this.player[i.cmd]&&this.player[i.cmd](i)}}}_initWork(){const e={debug:this.player._opt.debug,useOffscreen:this.player._opt.useOffscreen,useWCS:this.player._opt.useWCS,videoBuffer:this.player._opt.videoBuffer,videoBufferDelay:this.player._opt.videoBufferDelay,openWebglAlignment:this.player._opt.openWebglAlignment};this.decoderWorker.postMessage({cmd:C,opt:JSON.stringify(e),sampleRate:this.player.audio&&this.player.audio.audioContext.sampleRate||0})}decodeVideo(e,t,i){const o={type:S,ts:Math.max(t,0),isIFrame:i};this.decoderWorker.postMessage({cmd:R,buffer:e,options:o},[e.buffer])}decodeAudio(e,t){this.player._opt.useWCS||this.player._opt.useMSE?this._decodeAudioNoDelay(e,t):this._decodeAudio(e,t)}_decodeAudio(e,t){const i={type:w,ts:Math.max(t,0)};this.decoderWorker.postMessage({cmd:R,buffer:e,options:i},[e.buffer])}_decodeAudioNoDelay(e,t){this.decoderWorker.postMessage({cmd:k,buffer:e,ts:Math.max(t,0)},[e.buffer])}updateWorkConfig(e){this.decoderWorker.postMessage({cmd:I,key:e.key,value:e.value})}}class Ne extends Be{constructor(e){super(),this.player=e,this.stopId=null,this.firstTimestamp=null,this.startTimestamp=null,this.delay=-1,this.bufferList=[],this.dropping=!1,this.initInterval()}destroy(){this.stopId&&(clearInterval(this.stopId),this.stopId=null),this.firstTimestamp=null,this.startTimestamp=null,this.delay=-1,this.bufferList=[],this.dropping=!1,this.off(),this.player.debug.log("CommonDemux","destroy")}getDelay(e){if(!e)return-1;if(this.firstTimestamp){if(e){const t=Date.now()-this.startTimestamp,i=e-this.firstTimestamp;this.delay=t>=i?t-i:i-t}}else this.firstTimestamp=e,this.startTimestamp=Date.now(),this.delay=-1;return this.delay}resetDelay(){this.firstTimestamp=null,this.startTimestamp=null,this.delay=-1,this.dropping=!1}initInterval(){this.player.debug.log("common dumex","init Interval");let e=()=>{let e;const t=this.player._opt.videoBuffer,i=this.player._opt.videoBufferDelay;if(this.bufferList.length)if(this.dropping){for(e=this.bufferList.shift(),e.type===w&&0===e.payload[1]&&this._doDecoderDecode(e);!e.isIFrame&&this.bufferList.length;)e=this.bufferList.shift(),e.type===w&&0===e.payload[1]&&this._doDecoderDecode(e);e.isIFrame&&this.getDelay(e.ts)<=Math.min(t,200)&&(this.dropping=!1,this._doDecoderDecode(e))}else e=this.bufferList[0],-1===this.getDelay(e.ts)?(this.bufferList.shift(),this._doDecoderDecode(e)):this.delay>t+i?(this.resetDelay(),this.dropping=!0):(e=this.bufferList[0],this.getDelay(e.ts)>t&&(this.bufferList.shift(),this._doDecoderDecode(e)))};e(),this.stopId=setInterval(e,10)}_doDecode(e,t,i,o,r){const s=this.player;let a={ts:i,cts:r,type:t,isIFrame:!1};s._opt.useWCS&&!s._opt.useOffscreen||s._opt.useMSE?(t===S&&(a.isIFrame=o),this.pushBuffer(e,a)):t===S?s.decoderWorker&&s.decoderWorker.decodeVideo(e,i,o):t===w&&s._opt.hasAudio&&s.decoderWorker&&s.decoderWorker.decodeAudio(e,i)}_doDecoderDecode(e){const t=this.player,{webcodecsDecoder:i,mseDecoder:o}=t;e.type===w?t._opt.hasAudio&&t.decoderWorker&&t.decoderWorker.decodeAudio(e.payload,e.ts):e.type===S&&(t._opt.useWCS&&!t._opt.useOffscreen?i.decodeVideo(e.payload,e.ts,e.isIFrame):t._opt.useMSE&&o.decodeVideo(e.payload,e.ts,e.isIFrame,e.cts))}pushBuffer(e,t){t.type===w?this.bufferList.push({ts:t.ts,payload:e,type:w}):t.type===S&&this.bufferList.push({ts:t.ts,cts:t.cts,payload:e,type:S,isIFrame:t.isIFrame})}close(){}}class ze extends Ne{constructor(e){super(e),this.input=this._inputFlv(),this.flvDemux=this.dispatchFlvData(this.input),e.debug.log("FlvDemux","init")}destroy(){super.destroy(),this.input=null,this.flvDemux=null,this.player.debug.log("FlvDemux","destroy")}dispatch(e){this.flvDemux(e)}*_inputFlv(){yield 9;const e=new ArrayBuffer(4),t=new Uint8Array(e),i=new Uint32Array(e),o=this.player;for(;;){t[3]=0;const e=yield 15,r=e[4];t[0]=e[7],t[1]=e[6],t[2]=e[5];const s=i[0];t[0]=e[10],t[1]=e[9],t[2]=e[8];let a=i[0];16777215===a&&(t[3]=e[11],a=i[0]);const n=yield s;switch(r){case E:o._opt.hasAudio&&(o.updateStats({abps:n.byteLength}),n.byteLength>0&&this._doDecode(n,w,a));break;case B:if(o._times.demuxStart||(o._times.demuxStart=he()),o._opt.hasVideo){o.updateStats({vbps:n.byteLength});const e=n[0]>>4==1;if(n.byteLength>0){i[0]=n[4],i[1]=n[3],i[2]=n[2],i[3]=0;let t=i[0];this._doDecode(n,S,a,e,t)}}}}}dispatchFlvData(e){let t=e.next(),i=null;return o=>{let r=new Uint8Array(o);if(i){let e=new Uint8Array(i.length+r.length);e.set(i),e.set(r,i.length),r=e,i=null}for(;r.length>=t.value;){let i=r.slice(t.value);t=e.next(r.slice(0,t.value)),r=i}r.length>0&&(i=r)}}close(){this.input&&this.input.return(null)}}class He extends Ne{constructor(e){super(e),e.debug.log("M7sDemux","init")}destroy(){super.destroy(),this.player.debug.log("M7sDemux","destroy"),this.player=null}dispatch(e){const t=this.player,i=new DataView(e),o=i.getUint8(0),r=i.getUint32(1,!1);switch(o){case w:if(t._opt.hasAudio){const i=new Uint8Array(e,5);t.updateStats({abps:i.byteLength}),i.byteLength>0&&this._doDecode(i,o,r)}break;case S:if(t._opt.hasVideo)if(t._times.demuxStart||(t._times.demuxStart=he()),i.byteLength>5){const s=new Uint8Array(e,5),a=i.getUint8(5)>>4==1;t.updateStats({vbps:s.byteLength}),s.byteLength>0&&this._doDecode(s,o,r,a)}else this.player.debug.warn("M7sDemux","dispatch","dv byteLength is",i.byteLength)}}}class Ye{constructor(e){return new(Ye.getLoaderFactory(e._opt.demuxType))(e)}static getLoaderFactory(e){return e===A?He:e===n?ze:void 0}}class Xe{constructor(e){this.TAG="ExpGolomb",this._buffer=e,this._buffer_index=0,this._total_bytes=e.byteLength,this._total_bits=8*e.byteLength,this._current_word=0,this._current_word_bits_left=0}destroy(){this._buffer=null}_fillCurrentWord(){let e=this._total_bytes-this._buffer_index,t=Math.min(4,e),i=new Uint8Array(4);i.set(this._buffer.subarray(this._buffer_index,this._buffer_index+t)),this._current_word=new DataView(i.buffer).getUint32(0,!1),this._buffer_index+=t,this._current_word_bits_left=8*t}readBits(e){if(e<=this._current_word_bits_left){let t=this._current_word>>>32-e;return this._current_word<<=e,this._current_word_bits_left-=e,t}let t=this._current_word_bits_left?this._current_word:0;t>>>=32-this._current_word_bits_left;let i=e-this._current_word_bits_left;this._fillCurrentWord();let o=Math.min(i,this._current_word_bits_left),r=this._current_word>>>32-o;return this._current_word<<=o,this._current_word_bits_left-=o,t=t<<o|r,t}readBool(){return 1===this.readBits(1)}readByte(){return this.readBits(8)}_skipLeadingZero(){let e;for(e=0;e<this._current_word_bits_left;e++)if(0!=(this._current_word&2147483648>>>e))return this._current_word<<=e,this._current_word_bits_left-=e,e;return this._fillCurrentWord(),e+this._skipLeadingZero()}readUEG(){let e=this._skipLeadingZero();return this.readBits(e+1)-1}readSEG(){let e=this.readUEG();return 1&e?e+1>>>1:-1*(e>>>1)}}class qe{static _ebsp2rbsp(e){let t=e,i=t.byteLength,o=new Uint8Array(i),r=0;for(let e=0;e<i;e++)e>=2&&3===t[e]&&0===t[e-1]&&0===t[e-2]||(o[r]=t[e],r++);return new Uint8Array(o.buffer,0,r)}static parseSPS(e){let t=qe._ebsp2rbsp(e),i=new Xe(t);i.readByte();let o=i.readByte();i.readByte();let r=i.readByte();i.readUEG();let s=qe.getProfileString(o),a=qe.getLevelString(r),n=1,A=420,d=[0,420,422,444],c=8;if((100===o||110===o||122===o||244===o||44===o||83===o||86===o||118===o||128===o||138===o||144===o)&&(n=i.readUEG(),3===n&&i.readBits(1),n<=3&&(A=d[n]),c=i.readUEG()+8,i.readUEG(),i.readBits(1),i.readBool())){let e=3!==n?8:12;for(let t=0;t<e;t++)i.readBool()&&(t<6?qe._skipScalingList(i,16):qe._skipScalingList(i,64))}i.readUEG();let l=i.readUEG();if(0===l)i.readUEG();else if(1===l){i.readBits(1),i.readSEG(),i.readSEG();let e=i.readUEG();for(let t=0;t<e;t++)i.readSEG()}let u=i.readUEG();i.readBits(1);let h=i.readUEG(),p=i.readUEG(),m=i.readBits(1);0===m&&i.readBits(1),i.readBits(1);let g=0,f=0,b=0,y=0;i.readBool()&&(g=i.readUEG(),f=i.readUEG(),b=i.readUEG(),y=i.readUEG());let v=1,w=1,S=0,E=!0,B=0,C=0;if(i.readBool()){if(i.readBool()){let e=i.readByte(),t=[1,12,10,16,40,24,20,32,80,18,15,64,160,4,3,2],o=[1,11,11,11,33,11,11,11,33,11,11,33,99,3,2,1];e>0&&e<16?(v=t[e-1],w=o[e-1]):255===e&&(v=i.readByte()<<8|i.readByte(),w=i.readByte()<<8|i.readByte())}if(i.readBool()&&i.readBool(),i.readBool()&&(i.readBits(4),i.readBool()&&i.readBits(24)),i.readBool()&&(i.readUEG(),i.readUEG()),i.readBool()){let e=i.readBits(32),t=i.readBits(32);E=i.readBool(),B=t,C=2*e,S=B/C}}let R=1;1===v&&1===w||(R=v/w);let k=0,T=0;if(0===n)k=1,T=2-m;else{k=3===n?1:2,T=(1===n?2:1)*(2-m)}let I=16*(h+1),x=16*(p+1)*(2-m);I-=(g+f)*k,x-=(b+y)*T;let D=Math.ceil(I*R);return i.destroy(),i=null,{profile_string:s,level_string:a,bit_depth:c,ref_frames:u,chroma_format:A,chroma_format_string:qe.getChromaFormatString(A),frame_rate:{fixed:E,fps:S,fps_den:C,fps_num:B},sar_ratio:{width:v,height:w},codec_size:{width:I,height:x},present_size:{width:D,height:x}}}static _skipScalingList(e,t){let i=8,o=8,r=0;for(let s=0;s<t;s++)0!==o&&(r=e.readSEG(),o=(i+r+256)%256),i=0===o?i:o}static getProfileString(e){switch(e){case 66:return"Baseline";case 77:return"Main";case 88:return"Extended";case 100:return"High";case 110:return"High10";case 122:return"High422";case 244:return"High444";default:return"Unknown"}}static getLevelString(e){return(e/10).toFixed(1)}static getChromaFormatString(e){switch(e){case 420:return"4:2:0";case 422:return"4:2:2";case 444:return"4:4:4";default:return"Unknown"}}}function Ze(e){const t={},i=new DataView(e.buffer);let o=i.getUint8(0),r=i.getUint8(1);if(i.getUint8(2),i.getUint8(3),1!==o||0===r)return t;const s=1+(3&i.getUint8(4));if(3!==s&&4!==s)return t;let a=31&i.getUint8(5);if(0===a)return;let n=6;for(let o=0;o<a;o++){let r=i.getUint16(n,!1);if(n+=2,0===r)continue;let s=new Uint8Array(e.buffer,n,r);n+=r;let a=qe.parseSPS(s);if(0!==o)continue;t.codecWidth=a.codec_size.width,t.codecHeight=a.codec_size.height,t.presentWidth=a.present_size.width,t.presentHeight=a.present_size.height,t.profile=a.profile_string,t.level=a.level_string,t.bitDepth=a.bit_depth,t.chromaFormat=a.chroma_format,t.sarRatio=a.sar_ratio,t.frameRate=a.frame_rate,!1!==a.frame_rate.fixed&&0!==a.frame_rate.fps_num&&0!==a.frame_rate.fps_den||(t.frameRate={});let A=t.frameRate.fps_den,d=t.frameRate.fps_num;t.refSampleDuration=t.timescale*(A/d);let c=s.subarray(1,4),l="avc1.";for(let e=0;e<3;e++){let t=c[e].toString(16);t.length<2&&(t="0"+t),l+=t}t.codec=l}let A=i.getUint8(n);if(0===A)return t;n++;for(let t=0;t<A;t++){let t=i.getUint16(n,!1);n+=2,0!==t&&(new Uint8Array(e.buffer,n,t),n+=t)}return t.videoType="avc",t}class Ke extends Be{constructor(e){super(),this.player=e,this.hasInit=!1,this.isDecodeFirstIIframe=!1,this.isInitInfo=!1,this.decoder=null,this.initDecoder(),e.debug.log("Webcodecs","init")}destroy(){this.decoder&&("closed"!==this.decoder.state&&this.decoder.close(),this.decoder=null),this.hasInit=!1,this.isInitInfo=!1,this.isDecodeFirstIIframe=!1,this.off(),this.player.debug.log("Webcodecs","destroy")}initDecoder(){const e=this;this.decoder=new VideoDecoder({output(t){e.handleDecode(t)},error(t){e.handleError(t)}})}handleDecode(e){this.isInitInfo||(this.player.video.updateVideoInfo({width:e.codedWidth,height:e.codedHeight}),this.player.video.initCanvasViewSize(),this.isInitInfo=!0),this.player._times.videoStart||(this.player._times.videoStart=he(),this.player.handlePlayToRenderTimes()),this.player.handleRender(),this.player.video.render({videoFrame:e}),this.player.updateStats({fps:!0,ts:0,buf:this.player.demux.delay})}handleError(e){this.player.debug.error("Webcodecs","VideoDecoder handleError",e)}decodeVideo(e,t,i){if(this.hasInit){if(i&&0===e[1]){const t=Ze(e.slice(5)),i=this.player.video.videoInfo;if(t.codecWidth!==i.width||t.codecHeight!==i.height)return this.player.debug.log("Webcodecs",`width or height is update, width ${i.width}-> ${t.codecWidth}, height ${i.height}-> ${t.codecHeight}`),void this.player.emit(j.webcodecsWidthOrHeightChange)}if(!this.isDecodeFirstIIframe&&i&&(this.isDecodeFirstIIframe=!0),this.isDecodeFirstIIframe){const o=new EncodedVideoChunk({data:e.slice(5),timestamp:t,type:i?X:q});this.player.emit(x.timeUpdate,t);try{this.decoder.decode(o)}catch(e){this.player.debug.error("Webcodecs","VideoDecoder",e),-1!==e.toString().indexOf(re)&&this.player.emit(j.webcodecsDecodeError)}}else this.player.debug.warn("Webcodecs","VideoDecoder isDecodeFirstIIframe false")}else if(i&&0===e[1]){const t=15&e[0];if(this.player.video.updateVideoInfo({encTypeCode:t}),t===Q)return void this.emit(j.webcodecsH265NotSupport);this.player._times.decodeStart||(this.player._times.decodeStart=he());const i=function(e){let t=e.subarray(1,4),i="avc1.";for(let e=0;e<3;e++){let o=t[e].toString(16);o.length<2&&(o="0"+o),i+=o}return{codec:i,description:e}}(e.slice(5));this.decoder.configure(i),this.hasInit=!0}}}const _e={play:"播放",pause:"暂停",audio:"",mute:"",screenshot:"截图",loading:"加载",fullscreen:"全屏",fullscreenExit:"退出全屏",record:"录制",recordStop:"停止录制"};var $e=Object.keys(_e).reduce(((e,t)=>(e[t]=`\n <i class="jessibuca-icon jessibuca-icon-${t}"></i>\n ${_e[t]?`<span class="icon-title-tips"><span class="icon-title">${_e[t]}</span></span>`:""}\n`,e)),{}),et=(e,t)=>{const{events:{proxy:i}}=e,o=document.createElement("object");o.setAttribute("aria-hidden","true"),o.setAttribute("tabindex",-1),o.type="text/html",o.data="about:blank",me(o,{display:"block",position:"absolute",top:"0",left:"0",height:"100%",width:"100%",overflow:"hidden",pointerEvents:"none",zIndex:"-1"});let r=e.width,s=e.height;i(o,"load",(()=>{i(o.contentDocument.defaultView,"resize",(()=>{e.width===r&&e.height===s||(r=e.width,s=e.height,e.emit(x.resize),n())}))})),e.$container.appendChild(o),e.on(x.destroy,(()=>{e.$container.removeChild(o)})),e.on(x.volumechange,(()=>{!function(e){if(0===e)me(t.$volumeOn,"display","none"),me(t.$volumeOff,"display","flex"),me(t.$volumeHandle,"top","48px");else if(t.$volumeHandle&&t.$volumePanel){const i=ge(t.$volumePanel,"height")||60,o=ge(t.$volumeHandle,"height"),r=i-(i-o)*e-o;me(t.$volumeHandle,"top",`${r}px`),me(t.$volumeOn,"display","flex"),me(t.$volumeOff,"display","none")}t.$volumePanelText&&(t.$volumePanelText.innerHTML=parseInt(100*e))}(e.volume)})),e.on(x.loading,(e=>{me(t.$loading,"display",e?"flex":"none"),me(t.$poster,"display","none"),e&&me(t.$playBig,"display","none")}));const a=i=>{let o=!0===(r=i)||!1===r?i:e.fullscreen;var r;me(t.$fullscreenExit,"display",o?"flex":"none"),me(t.$fullscreen,"display",o?"none":"flex")},n=()=>{ye()&&t.$controls&&e._opt.useWebFullScreen&&setTimeout((()=>{if(e.fullscreen){let i=e.height/2-e.width+19,o=e.height/2-19;t.$controls.style.transform=`translateX(${-i}px) translateY(-${o}px) rotate(-90deg)`}else t.$controls.style.transform="translateX(0) translateY(0) rotate(0)"}),10)};try{ce.on("change",a),e.events.destroys.push((()=>{ce.off("change",a)}))}catch(e){}e.on(x.webFullscreen,(e=>{a(e),n()})),e.on(x.recording,(()=>{me(t.$record,"display",e.recording?"none":"flex"),me(t.$recordStop,"display",e.recording?"flex":"none"),me(t.$recording,"display",e.recording?"flex":"none")})),e.on(x.recordingTimestamp,(e=>{t.$recordingTime&&(t.$recordingTime.innerHTML=function(e){var t;if(e>-1){var i=Math.floor(e/3600),o=Math.floor(e/60)%60,r=e%60;t=i<10?"0"+i+":":i+":",o<10&&(t+="0"),t+=o+":",(r=Math.round(r))<10&&(t+="0"),t+=r.toFixed(0)}return t}(e))})),e.on(x.playing,(e=>{me(t.$play,"display",e?"none":"flex"),me(t.$playBig,"display",e?"none":"block"),me(t.$pause,"display",e?"flex":"none"),me(t.$screenshot,"display",e?"flex":"none"),me(t.$record,"display",e?"flex":"none"),me(t.$qualityMenu,"display",e?"flex":"none"),me(t.$volume,"display",e?"flex":"none"),a(),e||t.$speed&&(t.$speed.innerHTML=ve(""))})),e.on(x.kBps,(e=>{const i=ve(e);t.$speed&&(t.$speed.innerHTML=i)}))};function tt(e,t){void 0===t&&(t={});var i=t.insertAt;if(e&&"undefined"!=typeof document){var o=document.head||document.getElementsByTagName("head")[0],r=document.createElement("style");r.type="text/css","top"===i&&o.firstChild?o.insertBefore(r,o.firstChild):o.appendChild(r),r.styleSheet?r.styleSheet.cssText=e:r.appendChild(document.createTextNode(e))}}tt('@keyframes rotation{0%{-webkit-transform:rotate(0deg)}to{-webkit-transform:rotate(1turn)}}@keyframes magentaPulse{0%{background-color:#630030;-webkit-box-shadow:0 0 9px #333}50%{background-color:#a9014b;-webkit-box-shadow:0 0 18px #a9014b}to{background-color:#630030;-webkit-box-shadow:0 0 9px #333}}.jessibuca-container .jessibuca-icon{cursor:pointer;width:16px;height:16px}.jessibuca-container .jessibuca-poster{position:absolute;z-index:10;left:0;top:0;right:0;bottom:0;height:100%;width:100%;background-position:50%;background-repeat:no-repeat;background-size:contain;pointer-events:none}.jessibuca-container .jessibuca-play-big{position:absolute;display:none;height:100%;width:100%;background:rgba(0,0,0,.4)}.jessibuca-container .jessibuca-play-big:after{cursor:pointer;content:"";position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);display:block;width:48px;height:48px;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAACgklEQVRoQ+3ZPYsTQRjA8eeZZCFlWttAwCIkZOaZJt8hlvkeHrlccuAFT6wEG0FQOeQQLCIWih6chQgKgkkKIyqKCVYip54IWmiQkTmyYhFvd3Zn3yDb7szu/7cv7GaDkPEFM94PK0DSZ9DzDAyHw7uI2HRDlVJX5/N5r9FoHCYdr/fvCRiNRmpJ6AEidoUQ15NG+AH8BgD2n9AHANAmohdJQfwAfgGA4xF4bjabnW21Whob62ILoKNfAsAGEd2PU2ATcNSNiDf0/cE5/xAHxDpgEf0NADaJ6HLUiKgAbvcjpdSGlPJZVJCoAUfdSqkLxWLxTLlc/mkbEgtgET1TSnWklLdtIuIEuN23crlcp16vv7cBSQKgu38AwBYRXQyLSArg3hsjRDxNRE+CQhIF/BN9qVAobFYqle+mkLQAdLd+8K0T0U0TRJoAbvc9fVkJId75gaQRoLv1C2STiPTb7rFLWgE6+g0RncwyYEJEtawCvjDGmpzzp5kD6NfxfD7frtVqB17xen2a7oG3ALBm+oMoFQBEPD+dTvtBfpImDXjIGFvjnD/3c7ksG5MU4HDxWeZa0HB3XhKAXcdxOn5vUi9gnIDXSqm2lHLPK8pkfVyAbSLqm4T5HRs1YB8RO0KIid8g03FRAT4rpbpSyh3TINPxUQB2GGM9zvkn05gg420CJovLZT9ISNA5tgB9ItoOGhFmnh/AcZ/X9xhj65zzV2Eiwsz1A1j2B8dHAOgS0W6YnduY6wkYj8d3lFKn/j66Ea84jtOrVqtfbQSE3YYnYDAY5Eql0hYAnNDv6kKIx2F3anO+J8DmzqLY1goQxVE12ebqDJgcrSjGrs5AFEfVZJt/AF0m+jHzUTtnAAAAAElFTkSuQmCC");background-repeat:no-repeat;background-position:50%}.jessibuca-container .jessibuca-play-big:hover:after{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAACEElEQVRoQ+2ZXStEQRjH/3/yIXwDdz7J+i7kvdisXCk3SiFJW27kglBcSFFKbqwQSa4krykuKB09Naf2Yndn5jgzc06d53Znd36/mWfeniVyHsw5PwqB0DOonYEoijYBlOpAFwCMkHwLDS/9mwhEDUCfAAyTXA4tYSLwC6CtCegegH6S56FETAR+AHRoACcBTJAUWa+RloBAXwAYIrnt0yBNgZi7qtbHgw8RFwLC/QFglOScawlXAjH3gUqrE1cirgVi7mkAYyS/0xbxJSDcdwAGSa6nKeFTIOZeUyL3aYiEEBDuLwDjJGf+KxFKIOY+BdBL8iipSGiBmHtWbbuftiJZERBuOfgGSK7aSGRJIObeUml1ayKSRQHhlgtkiaTcdltGVgUE+ppkV54FaiS78yrwqlLoOI8Cch2XV548W7WRpTVwA6DP9kGUFYEpAOUkT9LQAvtq1M+0udKkQSgBqSlJWWYxKXj8vRACK+o6bbRIdYI+Ba7U7rKjg7L53JdAhWTZBsy0rWuBXZUuNVMg23auBF7UIl2yBbJt70JAoKV6/WwLk6R9mgKSJlJ1kLTxFmkJyCla8UZd15GJQKvyumyJ8gy8DAEvfZoINPqD41EtUjmUgoaJwAaAnjrKebVI34OSq85NBNqlCAWgE0CV5GEWwI3vQlmCbcSinYFCwPEIFDPgeIC1P1/MgHaIHDf4Aydx2TF7wnKeAAAAAElFTkSuQmCC")}.jessibuca-container .jessibuca-recording{display:none;position:absolute;left:50%;top:0;padding:0 3px;transform:translateX(-50%);justify-content:space-around;align-items:center;width:95px;height:20px;background:#000;opacity:1;border-radius:0 0 8px 8px;z-index:1}.jessibuca-container .jessibuca-recording .jessibuca-recording-red-point{width:8px;height:8px;background:#ff1f1f;border-radius:50%;animation:magentaPulse 1s linear infinite}.jessibuca-container .jessibuca-recording .jessibuca-recording-time{font-size:14px;font-weight:500;color:#ddd}.jessibuca-container .jessibuca-recording .jessibuca-icon-recordStop{width:16px;height:16px;cursor:pointer}.jessibuca-container .jessibuca-loading{display:none;flex-direction:column;justify-content:center;align-items:center;position:absolute;z-index:20;left:0;top:0;right:0;bottom:0;width:100%;height:100%;pointer-events:none}.jessibuca-container .jessibuca-loading-text{line-height:20px;font-size:13px;color:#fff;margin-top:10px}.jessibuca-container .jessibuca-controls{background-color:#161616;box-sizing:border-box;display:flex;flex-direction:column;justify-content:flex-end;position:absolute;z-index:40;left:0;right:0;bottom:0;height:38px;width:100%;padding-left:13px;padding-right:13px;font-size:14px;color:#fff;opacity:0;visibility:hidden;transition:all .2s ease-in-out;-webkit-user-select:none;user-select:none;transition:width .5s ease-in}.jessibuca-container .jessibuca-controls .jessibuca-controls-item{position:relative;display:flex;justify-content:center;padding:0 8px}.jessibuca-container .jessibuca-controls .jessibuca-controls-item:hover .icon-title-tips{visibility:visible;opacity:1}.jessibuca-container .jessibuca-controls .jessibuca-fullscreen,.jessibuca-container .jessibuca-controls .jessibuca-fullscreen-exit,.jessibuca-container .jessibuca-controls .jessibuca-icon-audio,.jessibuca-container .jessibuca-controls .jessibuca-microphone-close,.jessibuca-container .jessibuca-controls .jessibuca-pause,.jessibuca-container .jessibuca-controls .jessibuca-play,.jessibuca-container .jessibuca-controls .jessibuca-record,.jessibuca-container .jessibuca-controls .jessibuca-record-stop,.jessibuca-container .jessibuca-controls .jessibuca-screenshot{display:none}.jessibuca-container .jessibuca-controls .jessibuca-icon-audio,.jessibuca-container .jessibuca-controls .jessibuca-icon-mute{z-index:1}.jessibuca-container .jessibuca-controls .jessibuca-controls-bottom{display:flex;justify-content:space-between;height:100%}.jessibuca-container .jessibuca-controls .jessibuca-controls-bottom .jessibuca-controls-left,.jessibuca-container .jessibuca-controls .jessibuca-controls-bottom .jessibuca-controls-right{display:flex;align-items:center}.jessibuca-container.jessibuca-controls-show .jessibuca-controls{opacity:1;visibility:visible}.jessibuca-container.jessibuca-controls-show-auto-hide .jessibuca-controls{opacity:.8;visibility:visible;display:none}.jessibuca-container.jessibuca-hide-cursor *{cursor:none!important}.jessibuca-container .jessibuca-icon-loading{width:50px;height:50px;background:url("data:image/png;base64,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") no-repeat 50%;background-size:100% 100%;animation:rotation 1s linear infinite}.jessibuca-container .jessibuca-icon-screenshot{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAE5UlEQVRoQ+1YW2sdVRT+1s7JxbsoVkEUrIIX0ouz15zYNA+N1RdtQfCltlUfvLbqL/BCwZ8grbHtizQqPojgBSr0JkiMmT2nxgapqBURtPVCq7HxJCeZJVPmxDlzZubMmXOSEsnAvOy917fXt9e39tp7E5b4R0vcfywTuNgRbBgBx3HuJqLVzPzmYjprjHkcwAlmLqXNm4XAISLaSESPaq2HF4OE67rbRGRYRA7btn1fbgLGmKsA/Azg0gBkGzO/vZAkHMd5hIiqc5wHcCMz/5k0Z2oExsfHV1QqldPAf8lORNu11m8tBAljzFYAYWxRSl1vWdZvuQj4RsYYF4AVBlgIOVVlE55HRIxt23ZuCfmGjuOsJ6LPoiAistW27XfaEYmIbOYhPc9bXywWR1oiEJDYQkR1zrYjEjGyqfqbKd8a7kJVtLgQ+30i8pht2wfyRKIdmJkJBPkQTbILfudJ7CTZNBvVpggEcgpvc/ML38zESbLJsxBNE/A9biX0rdjGyTQXgbxyapdsarb0PMlXtWnGoXbKpm0Essqp3bJpK4E0OXmed3+hUBDP8w5FI91M0rdcyLLILElOCbaZilSWeXMncRx4klTCY1spfG3dhZJWx3GcDUR0EEB3ZMw0ET2gtT6SZWWzjmlrBIJCl0hAKfWgZVmHszqXZVxbCSxpCS2JJA6umIhe8ZKKVLPbaBJ+S9toqVRa53nedgAbAKwIwH4FcAzAa0R0l4i8F7PPz189k6RFRA+LyNcAXojDV0oNW5b1eW4Cxpg9AHZkSaaa6hhzb065uDSCH2LmRB8Sk9gY4293g43Qo/1pV80m8yQMfZSZ781cB1zXHRKRZ2IMpgD8A+DamL4ZItqitX4/jbQx5iEA7wLoihn3V/ACckWMJN/QWj9b1x5tGBsbW6uUOh5pPy0iL3Z2dn6ilJqanp5ep5TaJSLhF4NppdRNaU8gPmapVLrO87yfIoXuWyJ6uVKp+HmFjo6OQSJ6FcBtYT+UUmstyxqvkWuUgDFmP4AnQu2/e563qlgs+u9DNZ8xZhRAX7VRRPbath0XuXk7Y8xeAE+FgL6fnJzsHRwcLIfBR0ZGLunq6poAsDLUvp+Zw7b1r9PGmJMAbg8Z7WDmoThZuK67WkS+DD18fcPMdzSQUBR/EzN/nIC/SUQ+DPXV4dclsTHmHAD/SfHCNzc3t7Kvr++HJKeMMacA3BL0nyuXyzcPDAxMxo0fHR29slAo/Ajg6qD/fE9Pzw29vb1/x42fmJi4vFwu+5G/LOg/y8zXNJLQ2dAES5JANMQ7mfn1jBI6ycx3NiMhItqstf4oAX+ziHwQ6qvDj5NQNIn/ALCKmX+JSeIvABRD7fuY+ekGBPYBeDI05tTMzExvf3+/vz2Hk91/ET8RSeI6/DoCpVJpjed5fmKGvzMAXpqdnT3oed5Ud3d3v4jsAqBr9Ei0Rmv9VRqBBPzvROQVETnq2xJRdRu9tRF+bCVOKWT+Kvl/TSIFk6SW/LAjKfjV5K8rZABi8dOOEv7FI7Z8x6zwEWbemLbyMfJr5qiSiJ96oclymBOR3bZtP9+M89WxxpjdAHY2sN3DzM8ljWl4I3Nd9x7/OE1ENcdpETnmH3e11n41zv0l4J8RkU+J6AAz+xtF4teQQG7PFslwmcAiLfSyhC72Qv9/I/Avns2OT7QJskoAAAAASUVORK5CYII=") no-repeat 50%;background-size:100% 100%}.jessibuca-container .jessibuca-icon-screenshot:hover{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAED0lEQVRoQ+2ZycsdRRTFf2ejqHFAMQqiYBTUoElUHLNx3GgCgpuYRF2o0UT9CxwQ/BMkMSbZSKLiQgQHUDCJgjiAxiEiESdEcJbEedgcKaj3UV+/6q7u/jovPPkK3qbr1ql76p5bt6qemPKmKfefeQKHOoLFCNg+H1gi6fFJOmv7VmCvpD1N87Yh8ApwNXCzpB2TIGF7DRDm2inpmt4EbB8LfAMcGUHWSHryYJKwfRMwmuMP4BRJv9TN2RgB2wuB72BWsq+V9MTBIGF7NZBiGzhJ0o+9CIRBtt8FLqgADC6nRDbpVO9Iuqi3hCKB5cDrGZDVkp4aIhIV2aSQyyW9MScCkcQqIOfsnCORkc3I31b5VtyFRmg1IQ7dt0ja3icSQ2C2JhAjUU2ykd+dE7tBNp2i2olAJJFuc+nCt564QTadF6IzgUhiVGiqyinKaQjZpJP2ItBXTkPJZhACXeU0pGwGI9BWTkPLZlACBTldG4o5EA6E1dY66edcyNrs8Q36zg1vVaTazNs7iXPgDVJJzYs7VRvHRzaDEohyugJ4CTi84sg/wHWSdnVxsGQ7aQLXS9pZcqpL/6AEplpCU5HE8YpJ9YrXUKQ6baN1+HPaRm1fBqwFQnKGK2ZoPwCvAo8Ai4FnMpPMHMwapHUj8DFwbw3+Dklv9iZgexOwvktSRduxU2VDlErwmyXV+lCbxLbDdndlCT3TX3vV7JgnKfRuSVflfMkSsL0ZuDMz4E/gL+CETN+/wCpJzzaRtn0D8DRwWMbu1/gCcnSm7zFJd1W/jxGwvQx4r2IYnlbuA14GAomQFw8B6YtBKFSnNj2BxEJ3IvB1pdB9CjwQ8yqYhcg/DJxZ8WOZpA/SbzkC24DbEqOfgPMkBRKzmu23gEuSj1sk5SI3Y2J7C3BHMuZz4FxJf6fgto8APgIWJd+3SUrHjr9O294HnJUMWi8pSGqs2V4CvJ88fH0i6eyChKr4KyS9WIO/Ang+6RvDz0XgABCeFEdtkaQv65yy/QVweuwPY0+T9FuNQ8cAXwHHxf7wdHiypN9r7BfEl8GjYv9+SceXJLQ/mSDYTh2Baog3SHq0pYT2STqno4RWSnqhBn8l8FzSN4bfJol/jkn8bXUS228DFyfft0paVyCwFbg9sQkSDEkctueZZju8iO+tJPEYfo7A0piYKd73wP3xnB+20cvjNnphxdmlkj4sEMjhfwY8COyOY0fb6Bkl/K6FLKxS+M1KpDhJY8mvrG5doRwlf66QZfGbjhLh4pEt35kV3iUp/IvTunU8qtTil/7gaHOY2yjpntaez9b5RmBDYewmSXfX2RRvZLYvbThOh+NuqMa9Ww1+yLnXgO2SwkZR24oEens2oYHzBCa00PMSOtQL/f+NwH+Hg8hAnbrYgQAAAABJRU5ErkJggg==") no-repeat 50%;background-size:100% 100%}.jessibuca-container .jessibuca-icon-play{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAACgklEQVRoQ+3ZPYsTQRjA8eeZZCFlWttAwCIkZOaZJt8hlvkeHrlccuAFT6wEG0FQOeQQLCIWih6chQgKgkkKIyqKCVYip54IWmiQkTmyYhFvd3Zn3yDb7szu/7cv7GaDkPEFM94PK0DSZ9DzDAyHw7uI2HRDlVJX5/N5r9FoHCYdr/fvCRiNRmpJ6AEidoUQ15NG+AH8BgD2n9AHANAmohdJQfwAfgGA4xF4bjabnW21Whob62ILoKNfAsAGEd2PU2ATcNSNiDf0/cE5/xAHxDpgEf0NADaJ6HLUiKgAbvcjpdSGlPJZVJCoAUfdSqkLxWLxTLlc/mkbEgtgET1TSnWklLdtIuIEuN23crlcp16vv7cBSQKgu38AwBYRXQyLSArg3hsjRDxNRE+CQhIF/BN9qVAobFYqle+mkLQAdLd+8K0T0U0TRJoAbvc9fVkJId75gaQRoLv1C2STiPTb7rFLWgE6+g0RncwyYEJEtawCvjDGmpzzp5kD6NfxfD7frtVqB17xen2a7oG3ALBm+oMoFQBEPD+dTvtBfpImDXjIGFvjnD/3c7ksG5MU4HDxWeZa0HB3XhKAXcdxOn5vUi9gnIDXSqm2lHLPK8pkfVyAbSLqm4T5HRs1YB8RO0KIid8g03FRAT4rpbpSyh3TINPxUQB2GGM9zvkn05gg420CJovLZT9ISNA5tgB9ItoOGhFmnh/AcZ/X9xhj65zzV2Eiwsz1A1j2B8dHAOgS0W6YnduY6wkYj8d3lFKn/j66Ea84jtOrVqtfbQSE3YYnYDAY5Eql0hYAnNDv6kKIx2F3anO+J8DmzqLY1goQxVE12ebqDJgcrSjGrs5AFEfVZJt/AF0m+jHzUTtnAAAAAElFTkSuQmCC") no-repeat 50%;background-size:100% 100%}.jessibuca-container .jessibuca-icon-play:hover{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAACEElEQVRoQ+2ZXStEQRjH/3/yIXwDdz7J+i7kvdisXCk3SiFJW27kglBcSFFKbqwQSa4krykuKB09Naf2Yndn5jgzc06d53Znd36/mWfeniVyHsw5PwqB0DOonYEoijYBlOpAFwCMkHwLDS/9mwhEDUCfAAyTXA4tYSLwC6CtCegegH6S56FETAR+AHRoACcBTJAUWa+RloBAXwAYIrnt0yBNgZi7qtbHgw8RFwLC/QFglOScawlXAjH3gUqrE1cirgVi7mkAYyS/0xbxJSDcdwAGSa6nKeFTIOZeUyL3aYiEEBDuLwDjJGf+KxFKIOY+BdBL8iipSGiBmHtWbbuftiJZERBuOfgGSK7aSGRJIObeUml1ayKSRQHhlgtkiaTcdltGVgUE+ppkV54FaiS78yrwqlLoOI8Cch2XV548W7WRpTVwA6DP9kGUFYEpAOUkT9LQAvtq1M+0udKkQSgBqSlJWWYxKXj8vRACK+o6bbRIdYI+Ba7U7rKjg7L53JdAhWTZBsy0rWuBXZUuNVMg23auBF7UIl2yBbJt70JAoKV6/WwLk6R9mgKSJlJ1kLTxFmkJyCla8UZd15GJQKvyumyJ8gy8DAEvfZoINPqD41EtUjmUgoaJwAaAnjrKebVI34OSq85NBNqlCAWgE0CV5GEWwI3vQlmCbcSinYFCwPEIFDPgeIC1P1/MgHaIHDf4Aydx2TF7wnKeAAAAAElFTkSuQmCC") no-repeat 50%;background-size:100% 100%}.jessibuca-container .jessibuca-icon-pause{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAABA0lEQVRoQ+1YwQqCUBAcfWXXsLr2AXWTPXno8yVB8AP6Aa3oHI+kCDqYaawJljSe133uzO44bx0M/HEG/v1gAd9mkAyQgY4I/F8LJUlyrQFtD2AtIkcNoFEU+Z7n7QD4DfFHEVlocrVmgAUAIAOl3mILPcDgEFcUhyrUKMGUUcroc3NQRimj9XJBGaWMvvPydKN0o6/9QTdKN6rZANxj6EbpRulGuZnjYqs8BbyR8Ub2Izeys+u6yyAIDpo/ehzHM2NMDsA0xFsRmWhyfTIDWSXxCEBmrd2EYXjSHJqm6bQoii2AOYBL5Z0xgFxEVppcrQvQJO0zhgX0iXbdWWSADHRE4AZQ731AhEUeNwAAAABJRU5ErkJggg==") no-repeat 50%;background-size:100% 100%}.jessibuca-container .jessibuca-icon-pause:hover{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAA7klEQVRoQ+2YSwrCQBBEX6HiVvxsPYDewfN7By/gD9ciQkvERQwJdBSiYs0mEDo96aruombEjy/9+P/jAj7NoBkwA28i8H8tFBFRA9oeWEo6ZgCNiDGwAYpn3TpKmmVytWbABQBmoNRbbqEHGB7iiuJYhRol2DJqGX1uDsuoZdRmLuNZSzGWUcuoZdRHSp/IylNgK2ErYSthK3FHwLcSvpXIjoLt9Jfa6TMwl3TIMBkRE2AH9BriL5KGmVyvWIltJXEfKN6tJJ0ym0bECFgDU+Ba+WZQFCdpkcnVuoBM0i5jXECXaNftZQbMwJsI3AAPN3dAQflHegAAAABJRU5ErkJggg==") no-repeat 50%;background-size:100% 100%}.jessibuca-container .jessibuca-icon-record{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAC+UlEQVRoQ+1ZS2sTURT+zlDJYE3XSq219QHVuEjnJDT+Bff9Abqw2voAEfGxqygUqWhVFHGl/yMLu9BwByxk5SNI66ML6U7axjhHbmhgWiftncxoOiV3FcI53z3f/e65594zhIQPSnj86BBot4IdBToKRFyBnbeFlFIScVEiuYvIWC6Xe2YK8pcC7SYA4CMzH4mDQBXAqilQBDsLQLfPf9FxnF4i8kwwmypARI+Wl5dvmIBEsUmlUkNE9NaHsVCpVAZGR0d/m+A2JSAid3K53E0TkCg2pVKpz7KseR/GfKVSGYxMAMA0M1+JEpyJb6lUOm5ZVnkrAsVisaunp+esiByr1Wp3R0ZGvmifzZK4XQQWHMc52MgBpdQuAOcAXABwuB400ZTjONdaIjA7O5u2bVsnWU1EujzP+5nP5xdMVjvIJkCBD8x8VCm1G8AYgAkAAxt8Z5j5YmgCSqlTAJ4D2OcD/AXgATNfbYVEAIFPIvKKiE4D6GuCea8xX6gtpJT6DmBvECgRFRzHeROWRAABE4iWCbwHEFhkPM/L5vP5dyaz+23+KwHXdR3P854S0YG1ILSCuthNMfNM2OC1/RYENLY+ygcBnPfht6ZAA6BYLNr6dyqVokKhsGpaNQ2TWJstreXaE2aed133sojcj41AKyvdzCdAgSXLsk4MDw9/a/i4rntbRPxFNZoC/5jAV2be759DKTUJ4FZSFFi0bbs/k8noy2R9dAjEuWU2YgXkQOK3kD6BMsysi2Z9JC2Jdcw/ALzwPO+xvmcl7Rj177JVEbkO4BARjSflFDJJuW1dBxJPoCIiL4noDIB1BS0pW6j+oJmbm+uuVqvjRKQfLr0bZHnIzJf0f6HeAybahrUJqAPruhLlcnnPysqKfpXp11n/Gv62zoHAroS+AafT6QkiGrIsazKbzX7eVIHEt1US39gCkOzWYthkjNE+tuZujDGZQ8XRXn8N4KT5lLFZ6uaYPt+nwyDuvC80YdhvB9uOAu1WoaNAR4GIK/AHvdr+QAexB7EAAAAASUVORK5CYII=") no-repeat 50%;background-size:100% 100%}.jessibuca-container .jessibuca-icon-record:hover{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAACfUlEQVRoQ+2ZSYsUQRCFvycK4nJXXEbHBdwO4kn/gv9CD467ICIutxEFkREdFUU86T/xojcPntyQcT2INw+uISFVkD1Wd2dWlU7nUHlqisiX+fJFZGREi8yHMt8/HYG5VrBToFOg4QnMPxcyM2t4KE2nT0i6EwvylwIjQOCFpE1tEPgGfI0FamC3AFgazP8IrJL0KwZzkAI3gLMxIA1ttgCPA4w3wHpJP2NwBxG4KOlcDEgTGzNbA8wEGP57vA0CU5JONtlczFwz2wY8HUbAzBYCB4CtwCVJb33OIAXmioC70LoyBsxsEXAQOApsLIhelnS6FgEzW+5BBvwA/FS+SPJFa40KBZ5L2mxmS4AJ4IjHxCzwaUnHkgmY2V7gLrAyAPwOXJN0qg6DCgIvgQfAPsDjo2pcKddLciEz+wCs6AO6W9KjVBIVBGIgahN4BvRLMjslPYlZPbT53wR2AbeBtcUmXEFPdh5U06mbd/shBBzbr/Jx4FCAX0+BEsDMFocEYrNmFcE+BD4XsXZL0oyZnQCutkagzkn3m1NBwDe/Q9L74MAuFEqUn5op8I8JvJO0elacTALnc1HAH3Njkvwx+WeYWUegTa/pwaqIgexdyIN4uyRPmqULZRXEvulPwD3gpr+zcrtGQxfzRHYG2AAczuUWiom3kc4D2RN4BdwH9gM9CS0XFyoLGu9UuN974eIFVDiuSzruH5LqgRhtU20q8kBPV8LMlhVVmVdnYwX+SMdAZVeieAF7eeltmElJr4cpkH1bJfvGVvatxdR4bMu+teZuWxtKxWncXn8I7EldtQV7vz79fp9KwZp//9CksB8F206BuVahU6BToOEJ/Ab7+KdABdTt8AAAAABJRU5ErkJggg==") no-repeat 50%;background-size:100% 100%}.jessibuca-container .jessibuca-icon-recordStop{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAGDElEQVRoQ82ZaahVVRTHf//moKKggQawcmg0olGl0awvRoMVBRGFlQ1YQZIZqRVKmJmFgVk59EFQykYjgmajbJ7n2WiAbKKCBq0Vfznndd723Lvvve/5bMH9cvfaa63/2WuvaYteoIjYHDgEOAAYDOwIbA/4f9PvwHfAt8DbwGvAS5L8f49Ine6OCO89CTgFOBrYqU1Z3wBPAUskPdDm3i72jgBExCXAWGBQp4qTfR8CMyXd0a68tgBExEjgBmCfdhW1yP8eMFHS/S3y0xKAiNgQmA2MaUHwB8DnwNfAbwX/FsDOwG7Ani3I8ElcLOnvHG8WQET0Ax4C9msi7BHgbuAFSXaHhhQRewBDgZOBE5qwvuV1SSuayWsKICIcVZ4Atq4R8mdxKnMkfZT7UnXrEeE7dD7gO7VpDc/PwAhJrzaS3xBAROzrUFcJhVUZjhrjJX3cieHpnogYUNytUTXy/gAOlvROna5aABHhGG5f3qZmk33ztt4wvAbIBcCcBicxSNLKdK0RgNeB/RPmVcBxkp5eF8aXMiPiKODRGpd6XZJduhutBSAipgNX1Bg/tJkv9iao4u4tBzZJ5N4oaXz1v24AImIvwLE4peGSnDX7jCLC2f3JGoV7S3q//D8F8DJwULJpgiQnrz6niLgSmJYofkXSwWsBiIgRwGPNmPscARARDqGp7zu0Orz/l4kjYhlweGLk4Ebhq8oXEc6wGwH/tAhyA2C1JGfsphQRTqBvJkzLJB3ZBaBIKGkGXSqpWab013FWvacooXO21K07256WS4QRsRQ4PhHgsPrxmjsQEZOB6xKGIZJebGZVRDwOHNOJ5ZU9j0s6NqPnUJcpCc9kSVNKAA5ZQyoMn0gamDMsIj4rCrQca7P1zyT1zwmIiE+AKt9yScNUFGuuZaoxd7okR4Ccfzq997S0fleSy5acrjQ//QUMNADXH/cmu0dKcoWZE+r2MKs8I+YdSW5Dc7rcizycMI0ygKuA6ysLjiT9JX3RgtC+BLArYJet5q4JBuBG5aKKsV/ZryWt/p8BcJj2R3VjVNJsA1gEnFH5821JzZqXLtaI6LMTsNIafYsM4L6iOyoNe1FSNSI1PIj1AMCh1CG1pPsNYEkxGin/fFVSWg/VglgPAF4BDqwYs8QAFgDnVP78SJIzbJbWAwBXC9VRzgIDcLVXjfm/AP0kuR/NhbY+uwMR4e7QDf6WFaOmGYBHJbcnlh7USvPSlycQEXYdu1CVxhiARxzPJwsXSarrTbux9TEAh3qH/CqtKSU2Az5NZpsPSTqxBRdy49/SfWki60NJ2WFXTUXqwdmAsphbCJxZUeIGfltJvg8NKSIMfPcc0Mx6tpiLiK2AH4qeoxS3UNJZJYC6emicpJkZAOOAGT0EcLmkmzvQM8oz1BLAxsX8vjqBWynJ86FcJDoLGO4OC8jOMgthnrX696Qkn35Oh+dB21aYfgJ2kLSqqzCKiGuAaxNJkyRNzSlYl+sNmq2pkiZZbxWAJ8g/Aj6NksI+3kplui5AFL2271m1AvVJb1fmqXSsMhGYkhjznqSeNi0d4YsIz3/SCNXNK+omcy5ZPVKv0r2STu3Iig431dRolrRCkvuCLqoD4BlM3Th7nqTzOrSnrW0RcSdQp+tASX4gbAzAK8Ub2KwarQ8Cp0vy20CvU5FUFwN1SfRSSbemSpu9D9wCXFZjpacDoyU925sIIuIw4K5k8lCqmCWpzpbmb2QRMRc4t4GhfiOYJunLngCJiF2Aq4ELG8iZL6mRDflHvohwpnXGrSM/VM8DFkt6rh0gxRd3K3s24BBeRzMkpaP+bnzZR77iTvgLuOR29mxEDnmer7rk9dPT98CvBbNreGdSD8s8WT4i81rpjD5G0vzcR2kJQAHCs5ubgKZjwERhednrHvAa2eaPMFaSm6UstQyglBQRDm92qWwJnNXencGnZpdp67W+bQAVIKOLCz6sTUNTdjdTcyW5N2+bOgZQAeLHQLuV5/UeM6ZZPDXKfa1nqs/4QUXSG21bXdnQYwBV5RHhy2rXcmh0E+5GxOTGyCWwp34fSCovd09sX7P3X2uzPXCoLsVMAAAAAElFTkSuQmCC") no-repeat 50%;background-size:100% 100%}.jessibuca-container .jessibuca-icon-recordStop:hover{background:url("data:image/png;base64,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") no-repeat 50%;background-size:100% 100%}.jessibuca-container .jessibuca-icon-fullscreen{background:url("data:image/png;base64,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") no-repeat 50%;background-size:100% 100%}.jessibuca-container .jessibuca-icon-fullscreen:hover{background:url("data:image/png;base64,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") no-repeat 50%;background-size:100% 100%}.jessibuca-container .jessibuca-icon-fullscreenExit{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAADd0lEQVRoQ+2Zz2sdVRTHv+fJBDW6anDVXen6wZszYxYBiYgtFGst3VSDunKjpS0GpUlqfjVpsVVs6aaL0or4YxMVFCJZ2ZLdPUP+gq5bQnTxtNAkfTnlhnnlkmQy9yV9780rudt77tzv5/y4v4bQ4Y06XD/2ANodwec/AiJygJnvtdvTWfPnRkBEJAiCN8rl8kMfiPn5+Ve7u7v3rays0Orq6lJfX99/PuN2auMDoAD+BvA2M6/mTWSMOUtE48D6AjHGzN/kjdlNvy+AnWOOmQ/lTSYiEwDOWzsimgrDcCRvzG76GwGw8/zJzO9sN6GInAMwbW1UdSSKoqndCMwb6wNwGsB39Q+p6h/M/C4R2dTa1AoHYBWKyCkA1+pqiWi2Wq0e7e/vf7yRoJAAKcQggMtuJKIoOtoxACnE0/xOi/SXMAxPuhCFjUBdpIjYVWXSEf0TM3/g9BeriDMKdSPEz8z8vrU1xgwT0YXCrEJZy1iSJKOqOub0/8jMA0mSfKKqNwoPkHp7ioiGHIhRIvpHVa93BEBa2JcAfOlALAHo6RgAKzRJkk9V1S6xL7kpV4idOM31taxaIKJHqmpPnMMA9hcOQES2PDJkAT1XAAC+ZebPfWB3auNzmLObVsNRUNUXVHUujuM7OxXnMy4XwOcj29mIyOuq+lapVGrYCelKpkEQ3CyXy4tbzdN0AGPMxr2iYZ+sra3FcRybtgCIiK2BKw2rdgaUSqWoUqlIkQAepFDdAF7cBq5ERI9rtdr1OI7tmE2t6SmUEYFHAEaexYW/1QC2EF+ru5GIvg7D0D2GNJxprQY4o6qv1I/b6SpzOYqiLxpWng5oOQAzXxWRWwA+dkRfYOb1p5hGW6sBJpn5KytSRG4D+KguWFXHoyhy7xdeLC0F2ChSRL4H8OFuINoKYIUbY34gogHH3eeZef1K6tPaDpCm068A3nMEDzHzxY4BUNWSiPxORO6z5aDPPlGICNQ9bYyZIaLjjudzIQoFkKbTbwCO+UI0HcB9J/LdeY0xs0R02IGYYObRrWqiFQCfEZEtSHsfmGZm+4qxbbM/hQD8BeBNa0hEM2EYnmgLgP3lFARBT1dXly4vL//b29tbzQNIU+llAHeJaLFSqRzJes5vegR8xGbZLCwsHKzVav8z8/0sm0ID+MDvAfh4qZk2exFopnd9vv0ELrXBQO7fD10AAAAASUVORK5CYII=") no-repeat 50%;background-size:100% 100%}.jessibuca-container .jessibuca-icon-fullscreenExit:hover{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAC/ElEQVRoQ+2Zy49NQRCHvx+ReK6IlZ34E7CUiCAR4xEbTLCyQRATYswwb2IQZDYWgojHZpCQECts+ResiQwLj0RClNSkb9Lu3HtPz7mZc8+V6eXt6tP1VVV3VdcVbT7U5vozC9BqD/7/HjCzlZLet9rS9fbP9ICZvQPWSfqRAmFmS4ClMHm+JiR9S1mXVyYFwIBXwEZJv7I2MrPjQH8A6JN0OWtNM/OpAL7HS0mbsjYzswGgN8gNS+rJWtPM/HQAfJ9nkrY22tDMTgMjQaZH0nAzCmatTQE4ClyNPvQU2CbJQ2vKKB2Aa2hmR4DrkbbPgQ5Jv6sJSgkQILqA0dgTkjraBiBAxPHtPz2UtDuGKK0HKkqamd8qg5HS9yXtjebLdYjrHNRqiAeS9gQvnQGGSnML1bvGzOwc0BfN35PUaWYHgRulBwjW9ju+O4JwqM/AWFsABIgLwKkIYgJY1jYAAeJQuGIXVIVcKTKxh8WfBin9J+AVpx/eFWUEqFkyNACKp0rhgWYArkg6kQibSyylmPOklQdibijBX+fSLHFRJkDid+qKmdlaYENOI0zeEcBNSZ9qbVIEQHWuyGOTNZLetgrAz8ClPFpHa1ZL8rf5lFGEB2oBfAxQi4D5DeDmAP7mGJPka0oD4LnDr9imH/xFe8AP4vLIjBclxWXItCOtaIBjwOKo3HaFRyWdnLbmYUHhAJKumdkt4ECk9JCkSitmWixFAwxKOjt5uZvdBvZH2vZLit8XSSBFA/yjpJndAfY1A9FSgOCJu0BnBNErqfIkzfRCywECxCNgR6Rtt6TzmdqHBmyKXG4ZM4sTWc04NzNPWE+AuG3ZlZInSuGBinXMbBzYGVkrE6JUACGcHgPbUyGKAIj7REmZ18y897o5ghiQ5E/bltRChwE/kF7Xj0jyLkbDYWbzgBfA+iA4LmlXqwD8LydvszjAF0lfswBCKC0E3gBeP22p186f8RBKUbaejJmtAr5L+lBPptQAKfCzAClWmkmZWQ/MpHVTvv0X9iFAQGQyevIAAAAASUVORK5CYII=") no-repeat 50%;background-size:100% 100%}.jessibuca-container .jessibuca-icon-audio{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAACrUlEQVRoQ+2ZPYgTURCAZzbBXJnCeL2Cnb87b9MEtPBUrrMQFAtrtT5/ClGs9LBWWz0RtbBUFCF4oJDsbO68wsLA2YqQSmLlvpEHu7IuMdlLcus+yUKKhJfZ+ebnvZl5CJY/aLn+MAP41x7M1QPMfFtr/crzvHfTAs8FoNPp1LTWzwHgqIg0lFLvrQHwfX8BER8DwC6jNCIecF13wwoA3/dvIuKNpLJa60Oe560XGoCZd4rICiKeTCtaeABmPg4AJmRqg6xcaABmvg4At4aFRyEBhoVM4UMoCplHADCfJTEL5YEsIVNID5iQAYCHALCYxeq5b6PMfF5EBAAEESthGK7W6/XPRpFWq7W3VCqtZg2ZcT3g+/6i4zjzIlLSWn/yPO/DIGMNLCWY2Sj/+xGRK0qpZfNDEASnROTFVi0fr8+aA8z8Ld6KEfGt67oLYwMAwEUium8EREn7OgeAjwCwPyo/nrque3YSgAtE9GDaAM1mc65arc4Zuf1+P2w0Gt9jJZl5DQAORt+fENG5wgEw8zUAMB/zbBBRwyqAIAjuiMjlSOlNItpjFUCqWl0josMzgChR/9hGAWBbknjmAdPhDdqa0gfZzAMJKyVP4v8hhJYRcSni+0JEu63ahZj5anyQici6UuqIVQDdbrfS6/UqRulyufyTiH5sF8AlIro37VpoWEHIzGZ2tM+sEZFnSqkzk9RCS0R01wjIsZz+mug53hDRia0AnI4bGgDYISItz/M2jYC8Gpp2u30MEWuO4zha665Sqp0ZYFStX/iWchRAItFGzoHSsrJ2ZFl1mHg6bfVYJeGJv85CC++BpIJZ5kSFC6G0ha0e7mYJqcJ7IOkRay84UhD2XjHFIFZf8iW9YcYoYRi+tO6aNeupOs66iU/icV46zf/MAKZpzXFk/QL+JG1PUPhRiQAAAABJRU5ErkJggg==") no-repeat 50%;background-size:100% 100%}.jessibuca-container .jessibuca-icon-audio:hover{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAACSElEQVRoQ+2Zu4sUQRCHf5+C+gf4yBXMfMYHGvjCzEBQDIzV+HwEohipGKupD0QNDE8UEwUFTe68wEDhTMVUMFJ+0tArzbjs9u3Ojt0wBR0M9MzUV1XdXVWNKhcq1189wP/2YKcesH1d0nPgdVvgnQDY3iTpqaT9kuaAt9UA2D4o6aGkzVHpXcByFQC2r0q60lB2D7BUNIDtjZIeSDoyRNGyAWwfiiET4n6YlAtg+7Kka2PCozyAMSHT5CkLIIbMfUlbMhdmOQCZIVOeB2LI3JN0NNPq6bTZe8D2aUmOY72kN8DnoIXt7eF5FSEzkQdsB+OEsFwr6RPwbpixhqYStoPyqVwAbkaAY5KeTWD5wStZHrD9XdJgK34FhBP9H8kFOAvciQBhn3/RAcBHSTvjfx4DJ6cBOAPcbRvA9gZJYQT5DfwYKGl7UdLu+PwIOFUiwCVJYQRZBuZqA7gh6XxUegXYVhtAmq0uAnt7gLhQm9vorBZx74Hcc6D3QLKH/z2JGyVnlYs4pCfzEe4rsLW2XehicpAtAftqAwiZbhhBfgE/ZwVwDrjddi40KiG0HXpHO+KcJ8CJaXKheeBWBOgqnf6W1BwvgcOrATieFDTrJL0HViJAVwXNgVgPrJH0BfiQDTDKtREiNK7KLSnHASQLLacP1PxcVkWWq8PU3emq2yqJJ0b1Qsv2QKpdZp+orBBqmrfq5m5mSJXtgUZI1XnB0YCo94opCal6L/ka3ghtlIXqrllzT9VJ5k19Ek/y0zbf6QHatOYk3/oDujC8QMWgjf4AAAAASUVORK5CYII=") no-repeat 50%;background-size:100% 100%}.jessibuca-container .jessibuca-icon-mute{background:url("data:image/png;base64,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") no-repeat 50%;background-size:100% 100%}.jessibuca-container .jessibuca-icon-mute:hover{background:url("data:image/png;base64,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") no-repeat 50%;background-size:100% 100%}.jessibuca-container .jessibuca-icon-text{font-size:14px;width:30px}.jessibuca-container .jessibuca-speed{font-size:14px;color:#fff}.jessibuca-container .jessibuca-quality-menu-list{position:absolute;left:50%;bottom:100%;visibility:hidden;opacity:0;transform:translateX(-50%);transition:visibility .3s,opacity .3s;background-color:rgba(0,0,0,.5);border-radius:4px}.jessibuca-container .jessibuca-quality-menu-list.jessibuca-quality-menu-shown{visibility:visible;opacity:1}.jessibuca-container .icon-title-tips{pointer-events:none;position:absolute;left:50%;bottom:100%;visibility:hidden;opacity:0;transform:translateX(-50%);transition:visibility .3s ease 0s,opacity .3s ease 0s;background-color:rgba(0,0,0,.5);border-radius:4px}.jessibuca-container .icon-title{display:inline-block;padding:5px 10px;font-size:12px;white-space:nowrap;color:#fff}.jessibuca-container .jessibuca-quality-menu{padding:8px 0}.jessibuca-container .jessibuca-quality-menu-item{display:block;height:25px;margin:0;padding:0 10px;cursor:pointer;font-size:14px;text-align:center;width:50px;color:hsla(0,0%,100%,.5);transition:color .3s,background-color .3s}.jessibuca-container .jessibuca-quality-menu-item:hover{background-color:hsla(0,0%,100%,.2)}.jessibuca-container .jessibuca-quality-menu-item:focus{outline:none}.jessibuca-container .jessibuca-quality-menu-item.jessibuca-quality-menu-item-active{color:#2298fc}.jessibuca-container .jessibuca-volume-panel-wrap{position:absolute;left:50%;bottom:100%;visibility:hidden;opacity:0;transform:translateX(-50%) translateY(22%);transition:visibility .3s,opacity .3s;background-color:rgba(0,0,0,.5);border-radius:4px;height:120px;width:50px;overflow:hidden}.jessibuca-container .jessibuca-volume-panel-wrap.jessibuca-volume-panel-wrap-show{visibility:visible;opacity:1}.jessibuca-container .jessibuca-volume-panel{cursor:pointer;position:absolute;top:21px;height:60px;width:50px;overflow:hidden}.jessibuca-container .jessibuca-volume-panel-text{position:absolute;left:0;top:0;width:50px;height:20px;line-height:20px;text-align:center;color:#fff;font-size:12px}.jessibuca-container .jessibuca-volume-panel-handle{position:absolute;top:48px;left:50%;width:12px;height:12px;border-radius:12px;margin-left:-6px;background:#fff}.jessibuca-container .jessibuca-volume-panel-handle:before{bottom:-54px;background:#fff}.jessibuca-container .jessibuca-volume-panel-handle:after{bottom:6px;background:hsla(0,0%,100%,.2)}.jessibuca-container .jessibuca-volume-panel-handle:after,.jessibuca-container .jessibuca-volume-panel-handle:before{content:"";position:absolute;display:block;left:50%;width:3px;margin-left:-1px;height:60px}.jessibuca-container.jessibuca-fullscreen-web .jessibuca-controls{width:100vh}.jessibuca-container.jessibuca-fullscreen-web .jessibuca-play-big:after{transform:translate(-50%,-50%) rotate(270deg)}.jessibuca-container.jessibuca-fullscreen-web .jessibuca-loading{flex-direction:row}.jessibuca-container.jessibuca-fullscreen-web .jessibuca-loading-text{transform:rotate(270deg)}');class it{constructor(e){var t;this.player=e,((e,t)=>{e._opt.hasControl&&e._opt.controlAutoHide?e.$container.classList.add("jessibuca-controls-show-auto-hide"):e.$container.classList.add("jessibuca-controls-show");const i=e._opt,o=i.operateBtns;e.$container.insertAdjacentHTML("beforeend",`\n ${i.background?`<div class="jessibuca-poster" style="background-image: url(${i.background})"></div>`:""}\n <div class="jessibuca-loading">\n ${$e.loading}\n ${i.loadingText?`<div class="jessibuca-loading-text">${i.loadingText}</div>`:""}\n </div>\n ${i.hasControl&&o.play?'<div class="jessibuca-play-big"></div>':""}\n ${i.hasControl?`\n <div class="jessibuca-recording">\n <div class="jessibuca-recording-red-point"></div>\n <div class="jessibuca-recording-time">00:00:01</div>\n <div class="jessibuca-icon-recordStop jessibuca-recording-stop">${$e.recordStop}</div>\n </div>\n `:""}\n ${i.hasControl?`\n <div class="jessibuca-controls">\n <div class="jessibuca-controls-bottom">\n <div class="jessibuca-controls-left">\n ${i.showBandwidth?'<div class="jessibuca-controls-item jessibuca-speed"></div>':""}\n </div>\n <div class="jessibuca-controls-right">\n ${o.audio?`\n <div class="jessibuca-controls-item jessibuca-volume">\n ${$e.audio}\n ${$e.mute}\n <div class="jessibuca-volume-panel-wrap">\n <div class="jessibuca-volume-panel">\n <div class="jessibuca-volume-panel-handle"></div>\n </div>\n <div class="jessibuca-volume-panel-text"></div>\n </div>\n </div>\n `:""}\n ${o.play?`<div class="jessibuca-controls-item jessibuca-play">${$e.play}</div><div class="jessibuca-controls-item jessibuca-pause">${$e.pause}</div>`:""}\n ${o.screenshot?`<div class="jessibuca-controls-item jessibuca-screenshot">${$e.screenshot}</div>`:""}\n ${o.record?` <div class="jessibuca-controls-item jessibuca-record">${$e.record}</div><div class="jessibuca-controls-item jessibuca-record-stop">${$e.recordStop}</div>`:""}\n ${o.fullscreen?`<div class="jessibuca-controls-item jessibuca-fullscreen">${$e.fullscreen}</div><div class="jessibuca-controls-item jessibuca-fullscreen-exit">${$e.fullscreenExit}</div>`:""}\n </div>\n </div>\n </div>\n `:""}\n\n `),Object.defineProperty(t,"$poster",{value:e.$container.querySelector(".jessibuca-poster")}),Object.defineProperty(t,"$loading",{value:e.$container.querySelector(".jessibuca-loading")}),Object.defineProperty(t,"$play",{value:e.$container.querySelector(".jessibuca-play")}),Object.defineProperty(t,"$playBig",{value:e.$container.querySelector(".jessibuca-play-big")}),Object.defineProperty(t,"$recording",{value:e.$container.querySelector(".jessibuca-recording")}),Object.defineProperty(t,"$recordingTime",{value:e.$container.querySelector(".jessibuca-recording-time")}),Object.defineProperty(t,"$recordingStop",{value:e.$container.querySelector(".jessibuca-recording-stop")}),Object.defineProperty(t,"$pause",{value:e.$container.querySelector(".jessibuca-pause")}),Object.defineProperty(t,"$controls",{value:e.$container.querySelector(".jessibuca-controls")}),Object.defineProperty(t,"$fullscreen",{value:e.$container.querySelector(".jessibuca-fullscreen")}),Object.defineProperty(t,"$fullscreen",{value:e.$container.querySelector(".jessibuca-fullscreen")}),Object.defineProperty(t,"$volume",{value:e.$container.querySelector(".jessibuca-volume")}),Object.defineProperty(t,"$volumePanelWrap",{value:e.$container.querySelector(".jessibuca-volume-panel-wrap")}),Object.defineProperty(t,"$volumePanelText",{value:e.$container.querySelector(".jessibuca-volume-panel-text")}),Object.defineProperty(t,"$volumePanel",{value:e.$container.querySelector(".jessibuca-volume-panel")}),Object.defineProperty(t,"$volumeHandle",{value:e.$container.querySelector(".jessibuca-volume-panel-handle")}),Object.defineProperty(t,"$volumeOn",{value:e.$container.querySelector(".jessibuca-icon-audio")}),Object.defineProperty(t,"$volumeOff",{value:e.$container.querySelector(".jessibuca-icon-mute")}),Object.defineProperty(t,"$fullscreen",{value:e.$container.querySelector(".jessibuca-fullscreen")}),Object.defineProperty(t,"$fullscreenExit",{value:e.$container.querySelector(".jessibuca-fullscreen-exit")}),Object.defineProperty(t,"$record",{value:e.$container.querySelector(".jessibuca-record")}),Object.defineProperty(t,"$recordStop",{value:e.$container.querySelector(".jessibuca-record-stop")}),Object.defineProperty(t,"$screenshot",{value:e.$container.querySelector(".jessibuca-screenshot")}),Object.defineProperty(t,"$speed",{value:e.$container.querySelector(".jessibuca-speed")})})(e,this),t=this,Object.defineProperty(t,"controlsRect",{get:()=>t.$controls.getBoundingClientRect()}),et(e,this),((e,t)=>{const{events:{proxy:i},debug:o}=e;function r(e){const{bottom:i,height:o}=t.$volumePanel.getBoundingClientRect(),{height:r}=t.$volumeHandle.getBoundingClientRect();return pe(i-e.y-r/2,0,o-r/2)/(o-r)}if(i(window,["click","contextmenu"],(i=>{i.composedPath().indexOf(e.$container)>-1?t.isFocus=!0:t.isFocus=!1})),i(window,"orientationchange",(()=>{setTimeout((()=>{e.resize()}),300)})),i(t.$controls,"click",(e=>{e.stopPropagation()})),i(t.$pause,"click",(t=>{e.pause()})),i(t.$play,"click",(t=>{e.play(),e.resumeAudioAfterPause()})),i(t.$playBig,"click",(t=>{e.play(),e.resumeAudioAfterPause()})),i(t.$volume,"mouseover",(()=>{t.$volumePanelWrap.classList.add("jessibuca-volume-panel-wrap-show")})),i(t.$volume,"mouseout",(()=>{t.$volumePanelWrap.classList.remove("jessibuca-volume-panel-wrap-show")})),i(t.$volumeOn,"click",(i=>{i.stopPropagation(),me(t.$volumeOn,"display","none"),me(t.$volumeOff,"display","block");const o=e.volume;e.volume=0,e._lastVolume=o})),i(t.$volumeOff,"click",(i=>{i.stopPropagation(),me(t.$volumeOn,"display","block"),me(t.$volumeOff,"display","none"),e.volume=e.lastVolume||.5})),i(t.$screenshot,"click",(t=>{t.stopPropagation(),e.video.screenshot()})),i(t.$volumePanel,"click",(t=>{t.stopPropagation(),e.volume=r(t)})),i(t.$volumeHandle,"mousedown",(()=>{t.isVolumeDroging=!0})),i(t.$volumeHandle,"mousemove",(i=>{t.isVolumeDroging&&(e.volume=r(i))})),i(document,"mouseup",(()=>{t.isVolumeDroging&&(t.isVolumeDroging=!1)})),i(t.$record,"click",(t=>{t.stopPropagation(),e.recording=!0})),i(t.$recordStop,"click",(t=>{t.stopPropagation(),e.recording=!1})),i(t.$recordingStop,"click",(t=>{t.stopPropagation(),e.recording=!1})),i(t.$fullscreen,"click",(t=>{t.stopPropagation(),e.fullscreen=!0})),i(t.$fullscreenExit,"click",(t=>{t.stopPropagation(),e.fullscreen=!1})),e._opt.hasControl&&e._opt.controlAutoHide){i(e.$container,"mouseover",(()=>{e.fullscreen||(me(t.$controls,"display","block"),r())})),i(e.$container,"mousemove",(()=>{e.$container&&t.$controls&&(e.fullscreen,"none"===t.$controls.style.display&&(me(t.$controls,"display","block"),r()))})),i(e.$container,"mouseout",(()=>{s(),me(t.$controls,"display","none")}));let o=null;const r=()=>{s(),o=setTimeout((()=>{me(t.$controls,"display","none")}),5e3)},s=()=>{o&&(clearTimeout(o),o=null)}}})(e,this),e._opt.hotKey&&((e,t)=>{const{events:{proxy:i}}=e,o={};function r(e,t){o[e]?o[e].push(t):o[e]=[t]}r(te,(()=>{e.fullscreen&&(e.fullscreen=!1)})),r(ie,(()=>{e.volume+=.05})),r(oe,(()=>{e.volume-=.05})),i(window,"keydown",(e=>{if(t.isFocus){const t=document.activeElement.tagName.toUpperCase(),i=document.activeElement.getAttribute("contenteditable");if("INPUT"!==t&&"TEXTAREA"!==t&&""!==i&&"true"!==i){const t=o[e.keyCode];t&&(e.preventDefault(),t.forEach((e=>e())))}}}))})(e,this),this.player.debug.log("Control","init")}destroy(){this.$poster&&this.player.$container.removeChild(this.$poster),this.$loading&&this.player.$container.removeChild(this.$loading),this.$controls&&this.player.$container.removeChild(this.$controls),this.$recording&&this.player.$container.removeChild(this.$recording),this.$playBig&&this.player.$container.removeChild(this.$playBig),this.player.debug.log("control","destroy")}autoSize(){const e=this.player;e.$container.style.padding="0 0";const t=e.width,i=e.height,o=t/i,r=e.video.$videoElement.width/e.video.$videoElement.height;if(o>r){const o=(t-i*r)/2;e.$container.style.padding=`0 ${o}px`}else{const o=(i-t/r)/2;e.$container.style.padding=`${o}px 0`}}}tt(".jessibuca-container{position:relative;display:block;width:100%;height:100%;overflow:hidden}.jessibuca-container.jessibuca-fullscreen-web{position:fixed;z-index:9999;left:0;top:0;right:0;bottom:0;width:100vw!important;height:100vh!important;background:#000}");class ot{static init(){ot.types={avc1:[],avcC:[],hvc1:[],hvcC:[],btrt:[],dinf:[],dref:[],esds:[],ftyp:[],hdlr:[],mdat:[],mdhd:[],mdia:[],mfhd:[],minf:[],moof:[],moov:[],mp4a:[],mvex:[],mvhd:[],sdtp:[],stbl:[],stco:[],stsc:[],stsd:[],stsz:[],stts:[],tfdt:[],tfhd:[],traf:[],trak:[],trun:[],trex:[],tkhd:[],vmhd:[],smhd:[]};for(let e in ot.types)ot.types.hasOwnProperty(e)&&(ot.types[e]=[e.charCodeAt(0),e.charCodeAt(1),e.charCodeAt(2),e.charCodeAt(3)]);let e=ot.constants={};e.FTYP=new Uint8Array([105,115,111,109,0,0,0,1,105,115,111,109,97,118,99,49]),e.STSD_PREFIX=new Uint8Array([0,0,0,0,0,0,0,1]),e.STTS=new Uint8Array([0,0,0,0,0,0,0,0]),e.STSC=e.STCO=e.STTS,e.STSZ=new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0]),e.HDLR_VIDEO=new Uint8Array([0,0,0,0,0,0,0,0,118,105,100,101,0,0,0,0,0,0,0,0,0,0,0,0,86,105,100,101,111,72,97,110,100,108,101,114,0]),e.HDLR_AUDIO=new Uint8Array([0,0,0,0,0,0,0,0,115,111,117,110,0,0,0,0,0,0,0,0,0,0,0,0,83,111,117,110,100,72,97,110,100,108,101,114,0]),e.DREF=new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,12,117,114,108,32,0,0,0,1]),e.SMHD=new Uint8Array([0,0,0,0,0,0,0,0]),e.VMHD=new Uint8Array([0,0,0,1,0,0,0,0,0,0,0,0])}static box(e){let t=8,i=null,o=Array.prototype.slice.call(arguments,1),r=o.length;for(let e=0;e<r;e++)t+=o[e].byteLength;i=new Uint8Array(t),i[0]=t>>>24&255,i[1]=t>>>16&255,i[2]=t>>>8&255,i[3]=255&t,i.set(e,4);let s=8;for(let e=0;e<r;e++)i.set(o[e],s),s+=o[e].byteLength;return i}static generateInitSegment(e){let t=ot.box(ot.types.ftyp,ot.constants.FTYP),i=ot.moov(e),o=new Uint8Array(t.byteLength+i.byteLength);return o.set(t,0),o.set(i,t.byteLength),o}static moov(e){let t=ot.mvhd(e.timescale,e.duration),i=ot.trak(e),o=ot.mvex(e);return ot.box(ot.types.moov,t,i,o)}static mvhd(e,t){return ot.box(ot.types.mvhd,new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0,e>>>24&255,e>>>16&255,e>>>8&255,255&e,t>>>24&255,t>>>16&255,t>>>8&255,255&t,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255]))}static trak(e){return ot.box(ot.types.trak,ot.tkhd(e),ot.mdia(e))}static tkhd(e){let t=e.id,i=e.duration,o=e.presentWidth,r=e.presentHeight;return ot.box(ot.types.tkhd,new Uint8Array([0,0,0,7,0,0,0,0,0,0,0,0,t>>>24&255,t>>>16&255,t>>>8&255,255&t,0,0,0,0,i>>>24&255,i>>>16&255,i>>>8&255,255&i,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,o>>>8&255,255&o,0,0,r>>>8&255,255&r,0,0]))}static mdia(e){return ot.box(ot.types.mdia,ot.mdhd(e),ot.hdlr(e),ot.minf(e))}static mdhd(e){let t=e.timescale,i=e.duration;return ot.box(ot.types.mdhd,new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0,t>>>24&255,t>>>16&255,t>>>8&255,255&t,i>>>24&255,i>>>16&255,i>>>8&255,255&i,85,196,0,0]))}static hdlr(e){let t=null;return t="audio"===e.type?ot.constants.HDLR_AUDIO:ot.constants.HDLR_VIDEO,ot.box(ot.types.hdlr,t)}static minf(e){let t=null;return t="audio"===e.type?ot.box(ot.types.smhd,ot.constants.SMHD):ot.box(ot.types.vmhd,ot.constants.VMHD),ot.box(ot.types.minf,t,ot.dinf(),ot.stbl(e))}static dinf(){return ot.box(ot.types.dinf,ot.box(ot.types.dref,ot.constants.DREF))}static stbl(e){return ot.box(ot.types.stbl,ot.stsd(e),ot.box(ot.types.stts,ot.constants.STTS),ot.box(ot.types.stsc,ot.constants.STSC),ot.box(ot.types.stsz,ot.constants.STSZ),ot.box(ot.types.stco,ot.constants.STCO))}static stsd(e){return"audio"===e.type?ot.box(ot.types.stsd,ot.constants.STSD_PREFIX,ot.mp4a(e)):"avc"===e.videoType?ot.box(ot.types.stsd,ot.constants.STSD_PREFIX,ot.avc1(e)):ot.box(ot.types.stsd,ot.constants.STSD_PREFIX,ot.hvc1(e))}static mp4a(e){let t=e.channelCount,i=e.audioSampleRate,o=new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,t,0,16,0,0,0,0,i>>>8&255,255&i,0,0]);return ot.box(ot.types.mp4a,o,ot.esds(e))}static esds(e){let t=e.config||[],i=t.length,o=new Uint8Array([0,0,0,0,3,23+i,0,1,0,4,15+i,64,21,0,0,0,0,0,0,0,0,0,0,0,5].concat([i]).concat(t).concat([6,1,2]));return ot.box(ot.types.esds,o)}static avc1(e){let t=e.avcc;const i=e.codecWidth,o=e.codecHeight;let r=new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,i>>>8&255,255&i,o>>>8&255,255&o,0,72,0,0,0,72,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,255,255]);return ot.box(ot.types.avc1,r,ot.box(ot.types.avcC,t))}static hvc1(e){let t=e.avcc;const i=e.codecWidth,o=e.codecHeight;let r=new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,i>>>8&255,255&i,o>>>8&255,255&o,0,72,0,0,0,72,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,255,255]);return ot.box(ot.types.hvc1,r,ot.box(ot.types.hvcC,t))}static mvex(e){return ot.box(ot.types.mvex,ot.trex(e))}static trex(e){let t=e.id,i=new Uint8Array([0,0,0,0,t>>>24&255,t>>>16&255,t>>>8&255,255&t,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1]);return ot.box(ot.types.trex,i)}static moof(e,t){return ot.box(ot.types.moof,ot.mfhd(e.sequenceNumber),ot.traf(e,t))}static mfhd(e){let t=new Uint8Array([0,0,0,0,e>>>24&255,e>>>16&255,e>>>8&255,255&e]);return ot.box(ot.types.mfhd,t)}static traf(e,t){let i=e.id,o=ot.box(ot.types.tfhd,new Uint8Array([0,0,0,0,i>>>24&255,i>>>16&255,i>>>8&255,255&i])),r=ot.box(ot.types.tfdt,new Uint8Array([0,0,0,0,t>>>24&255,t>>>16&255,t>>>8&255,255&t])),s=ot.sdtp(e),a=ot.trun(e,s.byteLength+16+16+8+16+8+8);return ot.box(ot.types.traf,o,r,a,s)}static sdtp(e){let t=new Uint8Array(5),i=e.flags;return t[4]=i.isLeading<<6|i.dependsOn<<4|i.isDependedOn<<2|i.hasRedundancy,ot.box(ot.types.sdtp,t)}static trun(e,t){let i=new Uint8Array(28);t+=36,i.set([0,0,15,1,0,0,0,1,t>>>24&255,t>>>16&255,t>>>8&255,255&t],0);let o=e.duration,r=e.size,s=e.flags,a=e.cts;return i.set([o>>>24&255,o>>>16&255,o>>>8&255,255&o,r>>>24&255,r>>>16&255,r>>>8&255,255&r,s.isLeading<<2|s.dependsOn,s.isDependedOn<<6|s.hasRedundancy<<4|s.isNonSync,0,0,a>>>24&255,a>>>16&255,a>>>8&255,255&a],12),ot.box(ot.types.trun,i)}static mdat(e){return ot.box(ot.types.mdat,e)}}ot.init();class rt extends Be{constructor(e){super(),this.player=e,this.isAvc=!0,this.mediaSource=new window.MediaSource,this.sourceBuffer=null,this.hasInit=!1,this.isInitInfo=!1,this.cacheTrack={},this.timeInit=!1,this.sequenceNumber=0,this.mediaSourceOpen=!1,this.dropping=!1,this.firstRenderTime=null,this.mediaSourceAppendBufferError=!1,this.mediaSourceAppendBufferFull=!1,this.isDecodeFirstIIframe=!1,this.player.video.$videoElement.src=window.URL.createObjectURL(this.mediaSource);const{debug:t,events:{proxy:i}}=e;i(this.mediaSource,"sourceopen",(()=>{this.mediaSourceOpen=!0,this.player.emit(x.mseSourceOpen)})),i(this.mediaSource,"sourceclose",(()=>{this.player.emit(x.mseSourceClose)})),e.debug.log("MediaSource","init")}destroy(){this.stop(),this.mediaSource=null,this.mediaSourceOpen=!1,this.sourceBuffer=null,this.hasInit=!1,this.isInitInfo=!1,this.sequenceNumber=0,this.cacheTrack=null,this.timeInit=!1,this.mediaSourceAppendBufferError=!1,this.mediaSourceAppendBufferFull=!1,this.isDecodeFirstIIframe=!1,this.off(),this.player.debug.log("MediaSource","destroy")}get state(){return this.mediaSource&&this.mediaSource.readyState}get isStateOpen(){return this.state===_}get isStateClosed(){return this.state===$}get isStateEnded(){return this.state===K}get duration(){return this.mediaSource&&this.mediaSource.duration}set duration(e){this.mediaSource.duration=e}decodeVideo(e,t,i,o){const r=this.player;if(r)if(this.hasInit){if(i&&0===e[1]){let t=Ze(e.slice(5));const i=this.player.video.videoInfo;i&&i.width&&i.height&&t&&t.codecWidth&&t.codecHeight&&(t.codecWidth!==i.width||t.codecHeight!==i.height)&&(this.player.debug.warn("MediaSource",`width or height is update, width ${i.width}-> ${t.codecWidth}, height ${i.height}-> ${t.codecHeight}`),this.isInitInfo=!1,this.player.video.init=!1)}if(!this.isDecodeFirstIIframe&&i&&(this.isDecodeFirstIIframe=!0),this.isDecodeFirstIIframe){null===this.firstRenderTime&&(this.firstRenderTime=t);const r=t-this.firstRenderTime;this._decodeVideo(e,r,i,o)}else this.player.debug.warn("MediaSource","decodeVideo isDecodeFirstIIframe false")}else if(i&&0===e[1]){const o=15&e[0];if(r.video.updateVideoInfo({encTypeCode:o}),o===Q)return void this.emit(j.mediaSourceH265NotSupport);r._times.decodeStart||(r._times.decodeStart=he()),this._decodeConfigurationRecord(e,t,i,o),this.hasInit=!0}}_decodeConfigurationRecord(e,t,i,o){let r=e.slice(5),s={};s=Ze(r);const a={id:1,type:"video",timescale:1e3,duration:0,avcc:r,codecWidth:s.codecWidth,codecHeight:s.codecHeight,videoType:s.videoType},n=ot.generateInitSegment(a);this.isAvc=!0,this.appendBuffer(n.buffer),this.sequenceNumber=0,this.cacheTrack=null,this.timeInit=!1}_decodeVideo(e,t,i,o){const r=this.player;let s=e.slice(5),a=s.byteLength;const n=r.video.$videoElement,A=r._opt.videoBufferDelay;if(n.buffered.length>1&&(this.removeBuffer(n.buffered.start(0),n.buffered.end(0)),this.timeInit=!1),this.dropping&&t-this.cacheTrack.dts>A)this.dropping=!1,this.cacheTrack={};else if(this.cacheTrack&&t>=this.cacheTrack.dts){let e=8+this.cacheTrack.size,i=new Uint8Array(e);i[0]=e>>>24&255,i[1]=e>>>16&255,i[2]=e>>>8&255,i[3]=255&e,i.set(ot.types.mdat,4),i.set(this.cacheTrack.data,8),this.cacheTrack.duration=t-this.cacheTrack.dts;let o=ot.moof(this.cacheTrack,this.cacheTrack.dts),s=new Uint8Array(o.byteLength+i.byteLength);s.set(o,0),s.set(i,o.byteLength),this.appendBuffer(s.buffer),r.handleRender(),r.updateStats({fps:!0,ts:t,buf:r.demux&&r.demux.delay||0}),r._times.videoStart||(r._times.videoStart=he(),r.handlePlayToRenderTimes())}else r.debug.log("MediaSource","timeInit set false , cacheTrack = {}"),this.timeInit=!1,this.cacheTrack={};this.cacheTrack||(this.cacheTrack={}),this.cacheTrack.id=1,this.cacheTrack.sequenceNumber=++this.sequenceNumber,this.cacheTrack.size=a,this.cacheTrack.dts=t,this.cacheTrack.cts=o,this.cacheTrack.isKeyframe=i,this.cacheTrack.data=s,this.cacheTrack.flags={isLeading:0,dependsOn:i?2:1,isDependedOn:i?1:0,hasRedundancy:0,isNonSync:i?0:1},this.timeInit||1!==n.buffered.length||(r.debug.log("MediaSource","timeInit set true"),this.timeInit=!0,n.currentTime=n.buffered.end(0)),!this.isInitInfo&&n.videoWidth>0&&n.videoHeight>0&&(r.debug.log("MediaSource",`updateVideoInfo: ${n.videoWidth},${n.videoHeight}`),r.video.updateVideoInfo({width:n.videoWidth,height:n.videoHeight}),r.video.initCanvasViewSize(),this.isInitInfo=!0)}appendBuffer(e){const{debug:t,events:{proxy:i}}=this.player;if(null===this.sourceBuffer&&(this.sourceBuffer=this.mediaSource.addSourceBuffer(Z),i(this.sourceBuffer,"error",(e=>{this.player.emit(x.mseSourceBufferError,e)}))),this.mediaSourceAppendBufferError)t.error("MediaSource","this.mediaSourceAppendBufferError is true");else if(this.mediaSourceAppendBufferFull)t.error("MediaSource","this.mediaSourceAppendBufferFull is true");else if(!1===this.sourceBuffer.updating&&this.isStateOpen)try{this.sourceBuffer.appendBuffer(e)}catch(e){t.warn("MediaSource","this.sourceBuffer.appendBuffer()",e.code,e),22===e.code?(this.stop(),this.mediaSourceAppendBufferFull=!0,this.emit(j.mediaSourceFull)):11===e.code?(this.stop(),this.mediaSourceAppendBufferError=!0,this.emit(j.mediaSourceAppendBufferError)):(t.error("MediaSource","appendBuffer error",e),this.player.emit(x.mseSourceBufferError,e))}else this.isStateClosed?this.player.emit(j.mseSourceBufferError,"mediaSource is not attached to video or mediaSource is closed"):this.isStateEnded?this.player.emit(j.mseSourceBufferError,"mediaSource is closed"):!0===this.sourceBuffer.updating&&this.player.emit(x.mseSourceBufferBusy)}stop(){this.abortSourceBuffer(),this.removeSourceBuffer(),this.endOfStream()}dropSourceBuffer(e){const t=this.player.video.$videoElement;this.dropping=e,t.buffered.length>0&&t.buffered.end(0)-t.currentTime>1&&(this.player.debug.warn("MediaSource","dropSourceBuffer",`$video.buffered.end(0) is ${t.buffered.end(0)} - $video.currentTime ${t.currentTime}`),t.currentTime=t.buffered.end(0))}removeBuffer(e,t){if(this.isStateOpen&&!1===this.sourceBuffer.updating)try{this.sourceBuffer.remove(e,t)}catch(e){this.player.debug.warn("MediaSource","removeBuffer() error",e)}else this.player.debug.warn("MediaSource","removeBuffer() this.isStateOpen is",this.isStateOpen,"this.sourceBuffer.updating",this.sourceBuffer.updating)}endOfStream(){const e=this.player.video&&this.player.video.$videoElement;if(this.isStateOpen&&e&&e.readyState>=1)try{this.mediaSource.endOfStream()}catch(e){this.player.debug.warn("MediaSource","endOfStream() error",e)}}abortSourceBuffer(){this.isStateOpen&&this.sourceBuffer&&(this.sourceBuffer.abort(),this.sourceBuffer=null)}removeSourceBuffer(){if(!this.isStateClosed&&this.mediaSource&&this.sourceBuffer)try{this.mediaSource.removeSourceBuffer(this.sourceBuffer)}catch(e){this.player.debug.warn("MediaSource","removeSourceBuffer() error",e)}}}const st=()=>"undefined"!=typeof navigator&&parseFloat((""+(/CPU.*OS ([0-9_]{3,4})[0-9_]{0,1}|(CPU like).*AppleWebKit.*Mobile/i.exec(navigator.userAgent)||[0,""])[1]).replace("undefined","3_2").replace("_",".").replace("_",""))<10&&!window.MSStream,at=()=>"wakeLock"in navigator;class nt{constructor(e){if(this.player=e,this.enabled=!1,at()){this._wakeLock=null;const e=()=>{null!==this._wakeLock&&"visible"===document.visibilityState&&this.enable()};document.addEventListener("visibilitychange",e),document.addEventListener("fullscreenchange",e)}else st()?this.noSleepTimer=null:(this.noSleepVideo=document.createElement("video"),this.noSleepVideo.setAttribute("title","No Sleep"),this.noSleepVideo.setAttribute("playsinline",""),this._addSourceToVideo(this.noSleepVideo,"webm","data:video/webm;base64,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"),this._addSourceToVideo(this.noSleepVideo,"mp4","data:video/mp4;base64,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"),this.noSleepVideo.addEventListener("loadedmetadata",(()=>{this.noSleepVideo.duration<=1?this.noSleepVideo.setAttribute("loop",""):this.noSleepVideo.addEventListener("timeupdate",(()=>{this.noSleepVideo.currentTime>.5&&(this.noSleepVideo.currentTime=Math.random())}))})))}_addSourceToVideo(e,t,i){var o=document.createElement("source");o.src=i,o.type=`video/${t}`,e.appendChild(o)}get isEnabled(){return this.enabled}enable(){const e=this.player.debug;if(at())return navigator.wakeLock.request("screen").then((t=>{this._wakeLock=t,this.enabled=!0,e.log("wakeLock","Wake Lock active."),this._wakeLock.addEventListener("release",(()=>{e.log("wakeLock","Wake Lock released.")}))})).catch((t=>{throw this.enabled=!1,e.error("wakeLock",`${t.name}, ${t.message}`),t}));if(st())return this.disable(),this.noSleepTimer=window.setInterval((()=>{document.hidden||(window.location.href=window.location.href.split("#")[0],window.setTimeout(window.stop,0))}),15e3),this.enabled=!0,Promise.resolve();return this.noSleepVideo.play().then((e=>(this.enabled=!0,e))).catch((e=>{throw this.enabled=!1,e}))}disable(){const e=this.player.debug;at()?(this._wakeLock&&this._wakeLock.release(),this._wakeLock=null):st()?this.noSleepTimer&&(e.warn("wakeLock","NoSleep now disabled for older iOS devices."),window.clearInterval(this.noSleepTimer),this.noSleepTimer=null):this.noSleepVideo.pause(),this.enabled=!1}}class At extends Be{constructor(e,t){var i;super(),this.$container=e,this._opt=Object.assign({},l,t),this.debug=new Ae(this),this._opt.useWCS&&(this._opt.useWCS="VideoEncoder"in window),this._opt.useMSE&&(this._opt.useMSE=window.MediaSource&&window.MediaSource.isTypeSupported(Z)),this._opt.wcsUseVideoRender&&(this._opt.wcsUseVideoRender=window.MediaStreamTrackGenerator&&"function"==typeof window.MediaStreamTrackGenerator),this._opt.useMSE&&(this._opt.useWCS&&this.debug.log("Player","useWCS set true->false"),this._opt.forceNoOffscreen||this.debug.log("Player","forceNoOffscreen set false->true"),this._opt.useWCS=!1,this._opt.forceNoOffscreen=!0),this._opt.forceNoOffscreen||("undefined"==typeof OffscreenCanvas?(this._opt.forceNoOffscreen=!0,this._opt.useOffscreen=!1):this._opt.useOffscreen=!0),this._opt.hasAudio||(this._opt.operateBtns.audio=!1),this._opt.hasControl=this._hasControl(),this._loading=!1,this._playing=!1,this._hasLoaded=!1,this._checkHeartTimeout=null,this._checkLoadingTimeout=null,this._checkStatsInterval=null,this._startBpsTime=null,this._isPlayingBeforePageHidden=!1,this._stats={buf:0,fps:0,abps:0,vbps:0,ts:0},this._times={playInitStart:"",playStart:"",streamStart:"",streamResponse:"",demuxStart:"",decodeStart:"",videoStart:"",playTimestamp:"",streamTimestamp:"",streamResponseTimestamp:"",demuxTimestamp:"",decodeTimestamp:"",videoTimestamp:"",allTimestamp:""},this._videoTimestamp=0,this._audioTimestamp=0,i=this,Object.defineProperty(i,"rect",{get:()=>{const e=i.$container.getBoundingClientRect();return e.width=Math.max(e.width,i.$container.clientWidth),e.height=Math.max(e.height,i.$container.clientHeight),e}}),["bottom","height","left","right","top","width"].forEach((e=>{Object.defineProperty(i,e,{get:()=>i.rect[e]})})),this.events=new de(this),this.video=new Fe(this),this._opt.hasAudio&&(this.audio=new Ve(this)),this.recorder=new Pe(this),this._onlyMseOrWcsVideo()?this.loaded=!0:this.decoderWorker=new Ge(this),this.stream=null,this.demux=null,this._lastVolume=null,this._opt.useWCS&&(this.webcodecsDecoder=new Ke(this),this.loaded=!0),this._opt.useMSE&&(this.mseDecoder=new rt(this),this.loaded=!0),this.control=new it(this),ye()&&(this.keepScreenOn=new nt(this)),(e=>{try{const t=t=>{Ee(t)===e.$container&&(e.emit(D.fullscreen,e.fullscreen),e.fullscreen?e._opt.useMSE&&e.resize():e.resize())};ce.on("change",t),e.events.destroys.push((()=>{ce.off("change",t)}))}catch(e){}if(e.on(x.decoderWorkerInit,(()=>{e.debug.log("player","has loaded"),e.loaded=!0})),e.on(x.play,(()=>{e.loading=!1})),e.on(x.fullscreen,(t=>{if(t)try{ce.request(e.$container).then((()=>{})).catch((t=>{ye()&&e._opt.useWebFullScreen&&(e.webFullscreen=!0)}))}catch(t){ye()&&e._opt.useWebFullScreen&&(e.webFullscreen=!0)}else try{ce.exit().then((()=>{e.webFullscreen&&(e.webFullscreen=!1)})).catch((()=>{e.webFullscreen=!1}))}catch(t){e.webFullscreen=!1}})),ye()&&e.on(x.webFullscreen,(t=>{t?e.$container.classList.add("jessibuca-fullscreen-web"):e.$container.classList.remove("jessibuca-fullscreen-web"),e.emit(D.fullscreen,e.fullscreen)})),e.on(x.resize,(()=>{e.video&&e.video.resize()})),e._opt.debug){const t=[x.timeUpdate];Object.keys(x).forEach((i=>{e.on(x[i],(o=>{t.includes(i)||e.debug.log("player events",x[i],o)}))})),Object.keys(j).forEach((t=>{e.on(j[t],(i=>{e.debug.log("player event error",j[t],i)}))}))}})(this),(e=>{const{_opt:t,debug:i,events:{proxy:o}}=e;t.supportDblclickFullscreen&&o(e.$container,"dblclick",(t=>{const i=Ee(t).nodeName.toLowerCase();"canvas"!==i&&"video"!==i||(e.fullscreen=!e.fullscreen)})),o(document,"visibilitychange",(()=>{t.hiddenAutoPause&&(i.log("visibilitychange",document.visibilityState,e._isPlayingBeforePageHidden),"visible"===document.visibilityState?e._isPlayingBeforePageHidden&&e.play():(e._isPlayingBeforePageHidden=e.playing,e.playing&&e.pause()))})),o(window,"fullscreenchange",(()=>{null!==e.keepScreenOn&&"visible"===document.visibilityState&&e.enableWakeLock()}))})(this),this._opt.useWCS&&this.debug.log("Player","use WCS"),this._opt.useMSE&&this.debug.log("Player","use MSE"),this._opt.useOffscreen&&this.debug.log("Player","use offscreen"),this.debug.log("Player options",this._opt)}destroy(){this._loading=!1,this._playing=!1,this._hasLoaded=!1,this._lastVolume=null,this._times={playInitStart:"",playStart:"",streamStart:"",streamResponse:"",demuxStart:"",decodeStart:"",videoStart:"",playTimestamp:"",streamTimestamp:"",streamResponseTimestamp:"",demuxTimestamp:"",decodeTimestamp:"",videoTimestamp:"",allTimestamp:""},this.decoderWorker&&(this.decoderWorker.destroy(),this.decoderWorker=null),this.video&&(this.video.destroy(),this.video=null),this.audio&&(this.audio.destroy(),this.audio=null),this.stream&&(this.stream.destroy(),this.stream=null),this.recorder&&(this.recorder.destroy(),this.recorder=null),this.control&&(this.control.destroy(),this.control=null),this.webcodecsDecoder&&(this.webcodecsDecoder.destroy(),this.webcodecsDecoder=null),this.mseDecoder&&(this.mseDecoder.destroy(),this.mseDecoder=null),this.demux&&(this.demux.destroy(),this.demux=null),this.events&&(this.events.destroy(),this.events=null),this.clearCheckHeartTimeout(),this.clearCheckLoadingTimeout(),this.clearStatsInterval(),this.releaseWakeLock(),this.keepScreenOn=null,this.resetStats(),this._audioTimestamp=0,this._videoTimestamp=0,this.emit("destroy"),this.off(),this.debug.log("play","destroy end")}set fullscreen(e){ye()&&this._opt.useWebFullScreen?(this.emit(x.webFullscreen,e),setTimeout((()=>{this.updateOption({rotate:e?270:0}),this.resize()}),10)):this.emit(x.fullscreen,e)}get fullscreen(){return ce.isFullscreen||this.webFullscreen}set webFullscreen(e){this.emit(x.webFullscreen,e)}get webFullscreen(){return this.$container.classList.contains("jessibuca-fullscreen-web")}set loaded(e){this._hasLoaded=e}get loaded(){return this._hasLoaded}set playing(e){e&&(this.loading=!1),this.playing!==e&&(this._playing=e,this.emit(x.playing,e),this.emit(x.volumechange,this.volume),e?this.emit(x.play):this.emit(x.pause))}get playing(){return this._playing}get volume(){return this.audio&&this.audio.volume||0}set volume(e){e!==this.volume&&(this.audio&&this.audio.setVolume(e),this._lastVolume=e)}get lastVolume(){return this._lastVolume}set loading(e){this.loading!==e&&(this._loading=e,this.emit(x.loading,this._loading))}get loading(){return this._loading}set recording(e){e?this.playing&&this.recorder&&this.recorder.startRecord():this.recorder&&this.recorder.stopRecordAndSave()}get recording(){return!!this.recorder&&this.recorder.recording}set audioTimestamp(e){null!==e&&(this._audioTimestamp=e)}get audioTimestamp(){return this._audioTimestamp}set videoTimestamp(e){null!==e&&(this._videoTimestamp=e,this._opt.useWCS||this._opt.useMSE||this.audioTimestamp&&this.videoTimestamp&&this.audio&&this.audio.emit(x.videoSyncAudio,{audioTimestamp:this.audioTimestamp,videoTimestamp:this.videoTimestamp,diff:this.audioTimestamp-this.videoTimestamp}))}get videoTimestamp(){return this._videoTimestamp}get isDebug(){return!0===this._opt.debug}updateOption(e){this._opt=Object.assign({},this._opt,e)}init(){return new Promise(((e,t)=>{this.stream||(this.stream=new Qe(this)),this.audio||this._opt.hasAudio&&(this.audio=new Ve(this)),this.demux||(this.demux=new Ye(this)),this._opt.useWCS&&(this.webcodecsDecoder||(this.webcodecsDecoder=new Ke(this))),this._opt.useMSE&&(this.mseDecoder||(this.mseDecoder=new rt(this))),this.decoderWorker||this._onlyMseOrWcsVideo()?e():(this.decoderWorker=new Ge(this),this.once(x.decoderWorkerInit,(()=>{e()})))}))}play(e,t){return new Promise(((i,o)=>{if(!e&&!this._opt.url)return o();this.loading=!0,this.playing=!1,this._times.playInitStart=he(),e||(e=this._opt.url),this._opt.url=e,this.clearCheckHeartTimeout(),this.init().then((()=>{this._times.playStart=he(),this._opt.isNotMute&&this.mute(!1),this.webcodecsDecoder&&this.webcodecsDecoder.once(j.webcodecsH265NotSupport,(()=>{this.emit(j.webcodecsH265NotSupport),this._opt.autoWasm||this.emit(x.error,j.webcodecsH265NotSupport)})),this.mseDecoder&&(this.mseDecoder.once(j.mediaSourceH265NotSupport,(()=>{this.emit(j.mediaSourceH265NotSupport),this._opt.autoWasm||this.emit(x.error,j.mediaSourceH265NotSupport)})),this.mseDecoder.once(j.mediaSourceFull,(()=>{this.emit(j.mediaSourceFull)})),this.mseDecoder.once(j.mediaSourceAppendBufferError,(()=>{this.emit(j.mediaSourceAppendBufferError)})),this.mseDecoder.once(j.mediaSourceBufferListLarge,(()=>{this.emit(j.mediaSourceBufferListLarge)})),this.mseDecoder.once(j.mediaSourceAppendBufferEndTimeout,(()=>{this.emit(j.mediaSourceAppendBufferEndTimeout)}))),this.enableWakeLock(),this.stream.fetchStream(e,t),this.checkLoadingTimeout(),this.stream.once(j.fetchError,(e=>{o(e)})),this.stream.once(j.websocketError,(e=>{o(e)})),this.stream.once(x.streamEnd,(()=>{o()})),this.stream.once(j.hlsError,(e=>{o(e)})),this.stream.once(x.streamSuccess,(()=>{i(),this._times.streamResponse=he(),this.video.play(),this.checkStatsInterval()}))})).catch((e=>{o(e)}))}))}close(){return new Promise(((e,t)=>{this._close().then((()=>{this.video&&this.video.clearView(),e()}))}))}resumeAudioAfterPause(){this.lastVolume&&(this.volume=this.lastVolume)}_close(){return new Promise(((e,t)=>{this.stream&&(this.stream.destroy(),this.stream=null),this.demux&&(this.demux.destroy(),this.demux=null),this.decoderWorker&&(this.decoderWorker.destroy(),this.decoderWorker=null),this.webcodecsDecoder&&(this.webcodecsDecoder.destroy(),this.webcodecsDecoder=null),this.mseDecoder&&(this.mseDecoder.destroy(),this.mseDecoder=null),this.audio&&(this.audio.destroy(),this.audio=null),this.clearCheckHeartTimeout(),this.clearCheckLoadingTimeout(),this.clearStatsInterval(),this.playing=!1,this.loading=!1,this.recording=!1,this.video&&(this.video.resetInit(),this.video.pause(!0)),this.releaseWakeLock(),this.resetStats(),this._audioTimestamp=0,this._videoTimestamp=0,this._times={playInitStart:"",playStart:"",streamStart:"",streamResponse:"",demuxStart:"",decodeStart:"",videoStart:"",playTimestamp:"",streamTimestamp:"",streamResponseTimestamp:"",demuxTimestamp:"",decodeTimestamp:"",videoTimestamp:"",allTimestamp:""},setTimeout((()=>{e()}),0)}))}pause(){return arguments.length>0&&void 0!==arguments[0]&&arguments[0]?this.close():this._close()}mute(e){this.audio&&this.audio.mute(e)}resize(){this.video.resize()}startRecord(e,t){this.recording||(this.recorder.setFileName(e,t),this.recording=!0)}stopRecordAndSave(){this.recording&&(this.recording=!1)}_hasControl(){let e=!1,t=!1;return Object.keys(this._opt.operateBtns).forEach((e=>{this._opt.operateBtns[e]&&(t=!0)})),(this._opt.showBandwidth||this._opt.text||t)&&(e=!0),e}_onlyMseOrWcsVideo(){return!1===this._opt.hasAudio&&(this._opt.useMSE||this._opt.useWCS&&!this._opt.useOffscreen)}checkHeart(){this.clearCheckHeartTimeout(),this.checkHeartTimeout()}checkHeartTimeout(){this._checkHeartTimeout=setTimeout((()=>{if(this.playing){if(0!==this._stats.fps)return;this.pause().then((()=>{this.emit(x.timeout,x.delayTimeout),this.emit(x.delayTimeout)}))}}),1e3*this._opt.heartTimeout)}checkStatsInterval(){this._checkStatsInterval=setInterval((()=>{this.updateStats()}),1e3)}clearCheckHeartTimeout(){this._checkHeartTimeout&&(clearTimeout(this._checkHeartTimeout),this._checkHeartTimeout=null)}checkLoadingTimeout(){this._checkLoadingTimeout=setTimeout((()=>{this.playing||this.pause().then((()=>{this.emit(x.timeout,x.loadingTimeout),this.emit(x.loadingTimeout)}))}),1e3*this._opt.loadingTimeout)}clearCheckLoadingTimeout(){this._checkLoadingTimeout&&(clearTimeout(this._checkLoadingTimeout),this._checkLoadingTimeout=null)}clearStatsInterval(){this._checkStatsInterval&&(clearInterval(this._checkStatsInterval),this._checkStatsInterval=null)}handleRender(){this.loading&&(this.emit(x.start),this.loading=!1,this.clearCheckLoadingTimeout()),this.playing||(this.playing=!0),this.checkHeart()}updateStats(e){e=e||{},this._startBpsTime||(this._startBpsTime=he()),Se(e.ts)&&(this._stats.ts=e.ts),Se(e.buf)&&(this._stats.buf=e.buf),e.fps&&(this._stats.fps+=1),e.abps&&(this._stats.abps+=e.abps),e.vbps&&(this._stats.vbps+=e.vbps);const t=he();t-this._startBpsTime<1e3||(this.emit(x.stats,this._stats),this.emit(x.performance,function(e){let t=0;return e>=24?t=2:e>=15&&(t=1),t}(this._stats.fps)),this._stats.fps=0,this._stats.abps=0,this._stats.vbps=0,this._startBpsTime=t)}resetStats(){this._startBpsTime=null,this._stats={buf:0,fps:0,abps:0,vbps:0,ts:0}}enableWakeLock(){this._opt.keepScreenOn&&this.keepScreenOn&&this.keepScreenOn.enable()}releaseWakeLock(){this._opt.keepScreenOn&&this.keepScreenOn&&this.keepScreenOn.disable()}handlePlayToRenderTimes(){const e=this._times;e.playTimestamp=e.playStart-e.playInitStart,e.streamTimestamp=e.streamStart-e.playStart,e.streamResponseTimestamp=e.streamResponse-e.streamStart,e.demuxTimestamp=e.demuxStart-e.streamResponse,e.decodeTimestamp=e.decodeStart-e.demuxStart,e.videoTimestamp=e.videoStart-e.decodeStart,e.allTimestamp=e.videoStart-e.playInitStart,this.emit(x.playToRenderTimes,e)}getOption(){return this._opt}}class dt extends Be{constructor(e){super();let t=e,i=e.container;if("string"==typeof e.container&&(i=document.querySelector(e.container)),!i)throw new Error("Jessibuca need container option");if("CANVAS"===i.nodeName||"VIDEO"===i.nodeName)throw new Error(`Jessibuca container type can not be ${i.nodeName} type`);if(t.videoBuffer>=t.heartTimeout)throw new Error(`Jessibuca videoBuffer ${t.videoBuffer}s must be less than heartTimeout ${t.heartTimeout}s`);i.classList.add("jessibuca-container"),delete t.container,t.forceNoOffscreen=!0,ye()&&(t.controlAutoHide=!1),Se(t.videoBuffer)&&(t.videoBuffer=1e3*Number(t.videoBuffer)),Se(t.timeout)&&(we(t.loadingTimeout)&&(t.loadingTimeout=t.timeout),we(t.heartTimeout)&&(t.heartTimeout=t.timeout)),this._opt=t,this.$container=i,this._loadingTimeoutReplayTimes=0,this._heartTimeoutReplayTimes=0,this.events=new de(this),this._initPlayer(i,t)}destroy(){this.events&&(this.events.destroy(),this.events=null),this.player&&(this.player.destroy(),this.player=null),this.$container=null,this._opt=null,this._loadingTimeoutReplayTimes=0,this._heartTimeoutReplayTimes=0,this.off()}_initPlayer(e,t){this.player=new At(e,t),this.player.debug.log("jessibuca","_initPlayer",this.player.getOption()),this._bindEvents()}_resetPlayer(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this.player.destroy(),this.player=null,this._opt=Object.assign(this._opt,e),this._opt.url="",this._initPlayer(this.$container,this._opt)}_bindEvents(){Object.keys(D).forEach((e=>{this.player.on(D[e],(t=>{this.emit(e,t)}))}))}setDebug(e){this.player.updateOption({debug:!!e})}mute(){this.player.mute(!0)}cancelMute(){this.player.mute(!1)}setVolume(e){this.player.volume=e}audioResume(){this.player.audio&&this.player.audio.audioEnabled(!0)}setTimeout(e){e=Number(e),this.player.updateOption({timeout:e,loadingTimeout:e,heartTimeout:e})}setScaleMode(e){let t={isFullResize:!1,isResize:!1};switch(e=Number(e)){case P:t.isFullResize=!1,t.isResize=!1;break;case G:t.isFullResize=!1,t.isResize=!0;break;case N:t.isFullResize=!0,t.isResize=!0}this.player.updateOption(t),this.resize()}pause(){return this.player.pause()}close(){return this._opt.url="",this._opt.playOptions={},this.player.close()}clearView(){this.player.video.clearView()}play(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return new Promise(((i,o)=>{if(!e&&!this._opt.url)return this.emit(x.error,j.playError),void o("play url is empty");e?this._opt.url?e===this._opt.url?this.player.playing?i():(this.clearView(),this.player.play(this._opt.url,this._opt.playOptions).then((()=>{i(),this.player.resumeAudioAfterPause()})).catch((e=>{this.player.debug.warn("jessibuca","pause -> play and play error",e),this.player.pause().then((()=>{o(e)}))}))):this.player.pause().then((()=>{this.clearView(),this._play(e,t).then((()=>{i()})).catch((e=>{this.player.debug.warn("jessibuca","this._play error",e),o(e)}))})).catch((e=>{this.player.debug.warn("jessibuca","this._opt.url is null and pause error",e),o(e)})):this._play(e,t).then((()=>{i()})).catch((e=>{this.player.debug.warn("jessibuca","this._play error",e),o(e)})):this.player.play(this._opt.url,this._opt.playOptions).then((()=>{i(),this.player.resumeAudioAfterPause()})).catch((e=>{this.player.debug.warn("jessibuca","url is null and play error",e),this.player.pause().then((()=>{o(e)}))}))}))}_play(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return new Promise(((i,o)=>{this._opt.url=e,this._opt.playOptions=t;const r=0===e.indexOf("http"),d=r?a:s,c=r||-1!==e.indexOf(".flv")||this._opt.isFlv?n:A;this.player.updateOption({protocol:d,demuxType:c}),this.player.once(j.webglAlignmentError,(()=>{this.pause().then((()=>{this.player.debug.log("Jessibuca","webglAlignmentError"),this._resetPlayer({openWebglAlignment:!0}),this.play(e).then((()=>{this.player.debug.log("Jessibuca","webglAlignmentError and play success")})).catch((()=>{this.player.debug.log("Jessibuca","webglAlignmentError and play error")}))}))})),this.player.once(j.mediaSourceH265NotSupport,(()=>{this.pause().then((()=>{this.player._opt.autoWasm&&(this.player.debug.log("Jessibuca","auto wasm [mse-> wasm] reset player and play"),this._resetPlayer({useMSE:!1}),this.play(e,t).then((()=>{this.player.debug.log("Jessibuca","auto wasm [mse-> wasm] reset player and play success")})).catch((()=>{this.player.debug.log("Jessibuca","auto wasm [mse-> wasm] reset player and play error")})))}))})),this.player.once(j.webcodecsH265NotSupport,(()=>{this.pause().then((()=>{this.player._opt.autoWasm&&(this.player.debug.log("Jessibuca","auto wasm [wcs-> wasm] reset player and play"),this._resetPlayer({useWCS:!1}),this.play(e,t).then((()=>{this.player.debug.log("Jessibuca","auto wasm [wcs-> wasm] reset player and play success")})).catch((()=>{this.player.debug.log("Jessibuca","auto wasm [wcs-> wasm] reset player and play error")})))}))})),this.player.once(j.mediaSourceFull,(()=>{this.pause().then((()=>{this.player.debug.log("Jessibuca","media source full"),this._resetPlayer(),this.play(e).then((()=>{this.player.debug.log("Jessibuca","media source full and reset player and play success")})).catch((()=>{this.player.debug.warn("Jessibuca","media source full and reset player and play error")}))}))})),this.player.once(j.mediaSourceAppendBufferError,(()=>{this.pause().then((()=>{this.player.debug.log("Jessibuca","media source append buffer error"),this._resetPlayer(),this.play(e).then((()=>{this.player.debug.log("Jessibuca","media source append buffer error and reset player and play success")})).catch((()=>{this.player.debug.warn("Jessibuca","media source append buffer error and reset player and play error")}))}))})),this.player.once(j.mediaSourceBufferListLarge,(()=>{this.pause().then((()=>{this.player.debug.log("Jessibuca","media source buffer list large"),this._resetPlayer(),this.play(e).then((()=>{this.player.debug.log("Jessibuca","media source buffer list large and reset player and play success")})).catch((()=>{this.player.debug.warn("Jessibuca","media source buffer list large and reset player and play error")}))}))})),this.player.once(j.mediaSourceAppendBufferEndTimeout,(()=>{this.pause().then((()=>{this.player.debug.log("Jessibuca","media source append buffer end timeout"),this._resetPlayer(),this.play(e).then((()=>{this.player.debug.log("Jessibuca","media source append buffer end timeout and reset player and play success")})).catch((()=>{this.player.debug.warn("Jessibuca","media source append buffer end timeout and reset player and play error")}))}))})),this.player.once(j.mseSourceBufferError,(()=>{this.pause().then((()=>{this.player.debug.log("Jessibuca","mseSourceBufferError close success")}))})),this.player.once(j.webcodecsH265NotSupport,(()=>{this.pause().then((()=>{this.player._opt.autoWasm&&(this.player.debug.log("Jessibuca","auto wasm [wcs-> wasm] reset player and play"),this._resetPlayer({useWCS:!1}),this.play(e).then((()=>{this.player.debug.log("Jessibuca","auto wasm [wcs-> wasm] reset player and play success")})).catch((()=>{this.player.debug.warn("Jessibuca","auto wasm [wcs-> wasm] reset player and play error")})))}))})),this.player.once(j.webcodecsWidthOrHeightChange,(()=>{this.pause().then((()=>{this.player.debug.log("Jessibuca","webcodecs Width Or Height Change reset player and play"),this._resetPlayer({useWCS:!0}),this.play(e).then((()=>{this.player.debug.log("Jessibuca","webcodecs Width Or Height Change reset player and play success")})).catch((()=>{this.player.debug.warn("Jessibuca","webcodecs Width Or Height Change reset player and play error")}))}))})),this.player.once(j.webcodecsDecodeError,(()=>{this.pause().then((()=>{this.player._opt.autoWasm&&(this.player.debug.log("Jessibuca","webcodecs decode error reset player and play"),this._resetPlayer({useWCS:!1}),this.play(e).then((()=>{this.player.debug.log("Jessibuca","webcodecs decode error reset player and play success")})).catch((()=>{this.player.debug.warn("Jessibuca","webcodecs decode error reset player and play error")})))}))})),this.player.once(j.wasmDecodeError,(()=>{this.player._opt.wasmDecodeErrorReplay&&this.pause().then((()=>{this.player.debug.log("Jessibuca","wasm decode error and reset player and play"),this._resetPlayer({useWCS:!1}),this.play(e,t).then((()=>{this.player.debug.log("Jessibuca","wasm decode error and reset player and play success")})).catch((()=>{this.player.debug.warn("Jessibuca","wasm decode error and reset player and play error")}))}))})),this.player.on(x.delayTimeout,(()=>{this.player._opt.heartTimeoutReplay&&(this._heartTimeoutReplayTimes<this.player._opt.heartTimeoutReplayTimes||-1===this.player._opt.heartTimeoutReplayTimes)&&(this.player.debug.log("Jessibuca",`delay timeout replay time is ${this._heartTimeoutReplayTimes}`),this._heartTimeoutReplayTimes+=1,this.play(e,t).then((()=>{this._heartTimeoutReplayTimes=0})).catch((()=>{})))})),this.player.on(x.loadingTimeout,(()=>{this.player._opt.loadingTimeoutReplay&&(this._loadingTimeoutReplayTimes<this.player._opt.loadingTimeoutReplayTimes||-1===this.player._opt.loadingTimeoutReplayTimes)&&(this.player.debug.log("Jessibuca",`loading timeout replay time is ${this._loadingTimeoutReplayTimes}`),this._loadingTimeoutReplayTimes+=1,this.play(e,t).then((()=>{this._loadingTimeoutReplayTimes=0})).catch((()=>{})))})),this.hasLoaded()?this.player.play(e,t).then((()=>{i()})).catch((e=>{this.player.debug.warn("Jessibuca","hasLoaded and play error",e),this.player.pause().then((()=>{o(e)}))})):this.player.once(x.decoderWorkerInit,(()=>{this.player.play(e,t).then((()=>{i()})).catch((e=>{this.player.debug.warn("Jessibuca","decoderWorkerInit and play error",e),this.player.pause().then((()=>{o(e)}))}))}))}))}resize(){this.player.resize()}setBufferTime(e){e=Number(e),this.player.updateOption({videoBuffer:1e3*e}),this.player.decoderWorker&&this.player.decoderWorker.updateWorkConfig({key:"videoBuffer",value:1e3*e})}setRotate(e){e=parseInt(e,10);this._opt.rotate!==e&&-1!==[0,90,180,270].indexOf(e)&&(this.player.updateOption({rotate:e}),this.resize())}hasLoaded(){return this.player.loaded}setKeepScreenOn(){this.player.updateOption({keepScreenOn:!0})}setFullscreen(e){const t=!!e;this.player.fullscreen!==t&&(this.player.fullscreen=t)}screenshot(e,t,i,o){return this.player.video?this.player.video.screenshot(e,t,i,o):""}startRecord(e,t){return new Promise(((i,o)=>{this.player.playing?(this.player.startRecord(e,t),i()):o()}))}stopRecordAndSave(){this.player.recording&&this.player.stopRecordAndSave()}isPlaying(){return!!this.player&&this.player.playing}isMute(){return!this.player.audio||this.player.audio.isMute}isRecording(){return this.player.recorder.recording}}return r(dt,"ERROR",j),r(dt,"TIMEOUT",{loadingTimeout:x.loadingTimeout,delayTimeout:x.delayTimeout}),window.Jessibuca=dt,dt})); |