Ver Fonte

沅陵管理平台智慧路灯静态页面搭建

nahida há 1 ano atrás
pai
commit
5231ca4472

+ 11 - 5
components.d.ts

@@ -7,21 +7,24 @@ export {}
 /* prettier-ignore */
 declare module 'vue' {
   export interface GlobalComponents {
+    AddOrModifyModal: typeof import('./src/components/AddOrModifyModal.vue')['default']
     ElButton: typeof import('element-plus/es')['ElButton']
+    ElCard: typeof import('element-plus/es')['ElCard']
+    ElCol: typeof import('element-plus/es')['ElCol']
     ElContainer: typeof import('element-plus/es')['ElContainer']
-    ElForm: typeof import('element-plus/es')['ElForm']
-    ElFormItem: typeof import('element-plus/es')['ElFormItem']
     ElHeader: typeof import('element-plus/es')['ElHeader']
     ElIcon: typeof import('element-plus/es')['ElIcon']
     ElInput: typeof import('element-plus/es')['ElInput']
+    ElLink: typeof import('element-plus/es')['ElLink']
     ElMain: typeof import('element-plus/es')['ElMain']
     ElMenu: typeof import('element-plus/es')['ElMenu']
     ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
-    ElMenuItemGroup: typeof import('element-plus/es')['ElMenuItemGroup']
+    ElRow: typeof import('element-plus/es')['ElRow']
     ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
+    ElSpin: typeof import('element-plus/es')['ElSpin']
     ElSubMenu: typeof import('element-plus/es')['ElSubMenu']
-    ElTable: typeof import('element-plus/es')['ElTable']
-    ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
+    ElSwitch: typeof import('element-plus/es')['ElSwitch']
+    ElTag: typeof import('element-plus/es')['ElTag']
     IconCommunity: typeof import('./src/components/icons/IconCommunity.vue')['default']
     IconDocumentation: typeof import('./src/components/icons/IconDocumentation.vue')['default']
     IconEcosystem: typeof import('./src/components/icons/IconEcosystem.vue')['default']
@@ -31,4 +34,7 @@ declare module 'vue' {
     RouterLink: typeof import('vue-router')['RouterLink']
     RouterView: typeof import('vue-router')['RouterView']
   }
+  export interface ComponentCustomProperties {
+    vLoading: typeof import('element-plus/es')['ElLoadingDirective']
+  }
 }

+ 138 - 0
global.d.ts

@@ -0,0 +1,138 @@
+declare class DHAlarmWeb {
+  localStream: MediaStream | null;
+  pc: RTCPeerConnection | null;
+  webrtcWs: WebSocket | null;
+  alarmWs: WebSocket | null;
+  audioWs: { [key: number]: WebSocket };
+  deviceAudioWs: { [key: number]: WebSocket };
+  started: boolean;
+  webrtcSocketOpened: boolean;
+  alarmSocketOpened: number;
+  clientid: string | null;
+  roomid: string | null;
+  onStreamCallBack: ((stream: MediaStream) => void) | null;
+  alarmUrl: string | null;
+  webrtcUrl: string | null;
+  onAlarmMessage: ((message: string) => void) | null;
+  onLoging: ((status: any) => void) | null;
+  onDeviceList: ((deviceList: any) => void) | null;
+  onNotify: ((notification: any) => void) | null;
+  onPlayRT: ((params: any) => void) | null;
+  onPlayRTState: ((state: any) => void) | null;
+  onDeviceRemove: ((device: any) => void) | null;
+  onParseMsgError: ((error: any) => void) | null;
+  uname: string | null;
+  pwd: string | null;
+  isLogin: boolean;
+  loginHandle: number | null;
+  deviceId: number | null;
+  context: AudioContext | null;
+  recorder: ScriptProcessorNode | null;
+  audioInput: MediaStreamAudioSourceNode | null;
+  wfs: { [key: number]: any };
+  player: { [key: number]: any };
+  bufferPool: { [key: number]: any };
+  isDeviceAudioPlay: { [key: number]: boolean };
+  onAlarmServerClosed: (() => void) | null;
+  keepAliveInterval: NodeJS.Timeout | null;
+  onDeviceAudioData: ((data: any, deviceId: number) => void) | null;
+  onLocalAudioData: ((data: any) => void) | null;
+  onDeviceVideoData: ((frame: any, deviceId: number) => void) | null;
+  onDHAlarmWebError: ((error: any) => void) | null;
+  hasDeviceList: boolean;
+  loginState: number;
+  loginTimer: NodeJS.Timeout | null;
+  deviceListTimer: NodeJS.Timeout | null;
+  loginInterval: number;
+  talkDeviceIds: number[];
+  multiTalkDeviceIds: number[];
+  notStartBCWsDids: number[];
+  multiTalkFilePath: string | null;
+  multiFileTalkIntv: number;
+  multiTalkType: number;
+  sendIds: number[];
+  bufferFileArr_8k: ArrayBuffer[];
+  bufferFileArr_16k: ArrayBuffer[];
+  broadcastType: number;
+  remainFileBuffer_8k: number;
+  remainFileBuffer_16k: number;
+  bcPlayState: string;
+  uploadFilePath: string | null;
+  audioFileStream: any | null;
+  audioUploadWs: WebSocket | null;
+  uploadFileArr: ArrayBuffer[];
+  totalUploadFileArr: ArrayBuffer[];
+  overInter: NodeJS.Timeout | number;
+  tunnelDataId: number;
+  tunnelQueue: any[];
+  tunnelReqTimeout: number;
+  pbAudioWs: { [key: number]: WebSocket };
+  pbWfs: { [key: number]: any };
+  pbPlayer: { [key: number]: any };
+  pbBufferPool: { [key: number]: any };
+  dataWsPort: number;
+  mediaWsPort: number;
+  onGroupList: ((groupList: any) => void) | null;
+  onAddGroup: ((group: any) => void) | null;
+  onEditGroup: ((group: any) => void) | null;
+  onDelGroup: ((groupId: number) => void) | null;
+  onUserList: ((userList: any) => void) | null;
+  onUserGroups: ((userGroups: any) => void) | null;
+  onAddUser: ((user: any) => void) | null;
+  onEditPassword: ((userId: number, newPassword: string) => void) | null;
+  onDelUser: ((userId: number) => void) | null;
+  onAuthorizeGroup: ((groupId: number, userId: number) => void) | null;
+  onEditDevice: ((deviceId: number, params: any) => void) | null;
+  onMoveDevice: ((deviceId: number, groupId: number) => void) | null;
+  onGetWebPush: ((webPush: any) => void) | null;
+  onEditWebPush: ((webPushId: number, params: any) => void) | null;
+  onPlayAudioFileEnd: (() => void) | null;
+  onAlarmMultiTalkStopped: ((deviceId: number) => void) | null;
+  onMultiTalkStartFinished: (() => void) | null;
+  onMultiTalkCountLimit: (() => void) | null;
+  onMultiTalkClosedError: ((deviceId: number, isLast: boolean) => void) | null;
+  onStartBroadcast: ((params: any) => void) | null;
+  onBroadcastWsClosed: (() => void) | null;
+  onUploadAudioFile: ((uploadInfo: any) => void) | null;
+  onDeleteAudioFile: ((fileId: number) => void) | null;
+  onDecodeAudioError: ((error: any) => void) | null;
+  onUploadAudioFileEnd: (() => void) | null;
+  onGetAudioFileList: ((fileList: any) => void) | null;
+  onGetBCTaskList: ((taskList: any) => void) | null;
+  onUploadBCTask: ((task: any) => void) | null;
+  onEditBCTask: ((taskId: number, params: any) => void) | null;
+  onDeleteBCTask: ((taskId: number) => void) | null;
+  onConfigTunnel: ((tunnelConfig: any) => void) | null;
+  onGetDeviceExtra: ((extraInfo: any) => void) | null;
+  onSetDeviceExtra: ((deviceId: number, extraParams: any) => void) | null;
+  onGetRecordList: ((recordList: any) => void) | null;
+
+  constructor();
+
+  openAlarmSocket(): void;
+  onAlarmSocketOpened(): void;
+  registerAlarm(): void;
+  onAlarmSocketMessage(event: MessageEvent): void;
+  onAlarmSocketError(event: Event): void;
+  onAlarmSocketClosed(): void;
+  sendAlarmMessage(message: any): void;
+  sendAlarmMessageCallBack(message: any, callback: () => void): void;
+  processAlarmMessage(data: string): void;
+  setWebsocketPort(ports: { dataWsPort: number, mediaWsPort: number }): void;
+  login(username: string, password: string, serverAddress: string): void;
+  logout(loginHandle: number): void;
+  playRT(elementId: string, deviceId: number, loginHandle: number, preview?: boolean): void;
+  stopRT(deviceId: number, loginHandle: number): void;
+  doControl(deviceId: number, loginHandle: number, index: number): void;
+  playVideo(elementId: string, deviceId: number, loginHandle: number): void;
+  onVideoFrame(frame: any, deviceId: number): void;
+  startTalk(deviceId: number): void;
+  stopTalk(deviceId: number): void;
+  registerTalk(deviceId: number): void;
+  openAudio(loginHandle: number, deviceId: number, startBroadcast?: boolean, sendAudio?: boolean): void;
+  onAudioSocketOpened(deviceId: number): void;
+  onAudioSocketMessage(event: MessageEvent, deviceId: number, startBroadcast?: boolean, sendAudio?: boolean): void;
+  onAudioSocketError(event: Event, deviceId: number): void;
+  onAudioSocketClosed(deviceId: number, sendAudio?: boolean): void;
+  sendAudio(deviceId?: number): void;
+}

+ 1 - 0
index.html

@@ -5,6 +5,7 @@
     <link rel="icon" href="/favicon.ico">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <title>Vite App</title>
+    <script src="public/dhWebSdk/dhsdk.min.js"></script>
   </head>
   <body>
     <div id="app"></div>

+ 78 - 0
package-lock.json

@@ -10,9 +10,11 @@
       "dependencies": {
         "@element-plus/icons-vue": "^2.3.1",
         "@vueuse/core": "^12.0.0",
+        "echarts": "^5.5.1",
         "element-plus": "^2.9.0",
         "pinia": "^2.2.6",
         "vue": "^3.5.13",
+        "vue-echarts": "^7.0.3",
         "vue-router": "^4.4.5"
       },
       "devDependencies": {
@@ -3628,6 +3630,22 @@
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/echarts": {
+      "version": "5.5.1",
+      "resolved": "https://registry.npmmirror.com/echarts/-/echarts-5.5.1.tgz",
+      "integrity": "sha512-Fce8upazaAXUVUVsjgV6mBnGuqgO+JNDlcgF79Dksy4+wgGpQB2lmYoO4TSweFg/mZITdpGHomw/cNBJZj1icA==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "tslib": "2.3.0",
+        "zrender": "5.6.0"
+      }
+    },
+    "node_modules/echarts/node_modules/tslib": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz",
+      "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==",
+      "license": "0BSD"
+    },
     "node_modules/editorconfig": {
       "version": "1.0.4",
       "resolved": "https://registry.npmmirror.com/editorconfig/-/editorconfig-1.0.4.tgz",
@@ -9244,6 +9262,51 @@
         }
       }
     },
+    "node_modules/vue-echarts": {
+      "version": "7.0.3",
+      "resolved": "https://registry.npmmirror.com/vue-echarts/-/vue-echarts-7.0.3.tgz",
+      "integrity": "sha512-/jSxNwOsw5+dYAUcwSfkLwKPuzTQ0Cepz1LxCOpj2QcHrrmUa/Ql0eQqMmc1rTPQVrh2JQ29n2dhq75ZcHvRDw==",
+      "license": "MIT",
+      "dependencies": {
+        "vue-demi": "^0.13.11"
+      },
+      "peerDependencies": {
+        "@vue/runtime-core": "^3.0.0",
+        "echarts": "^5.5.1",
+        "vue": "^2.7.0 || ^3.1.1"
+      },
+      "peerDependenciesMeta": {
+        "@vue/runtime-core": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/vue-echarts/node_modules/vue-demi": {
+      "version": "0.13.11",
+      "resolved": "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.13.11.tgz",
+      "integrity": "sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==",
+      "hasInstallScript": true,
+      "license": "MIT",
+      "bin": {
+        "vue-demi-fix": "bin/vue-demi-fix.js",
+        "vue-demi-switch": "bin/vue-demi-switch.js"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/antfu"
+      },
+      "peerDependencies": {
+        "@vue/composition-api": "^1.0.0-rc.1",
+        "vue": "^3.0.0-0 || ^2.6.0"
+      },
+      "peerDependenciesMeta": {
+        "@vue/composition-api": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/vue-eslint-parser": {
       "version": "9.4.3",
       "resolved": "https://registry.npmmirror.com/vue-eslint-parser/-/vue-eslint-parser-9.4.3.tgz",
@@ -9633,6 +9696,21 @@
       "funding": {
         "url": "https://github.com/sponsors/sindresorhus"
       }
+    },
+    "node_modules/zrender": {
+      "version": "5.6.0",
+      "resolved": "https://registry.npmmirror.com/zrender/-/zrender-5.6.0.tgz",
+      "integrity": "sha512-uzgraf4njmmHAbEUxMJ8Oxg+P3fT04O+9p7gY+wJRVxo8Ge+KmYv0WJev945EH4wFuc4OY2NLXz46FZrWS9xJg==",
+      "license": "BSD-3-Clause",
+      "dependencies": {
+        "tslib": "2.3.0"
+      }
+    },
+    "node_modules/zrender/node_modules/tslib": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz",
+      "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==",
+      "license": "0BSD"
     }
   }
 }

+ 2 - 0
package.json

@@ -16,9 +16,11 @@
   "dependencies": {
     "@element-plus/icons-vue": "^2.3.1",
     "@vueuse/core": "^12.0.0",
+    "echarts": "^5.5.1",
     "element-plus": "^2.9.0",
     "pinia": "^2.2.6",
     "vue": "^3.5.13",
+    "vue-echarts": "^7.0.3",
     "vue-router": "^4.4.5"
   },
   "devDependencies": {

+ 2217 - 0
public/dhWebSdk/dhsdk.min.js

@@ -0,0 +1,2217 @@
+/**@license dhsdk v2.7.0 Copyright (c) 2021-12-13 diihoo*/
+"use strict";
+var DHAlarm = DHAlarm || {};
+var DHAlarmWeb = function () {
+  this.localStream = null;
+  this.pc = null;
+  this.webrtcWs = null;
+  this.alarmWs = null;
+  this.audioWs = {};
+  this.deviceAudioWs = {};
+  this.started = false;
+  this.webrtcSocketOpened = false;
+  this.alarmSocketOpened = 0;
+  this.clientid = null;
+  this.roomid = null;
+  this.onStreamCallBack = null;
+  this.alarmUrl = null;
+  this.webrtcUrl = null;
+  this.onAlarmMessage = null;
+  this.onLoging = null;
+  this.onDeviceList = null;
+  this.onNotify = null;
+  this.onPlayRT = null;
+  this.onPlayRTState = null;
+  this.onDeviceRemove = null;
+  this.onParseMsgError = null;
+  this.uname = null;
+  this.pwd = null;
+  this.isLogin = false;
+  this.loginHandle = null;
+  this.deviceId = null;
+  this.context = null;
+  this.recorder = null;
+  this.audioInput = null;
+  this.wfs = {};
+  DHAlarm.wrc = this;
+  this.player = {};
+  this.bufferPool = {};
+  this.isDeviceAudioPlay = {};
+  this.onAlarmServerClosed = null;
+  this.keepAliveInterval = null;
+  this.onDeviceAudioData = null;
+  this.onLocalAudioData = null;
+  this.onDeviceVideoData = null;
+  this.onDHAlarmWebError = null;
+  this.hasDeviceList = false;
+  this.loginState = 0;
+  this.loginTimer = null;
+  this.deviceListTimer = null;
+  this.loginInterval = 0;
+  this.talkDeviceIds = [];
+  this.multiTalkDeviceIds = [];
+  this.notStartBCWsDids = [];
+  this.multiTalkFilePath = null;
+  this.multiFileTalkIntv = 0;
+  this.multiTalkType = 0;
+  this.sendIds = [];
+  this.bufferFileArr_8k = [];
+  this.bufferFileArr_16k = [];
+  this.broadcastType = 0;
+  this.remainFileBuffer_8k = 0;
+  this.remainFileBuffer_16k = 0;
+  this.bcPlayState = "pause";
+  this.uploadFilePath = null;
+  this.audioFileStream = null;
+  this.audioUploadWs = null;
+  this.uploadFileArr = [];
+  this.totalUploadFileArr = [];
+  this.overInter = 0;
+  this.tunnelDataId = 1;
+  this.tunnelQueue = [];
+  this.tunnelReqTimeout = 20;
+  this.pbAudioWs = {};
+  this.pbWfs = {};
+  this.pbPlayer = {};
+  this.pbBufferPool = {};
+  this.dataWsPort = 8088;
+  this.mediaWsPort = 8088;
+  this.onGroupList = null;
+  this.onAddGroup = null;
+  this.onEditGroup = null;
+  this.onDelGroup = null;
+  this.onUserList = null;
+  this.onUserGroups = null;
+  this.onAddUser = null;
+  this.onEditPassword = null;
+  this.onDelUser = null;
+  this.onAuthorizeGroup = null;
+  this.onEditDevice = null;
+  this.onMoveDevice = null;
+  this.onGetWebPush = null;
+  this.onEditWebPush = null;
+  this.onPlayAudioFileEnd = null;
+  this.onAlarmMultiTalkStopped = null;
+  this.onMultiTalkStartFinished = null;
+  this.onMultiTalkCountLimit = null;
+  this.onMultiTalkClosedError = null;
+  this.onStartBroadcast = null;
+  this.onBroadcastWsClosed = null;
+  this.onUploadAudioFile = null;
+  this.onDeleteAudioFile = null;
+  this.onDecodeAudioError = null;
+  this.onUploadAudioFileEnd = null;
+  this.onGetAudioFileList = null;
+  this.onGetBCTaskList = null;
+  this.onUploadBCTask = null;
+  this.onEditBCTask = null;
+  this.onDeleteBCTask = null;
+  this.onConfigTunnel = null;
+  this.onGetDeviceExtra = null;
+  this.onSetDeviceExtra = null;
+  this.onGetRecordList = null
+};
+window.onbeforeunload = function () {
+}.bind(this);
+DHAlarmWeb.prototype.openAlarmSocket = function () {
+  console.log("openAlarmSocket");
+  this.alarmSocketOpened = 1;
+  this.alarmWs = new WebSocket(this.alarmUrl);
+  this.alarmWs.onopen = this.onAlarmSocketOpened.bind(this);
+  this.alarmWs.onmessage = this.onAlarmSocketMessage.bind(this);
+  this.alarmWs.onclose = this.onAlarmSocketClosed.bind(this);
+  this.alarmWs.onerror = this.onAlarmSocketError.bind(this)
+};
+DHAlarmWeb.prototype.onAlarmSocketOpened = function () {
+  this.alarmSocketOpened = 2;
+  console.log("onAlarmSocketOpened");
+  this.registerAlarm()
+};
+DHAlarmWeb.prototype.registerAlarm = function () {
+  var e = {cmd: "register", msg: ""};
+  this.alarmWs.send(JSON.stringify(e))
+};
+DHAlarmWeb.prototype.onAlarmSocketMessage = function (e) {
+  try {
+    var t = JSON.parse(e.data);
+    this.clientid = t.clientid
+  } catch (t) {
+    console.log(e)
+  }
+  this.processAlarmMessage(e.data)
+};
+DHAlarmWeb.prototype.onAlarmSocketError = function (e) {
+  console.log("onAlarmSocketError: " + JSON.stringify(e));
+  this.loginState = 0;
+  var t = {method: "systemManager.onError", error: "socketError"};
+  var i = {clientid: "", error: "fail", msg: t};
+  if (this.onDHAlarmWebError) {
+    this.onDHAlarmWebError(i)
+  }
+  this.clearLoginInt()
+};
+DHAlarmWeb.prototype.onAlarmSocketClosed = function () {
+  console.log("onAlarmSocketClosed");
+  var e = this.loginState;
+  var t = this.alarmSocketOpened;
+  var i = {clientid: "", error: "fail", msg: {method: "systemManager.onError", error: "loginTimeout"}};
+  this.alarmSocketOpened = 4;
+  this.loginState = 0;
+  this.clearKeepAliveInt();
+  this.clearLoginInt();
+  if (this.onDHAlarmWebError && e == 3) {
+    this.onDHAlarmWebError(i)
+  }
+  if (this.onAlarmServerClosed && t != 3) {
+    this.onAlarmServerClosed()
+  }
+};
+DHAlarmWeb.prototype.sendAlarmMessage = function (e) {
+  var t = JSON.stringify(e);
+  if (this.alarmWs && this.alarmWs.readyState === WebSocket.OPEN) {
+    this.alarmWs.send(t)
+  }
+};
+DHAlarmWeb.prototype.sendAlarmMessageCallBack = function (e, t) {
+  var i = JSON.stringify(e);
+  this.alarmWs.send(i)
+};
+DHAlarmWeb.prototype.processAlarmMessage = function (e) {
+  if (this.onAlarmMessage) {
+    this.onAlarmMessage(e)
+  }
+  try {
+    var t = JSON.parse(e);
+    var i = JSON.parse(t.msg);
+    if (i.method == "eventManager.notify") {
+      var s = i.params;
+      if (s.code == "DeviceStatus" && s.action == "Start") {
+        if (this.multiTalkType == 1) {
+          this.stopMultiMicTalk(this.loginHandle, false, [s.deviceId])
+        } else if (this.multiTalkType == 2) {
+          this.stopMultiFileTalk(this.loginHandle, false, [s.deviceId])
+        }
+        if (this.onAlarmMultiTalkStopped) {
+          this.onAlarmMultiTalkStopped(s.deviceId)
+        }
+      }
+      if (this.onNotify) {
+        this.onNotify(i)
+      }
+    } else if (i.method == "configManager.onDeviceList") {
+      this.hasDeviceList = true;
+      this.clearDeviceListTimer();
+      if (this.onDeviceList) {
+        this.onDeviceList(i)
+      }
+    } else if (i.method == "systemManager.onLogin") {
+      this.clearLoginTimer();
+      if (i.error == "success") {
+        this.loginHandle = i.params.loginHandle, this.clientid = t.clientid, this.loginState = 2;
+        this.clearKeepAliveInt();
+        this.keepAliveInterval = setInterval(function () {
+          var e = {
+            cmd: "send",
+            clientid: t.clientid,
+            msg: JSON.stringify({method: "systemManager.keepAlive", params: {loginHandle: i.params.loginHandle}})
+          };
+          this.sendAlarmMessage(e)
+        }.bind(this), 1e4);
+        this.clearDeviceListTimer();
+        this.deviceListTimer = setTimeout(function () {
+          if (!this.hasDeviceList) {
+            var e = {clientid: "", error: "fail", msg: {method: "systemManager.onError", error: "dataTimeout"}};
+            if (this.onDHAlarmWebError) {
+              this.onDHAlarmWebError(e)
+            }
+          }
+        }.bind(this), 1e4)
+      } else {
+        this.loginState = 0
+      }
+      if (this.onLogin) {
+        this.onLogin(i)
+      }
+    } else if (i.method == "systemManager.onPlayRT") {
+      if (this.onPlayRT) {
+        this.onPlayRT(i)
+      }
+    } else if (i.method == "systemManager.onPlayRTState") {
+      if (this.onPlayRTState) {
+        this.onPlayRTState(i)
+      }
+    } else if (i.method == "configManager.onDeviceRemove") {
+      if (this.onDeviceRemove) {
+        this.onDeviceRemove(i)
+      }
+    } else if (i.method == "configManager.onGroupList") {
+      if (this.onGroupList) {
+        this.onGroupList(i)
+      }
+    } else if (i.method == "configManager.onAddGroup") {
+      if (this.onAddGroup) {
+        this.onAddGroup(i)
+      }
+    } else if (i.method == "configManager.onEditGroup") {
+      if (this.onEditGroup) {
+        this.onEditGroup(i)
+      }
+    } else if (i.method == "configManager.onDelGroup") {
+      if (this.onDelGroup) {
+        this.onDelGroup(i)
+      }
+    } else if (i.method == "configManager.onUserList") {
+      if (this.onUserList) {
+        this.onUserList(i)
+      }
+    } else if (i.method == "configManager.onUserGroups") {
+      if (this.onUserGroups) {
+        this.onUserGroups(i)
+      }
+    } else if (i.method == "configManager.onAddUser") {
+      if (this.onAddUser) {
+        this.onAddUser(i)
+      }
+    } else if (i.method == "configManager.onEditPassword") {
+      if (this.onEditPassword) {
+        this.onEditPassword(i)
+      }
+    } else if (i.method == "configManager.onDelUser") {
+      if (this.onDelUser) {
+        this.onDelUser(i)
+      }
+    } else if (i.method == "configManager.onAuthorizeGroup") {
+      if (this.onAuthorizeGroup) {
+        this.onAuthorizeGroup(i)
+      }
+    } else if (i.method == "configManager.onEditDevice") {
+      if (this.onEditDevice) {
+        this.onEditDevice(i)
+      }
+    } else if (i.method == "configManager.onMoveDevice") {
+      if (this.onMoveDevice) {
+        this.onMoveDevice(i)
+      }
+    } else if (i.method == "configManager.onGetWebPush") {
+      if (this.onGetWebPush) {
+        this.onGetWebPush(i)
+      }
+    } else if (i.method == "configManager.onEditWebPush") {
+      if (this.onEditWebPush) {
+        this.onEditWebPush(i)
+      }
+    } else if (i.method == "deviceManager.onStartBroadcast") {
+      if (this.onStartBroadcast) {
+        this.onStartBroadcast(i)
+      }
+    } else if (i.method == "audioManager.onGetAudioFileList") {
+      if (this.onGetAudioFileList) {
+        this.onGetAudioFileList(i)
+      }
+    } else if (i.method == "audioManager.onUploadAudioFile") {
+      if (this.onUploadAudioFile) {
+        this.onUploadAudioFile(i)
+      }
+      if (i.error == "success") {
+        if (this.audioUploadWs && this.audioUploadWs.readyState == this.audioUploadWs.OPEN) {
+          for (var a = 0; a < 50; a++) {
+            if (this.uploadFileArr.length == 0) break;
+            this.audioUploadWs.send(this.uploadFileArr.shift())
+          }
+          if (this.totalUploadFileArr.length <= 50 && this.uploadFileArr.length == 0) {
+            this.audioUploadWs.send("OVER")
+          }
+          if (this.overInter > 0) return;
+          this.overInter = setInterval(function () {
+            if (this.overInter > 0) {
+              if (this.uploadFileArr.length == 0) {
+                this.audioUploadWs.send("OVER")
+              } else {
+                this.audioUploadWs.send("CANCEL")
+              }
+            }
+          }.bind(this), 1e4)
+        } else {
+          this.openAudioUploadWs(this.loginHandle)
+        }
+      }
+    } else if (i.method == "audioManager.onDeleteAudioFile") {
+      if (this.onDeleteAudioFile) {
+        this.onDeleteAudioFile(i)
+      }
+    } else if (i.method == "audioManager.onGetBCTaskList") {
+      if (this.onGetBCTaskList) {
+        this.onGetBCTaskList(i)
+      }
+    } else if (i.method == "audioManager.onUploadBCTask") {
+      if (this.onUploadBCTask) {
+        this.onUploadBCTask(i)
+      }
+    } else if (i.method == "audioManager.onEditBCTask") {
+      if (this.onEditBCTask) {
+        this.onEditBCTask(i)
+      }
+    } else if (i.method == "audioManager.onDeleteBCTask") {
+      if (this.onDeleteBCTask) {
+        this.onDeleteBCTask(i)
+      }
+    } else if (i.method == "deviceManager.onConfigTunnel") {
+      var r = JSON.parse(i.params.tunnelData);
+      if (r == null) return;
+      var n = this.tunnelQueue.findIndex(e => e.id == r.id);
+      if (n == -1) {
+        if (this.onConfigTunnel) {
+          this.onConfigTunnel(i)
+        }
+        return
+      }
+      var o = this.tunnelQueue.splice(n, 1)[0];
+      var l = {};
+      if (this.onConfigTunnel) {
+        i.id = o.data.requestId;
+        this.onConfigTunnel(i)
+      }
+      if (o.method == "setBroadcastVolume") {
+        if (this.onSetBroadcastVolume) {
+          l.id = o.data.requestId;
+          l.volume = o.data.volume;
+          i.params.reqData = l;
+          this.onSetBroadcastVolume(i.params)
+        }
+      } else if (o.method == "getBroadcastVolume") {
+        if (this.onGetBroadcastVolume) {
+          l.id = o.data.requestId;
+          i.params.reqData = l;
+          this.onGetBroadcastVolume(i.params)
+        }
+      } else if (o.method == "configPayStatus") {
+        if (this.onConfigPayStatus) {
+          l.id = o.data.requestId;
+          i.params.reqData = l;
+          this.onConfigPayStatus(i.params)
+        }
+      } else if (o.method == "getDeviceVolume") {
+        if (this.onGetDeviceVolume) {
+          l.id = o.data.requestId;
+          l.type = o.data.type;
+          i.params.reqData = l;
+          this.onGetDeviceVolume(i.params)
+        }
+      } else if (o.method == "setDeviceVolume") {
+        if (this.onSetDeviceVolume) {
+          l.id = o.data.requestId;
+          l.type = o.data.type;
+          l.volume = o.data.volume;
+          i.params.reqData = l;
+          this.onSetDeviceVolume(i.params)
+        }
+      } else if (o.method == "getAudioOutputChannels") {
+        if (this.onGetAudioOutputChannels) {
+          l.id = o.data.requestId;
+          i.params.reqData = l;
+          this.onGetAudioOutputChannels(i.params)
+        }
+      }
+    } else if (i.method == "deviceManager.onGetDeviceExtra") {
+      if (this.onGetDeviceExtra) {
+        this.onGetDeviceExtra(i)
+      }
+    } else if (i.method == "deviceManager.onSetDeviceExtra") {
+      if (this.onSetDeviceExtra) {
+        this.onSetDeviceExtra(i)
+      }
+    } else if (i.method == "deviceManager.onGetRecordList") {
+      if (this.onGetRecordList) {
+        this.onGetRecordList(i)
+      }
+    }
+  } catch (e) {
+    if (this.onParseMsgError) {
+      this.onParseMsgError(t)
+    }
+    console.log(e)
+  }
+};
+DHAlarmWeb.prototype.setWebsocketPort = function (e) {
+  this.dataWsPort = e.dataWsPort;
+  this.mediaWsPort = e.mediaWsPort
+};
+DHAlarmWeb.prototype.login = function (e, t, i) {
+  if (!i) {
+    return
+  }
+  this.alarmUrl = "wss://" + i + ":" + this.dataWsPort + "/ws";
+  this.webrtcUrl = "wss://" + i + ":8089/ws";
+  this.uname = e;
+  this.pwd = t;
+  if (this.loginState != 0 && this.loginState != 3) return;
+  if (this.alarmUrl == "" || this.alarmSocketOpened == 0 || this.alarmSocketOpened == 4) {
+    this.openAlarmSocket()
+  }
+  this.loginState = 1;
+  this.clearLoginInt();
+  this.loginInterval = setInterval(function () {
+    if (DHAlarm.wrc.alarmSocketOpened == 2) {
+      this.clearLoginInt();
+      var i = {method: "systemManager.login", params: {userName: e, password: t}};
+      var s = {cmd: "send", msg: JSON.stringify(i)};
+      DHAlarm.wrc.sendAlarmMessage(s);
+      this.clearLoginTimer();
+      this.loginTimer = setTimeout(function () {
+        if (this.loginState == 1) {
+          this.loginState = 3;
+          this.closeAlarmWs()
+        }
+      }.bind(this), 1e4)
+    }
+  }.bind(this), 1e3)
+};
+DHAlarmWeb.prototype.logout = function (e) {
+  if (!e) return;
+  var t = {method: "systemManager.logout", params: {loginHandle: parseInt(e)}};
+  var i = {cmd: "send", msg: JSON.stringify(t)};
+  this.sendAlarmMessage(i);
+  var s = {cmd: "deregister", msg: ""};
+  this.sendAlarmMessage(s);
+  this.clientid = null;
+  this.clearKeepAliveInt();
+  this.clearLoginInt();
+  this.clearLoginTimer();
+  this.clearDeviceListTimer();
+  this.hasDeviceList = false;
+  this.loginState = 0;
+  this.closeAlarmWs();
+  for (var a = 0; a < this.audioWs.length; a++) {
+    if (this.audioWs[a]) {
+      this.audioWs[a].close()
+    }
+    if (this.deviceAudioWs[a]) {
+      this.deviceAudioWs[a].close()
+    }
+    if (this.player[a]) {
+      this.player[a].destroy()
+    }
+  }
+  for (var a = 0; a < this.pbAudioWs.length; a++) {
+    if (this.pbAudioWs[a]) {
+      this.pbAudioWs[a].close()
+    }
+    if (this.pbWfs[a]) {
+      this.pbWfs[a].close()
+    }
+    if (this.pbPlayer[a]) {
+      this.pbPlayer[a].destroy()
+    }
+  }
+};
+DHAlarmWeb.prototype.playRT = function (e, t, i, s) {
+  if (!t || !i) return;
+  var a = {method: "deviceManager.playRT", params: {deviceId: parseInt(t), loginHandle: parseInt(i), preview: false}};
+  var r = {cmd: "send", msg: JSON.stringify(a)};
+  t = parseInt(t);
+  if (s != false) {
+    s = true;
+    if (this.talkDeviceIds.indexOf(t) == -1) {
+      this.talkDeviceIds.push(t)
+    }
+  }
+  this.sendAlarmMessage(r);
+  if (!this.audioWs[t] || this.audioWs[t].readyState != 1) {
+    this.openAudio(i, t, s, false)
+  }
+  if (s) {
+    this.startTalk(t);
+    this.playDeviceAudio(t)
+  }
+  if (!this.deviceAudioWs[t] || this.deviceAudioWs[t].readyState != 1) {
+    this.openDeviceAudio(i, t)
+  }
+  this.playVideo(e, t, i)
+};
+DHAlarmWeb.prototype.stopRT = function (e, t) {
+  if (!e || !t) return;
+  var i = {method: "deviceManager.stopRT", params: {deviceId: parseInt(e), loginHandle: parseInt(t)}};
+  var s = {cmd: "send", msg: JSON.stringify(i)};
+  e = parseInt(e);
+  this.sendAlarmMessage(s);
+  this.closeAudio(e);
+  if (this.deviceAudioWs[e]) {
+    this.deviceAudioWs[e].close()
+  }
+  if (this.player[e]) {
+    this.player[e].destroy()
+  }
+  if (this.bufferPool[e]) {
+    this.bufferPool[e].stopBuffering()
+  }
+  if (this.wfs[e]) {
+    this.wfs[e].destroy()
+  }
+  this.closeDeviceAudio(e);
+  this.deviceId = null;
+  this.playDeviceId = null
+};
+DHAlarmWeb.prototype.doControl = function (e, t, i) {
+  var s = {
+    method: "deviceManager.doControl",
+    params: {deviceId: parseInt(e), loginHandle: parseInt(t), index: parseInt(i)}
+  };
+  var a = {cmd: "send", msg: JSON.stringify(s)};
+  this.sendAlarmMessage(a)
+};
+DHAlarmWeb.prototype.playVideo = function (e, t, i) {
+  this.playDeviceId = t;
+  if (!this.wfs[t] || this.wfs[t].websocketLoader.client.readyState != 1) {
+    this.wfs[t] = new Wfs;
+    this.wfs[t].attachMedia(e, t, this.clientid, this.loginHandle, this.alarmUrl);
+    this.wfs[t].websocketLoader.onVideoFrame = function (e) {
+      this.onVideoFrame(e, t)
+    }.bind(this)
+  }
+};
+DHAlarmWeb.prototype.onVideoFrame = function (e, t) {
+  if (this.onDeviceVideoData) {
+    this.onDeviceVideoData(e, t)
+  }
+};
+DHAlarmWeb.prototype.startTalk = function (e) {
+  e = parseInt(e);
+  if (this.talkDeviceIds.indexOf(e) == -1) {
+    this.talkDeviceIds.push(e)
+  }
+  var t = this.multiTalkDeviceIds.indexOf(parseInt(e));
+  if (t > -1) {
+    this.multiTalkDeviceIds.splice(t, 1)
+  }
+  this.sendAudio(e)
+};
+DHAlarmWeb.prototype.stopTalk = function (e) {
+  this.removeTalkDid(e)
+};
+DHAlarmWeb.prototype.registerTalk = function (e) {
+  var t = {
+    cmd: "register",
+    clientid: this.clientid,
+    loginHandle: parseInt(this.loginHandle),
+    sessiontype: "talk",
+    deviceid: parseInt(e),
+    msg: ""
+  };
+  this.audioWs[e].send(JSON.stringify(t))
+};
+DHAlarmWeb.prototype.openAudio = function (e, t, i, s) {
+  this.loginHandle = e;
+  this.deviceId = t;
+  this.audioWs[t] = new WebSocket(this.alarmUrl);
+  this.audioWs[t].onopen = function () {
+    this.onAudioSocketOpened(t)
+  }.bind(this);
+  this.audioWs[t].onmessage = function (e) {
+    this.onAudioSocketMessage(e, t, i, s)
+  }.bind(this);
+  this.audioWs[t].onclose = function () {
+    this.onAudioSocketClosed(t, s)
+  }.bind(this);
+  this.audioWs[t].onerror = function (e) {
+    this.onAudioSocketError(e, t)
+  }.bind(this)
+};
+DHAlarmWeb.prototype.onAudioSocketOpened = function (e) {
+  console.log("onAudioSocketOpened  did:" + e);
+  this.registerTalk(e);
+  var t = this.notStartBCWsDids.indexOf(e);
+  if (t == -1) return;
+  this.notStartBCWsDids.splice(t, 1)
+};
+DHAlarmWeb.prototype.onAudioSocketMessage = function (e, t, i, s) {
+  var a = JSON.parse(e.data);
+  if (a.error == "success") {
+    if (!i) {
+      if (this.notStartBCWsDids.length == 0 && s == true) {
+        if (this.multiTalkType == 1) {
+          if (this.onMultiTalkStartFinished) {
+            this.onMultiTalkStartFinished()
+          }
+          this.sendAudio()
+        } else if (this.multiTalkType == 2) {
+          if (this.onMultiTalkStartFinished) {
+            this.onMultiTalkStartFinished()
+          }
+          setTimeout(function () {
+            this.sendFileAuido()
+          }.bind(this), 100)
+        }
+      }
+      return
+    }
+  }
+};
+DHAlarmWeb.prototype.onAudioSocketError = function (e, t) {
+  console.log("onAudioSocketError: " + JSON.stringify(e))
+};
+DHAlarmWeb.prototype.onAudioSocketClosed = function (e, t) {
+  console.log("onAudioSocketClosed  did:" + e);
+  var i = this.multiTalkDeviceIds.indexOf(e);
+  if (i > -1) {
+    this.multiTalkDeviceIds.splice(i, 1)
+  }
+  var s = this.notStartBCWsDids.indexOf(e);
+  if (s > -1) {
+    this.notStartBCWsDids.splice(s, 1)
+  }
+  if (t && this.multiTalkType > 0) {
+    var a = false;
+    if (this.multiTalkDeviceIds.length == 0) a = true;
+    if (this.onMultiTalkClosedError) {
+      this.onMultiTalkClosedError(e, a)
+    }
+  }
+};
+DHAlarmWeb.prototype.sendAudio = function (e) {
+  if (this.recorder) return;
+  var t = new ArrayBuffer(320);
+  var i = new DataView(t);
+  var s = 0;
+  var a = new ArrayBuffer(640);
+  var r = new DataView(a);
+  var n = 0;
+  if (navigator.mediaDevices === undefined) {
+    navigator.mediaDevices = {}
+  }
+  if (navigator.mediaDevices.getUserMedia === undefined) {
+    navigator.mediaDevices.getUserMedia = function (e) {
+      var t = navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
+      if (!t) {
+        return Promise.reject(new Error("getUserMedia is not implemented in this browser"))
+      }
+      return new Promise(function (i, s) {
+        t.call(navigator, e, i, s)
+      })
+    }
+  }
+  navigator.mediaDevices.getUserMedia({audio: true}).then(function (e) {
+    if (this.recorder) return;
+    this.context = new AudioContext;
+    this.recorder = this.context.createScriptProcessor(0, 1, 1);
+    this.audioInput = this.context.createMediaStreamSource(e);
+    this.audioInput.connect(this.recorder);
+    this.recorder.connect(this.context.destination);
+    this.recorder.onaudioprocess = function (e) {
+      if (!this.recorder) return;
+      var o = e.inputBuffer.getChannelData(0);
+      var l = this.context.createBuffer(1, this.recorder.bufferSize, this.context.sampleRate);
+      var d = l.getChannelData(0);
+      for (var h = 0; h < l.length; h++) {
+        d[h] = o[h]
+      }
+      var u = new OfflineAudioContext(1, parseInt(this.recorder.bufferSize * 8e3 / this.context.sampleRate), 8e3);
+      var c = u.createBufferSource();
+      c.buffer = l;
+      c.connect(u.destination);
+      c.start();
+      u.startRendering().then(function (e) {
+        var a = e.getChannelData(0);
+        c.stop();
+        var r = 0;
+        var n = a.length;
+        if (this.broadcastType == 2 && this.bcPlayState == "play" && this.talkDeviceIds.length == 0) {
+          if (this.bufferFileArr_8k.length == 0 || this.bufferFileArr_16k.length == 0) {
+            this.bcPlayState = "pause";
+            if (this.onPlayAudioFileEnd) {
+              this.onPlayAudioFileEnd()
+            }
+            return
+          }
+          for (var o = 0; o < parseInt(n / 160); o++) {
+            if (this.broadcastWs_8k && this.broadcastWs_8k.readyState == this.broadcastWs_8k.OPEN) {
+              var l = this.bufferFileArr_8k.shift();
+              if (!l) continue;
+              this.broadcastWs_8k.send(l)
+            }
+          }
+          this.remainFileBuffer_8k += n % 160;
+          if (this.remainFileBuffer_8k >= 160) {
+            if (this.broadcastWs_8k && this.broadcastWs_8k.readyState == this.broadcastWs_8k.OPEN) {
+              var l = this.bufferFileArr_8k.shift();
+              if (!l) return;
+              this.broadcastWs_8k.send(l);
+              this.remainFileBuffer_8k -= 160
+            }
+          }
+          return
+        }
+        while (r < n) {
+          var d = a[r];
+          var h = Math.max(-1, Math.min(1, d));
+          var u = h < 0 ? h * 32768 : h * 32767;
+          if (s < 320) {
+            i.setInt16(s, u, true)
+          } else {
+            if (this.multiTalkType == 2) {
+              this.sendIds = this.talkDeviceIds.concat()
+            } else {
+              if (this.multiTalkDeviceIds.length > 0) {
+                this.sendIds = this.multiTalkDeviceIds.concat();
+                for (var o in this.talkDeviceIds) {
+                  if (this.sendIds.indexOf(this.talkDeviceIds[o]) == -1) {
+                    this.sendIds.push(this.talkDeviceIds[o])
+                  }
+                }
+              } else {
+                this.sendIds = this.talkDeviceIds.concat()
+              }
+            }
+            var p = t.slice(0, 320);
+            var f = this;
+            var m = p;
+            var g = new Int16Array(m);
+            if (this.broadcastType == 1 && this.talkDeviceIds.length == 0) {
+              if (this.broadcastWs_8k && this.broadcastWs_8k.readyState == this.broadcastWs_8k.OPEN && this.bcPlayState == "play") {
+                this.broadcastWs_8k.send(g)
+              }
+            } else {
+              for (let e in f.sendIds) {
+                var v = f.sendIds[e];
+                if (f.audioWs[v] && f.audioWs[v].readyState == f.audioWs[v].OPEN) {
+                  f.audioWs[v].send(g)
+                }
+                if (f.onLocalAudioData) {
+                  f.onLocalAudioData(m, v)
+                }
+              }
+            }
+            i = new DataView(t);
+            s = 0;
+            i.setInt16(s, u, true)
+          }
+          r++;
+          s = s + 2
+        }
+      }.bind(this));
+      if (this.broadcastType == 0) return;
+      var p = new OfflineAudioContext(1, parseInt(this.recorder.bufferSize * 16e3 / this.context.sampleRate), 16e3);
+      var f = p.createBufferSource();
+      f.buffer = l;
+      f.connect(p.destination);
+      f.start();
+      p.startRendering().then(function (e) {
+        var t = e.getChannelData(0);
+        f.stop();
+        var i = 0;
+        var s = t.length;
+        if (this.broadcastType == 2 && this.bcPlayState == "play") {
+          for (var o = 0; o < parseInt(s / 320); o++) {
+            if (this.broadcastWs_16k && this.broadcastWs_16k.readyState == this.broadcastWs_16k.OPEN) {
+              var l = this.bufferFileArr_16k.shift();
+              if (!l) continue;
+              this.broadcastWs_16k.send(l)
+            }
+          }
+          this.remainFileBuffer_16k += s % 320;
+          if (this.remainFileBuffer_16k >= 320) {
+            if (this.broadcastWs_16k && this.broadcastWs_16k.readyState == this.broadcastWs_16k.OPEN) {
+              var l = this.bufferFileArr_16k.shift();
+              if (!l) return;
+              this.broadcastWs_16k.send(l);
+              this.remainFileBuffer_16k -= 320
+            }
+          }
+          return
+        }
+        while (i < s) {
+          var d = t[i];
+          var h = Math.max(-1, Math.min(1, d));
+          var u = h < 0 ? h * 32768 : h * 32767;
+          if (n < 640) {
+            r.setInt16(n, u, true)
+          } else {
+            var c = a.slice(0, 640);
+            var p = c;
+            var m = new Int16Array(p);
+            if (this.broadcastType == 1 && this.talkDeviceIds.length == 0) {
+              if (this.broadcastWs_16k && this.broadcastWs_16k.readyState == this.broadcastWs_16k.OPEN && this.bcPlayState == "play") {
+                this.broadcastWs_16k.send(m)
+              }
+            }
+            r = new DataView(a);
+            n = 0;
+            r.setInt16(n, u, true)
+          }
+          i++;
+          n = n + 2
+        }
+      }.bind(this))
+    }.bind(this)
+  }.bind(this)).catch(function (t) {
+    this.closeAudio(e);
+    console.log(t.name + ": " + t.message)
+  }.bind(this))
+};
+DHAlarmWeb.prototype.closeAudio = function (e) {
+  this.removeTalkDid(e);
+  if (this.audioWs[e] && this.multiTalkDeviceIds.indexOf(parseInt(e)) == -1 && this.talkDeviceIds.indexOf(parseInt(e)) == -1) {
+    this.audioWs[e].close()
+  }
+};
+DHAlarmWeb.prototype.removeTalkDid = function (e) {
+  var t = this.talkDeviceIds.indexOf(parseInt(e));
+  if (t > -1) {
+    this.talkDeviceIds.splice(t, 1)
+  }
+  if (this.recorder && this.talkDeviceIds.length == 0 && (this.multiTalkDeviceIds.length == 0 || this.multiTalkType == 2) && this.broadcastType == 0) {
+    this.recorder.disconnect();
+    this.recorder = null;
+    if (this.audioInput) {
+      this.audioInput.disconnect();
+      this.audioInput = null
+    }
+  }
+};
+DHAlarmWeb.prototype.registerDeviceAudio = function (e) {
+  var t = {
+    cmd: "register",
+    clientid: this.clientid,
+    loginHandle: parseInt(this.loginHandle),
+    sessiontype: "audio",
+    deviceid: parseInt(e),
+    msg: ""
+  };
+  this.deviceAudioWs[e].send(JSON.stringify(t))
+};
+DHAlarmWeb.prototype.openDeviceAudio = function (e, t) {
+  this.loginHandle = e;
+  this.deviceId = t;
+  this.deviceAudioWs[t] = new WebSocket(this.alarmUrl);
+  this.deviceAudioWs[t].binaryType = "arraybuffer";
+  this.deviceAudioWs[t].onopen = function () {
+    this.onDeviceAudioSocketOpened(t)
+  }.bind(this);
+  this.deviceAudioWs[t].onmessage = function (e) {
+    this.onDeviceAudioSocketMessage(e, t)
+  }.bind(this);
+  this.deviceAudioWs[t].onclose = function () {
+    this.onDeviceAudioSocketClosed(t)
+  }.bind(this);
+  this.deviceAudioWs[t].onerror = function (e) {
+    this.onDeviceAudioSocketError(e)
+  }.bind(this)
+};
+DHAlarmWeb.prototype.onDeviceAudioSocketOpened = function (e) {
+  console.log("onDeviceAudioSocketOpened  did:" + e);
+  this.registerDeviceAudio(e)
+};
+DHAlarmWeb.prototype.onDeviceAudioSocketMessage = function (e, t) {
+  if (typeof e.data == "object") {
+    if (!this.isDeviceAudioPlay || !this.isDeviceAudioPlay[t]) return;
+    this.parseDeviceAudio(e.data, t);
+    if (this.onDeviceAudioData) {
+      this.onDeviceAudioData(e.data, t)
+    }
+  } else {
+    var i = JSON.parse(e.data);
+    if (i.error == "success") {
+      this.player[t] = new PCMPlayer({encoding: "16bitInt", channels: 1, sampleRate: 8e3, flushingTime: 500});
+      this.bufferPool[t] = new DHBufferPool;
+      this.bufferPool[t].onFrame = function (e) {
+        this.feedData(e, t)
+      }.bind(this);
+      this.bufferPool[t].startBuffering()
+    }
+  }
+};
+DHAlarmWeb.prototype.onDeviceAudioSocketError = function (e) {
+  console.log("onDeviceAudioSocketError: " + JSON.stringify(e))
+};
+DHAlarmWeb.prototype.onDeviceAudioSocketClosed = function (e) {
+  console.log("onDeviceAudioSocketClosed  did:" + e)
+};
+DHAlarmWeb.prototype.parseDeviceAudio = function (e, t) {
+  var i = new Int16Array(e);
+  this.bufferPool[t].addFrame(i)
+};
+DHAlarmWeb.prototype.feedData = function (e, t) {
+  this.player[t].feed(e);
+  this.player[t].volume(1)
+};
+DHAlarmWeb.prototype.playDeviceAudio = function (e) {
+  this.isDeviceAudioPlay = {};
+  this.isDeviceAudioPlay[e] = true
+};
+DHAlarmWeb.prototype.closeDeviceAudio = function (e) {
+  this.isDeviceAudioPlay = {};
+  this.isDeviceAudioPlay[e] = false
+};
+DHAlarmWeb.prototype.clearKeepAliveInt = function () {
+  if (this.keepAliveInterval) clearInterval(this.keepAliveInterval);
+  this.keepAliveInterval = 0
+};
+DHAlarmWeb.prototype.clearLoginInt = function () {
+  if (this.loginInterval) clearInterval(this.loginInterval);
+  this.loginInterval = 0
+};
+DHAlarmWeb.prototype.clearLoginTimer = function () {
+  if (this.loginTimer) clearTimeout(this.loginTimer);
+  this.loginTimer = 0
+};
+DHAlarmWeb.prototype.clearDeviceListTimer = function () {
+  if (this.deviceListTimer) clearTimeout(this.deviceListTimer);
+  this.deviceListTimer = 0
+};
+DHAlarmWeb.prototype.closeAlarmWs = function () {
+  if (this.alarmWs && this.alarmSocketOpened != 0 && this.alarmSocketOpened != 4) {
+    this.alarmSocketOpened = 3;
+    this.alarmWs.close()
+  }
+};
+DHAlarmWeb.prototype.addGroup = function (e, t, i, s, a, r) {
+  var n = {
+    method: "configManager.addGroup",
+    id: e,
+    params: {loginHandle: parseInt(t), groupType: i, groupName: s, groupContact: a, groupPhone: r}
+  };
+  var o = {cmd: "send", msg: JSON.stringify(n)};
+  this.sendAlarmMessage(o)
+};
+DHAlarmWeb.prototype.editGroup = function (e, t, i, s, a, r) {
+  var n = {
+    method: "configManager.editGroup",
+    id: e,
+    params: {loginHandle: parseInt(t), groupId: parseInt(i), groupName: s}
+  };
+  if (a !== "" && a !== null && a !== undefined) {
+    n.params.groupContact = a
+  }
+  if (r !== "" && r !== null && r !== undefined) {
+    n.params.groupPhone = r
+  }
+  var o = {cmd: "send", msg: JSON.stringify(n)};
+  this.sendAlarmMessage(o)
+};
+DHAlarmWeb.prototype.delGroup = function (e, t, i) {
+  var s = {method: "configManager.delGroup", id: e, params: {loginHandle: parseInt(t), groupId: parseInt(i)}};
+  var a = {cmd: "send", msg: JSON.stringify(s)};
+  this.sendAlarmMessage(a)
+};
+DHAlarmWeb.prototype.getUsers = function (e, t) {
+  var i = {method: "configManager.getUsers", id: e, params: {loginHandle: parseInt(t)}};
+  var s = {cmd: "send", msg: JSON.stringify(i)};
+  this.sendAlarmMessage(s)
+};
+DHAlarmWeb.prototype.getUserGroups = function (e, t, i) {
+  var s = {method: "configManager.getUserGroups", id: e, params: {loginHandle: parseInt(t), userId: parseInt(i)}};
+  var a = {cmd: "send", msg: JSON.stringify(s)};
+  this.sendAlarmMessage(a)
+};
+DHAlarmWeb.prototype.addUser = function (e, t, i, s) {
+  var a = {method: "configManager.addUser", id: e, params: {loginHandle: parseInt(t), userName: i, password: s}};
+  var r = {cmd: "send", msg: JSON.stringify(a)};
+  this.sendAlarmMessage(r)
+};
+DHAlarmWeb.prototype.editPassword = function (e, t, i, s) {
+  var a = {
+    method: "configManager.editPassword",
+    id: e,
+    params: {loginHandle: parseInt(t), userId: parseInt(i), password: s}
+  };
+  var r = {cmd: "send", msg: JSON.stringify(a)};
+  this.sendAlarmMessage(r)
+};
+DHAlarmWeb.prototype.delUser = function (e, t, i) {
+  var s = {method: "configManager.delUser", id: e, params: {loginHandle: parseInt(t), userId: parseInt(i)}};
+  var a = {cmd: "send", msg: JSON.stringify(s)};
+  this.sendAlarmMessage(a)
+};
+DHAlarmWeb.prototype.authorizeGroup = function (e, t, i, s) {
+  var a = {
+    method: "configManager.authorizeGroup",
+    id: e,
+    params: {loginHandle: parseInt(t), userId: parseInt(i), groupIds: s}
+  };
+  var r = {cmd: "send", msg: JSON.stringify(a)};
+  this.sendAlarmMessage(r)
+};
+DHAlarmWeb.prototype.editDevice = function (e, t, i, s, a, r) {
+  var n = {
+    method: "configManager.editDevice",
+    id: e,
+    params: {loginHandle: parseInt(t), deviceId: parseInt(i), deviceName: s}
+  };
+  if (a !== "" && a !== null && a !== undefined) {
+    n.params.deviceContact = a
+  }
+  if (r !== "" && r !== null && r !== undefined) {
+    n.params.devicePhone = r
+  }
+  var o = {cmd: "send", msg: JSON.stringify(n)};
+  this.sendAlarmMessage(o)
+};
+DHAlarmWeb.prototype.moveDevice = function (e, t, i, s) {
+  var a = {
+    method: "configManager.moveDevice",
+    id: e,
+    params: {loginHandle: parseInt(t), deviceId: parseInt(i), groupId: parseInt(s)}
+  };
+  var r = {cmd: "send", msg: JSON.stringify(a)};
+  this.sendAlarmMessage(r)
+};
+DHAlarmWeb.prototype.getGroups = function (e, t) {
+  var i = {method: "configManager.getGroups", id: e, params: {loginHandle: parseInt(t)}};
+  var s = {cmd: "send", msg: JSON.stringify(i)};
+  this.sendAlarmMessage(s)
+};
+DHAlarmWeb.prototype.getWebPush = function (e, t, i) {
+  var s = {method: "configManager.getWebPush", id: e, params: {loginHandle: parseInt(t), deviceId: parseInt(i)}};
+  var a = {cmd: "send", msg: JSON.stringify(s)};
+  this.sendAlarmMessage(a)
+};
+DHAlarmWeb.prototype.editWebPush = function (e, t, i, s, a, r, n, o) {
+  var l = {
+    method: "configManager.editWebPush",
+    id: e,
+    params: {
+      loginHandle: parseInt(t),
+      deviceId: parseInt(i),
+      url: s,
+      context: a,
+      isAuth: parseInt(r),
+      userName: n,
+      password: o
+    }
+  };
+  var d = {cmd: "send", msg: JSON.stringify(l)};
+  this.sendAlarmMessage(d)
+};
+DHAlarmWeb.prototype.startMultiMicTalk = function (e, t) {
+  this.multiTalkType = 1;
+  this.notStartBCWsDids = [];
+  for (let n in t) {
+    if (this.multiTalkDeviceIds.length >= 100) {
+      if (this.onMultiTalkCountLimit) {
+        this.onMultiTalkCountLimit()
+      }
+      return
+    }
+    var i = parseInt(t[n]);
+    if (this.talkDeviceIds.indexOf(i) > -1) continue;
+    var s = this.multiTalkDeviceIds.indexOf(i);
+    var a = {method: "deviceManager.playRT", params: {deviceId: parseInt(i), loginHandle: parseInt(e), preview: false}};
+    var r = {cmd: "send", msg: JSON.stringify(a)};
+    if (s == -1) {
+      this.multiTalkDeviceIds.push(i);
+      this.notStartBCWsDids.push(i);
+      this.sendAlarmMessage(r)
+    }
+    if (!this.audioWs[i] || this.audioWs[i].readyState != 1) {
+      this.openAudio(e, i, false, true)
+    } else {
+      var s = this.notStartBCWsDids.indexOf(i);
+      if (s == -1) continue;
+      this.notStartBCWsDids.splice(s, 1)
+    }
+  }
+  if (this.notStartBCWsDids.length == 0) {
+    if (this.onMultiTalkStartFinished) {
+      this.onMultiTalkStartFinished()
+    }
+    this.sendAudio()
+  }
+};
+DHAlarmWeb.prototype.stopMultiMicTalk = function (e, t, i) {
+  if (t) i = this.multiTalkDeviceIds.concat();
+  for (let t in i) {
+    var s = parseInt(i[t]);
+    var a = {method: "deviceManager.stopRT", params: {deviceId: parseInt(s), loginHandle: parseInt(e)}};
+    var r = {cmd: "send", msg: JSON.stringify(a)};
+    var n = this.multiTalkDeviceIds.indexOf(s);
+    if (n > -1) {
+      this.multiTalkDeviceIds.splice(n, 1)
+    }
+    if (this.audioWs[s] && this.talkDeviceIds.indexOf(s) == -1) {
+      this.sendAlarmMessage(r);
+      this.audioWs[s].close();
+      this.removeTalkDid(s)
+    }
+  }
+  if (this.multiTalkDeviceIds.length == 0) {
+    this.multiTalkType = 0;
+    this.notStartBCWsDids = []
+  }
+};
+DHAlarmWeb.prototype.startMultiFileTalk = function (e, t, i) {
+  this.multiTalkType = 2;
+  this.multiTalkFilePath = i;
+  this.notStartBCWsDids = [];
+  for (let i in t) {
+    if (this.multiTalkDeviceIds.length >= 100) {
+      if (this.onMultiTalkCountLimit) {
+        this.onMultiTalkCountLimit()
+      }
+      return
+    }
+    var s = parseInt(t[i]);
+    if (this.talkDeviceIds.indexOf(s) > -1) continue;
+    var a = this.multiTalkDeviceIds.indexOf(s);
+    var r = {method: "deviceManager.playRT", params: {deviceId: parseInt(s), loginHandle: parseInt(e), preview: false}};
+    var n = {cmd: "send", msg: JSON.stringify(r)};
+    if (a == -1) {
+      this.multiTalkDeviceIds.push(s);
+      this.notStartBCWsDids.push(s);
+      this.sendAlarmMessage(n)
+    }
+    if (!this.audioWs[s] || this.audioWs[s].readyState != 1) {
+      this.openAudio(e, s, false, true)
+    } else {
+      var a = this.notStartBCWsDids.indexOf(s);
+      if (a == -1) continue;
+      this.notStartBCWsDids.splice(a, 1)
+    }
+  }
+  if (this.notStartBCWsDids.length == 0) {
+    if (this.onMultiTalkStartFinished) {
+      this.onMultiTalkStartFinished()
+    }
+    this.sendFileAuido()
+  }
+};
+DHAlarmWeb.prototype.stopMultiFileTalk = function (e, t, i) {
+  if (t) i = this.multiTalkDeviceIds.concat();
+  for (let o in i) {
+    var s = parseInt(i[o]);
+    var a = {method: "deviceManager.stopRT", params: {deviceId: parseInt(s), loginHandle: parseInt(e)}};
+    var r = {cmd: "send", msg: JSON.stringify(a)};
+    var n = this.multiTalkDeviceIds.indexOf(s);
+    if (n == -1) continue;
+    this.multiTalkDeviceIds.splice(n, 1);
+    this.sendAlarmMessage(r);
+    if (this.audioWs[s] && this.talkDeviceIds.indexOf(s) == -1) {
+      this.audioWs[s].close()
+    }
+    if (this.multiFileTalkIntv > 0 && (t || this.multiTalkDeviceIds.length == 0)) {
+      clearInterval(this.multiFileTalkIntv);
+      this.multiFileTalkIntv = 0
+    }
+  }
+  if (this.multiTalkDeviceIds.length == 0) {
+    this.multiTalkType = 0;
+    this.notStartBCWsDids = []
+  }
+};
+DHAlarmWeb.prototype.sendFileAuido = function () {
+  if (this.multiFileTalkIntv > 0) return;
+  var e = new AudioContext;
+  var t = new ArrayBuffer(320);
+  var i = new DataView(t);
+  var s = 0;
+  var a = new ArrayBuffer(640);
+  var r = new DataView(a);
+  var n = 0;
+  var o = new XMLHttpRequest;
+  var l = this;
+  o.open("GET", this.multiTalkFilePath, true);
+  o.responseType = "arraybuffer";
+  o.onload = function () {
+    var o = this.response;
+    e.decodeAudioData(o, function (e) {
+      var o = new OfflineAudioContext(1, parseInt(e.length * 8e3 / e.sampleRate), 8e3);
+      var d = o.createBufferSource();
+      d.buffer = e;
+      d.connect(o.destination);
+      d.start();
+      l.bufferFileArr_8k = [];
+      var h = [];
+      o.startRendering().then(function (e) {
+        var a = e.getChannelData(0);
+        d.stop();
+        var r = 0;
+        var n = a.length;
+        while (r < n) {
+          var o = a[r];
+          var u = Math.max(-1, Math.min(1, o));
+          var c = u < 0 ? u * 32768 : u * 32767;
+          if (s < 320) {
+            i.setInt16(s, c, true)
+          } else {
+            var p = t.slice(0, 320);
+            var f = new Int16Array(p);
+            h.push(f);
+            l.bufferFileArr_8k.push(f);
+            i = new DataView(t);
+            s = 0;
+            i.setInt16(s, c, true)
+          }
+          r++;
+          s = s + 2
+        }
+        if (l.broadcastWs_8k && l.broadcastWs_8k.readyState == WebSocket.OPEN) {
+          l.sendAudio()
+        }
+        let m = 0;
+        if (l.multiFileTalkIntv > 0 || l.broadcastType > 0 || l.multiTalkType == 0) return;
+        l.multiFileTalkIntv = setInterval(function () {
+          if (m == h.length) {
+            clearInterval(l.multiFileTalkIntv);
+            l.multiFileTalkIntv = 0;
+            if (l.onPlayAudioFileEnd) {
+              l.onPlayAudioFileEnd()
+            }
+            h = [];
+            return
+          }
+          if (l.multiTalkType == 2) {
+            let t = h[m];
+            for (let i in l.multiTalkDeviceIds) {
+              var e = l.multiTalkDeviceIds[i];
+              if (l.talkDeviceIds.indexOf(e) > -1) continue;
+              if (l.audioWs[e] && l.audioWs[e].readyState == l.audioWs[e].OPEN) {
+                l.audioWs[e].send(t)
+              }
+            }
+          }
+          m++
+        }, 20)
+      }).catch(function (e) {
+        console.log(e);
+        var t = {
+          clientid: "",
+          error: "fail",
+          msg: {method: "systemManager.onError", error: "renderError", errorMsg: e}
+        };
+        if (l.onDHAlarmWebError) {
+          l.onDHAlarmWebError(t)
+        }
+      });
+      var u = new OfflineAudioContext(1, parseInt(e.length * 16e3 / e.sampleRate), 16e3);
+      var c = u.createBufferSource();
+      c.buffer = e;
+      c.connect(u.destination);
+      c.start();
+      l.bufferFileArr_16k = [];
+      var p = [];
+      u.startRendering().then(function (e) {
+        var t = e.getChannelData(0);
+        c.stop();
+        var i = 0;
+        var s = t.length;
+        while (i < s) {
+          var o = t[i];
+          var d = Math.max(-1, Math.min(1, o));
+          var h = d < 0 ? d * 32768 : d * 32767;
+          if (n < 640) {
+            r.setInt16(n, h, true)
+          } else {
+            var u = a.slice(0, 640);
+            var f = new Int16Array(u);
+            p.push(f);
+            l.bufferFileArr_16k.push(f);
+            r = new DataView(a);
+            n = 0;
+            r.setInt16(n, h, true)
+          }
+          i++;
+          n = n + 2
+        }
+        if (l.broadcastWs_16k && l.broadcastWs_16k.readyState == WebSocket.OPEN) {
+          l.sendAudio()
+        }
+      }).catch(function (e) {
+        console.log(e);
+        var t = {clientid: "", error: "fail", msg: {method: "systemManager.onError", error: "renderError"}};
+        if (l.onDHAlarmWebError) {
+          l.onDHAlarmWebError(t)
+        }
+      })
+    }, function (e) {
+      console.log(e);
+      var t = {clientid: "", error: "fail", msg: {method: "systemManager.onError", error: "decodeError", errorMsg: e}};
+      if (l.onDecodeAudioError) {
+        l.onDecodeAudioError(t)
+      }
+    })
+  };
+  o.send()
+};
+DHAlarmWeb.prototype.startBroadcast = function (e, t, i, s) {
+  if (i !== 1 && i !== 2) return;
+  this.broadcastType = i;
+  this.bcPlayState = "play";
+  if (i == 2) this.multiTalkFilePath = s;
+  t = t.map(e => {
+    return +e
+  });
+  var a = {
+    method: "deviceManager.startBroadcast",
+    params: {loginHandle: parseInt(e), mode: "RealTime", audioparam: {sampleRate: [8e3, 16e3]}, deviceIds: t}
+  };
+  var r = {cmd: "send", msg: JSON.stringify(a)};
+  this.sendAlarmMessage(r);
+  if (!this.broadcastWs_8k || this.broadcastWs_8k.readyState != 1) {
+    this.openBrocastWs_8k(e)
+  }
+  if (!this.broadcastWs_16k || this.broadcastWs_16k.readyState != 1) {
+    this.openBrocastWs_16k(e)
+  }
+  if (this.broadcastWs_8k && this.broadcastWs_8k.readyState == WebSocket.OPEN || this.broadcastWs_16k && this.broadcastWs_16k.readyState == WebSocket.OPEN) {
+    if (i == 1) {
+      this.sendAudio()
+    } else {
+      this.sendFileAuido()
+    }
+  }
+};
+DHAlarmWeb.prototype.updateBroadcastFile = function (e) {
+  this.broadcastType = 2;
+  this.bcPlayState = "play";
+  this.multiTalkFilePath = e;
+  if (this.recorder && this.talkDeviceIds.length == 0) {
+    this.recorder.disconnect();
+    this.recorder = null;
+    if (this.audioInput) {
+      this.audioInput.disconnect();
+      this.audioInput = null
+    }
+  }
+  if (!this.broadcastWs_8k || this.broadcastWs_8k.readyState != 1) {
+    this.openBrocastWs_8k(this.loginHandle)
+  }
+  if (!this.broadcastWs_16k || this.broadcastWs_16k.readyState != 1) {
+    this.openBrocastWs_16k(this.loginHandle)
+  }
+  if (this.broadcastWs_8k && this.broadcastWs_8k.readyState == WebSocket.OPEN || this.broadcastWs_16k && this.broadcastWs_16k.readyState == WebSocket.OPEN) {
+    this.sendFileAuido()
+  }
+};
+DHAlarmWeb.prototype.stopBroadcast = function (e) {
+  this.broadcastType = 0;
+  this.bcPlayState = "pause";
+  var t = {method: "deviceManager.stopBroadcast", params: {loginHandle: parseInt(e)}};
+  var i = {cmd: "send", msg: JSON.stringify(t)};
+  this.sendAlarmMessage(i);
+  this.bufferFileArr_8k = [];
+  this.bufferFileArr_16k = [];
+  if (this.recorder && this.talkDeviceIds.length == 0) {
+    this.recorder.disconnect();
+    this.recorder = null;
+    if (this.audioInput) {
+      this.audioInput.disconnect();
+      this.audioInput = null
+    }
+  }
+  if (this.broadcastWs_8k && this.broadcastWs_8k.readyState == WebSocket.OPEN) {
+    this.broadcastWs_8k.close()
+  }
+  if (this.broadcastWs_16k && this.broadcastWs_16k.readyState == WebSocket.OPEN) {
+    this.broadcastWs_16k.close()
+  }
+  if (this.multiFileTalkIntv > 0) {
+    clearInterval(this.multiFileTalkIntv)
+  }
+};
+DHAlarmWeb.prototype.setBroadcastState = function (e) {
+  if (e != "play" && e != "pause") return false;
+  this.bcPlayState = e;
+  return true
+};
+DHAlarmWeb.prototype.openBrocastWs_8k = function (e) {
+  this.broadcastWs_8k = new WebSocket(this.alarmUrl);
+  this.broadcastWs_8k.onopen = function () {
+    var t = {
+      cmd: "register",
+      clientid: this.clientid,
+      loginHandle: parseInt(e),
+      sessiontype: "mt8",
+      deviceid: 1,
+      msg: ""
+    };
+    this.broadcastWs_8k.send(JSON.stringify(t))
+  }.bind(this);
+  this.broadcastWs_8k.onmessage = function (e) {
+    var t = JSON.parse(e.data);
+    if (t.error == "success") {
+      if (this.broadcastType == 1) {
+        this.sendAudio()
+      } else if (this.broadcastType == 2) {
+        this.sendFileAuido()
+      }
+    }
+  }.bind(this);
+  this.broadcastWs_8k.onclose = function (e) {
+    if (this.onBroadcastWsClosed) {
+      this.onBroadcastWsClosed(e)
+    }
+  }.bind(this);
+  this.broadcastWs_8k.onerror = function (e) {
+  }.bind(this)
+};
+DHAlarmWeb.prototype.openBrocastWs_16k = function (e) {
+  this.broadcastWs_16k = new WebSocket(this.alarmUrl);
+  this.broadcastWs_16k.onopen = function () {
+    var t = {
+      cmd: "register",
+      clientid: this.clientid,
+      loginHandle: parseInt(e),
+      sessiontype: "mt16",
+      deviceid: 1,
+      msg: ""
+    };
+    this.broadcastWs_16k.send(JSON.stringify(t))
+  }.bind(this);
+  this.broadcastWs_16k.onmessage = function (e) {
+    var t = JSON.parse(e.data);
+    if (t.error == "success") {
+      if (this.broadcastType == 1) {
+        this.sendAudio()
+      } else if (this.broadcastType == 2) {
+        this.sendFileAuido()
+      }
+    }
+  }.bind(this);
+  this.broadcastWs_16k.onclose = function () {
+  }.bind(this);
+  this.broadcastWs_16k.onerror = function (e) {
+  }.bind(this)
+};
+DHAlarmWeb.prototype.getAudioFileList = function (e, t) {
+  var i = {method: "audioManager.getAudioFileList", id: e, params: {loginHandle: parseInt(t)}};
+  var s = {cmd: "send", msg: JSON.stringify(i)};
+  this.sendAlarmMessage(s)
+};
+DHAlarmWeb.prototype.uploadAudioFile = function (e, t, i, s) {
+  var a = new AudioContext;
+  var r = new XMLHttpRequest;
+  var n = this;
+  r.open("GET", s, true);
+  r.responseType = "arraybuffer";
+  r.onload = function () {
+    var s = this.response;
+    if (s.length > 10 * 1024 * 1024) {
+      var r = {
+        clientid: "",
+        error: "fail",
+        msg: {method: "systemManager.onError", error: "fileError", errorMsg: "the file is too big"}
+      };
+      if (n.onDecodeAudioError) {
+        n.onDecodeAudioError(r)
+      }
+    }
+    a.decodeAudioData(s, function (s) {
+      n.audioFileStream = s;
+      var a = new ArrayBuffer(640);
+      var r = new DataView(a);
+      var o = 0;
+      var l = new OfflineAudioContext(1, parseInt(s.length * 16e3 / s.sampleRate), 16e3);
+      var d = l.createBufferSource();
+      d.buffer = s;
+      d.connect(l.destination);
+      d.start();
+      l.startRendering().then(function (s) {
+        var l = s.getChannelData(0);
+        d.stop();
+        var h = 0;
+        var u = l.length;
+        while (h < u) {
+          var c = l[h];
+          var p = Math.max(-1, Math.min(1, c));
+          var f = p < 0 ? p * 32768 : p * 32767;
+          if (o < 640) {
+            r.setInt16(o, f, true)
+          } else {
+            var m = a.slice(0, 640);
+            var g = new Int16Array(m);
+            n.uploadFileArr.push(g);
+            r = new DataView(a);
+            o = 0;
+            r.setInt16(o, f, true)
+          }
+          h++;
+          o = o + 2
+        }
+        n.totalUploadFileArr = n.uploadFileArr.concat();
+        var v = {
+          method: "audioManager.uploadAudioFile",
+          id: e,
+          params: {
+            loginHandle: parseInt(t),
+            file: {name: i, length: n.totalUploadFileArr.length * 640, sampleRate: 16e3, bitsPerSec: 128, encode: "pcm"}
+          }
+        };
+        var A = {cmd: "send", msg: JSON.stringify(v)};
+        n.sendAlarmMessage(A)
+      }).catch(function (e) {
+        console.log(e);
+        var t = {
+          clientid: "",
+          error: "fail",
+          msg: {method: "systemManager.onError", error: "renderError", errorMsg: e}
+        };
+        if (n.onDHAlarmWebError) {
+          n.onDHAlarmWebError(t)
+        }
+      })
+    }, function (e) {
+      console.log(e);
+      var t = {clientid: "", error: "fail", msg: {method: "systemManager.onError", error: "decodeError", errorMsg: e}};
+      if (n.onDecodeAudioError) {
+        n.onDecodeAudioError(t)
+      }
+    })
+  };
+  r.send()
+};
+DHAlarmWeb.prototype.openAudioUploadWs = function (e) {
+  this.audioUploadWs = new WebSocket(this.alarmUrl);
+  this.audioUploadWs.onopen = function () {
+    var t = {
+      cmd: "register",
+      clientid: this.clientid,
+      loginHandle: parseInt(e),
+      sessiontype: "mt16",
+      deviceid: 1,
+      msg: ""
+    };
+    this.audioUploadWs.send(JSON.stringify(t))
+  }.bind(this);
+  this.audioUploadWs.onmessage = function (e) {
+    var t = JSON.parse(e.data);
+    if (t.error != "fail") {
+      if (this.onUploadAudioFileProgress) {
+        var i = 1 - this.uploadFileArr.length / this.totalUploadFileArr.length;
+        if (i < 1) {
+          this.onUploadAudioFileProgress(i.toFixed(4))
+        }
+      }
+      for (var s = 0; s < 50; s++) {
+        if (this.uploadFileArr.length == 0) break;
+        this.audioUploadWs.send(this.uploadFileArr.shift())
+      }
+      if (this.overInter > 0) {
+        clearInterval(this.overInter);
+        this.overInter = 0
+      }
+      if (t.msg == "OVER") {
+        this.onUploadAudioFileProgress(1);
+        this.audioUploadWs.close();
+        return
+      }
+      if (this.uploadFileArr.length == 0 && t.msg != "OVER") {
+        this.audioUploadWs.send("OVER")
+      }
+      this.overInter = setInterval(function () {
+        if (this.overInter > 0) {
+          if (this.uploadFileArr.length == 0) {
+            this.audioUploadWs.send("OVER")
+          } else {
+            this.audioUploadWs.send("CANCEL")
+          }
+        }
+      }.bind(this), 1e4)
+    }
+  }.bind(this);
+  this.audioUploadWs.onclose = function () {
+    console.log("audioUploadWs closed");
+    clearInterval(this.overInter)
+  }.bind(this);
+  this.audioUploadWs.onerror = function (e) {
+    console.log("audioUploadWs error");
+    clearInterval(this.overInter)
+  }.bind(this)
+};
+DHAlarmWeb.prototype.deleteAudioFile = function (e, t, i) {
+  var s = {method: "audioManager.deleteAudioFile", id: e, params: {loginHandle: parseInt(t), fileId: i}};
+  var a = {cmd: "send", msg: JSON.stringify(s)};
+  this.sendAlarmMessage(a)
+};
+DHAlarmWeb.prototype.getBCTaskList = function (e, t, i = "timed") {
+  var s = {method: "audioManager.getBCTaskList", id: e, params: {loginHandle: parseInt(t), taskType: i}};
+  var a = {cmd: "send", msg: JSON.stringify(s)};
+  this.sendAlarmMessage(a)
+};
+DHAlarmWeb.prototype.uploadBCTask = function (e, t, i, s, a, r, n, o, l, d, h, u, c, p = "timed", f = "file") {
+  var m = {}, g = {}, v = {};
+  if (h && h.enable) {
+    m.enable = h.enable;
+    if (h.beginDate) m.beginDate = h.beginDate;
+    if (h.endDate) m.endDate = h.endDate
+  } else {
+    m.enable = false;
+    m.beginDate = "";
+    m.endDate = ""
+  }
+  if (u == "seconds") {
+    g.enable = true;
+    g.seconds = parseInt(c);
+    v.enable = false;
+    v.times = 0
+  } else if (u == "times") {
+    g.enable = false;
+    g.seconds = 0;
+    v.enable = true;
+    v.times = parseInt(c)
+  }
+  a = a.map(e => {
+    return +e
+  });
+  r = r.map(e => {
+    return +e
+  });
+  l = l.map(e => {
+    return +e
+  });
+  var A = {
+    method: "audioManager.uploadBCTask",
+    id: e,
+    params: {
+      loginHandle: parseInt(t),
+      id: e,
+      task: {
+        fileIds: r,
+        deviceIds: a,
+        name: i,
+        volume: parseInt(s),
+        expire: m,
+        enable: n,
+        duration: g,
+        loop: v,
+        execMode: o,
+        weekDay: l,
+        startTimeOfDay: d,
+        taskType: p,
+        bcType: f
+      }
+    }
+  };
+  var y = {cmd: "send", msg: JSON.stringify(A)};
+  this.sendAlarmMessage(y)
+};
+DHAlarmWeb.prototype.editBCTask = function (e, t, i, s, a, r, n, o, l, d, h, u, c, p, f = "timed", m = "file") {
+  var g = {}, v = {}, A = {};
+  if (u && u.enable) {
+    g.enable = u.enable;
+    if (u.beginDate) g.beginDate = u.beginDate;
+    if (u.endDate) g.endDate = u.endDate
+  } else {
+    g.enable = false;
+    g.beginDate = "";
+    g.endDate = ""
+  }
+  if (c == "seconds") {
+    v.enable = true;
+    v.seconds = parseInt(p);
+    A.enable = false;
+    A.times = 0
+  } else if (c == "times") {
+    v.enable = false;
+    v.seconds = 0;
+    A.enable = true;
+    A.times = parseInt(p)
+  }
+  r = r.map(e => {
+    return +e
+  });
+  n = n.map(e => {
+    return +e
+  });
+  d = d.map(e => {
+    return +e
+  });
+  var y = {
+    method: "audioManager.editBCTask",
+    id: e,
+    params: {
+      loginHandle: parseInt(t),
+      id: e,
+      task: {
+        id: parseInt(i),
+        fileIds: n,
+        deviceIds: r,
+        name: s,
+        volume: parseInt(a),
+        expire: g,
+        enable: o,
+        duration: v,
+        loop: A,
+        execMode: l,
+        weekDay: d,
+        startTimeOfDay: h,
+        taskType: f,
+        bcType: m
+      }
+    }
+  };
+  var b = {cmd: "send", msg: JSON.stringify(y)};
+  this.sendAlarmMessage(b)
+};
+DHAlarmWeb.prototype.deleteBCTask = function (e, t, i) {
+  var s = {method: "audioManager.deleteBCTask", id: e, params: {loginHandle: parseInt(t), taskId: i}};
+  var a = {cmd: "send", msg: JSON.stringify(s)};
+  this.sendAlarmMessage(a)
+};
+DHAlarmWeb.prototype.tryBCTask = function (e, t, i, s) {
+  if (s != "start" && s != "stop") return;
+  var a = {method: "audioManager.tryBCTask", id: e, params: {loginHandle: parseInt(t), taskId: i, action: s}};
+  var r = {cmd: "send", msg: JSON.stringify(a)};
+  this.sendAlarmMessage(r)
+};
+DHAlarmWeb.prototype.configPayStatus = function (e, t, i, s, a, r, n, o, l, d, h, u) {
+  var c = this.tunnelDataId++;
+  var p = {
+    id: c,
+    method: "configManager.setConfig",
+    name: "ui.lcd.payStatus",
+    context: "",
+    data: {
+      status: parseInt(s),
+      divCode: parseInt(a),
+      orgCode: parseInt(r),
+      carNumber: n,
+      carType: parseInt(o),
+      qrText: l,
+      duration: d,
+      validDate: h,
+      decimal: u.toString()
+    }
+  };
+  var f = {
+    method: "deviceManager.configTunnel",
+    params: {loginHandle: parseInt(t), deviceId: parseInt(i), tunnelData: JSON.stringify(p)}
+  };
+  var m = {cmd: "send", msg: JSON.stringify(f)};
+  this.sendAlarmMessage(m);
+  var g = {};
+  g.requestId = e;
+  g.deviceId = i;
+  g.timestamp = Date.parse(new Date) / 1e3;
+  this.setTunnelQueue(c, "configPayStatus", g)
+};
+DHAlarmWeb.prototype.setDeviceExtra = function (e, t, i, s, a, r, n) {
+  var o = {
+    method: "deviceManager.setDeviceExtra",
+    id: e,
+    params: {loginHandle: parseInt(t), deviceId: parseInt(i), location: s, contact: a, phone: r, remark: n}
+  };
+  var l = {cmd: "send", msg: JSON.stringify(o)};
+  this.sendAlarmMessage(l)
+};
+DHAlarmWeb.prototype.getDeviceExtra = function (e, t, i) {
+  var s = {method: "deviceManager.getDeviceExtra", id: e, params: {loginHandle: parseInt(t), deviceId: parseInt(i)}};
+  var a = {cmd: "send", msg: JSON.stringify(s)};
+  this.sendAlarmMessage(a)
+};
+DHAlarmWeb.prototype.uploadBCTaskRealtime = function (e, t, i, s, a, r, n, o) {
+  a = a.map(e => {
+    return +e
+  });
+  r = r.map(e => {
+    return +e
+  });
+  var l = {
+    method: "audioManager.uploadBCTask",
+    id: e,
+    params: {
+      loginHandle: parseInt(t),
+      id: e,
+      task: {
+        fileIds: r,
+        deviceIds: a,
+        name: i,
+        volume: parseInt(s),
+        expire: {enable: false, beginDate: "", endDate: ""},
+        enable: true,
+        duration: {enable: false, seconds: 0},
+        loop: {enable: true, times: parseInt(n)},
+        execMode: "Single",
+        weekDay: [],
+        startTimeOfDay: "",
+        taskType: "realtime",
+        bcType: o
+      }
+    }
+  };
+  var d = {cmd: "send", msg: JSON.stringify(l)};
+  this.sendAlarmMessage(d)
+};
+DHAlarmWeb.prototype.editBCTaskRealtime = function (e, t, i, s, a, r, n, o, l) {
+  r = r.map(e => {
+    return +e
+  });
+  n = n.map(e => {
+    return +e
+  });
+  var d = {
+    method: "audioManager.editBCTask",
+    id: e,
+    params: {
+      loginHandle: parseInt(t),
+      id: e,
+      task: {
+        id: parseInt(i),
+        fileIds: n,
+        deviceIds: r,
+        name: s,
+        volume: parseInt(a),
+        expire: {enable: false, beginDate: "", endDate: ""},
+        enable: true,
+        duration: {enable: false, seconds: 0},
+        loop: {enable: true, times: parseInt(o)},
+        execMode: "Single",
+        weekDay: [],
+        startTimeOfDay: "",
+        taskType: "realtime",
+        bcType: l
+      }
+    }
+  };
+  var h = {cmd: "send", msg: JSON.stringify(d)};
+  this.sendAlarmMessage(h)
+};
+DHAlarmWeb.prototype.getAudioOutputChannels = function (e, t, i) {
+  var s = this.tunnelDataId++;
+  var a = {id: s, method: "devAudioOutput.getAudioOutputChannels", deviceId: parseInt(i), params: {}};
+  var r = {
+    method: "deviceManager.configTunnel",
+    params: {loginHandle: parseInt(t), deviceId: parseInt(i), tunnelData: JSON.stringify(a)}
+  };
+  var n = {cmd: "send", msg: JSON.stringify(r)};
+  this.sendAlarmMessage(n);
+  var o = {};
+  o.requestId = e;
+  o.deviceId = i;
+  o.timestamp = Date.parse(new Date) / 1e3;
+  this.setTunnelQueue(s, "getAudioOutputChannels", o)
+};
+DHAlarmWeb.prototype.setBroadcastVolume = function (e, t, i, s) {
+  if (Array.isArray(s)) {
+    s = s.map(e => {
+      return +e
+    })
+  } else {
+    s = [parseInt(s)]
+  }
+  var a = this.tunnelDataId++;
+  var r = {id: a, method: "devAudioOutput.setBroadcastVolume", deviceId: parseInt(i), params: {volume: s}};
+  var n = {
+    method: "deviceManager.configTunnel",
+    params: {loginHandle: parseInt(t), deviceId: parseInt(i), tunnelData: JSON.stringify(r)}
+  };
+  var o = {cmd: "send", msg: JSON.stringify(n)};
+  this.sendAlarmMessage(o);
+  var l = {};
+  l.requestId = e;
+  l.deviceId = i;
+  l.volume = s;
+  l.timestamp = Date.parse(new Date) / 1e3;
+  this.setTunnelQueue(a, "setBroadcastVolume", l)
+};
+DHAlarmWeb.prototype.getBroadcastVolume = function (e, t, i) {
+  var s = this.tunnelDataId++;
+  var a = {id: s, method: "devAudioOutput.getBroadcastVolume", deviceId: parseInt(i), params: {}};
+  var r = {
+    method: "deviceManager.configTunnel",
+    params: {loginHandle: parseInt(t), deviceId: parseInt(i), tunnelData: JSON.stringify(a)}
+  };
+  var n = {cmd: "send", msg: JSON.stringify(r)};
+  this.sendAlarmMessage(n);
+  var o = {};
+  o.requestId = e;
+  o.deviceId = i;
+  o.timestamp = Date.parse(new Date) / 1e3;
+  this.setTunnelQueue(s, "getBroadcastVolume", o)
+};
+DHAlarmWeb.prototype.setTunnelQueue = function (e, t, i) {
+  this.tunnelQueue = this.tunnelQueue.filter(e => e.data.timestamp + this.tunnelReqTimeout > i.timestamp);
+  this.tunnelQueue.push({id: e, method: t, data: i})
+};
+DHAlarmWeb.prototype.getDeviceVolume = function (e, t, i, s) {
+  var a = s == "input" ? "AudioInputVolume" : "AudioOutputVolume";
+  var r = this.tunnelDataId++;
+  var n = {id: r, method: "configManager.getConfig", name: a, deviceId: parseInt(i), params: {}};
+  var o = {
+    method: "deviceManager.configTunnel",
+    params: {loginHandle: parseInt(t), deviceId: parseInt(i), tunnelData: JSON.stringify(n)}
+  };
+  var l = {cmd: "send", msg: JSON.stringify(o)};
+  this.sendAlarmMessage(l);
+  var d = {};
+  d.requestId = e;
+  d.deviceId = i;
+  d.type = s;
+  d.timestamp = Date.parse(new Date) / 1e3;
+  this.setTunnelQueue(r, "getDeviceVolume", d)
+};
+DHAlarmWeb.prototype.setDeviceVolume = function (e, t, i, s, a) {
+  if (Array.isArray(a)) {
+    a = a.map(e => {
+      return +e
+    })
+  } else {
+    a = [parseInt(a)]
+  }
+  var r = s == "input" ? "AudioInputVolume" : "AudioOutputVolume";
+  var n = this.tunnelDataId++;
+  var o = {id: n, method: "configManager.setConfig", name: r, deviceId: parseInt(i), params: a};
+  var l = {
+    method: "deviceManager.configTunnel",
+    params: {loginHandle: parseInt(t), deviceId: parseInt(i), tunnelData: JSON.stringify(o)}
+  };
+  var d = {cmd: "send", msg: JSON.stringify(l)};
+  this.sendAlarmMessage(d);
+  var h = {};
+  h.requestId = e;
+  h.deviceId = i;
+  h.type = s;
+  h.timestamp = Date.parse(new Date) / 1e3;
+  this.setTunnelQueue(n, "setDeviceVolume", h)
+};
+DHAlarmWeb.prototype.getRecordList = function (e, t, i, s) {
+  var a = {
+    method: "deviceManager.getRecordList",
+    params: {loginHandle: parseInt(e), deviceId: parseInt(t), beginTime: parseInt(i), endTime: parseInt(s)}
+  };
+  var r = {cmd: "send", msg: JSON.stringify(a)};
+  this.sendAlarmMessage(r)
+};
+DHAlarmWeb.prototype.playBack = function (e, t, i, s) {
+  var a = {
+    method: "deviceManager.playBack",
+    params: {loginHandle: parseInt(e), deviceId: parseInt(t), beginTime: parseInt(i)}
+  };
+  var r = {cmd: "send", msg: JSON.stringify(a)};
+  this.sendAlarmMessage(r);
+  var n = t + "_" + i;
+  if (!this.pbWfs[n] || this.pbWfs[n].websocketLoader.client.readyState != 1) {
+    this.pbWfs[n] = new Wfs;
+    this.pbWfs[n].attachMedia(s, t, this.clientid, this.loginHandle, this.alarmUrl, "pbvideo", i);
+    this.pbWfs[n].websocketLoader.onVideoFrame = function (e) {
+      this.onVideoFrame(e, t)
+    }.bind(this)
+  }
+  if (!this.pbAudioWs[n] || this.pbAudioWs[n].readyState != 1) {
+    this.openPBAudio(e, t, i)
+  }
+};
+DHAlarmWeb.prototype.openPBAudio = function (e, t, i) {
+  var s = t + "_" + i;
+  this.pbAudioWs[s] = new WebSocket(this.alarmUrl);
+  this.pbAudioWs[s].binaryType = "arraybuffer";
+  this.pbAudioWs[s].onopen = function () {
+    var e = {
+      cmd: "register",
+      clientid: this.clientid,
+      loginHandle: parseInt(this.loginHandle),
+      sessiontype: "pbaudio",
+      deviceid: parseInt(t),
+      msg: i.toString()
+    };
+    this.pbAudioWs[s].send(JSON.stringify(e))
+  }.bind(this);
+  this.pbAudioWs[s].onmessage = function (e) {
+    if (typeof e.data == "object") {
+      var a = new Int16Array(e.data);
+      this.pbBufferPool[s].addFrame(a);
+      if (this.onPBAudioData) {
+        this.onPBAudioData(e.data, t, i)
+      }
+    } else {
+      var r = JSON.parse(e.data);
+      if (r.error == "success") {
+        this.pbPlayer[s] = new PCMPlayer({encoding: "16bitInt", channels: 1, sampleRate: 8e3, flushingTime: 500});
+        this.pbBufferPool[s] = new DHBufferPool;
+        this.pbBufferPool[s].onFrame = function (e) {
+          this.pbPlayer[s].feed(e);
+          this.pbPlayer[s].volume(1)
+        }.bind(this);
+        this.pbBufferPool[s].startBuffering()
+      }
+    }
+  }.bind(this);
+  this.pbAudioWs[s].onclose = function () {
+    console.log("pbAudioWs onclosed ")
+  }.bind(this);
+  this.pbAudioWs[s].onerror = function (e) {
+    console.log("pbAudioWs onerror " + JSON.stringify(e))
+  }.bind(this)
+};
+DHAlarmWeb.prototype.stopBack = function (e, t, i) {
+  var s = t + "_" + i;
+  var a = {
+    method: "deviceManager.stopBack",
+    params: {loginHandle: parseInt(e), deviceId: parseInt(t), beginTime: parseInt(i)}
+  };
+  var r = {cmd: "send", msg: JSON.stringify(a)};
+  this.sendAlarmMessage(r);
+  if (this.pbAudioWs[s]) {
+    this.pbAudioWs[s].close()
+  }
+  if (this.pbPlayer[s]) {
+    this.pbPlayer[s].destroy()
+  }
+  if (this.pbBufferPool[s]) {
+    this.pbBufferPool[s].stopBuffering()
+  }
+  if (this.pbWfs[s]) {
+    this.pbWfs[s].destroy()
+  }
+};
+"use strict";
+var DHBufferPool = function () {
+  this.frameArray = null;
+  this.startTime = null;
+  this.firstFrameTime = null;
+  this.timer = null;
+  this.onFrame = null;
+  this.nrDelay = null;
+  this.sampleRate = null;
+  this.sampleIn = null;
+  this.channel = null;
+  this.intv = null;
+  this.flag = null;
+  this.count = null;
+  this.renderTick = null;
+  this.lastTick = null;
+  this.dropTick = null;
+  this.interval = null
+};
+DHBufferPool.prototype.setOption = function (e) {
+};
+DHBufferPool.prototype.startBuffering = function () {
+  console.log("startBuffering");
+  this.frameArray = new Array;
+  this.sampleRate = 8e3;
+  this.sampleIn = 16;
+  this.channel = 1;
+  this.flag = 0;
+  this.count = 0;
+  this.renderTick = 0;
+  this.lastTick = 0;
+  this.nrDelay = 5 * 320;
+  this.intv = 35;
+  this.dropTick = 0;
+  this.interval = setInterval(function () {
+    this.consume()
+  }.bind(this), 1)
+};
+DHBufferPool.prototype.stopBuffering = function () {
+  clearInterval(this.interval);
+  this.frameArray.splice(0, this.frameArray.length)
+};
+DHBufferPool.prototype.addFrame = function (e) {
+  if (this.renderTick == 0) {
+    this.renderTick = performance.now()
+  }
+  if (this.renderTick >= this.dropTick + 100) {
+    this.dropTick = this.renderTick;
+    return
+  }
+  this.frameArray.unshift(e)
+};
+DHBufferPool.prototype.consume = function () {
+  var e = performance.now();
+  if (this.renderTick > 0) {
+    if (e < this.renderTick + 120) {
+      return
+    }
+  } else {
+    return
+  }
+  if (this.lastTick + this.intv > e) {
+    return
+  }
+  this.lastTick = performance.now();
+  if (this.frameArray.length < 4) return;
+  var t = this.frameArray.pop();
+  var i = this.frameArray.pop();
+  var s = new Int16Array(t.length * 2);
+  s.set(t, 0);
+  s.set(i, t.length);
+  if (this.onFrame) {
+    this.onFrame(s)
+  }
+};
+
+function PCMPlayer(e) {
+  this.init(e)
+}
+
+PCMPlayer.prototype.init = function (e) {
+  var t = {encoding: "16bitInt", channels: 1, sampleRate: 8e3, flushingTime: 1e3};
+  this.option = Object.assign({}, t, e);
+  this.samples = new Float32Array;
+  this.flush = this.flush.bind(this);
+  this.interval = setInterval(this.flush, this.option.flushingTime);
+  this.maxValue = this.getMaxValue();
+  this.typedArray = this.getTypedArray();
+  this.createContext()
+};
+PCMPlayer.prototype.getMaxValue = function () {
+  var e = {"8bitInt": 128, "16bitInt": 32768, "32bitInt": 2147483648, "32bitFloat": 1};
+  return e[this.option.encoding] ? e[this.option.encoding] : e["16bitInt"]
+};
+PCMPlayer.prototype.getTypedArray = function () {
+  var e = {"8bitInt": Int8Array, "16bitInt": Int16Array, "32bitInt": Int32Array, "32bitFloat": Float32Array};
+  return e[this.option.encoding] ? e[this.option.encoding] : e["16bitInt"]
+};
+PCMPlayer.prototype.createContext = function () {
+  this.audioCtx = new (window.AudioContext || window.webkitAudioContext);
+  this.gainNode = this.audioCtx.createGain();
+  this.gainNode.gain.value = 1;
+  this.gainNode.connect(this.audioCtx.destination);
+  this.startTime = this.audioCtx.currentTime
+};
+PCMPlayer.prototype.isTypedArray = function (e) {
+  return e.byteLength && e.buffer && e.buffer.constructor == ArrayBuffer
+};
+PCMPlayer.prototype.feed = function (e) {
+  if (!this.isTypedArray(e)) return;
+  e = this.getFormatedValue(e);
+  var t = new Float32Array(this.samples.length + e.length);
+  t.set(this.samples, 0);
+  t.set(e, this.samples.length);
+  this.samples = t
+};
+PCMPlayer.prototype.getFormatedValue = function (e) {
+  var e = new this.typedArray(e.buffer), t = new Float32Array(e.length), i;
+  for (i = 0; i < e.length; i++) {
+    t[i] = e[i] / this.maxValue
+  }
+  return t
+};
+PCMPlayer.prototype.volume = function (e) {
+  this.gainNode.gain.value = e
+};
+PCMPlayer.prototype.destroy = function () {
+  if (this.interval) {
+    clearInterval(this.interval)
+  }
+  this.samples = null;
+  if (this.audioCtx) {
+    this.audioCtx.close()
+  }
+  this.audioCtx = null
+};
+PCMPlayer.prototype.flush = function () {
+  if (!this.samples.length) return;
+  var e = this.audioCtx.createBufferSource(), t = this.samples.length / this.option.channels,
+    i = this.audioCtx.createBuffer(this.option.channels, t, this.option.sampleRate), s, a, r, n, o;
+  for (a = 0; a < this.option.channels; a++) {
+    s = i.getChannelData(a);
+    r = a;
+    o = 50;
+    for (n = 0; n < t; n++) {
+      s[n] = this.samples[r];
+      if (n < 50) {
+        s[n] = s[n] * n / 50
+      }
+      if (n >= t - 51) {
+        s[n] = s[n] * o-- / 50
+      }
+      r += this.option.channels
+    }
+  }
+  if (this.startTime < this.audioCtx.currentTime) {
+    this.startTime = this.audioCtx.currentTime
+  }
+  e.buffer = i;
+  e.connect(this.gainNode);
+  e.start(this.startTime);
+  this.startTime += i.duration;
+  this.samples = new Float32Array
+};

+ 4152 - 0
public/dhWebSdk/wfs.js

@@ -0,0 +1,4152 @@
+(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Wfs = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+function EventEmitter() {
+  this._events = this._events || {};
+  this._maxListeners = this._maxListeners || undefined;
+}
+module.exports = EventEmitter;
+
+// Backwards-compat with node 0.10.x
+EventEmitter.EventEmitter = EventEmitter;
+
+EventEmitter.prototype._events = undefined;
+EventEmitter.prototype._maxListeners = undefined;
+
+// By default EventEmitters will print a warning if more than 10 listeners are
+// added to it. This is a useful default which helps finding memory leaks.
+EventEmitter.defaultMaxListeners = 10;
+
+// Obviously not all Emitters should be limited to 10. This function allows
+// that to be increased. Set to zero for unlimited.
+EventEmitter.prototype.setMaxListeners = function(n) {
+  if (!isNumber(n) || n < 0 || isNaN(n))
+    throw TypeError('n must be a positive number');
+  this._maxListeners = n;
+  return this;
+};
+
+EventEmitter.prototype.emit = function(type) {
+  var er, handler, len, args, i, listeners;
+
+  if (!this._events)
+    this._events = {};
+
+  // If there is no 'error' event listener then throw.
+  if (type === 'error') {
+    if (!this._events.error ||
+        (isObject(this._events.error) && !this._events.error.length)) {
+      er = arguments[1];
+      if (er instanceof Error) {
+        throw er; // Unhandled 'error' event
+      } else {
+        // At least give some kind of context to the user
+        var err = new Error('Uncaught, unspecified "error" event. (' + er + ')');
+        err.context = er;
+        throw err;
+      }
+    }
+  }
+
+  handler = this._events[type];
+
+  if (isUndefined(handler))
+    return false;
+
+  if (isFunction(handler)) {
+    switch (arguments.length) {
+      // fast cases
+      case 1:
+        handler.call(this);
+        break;
+      case 2:
+        handler.call(this, arguments[1]);
+        break;
+      case 3:
+        handler.call(this, arguments[1], arguments[2]);
+        break;
+      // slower
+      default:
+        args = Array.prototype.slice.call(arguments, 1);
+        handler.apply(this, args);
+    }
+  } else if (isObject(handler)) {
+    args = Array.prototype.slice.call(arguments, 1);
+    listeners = handler.slice();
+    len = listeners.length;
+    for (i = 0; i < len; i++)
+      listeners[i].apply(this, args);
+  }
+
+  return true;
+};
+
+EventEmitter.prototype.addListener = function(type, listener) {
+  var m;
+
+  if (!isFunction(listener))
+    throw TypeError('listener must be a function');
+
+  if (!this._events)
+    this._events = {};
+
+  // To avoid recursion in the case that type === "newListener"! Before
+  // adding it to the listeners, first emit "newListener".
+  if (this._events.newListener)
+    this.emit('newListener', type,
+              isFunction(listener.listener) ?
+              listener.listener : listener);
+
+  if (!this._events[type])
+    // Optimize the case of one listener. Don't need the extra array object.
+    this._events[type] = listener;
+  else if (isObject(this._events[type]))
+    // If we've already got an array, just append.
+    this._events[type].push(listener);
+  else
+    // Adding the second element, need to change to array.
+    this._events[type] = [this._events[type], listener];
+
+  // Check for listener leak
+  if (isObject(this._events[type]) && !this._events[type].warned) {
+    if (!isUndefined(this._maxListeners)) {
+      m = this._maxListeners;
+    } else {
+      m = EventEmitter.defaultMaxListeners;
+    }
+
+    if (m && m > 0 && this._events[type].length > m) {
+      this._events[type].warned = true;
+      console.error('(node) warning: possible EventEmitter memory ' +
+                    'leak detected. %d listeners added. ' +
+                    'Use emitter.setMaxListeners() to increase limit.',
+                    this._events[type].length);
+      if (typeof console.trace === 'function') {
+        // not supported in IE 10
+        console.trace();
+      }
+    }
+  }
+
+  return this;
+};
+
+EventEmitter.prototype.on = EventEmitter.prototype.addListener;
+
+EventEmitter.prototype.once = function(type, listener) {
+  if (!isFunction(listener))
+    throw TypeError('listener must be a function');
+
+  var fired = false;
+
+  function g() {
+    this.removeListener(type, g);
+
+    if (!fired) {
+      fired = true;
+      listener.apply(this, arguments);
+    }
+  }
+
+  g.listener = listener;
+  this.on(type, g);
+
+  return this;
+};
+
+// emits a 'removeListener' event iff the listener was removed
+EventEmitter.prototype.removeListener = function(type, listener) {
+  var list, position, length, i;
+
+  if (!isFunction(listener))
+    throw TypeError('listener must be a function');
+
+  if (!this._events || !this._events[type])
+    return this;
+
+  list = this._events[type];
+  length = list.length;
+  position = -1;
+
+  if (list === listener ||
+      (isFunction(list.listener) && list.listener === listener)) {
+    delete this._events[type];
+    if (this._events.removeListener)
+      this.emit('removeListener', type, listener);
+
+  } else if (isObject(list)) {
+    for (i = length; i-- > 0;) {
+      if (list[i] === listener ||
+          (list[i].listener && list[i].listener === listener)) {
+        position = i;
+        break;
+      }
+    }
+
+    if (position < 0)
+      return this;
+
+    if (list.length === 1) {
+      list.length = 0;
+      delete this._events[type];
+    } else {
+      list.splice(position, 1);
+    }
+
+    if (this._events.removeListener)
+      this.emit('removeListener', type, listener);
+  }
+
+  return this;
+};
+
+EventEmitter.prototype.removeAllListeners = function(type) {
+  var key, listeners;
+
+  if (!this._events)
+    return this;
+
+  // not listening for removeListener, no need to emit
+  if (!this._events.removeListener) {
+    if (arguments.length === 0)
+      this._events = {};
+    else if (this._events[type])
+      delete this._events[type];
+    return this;
+  }
+
+  // emit removeListener for all listeners on all events
+  if (arguments.length === 0) {
+    for (key in this._events) {
+      if (key === 'removeListener') continue;
+      this.removeAllListeners(key);
+    }
+    this.removeAllListeners('removeListener');
+    this._events = {};
+    return this;
+  }
+
+  listeners = this._events[type];
+
+  if (isFunction(listeners)) {
+    this.removeListener(type, listeners);
+  } else if (listeners) {
+    // LIFO order
+    while (listeners.length)
+      this.removeListener(type, listeners[listeners.length - 1]);
+  }
+  delete this._events[type];
+
+  return this;
+};
+
+EventEmitter.prototype.listeners = function(type) {
+  var ret;
+  if (!this._events || !this._events[type])
+    ret = [];
+  else if (isFunction(this._events[type]))
+    ret = [this._events[type]];
+  else
+    ret = this._events[type].slice();
+  return ret;
+};
+
+EventEmitter.prototype.listenerCount = function(type) {
+  if (this._events) {
+    var evlistener = this._events[type];
+
+    if (isFunction(evlistener))
+      return 1;
+    else if (evlistener)
+      return evlistener.length;
+  }
+  return 0;
+};
+
+EventEmitter.listenerCount = function(emitter, type) {
+  return emitter.listenerCount(type);
+};
+
+function isFunction(arg) {
+  return typeof arg === 'function';
+}
+
+function isNumber(arg) {
+  return typeof arg === 'number';
+}
+
+function isObject(arg) {
+  return typeof arg === 'object' && arg !== null;
+}
+
+function isUndefined(arg) {
+  return arg === void 0;
+}
+
+},{}],2:[function(require,module,exports){
+// shim for using process in browser
+var process = module.exports = {};
+
+// cached from whatever global is present so that test runners that stub it
+// don't break things.  But we need to wrap it in a try catch in case it is
+// wrapped in strict mode code which doesn't define any globals.  It's inside a
+// function because try/catches deoptimize in certain engines.
+
+var cachedSetTimeout;
+var cachedClearTimeout;
+
+function defaultSetTimout() {
+    throw new Error('setTimeout has not been defined');
+}
+function defaultClearTimeout () {
+    throw new Error('clearTimeout has not been defined');
+}
+(function () {
+    try {
+        if (typeof setTimeout === 'function') {
+            cachedSetTimeout = setTimeout;
+        } else {
+            cachedSetTimeout = defaultSetTimout;
+        }
+    } catch (e) {
+        cachedSetTimeout = defaultSetTimout;
+    }
+    try {
+        if (typeof clearTimeout === 'function') {
+            cachedClearTimeout = clearTimeout;
+        } else {
+            cachedClearTimeout = defaultClearTimeout;
+        }
+    } catch (e) {
+        cachedClearTimeout = defaultClearTimeout;
+    }
+} ())
+function runTimeout(fun) {
+    if (cachedSetTimeout === setTimeout) {
+        //normal enviroments in sane situations
+        return setTimeout(fun, 0);
+    }
+    // if setTimeout wasn't available but was latter defined
+    if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
+        cachedSetTimeout = setTimeout;
+        return setTimeout(fun, 0);
+    }
+    try {
+        // when when somebody has screwed with setTimeout but no I.E. maddness
+        return cachedSetTimeout(fun, 0);
+    } catch(e){
+        try {
+            // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
+            return cachedSetTimeout.call(null, fun, 0);
+        } catch(e){
+            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
+            return cachedSetTimeout.call(this, fun, 0);
+        }
+    }
+
+
+}
+function runClearTimeout(marker) {
+    if (cachedClearTimeout === clearTimeout) {
+        //normal enviroments in sane situations
+        return clearTimeout(marker);
+    }
+    // if clearTimeout wasn't available but was latter defined
+    if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
+        cachedClearTimeout = clearTimeout;
+        return clearTimeout(marker);
+    }
+    try {
+        // when when somebody has screwed with setTimeout but no I.E. maddness
+        return cachedClearTimeout(marker);
+    } catch (e){
+        try {
+            // When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally
+            return cachedClearTimeout.call(null, marker);
+        } catch (e){
+            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
+            // Some versions of I.E. have different rules for clearTimeout vs setTimeout
+            return cachedClearTimeout.call(this, marker);
+        }
+    }
+
+
+
+}
+var queue = [];
+var draining = false;
+var currentQueue;
+var queueIndex = -1;
+
+function cleanUpNextTick() {
+    if (!draining || !currentQueue) {
+        return;
+    }
+    draining = false;
+    if (currentQueue.length) {
+        queue = currentQueue.concat(queue);
+    } else {
+        queueIndex = -1;
+    }
+    if (queue.length) {
+        drainQueue();
+    }
+}
+
+function drainQueue() {
+    if (draining) {
+        return;
+    }
+    var timeout = runTimeout(cleanUpNextTick);
+    draining = true;
+
+    var len = queue.length;
+    while(len) {
+        currentQueue = queue;
+        queue = [];
+        while (++queueIndex < len) {
+            if (currentQueue) {
+                currentQueue[queueIndex].run();
+            }
+        }
+        queueIndex = -1;
+        len = queue.length;
+    }
+    currentQueue = null;
+    draining = false;
+    runClearTimeout(timeout);
+}
+
+process.nextTick = function (fun) {
+    var args = new Array(arguments.length - 1);
+    if (arguments.length > 1) {
+        for (var i = 1; i < arguments.length; i++) {
+            args[i - 1] = arguments[i];
+        }
+    }
+    queue.push(new Item(fun, args));
+    if (queue.length === 1 && !draining) {
+        runTimeout(drainQueue);
+    }
+};
+
+// v8 likes predictible objects
+function Item(fun, array) {
+    this.fun = fun;
+    this.array = array;
+}
+Item.prototype.run = function () {
+    this.fun.apply(null, this.array);
+};
+process.title = 'browser';
+process.browser = true;
+process.env = {};
+process.argv = [];
+process.version = ''; // empty string to avoid regexp issues
+process.versions = {};
+
+function noop() {}
+
+process.on = noop;
+process.addListener = noop;
+process.once = noop;
+process.off = noop;
+process.removeListener = noop;
+process.removeAllListeners = noop;
+process.emit = noop;
+process.prependListener = noop;
+process.prependOnceListener = noop;
+
+process.listeners = function (name) { return [] }
+
+process.binding = function (name) {
+    throw new Error('process.binding is not supported');
+};
+
+process.cwd = function () { return '/' };
+process.chdir = function (dir) {
+    throw new Error('process.chdir is not supported');
+};
+process.umask = function() { return 0; };
+
+},{}],3:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _events = require('../events');
+
+var _events2 = _interopRequireDefault(_events);
+
+var _eventHandler = require('../event-handler');
+
+var _eventHandler2 = _interopRequireDefault(_eventHandler);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /*
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * Buffer Controller
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               */
+
+var BufferController = function (_EventHandler) {
+  _inherits(BufferController, _EventHandler);
+
+  function BufferController(wfs) {
+    _classCallCheck(this, BufferController);
+
+    var _this = _possibleConstructorReturn(this, (BufferController.__proto__ || Object.getPrototypeOf(BufferController)).call(this, wfs, _events2.default.MEDIA_ATTACHING, _events2.default.BUFFER_APPENDING, _events2.default.BUFFER_RESET));
+
+    _this.mediaSource = null;
+    _this.media = null;
+    _this.pendingTracks = {};
+    _this.sourceBuffer = {};
+    _this.segments = [];
+
+    _this.appended = 0;
+    _this._msDuration = null;
+
+    // Source Buffer listeners
+    _this.onsbue = _this.onSBUpdateEnd.bind(_this);
+
+    _this.browserType = 0;
+    if (navigator.userAgent.toLowerCase().indexOf('firefox') !== -1) {
+      _this.browserType = 1;
+    }
+    _this.mediaType = 'H264Raw';
+
+    _this.websocketName = undefined;
+    _this.channelName = undefined;
+    return _this;
+  }
+
+  _createClass(BufferController, [{
+    key: 'destroy',
+    value: function destroy() {
+      _eventHandler2.default.prototype.destroy.call(this);
+    }
+  }, {
+    key: 'onMediaAttaching',
+    value: function onMediaAttaching(data) {
+      var media = this.media = data.media;
+      this.mediaType = data.mediaType;
+      this.websocketName = data.websocketName;
+      this.channelName = data.channelName;
+      this.deviceId = data.deviceId;
+      this.clientid = data.clientid;
+      this.loginHandle = data.loginHandle;
+      this.wsUrl = data.wsUrl;
+      this.sessiontype = data.sessiontype;
+      this.begintime = data.begintime;
+      if (media) {
+        // setup the media source
+        var ms = this.mediaSource = new MediaSource();
+        //Media Source listeners
+        this.onmso = this.onMediaSourceOpen.bind(this);
+        this.onmse = this.onMediaSourceEnded.bind(this);
+        this.onmsc = this.onMediaSourceClose.bind(this);
+        ms.addEventListener('sourceopen', this.onmso);
+        ms.addEventListener('sourceended', this.onmse);
+        ms.addEventListener('sourceclose', this.onmsc);
+        // link video and media Source
+        media.src = URL.createObjectURL(ms);
+      }
+    }
+  }, {
+    key: 'onMediaDetaching',
+    value: function onMediaDetaching() {}
+  }, {
+    key: 'onBufferAppending',
+    value: function onBufferAppending(data) {
+      if (!this.segments) {
+        this.segments = [data];
+      } else {
+        this.segments.push(data);
+      }
+	  if(this.media.paused){
+		   //this.media.play();
+		  // return;
+	  }
+      this.doAppending();
+    }
+  }, {
+    key: 'onMediaSourceClose',
+    value: function onMediaSourceClose() {
+      console.log('media source closed');
+    }
+  }, {
+    key: 'onMediaSourceEnded',
+    value: function onMediaSourceEnded() {
+      console.log('media source ended');
+    }
+  }, {
+    key: 'onSBUpdateEnd',
+    value: function onSBUpdateEnd(event) {
+      // Firefox
+      if (this.browserType === 1) {
+       this.mediaSource.endOfStream();
+        this.media.play();
+      }
+      // console.log("currentTime: " + this.media.currentTime);
+      var buffered = this.sourceBuffer['video'].buffered;
+      var played = this.media.played;
+
+	  if(buffered.length >0 && played.length){
+			if((buffered.end(0) - this.media.currentTime)> 1){
+				if(!this.media.paused){
+					this.media.currentTime = buffered.end(0);
+				}
+
+			}
+	  }
+      // for (var j = 0; j < played.length; j++) {
+       // console.log("played start: " + played.start(j));
+       // console.log("played end: " + played.end(j));
+      // }
+     // console.log("readystate: " + this.media.readyState);
+      // for (var i = 0; i < buffered.length; i++) {
+       // console.log("start: " + buffered.start(i));
+       // console.log("end: " + buffered.end(i));
+      // }
+      this.appending = false;
+      this.doAppending();
+      this.updateMediaElementDuration();
+    }
+  }, {
+    key: 'updateMediaElementDuration',
+    value: function updateMediaElementDuration() {}
+  }, {
+    key: 'onMediaSourceOpen',
+    value: function onMediaSourceOpen() {
+      var mediaSource = this.mediaSource;
+      if (mediaSource) {
+        // once received, don't listen anymore to sourceopen event
+        mediaSource.removeEventListener('sourceopen', this.onmso);
+      }
+
+      if (this.mediaType === 'FMp4') {
+        this.checkPendingTracks();
+      }
+      this.wfs.trigger(_events2.default.MEDIA_ATTACHED, { media: this.media, channelName: this.channelName, mediaType: this.mediaType, websocketName: this.websocketName, deviceId: this.deviceId,clientid: this.clientid,loginHandle: this.loginHandle,wsUrl: this.wsUrl, sessiontype: this.sessiontype, begintime: this.begintime });
+    }
+  }, {
+    key: 'checkPendingTracks',
+    value: function checkPendingTracks() {
+      this.createSourceBuffers({ tracks: 'video', mimeType: '' });
+      this.pendingTracks = {};
+    }
+  }, {
+    key: 'onBufferReset',
+    value: function onBufferReset(data) {
+      if (this.mediaType === 'H264Raw') {
+        this.createSourceBuffers({ tracks: 'video', mimeType: data.mimeType });
+      }
+    }
+  }, {
+    key: 'createSourceBuffers',
+    value: function createSourceBuffers(tracks) {
+      var sourceBuffer = this.sourceBuffer,
+          mediaSource = this.mediaSource;
+      var mimeType = void 0;
+      if (tracks.mimeType === '') {
+        mimeType = 'video/mp4;codecs=avc1.420028'; // avc1.42c01f avc1.42801e avc1.640028 avc1.420028
+      } else {
+       mimeType = 'video/mp4;codecs=' + tracks.mimeType;
+      }
+
+      try {
+        var sb = sourceBuffer['video'] = this.mediaSource.addSourceBuffer(mimeType);
+        sb.addEventListener('updateend', this.onsbue);
+        track.buffer = sb;
+      } catch (err) {}
+      this.wfs.trigger(_events2.default.BUFFER_CREATED, { tracks: tracks });
+      let playPromise = this.media.play();
+	  if (playPromise !== undefined) {
+			playPromise.then(function() {
+				this.media.play();
+			}.bind(this)).catch(function(error) {
+				console.log(error);
+			});
+	  }
+    }
+  }, {
+    key: 'doAppending',
+    value: function doAppending() {
+      var wfs = this.wfs,
+          sourceBuffer = this.sourceBuffer,
+          segments = this.segments;
+      if (Object.keys(sourceBuffer).length) {
+        if (this.media.error) {
+          this.segments = [];
+          if(this.errLogTimes > 200) return;
+          this.errLogTimes >= 0 ? this.errLogTimes++ : this.errLogTimes = 0;
+          console.log('trying to append although a media error occured, flush segment and abort:'+this.media.error.message);
+          return;
+        }
+        this.errLogTimes = 0;
+        if (this.appending) {
+          return;
+        }
+
+        if (segments && segments.length) {
+          var segment = segments.shift();
+          //console.log("segments len: " + segments.length + " segment len: " + segment.data.length);
+          try {
+            if (sourceBuffer[segment.type]) {
+              this.parent = segment.parent;
+              sourceBuffer[segment.type].appendBuffer(segment.data);
+              this.appendError = 0;
+              this.appended++;
+              this.appending = true;
+            } else {}
+          } catch (err) {
+            // in case any error occured while appending, put back segment in segments table
+            segments.unshift(segment);
+            var event = { type: ErrorTypes.MEDIA_ERROR };
+            if (err.code !== 22) {
+              if (this.appendError) {
+                this.appendError++;
+              } else {
+                this.appendError = 1;
+              }
+              event.details = ErrorDetails.BUFFER_APPEND_ERROR;
+              event.frag = this.fragCurrent;
+              if (this.appendError > wfs.config.appendErrorMaxRetry) {
+                segments = [];
+                event.fatal = true;
+                return;
+              } else {
+                event.fatal = false;
+              }
+            } else {
+              this.segments = [];
+              event.details = ErrorDetails.BUFFER_FULL_ERROR;
+              return;
+            }
+          }
+        }
+      }
+    }
+  }]);
+
+  return BufferController;
+}(_eventHandler2.default);
+
+exports.default = BufferController;
+
+},{"../event-handler":8,"../events":9}],4:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _events = require('../events');
+
+var _events2 = _interopRequireDefault(_events);
+
+var _eventHandler = require('../event-handler');
+
+var _eventHandler2 = _interopRequireDefault(_eventHandler);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /*
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * Flow Controller
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               */
+
+var FlowController = function (_EventHandler) {
+  _inherits(FlowController, _EventHandler);
+
+  function FlowController(wfs) {
+    _classCallCheck(this, FlowController);
+
+    var _this = _possibleConstructorReturn(this, (FlowController.__proto__ || Object.getPrototypeOf(FlowController)).call(this, wfs, _events2.default.MEDIA_ATTACHED, _events2.default.BUFFER_CREATED, _events2.default.FILE_PARSING_DATA, _events2.default.FILE_HEAD_LOADED, _events2.default.FILE_DATA_LOADED, _events2.default.WEBSOCKET_ATTACHED, _events2.default.FRAG_PARSING_DATA, _events2.default.FRAG_PARSING_INIT_SEGMENT));
+
+    _this.fileStart = 0;
+    _this.fileEnd = 0;
+    _this.pendingAppending = 0;
+    _this.mediaType = undefined;
+    channelName: _this.channelName;
+    return _this;
+  }
+
+  _createClass(FlowController, [{
+    key: 'destroy',
+    value: function destroy() {
+      _eventHandler2.default.prototype.destroy.call(this);
+    }
+  }, {
+    key: 'onMediaAttached',
+    value: function onMediaAttached(data) {
+      if (data.websocketName != undefined) {
+        var client = new WebSocket(data.wsUrl);
+        this.wfs.attachWebsocket(client, data.channelName, data.deviceId, data.clientid, data.loginHandle, data.sessiontype, data.begintime);
+      } else {
+        console.log('websocketName ERROE!!!');
+      }
+    }
+  }, {
+    key: 'onBufferCreated',
+    value: function onBufferCreated(data) {
+      this.mediaType = data.mediaType;
+    }
+  }, {
+    key: 'onFileHeadLoaded',
+    value: function onFileHeadLoaded(data) {}
+  }, {
+    key: 'onFileDataLoaded',
+    value: function onFileDataLoaded(data) {}
+  }, {
+    key: 'onFileParsingData',
+    value: function onFileParsingData(data) {}
+  }, {
+    key: 'onWebsocketAttached',
+    value: function onWebsocketAttached(data) {
+      this.wfs.trigger(_events2.default.BUFFER_APPENDING, { type: 'video', data: data.payload, parent: 'main' });
+    }
+  }, {
+    key: 'onFragParsingInitSegment',
+    value: function onFragParsingInitSegment(data) {
+      var tracks = data.tracks,
+          trackName,
+          track;
+
+      track = tracks.video;
+      if (track) {
+        track.id = data.id;
+      }
+
+      for (trackName in tracks) {
+        track = tracks[trackName];
+        var initSegment = track.initSegment;
+        if (initSegment) {
+          this.pendingAppending++;
+          this.wfs.trigger(_events2.default.BUFFER_APPENDING, { type: trackName, data: initSegment, parent: 'main' });
+        }
+      }
+    }
+  }, {
+    key: 'onFragParsingData',
+    value: function onFragParsingData(data) {
+      var _this2 = this;
+
+      if (data.type === 'video') {}
+
+      [data.data1, data.data2].forEach(function (buffer) {
+        if (buffer) {
+          _this2.pendingAppending++;
+          _this2.wfs.trigger(_events2.default.BUFFER_APPENDING, { type: data.type, data: buffer, parent: 'main' });
+        }
+      });
+    }
+  }]);
+
+  return FlowController;
+}(_eventHandler2.default);
+
+exports.default = FlowController;
+
+},{"../event-handler":8,"../events":9}],5:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /**
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * Parser for exponential Golomb codes, a variable-bitwidth number encoding scheme used by h264.
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     */
+
+var _logger = require('../utils/logger');
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var ExpGolomb = function () {
+  function ExpGolomb(data) {
+    _classCallCheck(this, ExpGolomb);
+
+    this.data = data;
+    // the number of bytes left to examine in this.data
+    this.bytesAvailable = this.data.byteLength;
+    // the current word being examined
+    this.word = 0; // :uint
+    // the number of bits left to examine in the current word
+    this.bitsAvailable = 0; // :uint
+  }
+
+  // ():void
+
+
+  _createClass(ExpGolomb, [{
+    key: 'loadWord',
+    value: function loadWord() {
+      var position = this.data.byteLength - this.bytesAvailable,
+          workingBytes = new Uint8Array(4),
+          availableBytes = Math.min(4, this.bytesAvailable);
+      if (availableBytes === 0) {
+        throw new Error('no bytes available');
+      }
+      workingBytes.set(this.data.subarray(position, position + availableBytes));
+      this.word = new DataView(workingBytes.buffer).getUint32(0);
+      // track the amount of this.data that has been processed
+      this.bitsAvailable = availableBytes * 8;
+      this.bytesAvailable -= availableBytes;
+    }
+
+    // (count:int):void
+
+  }, {
+    key: 'skipBits',
+    value: function skipBits(count) {
+      var skipBytes; // :int
+      if (this.bitsAvailable > count) {
+        this.word <<= count;
+        this.bitsAvailable -= count;
+      } else {
+        count -= this.bitsAvailable;
+        skipBytes = count >> 3;
+        count -= skipBytes >> 3;
+        this.bytesAvailable -= skipBytes;
+        this.loadWord();
+        this.word <<= count;
+        this.bitsAvailable -= count;
+      }
+    }
+
+    // (size:int):uint
+
+  }, {
+    key: 'readBits',
+    value: function readBits(size) {
+      var bits = Math.min(this.bitsAvailable, size),
+          // :uint
+      valu = this.word >>> 32 - bits; // :uint
+      if (size > 32) {
+        _logger.logger.error('Cannot read more than 32 bits at a time');
+      }
+      this.bitsAvailable -= bits;
+      if (this.bitsAvailable > 0) {
+        this.word <<= bits;
+      } else if (this.bytesAvailable > 0) {
+        this.loadWord();
+      }
+      bits = size - bits;
+      if (bits > 0) {
+        return valu << bits | this.readBits(bits);
+      } else {
+        return valu;
+      }
+    }
+
+    // ():uint
+
+  }, {
+    key: 'skipLZ',
+    value: function skipLZ() {
+      var leadingZeroCount; // :uint
+      for (leadingZeroCount = 0; leadingZeroCount < this.bitsAvailable; ++leadingZeroCount) {
+        if (0 !== (this.word & 0x80000000 >>> leadingZeroCount)) {
+          // the first bit of working word is 1
+          this.word <<= leadingZeroCount;
+          this.bitsAvailable -= leadingZeroCount;
+          return leadingZeroCount;
+        }
+      }
+      // we exhausted word and still have not found a 1
+      this.loadWord();
+      return leadingZeroCount + this.skipLZ();
+    }
+
+    // ():void
+
+  }, {
+    key: 'skipUEG',
+    value: function skipUEG() {
+      this.skipBits(1 + this.skipLZ());
+    }
+
+    // ():void
+
+  }, {
+    key: 'skipEG',
+    value: function skipEG() {
+      this.skipBits(1 + this.skipLZ());
+    }
+
+    // ():uint
+
+  }, {
+    key: 'readUEG',
+    value: function readUEG() {
+      var clz = this.skipLZ(); // :uint
+      return this.readBits(clz + 1) - 1;
+    }
+
+    // ():int
+
+  }, {
+    key: 'readEG',
+    value: function readEG() {
+      var valu = this.readUEG(); // :int
+      if (0x01 & valu) {
+        // the number is odd if the low order bit is set
+        return 1 + valu >>> 1; // add 1 to make it even, and divide by 2
+      } else {
+        return -1 * (valu >>> 1); // divide by two then make it negative
+      }
+    }
+
+    // Some convenience functions
+    // :Boolean
+
+  }, {
+    key: 'readBoolean',
+    value: function readBoolean() {
+      return 1 === this.readBits(1);
+    }
+
+    // ():int
+
+  }, {
+    key: 'readUByte',
+    value: function readUByte() {
+      return this.readBits(8);
+    }
+
+    // ():int
+
+  }, {
+    key: 'readUShort',
+    value: function readUShort() {
+      return this.readBits(16);
+    }
+    // ():int
+
+  }, {
+    key: 'readUInt',
+    value: function readUInt() {
+      return this.readBits(32);
+    }
+
+    /**
+     * Advance the ExpGolomb decoder past a scaling list. The scaling
+     * list is optionally transmitted as part of a sequence parameter
+     * set and is not relevant to transmuxing.
+     * @param count {number} the number of entries in this scaling list
+     * @see Recommendation ITU-T H.264, Section 7.3.2.1.1.1
+     */
+
+  }, {
+    key: 'skipScalingList',
+    value: function skipScalingList(count) {
+      var lastScale = 8,
+          nextScale = 8,
+          j,
+          deltaScale;
+      for (j = 0; j < count; j++) {
+        if (nextScale !== 0) {
+          deltaScale = this.readEG();
+          nextScale = (lastScale + deltaScale + 256) % 256;
+        }
+        lastScale = nextScale === 0 ? lastScale : nextScale;
+      }
+    }
+
+    /**
+     * Read a sequence parameter set and return some interesting video
+     * properties. A sequence parameter set is the H264 metadata that
+     * describes the properties of upcoming video frames.
+     * @param data {Uint8Array} the bytes of a sequence parameter set
+     * @return {object} an object with configuration parsed from the
+     * sequence parameter set, including the dimensions of the
+     * associated video frames.
+     */
+
+  }, {
+    key: 'readSPS',
+    value: function readSPS() {
+      var frameCropLeftOffset = 0,
+          frameCropRightOffset = 0,
+          frameCropTopOffset = 0,
+          frameCropBottomOffset = 0,
+          sarScale = 1,
+          profileIdc,
+          profileCompat,
+          levelIdc,
+          numRefFramesInPicOrderCntCycle,
+          picWidthInMbsMinus1,
+          picHeightInMapUnitsMinus1,
+          frameMbsOnlyFlag,
+          scalingListCount,
+          i;
+      this.readUByte();
+      profileIdc = this.readUByte(); // profile_idc
+      profileCompat = this.readBits(5); // constraint_set[0-4]_flag, u(5)
+      this.skipBits(3); // reserved_zero_3bits u(3),
+      levelIdc = this.readUByte(); //level_idc u(8)
+      this.skipUEG(); // seq_parameter_set_id
+      // some profiles have more optional data we don't need
+      if (profileIdc === 100 || profileIdc === 110 || profileIdc === 122 || profileIdc === 244 || profileIdc === 44 || profileIdc === 83 || profileIdc === 86 || profileIdc === 118 || profileIdc === 128) {
+        var chromaFormatIdc = this.readUEG();
+        if (chromaFormatIdc === 3) {
+          this.skipBits(1); // separate_colour_plane_flag
+        }
+        this.skipUEG(); // bit_depth_luma_minus8
+        this.skipUEG(); // bit_depth_chroma_minus8
+        this.skipBits(1); // qpprime_y_zero_transform_bypass_flag
+        if (this.readBoolean()) {
+          // seq_scaling_matrix_present_flag
+          scalingListCount = chromaFormatIdc !== 3 ? 8 : 12;
+          for (i = 0; i < scalingListCount; i++) {
+            if (this.readBoolean()) {
+              // seq_scaling_list_present_flag[ i ]
+              if (i < 6) {
+                this.skipScalingList(16);
+              } else {
+                this.skipScalingList(64);
+              }
+            }
+          }
+        }
+      }
+      this.skipUEG(); // log2_max_frame_num_minus4
+      var picOrderCntType = this.readUEG();
+      if (picOrderCntType === 0) {
+        this.readUEG(); //log2_max_pic_order_cnt_lsb_minus4
+      } else if (picOrderCntType === 1) {
+        this.skipBits(1); // delta_pic_order_always_zero_flag
+        this.skipEG(); // offset_for_non_ref_pic
+        this.skipEG(); // offset_for_top_to_bottom_field
+        numRefFramesInPicOrderCntCycle = this.readUEG();
+        for (i = 0; i < numRefFramesInPicOrderCntCycle; i++) {
+          this.skipEG(); // offset_for_ref_frame[ i ]
+        }
+      }
+      this.skipUEG(); // max_num_ref_frames
+      this.skipBits(1); // gaps_in_frame_num_value_allowed_flag
+      picWidthInMbsMinus1 = this.readUEG();
+      picHeightInMapUnitsMinus1 = this.readUEG();
+      frameMbsOnlyFlag = this.readBits(1);
+      if (frameMbsOnlyFlag === 0) {
+        this.skipBits(1); // mb_adaptive_frame_field_flag
+      }
+      this.skipBits(1); // direct_8x8_inference_flag
+      if (this.readBoolean()) {
+        // frame_cropping_flag
+        frameCropLeftOffset = this.readUEG();
+        frameCropRightOffset = this.readUEG();
+        frameCropTopOffset = this.readUEG();
+        frameCropBottomOffset = this.readUEG();
+      }
+      if (this.readBoolean()) {
+        // vui_parameters_present_flag
+        if (this.readBoolean()) {
+          // aspect_ratio_info_present_flag
+          var sarRatio = void 0;
+          var aspectRatioIdc = this.readUByte();
+          switch (aspectRatioIdc) {
+            case 1:
+              sarRatio = [1, 1];break;
+            case 2:
+              sarRatio = [12, 11];break;
+            case 3:
+              sarRatio = [10, 11];break;
+            case 4:
+              sarRatio = [16, 11];break;
+            case 5:
+              sarRatio = [40, 33];break;
+            case 6:
+              sarRatio = [24, 11];break;
+            case 7:
+              sarRatio = [20, 11];break;
+            case 8:
+              sarRatio = [32, 11];break;
+            case 9:
+              sarRatio = [80, 33];break;
+            case 10:
+              sarRatio = [18, 11];break;
+            case 11:
+              sarRatio = [15, 11];break;
+            case 12:
+              sarRatio = [64, 33];break;
+            case 13:
+              sarRatio = [160, 99];break;
+            case 14:
+              sarRatio = [4, 3];break;
+            case 15:
+              sarRatio = [3, 2];break;
+            case 16:
+              sarRatio = [2, 1];break;
+            case 255:
+              {
+                sarRatio = [this.readUByte() << 8 | this.readUByte(), this.readUByte() << 8 | this.readUByte()];
+                break;
+              }
+          }
+          if (sarRatio) {
+            sarScale = sarRatio[0] / sarRatio[1];
+          }
+        }
+      }
+      return {
+        width: Math.ceil(((picWidthInMbsMinus1 + 1) * 16 - frameCropLeftOffset * 2 - frameCropRightOffset * 2) * sarScale),
+        height: (2 - frameMbsOnlyFlag) * (picHeightInMapUnitsMinus1 + 1) * 16 - (frameMbsOnlyFlag ? 2 : 4) * (frameCropTopOffset + frameCropBottomOffset)
+      };
+    }
+  }, {
+    key: 'readSliceType',
+    value: function readSliceType() {
+      // skip NALu type
+      this.readUByte();
+      // discard first_mb_in_slice
+      this.readUEG();
+      // return slice_type
+      return this.readUEG();
+    }
+  }]);
+
+  return ExpGolomb;
+}();
+
+exports.default = ExpGolomb;
+
+},{"../utils/logger":17}],6:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _errors = require('../errors');
+
+var _events = require('../events');
+
+var _events2 = _interopRequireDefault(_events);
+
+var _expGolomb = require('./exp-golomb');
+
+var _expGolomb2 = _interopRequireDefault(_expGolomb);
+
+var _eventHandler = require('../event-handler');
+
+var _eventHandler2 = _interopRequireDefault(_eventHandler);
+
+var _mp4Remuxer = require('../remux/mp4-remuxer');
+
+var _mp4Remuxer2 = _interopRequireDefault(_mp4Remuxer);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
+
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               */
+
+
+var h264Demuxer = function (_EventHandler) {
+  _inherits(h264Demuxer, _EventHandler);
+
+  function h264Demuxer(wfs) {
+    var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
+
+    _classCallCheck(this, h264Demuxer);
+
+    var _this = _possibleConstructorReturn(this, (h264Demuxer.__proto__ || Object.getPrototypeOf(h264Demuxer)).call(this, wfs, _events2.default.H264_DATA_PARSING));
+
+    _this.config = _this.wfs.config || config;
+    _this.wfs = wfs;
+    _this.id = 'main';
+    var typeSupported = {
+      mp4: MediaSource.isTypeSupported('video/mp4') //,
+      // mp2t : wfs.config.enableMP2TPassThrough && MediaSource.isTypeSupported('video/mp2t')
+    };
+
+    _this.remuxer = new _mp4Remuxer2.default(_this.wfs, _this.id, _this.config);
+    _this.contiguous = true;
+    _this.timeOffset = 1;
+    _this.sn = 0;
+    _this.TIMESCALE = 90000;
+    _this.timestamp = 0;
+    _this.scaleFactor = _this.TIMESCALE / 1000;
+    _this.H264_TIMEBASE = 3000;
+	_this.gloUnits = null;
+	_this.lastUnitType;
+	_this.lastState = 0;
+	_this.trackWidth = 0;
+	_this.trackHeight = 0;
+	_this.firstIFrame = true;
+  _this.gloFirstFrameArr = [];
+    _this._avcTrack = { container: 'video/mp4', type: 'video', id: 1, sequenceNumber: 0,
+      //this._avcTrack = {container : 'video/mp4', type: 'video', id :1, sequenceNumber: 0,
+      samples: [], len: 0, nbNalu: 0, dropped: 0, count: 0 };
+    _this.browserType = 0;
+    if (navigator.userAgent.toLowerCase().indexOf('firefox') !== -1) {
+      _this.browserType = 1;
+    }
+    return _this;
+  }
+
+  _createClass(h264Demuxer, [{
+    key: 'destroy',
+    value: function destroy() {
+      _eventHandler2.default.prototype.destroy.call(this);
+    }
+  }, {
+    key: 'getTimestampM',
+    value: function getTimestampM() {
+      this.timestamp += this.H264_TIMEBASE;
+      return this.timestamp;
+    }
+  }, {
+    key: 'onH264DataParsing',
+    value: function onH264DataParsing(event) {
+      this._parseAVCTrack(event.data);
+      if (this.browserType === 1) {
+        // Firefox
+        this.remuxer.pushVideo(0, this.sn, this._avcTrack, this.timeOffset, this.contiguous);
+        this.sn += 1;
+      } else {
+        this.remuxer.pushVideo(0, this.sn, this._avcTrack, this.timeOffset, this.contiguous);
+        this.sn += 1;
+      }
+    }
+  }, {
+    key: '_parseAVCTrack',
+    value: function _parseAVCTrack(array) {
+      var _this2 = this;
+      var track = this._avcTrack,
+          samples = track.samples,
+          units = this._parseAVCNALu(array),
+          units2 = [],
+          debug = false,
+          key = false,
+          length = 0,
+          expGolombDecoder,
+          avcSample,
+          push,
+          i;
+      var debugString = '';
+      var pushAccesUnit = function () {
+        if (units2.length) {
+          if (!this.config.forceKeyFrameOnDiscontinuity || key === true || track.sps && (samples.length || this.contiguous)) {
+            var tss = this.getTimestampM();
+            avcSample = { units: { units: units2, length: length }, pts: tss, dts: tss, key: key };
+            samples.push(avcSample);
+            track.len += length;
+            track.nbNalu += units2.length;
+          } else {
+            track.dropped++;
+          }
+          units2 = [];
+          length = 0;
+        }
+      }.bind(this);
+      units.forEach(function (unit) {
+        switch (unit.type) {
+          //NDR
+          case 1:
+            push = true;
+            if (debug) {
+              debugString += 'NDR ';
+            }
+            break;
+          //IDR
+          case 5:
+            push = true;
+            if (debug) {
+              debugString += 'IDR ';
+            }
+            key = true;
+            break;
+          //SEI
+          case 6:
+            unit.data = _this2.discardEPB(unit.data);
+            expGolombDecoder = new _expGolomb2.default(unit.data);
+            // skip frameType
+            expGolombDecoder.readUByte();
+            break;
+          //SPS
+          case 7:
+            push = false;
+            if (debug) {
+              debugString += 'SPS ';
+            }
+            // if (!track.sps) {
+              expGolombDecoder = new _expGolomb2.default(unit.data);
+              var config = expGolombDecoder.readSPS();
+              track.width = config.width;
+              track.height = config.height;
+              track.sps = [unit.data];
+              track.duration = 0;
+              var codecarray = unit.data.subarray(1, 4);
+              var codecstring = 'avc1.';
+              for (i = 0; i < 3; i++) {
+                var h = codecarray[i].toString(16);
+                if (h.length < 2) {
+                  h = '0' + h;
+                }
+                codecstring += h;
+              }
+              track.codec = codecstring;
+			  if(_this2.trackWidth != track.width || _this2.trackHeight != track.height){
+				  _this2.trackWidth = track.width;
+				  _this2.trackHeight = track.height;
+				  _this2.wfs.trigger(_events2.default.BUFFER_RESET, { mimeType: track.codec });
+				  push = true;
+			  }
+            // }
+            break;
+          //PPS
+          case 8:
+            push = false;
+            if (debug) {
+              debugString += 'PPS ';
+            }
+            if (!track.pps) {
+              track.pps = [unit.data];
+              push = true;
+            }
+            break;
+          case 9:
+            push = false;
+            if (debug) {
+              debugString += 'AUD ';
+            }
+            pushAccesUnit();
+            break;
+          default:
+            push = false;
+            debugString += 'unknown NAL ' + unit.type + ' ';
+            break;
+        }
+
+        if (push) {
+          units2.push(unit);
+          length += unit.data.byteLength;
+        }
+      });
+
+      if (debug || debugString.length) {
+        logger.log(debugString);
+      }
+
+      pushAccesUnit();
+    }
+  }, {
+    key: '_parseAVCNALu',
+    value: function _parseAVCNALu(array) {
+      var i = 0,
+          len = array.byteLength,
+          value,
+          overflow,
+          state = 0; //state = this.avcNaluState;
+      var units = [],
+          unit,
+          unitType,
+          lastUnitStart,
+          lastUnitType;
+      while (i < len) {
+        value = array[i++];
+        // finding 3 or 4-byte start codes (00 00 01 OR 00 00 00 01)
+        switch (state) {
+          case 0:
+            if (value === 0) {
+              state = 1;
+			  this.lastState = 1;
+            }
+            break;
+          case 1:
+            if (value === 0) {
+              state = 2;
+			  this.lastState = 2;
+            } else {
+              state = 0;
+			  this.lastState = 0;
+            }
+            break;
+          case 2:
+          case 3:
+            if (value === 0) {
+              state = 3;
+			        this.lastState = 3;
+            } else if (value === 1 && i < len) {
+              unitType = array[i] & 0x1f;
+              //判断第一次帧数据是否有Idr
+            if(this.firstIFrame && this.lastUnitType !=5 ){
+              //第一次数据包中没有包含完整的IDR,存储此次数据
+                if(lastUnitType){
+                  unit = { data: array.subarray(lastUnitStart, i - state - 1), type: lastUnitType};
+                  this.gloFirstFrameArr.push(unit);
+                }
+                lastUnitStart = i;
+                lastUnitType = unitType;
+                this.lastUnitType = lastUnitType;
+                state = 0;
+                this.lastState = 0;
+                break;
+			       }
+			        this.firstIFrame = false;
+              //判断此次数据是否包含完整的开头和结尾
+              if (lastUnitStart) {
+                  unit = { data: array.subarray(lastUnitStart, i - state - 1), type: lastUnitType };
+                  units.push(unit);
+              } else {
+                //当前数据首次找到开头,判断上次数据是否有遗留
+                if(this.gloUnits){
+                  //判断是否存在在首次数据包中存储的没有IDR的数据
+                  if(this.gloFirstFrameArr.length > 0){
+                    for(var index=0;index < this.gloFirstFrameArr.length; index++){
+                      units.push(this.gloFirstFrameArr[index]);
+                    }
+                    this.gloFirstFrameArr = [];
+                  }
+                  var data = array.subarray(0, i - state - 1);
+                  var unitArray = new Uint8Array(data.length + this.gloUnits.data.length);
+                  unitArray.set(this.gloUnits.data);
+                  unitArray.set(data,this.gloUnits.data.length);
+                  unit = { data: unitArray, type: this.gloUnits.type};
+                  units.push(unit);
+                  this.gloUnits = null;
+                }
+              }
+              lastUnitStart = i;
+              lastUnitType = unitType;
+              this.lastUnitType = lastUnitType;
+              state = 0;
+              this.lastState = 0;
+            } else {
+                this.lastState = 0;
+                state = 0;
+            }
+            break;
+          default:
+            break;
+        }
+      }
+		 var unitData;
+		if (lastUnitStart) {
+			unitData = array.subarray(lastUnitStart, len);
+		}else{
+			unitData = array;
+		}
+		if(this.gloUnits){
+			var unitArray = new Uint8Array(unitData.length + this.gloUnits.data.length);
+			unitArray.set(this.gloUnits.data);
+			unitArray.set(unitData,this.gloUnits.data.length);
+			this.gloUnits ={ data: unitArray, type: this.gloUnits.type, state: this.gloUnits.state };
+		}else if(this.lastUnitType){
+			this.gloUnits ={ data: unitData, type: this.lastUnitType, state: state};
+		}
+      return units;
+    }
+
+    /**
+     * remove Emulation Prevention bytes from a RBSP
+     */
+
+  }, {
+    key: 'discardEPB',
+    value: function discardEPB(data) {
+      var length = data.byteLength,
+          EPBPositions = [],
+          i = 1,
+          newLength,
+          newData;
+      // Find all `Emulation Prevention Bytes`
+      while (i < length - 2) {
+        if (data[i] === 0 && data[i + 1] === 0 && data[i + 2] === 0x03) {
+          EPBPositions.push(i + 2);
+          i += 2;
+        } else {
+          i++;
+        }
+      }
+      // If no Emulation Prevention Bytes were found just return the original
+      // array
+      if (EPBPositions.length === 0) {
+        return data;
+      }
+      // Create a new array to hold the NAL unit data
+      newLength = length - EPBPositions.length;
+      newData = new Uint8Array(newLength);
+      var sourceIndex = 0;
+
+      for (i = 0; i < newLength; sourceIndex++, i++) {
+        if (sourceIndex === EPBPositions[0]) {
+          // Skip this byte
+          sourceIndex++;
+          // Remove this position index
+          EPBPositions.shift();
+        }
+        newData[i] = data[sourceIndex];
+      }
+      return newData;
+    }
+  }]);
+
+  return h264Demuxer;
+}(_eventHandler2.default);
+
+exports.default = h264Demuxer;
+
+},{"../errors":7,"../event-handler":8,"../events":9,"../remux/mp4-remuxer":16,"./exp-golomb":5}],7:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+var ErrorTypes = exports.ErrorTypes = {
+  // Identifier for a network error (loading error / timeout ...)
+  NETWORK_ERROR: 'networkError',
+  // Identifier for a media Error (video/parsing/mediasource error)
+  MEDIA_ERROR: 'mediaError',
+  // Identifier for all other errors
+  OTHER_ERROR: 'otherError'
+};
+
+var ErrorDetails = exports.ErrorDetails = {
+  // Identifier for a manifest load error - data: { url : faulty URL, response : { code: error code, text: error text }}
+  MANIFEST_LOAD_ERROR: 'manifestLoadError',
+  // Identifier for a manifest load timeout - data: { url : faulty URL, response : { code: error code, text: error text }}
+  MANIFEST_LOAD_TIMEOUT: 'manifestLoadTimeOut',
+  // Identifier for a manifest parsing error - data: { url : faulty URL, reason : error reason}
+  MANIFEST_PARSING_ERROR: 'manifestParsingError',
+  // Identifier for a manifest with only incompatible codecs error - data: { url : faulty URL, reason : error reason}
+  MANIFEST_INCOMPATIBLE_CODECS_ERROR: 'manifestIncompatibleCodecsError',
+  // Identifier for a level load error - data: { url : faulty URL, response : { code: error code, text: error text }}
+  LEVEL_LOAD_ERROR: 'levelLoadError',
+  // Identifier for a level load timeout - data: { url : faulty URL, response : { code: error code, text: error text }}
+  LEVEL_LOAD_TIMEOUT: 'levelLoadTimeOut',
+  // Identifier for a level switch error - data: { level : faulty level Id, event : error description}
+  LEVEL_SWITCH_ERROR: 'levelSwitchError',
+  // Identifier for an audio track load error - data: { url : faulty URL, response : { code: error code, text: error text }}
+  AUDIO_TRACK_LOAD_ERROR: 'audioTrackLoadError',
+  // Identifier for an audio track load timeout - data: { url : faulty URL, response : { code: error code, text: error text }}
+  AUDIO_TRACK_LOAD_TIMEOUT: 'audioTrackLoadTimeOut',
+  // Identifier for fragment load error - data: { frag : fragment object, response : { code: error code, text: error text }}
+  FRAG_LOAD_ERROR: 'fragLoadError',
+  // Identifier for fragment loop loading error - data: { frag : fragment object}
+  FRAG_LOOP_LOADING_ERROR: 'fragLoopLoadingError',
+  // Identifier for fragment load timeout error - data: { frag : fragment object}
+  FRAG_LOAD_TIMEOUT: 'fragLoadTimeOut',
+  // Identifier for a fragment decryption error event - data: parsing error description
+  FRAG_DECRYPT_ERROR: 'fragDecryptError',
+  // Identifier for a fragment parsing error event - data: parsing error description
+  FRAG_PARSING_ERROR: 'fragParsingError',
+  // Identifier for decrypt key load error - data: { frag : fragment object, response : { code: error code, text: error text }}
+  KEY_LOAD_ERROR: 'keyLoadError',
+  // Identifier for decrypt key load timeout error - data: { frag : fragment object}
+  KEY_LOAD_TIMEOUT: 'keyLoadTimeOut',
+  // Triggered when an exception occurs while adding a sourceBuffer to MediaSource - data : {  err : exception , mimeType : mimeType }
+  BUFFER_ADD_CODEC_ERROR: 'bufferAddCodecError',
+  // Identifier for a buffer append error - data: append error description
+  BUFFER_APPEND_ERROR: 'bufferAppendError',
+  // Identifier for a buffer appending error event - data: appending error description
+  BUFFER_APPENDING_ERROR: 'bufferAppendingError',
+  // Identifier for a buffer stalled error event
+  BUFFER_STALLED_ERROR: 'bufferStalledError',
+  // Identifier for a buffer full event
+  BUFFER_FULL_ERROR: 'bufferFullError',
+  // Identifier for a buffer seek over hole event
+  BUFFER_SEEK_OVER_HOLE: 'bufferSeekOverHole',
+  // Identifier for an internal exception happening inside hls.js while handling an event
+  INTERNAL_EXCEPTION: 'internalException'
+};
+
+},{}],8:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+
+var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /*
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     *
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     * All objects in the event handling chain should inherit from this class
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     *
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     */
+
+
+var _events = require('./events');
+
+var _events2 = _interopRequireDefault(_events);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var EventHandler = function () {
+  function EventHandler(wfs) {
+    _classCallCheck(this, EventHandler);
+
+    this.wfs = wfs;
+    this.onEvent = this.onEvent.bind(this);
+
+    for (var _len = arguments.length, events = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
+      events[_key - 1] = arguments[_key];
+    }
+
+    this.handledEvents = events;
+    this.useGenericHandler = true;
+
+    this.registerListeners();
+  }
+
+  _createClass(EventHandler, [{
+    key: 'destroy',
+    value: function destroy() {
+      this.unregisterListeners();
+    }
+  }, {
+    key: 'isEventHandler',
+    value: function isEventHandler() {
+      return _typeof(this.handledEvents) === 'object' && this.handledEvents.length && typeof this.onEvent === 'function';
+    }
+  }, {
+    key: 'registerListeners',
+    value: function registerListeners() {
+      if (this.isEventHandler()) {
+        this.handledEvents.forEach(function (event) {
+          if (event === 'wfsEventGeneric') {
+            //throw new Error('Forbidden event name: ' + event);
+          }
+          this.wfs.on(event, this.onEvent);
+        }.bind(this));
+      }
+    }
+  }, {
+    key: 'unregisterListeners',
+    value: function unregisterListeners() {
+      if (this.isEventHandler()) {
+        this.handledEvents.forEach(function (event) {
+          this.wfs.off(event, this.onEvent);
+        }.bind(this));
+      }
+    }
+
+    /**
+     * arguments: event (string), data (any)
+     */
+
+  }, {
+    key: 'onEvent',
+    value: function onEvent(event, data) {
+      this.onEventGeneric(event, data);
+    }
+  }, {
+    key: 'onEventGeneric',
+    value: function onEventGeneric(event, data) {
+      var eventToFunction = function eventToFunction(event, data) {
+        var funcName = 'on' + event.replace('wfs', '');
+        if (typeof this[funcName] !== 'function') {
+          //throw new Error(`Event ${event} has no generic handler in this ${this.constructor.name} class (tried ${funcName})`);
+        }
+        return this[funcName].bind(this, data);
+      };
+      try {
+        eventToFunction.call(this, event, data).call();
+      } catch (err) {
+        console.log('internal error happened while processing ' + event + ':' + err.message);
+        //   this.hls.trigger(Event.ERROR, {type: ErrorTypes.OTHER_ERROR, details: ErrorDetails.INTERNAL_EXCEPTION, fatal: false, event : event, err : err});
+      }
+    }
+  }]);
+
+  return EventHandler;
+}();
+
+exports.default = EventHandler;
+
+},{"./events":9}],9:[function(require,module,exports){
+'use strict';
+
+module.exports = {
+
+  MEDIA_ATTACHING: 'wfsMediaAttaching',
+
+  MEDIA_ATTACHED: 'wfsMediaAttached',
+
+  FRAG_LOADING: 'wfsFragLoading',
+
+  BUFFER_CREATED: 'wfsBufferCreated',
+
+  BUFFER_APPENDING: 'wfsBufferAppending',
+
+  BUFFER_RESET: 'wfsBufferReset',
+
+  FRAG_PARSING_DATA: 'wfsFragParsingData',
+
+  FRAG_PARSING_INIT_SEGMENT: 'wfsFragParsingInitSegment',
+  //------------------------------------------
+  H264_DATA_PARSING: 'wfsH264DataParsing',
+  //------------------------------------------
+  WEBSOCKET_ATTACHED: 'wfsWebsocketAttached',
+
+  WEBSOCKET_ATTACHING: 'wfsWebsocketAttaching',
+
+  WEBSOCKET_DATA_UPLOADING: 'wfsWebsocketDataUploading',
+
+  WEBSOCKET_MESSAGE_SENDING: 'wfsWebsocketMessageSending',
+  //------------------------------------------
+  FILE_HEAD_LOADING: 'wfsFileHeadLoading',
+
+  FILE_HEAD_LOADED: 'wfsFileHeadLoaded',
+
+  FILE_DATA_LOADING: 'wfsFileDataLoading',
+
+  FILE_DATA_LOADED: 'wfsFileDataLoaded',
+
+  FILE_PARSING_DATA: 'wfsFileParsingData'
+  //------------------------------------------
+
+};
+
+},{}],10:[function(require,module,exports){
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+/**
+ *  AAC helper
+ */
+
+var AAC = function () {
+  function AAC() {
+    _classCallCheck(this, AAC);
+  }
+
+  _createClass(AAC, null, [{
+    key: "getSilentFrame",
+    value: function getSilentFrame(channelCount) {
+      if (channelCount === 1) {
+        return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x23, 0x80]);
+      } else if (channelCount === 2) {
+        return new Uint8Array([0x21, 0x00, 0x49, 0x90, 0x02, 0x19, 0x00, 0x23, 0x80]);
+      } else if (channelCount === 3) {
+        return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x8e]);
+      } else if (channelCount === 4) {
+        return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x80, 0x2c, 0x80, 0x08, 0x02, 0x38]);
+      } else if (channelCount === 5) {
+        return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x82, 0x30, 0x04, 0x99, 0x00, 0x21, 0x90, 0x02, 0x38]);
+      } else if (channelCount === 6) {
+        return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x82, 0x30, 0x04, 0x99, 0x00, 0x21, 0x90, 0x02, 0x00, 0xb2, 0x00, 0x20, 0x08, 0xe0]);
+      }
+      return null;
+    }
+  }]);
+
+  return AAC;
+}();
+
+exports.default = AAC;
+
+},{}],11:[function(require,module,exports){
+'use strict';
+
+// This is mostly for support of the es6 module export
+// syntax with the babel compiler, it looks like it doesnt support
+// function exports like we are used to in node/commonjs
+module.exports = require('./wfs.js').default;
+
+},{"./wfs.js":20}],12:[function(require,module,exports){
+(function (process,global){
+'use strict';
+
+var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
+
+/**
+ * [js-crc]{@link https://github.com/emn178/js-crc}
+ *
+ * @namespace crc
+ * @version 0.2.0
+ * @author Chen, Yi-Cyuan [emn178@gmail.com]
+ * @copyright Chen, Yi-Cyuan 2015-2017
+ * @license MIT
+ */
+/*jslint bitwise: true */
+(function () {
+  'use strict';
+
+  var root = (typeof window === 'undefined' ? 'undefined' : _typeof(window)) === 'object' ? window : {};
+  var NODE_JS = !root.JS_CRC_NO_NODE_JS && (typeof process === 'undefined' ? 'undefined' : _typeof(process)) === 'object' && process.versions && process.versions.node;
+  if (NODE_JS) {
+    root = global;
+  }
+  var COMMON_JS = !root.JS_CRC_NO_COMMON_JS && (typeof module === 'undefined' ? 'undefined' : _typeof(module)) === 'object' && module.exports;
+  var AMD = typeof define === 'function' && define.amd;
+  var ARRAY_BUFFER = !root.JS_CRC_NO_ARRAY_BUFFER && typeof ArrayBuffer !== 'undefined';
+  var HEX_CHARS = '0123456789abcdef'.split('');
+
+  var Modules = [{
+    name: 'crc32',
+    polynom: 0xEDB88320,
+    initValue: -1,
+    bytes: 4
+  }, {
+    name: 'crc16',
+    polynom: 0xA001,
+    initValue: 0,
+    bytes: 2
+  }];
+
+  var i, j, k, b;
+  for (i = 0; i < Modules.length; ++i) {
+    var m = Modules[i];
+    m.method = function (m) {
+      return function (message) {
+        return crc(message, m);
+      };
+    }(m);
+    m.table = [];
+    for (j = 0; j < 256; ++j) {
+      b = j;
+      for (k = 0; k < 8; ++k) {
+        b = b & 1 ? m.polynom ^ b >>> 1 : b >>> 1;
+      }
+      m.table[j] = b >>> 0;
+    }
+  }
+
+  var crc = function crc(message, module) {
+    var notString = typeof message !== 'string';
+    if (notString && ARRAY_BUFFER && message instanceof ArrayBuffer) {
+      message = new Uint8Array(message);
+    }
+
+    var crc = module.initValue,
+        code,
+        i,
+        length = message.length,
+        table = module.table;
+    if (notString) {
+      for (i = 0; i < length; ++i) {
+        crc = table[(crc ^ message[i]) & 0xFF] ^ crc >>> 8;
+      }
+    } else {
+      for (i = 0; i < length; ++i) {
+        code = message.charCodeAt(i);
+        if (code < 0x80) {
+          crc = table[(crc ^ code) & 0xFF] ^ crc >>> 8;
+        } else if (code < 0x800) {
+          crc = table[(crc ^ (0xc0 | code >> 6)) & 0xFF] ^ crc >>> 8;
+          crc = table[(crc ^ (0x80 | code & 0x3f)) & 0xFF] ^ crc >>> 8;
+        } else if (code < 0xd800 || code >= 0xe000) {
+          crc = table[(crc ^ (0xe0 | code >> 12)) & 0xFF] ^ crc >>> 8;
+          crc = table[(crc ^ (0x80 | code >> 6 & 0x3f)) & 0xFF] ^ crc >>> 8;
+          crc = table[(crc ^ (0x80 | code & 0x3f)) & 0xFF] ^ crc >>> 8;
+        } else {
+          code = 0x10000 + ((code & 0x3ff) << 10 | message.charCodeAt(++i) & 0x3ff);
+          crc = table[(crc ^ (0xf0 | code >> 18)) & 0xFF] ^ crc >>> 8;
+          crc = table[(crc ^ (0x80 | code >> 12 & 0x3f)) & 0xFF] ^ crc >>> 8;
+          crc = table[(crc ^ (0x80 | code >> 6 & 0x3f)) & 0xFF] ^ crc >>> 8;
+          crc = table[(crc ^ (0x80 | code & 0x3f)) & 0xFF] ^ crc >>> 8;
+        }
+      }
+    }
+    crc ^= module.initValue;
+
+    var hex = '';
+    if (module.bytes > 2) {
+      hex += HEX_CHARS[crc >> 28 & 0x0F] + HEX_CHARS[crc >> 24 & 0x0F] + HEX_CHARS[crc >> 20 & 0x0F] + HEX_CHARS[crc >> 16 & 0x0F];
+    }
+    hex += HEX_CHARS[crc >> 12 & 0x0F] + HEX_CHARS[crc >> 8 & 0x0F] + HEX_CHARS[crc >> 4 & 0x0F] + HEX_CHARS[crc & 0x0F];
+    return hex;
+  };
+
+  var exports = {};
+  for (i = 0; i < Modules.length; ++i) {
+    var m = Modules[i];
+    exports[m.name] = m.method;
+  }
+  if (COMMON_JS) {
+    module.exports = exports;
+  } else {
+    for (i = 0; i < Modules.length; ++i) {
+      var m = Modules[i];
+      root[m.name] = m.method;
+    }
+    if (AMD) {
+      define(function () {
+        return exports;
+      });
+    }
+  }
+})();
+
+}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+
+},{"_process":2}],13:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _events = require('../events');
+
+var _events2 = _interopRequireDefault(_events);
+
+var _eventHandler = require('../event-handler');
+
+var _eventHandler2 = _interopRequireDefault(_eventHandler);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /*
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * File Loader
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               */
+
+
+var FileLoader = function (_EventHandler) {
+  _inherits(FileLoader, _EventHandler);
+
+  function FileLoader(wfs) {
+    _classCallCheck(this, FileLoader);
+
+    var _this = _possibleConstructorReturn(this, (FileLoader.__proto__ || Object.getPrototypeOf(FileLoader)).call(this, wfs, _events2.default.FRAG_LOADING, _events2.default.FILE_HEAD_LOADING, _events2.default.FILE_DATA_LOADING));
+
+    _this.loaders = {};
+    return _this;
+  }
+
+  _createClass(FileLoader, [{
+    key: 'destroy',
+    value: function destroy() {
+      for (var loaderName in this.loaders) {
+        var loader = this.loaders[loaderName];
+        if (loader) {
+          loader.destroy();
+        }
+      }
+      this.loaders = {};
+      _eventHandler2.default.prototype.destroy.call(this);
+    }
+  }, {
+    key: 'onFileHeadLoading',
+    value: function onFileHeadLoading(data) {
+      var config = this.wfs.config;
+      var loader = new config.loader(config);
+      var loaderContext = void 0,
+          loaderConfig = void 0,
+          loaderCallbacks = void 0;
+      loaderContext = { url: config.fmp4FileUrl };
+      loaderConfig = { maxRetry: 0, retryDelay: 0 };
+      loaderCallbacks = { onSuccess: this.fileloadheadsuccess.bind(this) };
+      loader.loadHead(loaderContext, loaderConfig, loaderCallbacks);
+    }
+  }, {
+    key: 'fileloadheadsuccess',
+    value: function fileloadheadsuccess(response) {
+      this.wfs.trigger(_events2.default.FILE_HEAD_LOADED, { size: response });
+    }
+  }, {
+    key: 'onFileDataLoading',
+    value: function onFileDataLoading(data) {
+      var config = this.wfs.config;
+      var loader = new config.loader(config);
+      var loaderContext = void 0,
+          loaderConfig = void 0,
+          loaderCallbacks = void 0;
+      loaderContext = { url: config.fmp4FileUrl, responseType: 'arraybuffer', progressData: false };
+      var start = data.fileStart,
+          end = data.fileEnd;
+      if (!isNaN(start) && !isNaN(end)) {
+        loaderContext.rangeStart = start;
+        loaderContext.rangeEnd = end;
+      }
+      loaderConfig = { timeout: config.fragLoadingTimeOut, maxRetry: 0, retryDelay: 0, maxRetryDelay: config.fragLoadingMaxRetryTimeout };
+      loaderCallbacks = { onSuccess: this.fileloaddatasuccess.bind(this) };
+      loader.load(loaderContext, loaderConfig, loaderCallbacks);
+    }
+  }, {
+    key: 'fileloaddatasuccess',
+    value: function fileloaddatasuccess(response, stats, context) {
+      this.wfs.trigger(_events2.default.FILE_DATA_LOADED, { payload: response.data, stats: stats });
+    }
+  }, {
+    key: 'loaderror',
+    value: function loaderror(response, context) {
+      var loader = context.loader;
+      if (loader) {
+        loader.abort();
+      }
+      this.loaders[context.type] = undefined;
+    }
+  }, {
+    key: 'loadtimeout',
+    value: function loadtimeout(stats, context) {
+      var loader = context.loader;
+      if (loader) {
+        loader.abort();
+      }
+      this.loaders[context.type] = undefined;
+    }
+  }, {
+    key: 'loadprogress',
+    value: function loadprogress(stats, context, data) {
+      var frag = context.frag;
+      frag.loaded = stats.loaded;
+    }
+  }]);
+
+  return FileLoader;
+}(_eventHandler2.default);
+
+exports.default = FileLoader;
+
+},{"../event-handler":8,"../events":9}],14:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _events = require('../events');
+
+var _events2 = _interopRequireDefault(_events);
+
+var _eventHandler = require('../event-handler');
+
+var _eventHandler2 = _interopRequireDefault(_eventHandler);
+
+var _h264Demuxer = require('../demux/h264-demuxer');
+
+var _h264Demuxer2 = _interopRequireDefault(_h264Demuxer);
+
+var _crc = require('./crc.js');
+
+var _crc2 = _interopRequireDefault(_crc);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /*
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * Websocket Loader
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               */
+
+var WebsocketLoader = function (_EventHandler) {
+  _inherits(WebsocketLoader, _EventHandler);
+
+  function WebsocketLoader(wfs) {
+    _classCallCheck(this, WebsocketLoader);
+
+    var _this = _possibleConstructorReturn(this, (WebsocketLoader.__proto__ || Object.getPrototypeOf(WebsocketLoader)).call(this, wfs, _events2.default.WEBSOCKET_ATTACHING, _events2.default.WEBSOCKET_DATA_UPLOADING, _events2.default.WEBSOCKET_MESSAGE_SENDING));
+
+    _this.buf = null;
+    _this.h264Demuxer = new _h264Demuxer2.default(wfs);
+    _this.mediaType = undefined;
+    _this.channelName = undefined;
+    _this.onVideoFrame = null;
+    return _this;
+  }
+
+  _createClass(WebsocketLoader, [{
+    key: 'destroy',
+    value: function destroy() {
+      !!this.client && this.client.close();
+      _eventHandler2.default.prototype.destroy.call(this);
+      this.h264Demuxer.destroy();
+    }
+  }, {
+    key: 'onWebsocketAttaching',
+    value: function onWebsocketAttaching(data) {
+      this.mediaType = data.mediaType;
+      this.channelName = data.channelName;
+	    this.deviceId = data.deviceId;
+      this.clientid = data.clientid;
+      this.loginHandle = data.loginHandle;
+      this.sessiontype = data.sessiontype;
+      this.begintime = data.begintime;
+      if (data.websocket instanceof WebSocket) {
+        this.client = data.websocket;
+        this.client.onopen = this.initSocketClient.bind(this);
+        this.client.onclose = function (e) {
+          console.log('Websocket Disconnected!');
+        };
+      }
+    }
+  }, {
+    key: 'initSocketClient',
+    value: function initSocketClient(client) {
+      this.client.binaryType = 'arraybuffer';
+      this.client.onmessage = this.receiveSocketMessage.bind(this);
+      this.wfs.trigger(_events2.default.WEBSOCKET_MESSAGE_SENDING, { commandType: "open", channelName: this.channelName, commandValue: "NA", deviceId: this.deviceId, clientid: this.clientid, loginHandle: this.loginHandle, sessiontype: this.sessiontype, begintime: this.begintime});
+      console.log('Websocket Open!');
+    }
+  }, {
+    key: 'receiveSocketMessage',
+    value: function receiveSocketMessage(event) {
+      // var buffer = new Uint8Array(event.data);
+      // console.log(buffer.length);
+      // var newBuffer;
+      // if (this.buf) {
+        // newBuffer = new Uint8Array(this.buf.byteLength + buffer.byteLength);
+        // newBuffer.set(this.buf);
+        // newBuffer.set(buffer, this.buf.byteLength);
+        // console.log("newBuffer.length:"+newBuffer.length);
+      // } else newBuffer = new Uint8Array(buffer);
+      // //get len
+      // var offset = 0;
+      // var lenView = new DataView(newBuffer.buffer);
+	  // console.log(lenView);
+	   // var len;
+	  // if(lenView.byteLength == 0){
+		  // len = 0;
+	  // }else{
+		  // len = lenView.getUint32(0);
+	  // }
+	  // console.log("len:"+len+",newBuffer:"+(newBuffer.byteLength - 4));
+      // while (len < newBuffer.byteLength - 4) {
+        // console.log("frames, len:" + len);
+        // var copy = newBuffer.subarray(4, len + 4);
+		// console.log(copy);
+        // this.wfs.trigger(_events2.default.H264_DATA_PARSING, { data: copy });
+        // //var copy2 = new Uint8Array(0);
+        // //this.wfs.trigger(Event.H264_DATA_PARSING, {data: copy2});
+        // //this.wfs.trigger(Event.H264_DATA_PARSING, {data: copy2});
+        // newBuffer = newBuffer.subarray(len + 4);
+        // offset += len + 4;
+        // len = lenView.getUint32(offset);
+        // //get len
+      // }
+      // if (len === newBuffer.byteLength - 4) {
+        // var copy = newBuffer.subarray(4, len + 4);
+        // this.wfs.trigger(_events2.default.H264_DATA_PARSING, { data: copy });
+        // //var copy2 = new Uint8Array(0);
+        // //this.wfs.trigger(Event.H264_DATA_PARSING,{data:copy2});
+        // //this.wfs.trigger(Event.H264_DATA_PARSING,{data:copy2});
+        // this.buf = null;
+      // } else this.buf = new Uint8Array(newBuffer);
+
+    // }
+	/****************************************************/
+	if(this.onVideoFrame && typeof(event.data) == "object"){
+		this.onVideoFrame(event.data);
+	}
+	 this.buf = new Uint8Array(event.data);
+      var copy = new Uint8Array(this.buf);
+      if (this.mediaType === 'FMp4') {
+        this.wfs.trigger(_events2.default.WEBSOCKET_ATTACHED, { payload: copy });
+      }
+      if (this.mediaType === 'H264Raw') {
+        this.wfs.trigger(_events2.default.H264_DATA_PARSING, { data: copy  });
+      }
+    }
+  }, {
+    key: 'onWebsocketDataUploading',
+    value: function onWebsocketDataUploading(event) {
+      this.client.send(event.data);
+    }
+  }, {
+    key: 'onWebsocketMessageSending',
+    value: function onWebsocketMessageSending(event) {
+      // this.client.send(JSON.stringify({ t: event.commandType, c: event.channelName, v: event.commandValue }));
+      var sendMsg = event.sessiontype == "video" ? "" : event.begintime.toString();
+       this.client.send( JSON.stringify({cmd: "register", clientid: event.clientid,deviceId: parseInt(event.deviceId),loginHandle: parseInt(event.loginHandle), msg: sendMsg,sessiontype:  event.sessiontype}) );
+    }
+  }]);
+
+  return WebsocketLoader;
+}(_eventHandler2.default);
+
+exports.default = WebsocketLoader;
+
+},{"../demux/h264-demuxer":6,"../event-handler":8,"../events":9,"./crc.js":12}],15:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+/**
+ * Generate MP4 Box
+*/
+
+//import Hex from '../utils/hex';
+var MP4 = function () {
+  function MP4() {
+    _classCallCheck(this, MP4);
+  }
+
+  _createClass(MP4, null, [{
+    key: 'init',
+    value: function init() {
+      MP4.types = {
+        avc1: [], // codingname
+        avcC: [],
+        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: []
+      };
+
+      var i;
+      for (i in MP4.types) {
+        if (MP4.types.hasOwnProperty(i)) {
+          MP4.types[i] = [i.charCodeAt(0), i.charCodeAt(1), i.charCodeAt(2), i.charCodeAt(3)];
+        }
+      }
+
+      var videoHdlr = new Uint8Array([0x00, // version 0
+      0x00, 0x00, 0x00, // flags
+      0x00, 0x00, 0x00, 0x00, // pre_defined
+      0x76, 0x69, 0x64, 0x65, // handler_type: 'vide'
+      0x00, 0x00, 0x00, 0x00, // reserved
+      0x00, 0x00, 0x00, 0x00, // reserved
+      0x00, 0x00, 0x00, 0x00, // reserved
+      0x56, 0x69, 0x64, 0x65, 0x6f, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x00 // name: 'VideoHandler'
+      ]);
+
+      var audioHdlr = new Uint8Array([0x00, // version 0
+      0x00, 0x00, 0x00, // flags
+      0x00, 0x00, 0x00, 0x00, // pre_defined
+      0x73, 0x6f, 0x75, 0x6e, // handler_type: 'soun'
+      0x00, 0x00, 0x00, 0x00, // reserved
+      0x00, 0x00, 0x00, 0x00, // reserved
+      0x00, 0x00, 0x00, 0x00, // reserved
+      0x53, 0x6f, 0x75, 0x6e, 0x64, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x00 // name: 'SoundHandler'
+      ]);
+
+      MP4.HDLR_TYPES = {
+        'video': videoHdlr,
+        'audio': audioHdlr
+      };
+
+      var dref = new Uint8Array([0x00, // version 0
+      0x00, 0x00, 0x00, // flags
+      0x00, 0x00, 0x00, 0x01, // entry_count
+      0x00, 0x00, 0x00, 0x0c, // entry_size
+      0x75, 0x72, 0x6c, 0x20, // 'url' type
+      0x00, // version 0
+      0x00, 0x00, 0x01 // entry_flags
+      ]);
+
+      var stco = new Uint8Array([0x00, // version
+      0x00, 0x00, 0x00, // flags
+      0x00, 0x00, 0x00, 0x00 // entry_count
+      ]);
+
+      MP4.STTS = MP4.STSC = MP4.STCO = stco;
+
+      MP4.STSZ = new Uint8Array([0x00, // version
+      0x00, 0x00, 0x00, // flags
+      0x00, 0x00, 0x00, 0x00, // sample_size
+      0x00, 0x00, 0x00, 0x00]);
+      MP4.VMHD = new Uint8Array([0x00, // version
+      0x00, 0x00, 0x01, // flags
+      0x00, 0x00, // graphicsmode
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // opcolor
+      ]);
+      MP4.SMHD = new Uint8Array([0x00, // version
+      0x00, 0x00, 0x00, // flags
+      0x00, 0x00, // balance
+      0x00, 0x00 // reserved
+      ]);
+
+      MP4.STSD = new Uint8Array([0x00, // version 0
+      0x00, 0x00, 0x00, // flags
+      0x00, 0x00, 0x00, 0x01]); // entry_count
+
+      var majorBrand = new Uint8Array([105, 115, 111, 109]); // isom
+      var avc1Brand = new Uint8Array([97, 118, 99, 49]); // avc1
+      var minorVersion = new Uint8Array([0, 0, 0, 1]);
+
+      MP4.FTYP = MP4.box(MP4.types.ftyp, majorBrand, minorVersion, majorBrand, avc1Brand);
+      MP4.DINF = MP4.box(MP4.types.dinf, MP4.box(MP4.types.dref, dref));
+    }
+  }, {
+    key: 'box',
+    value: function box(type) {
+      var payload = Array.prototype.slice.call(arguments, 1),
+          size = 8,
+          i = payload.length,
+          len = i,
+          result;
+      // calculate the total size we need to allocate
+      while (i--) {
+        size += payload[i].byteLength;
+      }
+      result = new Uint8Array(size);
+      result[0] = size >> 24 & 0xff;
+      result[1] = size >> 16 & 0xff;
+      result[2] = size >> 8 & 0xff;
+      result[3] = size & 0xff;
+      result.set(type, 4);
+      // copy the payload into the result
+      for (i = 0, size = 8; i < len; i++) {
+        // copy payload[i] array @ offset size
+        result.set(payload[i], size);
+        size += payload[i].byteLength;
+      }
+      return result;
+    }
+  }, {
+    key: 'hdlr',
+    value: function hdlr(type) {
+      return MP4.box(MP4.types.hdlr, MP4.HDLR_TYPES[type]);
+    }
+  }, {
+    key: 'mdat',
+    value: function mdat(data) {
+      //  console.log( "mdat==> ",data.length );
+      return MP4.box(MP4.types.mdat, data);
+    }
+  }, {
+    key: 'mdhd',
+    value: function mdhd(timescale, duration) {
+      duration *= timescale;
+      return MP4.box(MP4.types.mdhd, new Uint8Array([0x00, // version 0
+      0x00, 0x00, 0x00, // flags
+      0x00, 0x00, 0x00, 0x02, // creation_time
+      0x00, 0x00, 0x00, 0x03, // modification_time
+      timescale >> 24 & 0xFF, timescale >> 16 & 0xFF, timescale >> 8 & 0xFF, timescale & 0xFF, // timescale
+      duration >> 24, duration >> 16 & 0xFF, duration >> 8 & 0xFF, duration & 0xFF, // duration
+      0x55, 0xc4, // 'und' language (undetermined)
+      0x00, 0x00]));
+    }
+  }, {
+    key: 'mdia',
+    value: function mdia(track) {
+      return MP4.box(MP4.types.mdia, MP4.mdhd(track.timescale, track.duration), MP4.hdlr(track.type), MP4.minf(track));
+    }
+  }, {
+    key: 'mfhd',
+    value: function mfhd(sequenceNumber) {
+      return MP4.box(MP4.types.mfhd, new Uint8Array([0x00, 0x00, 0x00, 0x00, // flags
+      sequenceNumber >> 24, sequenceNumber >> 16 & 0xFF, sequenceNumber >> 8 & 0xFF, sequenceNumber & 0xFF]) // sequence_number
+      );
+    }
+  }, {
+    key: 'minf',
+    value: function minf(track) {
+      if (track.type === 'audio') {
+        return MP4.box(MP4.types.minf, MP4.box(MP4.types.smhd, MP4.SMHD), MP4.DINF, MP4.stbl(track));
+      } else {
+        return MP4.box(MP4.types.minf, MP4.box(MP4.types.vmhd, MP4.VMHD), MP4.DINF, MP4.stbl(track));
+      }
+    }
+  }, {
+    key: 'moof',
+    value: function moof(sn, baseMediaDecodeTime, track) {
+      return MP4.box(MP4.types.moof, MP4.mfhd(sn), MP4.traf(track, baseMediaDecodeTime));
+    }
+    /**
+     * @param tracks... (optional) {array} the tracks associated with this movie
+     */
+
+  }, {
+    key: 'moov',
+    value: function moov(tracks) {
+      var i = tracks.length,
+          boxes = [];
+
+      while (i--) {
+        boxes[i] = MP4.trak(tracks[i]);
+      }
+
+      return MP4.box.apply(null, [MP4.types.moov, MP4.mvhd(tracks[0].timescale, tracks[0].duration)].concat(boxes).concat(MP4.mvex(tracks)));
+    }
+  }, {
+    key: 'mvex',
+    value: function mvex(tracks) {
+      var i = tracks.length,
+          boxes = [];
+
+      while (i--) {
+        boxes[i] = MP4.trex(tracks[i]);
+      }
+      return MP4.box.apply(null, [MP4.types.mvex].concat(boxes));
+    }
+  }, {
+    key: 'mvhd',
+    value: function mvhd(timescale, duration) {
+      //duration*=timescale;
+      duration = 0;
+      var bytes = new Uint8Array([0x00, // version 0
+      0x00, 0x00, 0x00, // flags
+      0x00, 0x00, 0x00, 0x01, // creation_time
+      0x00, 0x00, 0x00, 0x02, // modification_time
+      timescale >> 24 & 0xFF, timescale >> 16 & 0xFF, timescale >> 8 & 0xFF, timescale & 0xFF, // timescale
+      duration >> 24 & 0xFF, duration >> 16 & 0xFF, duration >> 8 & 0xFF, duration & 0xFF, // duration
+      0x00, 0x01, 0x00, 0x00, // 1.0 rate
+      0x01, 0x00, // 1.0 volume
+      0x00, 0x00, // reserved
+      0x00, 0x00, 0x00, 0x00, // reserved
+      0x00, 0x00, 0x00, 0x00, // reserved
+      0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, // transformation: unity matrix
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // pre_defined
+      0xff, 0xff, 0xff, 0xff // next_track_ID
+      ]);
+      return MP4.box(MP4.types.mvhd, bytes);
+    }
+  }, {
+    key: 'sdtp',
+    value: function sdtp(track) {
+      var samples = track.samples || [],
+          bytes = new Uint8Array(4 + samples.length),
+          flags,
+          i;
+      // leave the full box header (4 bytes) all zero
+      // write the sample table
+      for (i = 0; i < samples.length; i++) {
+        flags = samples[i].flags;
+        bytes[i + 4] = flags.dependsOn << 4 | flags.isDependedOn << 2 | flags.hasRedundancy;
+      }
+
+      return MP4.box(MP4.types.sdtp, bytes);
+    }
+  }, {
+    key: 'stbl',
+    value: function stbl(track) {
+      return MP4.box(MP4.types.stbl, MP4.stsd(track), MP4.box(MP4.types.stts, MP4.STTS), MP4.box(MP4.types.stsc, MP4.STSC), MP4.box(MP4.types.stsz, MP4.STSZ), MP4.box(MP4.types.stco, MP4.STCO));
+    }
+  }, {
+    key: 'avc1',
+    value: function avc1(track) {
+      var sps = [],
+          pps = [],
+          i,
+          data,
+          len;
+      // assemble the SPSs
+
+      for (i = 0; i < track.sps.length; i++) {
+        data = track.sps[i];
+        len = data.byteLength;
+        sps.push(len >>> 8 & 0xFF);
+        sps.push(len & 0xFF);
+        sps = sps.concat(Array.prototype.slice.call(data)); // SPS
+      }
+
+      // assemble the PPSs
+      for (i = 0; i < track.pps.length; i++) {
+        data = track.pps[i];
+        len = data.byteLength;
+        pps.push(len >>> 8 & 0xFF);
+        pps.push(len & 0xFF);
+        pps = pps.concat(Array.prototype.slice.call(data));
+      }
+
+      var avcc = MP4.box(MP4.types.avcC, new Uint8Array([0x01, // version
+      sps[3], // profile
+      sps[4], // profile compat
+      sps[5], // level
+      0xfc | 3, // lengthSizeMinusOne, hard-coded to 4 bytes
+      0xE0 | track.sps.length // 3bit reserved (111) + numOfSequenceParameterSets
+      ].concat(sps).concat([track.pps.length // numOfPictureParameterSets
+      ]).concat(pps))),
+          // "PPS"
+      width = track.width,
+          height = track.height;
+      //console.log('avcc:' + Hex.hexDump(avcc));
+      return MP4.box(MP4.types.avc1, new Uint8Array([0x00, 0x00, 0x00, // reserved
+      0x00, 0x00, 0x00, // reserved
+      0x00, 0x01, // data_reference_index
+      0x00, 0x00, // pre_defined
+      0x00, 0x00, // reserved
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // pre_defined
+      width >> 8 & 0xFF, width & 0xff, // width
+      height >> 8 & 0xFF, height & 0xff, // height
+      0x00, 0x48, 0x00, 0x00, // horizresolution
+      0x00, 0x48, 0x00, 0x00, // vertresolution
+      0x00, 0x00, 0x00, 0x00, // reserved
+      0x00, 0x01, // frame_count
+      0x12, 0x6a, 0x65, 0x66, 0x66, // wfs.js
+      0x2d, 0x79, 0x61, 0x6e, 0x2f, 0x2f, 0x2f, 0x67, 0x77, 0x66, 0x73, 0x2E, 0x6A, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // compressorname
+      0x00, 0x18, // depth = 24
+      0x11, 0x11]), // pre_defined = -1
+      avcc, MP4.box(MP4.types.btrt, new Uint8Array([0x00, 0x1c, 0x9c, 0x80, // bufferSizeDB
+      0x00, 0x2d, 0xc6, 0xc0, // maxBitrate
+      0x00, 0x2d, 0xc6, 0xc0])) // avgBitrate
+      );
+    }
+  }, {
+    key: 'esds',
+    value: function esds(track) {
+      var configlen = track.config.length;
+      return new Uint8Array([0x00, // version 0
+      0x00, 0x00, 0x00, // flags
+
+      0x03, // descriptor_type
+      0x17 + configlen, // length
+      0x00, 0x01, //es_id
+      0x00, // stream_priority
+
+      0x04, // descriptor_type
+      0x0f + configlen, // length
+      0x40, //codec : mpeg4_audio
+      0x15, // stream_type
+      0x00, 0x00, 0x00, // buffer_size
+      0x00, 0x00, 0x00, 0x00, // maxBitrate
+      0x00, 0x00, 0x00, 0x00, // avgBitrate
+
+      0x05 // descriptor_type
+      ].concat([configlen]).concat(track.config).concat([0x06, 0x01, 0x02])); // GASpecificConfig)); // length + audio config descriptor
+    }
+  }, {
+    key: 'mp4a',
+    value: function mp4a(track) {
+      var audiosamplerate = track.audiosamplerate;
+      return MP4.box(MP4.types.mp4a, new Uint8Array([0x00, 0x00, 0x00, // reserved
+      0x00, 0x00, 0x00, // reserved
+      0x00, 0x01, // data_reference_index
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // reserved
+      0x00, track.channelCount, // channelcount
+      0x00, 0x10, // sampleSize:16bits
+      0x00, 0x00, 0x00, 0x00, // reserved2
+      audiosamplerate >> 8 & 0xFF, audiosamplerate & 0xff, //
+      0x00, 0x00]), MP4.box(MP4.types.esds, MP4.esds(track)));
+    }
+  }, {
+    key: 'stsd',
+    value: function stsd(track) {
+      if (track.type === 'audio') {
+        return MP4.box(MP4.types.stsd, MP4.STSD, MP4.mp4a(track));
+      } else {
+        return MP4.box(MP4.types.stsd, MP4.STSD, MP4.avc1(track));
+      }
+    }
+  }, {
+    key: 'tkhd',
+    value: function tkhd(track) {
+      var id = track.id,
+          duration = track.duration * track.timescale,
+          width = track.width,
+          height = track.height;
+
+      //   console.log( "tkhd==> ",track.id, track.duration, track.timescale, width,height );
+
+      return MP4.box(MP4.types.tkhd, new Uint8Array([0x00, // version 0
+      0x00, 0x00, 0x07, // flags
+      0x00, 0x00, 0x00, 0x00, // creation_time
+      0x00, 0x00, 0x00, 0x00, // modification_time
+      id >> 24 & 0xFF, id >> 16 & 0xFF, id >> 8 & 0xFF, id & 0xFF, // track_ID
+      0x00, 0x00, 0x00, 0x00, // reserved
+      duration >> 24, duration >> 16 & 0xFF, duration >> 8 & 0xFF, duration & 0xFF, // duration
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // reserved
+      0x00, 0x00, // layer
+      0x00, 0x00, // alternate_group
+      0x00, 0x00, // non-audio track volume
+      0x00, 0x00, // reserved
+      0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, // transformation: unity matrix
+      width >> 8 & 0xFF, width & 0xFF, 0x00, 0x00, // width
+      height >> 8 & 0xFF, height & 0xFF, 0x00, 0x00 // height
+      ]));
+    }
+  }, {
+    key: 'traf',
+    value: function traf(track, baseMediaDecodeTime) {
+      var sampleDependencyTable = MP4.sdtp(track),
+          id = track.id;
+
+      //  console.log( "traf==> ",id ,baseMediaDecodeTime);
+
+      return MP4.box(MP4.types.traf, MP4.box(MP4.types.tfhd, new Uint8Array([0x00, // version 0
+      0x00, 0x00, 0x00, // flags
+      id >> 24, id >> 16 & 0XFF, id >> 8 & 0XFF, id & 0xFF]) // track_ID
+      ), MP4.box(MP4.types.tfdt, new Uint8Array([0x00, // version 0
+      0x00, 0x00, 0x00, // flags
+      baseMediaDecodeTime >> 24, baseMediaDecodeTime >> 16 & 0XFF, baseMediaDecodeTime >> 8 & 0XFF, baseMediaDecodeTime & 0xFF]) // baseMediaDecodeTime
+      ), MP4.trun(track, sampleDependencyTable.length + 16 + // tfhd
+      16 + // tfdt
+      8 + // traf header
+      16 + // mfhd
+      8 + // moof header
+      8), // mdat header
+      sampleDependencyTable);
+    }
+
+    /**
+     * Generate a track box.
+     * @param track {object} a track definition
+     * @return {Uint8Array} the track box
+     */
+
+  }, {
+    key: 'trak',
+    value: function trak(track) {
+      track.duration = track.duration || 0xffffffff;
+      return MP4.box(MP4.types.trak, MP4.tkhd(track), MP4.mdia(track));
+    }
+  }, {
+    key: 'trex',
+    value: function trex(track) {
+      var id = track.id;
+      return MP4.box(MP4.types.trex, new Uint8Array([0x00, // version 0
+      0x00, 0x00, 0x00, // flags
+      id >> 24, id >> 16 & 0XFF, id >> 8 & 0XFF, id & 0xFF, // track_ID
+      0x00, 0x00, 0x00, 0x01, // default_sample_description_index
+      0x00, 0x00, 0x00, 0x00, // default_sample_duration
+      0x00, 0x00, 0x00, 0x00, // default_sample_size
+      0x00, 0x01, 0x00, 0x01 // default_sample_flags
+      ]));
+    }
+  }, {
+    key: 'trun',
+    value: function trun(track, offset) {
+      var samples = track.samples || [],
+          len = samples.length,
+          arraylen = 12 + 16 * len,
+          array = new Uint8Array(arraylen),
+          i,
+          sample,
+          duration,
+          size,
+          flags,
+          cts;
+
+      //sample = samples[0];
+      //       console.log( "trun==> ",sample.duration, sample.cts ,sample.size,len );
+
+      offset += 8 + arraylen;
+      array.set([0x00, // version 0
+      0x00, 0x0f, 0x01, // flags
+      len >>> 24 & 0xFF, len >>> 16 & 0xFF, len >>> 8 & 0xFF, len & 0xFF, // sample_count
+      offset >>> 24 & 0xFF, offset >>> 16 & 0xFF, offset >>> 8 & 0xFF, offset & 0xFF // data_offset
+      ], 0);
+      for (i = 0; i < len; i++) {
+        sample = samples[i];
+        duration = sample.duration;
+        size = sample.size;
+        flags = sample.flags;
+        cts = sample.cts;
+        array.set([duration >>> 24 & 0xFF, duration >>> 16 & 0xFF, duration >>> 8 & 0xFF, duration & 0xFF, // sample_duration
+        size >>> 24 & 0xFF, size >>> 16 & 0xFF, size >>> 8 & 0xFF, size & 0xFF, // sample_size
+        flags.isLeading << 2 | flags.dependsOn, flags.isDependedOn << 6 | flags.hasRedundancy << 4 | flags.paddingValue << 1 | flags.isNonSync, flags.degradPrio & 0xF0 << 8, flags.degradPrio & 0x0F, // sample_flags
+        cts >>> 24 & 0xFF, cts >>> 16 & 0xFF, cts >>> 8 & 0xFF, cts & 0xFF // sample_composition_time_offset
+        ], 12 + 16 * i);
+      }
+      return MP4.box(MP4.types.trun, array);
+    }
+  }, {
+    key: 'initSegment',
+    value: function initSegment(tracks) {
+      if (!MP4.types) {
+        MP4.init();
+      }
+      var movie = MP4.moov(tracks),
+          result;
+      result = new Uint8Array(MP4.FTYP.byteLength + movie.byteLength);
+      result.set(MP4.FTYP);
+      result.set(movie, MP4.FTYP.byteLength);
+
+      return result;
+    }
+  }]);
+
+  return MP4;
+}();
+
+exports.default = MP4;
+
+},{}],16:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /**
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * fMP4 remuxer
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     */
+
+
+var _aac = require('../helper/aac');
+
+var _aac2 = _interopRequireDefault(_aac);
+
+var _events = require('../events');
+
+var _events2 = _interopRequireDefault(_events);
+
+var _logger = require('../utils/logger');
+
+var _mp4Generator = require('../remux/mp4-generator');
+
+var _mp4Generator2 = _interopRequireDefault(_mp4Generator);
+
+var _errors = require('../errors');
+
+require('../utils/polyfill');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var MP4Remuxer = function () {
+  function MP4Remuxer(observer, id, config) {
+    _classCallCheck(this, MP4Remuxer);
+
+    this.observer = observer;
+    this.id = id;
+    this.config = config;
+    this.ISGenerated = false;
+    this.PES2MP4SCALEFACTOR = 4;
+    this.PES_TIMESCALE = 90000;
+    this.MP4_TIMESCALE = this.PES_TIMESCALE / this.PES2MP4SCALEFACTOR;
+    this.nextAvcDts = 90300;
+    this.H264_TIMEBASE = 3000;
+	this.width = 0;
+	this.height = 0;
+  }
+
+  _createClass(MP4Remuxer, [{
+    key: 'destroy',
+    value: function destroy() {}
+  }, {
+    key: 'insertDiscontinuity',
+    value: function insertDiscontinuity() {
+      this._initPTS = this._initDTS = undefined;
+    }
+  }, {
+    key: 'switchLevel',
+    value: function switchLevel() {
+      this.ISGenerated = false;
+    }
+  }, {
+    key: 'pushVideo',
+    value: function pushVideo(level, sn, videoTrack, timeOffset, contiguous) {
+      this.level = level;
+      this.sn = sn;
+      var videoData = void 0;
+      // generate Init Segment if needed
+      if (!this.ISGenerated) {
+		  this.width = videoTrack.width;
+		  this.height = videoTrack.height;
+        this.generateVideoIS(videoTrack, timeOffset);
+      }
+      if (this.ISGenerated) {
+        // if (videoTrack.samples.length) {
+        this.remuxVideo_2(videoTrack, timeOffset, contiguous);
+        // }
+      }
+    }
+  }, {
+    key: 'remuxVideo_2',
+    value: function remuxVideo_2(track, timeOffset, contiguous, audioTrackLength) {
+      var offset = 8,
+          pesTimeScale = this.PES_TIMESCALE,
+          pes2mp4ScaleFactor = this.PES2MP4SCALEFACTOR,
+          mp4SampleDuration,
+          mdat,
+          moof,
+          firstPTS,
+          firstDTS,
+          nextDTS,
+          inputSamples = track.samples,
+          outputSamples = [];
+
+      /* concatenate the video data and construct the mdat in place
+        (need 8 more bytes to fill length and mpdat type) */
+      mdat = new Uint8Array(track.len + 4 * track.nbNalu + 8);
+      var view = new DataView(mdat.buffer);
+      view.setUint32(0, mdat.byteLength);
+      mdat.set(_mp4Generator2.default.types.mdat, 4);
+      var sampleDuration = 0;
+      var ptsnorm = void 0,
+          dtsnorm = void 0,
+          mp4Sample = void 0,
+          lastDTS = void 0;
+
+      for (var i = 0; i < inputSamples.length; i++) {
+        var avcSample = inputSamples[i],
+            mp4SampleLength = 0,
+            compositionTimeOffset = void 0;
+        // convert NALU bitstream to MP4 format (prepend NALU with size field)
+        while (avcSample.units.units.length) {
+          var unit = avcSample.units.units.shift();
+          view.setUint32(offset, unit.data.byteLength);
+          offset += 4;
+          mdat.set(unit.data, offset);
+          offset += unit.data.byteLength;
+          mp4SampleLength += 4 + unit.data.byteLength;
+        }
+
+        var pts = avcSample.pts - this._initPTS;
+        var dts = avcSample.dts - this._initDTS;
+        dts = Math.min(pts, dts);
+
+        if (lastDTS !== undefined) {
+          ptsnorm = this._PTSNormalize(pts, lastDTS);
+          dtsnorm = this._PTSNormalize(dts, lastDTS);
+          sampleDuration = dtsnorm - lastDTS;
+          if (sampleDuration <= 0) {
+            _logger.logger.log('invalid sample duration at PTS/DTS: ' + avcSample.pts + '/' + avcSample.dts + '|dts norm: ' + dtsnorm + '|lastDTS: ' + lastDTS + ':' + sampleDuration);
+            sampleDuration = 1;
+          }
+        } else {
+          var nextAvcDts = this.nextAvcDts,
+              delta;
+          ptsnorm = this._PTSNormalize(pts, nextAvcDts);
+          dtsnorm = this._PTSNormalize(dts, nextAvcDts);
+          if (nextAvcDts) {
+            delta = Math.round(dtsnorm - nextAvcDts);
+            if ( /*contiguous ||*/Math.abs(delta) < 600) {
+              if (delta) {
+                if (delta > 1) {
+                  _logger.logger.log('AVC:' + delta + ' ms hole between fragments detected,filling it');
+                } else if (delta < -1) {
+                  _logger.logger.log('AVC:' + -delta + ' ms overlapping between fragments detected');
+                }
+                dtsnorm = nextAvcDts;
+                ptsnorm = Math.max(ptsnorm - delta, dtsnorm);
+                _logger.logger.log('Video/PTS/DTS adjusted: ' + ptsnorm + '/' + dtsnorm + ',delta:' + delta);
+              }
+            }
+          }
+          this.firstPTS = Math.max(0, ptsnorm);
+          this.firstDTS = Math.max(0, dtsnorm);
+          sampleDuration = 0.03;
+        }
+        outputSamples.push({
+          size: mp4SampleLength,
+          duration: this.H264_TIMEBASE,
+          cts: 0,
+          flags: {
+            isLeading: 0,
+            isDependedOn: 0,
+            hasRedundancy: 0,
+            degradPrio: 0,
+            dependsOn: avcSample.key ? 2 : 1,
+            isNonSync: avcSample.key ? 0 : 1
+          }
+        });
+        lastDTS = dtsnorm;
+      }
+      var lastSampleDuration = 0;
+      if (outputSamples.length >= 2) {
+        lastSampleDuration = outputSamples[outputSamples.length - 2].duration;
+        outputSamples[0].duration = lastSampleDuration;
+      }
+      this.nextAvcDts = dtsnorm + lastSampleDuration;
+      var dropped = track.dropped;
+      track.len = 0;
+      track.nbNalu = 0;
+      track.dropped = 0;
+      if (outputSamples.length && navigator.userAgent.toLowerCase().indexOf('chrome') > -1) {
+        var flags = outputSamples[0].flags;
+        flags.dependsOn = 2;
+        flags.isNonSync = 0;
+      }
+      track.samples = outputSamples;
+      moof = _mp4Generator2.default.moof(track.sequenceNumber++, dtsnorm, track);
+      track.samples = [];
+
+      var data = {
+        id: this.id,
+        level: this.level,
+        sn: this.sn,
+        data1: moof,
+        data2: mdat,
+        startPTS: ptsnorm,
+        endPTS: ptsnorm,
+        startDTS: dtsnorm,
+        endDTS: dtsnorm,
+        type: 'video',
+        nb: outputSamples.length,
+        dropped: dropped
+      };
+      this.observer.trigger(_events2.default.FRAG_PARSING_DATA, data);
+      return data;
+    }
+  }, {
+    key: 'generateVideoIS',
+    value: function generateVideoIS(videoTrack, timeOffset) {
+      var observer = this.observer,
+          videoSamples = videoTrack.samples,
+          pesTimeScale = this.PES_TIMESCALE,
+          tracks = {},
+          data = { id: this.id, level: this.level, sn: this.sn, tracks: tracks, unique: false },
+          computePTSDTS = this._initPTS === undefined,
+          initPTS,
+          initDTS;
+
+      if (computePTSDTS) {
+        initPTS = initDTS = Infinity;
+      }
+
+      if (videoTrack.sps && videoTrack.pps && videoSamples.length) {
+        videoTrack.timescale = 90000; //this.MP4_TIMESCALE;
+        tracks.video = {
+          container: 'video/mp4',
+          codec: videoTrack.codec,
+          initSegment: _mp4Generator2.default.initSegment([videoTrack]),
+          metadata: {
+            width: videoTrack.width,
+            height: videoTrack.height
+          }
+        };
+        if (computePTSDTS) {
+          initPTS = Math.min(initPTS, videoSamples[0].pts - this.H264_TIMEBASE);
+          initDTS = Math.min(initDTS, videoSamples[0].dts - this.H264_TIMEBASE);
+        }
+      }
+
+      if (Object.keys(tracks).length) {
+        observer.trigger(_events2.default.FRAG_PARSING_INIT_SEGMENT, data);
+        this.ISGenerated = true;
+        if (computePTSDTS) {
+          this._initPTS = initPTS;
+          this._initDTS = initDTS;
+        }
+      } else {
+        console.log("generateVideoIS ERROR==> ", _errors.ErrorTypes.MEDIA_ERROR);
+      }
+    }
+  }, {
+    key: 'remux',
+    value: function remux(level, sn, audioTrack, videoTrack, id3Track, textTrack, timeOffset, contiguous) {
+      this.level = level;
+      this.sn = sn;
+      // generate Init Segment if needed
+      if (!this.ISGenerated) {
+        this.generateIS(audioTrack, videoTrack, timeOffset);
+      }
+
+      if (this.ISGenerated) {
+        // Purposefully remuxing audio before video, so that remuxVideo can use nextAacPts, which is
+        // calculated in remuxAudio.
+        //logger.log('nb AAC samples:' + audioTrack.samples.length);
+        if (audioTrack.samples.length) {
+          var audioData = this.remuxAudio(audioTrack, timeOffset, contiguous);
+          //logger.log('nb AVC samples:' + videoTrack.samples.length);
+          if (videoTrack.samples.length) {
+            var audioTrackLength = void 0;
+            if (audioData) {
+              audioTrackLength = audioData.endPTS - audioData.startPTS;
+            }
+            this.remuxVideo(videoTrack, timeOffset, contiguous, audioTrackLength);
+          }
+        } else {
+          var videoData = void 0;
+          //logger.log('nb AVC samples:' + videoTrack.samples.length);
+          if (videoTrack.samples.length) {
+            videoData = this.remuxVideo(videoTrack, timeOffset, contiguous);
+          }
+          if (videoData && audioTrack.codec) {
+            this.remuxEmptyAudio(audioTrack, timeOffset, contiguous, videoData);
+          }
+        }
+      }
+      //logger.log('nb ID3 samples:' + audioTrack.samples.length);
+      if (id3Track.samples.length) {
+        this.remuxID3(id3Track, timeOffset);
+      }
+      //logger.log('nb ID3 samples:' + audioTrack.samples.length);
+      if (textTrack.samples.length) {
+        this.remuxText(textTrack, timeOffset);
+      }
+      //notify end of parsing
+      this.observer.trigger(_events2.default.FRAG_PARSED, { id: this.id, level: this.level, sn: this.sn });
+    }
+  }, {
+    key: 'generateIS',
+    value: function generateIS(audioTrack, videoTrack, timeOffset) {
+      var observer = this.observer,
+          audioSamples = audioTrack.samples,
+          videoSamples = videoTrack.samples,
+          pesTimeScale = this.PES_TIMESCALE,
+          tracks = {},
+          data = { id: this.id, level: this.level, sn: this.sn, tracks: tracks, unique: false },
+          computePTSDTS = this._initPTS === undefined,
+          initPTS,
+          initDTS;
+
+      if (computePTSDTS) {
+        initPTS = initDTS = Infinity;
+      }
+      if (audioTrack.config && audioSamples.length) {
+        audioTrack.timescale = audioTrack.audiosamplerate;
+        // MP4 duration (track duration in seconds multiplied by timescale) is coded on 32 bits
+        // we know that each AAC sample contains 1024 frames....
+        // in order to avoid overflowing the 32 bit counter for large duration, we use smaller timescale (timescale/gcd)
+        // we just need to ensure that AAC sample duration will still be an integer (will be 1024/gcd)
+        if (audioTrack.timescale * audioTrack.duration > Math.pow(2, 32)) {
+          var greatestCommonDivisor = function greatestCommonDivisor(a, b) {
+            if (!b) {
+              return a;
+            }
+            return greatestCommonDivisor(b, a % b);
+          };
+          audioTrack.timescale = audioTrack.audiosamplerate / greatestCommonDivisor(audioTrack.audiosamplerate, 1024);
+        }
+        _logger.logger.log('audio mp4 timescale :' + audioTrack.timescale);
+        tracks.audio = {
+          container: 'audio/mp4',
+          codec: audioTrack.codec,
+          initSegment: _mp4Generator2.default.initSegment([audioTrack]),
+          metadata: {
+            channelCount: audioTrack.channelCount
+          }
+        };
+        if (computePTSDTS) {
+          // remember first PTS of this demuxing context. for audio, PTS + DTS ...
+          initPTS = initDTS = audioSamples[0].pts - pesTimeScale * timeOffset;
+        }
+      }
+
+      if (videoTrack.sps && videoTrack.pps && videoSamples.length) {
+        videoTrack.timescale = this.MP4_TIMESCALE;
+        tracks.video = {
+          container: 'video/mp4',
+          codec: videoTrack.codec,
+          initSegment: _mp4Generator2.default.initSegment([videoTrack]),
+          metadata: {
+            width: videoTrack.width,
+            height: videoTrack.height
+          }
+        };
+        if (computePTSDTS) {
+          initPTS = Math.min(initPTS, videoSamples[0].pts - pesTimeScale * timeOffset);
+          initDTS = Math.min(initDTS, videoSamples[0].dts - pesTimeScale * timeOffset);
+        }
+      }
+
+      if (Object.keys(tracks).length) {
+        observer.trigger(_events2.default.FRAG_PARSING_INIT_SEGMENT, data);
+        this.ISGenerated = true;
+        if (computePTSDTS) {
+          this._initPTS = initPTS;
+          this._initDTS = initDTS;
+        }
+      } else {
+        observer.trigger(_events2.default.ERROR, { type: _errors.ErrorTypes.MEDIA_ERROR, id: this.id, details: _errors.ErrorDetails.FRAG_PARSING_ERROR, fatal: false, reason: 'no audio/video samples found' });
+      }
+    }
+  }, {
+    key: 'remuxVideo',
+    value: function remuxVideo(track, timeOffset, contiguous, audioTrackLength) {
+      var offset = 8,
+          pesTimeScale = this.PES_TIMESCALE,
+          pes2mp4ScaleFactor = this.PES2MP4SCALEFACTOR,
+          mp4SampleDuration,
+          mdat,
+          moof,
+          firstPTS,
+          firstDTS,
+          nextDTS,
+          lastPTS,
+          lastDTS,
+          inputSamples = track.samples,
+          outputSamples = [];
+
+      // PTS is coded on 33bits, and can loop from -2^32 to 2^32
+      // PTSNormalize will make PTS/DTS value monotonic, we use last known DTS value as reference value
+      var nextAvcDts = void 0;
+      if (contiguous) {
+        // if parsed fragment is contiguous with last one, let's use last DTS value as reference
+        nextAvcDts = this.nextAvcDts;
+      } else {
+        // if not contiguous, let's use target timeOffset
+        nextAvcDts = timeOffset * pesTimeScale;
+      }
+
+      // compute first DTS and last DTS, normalize them against reference value
+      var sample = inputSamples[0];
+      firstDTS = Math.max(this._PTSNormalize(sample.dts, nextAvcDts) - this._initDTS, 0);
+      firstPTS = Math.max(this._PTSNormalize(sample.pts, nextAvcDts) - this._initDTS, 0);
+
+      // check timestamp continuity accross consecutive fragments (this is to remove inter-fragment gap/hole)
+      var delta = Math.round((firstDTS - nextAvcDts) / 90);
+      // if fragment are contiguous, detect hole/overlapping between fragments
+      if (contiguous) {
+        if (delta) {
+          if (delta > 1) {
+            _logger.logger.log('AVC:' + delta + ' ms hole between fragments detected,filling it');
+          } else if (delta < -1) {
+            _logger.logger.log('AVC:' + -delta + ' ms overlapping between fragments detected');
+          }
+          // remove hole/gap : set DTS to next expected DTS
+          firstDTS = nextAvcDts;
+          inputSamples[0].dts = firstDTS + this._initDTS;
+          // offset PTS as well, ensure that PTS is smaller or equal than new DTS
+          firstPTS = Math.max(firstPTS - delta, nextAvcDts);
+          inputSamples[0].pts = firstPTS + this._initDTS;
+          _logger.logger.log('Video/PTS/DTS adjusted: ' + firstPTS + '/' + firstDTS + ',delta:' + delta);
+        }
+      }
+      nextDTS = firstDTS;
+
+      // compute lastPTS/lastDTS
+      sample = inputSamples[inputSamples.length - 1];
+      lastDTS = Math.max(this._PTSNormalize(sample.dts, nextAvcDts) - this._initDTS, 0);
+      lastPTS = Math.max(this._PTSNormalize(sample.pts, nextAvcDts) - this._initDTS, 0);
+      lastPTS = Math.max(lastPTS, lastDTS);
+
+      var vendor = navigator.vendor,
+          userAgent = navigator.userAgent,
+          isSafari = vendor && vendor.indexOf('Apple') > -1 && userAgent && !userAgent.match('CriOS');
+
+      // on Safari let's signal the same sample duration for all samples
+      // sample duration (as expected by trun MP4 boxes), should be the delta between sample DTS
+      // set this constant duration as being the avg delta between consecutive DTS.
+      if (isSafari) {
+        mp4SampleDuration = Math.round((lastDTS - firstDTS) / (pes2mp4ScaleFactor * (inputSamples.length - 1)));
+      }
+
+      // normalize all PTS/DTS now ...
+      for (var i = 0; i < inputSamples.length; i++) {
+        var _sample = inputSamples[i];
+        if (isSafari) {
+          // sample DTS is computed using a constant decoding offset (mp4SampleDuration) between samples
+          _sample.dts = firstDTS + i * pes2mp4ScaleFactor * mp4SampleDuration;
+        } else {
+          // ensure sample monotonic DTS
+          _sample.dts = Math.max(this._PTSNormalize(_sample.dts, nextAvcDts) - this._initDTS, firstDTS);
+          // ensure dts is a multiple of scale factor to avoid rounding issues
+          _sample.dts = Math.round(_sample.dts / pes2mp4ScaleFactor) * pes2mp4ScaleFactor;
+        }
+        // we normalize PTS against nextAvcDts, we also substract initDTS (some streams don't start @ PTS O)
+        // and we ensure that computed value is greater or equal than sample DTS
+        _sample.pts = Math.max(this._PTSNormalize(_sample.pts, nextAvcDts) - this._initDTS, _sample.dts);
+        // ensure pts is a multiple of scale factor to avoid rounding issues
+        _sample.pts = Math.round(_sample.pts / pes2mp4ScaleFactor) * pes2mp4ScaleFactor;
+      }
+      /* concatenate the video data and construct the mdat in place
+        (need 8 more bytes to fill length and mpdat type) */
+      mdat = new Uint8Array(track.len + 4 * track.nbNalu + 8);
+      var view = new DataView(mdat.buffer);
+      view.setUint32(0, mdat.byteLength);
+      mdat.set(_mp4Generator2.default.types.mdat, 4);
+
+      for (var _i = 0; _i < inputSamples.length; _i++) {
+        var avcSample = inputSamples[_i],
+            mp4SampleLength = 0,
+            compositionTimeOffset = void 0;
+        // convert NALU bitstream to MP4 format (prepend NALU with size field)
+        while (avcSample.units.units.length) {
+          var unit = avcSample.units.units.shift();
+          view.setUint32(offset, unit.data.byteLength);
+          offset += 4;
+          mdat.set(unit.data, offset);
+          offset += unit.data.byteLength;
+          mp4SampleLength += 4 + unit.data.byteLength;
+        }
+
+        if (!isSafari) {
+          // expected sample duration is the Decoding Timestamp diff of consecutive samples
+          if (_i < inputSamples.length - 1) {
+            mp4SampleDuration = inputSamples[_i + 1].dts - avcSample.dts;
+          } else {
+            var config = this.config,
+                lastFrameDuration = avcSample.dts - inputSamples[_i > 0 ? _i - 1 : _i].dts;
+            if (config.stretchShortVideoTrack) {
+              // In some cases, a segment's audio track duration may exceed the video track duration.
+              // Since we've already remuxed audio, and we know how long the audio track is, we look to
+              // see if the delta to the next segment is longer than the minimum of maxBufferHole and
+              // maxSeekHole. If so, playback would potentially get stuck, so we artificially inflate
+              // the duration of the last frame to minimize any potential gap between segments.
+              var maxBufferHole = config.maxBufferHole,
+                  maxSeekHole = config.maxSeekHole,
+                  gapTolerance = Math.floor(Math.min(maxBufferHole, maxSeekHole) * pesTimeScale),
+                  deltaToFrameEnd = (audioTrackLength ? firstPTS + audioTrackLength * pesTimeScale : this.nextAacPts) - avcSample.pts;
+              if (deltaToFrameEnd > gapTolerance) {
+                // We subtract lastFrameDuration from deltaToFrameEnd to try to prevent any video
+                // frame overlap. maxBufferHole/maxSeekHole should be >> lastFrameDuration anyway.
+                mp4SampleDuration = deltaToFrameEnd - lastFrameDuration;
+                if (mp4SampleDuration < 0) {
+                  mp4SampleDuration = lastFrameDuration;
+                }
+                _logger.logger.log('It is approximately ' + deltaToFrameEnd / 90 + ' ms to the next segment; using duration ' + mp4SampleDuration / 90 + ' ms for the last video frame.');
+              } else {
+                mp4SampleDuration = lastFrameDuration;
+              }
+            } else {
+              mp4SampleDuration = lastFrameDuration;
+            }
+          }
+          mp4SampleDuration /= pes2mp4ScaleFactor;
+          compositionTimeOffset = Math.round((avcSample.pts - avcSample.dts) / pes2mp4ScaleFactor);
+        } else {
+          compositionTimeOffset = Math.max(0, mp4SampleDuration * Math.round((avcSample.pts - avcSample.dts) / (pes2mp4ScaleFactor * mp4SampleDuration)));
+        }
+        outputSamples.push({
+          size: mp4SampleLength,
+          // constant duration
+          duration: mp4SampleDuration,
+          cts: compositionTimeOffset,
+          flags: {
+            isLeading: 0,
+            isDependedOn: 0,
+            hasRedundancy: 0,
+            degradPrio: 0,
+            dependsOn: avcSample.key ? 2 : 1,
+            isNonSync: avcSample.key ? 0 : 1
+          }
+        });
+      }
+      // next AVC sample DTS should be equal to last sample DTS + last sample duration (in PES timescale)
+      this.nextAvcDts = lastDTS + mp4SampleDuration * pes2mp4ScaleFactor;
+      var dropped = track.dropped;
+      track.len = 0;
+      track.nbNalu = 0;
+      track.dropped = 0;
+      if (outputSamples.length && navigator.userAgent.toLowerCase().indexOf('chrome') > -1) {
+        var flags = outputSamples[0].flags;
+        // chrome workaround, mark first sample as being a Random Access Point to avoid sourcebuffer append issue
+        // https://code.google.com/p/chromium/issues/detail?id=229412
+        flags.dependsOn = 2;
+        flags.isNonSync = 0;
+      }
+      track.samples = outputSamples;
+      moof = _mp4Generator2.default.moof(track.sequenceNumber++, firstDTS / pes2mp4ScaleFactor, track);
+      track.samples = [];
+
+      var data = {
+        id: this.id,
+        level: this.level,
+        sn: this.sn,
+        data1: moof,
+        data2: mdat,
+        startPTS: firstPTS / pesTimeScale,
+        endPTS: (lastPTS + pes2mp4ScaleFactor * mp4SampleDuration) / pesTimeScale,
+        startDTS: firstPTS / pesTimeScale,
+        endDTS: (lastPTS + pes2mp4ScaleFactor * mp4SampleDuration) / pesTimeScale,
+        // startDTS: firstDTS / pesTimeScale,
+        // endDTS: this.nextAvcDts / pesTimeScale,
+        type: 'video',
+        nb: outputSamples.length,
+        dropped: dropped
+      };
+      this.observer.trigger(_events2.default.FRAG_PARSING_DATA, data);
+      return data;
+    }
+  }, {
+    key: 'remuxAudio',
+    value: function remuxAudio(track, timeOffset, contiguous) {
+      var pesTimeScale = this.PES_TIMESCALE,
+          mp4timeScale = track.timescale,
+          pes2mp4ScaleFactor = pesTimeScale / mp4timeScale,
+          expectedSampleDuration = track.timescale * 1024 / track.audiosamplerate;
+      var view,
+          offset = 8,
+          aacSample,
+          mp4Sample,
+          unit,
+          mdat,
+          moof,
+          firstPTS,
+          firstDTS,
+          lastDTS,
+          pts,
+          dts,
+          ptsnorm,
+          dtsnorm,
+          samples = [],
+          samples0 = [];
+
+      track.samples.sort(function (a, b) {
+        return a.pts - b.pts;
+      });
+      samples0 = track.samples;
+
+      var nextAacPts = contiguous ? this.nextAacPts : timeOffset * pesTimeScale;
+
+      // If the audio track is missing samples, the frames seem to get "left-shifted" within the
+      // resulting mp4 segment, causing sync issues and leaving gaps at the end of the audio segment.
+      // In an effort to prevent this from happening, we inject frames here where there are gaps.
+      // When possible, we inject a silent frame; when that's not possible, we duplicate the last
+      // frame.
+      var firstPtsNorm = this._PTSNormalize(samples0[0].pts - this._initPTS, nextAacPts),
+          pesFrameDuration = expectedSampleDuration * pes2mp4ScaleFactor;
+      var nextPtsNorm = firstPtsNorm + pesFrameDuration;
+      for (var i = 1; i < samples0.length;) {
+        // First, let's see how far off this frame is from where we expect it to be
+        var sample = samples0[i],
+            ptsNorm = this._PTSNormalize(sample.pts - this._initPTS, nextAacPts),
+            delta = ptsNorm - nextPtsNorm;
+
+        // If we're overlapping by more than half a duration, drop this sample
+        if (delta < -0.5 * pesFrameDuration) {
+          _logger.logger.log('Dropping frame due to ' + Math.abs(delta / 90) + ' ms overlap.');
+          samples0.splice(i, 1);
+          track.len -= sample.unit.length;
+          // Don't touch nextPtsNorm or i
+        }
+        // Otherwise, if we're more than half a frame away from where we should be, insert missing frames
+        else if (delta > 0.5 * pesFrameDuration) {
+            var missing = Math.round(delta / pesFrameDuration);
+            _logger.logger.log('Injecting ' + missing + ' frame' + (missing > 1 ? 's' : '') + ' of missing audio due to ' + Math.round(delta / 90) + ' ms gap.');
+            for (var j = 0; j < missing; j++) {
+              var newStamp = samples0[i - 1].pts + pesFrameDuration,
+                  fillFrame = _aac2.default.getSilentFrame(track.channelCount);
+              if (!fillFrame) {
+                _logger.logger.log('Unable to get silent frame for given audio codec; duplicating last frame instead.');
+                fillFrame = sample.unit.slice(0);
+              }
+              samples0.splice(i, 0, { unit: fillFrame, pts: newStamp, dts: newStamp });
+              track.len += fillFrame.length;
+              i += 1;
+            }
+
+            // Adjust sample to next expected pts
+            nextPtsNorm += (missing + 1) * pesFrameDuration;
+            sample.pts = samples0[i - 1].pts + pesFrameDuration;
+            i += 1;
+          }
+          // Otherwise, we're within half a frame duration, so just adjust pts
+          else {
+              if (Math.abs(delta) > 0.1 * pesFrameDuration) {
+                _logger.logger.log('Invalid frame delta ' + (ptsNorm - nextPtsNorm + pesFrameDuration) + ' at PTS ' + Math.round(ptsNorm / 90) + ' (should be ' + pesFrameDuration + ').');
+              }
+              nextPtsNorm += pesFrameDuration;
+              sample.pts = samples0[i - 1].pts + pesFrameDuration;
+              i += 1;
+            }
+      }
+
+      while (samples0.length) {
+        aacSample = samples0.shift();
+        unit = aacSample.unit;
+        pts = aacSample.pts - this._initDTS;
+        dts = aacSample.dts - this._initDTS;
+        //logger.log(`Audio/PTS:${Math.round(pts/90)}`);
+        // if not first sample
+        if (lastDTS !== undefined) {
+          ptsnorm = this._PTSNormalize(pts, lastDTS);
+          dtsnorm = this._PTSNormalize(dts, lastDTS);
+          mp4Sample.duration = (dtsnorm - lastDTS) / pes2mp4ScaleFactor;
+        } else {
+          ptsnorm = this._PTSNormalize(pts, nextAacPts);
+          dtsnorm = this._PTSNormalize(dts, nextAacPts);
+          var _delta = Math.round(1000 * (ptsnorm - nextAacPts) / pesTimeScale);
+          // if fragment are contiguous, detect hole/overlapping between fragments
+          if (contiguous) {
+            // log delta
+            if (_delta) {
+              if (_delta > 0) {
+                _logger.logger.log(_delta + ' ms hole between AAC samples detected,filling it');
+                // if we have frame overlap, overlapping for more than half a frame duraion
+              } else if (_delta < -12) {
+                // drop overlapping audio frames... browser will deal with it
+                _logger.logger.log(-_delta + ' ms overlapping between AAC samples detected, drop frame');
+                track.len -= unit.byteLength;
+                continue;
+              }
+              // set PTS/DTS to expected PTS/DTS
+              ptsnorm = dtsnorm = nextAacPts;
+            }
+          }
+          // remember first PTS of our aacSamples, ensure value is positive
+          firstPTS = Math.max(0, ptsnorm);
+          firstDTS = Math.max(0, dtsnorm);
+          if (track.len > 0) {
+            /* concatenate the audio data and construct the mdat in place
+              (need 8 more bytes to fill length and mdat type) */
+            mdat = new Uint8Array(track.len + 8);
+            view = new DataView(mdat.buffer);
+            view.setUint32(0, mdat.byteLength);
+            mdat.set(_mp4Generator2.default.types.mdat, 4);
+          } else {
+            // no audio samples
+            return;
+          }
+        }
+        mdat.set(unit, offset);
+        offset += unit.byteLength;
+        //console.log('PTS/DTS/initDTS/normPTS/normDTS/relative PTS : ${aacSample.pts}/${aacSample.dts}/${this._initDTS}/${ptsnorm}/${dtsnorm}/${(aacSample.pts/4294967296).toFixed(3)}');
+        mp4Sample = {
+          size: unit.byteLength,
+          cts: 0,
+          duration: 0,
+          flags: {
+            isLeading: 0,
+            isDependedOn: 0,
+            hasRedundancy: 0,
+            degradPrio: 0,
+            dependsOn: 1
+          }
+        };
+        samples.push(mp4Sample);
+        lastDTS = dtsnorm;
+      }
+      var lastSampleDuration = 0;
+      var nbSamples = samples.length;
+      //set last sample duration as being identical to previous sample
+      if (nbSamples >= 2) {
+        lastSampleDuration = samples[nbSamples - 2].duration;
+        mp4Sample.duration = lastSampleDuration;
+      }
+      if (nbSamples) {
+        // next aac sample PTS should be equal to last sample PTS + duration
+        this.nextAacPts = ptsnorm + pes2mp4ScaleFactor * lastSampleDuration;
+        //logger.log('Audio/PTS/PTSend:' + aacSample.pts.toFixed(0) + '/' + this.nextAacDts.toFixed(0));
+        track.len = 0;
+        track.samples = samples;
+        moof = _mp4Generator2.default.moof(track.sequenceNumber++, firstDTS / pes2mp4ScaleFactor, track);
+        track.samples = [];
+        var audioData = {
+          id: this.id,
+          level: this.level,
+          sn: this.sn,
+          data1: moof,
+          data2: mdat,
+          startPTS: firstPTS / pesTimeScale,
+          endPTS: this.nextAacPts / pesTimeScale,
+          startDTS: firstDTS / pesTimeScale,
+          endDTS: (dtsnorm + pes2mp4ScaleFactor * lastSampleDuration) / pesTimeScale,
+          type: 'audio',
+          nb: nbSamples
+        };
+        this.observer.trigger(_events2.default.FRAG_PARSING_DATA, audioData);
+        return audioData;
+      }
+      return null;
+    }
+  }, {
+    key: 'remuxEmptyAudio',
+    value: function remuxEmptyAudio(track, timeOffset, contiguous, videoData) {
+      var pesTimeScale = this.PES_TIMESCALE,
+          mp4timeScale = track.timescale ? track.timescale : track.audiosamplerate,
+          pes2mp4ScaleFactor = pesTimeScale / mp4timeScale,
+
+
+      // sync with video's timestamp
+      startDTS = videoData.startDTS * pesTimeScale + this._initDTS,
+          endDTS = videoData.endDTS * pesTimeScale + this._initDTS,
+
+
+      // one sample's duration value
+      sampleDuration = 1024,
+          frameDuration = pes2mp4ScaleFactor * sampleDuration,
+
+
+      // samples count of this segment's duration
+      nbSamples = Math.ceil((endDTS - startDTS) / frameDuration),
+
+
+      // silent frame
+      silentFrame = _aac2.default.getSilentFrame(track.channelCount);
+
+      // Can't remux if we can't generate a silent frame...
+      if (!silentFrame) {
+        _logger.logger.trace('Unable to remuxEmptyAudio since we were unable to get a silent frame for given audio codec!');
+        return;
+      }
+
+      var samples = [];
+      for (var i = 0; i < nbSamples; i++) {
+        var stamp = startDTS + i * frameDuration;
+        samples.push({ unit: silentFrame.slice(0), pts: stamp, dts: stamp });
+        track.len += silentFrame.length;
+      }
+      track.samples = samples;
+
+      this.remuxAudio(track, timeOffset, contiguous);
+    }
+  }, {
+    key: 'remuxID3',
+    value: function remuxID3(track, timeOffset) {
+      var length = track.samples.length,
+          sample;
+      // consume samples
+      if (length) {
+        for (var index = 0; index < length; index++) {
+          sample = track.samples[index];
+          // setting id3 pts, dts to relative time
+          // using this._initPTS and this._initDTS to calculate relative time
+          sample.pts = (sample.pts - this._initPTS) / this.PES_TIMESCALE;
+          sample.dts = (sample.dts - this._initDTS) / this.PES_TIMESCALE;
+        }
+        this.observer.trigger(_events2.default.FRAG_PARSING_METADATA, {
+          id: this.id,
+          level: this.level,
+          sn: this.sn,
+          samples: track.samples
+        });
+      }
+
+      track.samples = [];
+      timeOffset = timeOffset;
+    }
+  }, {
+    key: 'remuxText',
+    value: function remuxText(track, timeOffset) {
+      track.samples.sort(function (a, b) {
+        return a.pts - b.pts;
+      });
+
+      var length = track.samples.length,
+          sample;
+      // consume samples
+      if (length) {
+        for (var index = 0; index < length; index++) {
+          sample = track.samples[index];
+          // setting text pts, dts to relative time
+          // using this._initPTS and this._initDTS to calculate relative time
+          sample.pts = (sample.pts - this._initPTS) / this.PES_TIMESCALE;
+        }
+        this.observer.trigger(_events2.default.FRAG_PARSING_USERDATA, {
+          id: this.id,
+          level: this.level,
+          sn: this.sn,
+          samples: track.samples
+        });
+      }
+
+      track.samples = [];
+      timeOffset = timeOffset;
+    }
+  }, {
+    key: '_PTSNormalize',
+    value: function _PTSNormalize(value, reference) {
+      var offset;
+      if (reference === undefined) {
+        return value;
+      }
+      if (reference < value) {
+        // - 2^33
+        offset = -8589934592;
+      } else {
+        // + 2^33
+        offset = 8589934592;
+      }
+      /* PTS is 33bit (from 0 to 2^33 -1)
+        if diff between value and reference is bigger than half of the amplitude (2^32) then it means that
+        PTS looping occured. fill the gap */
+      while (Math.abs(value - reference) > 4294967296) {
+        value += offset;
+      }
+      return value;
+    }
+  }, {
+    key: 'passthrough',
+    get: function get() {
+      return false;
+    }
+  }]);
+
+  return MP4Remuxer;
+}();
+
+exports.default = MP4Remuxer;
+
+},{"../errors":7,"../events":9,"../helper/aac":10,"../remux/mp4-generator":15,"../utils/logger":17,"../utils/polyfill":18}],17:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+
+var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
+
+function noop() {}
+
+var fakeLogger = {
+  trace: noop,
+  debug: noop,
+  log: noop,
+  warn: noop,
+  info: noop,
+  error: noop
+};
+
+var exportedLogger = fakeLogger;
+
+//let lastCallTime;
+// function formatMsgWithTimeInfo(type, msg) {
+//   const now = Date.now();
+//   const diff = lastCallTime ? '+' + (now - lastCallTime) : '0';
+//   lastCallTime = now;
+//   msg = (new Date(now)).toISOString() + ' | [' +  type + '] > ' + msg + ' ( ' + diff + ' ms )';
+//   return msg;
+// }
+
+function formatMsg(type, msg) {
+  msg = '[' + type + '] > ' + msg;
+  return msg;
+}
+
+function consolePrintFn(type) {
+  var func = window.console[type];
+  if (func) {
+    return function () {
+      for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
+        args[_key] = arguments[_key];
+      }
+
+      if (args[0]) {
+        args[0] = formatMsg(type, args[0]);
+      }
+      func.apply(window.console, args);
+    };
+  }
+  return noop;
+}
+
+function exportLoggerFunctions(debugConfig) {
+  for (var _len2 = arguments.length, functions = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
+    functions[_key2 - 1] = arguments[_key2];
+  }
+
+  functions.forEach(function (type) {
+    exportedLogger[type] = debugConfig[type] ? debugConfig[type].bind(debugConfig) : consolePrintFn(type);
+  });
+}
+
+var enableLogs = exports.enableLogs = function enableLogs(debugConfig) {
+  if (debugConfig === true || (typeof debugConfig === 'undefined' ? 'undefined' : _typeof(debugConfig)) === 'object') {
+    exportLoggerFunctions(debugConfig,
+    // Remove out from list here to hard-disable a log-level
+    //'trace',
+    'debug', 'log', 'info', 'warn', 'error');
+    // Some browsers don't allow to use bind on console object anyway
+    // fallback to default if needed
+    try {
+      exportedLogger.log();
+    } catch (e) {
+      exportedLogger = fakeLogger;
+    }
+  } else {
+    exportedLogger = fakeLogger;
+  }
+};
+
+var logger = exports.logger = exportedLogger;
+
+},{}],18:[function(require,module,exports){
+'use strict';
+
+if (typeof ArrayBuffer !== 'undefined' && !ArrayBuffer.prototype.slice) {
+  ArrayBuffer.prototype.slice = function (start, end) {
+    var that = new Uint8Array(this);
+    if (end === undefined) {
+      end = that.length;
+    }
+    var result = new ArrayBuffer(end - start);
+    var resultArray = new Uint8Array(result);
+    for (var i = 0; i < resultArray.length; i++) {
+      resultArray[i] = that[i + start];
+    }
+    return result;
+  };
+}
+
+},{}],19:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+/**
+ * XHR based logger
+*/
+
+var XhrLoader = function () {
+  function XhrLoader(config) {
+    _classCallCheck(this, XhrLoader);
+
+    if (config && config.xhrSetup) {
+      this.xhrSetup = config.xhrSetup;
+    }
+  }
+
+  _createClass(XhrLoader, [{
+    key: 'destroy',
+    value: function destroy() {
+      this.abort();
+      this.loader = null;
+    }
+  }, {
+    key: 'abort',
+    value: function abort() {
+      var loader = this.loader;
+      if (loader && loader.readyState !== 4) {
+        this.stats.aborted = true;
+        loader.abort();
+      }
+
+      window.clearTimeout(this.requestTimeout);
+      this.requestTimeout = null;
+      window.clearTimeout(this.retryTimeout);
+      this.retryTimeout = null;
+    }
+  }, {
+    key: 'loadHead',
+    value: function loadHead(context, config, callbacks) {
+      this.context = context;
+      this.config = config;
+      this.callbacks = callbacks;
+      this.stats = { trequest: performance.now(), retry: 0 };
+      this.retryDelay = config.retryDelay;
+      var xhr = new XMLHttpRequest();
+      xhr.open('head', context.url);
+      xhr.onload = function () {
+        callbacks.onSuccess(xhr.getResponseHeader('content-length'));
+      };
+      xhr.send();
+    }
+  }, {
+    key: 'load',
+    value: function load(context, config, callbacks) {
+      this.context = context;
+      this.config = config;
+      this.callbacks = callbacks;
+      this.stats = { trequest: performance.now(), retry: 0 };
+      this.retryDelay = config.retryDelay;
+      this.loadInternal();
+    }
+  }, {
+    key: 'loadInternal',
+    value: function loadInternal() {
+      var xhr,
+          context = this.context;
+      if (typeof XDomainRequest !== 'undefined') {
+        xhr = this.loader = new XDomainRequest();
+      } else {
+        xhr = this.loader = new XMLHttpRequest();
+      }
+      xhr.onloadend = this.loadend.bind(this);
+      xhr.onprogress = this.loadprogress.bind(this);
+      xhr.open('GET', context.url, true);
+      if (context.rangeEnd) {
+        xhr.setRequestHeader('Range', 'bytes=' + context.rangeStart + '-' + (context.rangeEnd - 1));
+      }
+      xhr.responseType = context.responseType;
+      var stats = this.stats;
+      stats.tfirst = 0;
+      stats.loaded = 0;
+      if (this.xhrSetup) {
+        this.xhrSetup(xhr, context.url);
+      }
+      // setup timeout before we perform request
+      this.requestTimeout = window.setTimeout(this.loadtimeout.bind(this), this.config.timeout);
+      xhr.send();
+    }
+  }, {
+    key: 'loadend',
+    value: function loadend(event) {
+      var xhr = event.currentTarget,
+          status = xhr.status,
+          stats = this.stats,
+          context = this.context,
+          config = this.config;
+      // don't proceed if xhr has been aborted
+      if (stats.aborted) {
+        return;
+      }
+      // in any case clear the current xhrs timeout
+      window.clearTimeout(this.requestTimeout);
+
+      // http status between 200 to 299 are all successful
+      if (status >= 200 && status < 300) {
+        stats.tload = Math.max(stats.tfirst, performance.now());
+        var data = void 0,
+            len = void 0;
+        if (context.responseType === 'arraybuffer') {
+          data = xhr.response;
+          len = data.byteLength;
+        } else {
+          data = xhr.responseText;
+          len = data.length;
+        }
+        stats.loaded = stats.total = len;
+        var response = { url: xhr.responseURL, data: data };
+        this.callbacks.onSuccess(response, stats, context);
+      } else {
+        // if max nb of retries reached or if http status between 400 and 499 (such error cannot be recovered, retrying is useless), return error
+        if (stats.retry >= config.maxRetry || status >= 400 && status < 499) {
+          //  logger.error(`${status} while loading ${context.url}` );
+          this.callbacks.onError({ code: status, text: xhr.statusText }, context);
+        } else {
+          // retry
+          //  logger.warn(`${status} while loading ${context.url}, retrying in ${this.retryDelay}...`);
+          // aborts and resets internal state
+          this.destroy();
+          // schedule retry
+          this.retryTimeout = window.setTimeout(this.loadInternal.bind(this), this.retryDelay);
+          // set exponential backoff
+          this.retryDelay = Math.min(2 * this.retryDelay, config.maxRetryDelay);
+          stats.retry++;
+        }
+      }
+    }
+  }, {
+    key: 'loadtimeout',
+    value: function loadtimeout() {
+      //  logger.warn(`timeout while loading ${this.context.url}` );
+      this.callbacks.onTimeout(this.stats, this.context);
+    }
+  }, {
+    key: 'loadprogress',
+    value: function loadprogress(event) {
+      var stats = this.stats;
+      if (stats.tfirst === 0) {
+        stats.tfirst = Math.max(performance.now(), stats.trequest);
+      }
+      stats.loaded = event.loaded;
+      if (event.lengthComputable) {
+        stats.total = event.total;
+      }
+      var onProgress = this.callbacks.onProgress;
+      if (onProgress) {
+        // last args is to provide on progress data
+        onProgress(stats, this.context, null);
+      }
+    }
+  }]);
+
+  return XhrLoader;
+}();
+
+exports.default = XhrLoader;
+
+},{}],20:[function(require,module,exports){
+/**
+ * WFS interface, Jeff Yang 2016.10
+ */
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _events = require('./events');
+
+var _events2 = _interopRequireDefault(_events);
+
+var _flowController = require('./controller/flow-controller');
+
+var _flowController2 = _interopRequireDefault(_flowController);
+
+var _bufferController = require('./controller/buffer-controller');
+
+var _bufferController2 = _interopRequireDefault(_bufferController);
+
+var _events3 = require('events');
+
+var _events4 = _interopRequireDefault(_events3);
+
+var _xhrLoader = require('./utils/xhr-loader');
+
+var _xhrLoader2 = _interopRequireDefault(_xhrLoader);
+
+var _fileLoader = require('./loader/file-loader');
+
+var _fileLoader2 = _interopRequireDefault(_fileLoader);
+
+var _websocketLoader = require('./loader/websocket-loader');
+
+var _websocketLoader2 = _interopRequireDefault(_websocketLoader);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var Wfs = function () {
+  _createClass(Wfs, null, [{
+    key: 'isSupported',
+    value: function isSupported() {
+      return window.MediaSource && typeof window.MediaSource.isTypeSupported === 'function' && window.MediaSource.isTypeSupported('video/mp4; codecs="avc1.42c01f,mp4a.40.2"');
+    }
+  }, {
+    key: 'version',
+    get: function get() {
+      // replaced with browserify-versionify transform
+      return '' + 'v.0.0.0.1';
+    }
+  }, {
+    key: 'Events',
+    get: function get() {
+      return _events2.default;
+    }
+  }, {
+    key: 'DefaultConfig',
+    get: function get() {
+      if (!Wfs.defaultConfig) {
+        Wfs.defaultConfig = {
+          autoStartLoad: true,
+          startPosition: -1,
+          debug: false,
+          fLoader: undefined,
+          loader: _xhrLoader2.default,
+          //loader: FetchLoader,
+          fmp4FileUrl: 'xxxx.mp4',
+          fragLoadingTimeOut: 20000,
+          fragLoadingMaxRetry: 6,
+          fragLoadingRetryDelay: 1000,
+          fragLoadingMaxRetryTimeout: 64000,
+          fragLoadingLoopThreshold: 3,
+          forceKeyFrameOnDiscontinuity: true,
+          appendErrorMaxRetry: 3
+        };
+      }
+      return Wfs.defaultConfig;
+    },
+    set: function set(defaultConfig) {
+      Wfs.defaultConfig = defaultConfig;
+    }
+  }]);
+
+  function Wfs() {
+    var config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+
+    _classCallCheck(this, Wfs);
+
+    var defaultConfig = Wfs.DefaultConfig;
+    for (var prop in defaultConfig) {
+      if (prop in config) {
+        continue;
+      }
+      config[prop] = defaultConfig[prop];
+    }
+    this.config = config;
+    // observer setup
+    var observer = this.observer = new _events4.default();
+    observer.trigger = function trigger(event) {
+      for (var _len = arguments.length, data = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
+        data[_key - 1] = arguments[_key];
+      }
+
+      observer.emit.apply(observer, [event, event].concat(data));
+    };
+
+    observer.off = function off(event) {
+      for (var _len2 = arguments.length, data = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
+        data[_key2 - 1] = arguments[_key2];
+      }
+
+      observer.removeListener.apply(observer, [event].concat(data));
+    };
+    this.on = observer.on.bind(observer);
+    this.off = observer.off.bind(observer);
+    this.trigger = observer.trigger.bind(observer);
+
+    this.flowController = new _flowController2.default(this);
+    this.bufferController = new _bufferController2.default(this);
+    //  this.fileLoader = new FileLoader(this);
+    this.websocketLoader = new _websocketLoader2.default(this);
+    this.mediaType = undefined;
+  }
+
+  _createClass(Wfs, [{
+    key: 'destroy',
+    value: function destroy() {
+      this.flowController.destroy();
+      this.bufferController.destroy();
+      //   this.fileLoader.destroy();
+      this.websocketLoader.destroy();
+    }
+  }, {
+    key: 'attachMedia',
+    value: function attachMedia(media,deviceId,clientid, loginHandle, wsUrl) {
+      var sessiontype = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 'video';
+      var begintime = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : '0';
+      var channelName = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : 'chX';
+      var mediaType = arguments.length > 8 && arguments[8] !== undefined ? arguments[8] : 'H264Raw';
+      var websocketName = arguments.length > 9 && arguments[9] !== undefined ? arguments[9] : 'play2';
+      // 'H264Raw' 'FMp4'
+      this.mediaType = mediaType;
+      this.media = media;
+      this.trigger(_events2.default.MEDIA_ATTACHING, { media: media, channelName: channelName, mediaType: mediaType, websocketName: websocketName, deviceId: deviceId,clientid: clientid,loginHandle: loginHandle,wsUrl: wsUrl ,sessiontype: sessiontype, begintime: begintime});
+    }
+  }, {
+    key: 'attachWebsocket',
+    value: function attachWebsocket(websocket, channelName, deviceId, clientid, loginHandle, sessiontype, begintime) {
+      this.trigger(_events2.default.WEBSOCKET_ATTACHING, { websocket: websocket, mediaType: this.mediaType, channelName: channelName, deviceId: deviceId,clientid: clientid,loginHandle: loginHandle, sessiontype: sessiontype, begintime: begintime});
+    }
+  }]);
+
+  return Wfs;
+}();
+
+exports.default = Wfs;
+
+},{"./controller/buffer-controller":3,"./controller/flow-controller":4,"./events":9,"./loader/file-loader":13,"./loader/websocket-loader":14,"./utils/xhr-loader":19,"events":1}]},{},[11])(11)
+});

Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
src/assets/react.svg


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
src/assets/svg/温度.svg


+ 1 - 0
src/assets/svg/电流.svg

@@ -0,0 +1 @@
+<svg t="1721976532579" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5346" width="200" height="200"><path d="M512 1024c-281.6 0-512-230.4-512-512s230.4-512 512-512c108.8 0 211.2 32 300.8 96 12.8 12.8 19.2 32 6.4 44.8s-32 19.2-44.8 6.4C697.6 89.6 608 64 512 64 262.4 64 64 262.4 64 512s198.4 448 448 448 448-198.4 448-448c0-76.8-19.2-153.6-57.6-224-6.4-12.8-6.4-32 12.8-44.8 12.8-6.4 32-6.4 44.8 12.8 38.4 76.8 64 166.4 64 256 0 281.6-230.4 512-512 512z" p-id="5347"></path><path d="M729.6 678.4L550.4 300.8c0-6.4-19.2-12.8-38.4-12.8s-32 12.8-38.4 19.2l-179.2 377.6c-6.4 19.2 6.4 38.4 25.6 44.8s44.8 0 51.2-19.2L428.8 576h166.4l57.6 134.4c12.8 19.2 38.4 25.6 51.2 19.2 19.2-12.8 32-32 25.6-51.2zM460.8 518.4L512 403.2l51.2 115.2H460.8z" p-id="5348"></path></svg>

+ 1 - 0
src/assets/svg/闪电.svg

@@ -0,0 +1 @@
+<svg t="1721975988382" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4302" width="200" height="200"><path d="M377.9 114.1h358.3l-136.4 268 231.5 0.3-485.1 559.3 139.5-356.4H222.6z" fill="#FED928" p-id="4303"></path></svg>

BIN
src/assets/灯杆.png


+ 4 - 1
src/main.ts

@@ -8,11 +8,14 @@ import 'element-plus/dist/index.css'
 
 import App from './App.vue'
 import router from './router'
+import zhCn from 'element-plus/es/locale/lang/zh-cn'
 
 const app = createApp(App)
 
 app.use(createPinia())
 app.use(router)
-app.use(ElementPlus)
+app.use(ElementPlus,{
+  locale: zhCn
+})
 
 app.mount('#app')

+ 42 - 22
src/router/route.ts

@@ -363,50 +363,70 @@ export const routeList:RouterType[] = [
     addr: 'zhdpgl/zhtc/kll'
   },
 
-
-
-
-
   {
     path: 'zhld',
     name: '智慧路灯',
     icon: 'Location',
   },
   {
-    path: 'zhld/yqzl',
-    name: '园区总览2',
+    path: 'zhld/tyfw',
+    name: '智慧路灯-统一服务',
+    icon: 'Location',
+    addr: 'zhld/tyfw'
+  },
+  {
+    path: 'zhld/bjld',
+    name: '智慧路灯-报警联动',
+    icon: 'Location',
+    addr: 'zhld/bjld'
+  },
+  {
+    path: 'zhld/sbjr',
+    name: '智慧路灯-设备接入',
+    icon: 'Location',
+    addr: 'zhld/sbjr'
+  },
+  {
+    path: 'zhld/yzxg',
+    name: '智慧路灯-阈值修改',
+    icon: 'Location',
+    addr: 'zhld/yzxg'
+  },
+  {
+    path: 'zhld/bjckcl',
+    name: '智慧路灯-报警查看处理',
     icon: 'Location',
-    addr: 'zhld/yqzl'
+    addr: 'zhld/bjckcl'
   },
   {
-    path: 'zhld/zhaf',
-    name: '智慧安防2',
+    path: 'zhld/csjc',
+    name: '智慧路灯-参数监测',
     icon: 'Location',
-    addr: 'zhld/zhaf'
+    addr: 'zhld/csjc'
   },
   {
-    path: 'zhld/zhnh',
-    name: '智慧能耗2',
+    path: 'zhld/yckz',
+    name: '智慧路灯-远程控制',
     icon: 'Location',
-    addr: 'zhld/zhnh'
+    addr: 'zhld/yckz'
   },
   {
-    path: 'zhld/zhxf',
-    name: '智慧消防2',
+    path: 'zhld/yczj',
+    name: '智慧路灯-远程自检',
     icon: 'Location',
-    addr: 'zhld/zhxf'
+    addr: 'zhld/yczj'
   },
   {
-    path: 'zhld/zhdg',
-    name: '智慧灯杆2',
+    path: 'zhld/dsrw',
+    name: '智慧路灯-定时任务',
     icon: 'Location',
-    addr: 'zhld/zhdg'
+    addr: 'zhld/dsrw'
   },
   {
-    path: 'zhld/zhtc',
-    name: '智慧停车2',
+    path: 'zhld/lstj',
+    name: '智慧路灯-历史统计',
     icon: 'Location',
-    addr: 'zhld/zhtc'
+    addr: 'zhld/lstj'
   },
   {
     path: 'zhhj',

+ 1 - 1
src/views/zhhj/bjcx.vue

@@ -3,7 +3,7 @@
 </script>
 
 <template>
-yfdhyfghhtths
+
 </template>
 
 <style scoped>

+ 2 - 1
src/views/zhhj/ssjc.vue

@@ -1,9 +1,10 @@
 <script setup lang="ts">
 
+window.open('https://172.16.102.27:8088/')
 </script>
 
 <template>
-dsfaw3524tgzfz
+<!--<iframe class="w-full h-90vh" src="https://172.16.102.27:8088/" />-->
 </template>
 
 <style scoped>

+ 91 - 0
src/views/zhld/bjckcl.vue

@@ -0,0 +1,91 @@
+<template>
+  <div>
+    <el-table
+      :data="data"
+      style="width: 100%"
+      @filter-change="handleFilterChange"
+      @sort-change="handleSortChange"
+    >
+      <el-table-column
+        prop="name"
+        label="所属组织"
+        sortable
+        :filters="[
+          { text: 'A', value: 'A' },
+          { text: 'B', value: 'B' },
+          { text: 'C', value: 'C' }
+        ]"
+        :filter-method="filterHandler"
+        filter-placement="bottom-end"
+      />
+      <el-table-column
+        prop="age"
+        label="报警时间"
+        sortable
+      />
+      <el-table-column
+        prop="address"
+        label="断线报警记录"
+        :filters="[
+          { text: 'A', value: 'A' },
+          { text: 'B', value: 'B' },
+          { text: 'C', value: 'C' }
+        ]"
+        :filter-method="filterHandler"
+        filter-placement="bottom-end"
+      />
+    </el-table>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ElTable, ElTableColumn } from 'element-plus';
+
+interface DataType {
+  key: string;
+  name: string;
+  age: string;
+  address: string;
+}
+
+const data: DataType[] = [
+  {
+    key: '1',
+    name: 'A区',
+    age: '2024-08-08',
+    address: 'A区出现功能异常',
+  },
+  {
+    key: '2',
+    name: 'A区',
+    age: '2024-07-12',
+    address: 'A区出现功能异常',
+  },
+  {
+    key: '3',
+    name: 'B区',
+    age: '2024-08-01',
+    address: 'B区出现功能异常',
+  },
+  {
+    key: '4',
+    name: 'C区',
+    age: '2024-07-01',
+    address: 'C区出现功能异常',
+  },
+];
+
+const handleFilterChange = (filters) => {
+  console.log('Filters:', filters);
+};
+
+const handleSortChange = ({ column, prop, order }) => {
+  console.log(`Sort by ${prop}: ${order}`);
+};
+
+const filterHandler = (value, row, column) => {
+  const property = column.property;
+  return row[property].indexOf(value) === 0;
+};
+</script>
+

+ 51 - 0
src/views/zhld/bjld.vue

@@ -0,0 +1,51 @@
+<template>
+  <div class="font-700 text-blue-5 mb-20px text-30px">报警联动</div>
+  <el-card class="w-400px">
+    <div class="flex justify-between">
+      <div>是否报警时顺便录像</div>
+      <el-switch v-model="recordVideo" />
+    </div>
+    <div class="flex justify-between">
+      <div>是否报警时顺便抓拍图片</div>
+      <el-switch v-model="captureImage" />
+    </div>
+    <div class="flex justify-between">
+      <div>是否报警时发短信提醒</div>
+      <el-switch v-model="sendSMS" />
+    </div>
+    <div class="flex justify-between">
+      <div class="flex-4">收短信的手机号</div>
+      <div><el-input v-model="phoneNumber" size="small" /></div>
+    </div>
+    <div class="flex justify-end mt-30px">
+      <el-button type="primary" @click="handleSave">确认保存</el-button>
+    </div>
+  </el-card>
+  <div class="font-700 text-blue-5 mb-20px text-20px">智能空开联动</div>
+  <el-card class="w-400px">
+    <div class="flex justify-between">
+      <div>是否报警时顺便关闭智能空开联动开关</div>
+      <el-switch v-model="closeSmartBreaker" />
+    </div>
+    <div class="flex justify-end mt-30px">
+      <el-button type="primary" @click="handleSave">确认保存</el-button>
+    </div>
+  </el-card>
+</template>
+
+<script setup>
+import { ref } from 'vue';
+import { ElMessage } from 'element-plus';
+
+// 定义响应式变量
+const recordVideo = ref(true);
+const captureImage = ref(true);
+const sendSMS = ref(true);
+const phoneNumber = ref('');
+const closeSmartBreaker = ref(true);
+
+// 处理保存操作
+const handleSave = () => {
+  ElMessage.success('保存成功');
+};
+</script>

+ 78 - 0
src/views/zhld/csjc.vue

@@ -0,0 +1,78 @@
+<template>
+  <div>
+    <div class="font-bold text-blue-5 mb-20px text-30px">参数监控信息</div>
+    <div class="flex flex-wrap gap-10">
+      <el-card title="电压监控" shadow="always" class="w-30% text-20px">
+        <div class="flex items-center">
+          <el-icon class="custom-icon-size"><i.Lightning /></el-icon>
+          <p class="h-50px leading-50px">当前电压: 221V</p>
+        </div>
+      </el-card>
+      <el-card title="电流监控" shadow="always" class="w-30% text-20px">
+        <div class="flex items-center">
+          <el-icon class="custom-icon-size"><i.Ticket /></el-icon>
+          <p class="h-50px leading-50px">当前电流: 10A</p>
+        </div>
+      </el-card>
+      <el-card title="温度监控" shadow="always" class="w-30% text-20px">
+        <div class="flex items-center">
+          <el-icon class="custom-icon-size"><i.PartlyCloudy /></el-icon>
+          <p class="h-50px leading-50px">当前温度: 160℃</p>
+        </div>
+      </el-card>
+      <el-card title="灯杆实时监控" shadow="always" class="w-30%" extra="<a href='#'>查看更多</a>">
+        <div class="flex justify-between border-b-1 border-b-solid border-b-blue-50 pb-10px">
+          <div>一号灯杆</div>
+          <el-tag type="success" effect="dark">
+            <el-icon class="custom-icon-size"><i.CircleCheck /></el-icon> 在线
+          </el-tag>
+        </div>
+        <div class="flex justify-between border-b-1 border-b-solid border-b-blue-50 pb-10px">
+          <div>二号灯杆</div>
+          <el-tag type="warning" effect="dark">
+            <el-icon class="custom-icon-size"><i.WarningFilled /></el-icon> 离线
+          </el-tag>
+        </div>
+        <div class="flex justify-between border-b-1 border-b-solid border-b-blue-50 pb-10px">
+          <div>三号灯杆</div>
+          <el-tag type="danger" effect="dark">
+            <el-icon class="custom-icon-size"><i.WarningFilled /></el-icon> 故障
+          </el-tag>
+        </div>
+      </el-card>
+      <el-card title="垃圾桶实时监控" shadow="always" class="w-30%" extra="<a href='#'>查看更多</a>">
+        <div class="flex justify-between border-b-1 border-b-solid border-b-blue-50 pb-10px">
+          <div>一号垃圾桶</div>
+          <el-tag type="success" effect="dark">
+            <el-icon class="custom-icon-size"><i.CircleCheckFilled /></el-icon> 空间充足
+          </el-tag>
+        </div>
+        <div class="flex justify-between border-b-1 border-b-solid border-b-blue-50 pb-10px">
+          <div>二号垃圾桶</div>
+          <el-tag type="warning" effect="dark">
+            <el-icon class="custom-icon-size"><i.WarningFilled /></el-icon> 快满
+          </el-tag>
+        </div>
+        <div class="flex justify-between border-b-1 border-b-solid border-b-blue-50 pb-10px">
+          <div>三号垃圾桶</div>
+          <el-tag type="danger" effect="dark">
+            <el-icon class="custom-icon-size"><i.Close /></el-icon> 满
+          </el-tag>
+        </div>
+      </el-card>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import * as i from '@element-plus/icons-vue';
+import { ElCard, ElTag, ElIcon } from 'element-plus';
+import { CircleCheck, CircleCheckFilled, Close, PartlyCloudy, Ticket, WarningFilled } from '@element-plus/icons-vue'
+</script>
+
+<style scoped>
+.custom-icon-size {
+  width: 25px;
+  height: 25px;
+}
+</style>

+ 148 - 0
src/views/zhld/dsrw.vue

@@ -0,0 +1,148 @@
+<template>
+  <div>
+    <el-button type="primary" @click="dialogVisible = true">新增定时任务</el-button>
+    <el-table :data="data" :row-selection="rowSelection">
+      <el-table-column label="名称" width="360">
+        <el-table-column prop="firstName" label="任务名称" width="180" />
+        <el-table-column prop="lastName" label="空开名称" width="180" />
+      </el-table-column>
+      <el-table-column prop="age" label="设备类型" width="180" />
+      <el-table-column prop="address" label="循环类型" width="180" />
+      <el-table-column label="当前状态" width="180">
+        <template #default="{ row }">
+          <el-tag
+            v-for="tag in row.tags"
+            :key="tag"
+            :type="getTagType(tag)"
+          >
+            {{ tag.toUpperCase() }}
+          </el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" width="180">
+        <template #default="{ row }">
+          <el-switch
+            v-model="row.tags[0]"
+            active-text="启用"
+            inactive-text="停用"
+            active-value="启用"
+            inactive-value="停用"
+            @change="toggleStatus(row)"
+          />
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <!-- 新增定时任务对话框 -->
+    <el-dialog v-model="dialogVisible" title="新增定时任务">
+      <el-form :model="newTask" label-width="100px">
+        <el-form-item label="任务名称">
+          <el-input v-model="newTask.firstName" />
+        </el-form-item>
+        <el-form-item label="空开名称">
+          <el-input v-model="newTask.lastName" />
+        </el-form-item>
+        <el-form-item label="设备类型">
+          <el-input-number v-model="newTask.age" />
+        </el-form-item>
+        <el-form-item label="循环类型">
+          <el-select v-model="newTask.address" placeholder="请选择循环类型">
+            <el-option label="预设类型1" value="预设类型1" />
+            <el-option label="预设类型2" value="预设类型2" />
+          </el-select>
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="dialogVisible = false">取消</el-button>
+          <el-button type="primary" @click="addTask">确定</el-button>
+        </span>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ref } from 'vue';
+import { ElButton, ElTable, ElTableColumn, ElTag, ElSwitch, ElDialog, ElForm, ElFormItem, ElInput, ElInputNumber, ElSelect, ElOption } from 'element-plus';
+
+interface DataType {
+  key: string;
+  firstName: string;
+  lastName: string;
+  age: number;
+  address: string;
+  tags: string[];
+}
+
+const data = ref<DataType[]>([
+  {
+    key: '1',
+    firstName: '定时任务1',
+    lastName: 'G845215',
+    age: 88,
+    address: '预设类型1',
+    tags: ['启用'],
+  },
+  {
+    key: '2',
+    firstName: '定时任务2',
+    lastName: 'G845212',
+    age: 77,
+    address: '预设类型1',
+    tags: ['停用'],
+  },
+  {
+    key: '3',
+    firstName: '定时任务3',
+    lastName: 'G845212',
+    age: 77,
+    address: '预设类型1',
+    tags: ['停用'],
+  },
+]);
+
+const rowSelection = {};
+const dialogVisible = ref(false);
+const newTask = ref({
+  key: '',
+  firstName: '',
+  lastName: '',
+  age: 0,
+  address: '',
+  tags: ['启用'], // 默认状态为启用
+});
+
+const toggleStatus = (row: DataType) => {
+  // 这里不需要额外逻辑,因为 ElSwitch 已经自动更新了 row.tags[0]
+};
+
+const addTask = () => {
+  newTask.value.key = String(data.value.length + 1); // 自动生成唯一键
+  data.value.push({ ...newTask.value });
+  dialogVisible.value = false;
+  newTask.value = {
+    key: '',
+    firstName: '',
+    lastName: '',
+    age: 0,
+    address: '',
+    tags: ['启用'],
+  };
+};
+
+const getTagType = (tag: string): string => {
+  switch (tag) {
+    case '启用':
+      return 'success';
+    case '停用':
+      return 'danger';
+    default:
+      return '';
+  }
+};
+</script>
+
+<style scoped>
+/* 如果有其他特定样式需求,可以在这里添加 */
+</style>

+ 45 - 0
src/views/zhld/lstj.vue

@@ -0,0 +1,45 @@
+<template>
+  <div>
+    <div class="font-bold text-blue-5 mb-20 text-3xl">用能统计</div>
+    <el-row :gutter="16">
+      <el-col :span="12">
+        <el-card>
+          <el-statistic title="建筑用能" :value="buildingEnergy" />
+        </el-card>
+      </el-col>
+      <el-col :span="12">
+        <el-card>
+          <el-statistic title="部门用能" :value="departmentEnergy" />
+        </el-card>
+      </el-col>
+      <el-col :span="12">
+        <el-card>
+          <el-statistic title="分项总用能" :value="totalItemEnergy" />
+        </el-card>
+      </el-col>
+    </el-row>
+    <div class="mt-50 font-bold text-blue-5 mb-20 text-3xl">灯杆垃圾桶统计</div>
+    <el-row :gutter="16">
+      <el-col :span="12">
+        <el-card>
+          <el-statistic title="灯杆用能" :value="poleEnergy" />
+        </el-card>
+      </el-col>
+      <el-col :span="12">
+        <el-card>
+          <el-statistic title="垃圾桶用能" :value="binEnergy" />
+        </el-card>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script setup lang="ts">import { ref } from 'vue';
+import { ElRow, ElCol, ElCard, ElStatistic } from 'element-plus';
+
+const buildingEnergy = ref('9871kw');
+const departmentEnergy = ref('781kw');
+const totalItemEnergy = ref('145874kw');
+const poleEnergy = ref('73kw');
+const binEnergy = ref('3kw');
+</script>

+ 153 - 0
src/views/zhld/sbjr.vue

@@ -0,0 +1,153 @@
+<template>
+  <div>
+    <el-button type="primary" @click="handleAdd">新增设备</el-button>
+    <el-table :data="data" style="width: 100%">
+      <el-table-column prop="name" label="设备名" width="180" />
+      <el-table-column prop="address" label="设备地址" width="180" />
+      <el-table-column prop="threshold" label="报警阈值" width="180" />
+      <el-table-column prop="password" label="二次密码" width="180" />
+      <el-table-column label="操作">
+        <template #default="scope">
+          <el-space size="middle">
+            <el-button type="primary" @click="modifyData(scope.row)">修改密码</el-button>
+            <el-button type="danger" @click="deleteDevice(scope.row)">删除设备</el-button>
+          </el-space>
+        </template>
+      </el-table-column>
+    </el-table>
+    <el-dialog
+      v-model="isOpen"
+      :title="isAdding ? '新增设备' : '修改设备'"
+      width="30%"
+      :destroy-on-close="true"
+      @close="handleClose"
+    >
+      <el-form
+        ref="formRef"
+        :model="form"
+        label-width="120px"
+        @finish="onCreate"
+        @finish-failed="onFinishFailed"
+      >
+        <el-form-item label="设备名" prop="name" :rules="[{ required: true, message: '请输入设备名' }]">
+          <el-input v-model="form.name" />
+        </el-form-item>
+        <el-form-item label="设备地址" prop="address" :rules="[{ required: true, message: '请输入设备地址' }]">
+          <el-input v-model="form.address" />
+        </el-form-item>
+        <el-form-item label="报警阈值" prop="threshold" :rules="[{ required: true, message: '请输入报警阈值' }]">
+          <el-input-number v-model="form.threshold" :min="0" />
+        </el-form-item>
+        <el-form-item label="二次密码" prop="password" :rules="[{ required: true, message: '请输入二次密码' }]">
+          <el-input v-model="form.password" type="password" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="handleClose">取消</el-button>
+          <el-button type="primary" @click="submitForm">确认</el-button>
+        </span>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ref, watch } from 'vue';
+import { ElButton, ElTable, ElTableColumn, ElSpace, ElDialog, ElForm, ElFormItem, ElInput, ElInputNumber, ElMessage } from 'element-plus';
+
+const data = ref([
+  {
+    address: "长沙",
+    key: "1",
+    name: "G12555",
+    password: "******",
+    threshold: 0
+  }
+]);
+
+const isAdding = ref(false); // 新增状态
+const currentRecord = ref(null); // 当前操作的记录
+const isOpen = ref(false);
+const formRef = ref(null);
+const form = ref({
+  name: '',
+  address: '',
+  threshold: 0,
+  password: ''
+});
+
+watch(() => currentRecord.value, (newVal) => {
+  if (newVal) {
+    form.value.name = newVal.name;
+    form.value.address = newVal.address;
+    form.value.threshold = newVal.threshold;
+    form.value.password = newVal.password;
+  }
+});
+
+const modifyData = (record) => {
+  currentRecord.value = record;
+  isAdding.value = false;
+  isOpen.value = true;
+};
+
+const handleAdd = () => {
+  isAdding.value = true; // 设置为新增状态
+  currentRecord.value = null; // 清空记录
+  isOpen.value = true;
+};
+
+const onFinishFailed = (errorInfo) => {
+  console.log('Failed:', errorInfo);
+  // 处理表单验证失败的情况
+};
+
+const deleteDevice = (record) => {
+  const index = data.value.findIndex(item => item.key === record.key);
+  if (index !== -1) {
+    data.value.splice(index, 1);
+    ElMessage.success('设备删除成功');
+  }
+};
+
+const handleClose = () => {
+  isOpen.value = false;
+  form.value = {
+    name: '',
+    address: '',
+    threshold: 0,
+    password: ''
+  };
+};
+
+const submitForm = () => {
+  formRef.value.validate((valid) => {
+    if (valid) {
+      if (isAdding.value) {
+        addDevice({ ...form.value, key: String(data.value.length + 1) }); // 新增设备
+      } else {
+        updateDevice({ ...form.value, key: currentRecord.value.key }); // 更新设备
+      }
+      handleClose();
+    } else {
+      console.log('error submit!!');
+      return false;
+    }
+  });
+};
+
+const addDevice = (device) => {
+  device.key = String(data.value.length + 1); // 假设key是唯一的标识符
+  data.value.push(device);
+  ElMessage.success('设备新增成功');
+};
+
+const updateDevice = (device) => {
+  const index = data.value.findIndex(item => item.key === device.key);
+  if (index !== -1) {
+    data.value[index] = { ...data.value[index], ...device };
+    ElMessage.success('设备修改成功');
+  }
+};
+</script>

+ 119 - 0
src/views/zhld/tyfw.vue

@@ -0,0 +1,119 @@
+<template>
+  <div class="font-700 text-blue-5 mb-20px text-30px">统一服务中心</div>
+  <div class="flex flex-wrap gap-10">
+    <el-card class="box-card" shadow="always" style="width: 30%">
+      <template #header>
+        <span>电压监控</span>
+      </template>
+      <div class="flex">
+        <img class="w-50px" src="/src/assets/svg/闪电.svg"/>
+        <p class="h-50px line-height-50px">当前电压:90999999V</p>
+      </div>
+    </el-card>
+    <el-card class="box-card" shadow="always" style="width: 30%">
+      <template #header>
+        <span>电流监控</span>
+      </template>
+      <div class="flex">
+        <img class="w-50px" src="/src/assets/svg/电流.svg"/>
+        <p class="h-50px line-height-50px">当前电流:100000A</p>
+      </div>
+    </el-card>
+    <el-card class="box-card" shadow="always" style="width: 30%">
+      <template #header>
+        <span>温度监控</span>
+      </template>
+      <div class="flex">
+        <img class="w-50px" src="/src/assets/svg/温度.svg"/>
+        <p class="h-50px line-height-50px">当前温度:1000℃</p>
+      </div>
+    </el-card>
+    <el-card class="box-card" shadow="always" style="width: 30%">
+      <template #header>
+        <span>灯杆实时监控</span>
+        <el-link type="primary" :underline="false">查看更多</el-link>
+      </template>
+      <div v-for="(pole, index) in poles" :key="index" class="flex justify-between border-b-1 border-b-solid border-b-blue-50 pb-10px">
+        <div>{{ pole.name }}</div>
+        <el-tag :icon="pole.icon" :type="pole.type">{{ pole.status }}</el-tag>
+      </div>
+    </el-card>
+    <el-card class="box-card" shadow="always" style="width: 30%">
+      <template #header>
+        <span>垃圾桶实时监控</span>
+        <el-link type="primary" :underline="false">查看更多</el-link>
+      </template>
+      <div v-for="(bin, index) in bins" :key="index" class="flex justify-between border-b-1 border-b-solid border-b-blue-50 pb-10px">
+        <div>{{ bin.name }}</div>
+        <el-tag :icon="bin.icon" :type="bin.type">{{ bin.status }}</el-tag>
+      </div>
+    </el-card>
+  </div>
+  <div class="font-700 text-blue-5 mb-20px text-20px mt-20px">电力资源使用问题</div>
+  <div class="flex flex-wrap gap-10">
+    <el-card class="box-card" shadow="always" style="width: 30%">
+      <template #header>
+        <span>能源浪费通报</span>
+        <el-link type="primary" :underline="false">查看更多</el-link>
+      </template>
+      <div v-for="(unit, index) in units" :key="index" class="flex justify-between border-b-1 border-b-solid border-b-blue-50 pb-10px">
+        <div>{{ unit.name }}</div>
+        <el-tag :icon="unit.icon" :type="unit.type">{{ unit.status }}</el-tag>
+      </div>
+    </el-card>
+    <el-card class="box-card" shadow="always" style="width: 30%">
+      <template #header>
+        <span>安全隐患通报</span>
+        <el-link type="primary" :underline="false">查看更多</el-link>
+      </template>
+      <div v-for="(building, index) in buildings" :key="index" class="flex justify-between border-b-1 border-b-solid border-b-blue-50 pb-10px">
+        <div>{{ building.name }}</div>
+        <el-tag :icon="building.icon" :type="building.type">{{ building.status }}</el-tag>
+      </div>
+    </el-card>
+    <el-card class="box-card" shadow="always" style="width: 30%">
+      <template #header>
+        <span>供需紧平衡</span>
+        <el-link type="primary" :underline="false">查看更多</el-link>
+      </template>
+      <div v-for="(balance, index) in balances" :key="index" class="flex justify-between border-b-1 border-b-solid border-b-blue-50 pb-10px">
+        <div>{{ balance.name }}</div>
+        <el-tag :icon="balance.icon" :type="balance.type">{{ balance.status }}</el-tag>
+      </div>
+    </el-card>
+  </div>
+</template>
+
+<script setup lang="ts">
+import * as i from '@element-plus/icons-vue';
+
+const poles = [
+  { name: '一号灯杆', icon: i.Aim, type: 'success', status: '在线' },
+  { name: '二号灯杆', icon: i.Warning, type: 'warning', status: '离线' },
+  { name: '三号灯杆', icon: i.Fold, type: 'danger', status: '故障' }
+];
+
+const bins = [
+  { name: '一号垃圾桶', icon: i.Aim, type: 'success', status: '空间充足' },
+  { name: '二号垃圾桶', icon: i.Warning, type: 'warning', status: '快满' },
+  { name: '三号垃圾桶', icon: i.Fold, type: 'danger', status: '满' }
+];
+
+const units = [
+  { name: '一单元', icon: i.Aim, type: 'success', status: '良好用电习惯' },
+  { name: '二单元', icon: i.Warning, type: 'warning', status: '电力浪费警告' },
+  { name: '三单元', icon: i.Fold, type: 'danger', status: '严重电力浪费' }
+];
+
+const buildings = [
+  { name: '三栋', icon: i.Aim, type: 'success', status: '较低风险' },
+  { name: '二栋', icon: i.Aim, type: 'success', status: '较低风险' },
+  { name: '一栋', icon: i.Fold, type: 'danger', status: '严重安全隐患' }
+];
+
+const balances = [
+  { name: '三栋', icon: i.Aim, type: 'success', status: '供需平衡' },
+  { name: '二栋', icon: i.Aim, type: 'success', status: '供需平衡' },
+  { name: '一栋', icon: i.Fold, type: 'danger', status: '供需失衡' }
+];
+</script>

+ 99 - 0
src/views/zhld/yckz.vue

@@ -0,0 +1,99 @@
+<template>
+  <div class="font-700 text-blue-5 mb-20px text-30px">远程控制</div>
+  <div class="flex flex-wrap gap-10">
+    <el-card title="灯杆实时监控" :bordered="true" style="width: 30%">
+      <template #extra>
+        <a href="#">查看更多</a>
+      </template>
+      <div v-for="(pole, index) in poles" :key="index" class="flex justify-between border-b-1 border-b-solid border-b-blue-50 pb-10px">
+        <div>{{ pole.name }}</div>
+        <el-tag :type="pole.type" effect="dark">
+          <component :is="pole.iconComponent" class="icon-size-15" />
+          {{ pole.status }}
+        </el-tag>
+        <div>
+          <span>空开状态</span>
+          <el-switch v-model="pole.switchState"></el-switch>
+        </div>
+      </div>
+    </el-card>
+    <el-card title="垃圾桶实时监控" :bordered="true" style="width: 30%">
+      <template #extra>
+        <a href="#">查看更多</a>
+      </template>
+      <div v-for="(bin, index) in bins" :key="index" class="flex justify-between border-b-1 border-b-solid border-b-blue-50 pb-10px">
+        <div>{{ bin.name }}</div>
+        <el-tag :type="bin.type" effect="dark">
+          <component :is="bin.iconComponent" class="icon-size-15" />
+          {{ bin.status }}
+        </el-tag>
+        <div>
+          <span>空开状态</span>
+          <el-switch v-model="bin.switchState"></el-switch>
+        </div>
+      </div>
+    </el-card>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ref } from 'vue'
+import { ElCard, ElTag, ElSwitch } from 'element-plus'
+import { Checked, Close, Warning } from '@element-plus/icons-vue'
+
+const poles = ref([
+  { name: '一号灯杆', status: '在线', type: 'success', iconComponent: Checked, switchState: true },
+  { name: '二号灯杆', status: '在线', type: 'success', iconComponent: Checked, switchState: true },
+  { name: '三号灯杆', status: '在线', type: 'success', iconComponent: Checked, switchState: true },
+  { name: '四号灯杆', status: '在线', type: 'success', iconComponent: Checked, switchState: true }
+])
+
+const bins = ref([
+  { name: '一号垃圾桶', status: '空间充足', type: 'success', iconComponent: Checked, switchState: true },
+  { name: '二号垃圾桶', status: '快满', type: 'warning', iconComponent: Warning, switchState: true },
+  { name: '三号垃圾桶', status: '满', type: 'danger', iconComponent: Close, switchState: true },
+  { name: '四号垃圾桶', status: '满', type: 'danger', iconComponent: Close, switchState: true }
+])
+</script>
+
+<style scoped>
+.font-700 {
+  @apply font-bold;
+}
+.text-blue-5 {
+  @apply text-blue-500;
+}
+.mb-20px {
+  @apply mb-5;
+}
+.text-30px {
+  @apply text-3xl;
+}
+.flex {
+  @apply flex;
+}
+.flex-wrap {
+  @apply flex-wrap;
+}
+.gap-10 {
+  @apply gap-2.5;
+}
+.border-b-1 {
+  @apply border-b;
+}
+.border-b-solid {
+  @apply border-solid;
+}
+.border-b-blue-50 {
+  @apply border-blue-50;
+}
+.pb-10px {
+  @apply pb-2.5;
+}
+
+/* 新增的图标尺寸样式 */
+.icon-size-15 {
+  width: 15px;
+  height: 15px;
+}
+</style>

+ 32 - 0
src/views/zhld/yczj.vue

@@ -0,0 +1,32 @@
+<template>
+  <div>
+    <h1 class="text-2xl mb-5 text-blue-600">远程自检</h1>
+    <el-button @click="showLoader">空开远程自检</el-button>
+    <div v-loading="spinning" :element-loading-text="tip" element-loading-background="rgba(0, 0, 0, 0.7)">
+      <!-- 这里放置需要被 loading 覆盖的内容 -->
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ref } from 'vue';
+import { ElButton, ElMessage } from 'element-plus';
+
+const spinning = ref(false);
+const tip = ref('远程自检中...');
+
+const showLoader = () => {
+  spinning.value = true;
+  let ptg = -10;
+
+  const interval = setInterval(() => {
+    ptg += 10;
+
+    if (ptg > 120) {
+      clearInterval(interval);
+      spinning.value = false;
+      ElMessage.success('远程自检成功,暂未发现异常');
+    }
+  }, 100);
+};
+</script>

+ 0 - 11
src/views/zhld/yqzl.vue

@@ -1,11 +0,0 @@
-<script setup lang="ts">
-
-</script>
-
-<template>
- n,mmn,mn,nm,nm,mn
-</template>
-
-<style scoped>
-
-</style>

+ 124 - 0
src/views/zhld/yzxg.vue

@@ -0,0 +1,124 @@
+<template>
+  <div>
+    <!-- 筛选栏 -->
+    <el-row :gutter="20">
+      <el-col :span="8">
+        <div class="mb-10px">设备组织查询</div>
+        <el-input
+          v-model="searchName"
+          placeholder="设备组织查询"
+        >
+          <template #append>
+            <el-button :icon="Search" @click="handleSearch" />
+          </template>
+        </el-input>
+      </el-col>
+      <el-col :span="8">
+        <div class="mb-10px">通道编号查询</div>
+        <el-input
+          v-model="searchAge"
+          placeholder="通道编号查询"
+        >
+          <template #append>
+            <el-button :icon="Search" @click="handleSearch" />
+          </template>
+        </el-input>
+      </el-col>
+      <el-col :span="8">
+        <div class="mb-10px">通道名称</div>
+        <el-input
+          v-model="searchAddress"
+          placeholder="通道名称"
+        >
+          <template #append>
+            <el-button :icon="Search" @click="handleSearch" />
+          </template>
+        </el-input>
+      </el-col>
+    </el-row>
+
+    <!-- 操作按钮 -->
+    <el-row :gutter="20" style="margin-top: 20px;">
+      <el-col :span="24">
+        <el-button
+          type="primary"
+          :disabled="!hasSelected"
+          :loading="loading"
+          @click="start"
+        >
+          重设阈值
+        </el-button>
+        <span v-if="hasSelected">已选择 {{ selectedRowKeys.length }} 项</span>
+      </el-col>
+    </el-row>
+
+    <!-- 表格 -->
+    <el-table
+      :data="filteredData"
+      style="width: 100%; margin-top: 10px;"
+      @selection-change="onSelectChange"
+      :row-selection="selectedRowKeys"
+    >
+      <el-table-column type="selection" width="55" />
+      <el-table-column prop="name" label="设备组织" width="180" />
+      <el-table-column prop="age" label="通道编号" width="180" />
+      <el-table-column prop="address" label="通道名称" width="180" />
+    </el-table>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ref, computed } from 'vue';
+import { ElButton, ElInput, ElTable, ElTableColumn, ElMessage } from 'element-plus';
+import { Search } from '@element-plus/icons-vue';
+
+interface DataType {
+  key: number;
+  name: string;
+  age: number;
+  address: string;
+}
+
+const dataSource: DataType[] = Array.from({ length: 4 }).map((_, i) => ({
+  key: i,
+  name: `智慧路灯 ${i+1}`,
+  age: parseFloat((Math.random() * 33).toFixed(0)),
+  address: `${i}`,
+}));
+
+const selectedRowKeys = ref([]);
+const loading = ref(false);
+const searchName = ref('');
+const searchAge = ref('');
+const searchAddress = ref('');
+
+const hasSelected = computed(() => selectedRowKeys.value.length > 0);
+
+const handleSearch = () => {
+  // 这里可以添加搜索逻辑,当前已经通过计算属性实现了过滤
+  console.log('Searching...');
+};
+
+const start = () => {
+  loading.value = true;
+  setTimeout(() => {
+    selectedRowKeys.value = [];
+    loading.value = false;
+    ElMessage.success('阈值已重置');
+  }, 1000);
+};
+
+const onSelectChange = (newSelectedRowKeys:DataType[]) => {
+  console.log('selectedRowKeys changed: ', newSelectedRowKeys);
+  selectedRowKeys.value = newSelectedRowKeys;
+};
+
+const filteredData = computed(() => {
+  return dataSource.filter(item =>
+    item.name.includes(searchName.value) &&
+    item.age.toString().includes(searchAge.value) &&
+    item.address.includes(searchAddress.value)
+  );
+});
+</script>
+

+ 0 - 11
src/views/zhld/zhaf.vue

@@ -1,11 +0,0 @@
-<script setup lang="ts">
-
-</script>
-
-<template>
-zxczcxzcxzcxzcxzcxzczx
-</template>
-
-<style scoped>
-
-</style>

+ 0 - 11
src/views/zhld/zhdg.vue

@@ -1,11 +0,0 @@
-<script setup lang="ts">
-
-</script>
-
-<template>
-asdsadsadsadasdasdsadsa
-</template>
-
-<style scoped>
-
-</style>

+ 0 - 11
src/views/zhld/zhnh.vue

@@ -1,11 +0,0 @@
-<script setup lang="ts">
-
-</script>
-
-<template>
-wqeqwewqewqewqeqwewq
-</template>
-
-<style scoped>
-
-</style>

+ 0 - 11
src/views/zhld/zhtc.vue

@@ -1,11 +0,0 @@
-<script setup lang="ts">
-
-</script>
-
-<template>
-yuyutuytuytuytuyuytut
-</template>
-
-<style scoped>
-
-</style>

+ 0 - 11
src/views/zhld/zhxf.vue

@@ -1,11 +0,0 @@
-<script setup lang="ts">
-
-</script>
-
-<template>
-hjkjhkjhkjhkjhkhkhj
-</template>
-
-<style scoped>
-
-</style>

+ 3 - 0
vite.config.ts

@@ -11,6 +11,9 @@ import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
 
 // https://vite.dev/config/
 export default defineConfig({
+  server: {
+    port: 3000
+  },
   plugins: [
     vue(),
     vueJsx(),

Alguns ficheiros não foram mostrados porque muitos ficheiros mudaram neste diff