Commit b4048fbe80dba8e7756ae557a15ab60b4f80a44b

Authored by 648540858
2 parents 786c76ba 053cd130

合并开源主线

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 99 - [X] 支持接口鉴权
100 100 - [X] 云端录像,推流/代理/国标视频均可以录制在云端服务器,支持预览和下载
101 101 - [X] 支持打包可执行jar和war
  102 +- [X] 支持跨域请求,支持前后端分离部署
102 103  
103 104  
104 105 # 遇到问题如何解决
105 106 国标最麻烦的地方在于设备的兼容性,所以需要大量的设备来测试,目前作者手里的设备有限,再加上作者水平有限,所以遇到问题在所难免;
106   -1. 查看wiki,仔细的阅读可以帮你避免几乎所有的问题
  107 +1. 查看文档网站,仔细的阅读可以帮你避免几乎所有的问题
107 108 2. 搜索issues,这里有大部分的答案
108 109 3. 加QQ群(901799015),这里有大量热心的小伙伴,但是前提新希望你已经仔细阅读了wiki和搜索了issues。
109 110 4. 你可以请作者为你解答,但是我不是免费的。
110   -5. 你可以把遇到问题的设备寄给我,可以更容易的复现问题。
  111 +5. 你可以把遇到问题的设备寄给我,可以更容易的兼容设备和解决问题。
111 112  
112 113 # 使用帮助
113 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 14 PS: 目前的底图仅用用作演示和学习,商用情况请自行购买授权使用。
15 15  
16 16 ### 更换底图以及底图配置
17   -目前WVP支持使用了更换底图,配置文件在web_src/static/js/mapConfig.js,请修改后重新编译前端文件。
  17 +目前WVP支持使用了更换底图,配置文件在web_src/static/js/config.js,请修改后重新编译前端文件。
18 18 ```javascript
19 19 window.mapParam = {
20 20 // 开启/关闭地图功能
... ...
doc/_content/introduction/deployment.md
... ... @@ -27,13 +27,32 @@
27 27 ```shell
28 28 nohup java -jar wvp-pro-*.jar &
29 29 ```
30   -war包:
  30 +**war包:**
31 31 下载Tomcat后将war包放入webapps中,启动Tomcat以解压war包,停止Tomcat后,删除ROOT目录以及war包,将解压后的war包目录重命名为ROOT,将配置文件中的Server.port配置为与Tomcat端口一致
32 32 然后启动Tomcat。
33 33 **启动ZLM**
34 34 ```shell
35 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 57 [接入设备](./_content/ability/device.md)
39 58  
... ...
... ... @@ -11,7 +11,7 @@
11 11  
12 12 <groupId>com.genersoft</groupId>
13 13 <artifactId>wvp-pro</artifactId>
14   - <version>2.6.7</version>
  14 + <version>2.6.8</version>
15 15 <name>web video platform</name>
16 16 <description>国标28181视频平台</description>
17 17 <packaging>${project.packaging}</packaging>
... ... @@ -123,11 +123,9 @@
123 123 <artifactId>spring-boot-starter-security</artifactId>
124 124 </dependency>
125 125  
126   - <!-- druid数据库连接池 -->
127 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 129 </dependency>
132 130  
133 131 <!-- mysql数据库 -->
... ... @@ -216,8 +214,6 @@
216 214 <version>4.10.0</version>
217 215 </dependency>
218 216  
219   -
220   -
221 217 <!-- okhttp-digest -->
222 218 <dependency>
223 219 <groupId>io.github.rburgst</groupId>
... ... @@ -226,10 +222,17 @@
226 222 </dependency>
227 223  
228 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 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 236 </dependency>
234 237  
235 238 <!--反向代理-->
... ... @@ -289,7 +292,7 @@
289 292 <plugin>
290 293 <groupId>org.springframework.boot</groupId>
291 294 <artifactId>spring-boot-maven-plugin</artifactId>
292   - <version>2.3.5.RELEASE</version>
  295 + <version>2.7.2</version>
293 296 <configuration>
294 297 <includeSystemScope>true</includeSystemScope>
295 298 </configuration>
... ...
sql/2.6.6-2.6.7更新.sql 0 → 100755
  1 +alter table device
  2 + add asMessageChannel int default 0;
  3 +
  4 +alter table parent_platform
  5 + add asMessageChannel int default 0;
  6 +
  7 +alter table device
  8 + add mediaServerId varchar(50) default null;
  9 +
  10 +
  11 +
  12 +
... ...
src/main/resources/db/migration/V2.6.7_20230201__初始化.sql renamed to sql/初始化.sql
... ... @@ -32,6 +32,7 @@ CREATE TABLE `device` (
32 32 `transport` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
33 33 `streamMode` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
34 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 36 `registerTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
36 37 `keepaliveTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
37 38 `ip` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
... ... @@ -47,6 +48,7 @@ CREATE TABLE `device` (
47 48 `mobilePositionSubmissionInterval` int DEFAULT '5',
48 49 `subscribeCycleForAlarm` int DEFAULT NULL,
49 50 `ssrcCheck` int DEFAULT '0',
  51 + `asMessageChannel` int DEFAULT '0',
50 52 `geoCoordSys` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
51 53 `treeType` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
52 54 `custom_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
... ... @@ -329,6 +331,7 @@ CREATE TABLE `parent_platform` (
329 331 `catalogId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
330 332 `ptz` int DEFAULT NULL,
331 333 `rtcp` int DEFAULT NULL,
  334 + `asMessageChannel` int DEFAULT '0',
332 335 `status` bit(1) DEFAULT NULL,
333 336 `startOfflinePush` int DEFAULT '0',
334 337 `administrativeDivision` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
... ...
src/main/java/com/genersoft/iot/vmp/VManageBootstrap.java
1 1 package com.genersoft.iot.vmp;
2 2  
3   -import com.genersoft.iot.vmp.conf.druid.EnableDruidSupport;
4 3 import com.genersoft.iot.vmp.utils.GitUtil;
5 4 import com.genersoft.iot.vmp.utils.SpringBeanFactory;
6 5 import org.slf4j.Logger;
... ... @@ -25,7 +24,6 @@ import java.util.Collections;
25 24 @ServletComponentScan("com.genersoft.iot.vmp.conf")
26 25 @SpringBootApplication
27 26 @EnableScheduling
28   -@EnableDruidSupport
29 27 public class VManageBootstrap extends SpringBootServletInitializer {
30 28  
31 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 3 import io.swagger.v3.oas.annotations.media.Schema;
4 4  
5 5 import java.io.Serializable;
  6 +import java.util.Objects;
6 7  
7 8 @Schema(description = "流信息")
8 9 public class StreamInfo implements Serializable, Cloneable{
... ... @@ -168,7 +169,7 @@ public class StreamInfo implements Serializable, Cloneable{
168 169 }
169 170  
170 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 173 if (port > 0) {
173 174 this.rtmp = new StreamURL("rtmp", host, port, file);
174 175 }
... ... @@ -178,7 +179,7 @@ public class StreamInfo implements Serializable, Cloneable{
178 179 }
179 180  
180 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 183 if (port > 0) {
183 184 this.rtsp = new StreamURL("rtsp", host, port, file);
184 185 }
... ... @@ -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 245 if (port > 0) {
242 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 66 logDto.setUri(servletRequest.getRequestURI());
67 67 logDto.setCreateTime(DateUtil.getNow());
68 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 8 import org.springframework.http.HttpStatus;
9 9 import org.springframework.http.ResponseEntity;
10 10 import org.springframework.security.authentication.BadCredentialsException;
  11 +import org.springframework.web.HttpRequestMethodNotSupportedException;
11 12 import org.springframework.web.bind.annotation.ExceptionHandler;
12 13 import org.springframework.web.bind.annotation.ResponseStatus;
13 14 import org.springframework.web.bind.annotation.RestControllerAdvice;
... ... @@ -32,6 +33,28 @@ public class GlobalExceptionHandler {
32 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 60 * 自定义异常处理, 处理controller中返回的错误
... ...
src/main/java/com/genersoft/iot/vmp/conf/GlobalResponseAdvice.java
... ... @@ -10,14 +10,11 @@ import org.springframework.context.annotation.Bean;
10 10 import org.springframework.core.MethodParameter;
11 11 import org.springframework.http.MediaType;
12 12 import org.springframework.http.converter.HttpMessageConverter;
13   -import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
14 13 import org.springframework.http.server.ServerHttpRequest;
15 14 import org.springframework.http.server.ServerHttpResponse;
16 15 import org.springframework.web.bind.annotation.RestControllerAdvice;
17 16 import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
18 17  
19   -import java.util.List;
20   -
21 18 /**
22 19 * 全局统一返回结果
23 20 * @author lin
... ...
src/main/java/com/genersoft/iot/vmp/conf/ProxyServletConfig.java
... ... @@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.conf;
2 2  
3 3 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
4 4 import com.genersoft.iot.vmp.service.IMediaServerService;
  5 +import org.apache.catalina.connector.ClientAbortException;
5 6 import org.apache.http.HttpHost;
6 7 import org.apache.http.HttpRequest;
7 8 import org.apache.http.HttpResponse;
... ... @@ -169,13 +170,14 @@ public class ProxyServletConfig {
169 170 protected String rewriteQueryStringFromRequest(HttpServletRequest servletRequest, String queryString) {
170 171 String queryStr = super.rewriteQueryStringFromRequest(servletRequest, queryString);
171 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 182 return queryStr;
181 183 }
... ... @@ -192,6 +194,12 @@ public class ProxyServletConfig {
192 194 } catch (IOException ioException) {
193 195 if (ioException instanceof ConnectException) {
194 196 logger.error("录像服务 连接失败");
  197 + }else if (ioException instanceof ClientAbortException) {
  198 + /**
  199 + * TODO 使用这个代理库实现代理在遇到代理视频文件时,如果是206结果,会遇到报错蛋市目前功能正常,
  200 + * TODO 暂时去除异常处理。后续使用其他代理框架修改测试
  201 + */
  202 +
195 203 }else {
196 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 4 import org.junit.jupiter.api.Order;
5 5 import org.springframework.boot.context.properties.ConfigurationProperties;
6 6 import org.springframework.stereotype.Component;
7   -import org.springframework.util.ObjectUtils;
8 7  
9 8 @Component
10 9 @ConfigurationProperties(prefix = "sip", ignoreInvalidFields = true)
... ... @@ -13,6 +12,8 @@ public class SipConfig {
13 12  
14 13 private String ip;
15 14  
  15 + private String showIp;
  16 +
16 17 private Integer port;
17 18  
18 19 private String domain;
... ... @@ -96,4 +97,14 @@ public class SipConfig {
96 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 40 List<ParentPlatform> parentPlatforms = storager.queryEnableParentPlatformList(true);
41 41  
42 42 for (ParentPlatform parentPlatform : parentPlatforms) {
  43 +
  44 + ParentPlatformCatch parentPlatformCatchOld = redisCatchStorage.queryPlatformCatchInfo(parentPlatform.getServerGBId());
  45 +
43 46 // 更新缓存
44 47 ParentPlatformCatch parentPlatformCatch = new ParentPlatformCatch();
45 48 parentPlatformCatch.setParentPlatform(parentPlatform);
46 49 parentPlatformCatch.setId(parentPlatform.getServerGBId());
47 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 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 50 private Boolean pushStreamAfterAck = Boolean.FALSE;
51 51  
52 52 private Boolean sipLog = Boolean.FALSE;
  53 + private Boolean sendToPlatformsWhenIdLost = Boolean.FALSE;
  54 +
  55 + private Boolean refuseChannelStatusChannelFormNotify = Boolean.FALSE;
53 56  
54 57 private String serverId = "000000";
55 58  
  59 + private String recordPath = null;
  60 +
56 61 private String thirdPartyGBIdReg = "[\\s\\S]*";
57 62  
58 63 private String broadcastForPlatform = "UDP";
59 64  
60 65 private List<String> interfaceAuthenticationExcludes = new ArrayList<>();
61 66  
  67 + private List<String> allowedOrigins = new ArrayList<>();
  68 +
62 69 public Boolean getSavePositionHistory() {
63 70 return savePositionHistory;
64 71 }
... ... @@ -238,4 +245,36 @@ public class UserSetting {
238 245 public void setSipLog(Boolean sipLog) {
239 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 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 1 package com.genersoft.iot.vmp.conf.security;
2 2  
3 3 import com.alibaba.fastjson2.JSONObject;
  4 +import com.genersoft.iot.vmp.conf.security.dto.JwtUser;
4 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 7 import org.springframework.security.core.AuthenticationException;
  8 +import org.springframework.security.core.context.SecurityContextHolder;
9 9 import org.springframework.security.web.AuthenticationEntryPoint;
10 10 import org.springframework.stereotype.Component;
11 11  
... ... @@ -18,17 +18,15 @@ import java.io.IOException;
18 18 * @author lin
19 19 */
20 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 23 @Override
26 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 30 JSONObject jsonObject = new JSONObject();
33 31 jsonObject.put("code", ErrorCode.ERROR401.getCode());
34 32 jsonObject.put("msg", ErrorCode.ERROR401.getMsg());
... ...
src/main/java/com/genersoft/iot/vmp/conf/security/DefaultUserDetailsServiceImpl.java
1 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 7 import org.slf4j.Logger;
6 8 import org.slf4j.LoggerFactory;
7 9 import org.springframework.beans.factory.annotation.Autowired;
... ... @@ -10,10 +12,7 @@ import org.springframework.security.core.userdetails.UserDetailsService;
10 12 import org.springframework.security.core.userdetails.UsernameNotFoundException;
11 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 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 21  
22 22 @Override
23 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 1 package com.genersoft.iot.vmp.conf.security;
2 2  
3 3 import com.genersoft.iot.vmp.conf.security.dto.LoginUser;
  4 +import com.genersoft.iot.vmp.storager.dao.dto.User;
4 5 import org.springframework.security.authentication.AuthenticationManager;
5 6 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
6 7 import org.springframework.security.core.Authentication;
... ... @@ -9,6 +10,7 @@ import org.springframework.security.core.context.SecurityContextHolder;
9 10 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
10 11  
11 12 import javax.security.sasl.AuthenticationException;
  13 +import java.time.LocalDateTime;
12 14  
13 15 public class SecurityUtils {
14 16  
... ... @@ -25,9 +27,12 @@ public class SecurityUtils {
25 27 public static LoginUser login(String username, String password, AuthenticationManager authenticationManager) throws AuthenticationException {
26 28 //使用security框架自带的验证token生成器 也可以自定义。
27 29 UsernamePasswordAuthenticationToken token =new UsernamePasswordAuthenticationToken(username,password);
  30 + //认证 如果失败,这里会自动异常后返回,所以这里不需要判断返回值是否为空,确定是否登录成功
28 31 Authentication authenticate = authenticationManager.authenticate(token);
29   - SecurityContextHolder.getContext().setAuthentication(authenticate);
30 32 LoginUser user = (LoginUser) authenticate.getPrincipal();
  33 +
  34 + SecurityContextHolder.getContext().setAuthentication(token);
  35 +
31 36 return user;
32 37 }
33 38  
... ... @@ -49,8 +54,13 @@ public class SecurityUtils {
49 54 if(authentication!=null){
50 55 Object principal = authentication.getPrincipal();
51 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 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 15 import org.springframework.security.config.annotation.web.builders.WebSecurity;
16 16 import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
17 17 import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
  18 +import org.springframework.security.config.http.SessionCreationPolicy;
18 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 30 * 配置Spring Security
... ... @@ -56,22 +63,8 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
56 63 */
57 64 @Autowired
58 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 73 @Override
81 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 109  
127 110 @Override
128 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 124 .anyRequest().authenticated()
137   - // 异常处理(权限拒绝、登录失效等)
138   - .and().exceptionHandling()
139   - //匿名用户访问无权限资源时的异常处理
  125 + // 异常处理器
  126 + .and()
  127 + .exceptionHandling()
140 128 .authenticationEntryPoint(anonymousAuthenticationEntryPoint)
141   -// .accessDeniedHandler(accessDeniedHandler)//登录用户没有权限访问资源
142   - // 登入 允许所有用户
143   - .and().formLogin().permitAll()
144   - //登录成功处理逻辑
145   - .successHandler(loginSuccessHandler)
146   - //登录失败处理逻辑
147   - .failureHandler(loginFailureHandler)
148   - // 登出
149 129 .and().logout().logoutUrl("/api/user/logout").permitAll()
150   - //登出成功处理逻辑
151 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 19 */
20 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 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 171 */
172 172 public boolean doAuthenticatePlainTextPassword(Request request, String pass) {
173 173 AuthorizationHeader authHeader = (AuthorizationHeader) request.getHeader(AuthorizationHeader.NAME);
174   - if ( authHeader == null ) {
  174 + if ( authHeader == null || authHeader.getRealm() == null) {
175 175 return false;
176 176 }
177 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 188 @Schema(description = "SIP交互IP(设备访问平台的IP)")
189 189 private String localIp;
190 190  
  191 + @Schema(description = "是否作为消息通道")
  192 + private boolean asMessageChannel;
  193 +
  194 + @Schema(description = "设备注册的事务信息")
  195 + private SipTransactionInfo sipTransactionInfo;
  196 +
  197 +
191 198 public String getDeviceId() {
192 199 return deviceId;
193 200 }
... ... @@ -428,4 +435,20 @@ public class Device {
428 435 public void setKeepaliveIntervalTime(int keepaliveIntervalTime) {
429 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 189 @Schema(description = "树类型 国标规定了两种树的展现方式 行政区划 CivilCode 和业务分组:BusinessGrou")
190 190 private String treeType;
191 191  
  192 + @Schema(description = "是否作为消息通道")
  193 + private boolean asMessageChannel;
  194 +
192 195 public Integer getId() {
193 196 return id;
194 197 }
... ... @@ -428,4 +431,12 @@ public class ParentPlatform {
428 431 public void setTreeType(String treeType) {
429 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 16  
17 17 private ParentPlatform parentPlatform;
18 18  
  19 + private SipTransactionInfo sipTransactionInfo;
  20 +
19 21 public String getId() {
20 22 return id;
21 23 }
... ... @@ -55,4 +57,12 @@ public class ParentPlatformCatch {
55 57 public void setCallId(String callId) {
56 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 1 package com.genersoft.iot.vmp.gb28181.bean;
2 2  
3 3  
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +
4 6 import java.time.Instant;
5 7 import java.util.List;
6 8  
... ... @@ -9,22 +11,29 @@ import java.util.List;
9 11 * @author: swwheihei
10 12 * @date: 2020年5月8日 下午2:05:56
11 13 */
  14 +@Schema(description = "设备录像查询结果信息")
12 15 public class RecordInfo {
13 16  
  17 + @Schema(description = "设备编号")
14 18 private String deviceId;
15 19  
  20 + @Schema(description = "通道编号")
16 21 private String channelId;
17 22  
  23 + @Schema(description = "命令序列号")
18 24 private String sn;
19 25  
  26 + @Schema(description = "设备名称")
20 27 private String name;
21   -
  28 +
  29 + @Schema(description = "列表总数")
22 30 private int sumNum;
23 31  
24 32 private int count;
25 33  
26 34 private Instant lastTime;
27   -
  35 +
  36 + @Schema(description = "")
28 37 private List<RecordItem> recordList;
29 38  
30 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 2  
3 3  
4 4 import com.genersoft.iot.vmp.utils.DateUtil;
  5 +import io.swagger.v3.oas.annotations.media.Schema;
5 6 import org.jetbrains.annotations.NotNull;
6 7  
7   -import java.text.ParseException;
8 8 import java.time.Instant;
9 9 import java.time.temporal.TemporalAccessor;
10 10  
... ... @@ -13,26 +13,37 @@ import java.time.temporal.TemporalAccessor;
13 13 * @author: swwheihei
14 14 * @date: 2020年5月8日 下午2:06:54
15 15 */
  16 +@Schema(description = "设备录像详情")
16 17 public class RecordItem implements Comparable<RecordItem>{
17 18  
  19 + @Schema(description = "设备编号")
18 20 private String deviceId;
19   -
  21 +
  22 + @Schema(description = "名称")
20 23 private String name;
21   -
  24 +
  25 + @Schema(description = "文件路径名 (可选)")
22 26 private String filePath;
23 27  
  28 + @Schema(description = "录像文件大小,单位:Byte(可选)")
24 29 private String fileSize;
25 30  
  31 + @Schema(description = "录像地址(可选)")
26 32 private String address;
27   -
  33 +
  34 + @Schema(description = "录像开始时间(可选)")
28 35 private String startTime;
29   -
  36 +
  37 + @Schema(description = "录像结束时间(可选)")
30 38 private String endTime;
31   -
  39 +
  40 + @Schema(description = "保密属性(必选)缺省为0;0:不涉密,1:涉密")
32 41 private int secrecy;
33   -
  42 +
  43 + @Schema(description = "录像产生类型(可选)time或alarm 或 manua")
34 44 private String type;
35   -
  45 +
  46 + @Schema(description = "录像触发者ID(可选)")
36 47 private String recorderId;
37 48  
38 49 public String getDeviceId() {
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/event/device/RequestTimeoutEventImpl.java
1 1 package com.genersoft.iot.vmp.gb28181.event.device;
2 2  
3 3 import com.genersoft.iot.vmp.gb28181.bean.Device;
4   -import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
5 4 import com.genersoft.iot.vmp.service.IDeviceService;
6 5 import org.springframework.beans.factory.annotation.Autowired;
7 6 import org.springframework.context.ApplicationListener;
... ... @@ -9,8 +8,6 @@ import org.springframework.stereotype.Component;
9 8  
10 9 import javax.sip.ClientTransaction;
11 10 import javax.sip.address.SipURI;
12   -import javax.sip.header.CallIdHeader;
13   -import javax.sip.header.ToHeader;
14 11 import javax.sip.message.Request;
15 12  
16 13 /**
... ... @@ -34,7 +31,7 @@ public class RequestTimeoutEventImpl implements ApplicationListener&lt;RequestTimeo
34 31 if (device == null) {
35 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 61  
62 62 for (Device device : deviceList) {
63 63 if (deviceService.expire(device)){
64   - deviceService.offline(device.getDeviceId());
  64 + deviceService.offline(device.getDeviceId(), "注册已过期");
65 65 }else {
66   - deviceService.online(device);
  66 + deviceService.online(device, null);
67 67 }
68 68 }
69 69 // 重置cseq计数
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java
... ... @@ -120,7 +120,7 @@ public interface ISIPCommander {
120 120 */
121 121 void downloadStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId,
122 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 217 *
218 218 * @param device 视频设备
219 219 * @param channelId 通道id,非通道则是设备本身
220   - * @param frontCmd 上级平台的指令,如果存在则直接下发
221 220 * @param enabled 看守位使能:1 = 开启,0 = 关闭
222 221 * @param resetTime 自动归位时间间隔,开启看守位时使用,单位:秒(s)
223 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 22 * @param parentPlatform
23 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 33 * @param parentPlatform
36 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 46 @Autowired
47 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 50 Request request = null;
51 51 String sipAddress = parentPlatform.getDeviceIp() + ":" + parentPlatform.getDevicePort();
52 52 //请求行
... ... @@ -54,7 +54,8 @@ public class SIPRequestHeaderPlarformProvider {
54 54 parentPlatform.getServerIP() + ":" + parentPlatform.getServerPort());
55 55 //via
56 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 59 viaHeader.setRPort();
59 60 viaHeaders.add(viaHeader);
60 61 //from
... ... @@ -64,7 +65,7 @@ public class SIPRequestHeaderPlarformProvider {
64 65 //to
65 66 SipURI toSipURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(parentPlatform.getDeviceGBId(), sipConfig.getDomain());
66 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 70 //Forwards
70 71 MaxForwardsHeader maxForwards = sipLayer.getSipFactory().createHeaderFactory().createMaxForwardsHeader(70);
... ... @@ -86,15 +87,21 @@ public class SIPRequestHeaderPlarformProvider {
86 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 95 SipURI requestURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(parentPlatform.getServerGBId(), parentPlatform.getServerIP() + ":" + parentPlatform.getServerPort());
95 96 if (www == null) {
96 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 105 authorizationHeader.setURI(requestURI);
99 106 authorizationHeader.setAlgorithm("MD5");
100 107 registerRequest.addHeader(authorizationHeader);
... ... @@ -108,8 +115,6 @@ public class SIPRequestHeaderPlarformProvider {
108 115 // qop 保护质量 包含auth(默认的)和auth-int(增加了报文完整性检测)两种策略
109 116 String qop = www.getQop();
110 117  
111   - callIdHeader.setCallId(callId);
112   -
113 118 String cNonce = null;
114 119 String nc = "00000001";
115 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 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 280 HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", stream, true, "rtsp", mediaServerItem.getId());
281 281 subscribe.addSubscribe(hookSubscribe, (MediaServerItem mediaServerItemInUse, JSONObject json) -> {
282 282 if (event != null) {
... ... @@ -377,7 +377,7 @@ public class SIPCommander implements ISIPCommander {
377 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 381 String sdpIp;
382 382 if (!ObjectUtils.isEmpty(device.getSdpIp())) {
383 383 sdpIp = device.getSdpIp();
... ... @@ -479,10 +479,11 @@ public class SIPCommander implements ISIPCommander {
479 479 */
480 480 @Override
481 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 487 String sdpIp;
487 488 if (!ObjectUtils.isEmpty(device.getSdpIp())) {
488 489 sdpIp = device.getSdpIp();
... ... @@ -549,11 +550,14 @@ public class SIPCommander implements ISIPCommander {
549 550 content.append("a=downloadspeed:" + downloadSpeed + "\r\n");
550 551  
551 552 content.append("y=" + ssrcInfo.getSsrc() + "\r\n");//ssrc
552   -
  553 + logger.debug("此时请求下载信令的ssrc===>{}",ssrcInfo.getSsrc());
553 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 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 561 subscribe.removeSubscribe(hookSubscribe);
558 562 hookSubscribe.getContent().put("regist", false);
559 563 hookSubscribe.getContent().put("schema", "rtsp");
... ... @@ -562,7 +566,7 @@ public class SIPCommander implements ISIPCommander {
562 566 (MediaServerItem mediaServerItemForEnd, JSONObject jsonForEnd) -> {
563 567 logger.info("[录像]下载结束, 发送BYE");
564 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 570 } catch (InvalidArgumentException | ParseException | SipException |
567 571 SsrcTransactionNotFoundException e) {
568 572 logger.error("[录像]下载结束, 发送BYE失败 {}", e.getMessage());
... ... @@ -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 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 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 791 cmdXml.append("<GuardCmd>" + guardCmdStr + "</GuardCmd>\r\n");
779 792 cmdXml.append("</Control>\r\n");
780 793  
781   -
  794 +
782 795  
783 796 Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport()));
784 797 sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent,okEvent);
... ... @@ -854,7 +867,6 @@ public class SIPCommander implements ISIPCommander {
854 867 *
855 868 * @param device 视频设备
856 869 * @param channelId 通道id,非通道则是设备本身
857   - * @param frontCmd 上级平台的指令,如果存在则直接下发
858 870 * @param enabled 看守位使能:1 = 开启,0 = 关闭
859 871 * @param resetTime 自动归位时间间隔,开启看守位时使用,单位:秒(s)
860 872 * @param presetIndex 调用预置位编号,开启看守位时使用,取值范围0~255
... ... @@ -978,7 +990,7 @@ public class SIPCommander implements ISIPCommander {
978 990 catalogXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
979 991 catalogXml.append("</Query>\r\n");
980 992  
981   -
  993 +
982 994  
983 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 1193 cmdXml.append("</Query>\r\n");
1182 1194  
1183 1195  
1184   -
1185 1196 Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport()));
1186 1197 sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent);
1187 1198 }
... ... @@ -1427,7 +1438,7 @@ public class SIPCommander implements ISIPCommander {
1427 1438 if (device == null) {
1428 1439 return;
1429 1440 }
1430   - logger.info("[发送 报警通知] {}/{}->{},{}", device.getDeviceId(), deviceAlarm.getChannelId(),
  1441 + logger.info("[发送报警通知]设备: {}/{}->{},{}", device.getDeviceId(), deviceAlarm.getChannelId(),
1431 1442 deviceAlarm.getLongitude(), deviceAlarm.getLatitude());
1432 1443  
1433 1444 String characterSet = device.getCharset();
... ... @@ -1439,7 +1450,7 @@ public class SIPCommander implements ISIPCommander {
1439 1450 deviceStatusXml.append("<DeviceID>" + deviceAlarm.getChannelId() + "</DeviceID>\r\n");
1440 1451 deviceStatusXml.append("<AlarmPriority>" + deviceAlarm.getAlarmPriority() + "</AlarmPriority>\r\n");
1441 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 1454 deviceStatusXml.append("<AlarmDescription>" + deviceAlarm.getAlarmDescription() + "</AlarmDescription>\r\n");
1444 1455 deviceStatusXml.append("<Longitude>" + deviceAlarm.getLongitude() + "</Longitude>\r\n");
1445 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 24 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
25 25 import com.genersoft.iot.vmp.storager.dao.dto.PlatformRegisterInfo;
26 26 import com.genersoft.iot.vmp.utils.DateUtil;
  27 +import com.genersoft.iot.vmp.utils.GitUtil;
27 28 import gov.nist.javax.sip.message.MessageFactoryImpl;
28 29 import gov.nist.javax.sip.message.SIPRequest;
29 30 import gov.nist.javax.sip.message.SIPResponse;
... ... @@ -85,26 +86,49 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
85 86 @Autowired
86 87 private DynamicTask dynamicTask;
87 88  
  89 + @Autowired
  90 + private GitUtil gitUtil;
  91 +
88 92 @Override
89 93 public void register(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) throws InvalidArgumentException, ParseException, SipException {
90 94 register(parentPlatform, null, null, errorEvent, okEvent, false, true);
91 95 }
92 96  
93 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 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 110 SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent, boolean registerAgain, boolean isRegister) throws SipException, InvalidArgumentException, ParseException {
101 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 129 request = headerProviderPlatformProvider.createRegisterRequest(parentPlatform,
106   - redisCatchStorage.getCSEQ(), SipUtils.getNewFromTag(),
107   - SipUtils.getNewViaTag(), callIdHeader, isRegister);
  130 + redisCatchStorage.getCSEQ(), fromTag,
  131 + toTag, callIdHeader, isRegister);
108 132 // 将 callid 写入缓存, 等注册成功可以更新状态
109 133 String callIdFromHeader = callIdHeader.getCallId();
110 134 redisCatchStorage.updatePlatformRegisterInfo(callIdFromHeader, PlatformRegisterInfo.getInstance(parentPlatform.getServerGBId(), isRegister));
... ... @@ -122,8 +146,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
122 146 });
123 147  
124 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 152 sipSender.transmitRequest(parentPlatform.getDeviceIp(), request, null, okEvent);
... ... @@ -245,6 +268,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
245 268 catalogXml.append("<IPAddress>" + channel.getIpAddress() + "</IPAddress>\r\n");
246 269 catalogXml.append("<Port>" + channel.getPort() + "</Port>\r\n");
247 270 catalogXml.append("<Password>" + channel.getPort() + "</Password>\r\n");
  271 + catalogXml.append("<PTZType>" + channel.getPTZType() + "</PTZType>\r\n");
248 272 catalogXml.append("<Status>" + (channel.getStatus() == 1?"ON":"OFF") + "</Status>\r\n");
249 273 catalogXml.append("<Longitude>" +
250 274 (channel.getLongitudeWgs84() != 0? channel.getLongitudeWgs84():channel.getLongitude())
... ... @@ -285,6 +309,9 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
285 309  
286 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 315 if (sendAfterResponse) {
289 316 // 默认按照收到200回复后发送下一条, 如果超时收不到回复,就以30毫秒的间隔直接发送。
290 317 dynamicTask.startDelay(timeoutTaskKey, ()->{
... ... @@ -336,17 +363,22 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
336 363 if (parentPlatform == null) {
337 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 371 String characterSet = parentPlatform.getCharacterSet();
340 372 StringBuffer deviceInfoXml = new StringBuffer(600);
341 373 deviceInfoXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n");
342 374 deviceInfoXml.append("<Response>\r\n");
343 375 deviceInfoXml.append("<CmdType>DeviceInfo</CmdType>\r\n");
344 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 382 deviceInfoXml.append("<Result>OK</Result>\r\n");
351 383 deviceInfoXml.append("</Response>\r\n");
352 384  
... ... @@ -423,7 +455,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
423 455 if (parentPlatform == null) {
424 456 return;
425 457 }
426   - logger.info("[发送报警通知] {}/{}->{},{}: {}", parentPlatform.getServerGBId(), deviceAlarm.getChannelId(),
  458 + logger.info("[发送报警通知]平台: {}/{}->{},{}: {}", parentPlatform.getServerGBId(), deviceAlarm.getChannelId(),
427 459 deviceAlarm.getLongitude(), deviceAlarm.getLatitude(), JSON.toJSONString(deviceAlarm));
428 460 String characterSet = parentPlatform.getCharacterSet();
429 461 StringBuffer deviceStatusXml = new StringBuffer(600);
... ... @@ -434,7 +466,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
434 466 .append("<DeviceID>" + deviceAlarm.getChannelId() + "</DeviceID>\r\n")
435 467 .append("<AlarmPriority>" + deviceAlarm.getAlarmPriority() + "</AlarmPriority>\r\n")
436 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 470 .append("<AlarmDescription>" + deviceAlarm.getAlarmDescription() + "</AlarmDescription>\r\n")
439 471 .append("<Longitude>" + deviceAlarm.getLongitude() + "</Longitude>\r\n")
440 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 45 try {
46 46 return SipFactory.getInstance().createHeaderFactory();
47 47 } catch (PeerUnavailableException e) {
48   - e.printStackTrace();
  48 + logger.error("未处理的异常 ", e);
49 49 }
50 50 return null;
51 51 }
... ... @@ -54,7 +54,7 @@ public abstract class SIPRequestProcessorParent {
54 54 try {
55 55 return SipFactory.getInstance().createMessageFactory();
56 56 } catch (PeerUnavailableException e) {
57   - e.printStackTrace();
  57 + logger.error("未处理的异常 ", e);
58 58 }
59 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 8 import com.genersoft.iot.vmp.gb28181.bean.*;
9 9 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
10 10 import com.genersoft.iot.vmp.gb28181.session.AudioBroadcastManager;
  11 +import com.genersoft.iot.vmp.gb28181.session.SsrcConfig;
11 12 import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
12 13 import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
13 14 import com.genersoft.iot.vmp.gb28181.transmit.SIPSender;
... ... @@ -457,12 +458,8 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
457 458 if (!userSetting.getPushStreamAfterAck()) {
458 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 465 SipSubscribe.Event errorEvent = ((event) -> {
... ... @@ -471,7 +468,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
471 468 Response response = getMessageFactory().createResponse(event.statusCode, evt.getRequest());
472 469 sipSender.transmitRequest(request.getLocalAddress().getHostAddress(), response);
473 470 } catch (ParseException | SipException e) {
474   - e.printStackTrace();
  471 + logger.error("未处理的异常 ", e);
475 472 }
476 473 });
477 474 sendRtpItem.setApp("rtp");
... ... @@ -543,6 +540,15 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
543 540 }
544 541 }
545 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 552 if("push".equals(gbStream.getStreamType())) {
547 553 if (streamPushItem != null && streamPushItem.isPushIng()) {
548 554 // 推流状态
... ... @@ -572,7 +578,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
572 578 } catch (SdpParseException e) {
573 579 logger.error("sdp解析错误", e);
574 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 733 mediaListManager.removedChannelOnlineEventLister(gbStream.getApp(), gbStream.getStream());
728 734 responseAck(request, Response.REQUEST_TIMEOUT); // 超时
729 735 } catch (SipException e) {
730   - e.printStackTrace();
  736 + logger.error("未处理的异常 ", e);
731 737 } catch (InvalidArgumentException e) {
732   - e.printStackTrace();
  738 + logger.error("未处理的异常 ", e);
733 739 } catch (ParseException e) {
734   - e.printStackTrace();
  740 + logger.error("未处理的异常 ", e);
735 741 }
736 742 }, userSetting.getPlatformPlayTimeout());
737 743 // 添加监听
... ... @@ -750,11 +756,11 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
750 756 try {
751 757 responseAck(request, Response.BUSY_HERE);
752 758 } catch (SipException e) {
753   - e.printStackTrace();
  759 + logger.error("未处理的异常 ", e);
754 760 } catch (InvalidArgumentException e) {
755   - e.printStackTrace();
  761 + logger.error("未处理的异常 ", e);
756 762 } catch (ParseException e) {
757   - e.printStackTrace();
  763 + logger.error("未处理的异常 ", e);
758 764 }
759 765 return;
760 766 }
... ... @@ -812,11 +818,11 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
812 818 try {
813 819 responseAck(request, Response.BUSY_HERE);
814 820 } catch (SipException e) {
815   - e.printStackTrace();
  821 + logger.error("未处理的异常 ", e);
816 822 } catch (InvalidArgumentException e) {
817   - e.printStackTrace();
  823 + logger.error("未处理的异常 ", e);
818 824 } catch (ParseException e) {
819   - e.printStackTrace();
  825 + logger.error("未处理的异常 ", e);
820 826 }
821 827 return;
822 828 }
... ... @@ -869,7 +875,13 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
869 875 content.append("s=Play\r\n");
870 876 content.append("c=IN IP4 " + mediaServerItem.getSdpIp() + "\r\n");
871 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 885 content.append("a=sendonly\r\n");
874 886 content.append("a=rtpmap:96 PS/90000\r\n");
875 887 if (sendRtpItem.isTcp()) {
... ... @@ -890,11 +902,11 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
890 902 }
891 903 return sipResponse;
892 904 } catch (SipException e) {
893   - e.printStackTrace();
  905 + logger.error("未处理的异常 ", e);
894 906 } catch (InvalidArgumentException e) {
895   - e.printStackTrace();
  907 + logger.error("未处理的异常 ", e);
896 908 } catch (ParseException e) {
897   - e.printStackTrace();
  909 + logger.error("未处理的异常 ", e);
898 910 }
899 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 93 try {
94 94 responseAck((SIPRequest) evt.getRequest(), Response.OK, null, null);
95 95 }catch (SipException | InvalidArgumentException | ParseException e) {
96   - e.printStackTrace();
  96 + logger.error("未处理的异常 ", e);
97 97 }
98 98 boolean runed = !taskQueue.isEmpty();
99 99 taskQueue.offer(new HandlerCatchData(evt, null, null));
... ... @@ -229,7 +229,7 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements
229 229 jsonObject.put("speed", mobilePosition.getSpeed());
230 230 redisCatchStorage.sendMobilePositionMsg(jsonObject);
231 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 339 publisher.deviceAlarmEventPublish(deviceAlarm);
340 340 }
341 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 397 case CatalogEvent.OFF :
398 398 // 离线
399 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 405 break;
402 406 case CatalogEvent.VLOST:
403 407 // 视频丢失
404 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 414 break;
407 415 case CatalogEvent.DEFECT:
408 416 // 故障
... ... @@ -432,7 +440,7 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements
432 440 }
433 441 }
434 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 5 import com.genersoft.iot.vmp.gb28181.auth.DigestServerAuthenticationHelper;
6 6 import com.genersoft.iot.vmp.gb28181.bean.Device;
7 7 import com.genersoft.iot.vmp.gb28181.bean.RemoteAddressInfo;
  8 +import com.genersoft.iot.vmp.gb28181.bean.SipTransactionInfo;
8 9 import com.genersoft.iot.vmp.gb28181.bean.WvpSipDate;
9 10 import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
10 11 import com.genersoft.iot.vmp.gb28181.transmit.SIPSender;
... ... @@ -18,6 +19,7 @@ import gov.nist.javax.sip.address.AddressImpl;
18 19 import gov.nist.javax.sip.address.SipUri;
19 20 import gov.nist.javax.sip.header.SIPDateHeader;
20 21 import gov.nist.javax.sip.message.SIPRequest;
  22 +import gov.nist.javax.sip.message.SIPResponse;
21 23 import org.slf4j.Logger;
22 24 import org.slf4j.LoggerFactory;
23 25 import org.springframework.beans.factory.InitializingBean;
... ... @@ -34,6 +36,7 @@ import javax.sip.header.AuthorizationHeader;
34 36 import javax.sip.header.ContactHeader;
35 37 import javax.sip.header.FromHeader;
36 38 import javax.sip.header.ViaHeader;
  39 +import javax.sip.message.Request;
37 40 import javax.sip.message.Response;
38 41 import java.security.NoSuchAlgorithmException;
39 42 import java.text.ParseException;
... ... @@ -105,6 +108,30 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
105 108 SipUri uri = (SipUri) address.getURI();
106 109 String deviceId = uri.getUser();
107 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 135 String password = (device != null && !ObjectUtils.isEmpty(device.getPassword()))? device.getPassword() : sipConfig.getPassword();
109 136 AuthorizationHeader authHead = (AuthorizationHeader) request.getHeader(AuthorizationHeader.NAME);
110 137 if (authHead == null && !ObjectUtils.isEmpty(password)) {
... ... @@ -147,9 +174,6 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
147 174 // 添加Expires头
148 175 response.addHeader(request.getExpires());
149 176  
150   - RemoteAddressInfo remoteAddressInfo = SipUtils.getRemoteAddressFromRequest(request,
151   - userSetting.getSipUseSourceIpAsRemoteAddress());
152   -
153 177 if (device == null) {
154 178 device = new Device();
155 179 device.setStreamMode("UDP");
... ... @@ -182,13 +206,33 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
182 206 if (registerFlag) {
183 207 logger.info("[注册成功] deviceId: {}->{}", deviceId, requestAddress);
184 208 device.setRegisterTime(DateUtil.getNow());
185   - deviceService.online(device);
  209 + SipTransactionInfo sipTransactionInfo = new SipTransactionInfo((SIPResponse)response);
  210 + deviceService.online(device, sipTransactionInfo);
186 211 } else {
187 212 logger.info("[注销成功] deviceId: {}->{}" ,deviceId, requestAddress);
188   - deviceService.offline(deviceId);
  213 + deviceService.offline(deviceId, "主动注销");
189 214 }
190 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 1 package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl;
2 2  
  3 +import com.genersoft.iot.vmp.common.VideoManagerConstants;
3 4 import com.genersoft.iot.vmp.conf.DynamicTask;
4 5 import com.genersoft.iot.vmp.conf.UserSetting;
5 6 import com.genersoft.iot.vmp.gb28181.bean.CmdType;
... ... @@ -8,14 +9,11 @@ import com.genersoft.iot.vmp.gb28181.bean.SubscribeHolder;
8 9 import com.genersoft.iot.vmp.gb28181.bean.SubscribeInfo;
9 10 import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
10 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 12 import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor;
14 13 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
15 14 import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
16 15 import com.genersoft.iot.vmp.gb28181.utils.XmlUtil;
17 16 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
18   -import gov.nist.javax.sip.SipProviderImpl;
19 17 import gov.nist.javax.sip.message.SIPRequest;
20 18 import gov.nist.javax.sip.message.SIPResponse;
21 19 import org.dom4j.DocumentException;
... ... @@ -26,7 +24,9 @@ import org.springframework.beans.factory.InitializingBean;
26 24 import org.springframework.beans.factory.annotation.Autowired;
27 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 30 import javax.sip.header.ExpiresHeader;
31 31 import javax.sip.message.Response;
32 32 import java.text.ParseException;
... ... @@ -93,7 +93,7 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme
93 93 sipSender.transmitRequest(request.getLocalAddress().getHostAddress(), response);
94 94 }
95 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 146 }
147 147  
148 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 192 subscribeHolder.putCatalogSubscribe(platformId, subscribeInfo);
193 193 }
194 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 73 String channelId = getText(rootElement, "DeviceID");
74 74 // 远程启动功能
75 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 109 DeviceControlType deviceControlType = DeviceControlType.typeOf(rootElement);
107 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 186 // 发送给平台的报警信息。 发送redis通知
187 187 logger.info("[发送给平台的报警信息]内容:{}", JSONObject.toJSONString(deviceAlarm));
188 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 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 196 alarmChannelMessage.setGbId(channelId);
193 197 redisCatchStorage.sendAlarmMsg(alarmChannelMessage);
194 198 continue;
... ... @@ -204,6 +208,7 @@ public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent impleme
204 208 publisher.deviceAlarmEventPublish(deviceAlarm);
205 209 }
206 210 }catch (Exception e) {
  211 + logger.error("未处理的异常 ", e);
207 212 logger.warn("[收到报警通知] 发现未处理的异常, {}\r\n{}",e.getMessage(), evt.getRequest());
208 213 }
209 214 }
... ... @@ -264,12 +269,15 @@ public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent impleme
264 269 if (channelId.equals(parentPlatform.getDeviceGBId())) {
265 270 // 发送给平台的报警信息。 发送redis通知
266 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 275 alarmChannelMessage.setAlarmDescription(deviceAlarm.getAlarmDescription());
269 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 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 88 // 对于已经离线的设备判断他的注册是否已经过期
89 89 if (!deviceService.expire(device)){
90 90 device.setOnline(0);
91   - deviceService.online(device);
  91 + deviceService.online(device, null);
92 92 }
93 93 }
94 94 // 刷新过期任务
95 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 149 redisCatchStorage.sendMobilePositionMsg(jsonObject);
150 150  
151 151 } catch (DocumentException e) {
152   - e.printStackTrace();
  152 + logger.error("未处理的异常 ", e);
153 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 60 return;
61 61 }
62 62 String sn = rootElement.element("SN").getText();
  63 +
63 64 /*根据WVP原有的数据结构,设备和通道是分开放置,设备信息都是存放在设备表里,通道表里的设备信息不可作为真实信息处理
64 65 大部分NVR/IPC设备对他的通道信息实现都是返回默认的值没有什么参考价值。NVR/IPC通道我们统一使用设备表的设备信息来作为返回。
65 66 我们这里使用查询数据库的方式来实现这个设备信息查询的功能,在其他地方对设备信息更新达到正确的目的。*/
  67 +
66 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 79 try {
73   - cmderFroPlatform.deviceInfoResponse(parentPlatform,device, sn, fromHeader.getTag());
  80 + cmderFroPlatform.deviceInfoResponse(parentPlatform, device, sn, fromHeader.getTag());
74 81 } catch (SipException | InvalidArgumentException | ParseException e) {
75 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 132  
133 133 }
134 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 1 package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.cmd;
2 2  
3 3 import com.alibaba.fastjson2.JSONObject;
4   -import com.genersoft.iot.vmp.common.VideoManagerConstants;
5 4 import com.genersoft.iot.vmp.gb28181.bean.Device;
6 5 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
7   -import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
8 6 import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
9 7 import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
10 8 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
... ... @@ -26,7 +24,6 @@ import javax.sip.RequestEvent;
26 24 import javax.sip.SipException;
27 25 import javax.sip.message.Response;
28 26 import java.text.ParseException;
29   -import java.util.Objects;
30 27  
31 28 @Component
32 29 public class DeviceStatusResponseMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
... ... @@ -74,9 +71,9 @@ public class DeviceStatusResponseMessageHandler extends SIPRequestProcessorParen
74 71 }
75 72 String text = onlineElement.getText();
76 73 if ("ONLINE".equalsIgnoreCase(text.trim())) {
77   - deviceService.online(device);
  74 + deviceService.online(device, null);
78 75 }else {
79   - deviceService.offline(device.getDeviceId());
  76 + deviceService.offline(device.getDeviceId(), "设备状态查询结果:" + text.trim());
80 77 }
81 78 RequestMessage msg = new RequestMessage();
82 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 142 }
143 143  
144 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 150 }
151 151 }
152 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 164 public void releaseRequest(String deviceId, String sn,RecordInfo recordInfo){
164 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 173 RequestMessage msg = new RequestMessage();
169 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 2  
3 3 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
4 4 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch;
  5 +import com.genersoft.iot.vmp.gb28181.bean.SipTransactionInfo;
5 6 import com.genersoft.iot.vmp.gb28181.bean.SubscribeHolder;
6 7 import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
7 8 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
... ... @@ -10,6 +11,7 @@ import com.genersoft.iot.vmp.service.IPlatformService;
10 11 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
11 12 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
12 13 import com.genersoft.iot.vmp.storager.dao.dto.PlatformRegisterInfo;
  14 +import gov.nist.javax.sip.message.SIPResponse;
13 15 import org.slf4j.Logger;
14 16 import org.slf4j.LoggerFactory;
15 17 import org.springframework.beans.factory.annotation.Autowired;
... ... @@ -18,7 +20,6 @@ import org.springframework.stereotype.Component;
18 20 import javax.sip.InvalidArgumentException;
19 21 import javax.sip.ResponseEvent;
20 22 import javax.sip.SipException;
21   -import javax.sip.header.CallIdHeader;
22 23 import javax.sip.header.WWWAuthenticateHeader;
23 24 import javax.sip.message.Response;
24 25 import java.text.ParseException;
... ... @@ -65,9 +66,8 @@ public class RegisterResponseProcessor extends SIPResponseProcessorAbstract {
65 66 */
66 67 @Override
67 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 71 PlatformRegisterInfo platformRegisterInfo = redisCatchStorage.queryPlatformRegisterInfo(callId);
72 72 if (platformRegisterInfo == null) {
73 73 logger.info(String.format("[国标级联]未找到callId: %s 的注册/注销平台id", callId ));
... ... @@ -90,15 +90,17 @@ public class RegisterResponseProcessor extends SIPResponseProcessorAbstract {
90 90  
91 91 if (response.getStatusCode() == Response.UNAUTHORIZED) {
92 92 WWWAuthenticateHeader www = (WWWAuthenticateHeader)response.getHeader(WWWAuthenticateHeader.NAME);
  93 + SipTransactionInfo sipTransactionInfo = new SipTransactionInfo(response);
93 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 96 } catch (SipException | InvalidArgumentException | ParseException e) {
96 97 logger.error("[命令发送失败] 国标级联 再次注册: {}", e.getMessage());
97 98 }
98 99 }else if (response.getStatusCode() == Response.OK){
99 100  
100 101 if (platformRegisterInfo.isRegister()) {
101   - platformService.online(parentPlatform);
  102 + SipTransactionInfo sipTransactionInfo = new SipTransactionInfo(response);
  103 + platformService.online(parentPlatform, sipTransactionInfo);
102 104 }else {
103 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 9 import org.slf4j.Logger;
10 10 import org.slf4j.LoggerFactory;
11 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 13 import java.io.IOException;
18 14 import java.net.ConnectException;
19 15 import java.util.HashMap;
20 16 import java.util.Map;
21 17 import java.util.Objects;
22   -import java.util.concurrent.TimeUnit;
23 18  
24 19 @Component
25 20 public class AssistRESTfulUtils {
... ... @@ -137,6 +132,11 @@ public class AssistRESTfulUtils {
137 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 140 public JSONObject addStreamCallInfo(MediaServerItem mediaServerItem, String app, String stream, String callId, RequestCallback callback){
141 141 Map<String, Object> param = new HashMap<>();
142 142 param.put("app",app);
... ...
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
... ... @@ -119,10 +119,11 @@ public class ZLMHttpHookListener {
119 119 * 服务器定时上报时间,上报间隔可配置,默认10s上报一次
120 120 */
121 121 @ResponseBody
  122 +
122 123 @PostMapping(value = "/on_server_keepalive", produces = "application/json;charset=UTF-8")
123 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 128 taskExecutor.execute(() -> {
128 129 List<ZlmHttpHookSubscribe.Event> subscribes = this.subscribe.getSubscribes(HookType.on_server_keepalive);
... ... @@ -142,6 +143,7 @@ public class ZLMHttpHookListener {
142 143 * 播放器鉴权事件,rtsp/rtmp/http-flv/ws-flv/hls的播放都将触发此鉴权事件。
143 144 */
144 145 @ResponseBody
  146 +
145 147 @PostMapping(value = "/on_play", produces = "application/json;charset=UTF-8")
146 148 public HookResult onPlay(@RequestBody OnPlayHookParam param) {
147 149 if (logger.isDebugEnabled()) {
... ... @@ -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 287 return result;
268 288 }
269 289  
  290 +
270 291 /**
271 292 * rtsp/rtmp流注册或注销时触发此事件;此事件对回复不敏感。
272 293 */
... ... @@ -293,8 +314,12 @@ public class ZLMHttpHookListener {
293 314 subscribe.response(mediaInfo, json);
294 315 }
295 316 }
296   - // 流消失移除redis play
  317 +
  318 + List<OnStreamChangedHookParam.MediaTrack> tracks = param.getTracks();
  319 + // TODO 重构此处逻辑
  320 +
297 321 if (param.isRegist()) {
  322 + // 处理流注册的鉴权信息
298 323 if (param.getOriginType() == OriginType.RTMP_PUSH.ordinal()
299 324 || param.getOriginType() == OriginType.RTSP_PUSH.ordinal()
300 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 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 338 Map<String, Object> param = new HashMap<>(3);
339   - param.put("url", flvUrl);
  339 + param.put("url", streamUrl);
340 340 param.put("timeout_sec", timeout_sec);
341 341 param.put("expire_sec", expire_sec);
342 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 262 logger.info("[保持端口] {}->监听端口到期继续保持监听", ssrc);
263 263 keepPort(serverItem, ssrc);
264 264 });
265   - }
266 265 logger.info("[保持端口] {}->监听端口: {}", ssrc, localPort);
  266 + logger.info("[保持端口] {}->监听端口: {}", ssrc, localPort);
  267 + }else {
  268 + logger.info("[保持端口] 监听端口失败: {}", ssrc);
  269 + }
267 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 10 @JSONField(name = "api.secret")
11 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 19 @JSONField(name = "ffmpeg.bin")
14 20 private String ffmpegBin;
15 21  
16 22 @JSONField(name = "ffmpeg.cmd")
17 23 private String ffmpegCmd;
18 24  
  25 + @JSONField(name = "ffmpeg.snap")
  26 + private String ffmpegSnap;
  27 +
19 28 @JSONField(name = "ffmpeg.log")
20 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 91 @JSONField(name = "general.enableVhost")
23 92 private String generalEnableVhost;
24 93  
25   - @JSONField(name = "general.mediaServerId")
26   - private String generalMediaServerId;
27   -
28 94 @JSONField(name = "general.flowThreshold")
29 95 private String generalFlowThreshold;
30 96  
... ... @@ -34,6 +100,25 @@ public class ZLMServerConfig {
34 100 @JSONField(name = "general.streamNoneReaderDelayMS")
35 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 122 @JSONField(name = "ip")
38 123 private String ip;
39 124  
... ... @@ -59,6 +144,18 @@ public class ZLMServerConfig {
59 144 @JSONField(name = "hls.segNum")
60 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 159 @JSONField(name = "hook.access_file_except_hls")
63 160 private String hookAccessFileExceptHLS;
64 161  
... ... @@ -104,6 +201,18 @@ public class ZLMServerConfig {
104 201 @JSONField(name = "hook.on_stream_not_found")
105 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 216 @JSONField(name = "hook.timeoutSec")
108 217 private String hookTimeoutSec;
109 218  
... ... @@ -813,4 +922,292 @@ public class ZLMServerConfig {
813 922 public void setPortRange(String portRange) {
814 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 5 private boolean enable_audio;
6 6 private boolean enable_mp4;
7 7 private int mp4_max_second;
  8 + private String mp4_save_path;
8 9  
9 10 public HookResultForOnPublish() {
10 11 }
... ... @@ -41,4 +42,12 @@ public class HookResultForOnPublish extends HookResult{
41 42 public void setMp4_max_second(int mp4_max_second) {
42 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 2  
3 3 import com.genersoft.iot.vmp.gb28181.bean.Device;
4 4 import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
  5 +import com.genersoft.iot.vmp.gb28181.bean.SipTransactionInfo;
5 6 import com.genersoft.iot.vmp.gb28181.bean.SyncStatus;
6 7 import com.genersoft.iot.vmp.vmanager.bean.BaseTree;
7 8 import com.genersoft.iot.vmp.vmanager.bean.ResourceBaceInfo;
... ... @@ -18,13 +19,13 @@ public interface IDeviceService {
18 19 * 设备上线
19 20 * @param device 设备信息
20 21 */
21   - void online(Device device);
  22 + void online(Device device, SipTransactionInfo sipTransactionInfo);
22 23  
23 24 /**
24 25 * 设备下线
25 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 import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe;
7 7 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
8 8 import com.genersoft.iot.vmp.service.bean.InviteTimeOutCallback;
  9 +import com.genersoft.iot.vmp.gb28181.bean.SipTransactionInfo;
9 10 import com.github.pagehelper.PageInfo;
10 11  
11 12 import javax.sip.InvalidArgumentException;
... ... @@ -35,10 +36,16 @@ public interface IPlatformService {
35 36 boolean add(ParentPlatform parentPlatform);
36 37  
37 38 /**
  39 + * 添加级联平台
  40 + * @param parentPlatform 级联平台
  41 + */
  42 + boolean update(ParentPlatform parentPlatform);
  43 +
  44 + /**
38 45 * 平台上线
39 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 96 private ZLMRESTfulUtils zlmresTfulUtils;
97 97  
98 98 @Override
99   - public void online(Device device) {
  99 + public void online(Device device, SipTransactionInfo sipTransactionInfo) {
100 100 logger.info("[设备上线] deviceId:{}->{}:{}", device.getDeviceId(), device.getIp(), device.getPort());
101 101 Device deviceInRedis = redisCatchStorage.getDevice(device.getDeviceId());
102 102 Device deviceInDb = deviceMapper.getDeviceByDeviceId(device.getDeviceId());
... ... @@ -111,6 +111,14 @@ public class DeviceServiceImpl implements IDeviceService {
111 111 // 默认心跳间隔60
112 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 123 if (device.getCreateTime() == null) {
116 124 device.setOnline(1);
... ... @@ -163,12 +171,12 @@ public class DeviceServiceImpl implements IDeviceService {
163 171 // 刷新过期任务
164 172 String registerExpireTaskKey = VideoManagerConstants.REGISTER_EXPIRE_TASK_KEY_PREFIX + device.getDeviceId();
165 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 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 180 Device device = deviceMapper.getDeviceByDeviceId(deviceId);
173 181 if (device == null) {
174 182 return;
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/GbStreamServiceImpl.java
... ... @@ -41,6 +41,9 @@ public class GbStreamServiceImpl implements IGbStreamService {
41 41 private PlatformGbStreamMapper platformGbStreamMapper;
42 42  
43 43 @Autowired
  44 + private SubscribeHolder subscribeHolder;
  45 +
  46 + @Autowired
44 47 private ParentPlatformMapper platformMapper;
45 48  
46 49 @Autowired
... ... @@ -73,16 +76,23 @@ public class GbStreamServiceImpl implements IGbStreamService {
73 76 }
74 77 try {
75 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 83 gbStream.setCatalogId(catalogId);
78 84 gbStream.setPlatformId(platformId);
79 85 // TODO 修改为批量提交
80 86 platformGbStreamMapper.add(gbStream);
  87 + logger.info("[关联通道]直播流通道 平台:{}, 共需关联通道数:{}, 已关联:{}", platformId, gbStreams.size(), i + 1);
81 88 DeviceChannel deviceChannelListByStream = getDeviceChannelListByStreamWithStatus(gbStream, catalogId, parentPlatform);
82 89 deviceChannelList.add(deviceChannelListByStream);
83 90 }
84 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 96 result = true;
87 97 }catch (Exception e) {
88 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 11 import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
12 12 import com.genersoft.iot.vmp.gb28181.session.SsrcConfig;
13 13 import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
  14 +import com.genersoft.iot.vmp.media.zlm.AssistRESTfulUtils;
14 15 import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
15 16 import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
16 17 import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig;
... ... @@ -38,6 +39,7 @@ import org.springframework.transaction.TransactionDefinition;
38 39 import org.springframework.transaction.TransactionStatus;
39 40 import org.springframework.util.ObjectUtils;
40 41  
  42 +import java.io.File;
41 43 import java.time.LocalDateTime;
42 44 import java.util.*;
43 45  
... ... @@ -64,6 +66,9 @@ public class MediaServerServiceImpl implements IMediaServerService {
64 66 private UserSetting userSetting;
65 67  
66 68 @Autowired
  69 + private AssistRESTfulUtils assistRESTfulUtils;
  70 +
  71 + @Autowired
67 72 private ZLMRESTfulUtils zlmresTfulUtils;
68 73  
69 74 @Autowired
... ... @@ -409,13 +414,27 @@ public class MediaServerServiceImpl implements IMediaServerService {
409 414 }
410 415 RedisUtil.set(key, serverItem);
411 416 resetOnlineServerItem(serverItem);
  417 +
  418 +
412 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 431 setZLMConfig(serverItem, "0".equals(zlmServerConfig.getHookEnable()));
414 432 }
415 433 final String zlmKeepaliveKey = zlmKeepaliveKeyPrefix + serverItem.getId();
416 434 dynamicTask.stop(zlmKeepaliveKey);
417 435 dynamicTask.startDelay(zlmKeepaliveKey, new KeepAliveTimeoutRunnable(serverItem), (Math.getExponent(serverItem.getHookAliveInterval()) + 5) * 1000);
418 436 publisher.zlmOnlineEventPublish(serverItem.getId());
  437 +
419 438 logger.info("[ZLM] 连接成功 {} - {}:{} ",
420 439 zlmServerConfig.getGeneralMediaServerId(), zlmServerConfig.getIp(), zlmServerConfig.getHttpPort());
421 440 }
... ... @@ -549,6 +568,9 @@ public class MediaServerServiceImpl implements IMediaServerService {
549 568  
550 569 Map<String, Object> param = new HashMap<>();
551 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 574 param.put("hook.enable","1");
553 575 param.put("hook.on_flow_report","");
554 576 param.put("hook.on_play",String.format("%s/on_play", hookPrex));
... ... @@ -583,6 +605,13 @@ public class MediaServerServiceImpl implements IMediaServerService {
583 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 615 JSONObject responseJSON = zlmresTfulUtils.setServerConfig(mediaServerItem, param);
587 616  
588 617 if (responseJSON != null && responseJSON.getInteger("code") == 0) {
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/PlatformChannelServiceImpl.java
1 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 4 import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
8 5 import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent;
9 6 import com.genersoft.iot.vmp.service.IPlatformChannelService;
... ... @@ -15,7 +12,10 @@ import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce;
15 12 import org.slf4j.Logger;
16 13 import org.slf4j.LoggerFactory;
17 14 import org.springframework.beans.factory.annotation.Autowired;
  15 +import org.springframework.jdbc.datasource.DataSourceTransactionManager;
18 16 import org.springframework.stereotype.Service;
  17 +import org.springframework.transaction.TransactionDefinition;
  18 +import org.springframework.transaction.TransactionStatus;
19 19 import org.springframework.util.ObjectUtils;
20 20  
21 21 import java.util.ArrayList;
... ... @@ -35,6 +35,16 @@ public class PlatformChannelServiceImpl implements IPlatformChannelService {
35 35 private PlatformChannelMapper platformChannelMapper;
36 36  
37 37 @Autowired
  38 + TransactionDefinition transactionDefinition;
  39 +
  40 + @Autowired
  41 + DataSourceTransactionManager dataSourceTransactionManager;
  42 +
  43 + @Autowired
  44 + private SubscribeHolder subscribeHolder;
  45 +
  46 +
  47 + @Autowired
38 48 private DeviceChannelMapper deviceChannelMapper;
39 49  
40 50 @Autowired
... ... @@ -69,17 +79,47 @@ public class PlatformChannelServiceImpl implements IPlatformChannelService {
69 79 }
70 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 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 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 21 import com.genersoft.iot.vmp.service.bean.InviteTimeOutCallback;
22 22 import com.genersoft.iot.vmp.service.bean.SSRCInfo;
23 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 26 import com.github.pagehelper.PageHelper;
27 27 import com.github.pagehelper.PageInfo;
28 28 import org.slf4j.Logger;
... ... @@ -54,6 +54,15 @@ public class PlatformServiceImpl implements IPlatformService {
54 54 private ParentPlatformMapper platformMapper;
55 55  
56 56 @Autowired
  57 + private PlatformCatalogMapper catalogMapper;
  58 +
  59 + @Autowired
  60 + private PlatformChannelMapper platformChannelMapper;
  61 +
  62 + @Autowired
  63 + private PlatformGbStreamMapper platformGbStreamMapper;
  64 +
  65 + @Autowired
57 66 private IRedisCatchStorage redisCatchStorage;
58 67  
59 68 @Autowired
... ... @@ -135,36 +144,106 @@ public class PlatformServiceImpl implements IPlatformService {
135 144 }
136 145  
137 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 219 platformMapper.updateParentPlatformStatus(parentPlatform.getServerGBId(), true);
141 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 222 parentPlatformCatch = new ParentPlatformCatch();
147 223 parentPlatformCatch.setParentPlatform(parentPlatform);
148 224 parentPlatformCatch.setId(parentPlatform.getServerGBId());
149 225 parentPlatform.setStatus(true);
150 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 233 final String registerTaskKey = REGISTER_KEY_PREFIX + parentPlatform.getServerGBId();
155 234 if (!dynamicTask.isAlive(registerTaskKey)) {
  235 + logger.info("[国标级联]:{}, 添加定时注册任务", parentPlatform.getServerGBId());
156 236 // 添加注册任务
157 237 dynamicTask.startCron(registerTaskKey,
158 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 244 final String keepaliveTaskKey = KEEPALIVE_KEY_PREFIX + parentPlatform.getServerGBId();
167 245 if (!dynamicTask.contains(keepaliveTaskKey)) {
  246 + logger.info("[国标级联]:{}, 添加定时心跳任务", parentPlatform.getServerGBId());
168 247 // 添加心跳任务
169 248 dynamicTask.startCron(keepaliveTaskKey,
170 249 ()-> {
... ... @@ -205,11 +284,11 @@ public class PlatformServiceImpl implements IPlatformService {
205 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 292 try {
214 293 // 设置超时重发, 后续从底层支持消息重发
215 294 String key = KEEPALIVE_KEY_PREFIX + parentPlatform.getServerGBId() + "_timeout";
... ... @@ -217,10 +296,10 @@ public class PlatformServiceImpl implements IPlatformService {
217 296 return;
218 297 }
219 298 dynamicTask.startDelay(key, ()->{
220   - registerTask(parentPlatform);
  299 + registerTask(parentPlatform, sipTransactionInfo);
221 300 }, 1000);
222   - logger.info("[国标级联] 平台:{}注册即将到期,重新注册", parentPlatform.getServerGBId());
223   - commanderForPlatform.register(parentPlatform, eventResult -> {
  301 + logger.info("[国标级联] 平台:{}注册即将到期,开始续订", parentPlatform.getServerGBId());
  302 + commanderForPlatform.register(parentPlatform, sipTransactionInfo, eventResult -> {
224 303 dynamicTask.stop(key);
225 304 offline(parentPlatform, false);
226 305 },eventResult -> {
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
... ... @@ -438,7 +438,12 @@ public class PlayServiceImpl implements IPlayService {
438 438 onPublishHandlerForPlay(mediaServerItemInuse, response, device.getDeviceId(), channelId);
439 439 hookEvent.response(mediaServerItemInuse, response);
440 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 447 String path = "snap";
443 448 String fileName = device.getDeviceId() + "_" + channelId + ".jpg";
444 449 // 请求截图
... ... @@ -806,23 +811,75 @@ public class PlayServiceImpl implements IPlayService {
806 811 hookCallBack.call(downloadResult);
807 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 828 try {
811 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 883 } catch (InvalidArgumentException | SipException | ParseException e) {
827 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 201 dataSourceTransactionManager.commit(transactionStatus); //手动提交
202 202 result = true;
203 203 }catch (Exception e) {
204   - e.printStackTrace();
  204 + logger.error("未处理的异常 ", e);
205 205 dataSourceTransactionManager.rollback(transactionStatus);
206 206 }
207 207 return result;
... ...
src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisAlarmMsgListener.java
1 1 package com.genersoft.iot.vmp.service.redisMsg;
2 2  
3 3 import com.alibaba.fastjson2.JSON;
  4 +import com.genersoft.iot.vmp.conf.UserSetting;
4 5 import com.genersoft.iot.vmp.gb28181.bean.*;
5 6 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
6 7 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
... ... @@ -44,13 +45,17 @@ public class RedisAlarmMsgListener implements MessageListener {
44 45 @Autowired
45 46 private ThreadPoolTaskExecutor taskExecutor;
46 47  
  48 + @Autowired
  49 + private UserSetting userSetting;
  50 +
47 51 @Override
48 52 public void onMessage(@NotNull Message message, byte[] bytes) {
  53 + // 消息示例: PUBLISH alarm_receive '{ "gbId": "", "alarmSn": 1, "alarmType": "111", "alarmDescription": "222", }'
49 54 logger.info("收到来自REDIS的ALARM通知: {}", new String(message.getBody()));
50 55 boolean isEmpty = taskQueue.isEmpty();
51 56 taskQueue.offer(message);
52 57 if (isEmpty) {
53   - logger.info("[线程池信息]活动线程数:{}, 最大线程数: {}", taskExecutor.getActiveCount(), taskExecutor.getMaxPoolSize());
  58 +// logger.info("[线程池信息]活动线程数:{}, 最大线程数: {}", taskExecutor.getActiveCount(), taskExecutor.getMaxPoolSize());
54 59 taskExecutor.execute(() -> {
55 60 while (!taskQueue.isEmpty()) {
56 61 Message msg = taskQueue.poll();
... ... @@ -69,22 +74,52 @@ public class RedisAlarmMsgListener implements MessageListener {
69 74 deviceAlarm.setAlarmMethod("" + alarmChannelMessage.getAlarmSn());
70 75 deviceAlarm.setAlarmType("" + alarmChannelMessage.getAlarmType());
71 76 deviceAlarm.setAlarmPriority("1");
72   - deviceAlarm.setAlarmTime(DateUtil.getNowForISO8601());
  77 + deviceAlarm.setAlarmTime(DateUtil.getNow());
73 78 deviceAlarm.setLongitude(0);
74 79 deviceAlarm.setLatitude(0);
75 80  
76 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 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 123 }else {
89 124 Device device = storage.queryVideoDevice(gbId);
90 125 ParentPlatform platform = storage.queryParentPlatByServerGBId(gbId);
... ... @@ -105,6 +140,7 @@ public class RedisAlarmMsgListener implements MessageListener {
105 140 }
106 141 }
107 142 }catch (Exception e) {
  143 + logger.error("未处理的异常 ", e);
108 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 202  
203 203 }
204 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 53 // 只是放入redis缓存起来
54 54 redisCatchStorage.updateGpsMsgInfo(gpsMsgInfo);
55 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 58 responseEvents.get(response.getApp() + response.getStream()).run(response);
59 59 }
60 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 95 gbStreamService.updateGbIdOrName(streamPushItemForUpdate);
96 96 }
97 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 79 streamPushService.online(statusChangeFromPushStream.getOnlineStreams());
80 80 }
81 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 82 zlmMediaListManager.removeMedia(app, stream);
83 83 }
84 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 5 import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
6 6 import com.genersoft.iot.vmp.storager.dao.dto.ChannelSourceInfo;
7 7 import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce;
  8 +import com.genersoft.iot.vmp.web.gb28181.dto.DeviceChannelExtend;
8 9 import com.github.pagehelper.PageInfo;
9 10  
10 11 import java.util.List;
... ... @@ -58,7 +59,7 @@ public interface IVideoManagerStorage {
58 59 */
59 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 375 void cleanContentForPlatform(String serverGBId);
375 376  
376 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 5 import com.genersoft.iot.vmp.gb28181.bean.DeviceChannelInPlatform;
6 6 import com.genersoft.iot.vmp.vmanager.bean.ResourceBaceInfo;
7 7 import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce;
  8 +import com.genersoft.iot.vmp.web.gb28181.dto.DeviceChannelExtend;
8 9 import org.apache.ibatis.annotations.*;
9 10 import org.springframework.stereotype.Repository;
10 11  
... ... @@ -82,7 +83,56 @@ public interface DeviceChannelMapper {
82 83 "</foreach> </if>" +
83 84 "ORDER BY dc.channelId " +
84 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 137 @Select("SELECT * FROM device_channel WHERE deviceId=#{deviceId} AND channelId=#{channelId}")
88 138 DeviceChannel queryChannel(String deviceId, String channelId);
... ... @@ -245,28 +295,6 @@ public interface DeviceChannelMapper {
245 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 298 @Select("SELECT * FROM device_channel WHERE deviceId=#{deviceId} AND status=1")
271 299 List<DeviceChannel> queryOnlineChannelsByDeviceId(String deviceId);
272 300  
... ... @@ -316,10 +344,10 @@ public interface DeviceChannelMapper {
316 344 "select * " +
317 345 "from device_channel " +
318 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 348 " <if test='parentId == null and length != null' > and parentId = #{parentId} or length(channelId)=#{length} </if>" +
321 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 351 " </script>"})
324 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 39 "mobilePositionSubmissionInterval," +
40 40 "subscribeCycleForAlarm," +
41 41 "ssrcCheck," +
  42 + "asMessageChannel," +
42 43 "geoCoordSys," +
43 44 "treeType," +
44   - "online" +
  45 + "online," +
  46 + "mediaServerId," +
  47 + "(SELECT count(0) FROM device_channel WHERE deviceId=device.deviceId) as channelCount "+
45 48 " FROM device WHERE deviceId = #{deviceId}")
46 49 Device getDeviceByDeviceId(String deviceId);
47 50  
... ... @@ -70,6 +73,7 @@ public interface DeviceMapper {
70 73 "mobilePositionSubmissionInterval," +
71 74 "subscribeCycleForAlarm," +
72 75 "ssrcCheck," +
  76 + "asMessageChannel," +
73 77 "geoCoordSys," +
74 78 "treeType," +
75 79 "online" +
... ... @@ -98,6 +102,7 @@ public interface DeviceMapper {
98 102 "#{mobilePositionSubmissionInterval}," +
99 103 "#{subscribeCycleForAlarm}," +
100 104 "#{ssrcCheck}," +
  105 + "#{asMessageChannel}," +
101 106 "#{geoCoordSys}," +
102 107 "#{treeType}," +
103 108 "#{online}" +
... ... @@ -152,9 +157,11 @@ public interface DeviceMapper {
152 157 "mobilePositionSubmissionInterval," +
153 158 "subscribeCycleForAlarm," +
154 159 "ssrcCheck," +
  160 + "asMessageChannel," +
155 161 "geoCoordSys," +
156 162 "treeType," +
157 163 "online," +
  164 + "mediaServerId," +
158 165 "(SELECT count(0) FROM device_channel WHERE deviceId=de.deviceId) as channelCount FROM device de" +
159 166 "<if test=\"online != null\"> where online=${online}</if>"+
160 167 " </script>"
... ... @@ -164,9 +171,6 @@ public interface DeviceMapper {
164 171 @Delete("DELETE FROM device WHERE deviceId=#{deviceId}")
165 172 int del(String deviceId);
166 173  
167   - @Update("UPDATE device SET online=0")
168   - int outlineForAll();
169   -
170 174 @Select("SELECT " +
171 175 "deviceId, " +
172 176 "coalesce(custom_name, name) as name, " +
... ... @@ -192,6 +196,7 @@ public interface DeviceMapper {
192 196 "mobilePositionSubmissionInterval," +
193 197 "subscribeCycleForAlarm," +
194 198 "ssrcCheck," +
  199 + "asMessageChannel," +
195 200 "geoCoordSys," +
196 201 "treeType," +
197 202 "online " +
... ... @@ -222,6 +227,7 @@ public interface DeviceMapper {
222 227 "mobilePositionSubmissionInterval," +
223 228 "subscribeCycleForAlarm," +
224 229 "ssrcCheck," +
  230 + "asMessageChannel," +
225 231 "geoCoordSys," +
226 232 "treeType," +
227 233 "online" +
... ... @@ -243,12 +249,13 @@ public interface DeviceMapper {
243 249 "<if test=\"mobilePositionSubmissionInterval != null\">, mobilePositionSubmissionInterval=#{mobilePositionSubmissionInterval}</if>" +
244 250 "<if test=\"subscribeCycleForAlarm != null\">, subscribeCycleForAlarm=#{subscribeCycleForAlarm}</if>" +
245 251 "<if test=\"ssrcCheck != null\">, ssrcCheck=#{ssrcCheck}</if>" +
  252 + "<if test=\"asMessageChannel != null\">, asMessageChannel=#{asMessageChannel}</if>" +
246 253 "<if test=\"geoCoordSys != null\">, geoCoordSys=#{geoCoordSys}</if>" +
247 254 "<if test=\"treeType != null\">, treeType=#{treeType}</if>" +
248 255 "<if test=\"mediaServerId != null\">, mediaServerId=#{mediaServerId}</if>" +
249 256 "WHERE deviceId=#{deviceId}"+
250 257 " </script>"})
251   - int updateCustom(Device device);
  258 + void updateCustom(Device device);
252 259  
253 260 @Insert("INSERT INTO device (" +
254 261 "deviceId, " +
... ... @@ -259,9 +266,11 @@ public interface DeviceMapper {
259 266 "updateTime," +
260 267 "charset," +
261 268 "ssrcCheck," +
  269 + "asMessageChannel," +
262 270 "geoCoordSys," +
263 271 "treeType," +
264   - "online" +
  272 + "online," +
  273 + "mediaServerId" +
265 274 ") VALUES (" +
266 275 "#{deviceId}," +
267 276 "#{name}," +
... ... @@ -271,9 +280,11 @@ public interface DeviceMapper {
271 280 "#{updateTime}," +
272 281 "#{charset}," +
273 282 "#{ssrcCheck}," +
  283 + "#{asMessageChannel}," +
274 284 "#{geoCoordSys}," +
275 285 "#{treeType}," +
276   - "#{online}" +
  286 + "#{online}," +
  287 + "#{mediaServerId}" +
277 288 ")")
278 289 void addCustomDevice(Device device);
279 290  
... ... @@ -282,4 +293,7 @@ public interface DeviceMapper {
282 293  
283 294 @Select("select * from device")
284 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 15 public interface ParentPlatformMapper {
16 16  
17 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 19 " status, startOfflinePush, catalogId, administrativeDivision, catalogGroup, createTime, updateTime, treeType) " +
20 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 22 " #{status}, #{startOfflinePush}, #{catalogId}, #{administrativeDivision}, #{catalogGroup}, #{createTime}, #{updateTime}, #{treeType})")
23 23 int addParentPlatform(ParentPlatform parentPlatform);
24 24  
... ... @@ -40,6 +40,7 @@ public interface ParentPlatformMapper {
40 40 "characterSet=#{characterSet}, " +
41 41 "ptz=#{ptz}, " +
42 42 "rtcp=#{rtcp}, " +
  43 + "asMessageChannel=#{asMessageChannel}, " +
43 44 "status=#{status}, " +
44 45 "startOfflinePush=#{startOfflinePush}, " +
45 46 "catalogGroup=#{catalogGroup}, " +
... ... @@ -68,9 +69,12 @@ public interface ParentPlatformMapper {
68 69 "FROM parent_platform pp ")
69 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 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 78 @Select("SELECT * FROM parent_platform WHERE serverGBId=#{platformGbId}")
75 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 177 @Override
178 178 public boolean startDownload(StreamInfo stream, String callId) {
179 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 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 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 189 return result;
188 190 }
... ... @@ -617,7 +619,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
617 619 stream,
618 620 callId
619 621 );
620   - List<Object> streamInfoScan = RedisUtil.scan(key);
  622 + List<Object> streamInfoScan = RedisUtil.scan2(key);
621 623 if (streamInfoScan.size() > 0) {
622 624 return (StreamInfo) RedisUtil.get((String) streamInfoScan.get(0));
623 625 }else {
... ... @@ -855,7 +857,8 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
855 857  
856 858 @Override
857 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 862 logger.info("[redis发送通知] 报警{}: {}", key, JSON.toJSON(msg));
860 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 13 import com.genersoft.iot.vmp.storager.dao.dto.ChannelSourceInfo;
14 14 import com.genersoft.iot.vmp.utils.DateUtil;
15 15 import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce;
  16 +import com.genersoft.iot.vmp.web.gb28181.dto.DeviceChannelExtend;
16 17 import com.github.pagehelper.PageHelper;
17 18 import com.github.pagehelper.PageInfo;
18 19 import org.slf4j.Logger;
... ... @@ -189,7 +190,7 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
189 190 dataSourceTransactionManager.commit(transactionStatus); //手动提交
190 191 return true;
191 192 }catch (Exception e) {
192   - e.printStackTrace();
  193 + logger.error("未处理的异常 ", e);
193 194 dataSourceTransactionManager.rollback(transactionStatus);
194 195 return false;
195 196 }
... ... @@ -305,7 +306,7 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
305 306 }
306 307 return true;
307 308 }catch (Exception e) {
308   - e.printStackTrace();
  309 + logger.error("未处理的异常 ", e);
309 310 dataSourceTransactionManager.rollback(transactionStatus);
310 311 return false;
311 312 }
... ... @@ -359,8 +360,8 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
359 360 }
360 361  
361 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 371 }
371 372  
372 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 379 public PageInfo<DeviceChannel> querySubChannels(String deviceId, String parentChannelId, String query, Boolean hasSubChannel, Boolean online, int page, int count) {
374 380 PageHelper.startPage(page, count);
375 381 List<DeviceChannel> all = deviceChannelMapper.queryChannels(deviceId, parentChannelId, query, hasSubChannel, online,null);
... ... @@ -512,6 +518,16 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
512 518 }
513 519  
514 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 531 public void outlineForAllParentPlatform() {
516 532 platformMapper.outlineForAllParentPlatform();
517 533 }
... ...
src/main/java/com/genersoft/iot/vmp/utils/DateUtil.java
... ... @@ -45,7 +45,6 @@ public class DateUtil {
45 45  
46 46 public static String ISO8601Toyyyy_MM_dd_HH_mm_ss(String formatTime) {
47 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 881  
882 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 892 public static void convertAndSend(String channel, JSONObject msg) {
887 893 if (redisTemplate == null) {
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/bean/WVPResult.java
... ... @@ -28,6 +28,10 @@ public class WVPResult&lt;T&gt; implements Cloneable{
28 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 35 public static <T> WVPResult<T> success(T t) {
32 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 30 * 位置信息管理
31 31 */
32 32 @Tag(name = "位置信息管理")
33   -@CrossOrigin
  33 +
34 34 @RestController
35 35 @RequestMapping("/api/position")
36 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 17 * @data: 2021-01-20
18 18 */
19 19 @Tag(name = "SSE推送")
20   -@CrossOrigin
  20 +
21 21 @Controller
22 22 @RequestMapping("/api")
23 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 6 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
7 7 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
8 8 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
9   -import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookListener;
10 9 import com.genersoft.iot.vmp.service.IDeviceAlarmService;
11 10 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
12 11 import com.genersoft.iot.vmp.utils.DateUtil;
13 12 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
14   -import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
15 13 import com.github.pagehelper.PageInfo;
16 14 import io.swagger.v3.oas.annotations.Operation;
17 15 import io.swagger.v3.oas.annotations.Parameter;
18   -import io.swagger.v3.oas.annotations.responses.ApiResponse;
19 16 import io.swagger.v3.oas.annotations.tags.Tag;
20 17 import org.slf4j.Logger;
21 18 import org.slf4j.LoggerFactory;
22 19 import org.springframework.beans.factory.annotation.Autowired;
23   -import org.springframework.http.HttpStatus;
24   -import org.springframework.http.ResponseEntity;
25 20 import org.springframework.util.ObjectUtils;
26   -import org.springframework.util.StringUtils;
27 21 import org.springframework.web.bind.annotation.*;
28 22  
29 23 import javax.sip.InvalidArgumentException;
30 24 import javax.sip.SipException;
31 25 import java.text.ParseException;
32   -import java.time.LocalDateTime;
33 26 import java.util.Arrays;
34 27 import java.util.List;
35 28  
36 29 @Tag(name = "报警信息管理")
37   -@CrossOrigin
  30 +
38 31 @RestController
39 32 @RequestMapping("/api/alarm")
40 33 public class AlarmController {
... ... @@ -78,11 +71,11 @@ public class AlarmController {
78 71 if (ObjectUtils.isEmpty(deviceIds)) {
79 72 deviceIds = null;
80 73 }
  74 +
81 75 if (ObjectUtils.isEmpty(time)) {
82 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 80 List<String> deviceIdList = null;
88 81 if (deviceIds != null) {
... ... @@ -110,7 +103,7 @@ public class AlarmController {
110 103 deviceAlarm.setAlarmDescription("test");
111 104 deviceAlarm.setAlarmMethod("1");
112 105 deviceAlarm.setAlarmPriority("1");
113   - deviceAlarm.setAlarmTime(DateUtil.formatterISO8601.format(LocalDateTime.now()));
  106 + deviceAlarm.setAlarmTime(DateUtil.getNow());
114 107 deviceAlarm.setAlarmType("1");
115 108 deviceAlarm.setLongitude(115.33333);
116 109 deviceAlarm.setLatitude(39.33333);
... ... @@ -177,16 +170,17 @@ public class AlarmController {
177 170 if (ObjectUtils.isEmpty(alarmType)) {
178 171 alarmType = null;
179 172 }
  173 +
180 174 if (ObjectUtils.isEmpty(startTime)) {
181 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 180 if (ObjectUtils.isEmpty(endTime)) {
184 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 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 14 import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
15 15 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
16 16 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
17   -
18 17 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
19 18 import io.swagger.v3.oas.annotations.Operation;
20 19 import io.swagger.v3.oas.annotations.Parameter;
... ... @@ -22,9 +21,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
22 21 import org.slf4j.Logger;
23 22 import org.slf4j.LoggerFactory;
24 23 import org.springframework.beans.factory.annotation.Autowired;
25   -import org.springframework.http.ResponseEntity;
26 24 import org.springframework.util.ObjectUtils;
27   -import org.springframework.util.StringUtils;
28 25 import org.springframework.web.bind.annotation.*;
29 26 import org.springframework.web.context.request.async.DeferredResult;
30 27  
... ... @@ -34,7 +31,6 @@ import java.text.ParseException;
34 31 import java.util.UUID;
35 32  
36 33 @Tag(name = "国标设备配置")
37   -@CrossOrigin
38 34 @RestController
39 35 @RequestMapping("/api/device/config")
40 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 32 import java.util.UUID;
33 33  
34 34 @Tag(name = "国标设备控制")
35   -@CrossOrigin
  35 +
36 36 @RestController
37 37 @RequestMapping("/api/device/control")
38 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 24 import io.swagger.v3.oas.annotations.Parameter;
25 25 import io.swagger.v3.oas.annotations.tags.Tag;
26 26 import org.apache.commons.compress.utils.IOUtils;
  27 +import org.apache.ibatis.annotations.Options;
27 28 import org.slf4j.Logger;
28 29 import org.slf4j.LoggerFactory;
29 30 import org.springframework.beans.factory.annotation.Autowired;
... ... @@ -46,7 +47,7 @@ import java.util.*;
46 47  
47 48 @Tag(name = "国标设备查询", description = "国标设备查询")
48 49 @SuppressWarnings("rawtypes")
49   -@CrossOrigin
  50 +
50 51 @RestController
51 52 @RequestMapping("/api/device/query")
52 53 public class DeviceQuery {
... ... @@ -97,8 +98,10 @@ public class DeviceQuery {
97 98 @Parameter(name = "page", description = "当前页", required = true)
98 99 @Parameter(name = "count", description = "每页查询数量", required = true)
99 100 @GetMapping("/devices")
  101 + @Options()
100 102 public PageInfo<Device> devices(int page, int count){
101   -
  103 +// if (page == null) page = 0;
  104 +// if (count == null) count = 20;
102 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 17 import java.util.List;
18 18  
19 19 @Tag(name = "视频流关联到级联平台")
20   -@CrossOrigin
  20 +
21 21 @RestController
22 22 @RequestMapping("/api/gbStream")
23 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 24  
25 25 @Tag(name = "媒体流相关")
26 26 @Controller
27   -@CrossOrigin
  27 +
28 28 @RequestMapping(value = "/api/media")
29 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 7 import com.genersoft.iot.vmp.conf.UserSetting;
8 8 import com.genersoft.iot.vmp.conf.exception.ControllerException;
9 9 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
  10 +import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch;
10 11 import com.genersoft.iot.vmp.gb28181.bean.PlatformCatalog;
11 12 import com.genersoft.iot.vmp.gb28181.bean.SubscribeHolder;
12 13 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
... ... @@ -37,7 +38,7 @@ import java.util.List;
37 38 * 级联平台管理
38 39 */
39 40 @Tag(name = "级联平台管理")
40   -@CrossOrigin
  41 +
41 42 @RestController
42 43 @RequestMapping("/api/platform")
43 44 public class PlatformController {
... ... @@ -205,58 +206,8 @@ public class PlatformController {
205 206 ) {
206 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 230 throw new ControllerException(ErrorCode.ERROR400);
280 231 }
281 232 ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(serverGBId);
  233 + ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(serverGBId);
282 234 if (parentPlatform == null) {
283 235 throw new ControllerException(ErrorCode.ERROR100.getCode(), "平台不存在");
284 236 }
  237 + if (parentPlatformCatch == null) {
  238 + throw new ControllerException(ErrorCode.ERROR100.getCode(), "平台不存在");
  239 + }
285 240 // 发送离线消息,无论是否成功都删除缓存
286 241 try {
287   - commanderForPlatform.unregister(parentPlatform, (event -> {
  242 + commanderForPlatform.unregister(parentPlatform, parentPlatformCatch.getSipTransactionInfo(), (event -> {
288 243 // 清空redis缓存
289 244 redisCatchStorage.delPlatformCatchInfo(parentPlatform.getServerGBId());
290 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 41 * @author lin
42 42 */
43 43 @Tag(name = "国标设备点播")
44   -@CrossOrigin
  44 +
45 45 @RestController
46 46 @RequestMapping("/api/play")
47 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 40 * @author lin
41 41 */
42 42 @Tag(name = "视频回放")
43   -@CrossOrigin
  43 +
44 44 @RestController
45 45 @RequestMapping("/api/playback")
46 46 public class PlaybackController {
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/ptz/PtzController.java
1 1 package com.genersoft.iot.vmp.vmanager.gb28181.ptz;
2 2  
3   -
  3 +
4 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 10 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
6 11 import io.swagger.v3.oas.annotations.Operation;
7 12 import io.swagger.v3.oas.annotations.Parameter;
... ... @@ -10,23 +15,16 @@ import org.slf4j.Logger;
10 15 import org.slf4j.LoggerFactory;
11 16 import org.springframework.beans.factory.annotation.Autowired;
12 17 import org.springframework.util.ObjectUtils;
13   -import org.springframework.util.StringUtils;
14 18 import org.springframework.web.bind.annotation.*;
15 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 21 import javax.sip.InvalidArgumentException;
24 22 import javax.sip.SipException;
25 23 import java.text.ParseException;
26 24 import java.util.UUID;
27 25  
28 26 @Tag(name = "云台控制")
29   -@CrossOrigin
  27 +
30 28 @RestController
31 29 @RequestMapping("/api/ptz")
32 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 3 import com.genersoft.iot.vmp.common.StreamInfo;
4 4 import com.genersoft.iot.vmp.conf.exception.ControllerException;
5 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 9 import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
  10 +import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
7 11 import com.genersoft.iot.vmp.service.IDeviceService;
8 12 import com.genersoft.iot.vmp.service.IPlayService;
  13 +import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
9 14 import com.genersoft.iot.vmp.utils.DateUtil;
10 15 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
11 16 import com.genersoft.iot.vmp.vmanager.bean.StreamContent;
12 17 import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
13   -
14 18 import io.swagger.v3.oas.annotations.Operation;
15 19 import io.swagger.v3.oas.annotations.Parameter;
16 20 import io.swagger.v3.oas.annotations.tags.Tag;
17 21 import org.slf4j.Logger;
18 22 import org.slf4j.LoggerFactory;
19 23 import org.springframework.beans.factory.annotation.Autowired;
20   -import org.springframework.web.bind.annotation.CrossOrigin;
21 24 import org.springframework.web.bind.annotation.GetMapping;
22 25 import org.springframework.web.bind.annotation.PathVariable;
23 26 import org.springframework.web.bind.annotation.RequestMapping;
24 27 import org.springframework.web.bind.annotation.RestController;
25 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 30 import javax.sip.InvalidArgumentException;
34 31 import javax.sip.SipException;
35 32 import java.text.ParseException;
36 33 import java.util.UUID;
37 34  
38 35 @Tag(name = "国标录像")
39   -@CrossOrigin
  36 +
40 37 @RestController
41 38 @RequestMapping("/api/gb_record")
42 39 public class GBRecordController {
... ... @@ -74,10 +71,10 @@ public class GBRecordController {
74 71 }
75 72 DeferredResult<WVPResult<RecordInfo>> result = new DeferredResult<>();
76 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 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 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 6 import com.genersoft.iot.vmp.storager.dao.dto.LogDto;
7 7 import com.genersoft.iot.vmp.utils.DateUtil;
8 8 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
9   -import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
10 9 import com.github.pagehelper.PageInfo;
11   -
12 10 import io.swagger.v3.oas.annotations.Operation;
13 11 import io.swagger.v3.oas.annotations.Parameter;
14 12 import io.swagger.v3.oas.annotations.tags.Tag;
15 13 import org.slf4j.Logger;
16 14 import org.slf4j.LoggerFactory;
17 15 import org.springframework.beans.factory.annotation.Autowired;
18   -import org.springframework.http.HttpStatus;
19   -import org.springframework.http.ResponseEntity;
20 16 import org.springframework.util.ObjectUtils;
21   -import org.springframework.util.StringUtils;
22 17 import org.springframework.web.bind.annotation.*;
23 18  
24   -import java.text.ParseException;
25   -
26 19 @Tag(name = "日志管理")
27   -@CrossOrigin
  20 +
28 21 @RestController
29 22 @RequestMapping("/api/log")
30 23 public class LogController {
... ... @@ -67,18 +60,21 @@ public class LogController {
67 60 if (ObjectUtils.isEmpty(query)) {
68 61 query = null;
69 62 }
  63 +
  64 + if (!userSetting.getLogInDatebase()) {
  65 + logger.warn("自动记录日志功能已关闭,查询结果可能不完整。");
  66 + }
  67 +
70 68 if (ObjectUtils.isEmpty(startTime)) {
71 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 74 if (ObjectUtils.isEmpty(endTime)) {
74 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 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 14 //import org.springframework.web.bind.annotation.*;
15 15 //
16 16 //@Tag(name = "云端录像")
17   -//@CrossOrigin
  17 +//
18 18 //@RestController
19 19 //@RequestMapping("/api/record")
20 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 2  
3 3 import com.alibaba.fastjson2.JSON;
4 4 import com.alibaba.fastjson2.JSONObject;
5   -import com.genersoft.iot.vmp.VManageBootstrap;
6 5 import com.genersoft.iot.vmp.common.SystemAllInfo;
7 6 import com.genersoft.iot.vmp.common.VersionPo;
8 7 import com.genersoft.iot.vmp.conf.SipConfig;
... ... @@ -15,30 +14,24 @@ import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
15 14 import com.genersoft.iot.vmp.service.*;
16 15 import com.genersoft.iot.vmp.service.bean.MediaServerLoad;
17 16 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
18   -import com.genersoft.iot.vmp.utils.SpringBeanFactory;
19 17 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
20 18 import com.genersoft.iot.vmp.vmanager.bean.ResourceBaceInfo;
21 19 import com.genersoft.iot.vmp.vmanager.bean.ResourceInfo;
22 20 import com.genersoft.iot.vmp.vmanager.bean.SystemConfigInfo;
23   -import gov.nist.javax.sip.SipStackImpl;
24   -
25 21 import io.swagger.v3.oas.annotations.Operation;
26 22 import io.swagger.v3.oas.annotations.Parameter;
27 23 import io.swagger.v3.oas.annotations.tags.Tag;
28 24 import org.springframework.beans.factory.annotation.Autowired;
29 25 import org.springframework.beans.factory.annotation.Value;
30   -import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
31 26 import org.springframework.util.ObjectUtils;
32 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 32 @SuppressWarnings("rawtypes")
40 33 @Tag(name = "服务控制")
41   -@CrossOrigin
  34 +
42 35 @RestController
43 36 @RequestMapping("/api/server")
44 37 public class ServerController {
... ... @@ -77,9 +70,6 @@ public class ServerController {
77 70  
78 71  
79 72 @Autowired
80   - private ThreadPoolTaskExecutor taskExecutor;
81   -
82   - @Autowired
83 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 25 */
26 26 @Tag(name = "拉流代理", description = "")
27 27 @Controller
28   -@CrossOrigin
  28 +
29 29 @RequestMapping(value = "/api/proxy")
30 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 41  
42 42 @Tag(name = "推流信息管理")
43 43 @Controller
44   -@CrossOrigin
  44 +
45 45 @RequestMapping(value = "/api/push")
46 46 public class StreamPushController {
47 47  
... ... @@ -181,7 +181,7 @@ public class StreamPushController {
181 181 String name = file.getName();
182 182 inputStream = file.getInputStream();
183 183 } catch (IOException e) {
184   - e.printStackTrace();
  184 + logger.error("未处理的异常 ", e);
185 185 }
186 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 6 import com.genersoft.iot.vmp.storager.dao.dto.Role;
7 7 import com.genersoft.iot.vmp.utils.DateUtil;
8 8 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
9   -import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
10   -
11 9 import io.swagger.v3.oas.annotations.Operation;
12 10 import io.swagger.v3.oas.annotations.Parameter;
13 11 import io.swagger.v3.oas.annotations.tags.Tag;
14 12 import org.springframework.beans.factory.annotation.Autowired;
15   -import org.springframework.http.HttpStatus;
16   -import org.springframework.http.ResponseEntity;
17 13 import org.springframework.web.bind.annotation.*;
18 14  
19 15 import java.util.List;
20 16  
21 17 @Tag(name = "角色管理")
22   -@CrossOrigin
  18 +
23 19 @RestController
24 20 @RequestMapping("/api/role")
25 21 public class RoleController {
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/user/UserController.java
1 1 package com.genersoft.iot.vmp.vmanager.user;
2 2  
3 3 import com.genersoft.iot.vmp.conf.exception.ControllerException;
  4 +import com.genersoft.iot.vmp.conf.security.JwtUtils;
4 5 import com.genersoft.iot.vmp.conf.security.SecurityUtils;
5 6 import com.genersoft.iot.vmp.conf.security.dto.LoginUser;
6 7 import com.genersoft.iot.vmp.service.IRoleService;
... ... @@ -21,10 +22,11 @@ import org.springframework.util.ObjectUtils;
21 22 import org.springframework.web.bind.annotation.*;
22 23  
23 24 import javax.security.sasl.AuthenticationException;
  25 +import javax.servlet.http.HttpServletRequest;
  26 +import javax.servlet.http.HttpServletResponse;
24 27 import java.util.List;
25 28  
26 29 @Tag(name = "用户管理")
27   -@CrossOrigin
28 30 @RestController
29 31 @RequestMapping("/api/user")
30 32 public class UserController {
... ... @@ -40,11 +42,13 @@ public class UserController {
40 42  
41 43 @GetMapping("/login")
42 44 @PostMapping("/login")
43   - @Operation(summary = "登录")
  45 + @Operation(summary = "登录", description = "登录成功后返回AccessToken, 可以从返回值获取到也可以从响应头中获取到," +
  46 + "后续的请求需要添加请求头 'access-token'或者放在参数里")
  47 +
44 48 @Parameter(name = "username", description = "用户名", required = true)
45 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 52 try {
49 53 user = SecurityUtils.login(username, password, authenticationManager);
50 54 } catch (AuthenticationException e) {
... ... @@ -52,10 +56,15 @@ public class UserController {
52 56 }
53 57 if (user == null) {
54 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 64 return user;
57 65 }
58 66  
  67 +
59 68 @PostMapping("/changePassword")
60 69 @Operation(summary = "修改密码")
61 70 @Parameter(name = "username", description = "用户名", required = true)
... ... @@ -74,8 +83,8 @@ public class UserController {
74 83 if (user == null) {
75 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 88 if (!result) {
80 89 throw new ControllerException(ErrorCode.ERROR100);
81 90 }
... ...
src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiControlController.java
1 1 package com.genersoft.iot.vmp.web.gb28181;
2 2  
3   -import com.alibaba.fastjson2.JSONObject;
4 3 import com.genersoft.iot.vmp.conf.exception.ControllerException;
5 4 import com.genersoft.iot.vmp.gb28181.bean.Device;
6 5 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
... ... @@ -9,7 +8,9 @@ import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
9 8 import org.slf4j.Logger;
10 9 import org.slf4j.LoggerFactory;
11 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 15 import javax.sip.InvalidArgumentException;
15 16 import javax.sip.SipException;
... ... @@ -18,7 +19,7 @@ import java.text.ParseException;
18 19 /**
19 20 * API兼容:设备控制
20 21 */
21   -@CrossOrigin
  22 +
22 23 @RestController
23 24 @RequestMapping(value = "/api/v1/control")
24 25 public class ApiControlController {
... ... @@ -102,4 +103,53 @@ public class ApiControlController {
102 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 6 import org.slf4j.LoggerFactory;
7 7 import org.springframework.beans.factory.annotation.Autowired;
8 8 import org.springframework.stereotype.Controller;
9   -import org.springframework.web.bind.annotation.CrossOrigin;
10 9 import org.springframework.web.bind.annotation.RequestMapping;
11 10 import org.springframework.web.bind.annotation.ResponseBody;
12 11  
... ... @@ -14,7 +13,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
14 13 * API兼容:系统接口
15 14 */
16 15 @Controller
17   -@CrossOrigin
  16 +
18 17 @RequestMapping(value = "/api/v1")
19 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 2  
3 3 import com.alibaba.fastjson2.JSONArray;
4 4 import com.alibaba.fastjson2.JSONObject;
  5 +import com.genersoft.iot.vmp.conf.exception.ControllerException;
5 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 11 import com.genersoft.iot.vmp.service.IDeviceService;
8 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 16 import com.github.pagehelper.PageInfo;
10 17 import org.slf4j.Logger;
11 18 import org.slf4j.LoggerFactory;
12 19 import org.springframework.beans.factory.annotation.Autowired;
  20 +import org.springframework.util.ObjectUtils;
13 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 33 * API兼容:设备信息
21 34 */
22 35 @SuppressWarnings("unchecked")
23   -@CrossOrigin
  36 +
24 37 @RestController
25 38 @RequestMapping(value = "/api/v1/device")
26 39 public class ApiDeviceController {
... ... @@ -29,17 +42,15 @@ public class ApiDeviceController {
29 42  
30 43 @Autowired
31 44 private IVideoManagerStorage storager;
  45 +
  46 + @Autowired
  47 + private SIPCommander cmder;
32 48 @Autowired
33 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 107  
97 108 @RequestMapping(value = "/channellist")
98 109 public JSONObject channellist( String serial,
99   - @RequestParam(required = false)String code,
100 110 @RequestParam(required = false)String channel_type,
  111 + @RequestParam(required = false)String code ,
101 112 @RequestParam(required = false)String dir_serial ,
102 113 @RequestParam(required = false)Integer start,
103 114 @RequestParam(required = false)Integer limit,
... ... @@ -109,64 +120,138 @@ public class ApiDeviceController {
109 120 // }
110 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 130 List<String> channelIds = null;
120 131 if (!StringUtils.isEmpty(code)) {
121 132 String[] split = code.trim().split(",");
122 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 136 if (start == null || limit ==null) {
126 137 deviceChannels = allDeviceChannelList;
127 138 result.put("ChannelCount", deviceChannels.size());
128 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 141 int total = allDeviceChannelList.size();
131 142 result.put("ChannelCount", total);
132 143 }
133 144  
134 145 JSONArray channleJSONList = new JSONArray();
135   - for (DeviceChannel deviceChannel : deviceChannels) {
  146 + for (DeviceChannelExtend deviceChannelExtend : deviceChannels) {
136 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 154 deviceJOSNChannel.put("Custom", false);
144 155 deviceJOSNChannel.put("CustomName", "");
145   - deviceJOSNChannel.put("SubCount", deviceChannel.getSubCount()); // 子节点数, SubCount > 0 表示该通道为子目录
  156 + deviceJOSNChannel.put("SubCount", deviceChannelExtend.getSubCount()); // TODO ? 子节点数, SubCount > 0 表示该通道为子目录
146 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 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 175 deviceJOSNChannel.put("CustomPTZType", "");
165   - deviceJOSNChannel.put("StreamID", deviceChannel.getStreamId()); // StreamID 直播流ID, 有值表示正在直播
  176 + deviceJOSNChannel.put("StreamID", deviceChannelExtend.getStreamId()); // StreamID 直播流ID, 有值表示正在直播
166 177 deviceJOSNChannel.put("NumOutputs ", -1); // 直播在线人数
167 178 channleJSONList.add(deviceJOSNChannel);
168 179 }
169 180 result.put("ChannelList", channleJSONList);
170 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 26 * API兼容:实时直播
27 27 */
28 28 @SuppressWarnings(value = {"rawtypes", "unchecked"})
29   -@CrossOrigin
  29 +
30 30 @RestController
31 31 @RequestMapping(value = "/api/v1/stream")
32 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 5 import org.springframework.beans.factory.annotation.Autowired;
6 6 import org.springframework.web.bind.annotation.*;
7 7  
8   -@CrossOrigin
  8 +
9 9 @RestController
10 10 @RequestMapping(value = "/auth")
11 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 30 poolMaxWait: 5
31 31 # [必选] jdbc数据库配置
32 32 datasource:
33   - type: com.alibaba.druid.pool.DruidDataSource
  33 + type: com.zaxxer.hikari.HikariDataSource
34 34 driver-class-name: com.mysql.cj.jdbc.Driver
35 35 url: jdbc:mysql://127.0.0.1:3306/wvp2?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&serverTimezone=PRC&useSSL=false&allowMultiQueries=true
36 36 username: root
37 37 password: root123
38   - druid:
  38 + hikari:
  39 + connection-timeout: 20000 # 是客户端等待连接池连接的最大毫秒数
39 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 47 # [可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口
73 48 server:
... ... @@ -90,10 +65,10 @@ server:
90 65  
91 66 # 作为28181服务器的配置
92 67 sip:
93   - # [必须修改] 本机的IP, 必须是网卡上的IP,用于sip下协议栈监听ip,如果监听所有设置为0.0.0.0
94   - monitor-ip: 0.0.0.0
95 68 # [必须修改] 本机的IP
96 69 ip: 192.168.0.100
  70 + # [可选] 没有任何业务需求,仅仅是在前端展示的时候用
  71 + show-ip: 192.168.0.100
97 72 # [可选] 28181服务监听的端口
98 73 port: 5060
99 74 # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007)
... ... @@ -203,6 +178,14 @@ user-settings:
203 178 sip-log: true
204 179 # 收到ack消息后开始发流,默认false, 回复200ok后直接开始发流
205 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 191 springdoc:
... ...
web_src/build/utils.js
... ... @@ -47,8 +47,7 @@ exports.cssLoaders = function (options) {
47 47 if (options.extract) {
48 48 return ExtractTextPlugin.extract({
49 49 use: loaders,
50   - fallback: 'vue-style-loader',
51   - publicPath: '../../'
  50 + fallback: 'vue-style-loader'
52 51 })
53 52 } else {
54 53 return ['vue-style-loader'].concat(loaders)
... ...
web_src/config/index.js
... ... @@ -8,8 +8,8 @@ module.exports = {
8 8 dev: {
9 9  
10 10 // Paths
11   - assetsSubDirectory: './static',
12   - assetsPublicPath: './',
  11 + assetsSubDirectory: 'static',
  12 + assetsPublicPath: '/',
13 13 proxyTable: {
14 14 '/debug': {
15 15 target: 'https://default.wvp-pro.cn:18082',
... ... @@ -61,7 +61,7 @@ module.exports = {
61 61 // Paths
62 62 assetsRoot: path.resolve(__dirname, '../../src/main/resources/static/'),
63 63 assetsSubDirectory: './static',
64   - assetsPublicPath: './',
  64 + assetsPublicPath: '/',
65 65  
66 66 /**
67 67 * Source Maps
... ...
web_src/index.html
... ... @@ -13,7 +13,8 @@
13 13 <script type="text/javascript" src="./static/js/EasyWasmPlayer.js"></script>
14 14 <script type="text/javascript" src="./static/js/liveplayer-lib.min.js"></script>
15 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 17 <div id="app"></div>
  18 +
18 19 </body>
19 20 </html>
... ...
web_src/package-lock.json
... ... @@ -23,7 +23,7 @@
23 23 "vue-clipboard2": "^0.3.1",
24 24 "vue-clipboards": "^1.3.0",
25 25 "vue-contextmenujs": "^1.3.13",
26   - "vue-cookies": "^1.7.4",
  26 + "vue-cookies": "^1.8.3",
27 27 "vue-giant-tree": "^0.1.5",
28 28 "vue-router": "^3.1.6",
29 29 "vue-ztree-2.0": "^1.0.4"
... ... @@ -13135,9 +13135,9 @@
13135 13135 "integrity": "sha1-O9rgI8e9QgleeNpCWAACUNUKuO8="
13136 13136 },
13137 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 13142 "node_modules/vue-giant-tree": {
13143 13143 "version": "0.1.5",
... ... @@ -25489,9 +25489,9 @@
25489 25489 "integrity": "sha1-O9rgI8e9QgleeNpCWAACUNUKuO8="
25490 25490 },
25491 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 25496 "vue-giant-tree": {
25497 25497 "version": "0.1.5",
... ...
web_src/package.json
... ... @@ -25,7 +25,7 @@
25 25 "vue-clipboard2": "^0.3.1",
26 26 "vue-clipboards": "^1.3.0",
27 27 "vue-contextmenujs": "^1.3.13",
28   - "vue-cookies": "^1.7.4",
  28 + "vue-cookies": "^1.8.3",
29 29 "vue-giant-tree": "^0.1.5",
30 30 "vue-router": "^3.1.6",
31 31 "vue-ztree-2.0": "^1.0.4"
... ...
web_src/src/App.vue
... ... @@ -5,6 +5,7 @@
5 5 </template>
6 6  
7 7 <script>
  8 +import userService from './components/service/UserService'
8 9 export default {
9 10 name: 'app',
10 11 data(){
... ... @@ -19,7 +20,7 @@ export default {
19 20 }
20 21 },
21 22 created() {
22   - if(!this.$cookies.get("session")){
  23 + if (userService.getToken() == null){
23 24 //如果没有登录状态则跳转到登录页
24 25 this.$router.push('/login');
25 26 }
... ... @@ -33,28 +34,14 @@ export default {
33 34 // this.getUserInfo();
34 35 },
35 36 methods: {
36   - //请求用户的一些信息
37   - getUserInfo(){
38   - var userinfo = this.$cookies.get("session");
39   - },
40 37 checkLogin(){
41 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 46 components: {}
60 47 };
... ...
web_src/src/components/CloudRecord.vue
... ... @@ -133,7 +133,7 @@
133 133 let that = this;
134 134 this.$axios({
135 135 method: 'get',
136   - url:`./record_proxy/${that.mediaServerId}/api/record/list`,
  136 + url:`/record_proxy/${that.mediaServerId}/api/record/list`,
137 137 params: {
138 138 page: that.currentPage,
139 139 count: that.count
... ... @@ -185,7 +185,7 @@
185 185 let that = this;
186 186 this.$axios({
187 187 method: 'delete',
188   - url:`./record_proxy/api/record/delete`,
  188 + url:`/record_proxy/api/record/delete`,
189 189 params: {
190 190 page: that.currentPage,
191 191 count: that.count
... ...
web_src/src/components/CloudRecordDetail.vue
... ... @@ -18,7 +18,7 @@
18 18 <i class="el-icon-video-camera" ></i>
19 19 {{ item.substring(0,17)}}
20 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 22 </li>
23 23 </ul>
24 24 </div>
... ... @@ -76,7 +76,7 @@
76 76 <li class="task-list-item" v-for="(item, index) in taskListEnded" :key="index">
77 77 <div class="task-list-item-box" style="height: 2rem;line-height: 2rem;">
78 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 80 </a>
81 81 </div>
82 82 </li>
... ... @@ -107,15 +107,15 @@
107 107 import uiHeader from '../layout/UiHeader.vue'
108 108 import player from './dialog/easyPlayer.vue'
109 109 import moment from 'moment'
  110 + import axios from "axios";
110 111 export default {
111 112 name: 'app',
112 113 components: {
113 114 uiHeader, player
114 115 },
115   - props: ['recordFile', 'mediaServerId', 'dateFiles', 'mediaServerPath'],
  116 + props: ['recordFile', 'mediaServerId', 'dateFiles'],
116 117 data() {
117 118 return {
118   - basePath: `${this.mediaServerPath}`,
119 119 dateFilesObj: [],
120 120 detailFiles: [],
121 121 chooseDate: null,
... ... @@ -220,14 +220,18 @@
220 220 }
221 221 this.queryRecordDetails(()=>{
222 222 if (this.detailFiles.length > 0){
  223 + console.log(this.detailFiles)
223 224 let timeForFile = this.getTimeForFile(this.detailFiles[0]);
224 225 let lastTimeForFile = this.getTimeForFile(this.detailFiles[this.detailFiles.length - 1]);
225 226 let timeNum = timeForFile[0].getTime() - new Date(this.chooseDate + " " + this.timeFormat).getTime()
  227 + console.log(timeNum)
226 228 let lastTimeNum = lastTimeForFile[1].getTime() - new Date(this.chooseDate + " " + this.timeFormat).getTime()
227 229  
228 230 this.playTime = parseInt(timeNum/1000)
229 231 this.sliderMIn = parseInt(timeNum/1000 - timeNum/1000%(60*60))
  232 + console.log(this.sliderMIn )
230 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 245 let that = this;
242 246 that.$axios({
243 247 method: 'get',
244   - url:`./record_proxy/${that.mediaServerId}/api/record/file/list`,
  248 + url:`/record_proxy/${that.mediaServerId}/api/record/file/list`,
245 249 params: {
246 250 app: that.recordFile.app,
247 251 stream: that.recordFile.stream,
... ... @@ -267,13 +271,23 @@
267 271 if (file == null) {
268 272 this.videoUrl = "";
269 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 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 291 getDataWidth(item){
278 292 let timeForFile = this.getTimeForFile(item);
279 293 let result = (timeForFile[2])/((this.sliderMax - this.sliderMIn)*1000)
... ... @@ -301,11 +315,12 @@
301 315 }
302 316 },
303 317 getTimeForFile(file){
  318 + console.log(file)
304 319 let timeStr = file.substring(0,17);
305 320 if(timeStr.indexOf("~") > 0){
306 321 timeStr = timeStr.replaceAll("-",":")
307 322 }
308   - let timeArr = timeStr.split("~");
  323 + let timeArr = timeStr.split("-");
309 324 let starTime = new Date(this.chooseDate + " " + timeArr[0]);
310 325 let endTime = new Date(this.chooseDate + " " + timeArr[1]);
311 326 if(this.checkIsOver24h(starTime,endTime)){
... ... @@ -340,7 +355,7 @@
340 355 let that = this;
341 356 this.$axios({
342 357 method: 'delete',
343   - url:`./record_proxy/${that.mediaServerId}/api/record/delete`,
  358 + url:`/record_proxy/${that.mediaServerId}/api/record/delete`,
344 359 params: {
345 360 page: that.currentPage,
346 361 count: that.count
... ... @@ -359,7 +374,7 @@
359 374 that.dateFilesObj = {};
360 375 this.$axios({
361 376 method: 'get',
362   - url:`./record_proxy/${that.mediaServerId}/api/record/date/list`,
  377 + url:`/record_proxy/${that.mediaServerId}/api/record/date/list`,
363 378 params: {
364 379 app: that.recordFile.app,
365 380 stream: that.recordFile.stream
... ... @@ -408,7 +423,7 @@
408 423 let that = this;
409 424 this.$axios({
410 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 427 params: {
413 428 app: that.recordFile.app,
414 429 stream: that.recordFile.stream,
... ... @@ -433,7 +448,7 @@
433 448 let that = this;
434 449 this.$axios({
435 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 452 params: {
438 453 isEnd: isEnd,
439 454 }
... ...
web_src/src/components/DeviceList.vue
... ... @@ -152,7 +152,7 @@ export default {
152 152 this.getDeviceListLoading = true;
153 153 this.$axios({
154 154 method: 'get',
155   - url: `./api/device/query/devices`,
  155 + url: `/api/device/query/devices`,
156 156 params: {
157 157 page: this.currentPage,
158 158 count: this.count
... ... @@ -182,7 +182,7 @@ export default {
182 182 }).then(() => {
183 183 this.$axios({
184 184 method: 'delete',
185   - url: `./api/device/query/devices/${row.deviceId}/delete`
  185 + url: `/api/device/query/devices/${row.deviceId}/delete`
186 186 }).then((res) => {
187 187 this.getDeviceList();
188 188 }).catch((error) => {
... ... @@ -208,7 +208,7 @@ export default {
208 208 let that = this;
209 209 this.$axios({
210 210 method: 'get',
211   - url: './api/device/query/devices/' + itemData.deviceId + '/sync'
  211 + url: '/api/device/query/devices/' + itemData.deviceId + '/sync'
212 212 }).then((res) => {
213 213 console.log("刷新设备结果:" + JSON.stringify(res));
214 214 if (res.data.code !== 0) {
... ... @@ -242,7 +242,7 @@ export default {
242 242 await this.$axios({
243 243 method: 'get',
244 244 async: false,
245   - url: `./api/device/query/${deviceId}/sync_status/`,
  245 + url: `/api/device/query/${deviceId}/sync_status/`,
246 246 }).then((res) => {
247 247 if (res.data.code == 0) {
248 248 if (res.data.data.errorMsg !== null) {
... ... @@ -261,7 +261,7 @@ export default {
261 261 let that = this;
262 262 this.$axios({
263 263 method: 'post',
264   - url: './api/device/query/transport/' + row.deviceId + '/' + row.streamMode
  264 + url: '/api/device/query/transport/' + row.deviceId + '/' + row.streamMode
265 265 }).then(function (res) {
266 266  
267 267 }).catch(function (e) {
... ...
web_src/src/components/GBRecordDetail.vue
... ... @@ -197,7 +197,7 @@
197 197 this.detailFiles = [];
198 198 this.$axios({
199 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 201 }).then((res)=>{
202 202 this.recordsLoading = false;
203 203 if(res.data.code === 0) {
... ... @@ -249,7 +249,7 @@
249 249 } else {
250 250 this.$axios({
251 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 253 this.endTime
254 254 }).then((res)=> {
255 255 if (res.data.code === 0) {
... ... @@ -273,7 +273,7 @@
273 273 console.log('前端控制:播放');
274 274 this.$axios({
275 275 method: 'get',
276   - url: './api/playback/resume/' + this.streamId
  276 + url: '/api/playback/resume/' + this.streamId
277 277 }).then((res)=> {
278 278 this.$refs["recordVideoPlayer"].play(this.videoUrl)
279 279 });
... ... @@ -282,14 +282,14 @@
282 282 console.log('前端控制:暂停');
283 283 this.$axios({
284 284 method: 'get',
285   - url: './api/playback/pause/' + this.streamId
  285 + url: '/api/playback/pause/' + this.streamId
286 286 }).then(function (res) {});
287 287 },
288 288 gbScale(command){
289 289 console.log('前端控制:倍速 ' + command);
290 290 this.$axios({
291 291 method: 'get',
292   - url: `./api/playback/speed/${this.streamId }/${command}`
  292 + url: `/api/playback/speed/${this.streamId }/${command}`
293 293 }).then(function (res) {});
294 294 },
295 295 downloadRecord: function (row) {
... ... @@ -311,7 +311,7 @@
311 311 }else {
312 312 this.$axios({
313 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 315 row.endTime + '&downloadSpeed=4'
316 316 }).then( (res)=> {
317 317 if (res.data.code === 0) {
... ... @@ -332,7 +332,7 @@
332 332 this.videoUrl = '';
333 333 this.$axios({
334 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 336 }).then((res)=> {
337 337 if (callback) callback(res)
338 338 });
... ... @@ -342,7 +342,7 @@
342 342 this.videoUrl = '';
343 343 this.$axios({
344 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 346 }).then(function (res) {
347 347 if (callback) callback()
348 348 });
... ...
web_src/src/components/Login.vue
... ... @@ -35,6 +35,7 @@
35 35  
36 36 <script>
37 37 import crypto from 'crypto'
  38 +import userService from "./service/UserService";
38 39 export default {
39 40 name: 'Login',
40 41 data(){
... ... @@ -81,13 +82,14 @@ export default {
81 82  
82 83 this.$axios({
83 84 method: 'get',
84   - url:"./api/user/login",
  85 + url:"/api/user/login",
85 86 params: loginParam
86 87 }).then(function (res) {
87 88 window.clearTimeout(timeoutTask)
88   - console.log(JSON.stringify(res));
  89 + console.log(res);
  90 + console.log("登录成功");
89 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 94 that.cancelEnterkeyDefaultAction();
93 95 that.$router.push('/');
... ... @@ -106,14 +108,6 @@ export default {
106 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 111 cancelEnterkeyDefaultAction: function() {
118 112 document.onkeydown = function(e) {
119 113 var key = window.event.keyCode;
... ...
web_src/src/components/ParentPlatformList.vue
... ... @@ -128,7 +128,7 @@ export default {
128 128 var that = this;
129 129 that.$axios({
130 130 method: 'delete',
131   - url:`./api/platform/delete/${platform.serverGBId}`
  131 + url:`/api/platform/delete/${platform.serverGBId}`
132 132 }).then(function (res) {
133 133 if (res.data.code === 0) {
134 134 that.$message({
... ... @@ -162,7 +162,7 @@ export default {
162 162  
163 163 this.$axios({
164 164 method: 'get',
165   - url:`./api/platform/query/${that.count}/${that.currentPage}`
  165 + url:`/api/platform/query/${that.count}/${that.currentPage}`
166 166 }).then(function (res) {
167 167 if (res.data.code === 0) {
168 168 that.total = res.data.data.total;
... ...
web_src/src/components/PushVideoList.vue
... ... @@ -171,7 +171,7 @@ export default {
171 171 this.getDeviceListLoading = true;
172 172 this.$axios({
173 173 method: 'get',
174   - url: `./api/push/list`,
  174 + url: `/api/push/list`,
175 175 params: {
176 176 page: that.currentPage,
177 177 count: that.count,
... ... @@ -197,7 +197,7 @@ export default {
197 197 this.getListLoading = true;
198 198 this.$axios({
199 199 method: 'get',
200   - url: './api/push/getPlayUrl',
  200 + url: '/api/push/getPlayUrl',
201 201 params: {
202 202 app: row.app,
203 203 stream: row.stream,
... ... @@ -223,7 +223,7 @@ export default {
223 223 let that = this;
224 224 that.$axios({
225 225 method: "post",
226   - url: "./api/push/stop",
  226 + url: "/api/push/stop",
227 227 params: {
228 228 app: row.app,
229 229 streamId: row.stream
... ... @@ -247,7 +247,7 @@ export default {
247 247 let that = this;
248 248 that.$axios({
249 249 method: "delete",
250   - url: "./api/push/remove_form_gb",
  250 + url: "/api/push/remove_form_gb",
251 251 data: row
252 252 }).then((res) => {
253 253 if (res.data.code === 0) {
... ... @@ -274,7 +274,7 @@ export default {
274 274 let that = this;
275 275 that.$axios({
276 276 method: "delete",
277   - url: "./api/push/batchStop",
  277 + url: "/api/push/batchStop",
278 278 data: {
279 279 gbStreams: this.multipleSelection
280 280 }
... ...
web_src/src/components/StreamProxyList.vue
... ... @@ -167,7 +167,7 @@
167 167 let that = this;
168 168 this.$axios({
169 169 method: 'get',
170   - url:`./api/proxy/list`,
  170 + url:`/api/proxy/list`,
171 171 params: {
172 172 page: that.currentPage,
173 173 count: that.count
... ... @@ -190,7 +190,7 @@
190 190 addOnvif: function(){
191 191 this.$axios({
192 192 method: 'get',
193   - url:`./api/onvif/search?timeout=3000`,
  193 + url:`/api/onvif/search?timeout=3000`,
194 194 }).then((res) =>{
195 195 if (res.data.code === 0 ){
196 196 if (res.data.data.length > 0) {
... ... @@ -218,7 +218,7 @@
218 218 let that = this;
219 219 this.$axios({
220 220 method: 'get',
221   - url:`./api/push/getPlayUrl`,
  221 + url:`/api/push/getPlayUrl`,
222 222 params: {
223 223 app: row.app,
224 224 stream: row.stream,
... ... @@ -247,7 +247,7 @@
247 247 let that = this;
248 248 that.$axios({
249 249 method:"delete",
250   - url:"./api/proxy/del",
  250 + url:"/api/proxy/del",
251 251 params:{
252 252 app: row.app,
253 253 stream: row.stream
... ... @@ -263,7 +263,7 @@
263 263 this.$set(row, 'startBtnLoading', true)
264 264 this.$axios({
265 265 method: 'get',
266   - url:`./api/proxy/start`,
  266 + url:`/api/proxy/start`,
267 267 params: {
268 268 app: row.app,
269 269 stream: row.stream
... ... @@ -295,7 +295,7 @@
295 295 let that = this;
296 296 this.$axios({
297 297 method: 'get',
298   - url:`./api/proxy/stop`,
  298 + url:`/api/proxy/stop`,
299 299 params: {
300 300 app: row.app,
301 301 stream: row.stream
... ...
web_src/src/components/UserManager.vue
... ... @@ -99,7 +99,7 @@ export default {
99 99 this.getUserListLoading = true;
100 100 this.$axios({
101 101 method: 'get',
102   - url: `./api/user/users`,
  102 + url: `/api/user/users`,
103 103 params: {
104 104 page: that.currentPage,
105 105 count: that.count
... ... @@ -141,7 +141,7 @@ export default {
141 141 }).then(() => {
142 142 this.$axios({
143 143 method: 'delete',
144   - url: `./api/user/delete?id=${row.id}`
  144 + url: `/api/user/delete?id=${row.id}`
145 145 }).then((res) => {
146 146 this.getUserList();
147 147 }).catch((error) => {
... ...
web_src/src/components/channelList.vue
... ... @@ -69,7 +69,7 @@
69 69 <span v-if="scope.row.longitude*scope.row.latitude === 0">无</span>
70 70 </template>
71 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 73 <el-table-column label="开启音频" min-width="120">
74 74 <template slot-scope="scope">
75 75 <el-switch @change="updateChannel(scope.row)" v-model="scope.row.hasAudio" active-color="#409EFF">
... ... @@ -206,7 +206,7 @@ export default {
206 206 if (typeof (this.$route.params.deviceId) == "undefined") return;
207 207 this.$axios({
208 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 210 params: {
211 211 page: that.currentPage,
212 212 count: that.count,
... ... @@ -238,7 +238,7 @@ export default {
238 238 let that = this;
239 239 this.$axios({
240 240 method: 'get',
241   - url: './api/play/start/' + deviceId + '/' + channelId
  241 + url: '/api/play/start/' + deviceId + '/' + channelId
242 242 }).then(function (res) {
243 243 console.log(res)
244 244 that.isLoging = false;
... ... @@ -278,7 +278,7 @@ export default {
278 278 var that = this;
279 279 this.$axios({
280 280 method: 'get',
281   - url: './api/play/stop/' + this.deviceId + "/" + itemData.channelId
  281 + url: '/api/play/stop/' + this.deviceId + "/" + itemData.channelId
282 282 }).then(function (res) {
283 283 that.initData();
284 284 }).catch(function (error) {
... ... @@ -334,7 +334,7 @@ export default {
334 334 if (!this.showTree) {
335 335 this.$axios({
336 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 338 params: {
339 339 page: this.currentPage,
340 340 count: this.count,
... ... @@ -358,7 +358,7 @@ export default {
358 358 }else {
359 359 this.$axios({
360 360 method: 'get',
361   - url: `./api/device/query/tree/channel/${this.deviceId}`,
  361 + url: `/api/device/query/tree/channel/${this.deviceId}`,
362 362 params: {
363 363 parentId: this.parentChannelId,
364 364 page: this.currentPage,
... ... @@ -387,7 +387,7 @@ export default {
387 387 updateChannel: function (row) {
388 388 this.$axios({
389 389 method: 'post',
390   - url: `./api/device/query/channel/update/${this.deviceId}`,
  390 + url: `/api/device/query/channel/update/${this.deviceId}`,
391 391 params: row
392 392 }).then(function (res) {
393 393 console.log(JSON.stringify(res));
... ...
web_src/src/components/common/jessibuca.vue
1 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 4 <div class="buttons-box" id="buttonsBox">
4 5 <div class="buttons-box-left">
5 6 <i v-if="!playing" class="iconfont icon-play jessibuca-btn" @click="playBtnClick"></i>
... ... @@ -12,7 +13,7 @@
12 13 <span class="jessibuca-btn">{{ kBps }} kb/s</span>
13 14 <!-- <i class="iconfont icon-file-record1 jessibuca-btn"></i>-->
14 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 17 style="font-size: 1rem !important"></i>
17 18 <i class="iconfont icon-shuaxin11 jessibuca-btn" @click="playBtnClick"></i>
18 19 <i v-if="!fullscreen" class="iconfont icon-weibiaoti10 jessibuca-btn" @click="fullscreenSwich"></i>
... ... @@ -92,29 +93,49 @@ export default {
92 93 jessibucaPlayer[this._uid] = new window.Jessibuca(Object.assign(
93 94 {
94 95 container: this.$refs.container,
95   - videoBuffer: 0.2, // 最大缓冲时长,单位秒
96   - isResize: true,
  96 + autoWasm: true,
  97 + background: "",
  98 + controlAutoHide: false,
  99 + debug: false,
97 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 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 119 operateBtns: {
108 120 fullscreen: false,
109 121 screenshot: false,
110 122 play: false,
111 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 140 options
120 141 ));
... ... @@ -146,13 +167,7 @@ export default {
146 167 _this.isNotMute = !msg;
147 168 });
148 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 173 jessibuca.on("bps", function (bps) {
... ... @@ -243,6 +258,11 @@ export default {
243 258 this.err = "";
244 259 this.performance = "";
245 260 },
  261 + screenshot: function () {
  262 + if (jessibucaPlayer[this._uid]) {
  263 + jessibucaPlayer[this._uid].screenshot();
  264 + }
  265 + },
246 266 mute: function () {
247 267 if (jessibucaPlayer[this._uid]) {
248 268 jessibucaPlayer[this._uid].mute();
... ...
web_src/src/components/console.vue
... ... @@ -114,7 +114,7 @@ export default {
114 114 getSystemInfo: function (){
115 115 this.$axios({
116 116 method: 'get',
117   - url: `./api/server/system/info`,
  117 + url: `/api/server/system/info`,
118 118 }).then( (res)=> {
119 119 if (res.data.code === 0) {
120 120 this.$refs.consoleCPU.setData(res.data.data.cpu)
... ... @@ -128,7 +128,7 @@ export default {
128 128 getLoad: function (){
129 129 this.$axios({
130 130 method: 'get',
131   - url: `./api/server/media_server/load`,
  131 + url: `/api/server/media_server/load`,
132 132 }).then( (res)=> {
133 133 if (res.data.code === 0) {
134 134 this.$refs.consoleNodeLoad.setData(res.data.data)
... ... @@ -139,7 +139,7 @@ export default {
139 139 getResourceInfo: function (){
140 140 this.$axios({
141 141 method: 'get',
142   - url: `./api/server/resource/info`,
  142 + url: `/api/server/resource/info`,
143 143 }).then( (res)=> {
144 144 if (res.data.code === 0) {
145 145 this.$refs.consoleResource.setData(res.data.data)
... ... @@ -151,7 +151,7 @@ export default {
151 151  
152 152 this.$axios({
153 153 method: 'get',
154   - url: `./api/server/system/configInfo`,
  154 + url: `/api/server/system/configInfo`,
155 155 }).then( (res)=> {
156 156 console.log(res)
157 157 if (res.data.code === 0) {
... ...
web_src/src/components/dialog/MediaServerEdit.vue
... ... @@ -78,7 +78,7 @@
78 78 <el-switch v-model="mediaServerForm.autoConfig" :disabled="mediaServerForm.defaultServer"></el-switch>
79 79 </el-form-item>
80 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 82 </el-form-item>
83 83  
84 84 <el-form-item v-if="!mediaServerForm.rtpEnable" label="收流端口" prop="rtpProxyPort">
... ... @@ -335,7 +335,7 @@ export default {
335 335 var that = this;
336 336 await that.$axios({
337 337 method: 'get',
338   - url:`./api/platform/exit/${deviceGbId}`
  338 + url:`/api/platform/exit/${deviceGbId}`
339 339 }).then(function (res) {
340 340 result = res.data;
341 341 }).catch(function (error) {
... ... @@ -349,8 +349,10 @@ export default {
349 349 }
350 350 },
351 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 195 let that = this;
196 196 this.$axios({
197 197 method: 'get',
198   - url:`./api/platform/query/10000/1`
  198 + url:`/api/platform/query/10000/1`
199 199 }).then(function (res) {
200 200 that.platformList = res.data.data.list;
201 201 }).catch(function (error) {
... ... @@ -212,7 +212,7 @@ export default {
212 212 if (that.proxyParam.mediaServerId !== "auto"){
213 213 that.$axios({
214 214 method: 'get',
215   - url:`./api/proxy/ffmpeg_cmd/list`,
  215 + url:`/api/proxy/ffmpeg_cmd/list`,
216 216 params: {
217 217 mediaServerId: that.proxyParam.mediaServerId
218 218 }
... ... @@ -230,7 +230,7 @@ export default {
230 230 this.noneReaderHandler();
231 231 this.$axios({
232 232 method: 'post',
233   - url:`./api/proxy/save`,
  233 + url:`/api/proxy/save`,
234 234 data: this.proxyParam
235 235 }).then((res)=> {
236 236 this.dialogLoading = false;
... ... @@ -261,7 +261,7 @@ export default {
261 261 var that = this;
262 262 await that.$axios({
263 263 method: 'get',
264   - url:`./api/platform/exit/${deviceGbId}`
  264 + url:`/api/platform/exit/${deviceGbId}`
265 265 }).then(function (res) {
266 266 result = res.data;
267 267 }).catch(function (error) {
... ...
web_src/src/components/dialog/SyncChannelProgress.vue
... ... @@ -55,7 +55,7 @@ export default {
55 55 getProgress(){
56 56 this.$axios({
57 57 method: 'get',
58   - url:`./api/device/query/${this.deviceId}/sync_status/`,
  58 + url:`/api/device/query/${this.deviceId}/sync_status/`,
59 59 }).then((res) => {
60 60 if (res.data.code === 0) {
61 61 if (!this.syncFlag) {
... ...
web_src/src/components/dialog/addUser.vue
... ... @@ -100,7 +100,7 @@ export default {
100 100 onSubmit: function () {
101 101 this.$axios({
102 102 method: 'post',
103   - url: "./api/user/add",
  103 + url: "/api/user/add",
104 104 params: {
105 105 username: this.username,
106 106 password: this.password,
... ... @@ -139,7 +139,7 @@ export default {
139 139  
140 140 this.$axios({
141 141 method: 'get',
142   - url: "./api/role/all"
  142 + url: "/api/role/all"
143 143 }).then((res) => {
144 144 this.loading = true;
145 145 if (res.data.code === 0) {
... ...
web_src/src/components/dialog/catalogEdit.vue
... ... @@ -116,7 +116,7 @@ export default {
116 116 console.log(this.form);
117 117 this.$axios({
118 118 method:"post",
119   - url:`./api/platform/catalog/${!this.isEdit? "add":"edit"}`,
  119 + url:`/api/platform/catalog/${!this.isEdit? "add":"edit"}`,
120 120 data: this.form
121 121 }).then((res)=> {
122 122 if (res.data.code === 0) {
... ...
web_src/src/components/dialog/changePassword.vue
... ... @@ -35,6 +35,7 @@
35 35  
36 36 <script>
37 37 import crypto from 'crypto'
  38 +import userService from "../service/UserService";
38 39 export default {
39 40 name: "changePassword",
40 41 props: {},
... ... @@ -90,7 +91,7 @@ export default {
90 91 onSubmit: function () {
91 92 this.$axios({
92 93 method: 'post',
93   - url:"./api/user/changePassword",
  94 + url:"/api/user/changePassword",
94 95 params: {
95 96 oldPassword: crypto.createHash('md5').update(this.oldPassword, "utf8").digest('hex'),
96 97 password: this.newPassword
... ... @@ -105,7 +106,7 @@ export default {
105 106 this.showDialog = false;
106 107 setTimeout(()=>{
107 108 // 删除cookie,回到登录页面
108   - this.$cookies.remove("session");
  109 + userService.clearUserInfo();
109 110 this.$router.push('/login');
110 111 this.sseSource.close();
111 112 },800)
... ...
web_src/src/components/dialog/changePasswordForAdmin.vue
... ... @@ -85,7 +85,7 @@ export default {
85 85 onSubmit: function () {
86 86 this.$axios({
87 87 method: 'post',
88   - url:"./api/user/changePasswordForAdmin",
  88 + url:"/api/user/changePasswordForAdmin",
89 89 params: {
90 90 password: this.newPassword,
91 91 userId: this.form.id,
... ...
web_src/src/components/dialog/changePushKey.vue
... ... @@ -65,7 +65,7 @@ export default {
65 65 onSubmit: function () {
66 66 this.$axios({
67 67 method: 'post',
68   - url:"./api/user/changePushKey",
  68 + url:"/api/user/changePushKey",
69 69 params: {
70 70 pushKey: this.newPushKey,
71 71 userId: this.form.id,
... ...
web_src/src/components/dialog/channelMapInfobox.vue
... ... @@ -44,7 +44,7 @@ export default {
44 44 let that = this;
45 45 this.$axios({
46 46 method: 'get',
47   - url: './api/play/start/' + deviceId + '/' + channelId
  47 + url: '/api/play/start/' + deviceId + '/' + channelId
48 48 }).then(function (res) {
49 49 that.isLoging = false;
50 50 if (res.data.code === 0) {
... ...
web_src/src/components/dialog/chooseChannel.vue
1 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 5 <el-row>
6 6 <el-col :span="10">
7 7 <el-tabs v-model="catalogTabActiveName" >
... ... @@ -56,7 +56,7 @@ export default {
56 56 },
57 57 data() {
58 58 return {
59   - isLoging: false,
  59 + loading: false,
60 60 tabActiveName: "gbChannel",
61 61 catalogTabActiveName: "catalog",
62 62 platformId: "",
... ... @@ -94,18 +94,17 @@ export default {
94 94  
95 95 },
96 96 save: function() {
97   - var that = this;
98 97  
99 98 this.$axios({
100 99 method:"post",
101   - url:"./api/platform/update_channel_for_gb",
  100 + url:"/api/platform/update_channel_for_gb",
102 101 data:{
103   - platformId: that.platformId,
104   - channelReduces: that.chooseData
  102 + platformId: this.platformId,
  103 + channelReduces: this.chooseData
105 104 }
106 105 }).then((res)=>{
107 106 if (res.data.code === 0) {
108   - that.$message({
  107 + this.$message({
109 108 showClose: true,
110 109 message: '保存成功,',
111 110 type: 'success'
... ... @@ -114,6 +113,7 @@ export default {
114 113 }).catch(function (error) {
115 114 console.log(error);
116 115 });
  116 +
117 117 },
118 118 catalogIdChange: function (id, name) {
119 119 this.catalogId = id;
... ...
web_src/src/components/dialog/chooseChannelForCatalog.vue
... ... @@ -82,7 +82,7 @@ export default {
82 82 let that = this;
83 83 this.$axios({
84 84 method:"get",
85   - url:`./api/platform/catalog`,
  85 + url:`/api/platform/catalog`,
86 86 params: {
87 87 platformId: that.platformId,
88 88 parentId: parentId
... ... @@ -134,7 +134,7 @@ export default {
134 134 removeCatalog: function (id, node){
135 135 this.$axios({
136 136 method:"delete",
137   - url:`./api/platform/catalog/del`,
  137 + url:`/api/platform/catalog/del`,
138 138 params: {
139 139 id: id,
140 140 platformId: this.platformId,
... ... @@ -156,7 +156,7 @@ export default {
156 156 setDefaultCatalog: function (id){
157 157 this.$axios({
158 158 method:"post",
159   - url:`./api/platform/catalog/default/update`,
  159 + url:`/api/platform/catalog/default/update`,
160 160 params: {
161 161 platformId: this.platformId,
162 162 catalogId: id,
... ... @@ -201,7 +201,7 @@ export default {
201 201 onClick: () => {
202 202 this.$axios({
203 203 method:"delete",
204   - url:"./api/platform/catalog/relation/del",
  204 + url:"/api/platform/catalog/relation/del",
205 205 data: data
206 206 }).then((res)=>{
207 207 console.log("移除成功")
... ...
web_src/src/components/dialog/chooseChannelForGb.vue
1 1 <template>
2   -<div id="chooseChannelForGb" >
  2 +<div id="chooseChannelForGb" v-loading="loading">
3 3 <div style="font-size: 17px; color: #606060; white-space: nowrap; line-height: 30px; font-family: monospace;">
4 4 <span v-if="catalogId == null">{{catalogName}}的国标通道</span>
5 5 <span v-if="catalogId != null">{{catalogName}}({{catalogId}})的国标通道</span>
... ... @@ -79,6 +79,7 @@ export default {
79 79 },
80 80 data() {
81 81 return {
  82 + loading: false,
82 83 gbChannels: [],
83 84 gbChoosechannel:{},
84 85 searchSrt: "",
... ... @@ -118,10 +119,12 @@ export default {
118 119 },
119 120 add: function (row) {
120 121 let all = typeof(row) === "undefined"
  122 +
121 123 this.getCatalogFromUser((catalogId)=> {
  124 + let task = null;
122 125 this.$axios({
123 126 method:"post",
124   - url:"./api/platform/update_channel_for_gb",
  127 + url:"/api/platform/update_channel_for_gb",
125 128 data:{
126 129 platformId: this.platformId,
127 130 all: all,
... ... @@ -130,12 +133,20 @@ export default {
130 133 }
131 134 }).then((res)=>{
132 135 console.log("保存成功")
  136 + window.clearTimeout(task);
  137 + this.loading = false;
133 138 this.getChannelList();
134   - }).catch(function (error) {
  139 + }).catch((error)=> {
  140 + window.clearTimeout(task);
  141 + this.loading = false;
135 142 console.log(error);
136 143 });
  144 + task= setTimeout(()=>{
  145 + this.loading = true;
  146 + }, 200)
137 147 })
138 148  
  149 +
139 150 },
140 151 remove: function (row) {
141 152 let all = typeof(row) === "undefined"
... ... @@ -149,7 +160,7 @@ export default {
149 160  
150 161 this.$axios({
151 162 method:"delete",
152   - url:"./api/platform/del_channel_for_gb",
  163 + url:"/api/platform/del_channel_for_gb",
153 164 data:{
154 165 platformId: this.platformId,
155 166 all: all,
... ... @@ -248,7 +259,7 @@ export default {
248 259  
249 260 this.$axios({
250 261 method:"get",
251   - url:`./api/platform/channel_list`,
  262 + url:`/api/platform/channel_list`,
252 263 params: {
253 264 page: that.currentPage,
254 265 count: that.count,
... ... @@ -290,7 +301,7 @@ export default {
290 301 }).then(() => {
291 302 this.$axios({
292 303 method:"delete",
293   - url:"./api/platform/del_channel_for_gb",
  304 + url:"/api/platform/del_channel_for_gb",
294 305 data:{
295 306 platformId: this.platformId,
296 307 channelReduces: this.multipleSelection
... ... @@ -310,7 +321,7 @@ export default {
310 321  
311 322 this.$axios({
312 323 method: "post",
313   - url: "./api/platform/update_channel_for_gb",
  324 + url: "/api/platform/update_channel_for_gb",
314 325 data: {
315 326 platformId: this.platformId,
316 327 channelReduces: this.multipleSelection,
... ...
web_src/src/components/dialog/chooseChannelForStream.vue
1 1 <template>
2   -<div id="chooseChannelFoStream" >
  2 +<div id="chooseChannelFoStream" v-loading="loading">
3 3 <div style="font-size: 17px; color: #606060; white-space: nowrap; line-height: 30px; font-family: monospace;">
4 4 <span v-if="catalogId == null">{{catalogName}}的直播通道</span>
5 5 <span v-if="catalogId != null">{{catalogName}}({{catalogId}})的直播通道</span>
... ... @@ -85,6 +85,7 @@ export default {
85 85 },
86 86 data() {
87 87 return {
  88 + loading: false,
88 89 gbStreams: [],
89 90 gbChoosechannel:{},
90 91 channelType: "",
... ... @@ -132,9 +133,10 @@ export default {
132 133 add: function (row, scope) {
133 134 let all = typeof(row) === "undefined"
134 135 this.getCatalogFromUser((catalogId)=>{
  136 + let task = null;
135 137 this.$axios({
136 138 method:"post",
137   - url:"./api/gbStream/add",
  139 + url:"/api/gbStream/add",
138 140 data:{
139 141 platformId: this.platformId,
140 142 catalogId: catalogId,
... ... @@ -143,11 +145,18 @@ export default {
143 145 }
144 146 }).then((res)=>{
145 147 console.log("保存成功")
  148 + window.clearTimeout(task);
  149 + this.loading = false;
146 150 // this.gbStreams.splice(scope.$index,1)
147 151 this.getChannelList();
148 152 }).catch(function (error) {
  153 + window.clearTimeout(task);
  154 + this.loading = false;
149 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 172  
164 173 this.$axios({
165 174 method:"delete",
166   - url:"./api/gbStream/del",
  175 + url:"/api/gbStream/del",
167 176 data:{
168 177 platformId: this.platformId,
169 178 all: all,
... ... @@ -186,7 +195,7 @@ export default {
186 195  
187 196 this.$axios({
188 197 method: 'get',
189   - url:`./api/gbStream/list`,
  198 + url:`/api/gbStream/list`,
190 199 params: {
191 200 page: that.currentPage,
192 201 count: that.count,
... ... @@ -222,7 +231,7 @@ export default {
222 231 }).then(() => {
223 232 this.$axios({
224 233 method:"delete",
225   - url:"./api/gbStream/del",
  234 + url:"/api/gbStream/del",
226 235 data:{
227 236 platformId: this.platformId,
228 237 gbStreams: this.multipleSelection,
... ... @@ -242,7 +251,7 @@ export default {
242 251 this.getCatalogFromUser((catalogId)=>{
243 252 this.$axios({
244 253 method:"post",
245   - url:"./api/gbStream/add",
  254 + url:"/api/gbStream/add",
246 255 data:{
247 256 platformId: this.platformId,
248 257 catalogId: catalogId,
... ...
web_src/src/components/dialog/configInfo.vue
... ... @@ -13,7 +13,7 @@
13 13 <el-descriptions title="国标服务信息" v-if="configInfoData.sip" :span="2">
14 14 <el-descriptions-item label="编号" >{{configInfoData.sip.id}}</el-descriptions-item>
15 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 17 <el-descriptions-item label="端口">{{configInfoData.sip.port}}</el-descriptions-item>
18 18 <el-descriptions-item label="密码">
19 19 <el-tag size="small">{{configInfoData.sip.password}}</el-tag>
... ...
web_src/src/components/dialog/deviceEdit.vue
... ... @@ -69,6 +69,7 @@
69 69 </el-form-item>
70 70 <el-form-item label="其他选项">
71 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 73 </el-form-item>
73 74 <el-form-item>
74 75 <div style="float: right;">
... ... @@ -134,7 +135,7 @@ export default {
134 135 this.form.mobilePositionSubmissionInterval = this.form.mobilePositionSubmissionInterval||0
135 136 this.$axios({
136 137 method: 'post',
137   - url:`./api/device/query/device/${this.isEdit?'update':'add'}/`,
  138 + url:`/api/device/query/device/${this.isEdit?'update':'add'}/`,
138 139 params: this.form
139 140 }).then((res) => {
140 141 console.log(res.data)
... ...
web_src/src/components/dialog/getCatalog.vue
... ... @@ -89,7 +89,7 @@ export default {
89 89 let that = this;
90 90 this.$axios({
91 91 method:"get",
92   - url:`./api/platform/catalog`,
  92 + url:`/api/platform/catalog`,
93 93 params: {
94 94 platformId: that.platformId,
95 95 parentId: parentId
... ... @@ -111,7 +111,7 @@ export default {
111 111 if (node.level === 0) {
112 112 this.$axios({
113 113 method:"get",
114   - url:`./api/platform/info/` + this.platformId,
  114 + url:`/api/platform/info/` + this.platformId,
115 115 })
116 116 .then((res)=> {
117 117 if (res.data.code === 0) {
... ...
web_src/src/components/dialog/importChannel.vue
... ... @@ -16,6 +16,7 @@
16 16 drag
17 17 :action="uploadUrl"
18 18 name="file"
  19 + :headers="headers"
19 20 :on-success="successHook"
20 21 :on-error="errorHook"
21 22 >
... ... @@ -33,6 +34,8 @@
33 34  
34 35 import ShowErrorData from './importChannelShowErrorData.vue'
35 36  
  37 +import userService from "../service/UserService";
  38 +
36 39 export default {
37 40 name: "importChannel",
38 41 components: {
... ... @@ -47,7 +50,10 @@ export default {
47 50 isEdit: false,
48 51 errorStreams: [],
49 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 59 methods: {
... ... @@ -60,7 +66,7 @@ export default {
60 66 console.log(this.form);
61 67 this.$axios({
62 68 method:"post",
63   - url:`./api/platform/catalog/${!this.isEdit? "add":"edit"}`,
  69 + url:`/api/platform/catalog/${!this.isEdit? "add":"edit"}`,
64 70 data: this.form
65 71 })
66 72 .then((res)=> {
... ...
web_src/src/components/dialog/onvifEdit.vue
... ... @@ -81,7 +81,7 @@ export default {
81 81 console.log(this.form);
82 82 this.$axios({
83 83 method: 'get',
84   - url:`./api/onvif/rtsp`,
  84 + url:`/api/onvif/rtsp`,
85 85 params: {
86 86 hostname: this.form.hostName,
87 87 timeout: 3000,
... ...
web_src/src/components/dialog/platformEdit.vue
... ... @@ -96,9 +96,10 @@
96 96 </el-form-item>
97 97 <el-form-item label="其他选项">
98 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 100 <el-checkbox label="拉起离线推流" v-model="platform.startOfflinePush"></el-checkbox>
101 101 <el-checkbox label="RTCP保活" v-model="platform.rtcp" @change="rtcpCheckBoxChange"></el-checkbox>
  102 + <el-checkbox label="作为消息通道" v-model="platform.asMessageChannel" ></el-checkbox>
102 103 </el-form-item>
103 104 <el-form-item>
104 105 <el-button type="primary" @click="onSubmit">{{
... ... @@ -138,13 +139,14 @@ export default {
138 139 showDialog: false,
139 140 isLoging: false,
140 141 onSubmit_text: "立即创建",
141   - saveUrl: "./api/platform/save",
  142 + saveUrl: "/api/platform/save",
142 143  
143 144 platform: {
144 145 id: null,
145 146 enable: true,
146 147 ptz: true,
147 148 rtcp: false,
  149 + asMessageChannel: false,
148 150 name: null,
149 151 serverGBId: null,
150 152 serverGBDomain: null,
... ... @@ -155,7 +157,7 @@ export default {
155 157 devicePort: null,
156 158 username: null,
157 159 password: null,
158   - expires: 300,
  160 + expires: 3600,
159 161 keepTimeout: 60,
160 162 transport: "UDP",
161 163 characterSet: "GB2312",
... ... @@ -192,7 +194,7 @@ export default {
192 194 this.saveUrl = "/api/platform/add";
193 195 this.$axios({
194 196 method: 'get',
195   - url:`./api/platform/server_config`
  197 + url:`/api/platform/server_config`
196 198 }).then(function (res) {
197 199 console.log(res);
198 200 if (res.data.code === 0) {
... ... @@ -213,6 +215,7 @@ export default {
213 215 this.platform.enable = platform.enable;
214 216 this.platform.ptz = platform.ptz;
215 217 this.platform.rtcp = platform.rtcp;
  218 + this.platform.asMessageChannel = platform.asMessageChannel;
216 219 this.platform.name = platform.name;
217 220 this.platform.serverGBId = platform.serverGBId;
218 221 this.platform.serverGBDomain = platform.serverGBDomain;
... ... @@ -290,6 +293,7 @@ export default {
290 293 enable: true,
291 294 ptz: true,
292 295 rtcp: false,
  296 + asMessageChannel: false,
293 297 name: null,
294 298 serverGBId: null,
295 299 administrativeDivision: null,
... ... @@ -301,7 +305,7 @@ export default {
301 305 devicePort: null,
302 306 username: null,
303 307 password: null,
304   - expires: 300,
  308 + expires: 3600,
305 309 keepTimeout: 60,
306 310 transport: "UDP",
307 311 characterSet: "GB2312",
... ... @@ -315,7 +319,7 @@ export default {
315 319 var that = this;
316 320 await that.$axios({
317 321 method: 'get',
318   - url:`./api/platform/exit/${deviceGbId}`})
  322 + url:`/api/platform/exit/${deviceGbId}`})
319 323 .then(function (res) {
320 324 if (res.data.code === 0) {
321 325 result = res.data.data;
... ... @@ -327,8 +331,8 @@ export default {
327 331 return result;
328 332 },
329 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 338 rtcpCheckBoxChange: function (result){
... ...
web_src/src/components/dialog/pushStreamEdit.vue
... ... @@ -109,7 +109,7 @@ export default {
109 109 if (this.edit) {
110 110 this.$axios({
111 111 method:"post",
112   - url:`./api/push/save_to_gb`,
  112 + url:`/api/push/save_to_gb`,
113 113 data: this.proxyParam
114 114 }).then( (res) => {
115 115 if (res.data.code === 0) {
... ... @@ -129,7 +129,7 @@ export default {
129 129 }else {
130 130 this.$axios({
131 131 method:"post",
132   - url:`./api/push/add`,
  132 + url:`/api/push/add`,
133 133 data: this.proxyParam
134 134 }).then( (res) => {
135 135 if (res.data.code === 0) {
... ... @@ -159,7 +159,7 @@ export default {
159 159 var that = this;
160 160 await that.$axios({
161 161 method:"get",
162   - url:`./api/platform/exit/${deviceGbId}`
  162 + url:`/api/platform/exit/${deviceGbId}`
163 163 }).then(function (res) {
164 164 result = res.data;
165 165 }).catch(function (error) {
... ...
web_src/src/components/dialog/queryTrace.vue
... ... @@ -72,7 +72,7 @@ export default {
72 72 onSubmit: function () {
73 73 console.log("onSubmit");
74 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 76 if (this.channel.channelId) {
77 77 url+="&channelId=${this.channel.channelId}"
78 78 }
... ...
web_src/src/components/dialog/recordDownload.vue
... ... @@ -71,7 +71,7 @@ export default {
71 71 getProgress: function (callback){
72 72 this.$axios({
73 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 75 }).then((res)=> {
76 76 console.log(res)
77 77 if (res.data.code === 0) {
... ... @@ -124,7 +124,7 @@ export default {
124 124 stopDownloadRecord: function (callback) {
125 125 this.$axios({
126 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 128 }).then((res)=> {
129 129 if (callback) callback(res)
130 130 });
... ... @@ -132,7 +132,7 @@ export default {
132 132 getFileDownload: function (){
133 133 this.$axios({
134 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 136 params: {
137 137 app: this.app,
138 138 stream: this.stream,
... ... @@ -164,7 +164,7 @@ export default {
164 164 getProgressForFile: function (callback){
165 165 this.$axios({
166 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 168 params: {
169 169 app: this.app,
170 170 stream: this.stream,
... ...
web_src/src/components/live.vue
... ... @@ -135,7 +135,7 @@ export default {
135 135 this.loading = true
136 136 this.$axios({
137 137 method: 'get',
138   - url: './api/play/start/' + deviceId + '/' + channelId
  138 + url: '/api/play/start/' + deviceId + '/' + channelId
139 139 }).then(function (res) {
140 140 if (res.data.code === 0 && res.data.data) {
141 141 let videoUrl;
... ...
web_src/src/components/map.vue
... ... @@ -298,7 +298,7 @@ export default {
298 298 let that = this;
299 299 this.$axios({
300 300 method: 'get',
301   - url: './api/play/start/' + deviceId + '/' + channelId
  301 + url: '/api/play/start/' + deviceId + '/' + channelId
302 302 }).then(function (res) {
303 303 that.isLoging = false;
304 304 if (res.data.code === 0) {
... ...
web_src/src/components/service/DeviceService.js
... ... @@ -9,7 +9,7 @@ class DeviceService{
9 9 getDeviceList(currentPage, count, callback, errorCallback){
10 10 this.$axios({
11 11 method: 'get',
12   - url:`./api/device/query/devices`,
  12 + url:`/api/device/query/devices`,
13 13 params: {
14 14 page: currentPage,
15 15 count: count
... ... @@ -25,7 +25,7 @@ class DeviceService{
25 25 getDevice(deviceId, callback, errorCallback){
26 26 this.$axios({
27 27 method: 'get',
28   - url:`./api/device/query/devices/${deviceId}`,
  28 + url:`/api/device/query/devices/${deviceId}`,
29 29 }).then((res) => {
30 30 if (typeof (callback) == "function") callback(res.data)
31 31 }).catch((error) => {
... ... @@ -82,7 +82,7 @@ class DeviceService{
82 82 getChanel(isCatalog, catalogUnderDevice, deviceId, currentPage, count, callback, errorCallback) {
83 83 this.$axios({
84 84 method: 'get',
85   - url: `./api/device/query/devices/${deviceId}/channels`,
  85 + url: `/api/device/query/devices/${deviceId}/channels`,
86 86 params:{
87 87 page: currentPage,
88 88 count: count,
... ... @@ -121,7 +121,7 @@ class DeviceService{
121 121 getSubChannel(isCatalog, deviceId, channelId, currentPage, count, callback, errorCallback) {
122 122 this.$axios({
123 123 method: 'get',
124   - url: `./api/device/query/sub_channels/${deviceId}/${channelId}/channels`,
  124 + url: `/api/device/query/sub_channels/${deviceId}/${channelId}/channels`,
125 125 params:{
126 126 page: currentPage,
127 127 count: count,
... ... @@ -161,7 +161,7 @@ class DeviceService{
161 161 }
162 162 this.$axios({
163 163 method: 'get',
164   - url: `./api/device/query/tree/${deviceId}`,
  164 + url: `/api/device/query/tree/${deviceId}`,
165 165 params:{
166 166 page: currentPage,
167 167 count: count,
... ...
web_src/src/components/service/MediaServer.js
... ... @@ -9,7 +9,7 @@ class MediaServer{
9 9 getOnlineMediaServerList(callback){
10 10 this.$axios({
11 11 method: 'get',
12   - url:`./api/server/media_server/online/list`,
  12 + url:`/api/server/media_server/online/list`,
13 13 }).then((res) => {
14 14 if (typeof (callback) == "function") callback(res.data)
15 15 }).catch((error) => {
... ... @@ -19,7 +19,7 @@ class MediaServer{
19 19 getMediaServerList(callback){
20 20 this.$axios({
21 21 method: 'get',
22   - url:`./api/server/media_server/list`,
  22 + url:`/api/server/media_server/list`,
23 23 }).then(function (res) {
24 24 if (typeof (callback) == "function") callback(res.data)
25 25 }).catch(function (error) {
... ... @@ -30,7 +30,7 @@ class MediaServer{
30 30 getMediaServer(id, callback){
31 31 this.$axios({
32 32 method: 'get',
33   - url:`./api/server/media_server/one/` + id,
  33 + url:`/api/server/media_server/one/` + id,
34 34 }).then(function (res) {
35 35 if (typeof (callback) == "function") callback(res.data)
36 36 }).catch(function (error) {
... ... @@ -41,7 +41,7 @@ class MediaServer{
41 41 checkServer(param, callback){
42 42 this.$axios({
43 43 method: 'get',
44   - url:`./api/server/media_server/check`,
  44 + url:`/api/server/media_server/check`,
45 45 params: {
46 46 ip: param.ip,
47 47 port: param.httpPort,
... ... @@ -57,7 +57,7 @@ class MediaServer{
57 57 checkRecordServer(param, callback){
58 58 this.$axios({
59 59 method: 'get',
60   - url:`./api/server/media_server/record/check`,
  60 + url:`/api/server/media_server/record/check`,
61 61 params: {
62 62 ip: param.ip,
63 63 port: param.recordAssistPort
... ... @@ -72,7 +72,7 @@ class MediaServer{
72 72 addServer(param, callback){
73 73 this.$axios({
74 74 method: 'post',
75   - url:`./api/server/media_server/save`,
  75 + url:`/api/server/media_server/save`,
76 76 data: param
77 77 }).then(function (res) {
78 78 if (typeof (callback) == "function") callback(res.data)
... ... @@ -84,7 +84,7 @@ class MediaServer{
84 84 delete(id, callback) {
85 85 this.$axios({
86 86 method: 'delete',
87   - url:`./api/server/media_server/delete`,
  87 + url:`/api/server/media_server/delete`,
88 88 params: {
89 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 23 <!-- </el-submenu>-->
24 24 <!-- <el-menu-item style="float: right;" @click="loginout">退出</el-menu-item>-->
25 25 <el-submenu index="" style="float: right;">
26   - <template slot="title">欢迎,{{ this.$cookies.get("session").username }}</template>
  26 + <template slot="title">欢迎,{{ username }}</template>
27 27 <el-menu-item @click="openDoc">在线文档</el-menu-item>
28   - <el-menu-item >
  28 + <el-menu-item>
29 29 <el-switch v-model="alarmNotify" inactive-text="报警信息推送" @change="alarmNotifyChannge"></el-switch>
30 30 </el-menu-item>
31 31 <el-menu-item @click="changePassword">修改密码</el-menu-item>
... ... @@ -39,6 +39,7 @@
39 39 <script>
40 40  
41 41 import changePasswordDialog from '../components/dialog/changePassword.vue'
  42 +import userService from '../components/service/UserService'
42 43  
43 44 export default {
44 45 name: "UiHeader",
... ... @@ -47,14 +48,17 @@ export default {
47 48 return {
48 49 alarmNotify: false,
49 50 sseSource: null,
  51 + username: userService.getUser().username,
50 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 56 created() {
55   - console.log(this.$cookies.get("session"))
  57 + console.log(4444)
  58 + console.log(JSON.stringify(userService.getUser()))
56 59 if (this.$route.path.startsWith("/channelList")) {
57 60 this.activeIndex = "/deviceList"
  61 +
58 62 }
59 63 },
60 64 mounted() {
... ... @@ -69,10 +73,13 @@ export default {
69 73 method: 'get',
70 74 url: "/api/user/logout"
71 75 }).then((res) => {
72   - // 删除cookie,回到登录页面
73   - this.$cookies.remove("session");
  76 + // 删除用户信息,回到登录页面
  77 + userService.clearUserInfo()
74 78 this.$router.push('/login');
75   - this.sseSource.close();
  79 + if (this.sseSource != null) {
  80 + this.sseSource.close();
  81 + }
  82 +
76 83 }).catch((error) => {
77 84 console.error("登出失败")
78 85 console.error(error)
... ... @@ -151,16 +158,19 @@ export default {
151 158 </script>
152 159 <style>
153 160 #UiHeader .el-switch__label {
154   - color: white ;
  161 + color: white;
155 162 }
  163 +
156 164 .el-menu--popup .el-menu-item .el-switch .el-switch__label {
157 165 color: white !important;
158 166 }
159   -#UiHeader .el-switch__label.is-active{
  167 +
  168 +#UiHeader .el-switch__label.is-active {
160 169 color: #409EFF;
161 170 }
  171 +
162 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 176 </style>
... ...
web_src/src/main.js
1 1 import Vue from 'vue';
2 2 import App from './App.vue';
  3 +
3 4 Vue.config.productionTip = false;
4 5 import ElementUI from 'element-ui';
5 6 import 'element-ui/lib/theme-chalk/index.css';
... ... @@ -10,15 +11,16 @@ import echarts from &#39;echarts&#39;;
10 11 import VCharts from 'v-charts';
11 12  
12 13 import VueClipboard from 'vue-clipboard2';
13   -import { Notification } from 'element-ui';
  14 +import {Notification} from 'element-ui';
14 15 import Fingerprint2 from 'fingerprintjs2';
15 16 import VueClipboards from 'vue-clipboards';
16 17 import Contextmenu from "vue-contextmenujs"
  18 +import userService from "./components/service/UserService"
17 19  
18 20  
19 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 24 if (index === 0) { //把微信浏览器里UA的wifi或4G等网络替换成空,不然切换网络会ID不一样
23 25 return component.value.replace(/\bNetType\/\w+\b/, '');
24 26 }
... ... @@ -37,18 +39,22 @@ Vue.use(VueClipboard);
37 39 Vue.use(ElementUI);
38 40 Vue.use(VueCookies);
39 41 Vue.use(VueClipboards);
40   -Vue.prototype.$axios = axios;
  42 +
41 43 Vue.prototype.$notify = Notification;
42 44 Vue.use(Contextmenu);
43 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 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 56 return response;
51   -}, function (error) {
  57 +}, (error) => {
52 58 // 对响应错误做点什么
53 59 if (error.response.status === 401) {
54 60 console.log("Received 401 Response")
... ... @@ -56,10 +62,22 @@ axios.interceptors.response.use(function (response) {
56 62 }
57 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 78 Vue.prototype.$cookies.config(60*30);
61 79  
62 80 new Vue({
63   - router: router,
64   - render: h => h(App),
  81 + router: router,
  82 + render: h => h(App),
65 83 }).$mount('#app')
... ...
web_src/static/js/mapConfig.js renamed to web_src/static/js/config.js
  1 +
  2 +window.baseUrl = ""
  3 +
1 4 // map组件全局参数, 注释此内容可以关闭地图功能
2 5 window.mapParam = {
3 6 // 开启/关闭地图功能
... ...
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 62 /**
63 63 * 1. 当为`true`的时候:视频画面做等比缩放后,完全填充canvas区域,画面不被拉伸,没有黑边,但画面显示不全。等同于 `setScaleMode(2)`
64 64 */
65   - isFullSize?: boolean;
  65 + isFullResize?: boolean;
66 66 /**
67 67 * 1. 当为`true`的时候:ws协议不检验是否以.flv为依据,进行协议解析。
68 68 */
... ... @@ -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,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") 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;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,iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAYAAAA6/NlyAAAHHklEQVRoQ91bfYwdVRX/nTvbPuuqlEQM0q4IRYMSP0KkaNTEEAokNUEDFr9iEIOiuCC2++4dl+Tti9nOmbfWFgryESPhH7V+IIpG8SN+Fr8qqKgQEKoUkQREwXTLs8495mze1tf35s2bfTu7ndf758y55/x+c879OvcMYYnbxMTEy4IgOImIxkRkrYisNsasUrPe+wNE9C8ielRE9iVJsndmZubBpYRES6E8DMNXeu83ENHrAJwO4OUARvrY+i+ABwDcLSJ7jDF3RlF0f9H4CiNcrVZPCIJgk4hcCOCNBQH9EYBveO93NRqNx4rQuWjCExMT64IguEJE3kdEq4sA1alDRDTsb02SZOfMzMxDi7ExMGFr7THGGCciVwKYG5PL0HTMb69UKtNTU1Ozg9gbiLC1diMRXQ/gxEGMFtDnQRHZHMfxHQvVtWDCzrkdANSredvfRWQ3Ee0F8DCAJwDs994nQRCM6qxNROu892uI6A0ATs2rWER2xHF8VV55lctN2Dl3LICvA3hzDgMPENFXROT2SqVyb71efzZHnzkRnRNGRkY2isj5AM7K0e/HAN7OzP/MIZuP8OTk5FiSJDpjnpylVER+YIzZEUXRN/MY7ydTrVbXE9FlRPT+LFkiesh7f1Ycx4/009nXw9balxDRLwC8OEPZ/SLi4jjWCCi8WWtfA2CKiN6WofzxIAhePz09/dfMj5P1slqtPj8IgntEZF0vORH51Ozs7NU7d+5sFs60Q2EYhpeKyDUZq8LDInJ6HMdP98KS6WHn3E8BvKlHZx2X72Xmry410Xb91trTiOjLAF7Rw+5uZu6FufcYds7pl7wiTSkRPSUi5zHzr5eT7LytWq32gmaz+a0MZ1zDzB9LxZ72sFqtbjDGfLcHmWeI6IwoinTfe8RarVYzzWbzJxnb2A3M/P1OgF0hPT4+XhkdHd0H4LgUNv8xxpy5devW3x4xpm2Gt2zZMjoyMnJ363DSCemJ/fv3j3XOLV2EnXMNXQ57hPIFURTdVgay8xhaq4geKVem4Jph5mr788MIV6vVtcYY9W5XI6Iboij6SJnIzmNxzl0E4Itp2IIgWDs9Pf23+XeHEQ7D8EYR+VBKx8eYeU0ZybaR1s3OxhSMNzLzh7sIb968+YUrVqxQ7z6na6ATlS6UOzG2Qlv366bj3bMHDx4c27Zt25P6/JCHnXO6Cf90yhe6l5lfXWbvto3nm4no0hSHXRVFkR56/k/YWvsbItJ0zGFNRC6K4/hLQ0JYt8FdW0si2hNF0RmHCLcSbWnr6pPM/CIAMgyEFaNz7tsAzuvEmyTJKZotmQtpa+04EV2bQuo6Zh4fFrItwu8C8PmUSP1oHMfXzxEOw3CXiGzqFPLen9NoNL43TIQ19UREmmRY0YF7FzO/k5xzLwWgYdCZaZj13h/faDT+PUyEW15OO/T8MQiCjUr4HAC6Ee/MG/+MmfNkN0r3Pay124jo4x3ADuiBRwl/EMBNKTF/SxzHl5SOTQ5AzrnLANyQsjxdooRrmk1I0TPFzPUc+ksnYq09l4i+k8aJrLXbiajr7EhEV0ZRlDZzl45gJyDNhRljfpkCdLt6WF2vIdDZPsDMnys9uxSA1tpXEdHvU1599qgknHHqu/moDOlWNkTTyu2rTGKMOfeonLQ0lFunv08AOBPAXu/9jkajsafnsgTgVma+eBjHcBbmrI3HXcxc1D1vab5b1tbyQKVSOb5erz9TGrQFAMk8POhWLI7jOwuwUxoV/Y6Hn2Hmy0uDtgAgc4RbZQt/Ttl7PrVy5crj6vW6L8BWKVS057TuAqAX0p3t3cz8hVKgLQDEIcLW2suJ6LoUnX9i5tMKsFUKFYcIZ6VpAWxiZr2xG/p2WCI+4yDxeKVSWXM0jOXDCE9OTq5JkuTRNDcS0U1RFKWdqobK612XaWEYflJEru7BYuhDu4tw66ShxSFpd0laD7meme8ZKre2gU0teXDOnQ2gV3q2FBfig37wnjUevVI/auhIlzwMSnYOe1bnPkUtWrXznuUualkM2b6EtWzJGKMlBaf0MrScZUuLJduXsAq07l1/DuCEDIP3iUi4VIVpRRCd19G3Ek8FtfTQe//DrAI1lSu69LBIogsirMK1Wm11s9n8GoC35AByH4DbvPe3r1q16g8LKS7NoXtRIrk83G4ha/bugURL93cD+Mt8+TAR6YT3j0ql8rtBC70HZb1gwmooDMO3eu+vJaKTBjXc6rfPe39ho9H41SL15O4+EOFWiGv5n2sViz83t8VuwWW9pRyY8Dxu59zJIqJVAhcP+JPHI8y8bL8SLJrwPHH9jYeI3kFEF+Ssmp/rqjN7HMe6lV2WVhjhdrRhGJ7a+lFrPYDXAtB667Q/X5723p+tNwLLwrbf1rIIEBryxpgTkyQZA6DlFccS0fMA6G84d6RVvBZht5eO/wEB1Kvsoc6vtAAAAABJRU5ErkJggg==") 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,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") 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,AAAAHGZ0eXBNNFYgAAACAGlzb21pc28yYXZjMQAAAAhmcmVlAAAGF21kYXTeBAAAbGliZmFhYyAxLjI4AABCAJMgBDIARwAAArEGBf//rdxF6b3m2Ui3lizYINkj7u94MjY0IC0gY29yZSAxNDIgcjIgOTU2YzhkOCAtIEguMjY0L01QRUctNCBBVkMgY29kZWMgLSBDb3B5bGVmdCAyMDAzLTIwMTQgLSBodHRwOi8vd3d3LnZpZGVvbGFuLm9yZy94MjY0Lmh0bWwgLSBvcHRpb25zOiBjYWJhYz0wIHJlZj0zIGRlYmxvY2s9MTowOjAgYW5hbHlzZT0weDE6MHgxMTEgbWU9aGV4IHN1Ym1lPTcgcHN5PTEgcHN5X3JkPTEuMDA6MC4wMCBtaXhlZF9yZWY9MSBtZV9yYW5nZT0xNiBjaHJvbWFfbWU9MSB0cmVsbGlzPTEgOHg4ZGN0PTAgY3FtPTAgZGVhZHpvbmU9MjEsMTEgZmFzdF9wc2tpcD0xIGNocm9tYV9xcF9vZmZzZXQ9LTIgdGhyZWFkcz02IGxvb2thaGVhZF90aHJlYWRzPTEgc2xpY2VkX3RocmVhZHM9MCBucj0wIGRlY2ltYXRlPTEgaW50ZXJsYWNlZD0wIGJsdXJheV9jb21wYXQ9MCBjb25zdHJhaW5lZF9pbnRyYT0wIGJmcmFtZXM9MCB3ZWlnaHRwPTAga2V5aW50PTI1MCBrZXlpbnRfbWluPTI1IHNjZW5lY3V0PTQwIGludHJhX3JlZnJlc2g9MCByY19sb29rYWhlYWQ9NDAgcmM9Y3JmIG1idHJlZT0xIGNyZj0yMy4wIHFjb21wPTAuNjAgcXBtaW49MCBxcG1heD02OSBxcHN0ZXA9NCB2YnZfbWF4cmF0ZT03NjggdmJ2X2J1ZnNpemU9MzAwMCBjcmZfbWF4PTAuMCBuYWxfaHJkPW5vbmUgZmlsbGVyPTAgaXBfcmF0aW89MS40MCBhcT0xOjEuMDAAgAAAAFZliIQL8mKAAKvMnJycnJycnJycnXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXiEASZACGQAjgCEASZACGQAjgAAAAAdBmjgX4GSAIQBJkAIZACOAAAAAB0GaVAX4GSAhAEmQAhkAI4AhAEmQAhkAI4AAAAAGQZpgL8DJIQBJkAIZACOAIQBJkAIZACOAAAAABkGagC/AySEASZACGQAjgAAAAAZBmqAvwMkhAEmQAhkAI4AhAEmQAhkAI4AAAAAGQZrAL8DJIQBJkAIZACOAAAAABkGa4C/AySEASZACGQAjgCEASZACGQAjgAAAAAZBmwAvwMkhAEmQAhkAI4AAAAAGQZsgL8DJIQBJkAIZACOAIQBJkAIZACOAAAAABkGbQC/AySEASZACGQAjgCEASZACGQAjgAAAAAZBm2AvwMkhAEmQAhkAI4AAAAAGQZuAL8DJIQBJkAIZACOAIQBJkAIZACOAAAAABkGboC/AySEASZACGQAjgAAAAAZBm8AvwMkhAEmQAhkAI4AhAEmQAhkAI4AAAAAGQZvgL8DJIQBJkAIZACOAAAAABkGaAC/AySEASZACGQAjgCEASZACGQAjgAAAAAZBmiAvwMkhAEmQAhkAI4AhAEmQAhkAI4AAAAAGQZpAL8DJIQBJkAIZACOAAAAABkGaYC/AySEASZACGQAjgCEASZACGQAjgAAAAAZBmoAvwMkhAEmQAhkAI4AAAAAGQZqgL8DJIQBJkAIZACOAIQBJkAIZACOAAAAABkGawC/AySEASZACGQAjgAAAAAZBmuAvwMkhAEmQAhkAI4AhAEmQAhkAI4AAAAAGQZsAL8DJIQBJkAIZACOAAAAABkGbIC/AySEASZACGQAjgCEASZACGQAjgAAAAAZBm0AvwMkhAEmQAhkAI4AhAEmQAhkAI4AAAAAGQZtgL8DJIQBJkAIZACOAAAAABkGbgCvAySEASZACGQAjgCEASZACGQAjgAAAAAZBm6AnwMkhAEmQAhkAI4AhAEmQAhkAI4AhAEmQAhkAI4AhAEmQAhkAI4AAAAhubW9vdgAAAGxtdmhkAAAAAAAAAAAAAAAAAAAD6AAABDcAAQAAAQAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAzB0cmFrAAAAXHRraGQAAAADAAAAAAAAAAAAAAABAAAAAAAAA+kAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAABAAAAAALAAAACQAAAAAAAkZWR0cwAAABxlbHN0AAAAAAAAAAEAAAPpAAAAAAABAAAAAAKobWRpYQAAACBtZGhkAAAAAAAAAAAAAAAAAAB1MAAAdU5VxAAAAAAALWhkbHIAAAAAAAAAAHZpZGUAAAAAAAAAAAAAAABWaWRlb0hhbmRsZXIAAAACU21pbmYAAAAUdm1oZAAAAAEAAAAAAAAAAAAAACRkaW5mAAAAHGRyZWYAAAAAAAAAAQAAAAx1cmwgAAAAAQAAAhNzdGJsAAAAr3N0c2QAAAAAAAAAAQAAAJ9hdmMxAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAALAAkABIAAAASAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGP//AAAALWF2Y0MBQsAN/+EAFWdCwA3ZAsTsBEAAAPpAADqYA8UKkgEABWjLg8sgAAAAHHV1aWRraEDyXyRPxbo5pRvPAyPzAAAAAAAAABhzdHRzAAAAAAAAAAEAAAAeAAAD6QAAABRzdHNzAAAAAAAAAAEAAAABAAAAHHN0c2MAAAAAAAAAAQAAAAEAAAABAAAAAQAAAIxzdHN6AAAAAAAAAAAAAAAeAAADDwAAAAsAAAALAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAAiHN0Y28AAAAAAAAAHgAAAEYAAANnAAADewAAA5gAAAO0AAADxwAAA+MAAAP2AAAEEgAABCUAAARBAAAEXQAABHAAAASMAAAEnwAABLsAAATOAAAE6gAABQYAAAUZAAAFNQAABUgAAAVkAAAFdwAABZMAAAWmAAAFwgAABd4AAAXxAAAGDQAABGh0cmFrAAAAXHRraGQAAAADAAAAAAAAAAAAAAACAAAAAAAABDcAAAAAAAAAAAAAAAEBAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAkZWR0cwAAABxlbHN0AAAAAAAAAAEAAAQkAAADcAABAAAAAAPgbWRpYQAAACBtZGhkAAAAAAAAAAAAAAAAAAC7gAAAykBVxAAAAAAALWhkbHIAAAAAAAAAAHNvdW4AAAAAAAAAAAAAAABTb3VuZEhhbmRsZXIAAAADi21pbmYAAAAQc21oZAAAAAAAAAAAAAAAJGRpbmYAAAAcZHJlZgAAAAAAAAABAAAADHVybCAAAAABAAADT3N0YmwAAABnc3RzZAAAAAAAAAABAAAAV21wNGEAAAAAAAAAAQAAAAAAAAAAAAIAEAAAAAC7gAAAAAAAM2VzZHMAAAAAA4CAgCIAAgAEgICAFEAVBbjYAAu4AAAADcoFgICAAhGQBoCAgAECAAAAIHN0dHMAAAAAAAAAAgAAADIAAAQAAAAAAQAAAkAAAAFUc3RzYwAAAAAAAAAbAAAAAQAAAAEAAAABAAAAAgAAAAIAAAABAAAAAwAAAAEAAAABAAAABAAAAAIAAAABAAAABgAAAAEAAAABAAAABwAAAAIAAAABAAAACAAAAAEAAAABAAAACQAAAAIAAAABAAAACgAAAAEAAAABAAAACwAAAAIAAAABAAAADQAAAAEAAAABAAAADgAAAAIAAAABAAAADwAAAAEAAAABAAAAEAAAAAIAAAABAAAAEQAAAAEAAAABAAAAEgAAAAIAAAABAAAAFAAAAAEAAAABAAAAFQAAAAIAAAABAAAAFgAAAAEAAAABAAAAFwAAAAIAAAABAAAAGAAAAAEAAAABAAAAGQAAAAIAAAABAAAAGgAAAAEAAAABAAAAGwAAAAIAAAABAAAAHQAAAAEAAAABAAAAHgAAAAIAAAABAAAAHwAAAAQAAAABAAAA4HN0c3oAAAAAAAAAAAAAADMAAAAaAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAACMc3RjbwAAAAAAAAAfAAAALAAAA1UAAANyAAADhgAAA6IAAAO+AAAD0QAAA+0AAAQAAAAEHAAABC8AAARLAAAEZwAABHoAAASWAAAEqQAABMUAAATYAAAE9AAABRAAAAUjAAAFPwAABVIAAAVuAAAFgQAABZ0AAAWwAAAFzAAABegAAAX7AAAGFwAAAGJ1ZHRhAAAAWm1ldGEAAAAAAAAAIWhkbHIAAAAAAAAAAG1kaXJhcHBsAAAAAAAAAAAAAAAALWlsc3QAAAAlqXRvbwAAAB1kYXRhAAAAAQAAAABMYXZmNTUuMzMuMTAw"),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}));
... ...