Просмотр исходного кода

更换播放器, 修正和优化sql脚本,

64850858 4 лет назад
Родитель
Сommit
e48ef997c0

+ 24 - 24
sql/mysql.sql

@@ -5,10 +5,10 @@ create table device
 (
     deviceId           varchar(50) not null
         primary key,
-    name               varchar(50) null,
-    manufacturer       varchar(50) null,
-    model              varchar(50) null,
-    firmware           varchar(50) null,
+    name               varchar(255) null,
+    manufacturer       varchar(255) null,
+    model              varchar(255) null,
+    firmware           varchar(255) null,
     transport          varchar(50) null,
     streamMode         varchar(50) null,
     online             varchar(50) null,
@@ -25,7 +25,7 @@ create table device
 create table device_channel
 (
     channelId   varchar(50) not null,
-    name        varchar(50) null,
+    name        varchar(255) null,
     manufacture varchar(50) null,
     model       varchar(50) null,
     owner       varchar(50) null,
@@ -42,7 +42,7 @@ create table device_channel
     secrecy     varchar(50) null,
     ipAddress   varchar(50) null,
     port        int          null,
-    password    varchar(50) null,
+    password    varchar(255) null,
     PTZType     int          null,
     status      int          null,
     longitude   double       null,
@@ -59,7 +59,7 @@ create table device_channel
 create table device_mobile_position
 (
     deviceId       varchar(50) not null,
-    deviceName     varchar(50) null,
+    deviceName     varchar(255) null,
     time           varchar(50) not null,
     longitude      double       not null,
     latitude       double       not null,
@@ -75,10 +75,10 @@ create table device_mobile_position
 
 create table gb_stream
 (
-    app        varchar(50) not null,
-    stream     varchar(50) not null,
+    app        varchar(255) not null,
+    stream     varchar(255) not null,
     gbId       varchar(50) not null,
-    name       varchar(50) null,
+    name       varchar(255) null,
     longitude  double       null,
     latitude   double       null,
     streamType varchar(50) null,
@@ -90,7 +90,7 @@ create table parent_platform
 (
     id          int auto_increment,
     enable         int          null,
-    name           varchar(50) null,
+    name           varchar(255) null,
     serverGBId     varchar(50) not null,
     serverGBDomain varchar(50) null,
     serverIP       varchar(50) null,
@@ -98,7 +98,7 @@ create table parent_platform
     deviceGBId     varchar(50) not null,
     deviceIp       varchar(50) null,
     devicePort     varchar(50) null,
-    username       varchar(50) null,
+    username       varchar(255) null,
     password       varchar(50) null,
     expires        varchar(50) null,
     keepTimeout    varchar(50) null,
@@ -122,21 +122,21 @@ create table platform_gb_channel
 create table platform_gb_stream
 (
     platformId varchar(50) not null,
-    app        varchar(50) not null,
-    stream     varchar(50) not null,
+    app        varchar(255) not null,
+    stream     varchar(255) not null,
     primary key (platformId, app, stream)
 );
 
 create table stream_proxy
 (
     type           varchar(50) not null,
-    app            varchar(50) not null,
-    stream         varchar(50) not null,
-    url            varchar(50) null,
-    src_url        varchar(50) null,
-    dst_url        blob         null,
+    app            varchar(255) not null,
+    stream         varchar(255) not null,
+    url            varchar(255) null,
+    src_url        varchar(255) null,
+    dst_url        varchar(255) null,
     timeout_ms     int          null,
-    ffmpeg_cmd_key varchar(50) null,
+    ffmpeg_cmd_key varchar(255) null,
     rtp_type       varchar(50) null,
     enable_hls     bit(1)   null,
     enable_mp4     bit(1)   null,
@@ -146,8 +146,8 @@ create table stream_proxy
 
 create table stream_push
 (
-    app              varchar(50) not null,
-    stream           varchar(50) not null,
+    app              varchar(255) not null,
+    stream           varchar(255) not null,
     totalReaderCount varchar(50) null,
     originType       int          null,
     originTypeStr    varchar(50) null,
@@ -160,8 +160,8 @@ create table user
 (
     id          int auto_increment
         primary key,
-    username    varchar(50) not null,
-    password    varchar(50) not null,
+    username    varchar(255) not null,
+    password    varchar(255) not null,
     roleId      int          not null,
     create_time varchar(50) not null
 );

+ 2 - 0
src/main/java/com/genersoft/iot/vmp/VManageBootstrap.java

@@ -5,9 +5,11 @@ import java.util.logging.LogManager;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.scheduling.annotation.EnableScheduling;
 import springfox.documentation.oas.annotations.EnableOpenApi;
 
 @SpringBootApplication
+@EnableScheduling
 @EnableOpenApi
 public class VManageBootstrap extends LogManager {
 	private static String[] args;

+ 2 - 0
src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java

@@ -8,6 +8,8 @@ package com.genersoft.iot.vmp.common;
  */
 public class VideoManagerConstants {
 	
+	public static final String WVP_SERVER_PREFIX = "VMP_wvp_server";
+
 	public static final String MEDIA_SERVER_PREFIX = "VMP_media_server";
 
 	public static final String MEDIA_STREAM_PREFIX = "VMP_media_stream";

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java

@@ -58,7 +58,7 @@ public class MediaConfig {
     @Value("${media.rtp.port-range}")
     private String rtpPortRange;
 
-    @Value("${media.record-assist-port}")
+    @Value("${media.record-assist-port:0}")
     private Integer recordAssistPort;
 
     public String getIp() {

+ 12 - 0
src/main/java/com/genersoft/iot/vmp/gb28181/session/VideoStreamSessionManager.java

@@ -48,4 +48,16 @@ public class VideoStreamSessionManager {
 		ssrcMap.remove(deviceId + "_" + channelId);
 		streamIdMap.remove(deviceId + "_" + channelId);
 	}
+
+	public ConcurrentHashMap<String, ClientTransaction> getSessionMap() {
+		return sessionMap;
+	}
+
+	public ConcurrentHashMap<String, String> getSsrcMap() {
+		return ssrcMap;
+	}
+
+	public ConcurrentHashMap<String, String> getStreamIdMap() {
+		return streamIdMap;
+	}
 }

+ 9 - 7
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java

@@ -34,11 +34,13 @@ public class ZLMRTPServerFactory {
         if (currentStreams == null) {
             currentStreams = new HashMap<>();
             JSONObject jsonObject = zlmresTfulUtils.listRtpServer();
-            JSONArray data = jsonObject.getJSONArray("data");
-            if (data != null) {
-                for (int i = 0; i < data.size(); i++) {
-                    JSONObject dataItem = data.getJSONObject(i);
-                    currentStreams.put(dataItem.getString("stream_id"), dataItem.getInteger("port"));
+            if (jsonObject != null) {
+                JSONArray data = jsonObject.getJSONArray("data");
+                if (data != null) {
+                    for (int i = 0; i < data.size(); i++) {
+                        JSONObject dataItem = data.getJSONObject(i);
+                        currentStreams.put(dataItem.getString("stream_id"), dataItem.getInteger("port"));
+                    }
                 }
             }
         }
@@ -73,12 +75,12 @@ public class ZLMRTPServerFactory {
                     result= createRTPServer(streamId);
                     break;
                 default:
-                    logger.error("创建RTP Server 失败: " + jsonObject.getString("msg"));
+                    logger.error("创建RTP Server 失败 {}: " + jsonObject.getString("msg"), newPort);
                     break;
             }
         }else {
             //  检查ZLM状态
-            logger.error("创建RTP Server 失败: 请检查ZLM服务");
+            logger.error("创建RTP Server 失败 {}: 请检查ZLM服务", newPort);
         }
         return result;
     }

+ 4 - 1
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java

@@ -127,7 +127,7 @@ public class ZLMRunner implements CommandLineRunner {
         if (responseJSON != null && responseJSON.getInteger("code") == 0) {
             logger.info("设置zlm成功");
         }else {
-            logger.info("设置zlm失败: " + responseJSON.getString("msg"));
+            logger.info("设置zlm失败");
         }
     }
 
@@ -155,6 +155,9 @@ public class ZLMRunner implements CommandLineRunner {
                 // 设置为未启用
                 logger.info("恢复流代理失败,请检查流地址后重新启用" + streamProxyDto.getApp() + "/" + streamProxyDto.getStream());
                 streamProxyService.stop(streamProxyDto.getApp(), streamProxyDto.getStream());
+            }else if (jsonObject.getInteger("code") != 0){ // TODO 将错误信息存入数据库, 前端展示
+                logger.info("恢复流代理失败:" + streamProxyDto.getApp() + "/" + streamProxyDto.getStream() + "[ " + JSONObject.toJSONString(jsonObject) + " ]");
+                streamProxyService.stop(streamProxyDto.getApp(), streamProxyDto.getStream());
             }
         }
     }

+ 0 - 1
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java

@@ -120,7 +120,6 @@ public class PlayServiceImpl implements IPlayService {
                         zlmresTfulUtils.getSnap(streamUrl, 15, 1, path, fileName);
                     }
                 }
-                System.out.println(path);
             } catch (FileNotFoundException e) {
                 e.printStackTrace();
             }

+ 50 - 1
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java

@@ -1,12 +1,15 @@
 package com.genersoft.iot.vmp.vmanager.gb28181.play;
 
+import com.alibaba.fastjson.JSONArray;
 import com.genersoft.iot.vmp.common.StreamInfo;
+import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
 import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig;
 import com.genersoft.iot.vmp.gb28181.bean.Device;
 import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
 import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
 import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
+import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
 import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult;
 import com.genersoft.iot.vmp.service.IMediaService;
 import com.genersoft.iot.vmp.service.IPlayService;
@@ -31,6 +34,8 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
 import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
 import org.springframework.web.context.request.async.DeferredResult;
 
+import java.util.Enumeration;
+import java.util.Map;
 import java.util.UUID;
 
 import javax.sip.message.Response;
@@ -46,6 +51,9 @@ public class PlayController {
 	@Autowired
 	private SIPCommander cmder;
 
+	@Autowired
+	private VideoStreamSessionManager streamSession;
+
 	@Autowired
 	private IVideoManagerStorager storager;
 
@@ -227,6 +235,20 @@ public class PlayController {
             logger.debug("语音广播API调用");
         }
         Device device = storager.queryVideoDevice(deviceId);
+		DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>(3 * 1000L);
+        if (device == null) {
+			resultHolder.put(DeferredResultHolder.CALLBACK_CMD_BROADCAST + deviceId, result);
+			RequestMessage msg = new RequestMessage();
+			msg.setId(DeferredResultHolder.CALLBACK_CMD_BROADCAST + deviceId);
+			JSONObject json = new JSONObject();
+			json.put("DeviceID", deviceId);
+			json.put("CmdType", "Broadcast");
+			json.put("Result", "Failed");
+			json.put("Description", "Device 不存在");
+			msg.setData(json);
+			resultHolder.invokeResult(msg);
+			return result;
+		}
 		cmder.audioBroadcastCmd(device, event -> {
 			Response response = event.getResponse();
 			RequestMessage msg = new RequestMessage();
@@ -239,7 +261,7 @@ public class PlayController {
 			msg.setData(json);
 			resultHolder.invokeResult(msg);
 		});
-        DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>(3 * 1000L);
+
 		result.onTimeout(() -> {
 			logger.warn(String.format("语音广播操作超时, 设备未返回应答指令"));
 			RequestMessage msg = new RequestMessage();
@@ -256,5 +278,32 @@ public class PlayController {
 		return result;
 	}
 
+	@ApiOperation("获取所有的ssrc")
+	@GetMapping("/ssrc")
+	public WVPResult<JSONObject> getSSRC() {
+		if (logger.isDebugEnabled()) {
+			logger.debug("获取所有的ssrc");
+		}
+		JSONArray objects = new JSONArray();
+		for(Map.Entry<String, String> entry: streamSession.getSsrcMap().entrySet()) {
+			System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
+			JSONObject jsonObject = new JSONObject();
+			String[] keyArray = entry.getKey().split("_");
+			jsonObject.put("deviceId", keyArray[0]);
+			jsonObject.put("channelId", keyArray[1]);
+			jsonObject.put("ssrc", entry.getValue());
+			jsonObject.put("streamId", streamSession.getStreamIdMap().get(entry.getKey()));
+			objects.add(jsonObject);
+		}
+		WVPResult<JSONObject> result = new WVPResult<>();
+		result.setCode(0);
+		result.setMsg("success");
+		JSONObject jsonObject = new JSONObject();
+		jsonObject.put("data", objects);
+		jsonObject.put("count", objects.size());
+		result.setData(jsonObject);
+		return result;
+	}
+
 }
 

+ 2 - 1
web_src/index.html

@@ -4,10 +4,11 @@
     <meta charset="utf-8">
     <meta name="viewport" content="width=device-width,initial-scale=1.0">
     <title>国标28181</title>
-    <link rel="stylesheet" type="text/css" href="./static/css/font-awesome.min.css">
+    <link rel="stylesheet" type="text/css" href="./static/css/iconfont.css">
     <link rel="stylesheet" type="text/css" href="./static/css/login.css">
   </head>
   <body>
+    <script type="text/javascript" src="./static/js/jessibuca/index.js"></script>
     <script type="text/javascript" src="./static/js/EasyWasmPlayer.js"></script>
     <script type="text/javascript" src="./static/js/ZLMRTCClient.js"></script>
     <script type="text/javascript" src="//api.map.baidu.com/api?v=2.0&ak=rk73w8dv1rkE4UdZsataG68VarhYQzrx&s=1"></script>

+ 26 - 13
web_src/package-lock.json

@@ -1633,7 +1633,7 @@
       "dev": true,
       "requires": {
         "browserslist": "1.7.7",
-        "caniuse-db": "1.0.30001146",
+        "caniuse-db": "1.0.30001244",
         "lodash.memoize": "4.1.2",
         "lodash.uniq": "4.5.0"
       },
@@ -1644,16 +1644,16 @@
           "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=",
           "dev": true,
           "requires": {
-            "caniuse-db": "1.0.30001146",
+            "caniuse-db": "1.0.30001244",
             "electron-to-chromium": "1.3.742"
           }
         }
       }
     },
     "caniuse-db": {
-      "version": "1.0.30001146",
-      "resolved": "https://registry.npm.taobao.org/caniuse-db/download/caniuse-db-1.0.30001146.tgz?cache=0&sync_timestamp=1602133173904&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcaniuse-db%2Fdownload%2Fcaniuse-db-1.0.30001146.tgz",
-      "integrity": "sha1-poOLhbXEFSLrDXsetgeHFsBQ1q4=",
+      "version": "1.0.30001244",
+      "resolved": "https://registry.nlark.com/caniuse-db/download/caniuse-db-1.0.30001244.tgz?cache=0&sync_timestamp=1626154539434&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fcaniuse-db%2Fdownload%2Fcaniuse-db-1.0.30001244.tgz",
+      "integrity": "sha1-pt/zJHNkjfCwrg+Z2YeXrft89Fk=",
       "dev": true
     },
     "caniuse-lite": {
@@ -2241,7 +2241,7 @@
     },
     "css-loader": {
       "version": "0.28.11",
-      "resolved": "https://registry.npm.taobao.org/css-loader/download/css-loader-0.28.11.tgz",
+      "resolved": "https://registry.nlark.com/css-loader/download/css-loader-0.28.11.tgz?cache=0&sync_timestamp=1621865230592&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fcss-loader%2Fdownload%2Fcss-loader-0.28.11.tgz",
       "integrity": "sha1-w/mGSnAL4nEbtaJGKyOJsaOS2rc=",
       "dev": true,
       "requires": {
@@ -2426,7 +2426,7 @@
           "dev": true,
           "requires": {
             "browserslist": "1.7.7",
-            "caniuse-db": "1.0.30001146",
+            "caniuse-db": "1.0.30001244",
             "normalize-range": "0.1.2",
             "num2fraction": "1.2.2",
             "postcss": "5.2.18",
@@ -2439,7 +2439,7 @@
           "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=",
           "dev": true,
           "requires": {
-            "caniuse-db": "1.0.30001146",
+            "caniuse-db": "1.0.30001244",
             "electron-to-chromium": "1.3.742"
           }
         },
@@ -3548,6 +3548,7 @@
         "is-string": "1.0.6",
         "object-inspect": "1.10.3",
         "object-keys": "1.1.1",
+        "object.assign": "4.1.2",
         "string.prototype.trimend": "1.0.4",
         "string.prototype.trimstart": "1.0.4",
         "unbox-primitive": "1.0.1"
@@ -5463,9 +5464,9 @@
       }
     },
     "math-expression-evaluator": {
-      "version": "1.2.22",
-      "resolved": "https://registry.npm.taobao.org/math-expression-evaluator/download/math-expression-evaluator-1.2.22.tgz",
-      "integrity": "sha1-wU3LPYtNFQ5dzqnGjI2tgDCbDV4=",
+      "version": "1.3.8",
+      "resolved": "https://registry.nlark.com/math-expression-evaluator/download/math-expression-evaluator-1.3.8.tgz",
+      "integrity": "sha1-Mg2jsrwVEvT1D8MCCysc1cjp1Xc=",
       "dev": true
     },
     "md5.js": {
@@ -6161,6 +6162,18 @@
         "isobject": "3.0.1"
       }
     },
+    "object.assign": {
+      "version": "4.1.2",
+      "resolved": "https://registry.nlark.com/object.assign/download/object.assign-4.1.2.tgz",
+      "integrity": "sha1-DtVKNC7Os3s4/3brgxoOeIy2OUA=",
+      "dev": true,
+      "requires": {
+        "call-bind": "1.0.2",
+        "define-properties": "1.1.3",
+        "has-symbols": "1.0.2",
+        "object-keys": "1.1.1"
+      }
+    },
     "object.getownpropertydescriptors": {
       "version": "2.1.2",
       "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.2.tgz",
@@ -7544,7 +7557,7 @@
           "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=",
           "dev": true,
           "requires": {
-            "caniuse-db": "1.0.30001146",
+            "caniuse-db": "1.0.30001244",
             "electron-to-chromium": "1.3.742"
           }
         },
@@ -9198,7 +9211,7 @@
       "dev": true,
       "requires": {
         "balanced-match": "0.4.2",
-        "math-expression-evaluator": "1.2.22",
+        "math-expression-evaluator": "1.3.8",
         "reduce-function-call": "1.0.3"
       },
       "dependencies": {

+ 1 - 1
web_src/package.json

@@ -36,7 +36,7 @@
     "babel-preset-stage-2": "^6.22.0",
     "chalk": "^2.0.1",
     "copy-webpack-plugin": "^4.6.0",
-    "css-loader": "^0.28.0",
+    "css-loader": "^0.28.11",
     "extract-text-webpack-plugin": "^3.0.0",
     "file-loader": "^1.1.4",
     "friendly-errors-webpack-plugin": "^1.6.1",

+ 0 - 8
web_src/src/components/channelList.vue

@@ -154,7 +154,6 @@ export default {
         },
         currentChange: function (val) {
             var url = `/${this.$router.currentRoute.name}/${this.deviceId}/${this.parentChannelId}/${this.count}/${val}`
-            console.log(url)
             this.$router.push(url).then(() => {
                 this.initParam();
                 this.initData();
@@ -182,7 +181,6 @@ export default {
                         channelType: that.channelType
 					}
             }).then(function (res) {
-                    console.log(res);
                     that.total = res.data.total;
                     that.deviceChannelList = res.data.list;
                     // 防止出现表格错位
@@ -196,7 +194,6 @@ export default {
 
         //通知设备上传媒体流
         sendDevicePush: function (itemData) {
-            console.log(itemData);
             let deviceId = this.deviceId;
             this.isLoging = true;
             let channelId = itemData.channelId;
@@ -232,13 +229,11 @@ export default {
             this.$refs.devicePlayer.openDialog("record", deviceId, channelId, {date: format})
         },
         stopDevicePush: function (itemData) {
-            console.log(itemData)
             var that = this;
             this.$axios({
                 method: 'get',
                 url: '/api/play/stop/' + this.deviceId + "/" + itemData.channelId
             }).then(function (res) {
-                console.log(JSON.stringify(res));
                 that.initData();
             }).catch(function (error) {
               if (error.response.status === 402) { // 已经停止过
@@ -273,7 +268,6 @@ export default {
             })
         },
         changeSubchannel(itemData) {
-            console.log(this.$router.currentRoute)
             this.beforeUrl = this.$router.currentRoute.path;
 
             var url = `/${this.$router.currentRoute.name}/${this.$router.currentRoute.params.deviceId}/${itemData.channelId}/${this.$router.currentRoute.params.count}/1`
@@ -310,13 +304,11 @@ export default {
             });
         },
         search: function () {
-            console.log(this.searchSrt)
             this.currentPage = 1;
             this.total = 0;
             this.initData();
         },
         updateChannel: function (row) {
-            console.log(row)
             this.$axios({
                 method: 'post',
                 url: `/api/device/query/channel/update/${this.deviceId}`,

+ 4 - 2
web_src/src/components/dialog/devicePlayer.vue

@@ -151,7 +151,8 @@
 <script>
 // import player from '../dialog/rtcPlayer.vue'
 // import LivePlayer from '@liveqing/liveplayer'
-import player from '../dialog/easyPlayer.vue'
+// import player from '../dialog/easyPlayer.vue'
+import player from '../dialog/jessibuca.vue'
 export default {
     name: 'devicePlayer',
     props: {},
@@ -280,7 +281,8 @@ export default {
             console.log(12121212)
             console.log(baseZlmApi)
             // return `${baseZlmApi}/${streamInfo.app}/${streamInfo.streamId}.flv`;
-            return `http://${baseZlmApi}/${streamInfo.app}/${streamInfo.streamId}.flv`;
+            // return `http://${baseZlmApi}/${streamInfo.app}/${streamInfo.streamId}.flv`;
+            return streamInfo.ws_flv;
         },
         coverPlay: function () {
             var that = this;

+ 296 - 0
web_src/src/components/dialog/jessibuca.vue

@@ -0,0 +1,296 @@
+<template>
+  <div id="jessibuca" style="width: auto; height: auto">
+    <div id="container" ref="container" style="width: 100%; height: 10rem; background-color: #000" @dblclick="fullscreenSwich">
+      <div class="buttons-box" id="buttonsBox">
+        <div class="buttons-box-left">
+          <i v-if="!playing" class="iconfont icon-play jessibuca-btn" @click="playBtnClick"></i>
+          <i v-if="playing" class="iconfont icon-pause jessibuca-btn" @click="pause"></i>
+          <i class="iconfont icon-stop jessibuca-btn" @click="destroy"></i>
+          <i v-if="isNotMute" class="iconfont icon-audio-high jessibuca-btn" @click="jessibuca.mute()"></i>
+          <i v-if="!isNotMute" class="iconfont icon-audio-mute jessibuca-btn" @click="jessibuca.cancelMute()"></i>
+        </div>
+        <div class="buttons-box-right">
+          <span class="jessibuca-btn">{{kBps}} kb/s</span>
+<!--          <i class="iconfont icon-file-record1 jessibuca-btn"></i>-->
+<!--          <i class="iconfont icon-xiangqing2 jessibuca-btn" ></i>-->
+          <i class="iconfont icon-crop2 jessibuca-btn" @click="jessibuca.screenshot('截图','png',0.5)"></i>
+          <i class="iconfont icon-shuaxin11 jessibuca-btn" @click="playBtnClick"></i>
+          <i v-if="!fullscreen" class="iconfont icon-weibiaoti10 jessibuca-btn" @click="fullscreenSwich"></i>
+          <i v-if="fullscreen" class="iconfont icon-weibiaoti11 jessibuca-btn" @click="fullscreenSwich"></i>
+        </div>
+    </div>
+
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+    name: 'jessibuca',
+    data() {
+        return {
+          jessibuca: null,
+          playing: false,
+          isNotMute: false,
+          quieting: false,
+          fullscreen: false,
+          loaded: false, // mute
+          speed: 0,
+          performance: "", // 工作情况
+          kBps: 0,
+          btnDom: null,
+          videoInfo: null,
+          volume: 1,
+          rotate: 0,
+          vod: true, // 点播
+          forceNoOffscreen: false,
+        };
+    },
+    props: ['videoUrl', 'error', 'hasaudio', 'height'],
+    mounted () {
+      window.onerror = (msg) => {
+        // console.error(msg)
+      };
+      let paramUrl = decodeURIComponent(this.$route.params.url)
+       this.$nextTick(() =>{
+         let dom = document.getElementById("container");
+         dom.style.height = (9/16 ) * dom.clientWidth + "px"
+          if (typeof (this.videoUrl) == "undefined") {
+            this.videoUrl = paramUrl;
+          }
+         this.btnDom = document.getElementById("buttonsBox");
+          console.log("初始化时的地址为: " + this.videoUrl)
+         this.play(this.videoUrl)
+        })
+    },
+    watch:{
+        videoUrl(newData, oldData){
+            this.play(newData)
+        },
+        immediate:true
+    },
+    methods: {
+        create(){
+          let options =  {};
+          console.log(this.$refs.container)
+
+          this.jessibuca = new window.Jessibuca(Object.assign(
+            {
+              container: this.$refs.container,
+              videoBuffer: 0.5, // 最大缓冲时长,单位秒
+              isResize: true,
+              decoder: "./static/js/jessibuca/index.js",
+              // text: "WVP-PRO",
+              // background: "bg.jpg",
+              loadingText: "加载中",
+              hasAudio: this.hasAudio,
+              debug: false,
+              supportDblclickFullscreen: false, // 是否支持屏幕的双击事件,触发全屏,取消全屏事件。
+              operateBtns: {
+                fullscreen: false,
+                screenshot: false,
+                play: false,
+                audio: false,
+              },
+              record: "record",
+              vod: this.vod,
+              forceNoOffscreen: this.forceNoOffscreen,
+              isNotMute: this.isNotMute,
+            },
+            options
+          ));
+
+          let _this = this;
+          this.jessibuca.on("load", function () {
+            console.log("on load init");
+          });
+
+          this.jessibuca.on("log", function (msg) {
+            console.log("on log", msg);
+          });
+          this.jessibuca.on("record", function (msg) {
+            console.log("on record:", msg);
+          });
+          this.jessibuca.on("pause", function () {
+            _this.playing = false;
+          });
+          this.jessibuca.on("play", function () {
+            _this.playing = true;
+          });
+          this.jessibuca.on("fullscreen", function (msg) {
+            console.log("on fullscreen", msg);
+            _this.fullscreen = msg
+          });
+
+          this.jessibuca.on("mute", function (msg) {
+            console.log("on mute", msg);
+            _this.isNotMute = !msg;
+          });
+          this.jessibuca.on("audioInfo", function (msg) {
+            // console.log("audioInfo", msg);
+          });
+
+          this.jessibuca.on("videoInfo", function (msg) {
+            this.videoInfo = msg;
+            // console.log("videoInfo", msg);
+
+          });
+
+          this.jessibuca.on("bps", function (bps) {
+            // console.log('bps', bps);
+
+          });
+          let _ts = 0;
+          this.jessibuca.on("timeUpdate", function (ts) {
+            // console.log('timeUpdate,old,new,timestamp', _ts, ts, ts - _ts);
+            _ts = ts;
+          });
+
+          this.jessibuca.on("videoInfo", function (info) {
+            console.log("videoInfo", info);
+          });
+
+          this.jessibuca.on("error", function (error) {
+            console.log("error", error);
+          });
+
+          this.jessibuca.on("timeout", function () {
+            console.log("timeout");
+          });
+
+          this.jessibuca.on('start', function () {
+            console.log('start');
+          })
+
+          this.jessibuca.on("performance", function (performance) {
+            let show = "卡顿";
+            if (performance === 2) {
+              show = "非常流畅";
+            } else if (performance === 1) {
+              show = "流畅";
+            }
+            _this.performance = show;
+          });
+          this.jessibuca.on('buffer', function (buffer) {
+            // console.log('buffer', buffer);
+          })
+
+          this.jessibuca.on('stats', function (stats) {
+            // console.log('stats', stats);
+          })
+
+          this.jessibuca.on('kBps', function (kBps) {
+            _this.kBps = Math.round(kBps);
+          });
+
+          // 显示时间戳 PTS
+          this.jessibuca.on('videoFrame', function () {
+
+          })
+
+          //
+          this.jessibuca.on('metadata', function () {
+
+          });
+        },
+        playBtnClick: function (event){
+          this.play(this.videoUrl)
+        },
+        play: function (url) {
+          console.log(url)
+            if (this.jessibuca) {
+              this.destroy();
+            }
+            this.create();
+            this.jessibuca.on("play", () => {
+              this.playing = true;
+              this.loaded = true;
+              this.quieting = this.jessibuca.quieting;
+            });
+            if (this.jessibuca.hasLoaded()) {
+              this.jessibuca.play(url);
+            } else {
+              this.jessibuca.on("load", () => {
+                console.log("load 播放")
+                this.jessibuca.play(url);
+              });
+            }
+        },
+        pause: function () {
+          if (this.jessibuca) {
+            this.jessibuca.pause();
+          }
+          this.playing = false;
+          this.err = "";
+          this.performance = "";
+        },
+        destroy: function () {
+          if (this.jessibuca) {
+            this.jessibuca.destroy();
+          }
+          if (document.getElementById("buttonsBox") == null) {
+            document.getElementById("container").appendChild(this.btnDom)
+          }
+          this.jessibuca = null;
+          this.playing = false;
+          this.err = "";
+          this.performance = "";
+
+        },
+        eventcallbacK: function(type, message) {
+            // console.log("player 事件回调")
+            // console.log(type)
+            // console.log(message)
+        },
+        fullscreenSwich: function (){
+            let isFull = this.isFullscreen()
+            this.jessibuca.setFullscreen(!isFull)
+            this.fullscreen = !isFull;
+        },
+        isFullscreen: function (){
+          return document.fullscreenElement ||
+            document.msFullscreenElement  ||
+            document.mozFullScreenElement ||
+            document.webkitFullscreenElement || false;
+        }
+    },
+    destroyed() {
+      if (this.jessibuca) {
+        this.jessibuca.destroy();
+      }
+      this.playing = false;
+      this.loaded = false;
+      this.performance = "";
+    },
+}
+</script>
+
+<style>
+  .buttons-box{
+    width: 100%;
+    height: 28px;
+    background-color: rgba(43, 51, 63, 0.7);
+    position: absolute;
+    display: -webkit-box;
+    display: -ms-flexbox;
+    display: flex;
+    left: 0;
+    bottom: 0;
+    user-select: none;
+    z-index: 10;
+  }
+  .jessibuca-btn{
+    width: 20px;
+    color: rgb(255, 255, 255);
+    line-height: 27px;
+    margin: 0px 10px;
+    padding: 0px 2px;
+    cursor: pointer;
+    text-align: center;
+    font-size: 0.8rem !important;
+  }
+  .buttons-box-right {
+    position: absolute;
+    right: 0;
+  }
+</style>

+ 1 - 1
web_src/src/router/index.js

@@ -15,7 +15,7 @@ import web from '../components/setting/Web.vue'
 import sip from '../components/setting/Sip.vue'
 import media from '../components/setting/Media.vue'
 
-import wasmPlayer from '../components/dialog/easyPlayer.vue'
+import wasmPlayer from '../components/dialog/jessibuca.vue'
 import rtcPlayer from '../components/dialog/rtcPlayer.vue'
 
 const originalPush = VueRouter.prototype.push

Разница между файлами не показана из-за своего большого размера
+ 0 - 4
web_src/static/css/font-awesome.min.css


Разница между файлами не показана из-за своего большого размера
+ 1655 - 0
web_src/static/css/iconfont.css


BIN
web_src/static/css/iconfont.woff2


+ 0 - 396
web_src/static/css/login.css

@@ -1,396 +0,0 @@
-
-
-
-
-/*//////////////////////////////////////////////////////////////////
-[ FONT ]*/
-
-@font-face {
-  font-family: Poppins-Regular;
-  src: url('../fonts/poppins/Poppins-Regular.ttf');
-}
-
-@font-face {
-  font-family: Poppins-Medium;
-  src: url('../fonts/poppins/Poppins-Medium.ttf');
-}
-
-@font-face {
-  font-family: Poppins-Bold;
-  src: url('../fonts/poppins/Poppins-Bold.ttf');
-}
-
-@font-face {
-  font-family: Poppins-SemiBold;
-  src: url('../fonts/poppins/Poppins-SemiBold.ttf');
-}
-
-.limiter {
-  width: 100%;
-  margin: 0 auto;
-  font-family: Poppins-Regular, sans-serif;
-
-}
-
-.container-login100 {
-  width: 100%;
-  min-height: 100vh;
-  display: -webkit-box;
-  display: -webkit-flex;
-  display: -moz-box;
-  display: -ms-flexbox;
-  display: flex;
-  flex-wrap: wrap;
-  justify-content: center;
-  align-items: center;
-  background: #f2f2f2;
-}
-
-.wrap-login100 {
-  background: #fff;
-  border-radius: 10px;
-  overflow: hidden;
-  padding: 77px 55px 33px 55px;
-
-  box-shadow: 0 5px 10px 0px rgba(0, 0, 0, 0.1);
-  -moz-box-shadow: 0 5px 10px 0px rgba(0, 0, 0, 0.1);
-  -webkit-box-shadow: 0 5px 10px 0px rgba(0, 0, 0, 0.1);
-  -o-box-shadow: 0 5px 10px 0px rgba(0, 0, 0, 0.1);
-  -ms-box-shadow: 0 5px 10px 0px rgba(0, 0, 0, 0.1);
-}
-
-
-/*------------------------------------------------------------------
-[ Form ]*/
-
-.login100-form {
-  width: 100%;
-}
-
-.login100-form-title {
-  display: block;
-  font-family: Poppins-Bold;
-  font-size: 30px;
-  color: #333333;
-  line-height: 1.2;
-  text-align: center;
-
-}
-.login100-form-title i {
-  font-size: 60px;
-}
-
-/*------------------------------------------------------------------
-[ Input ]*/
-
-.wrap-input100 {
-  width: 100%;
-  position: relative;
-  border-bottom: 2px solid #adadad;
-  margin-bottom: 37px;
-}
-
-.input100 {
-  font-family: Poppins-Regular;
-  font-size: 15px;
-  color: #555555;
-  line-height: 1.2;
-
-  display: block;
-  width: 100%;
-  height: 45px;
-  background: transparent;
-  padding: 0 5px;
-  outline: none;
-  border: none;
-}
-.input100::-webkit-input-placeholder { color: #adadad;}
-.input100:-moz-placeholder { color: #adadad;}
-.input100::-moz-placeholder { color: #adadad;}
-.input100:-ms-input-placeholder { color: #adadad;}
-
-/*---------------------------------------------*/
-.focus-input100 {
-  position: absolute;
-  display: block;
-  width: 100%;
-  height: 100%;
-  top: 0;
-  left: 0;
-  pointer-events: none;
-  color:transparent;
-}
-
-.focus-input100::before {
-  content: "";
-  display: block;
-  position: absolute;
-  bottom: -2px;
-  left: 0;
-  width: 0;
-  height: 2px;
-
-  -webkit-transition: all 0.4s;
-  -o-transition: all 0.4s;
-  -moz-transition: all 0.4s;
-  transition: all 0.4s;
-
-  background: #6a7dfe;
-  background: -webkit-linear-gradient(left, #21d4fd, #b721ff);
-  background: -o-linear-gradient(left, #21d4fd, #b721ff);
-  background: -moz-linear-gradient(left, #21d4fd, #b721ff);
-  background: linear-gradient(left, #21d4fd, #b721ff);
-}
-
-.focus-input100::after {
-  font-family: Poppins-Regular;
-  font-size: 15px;
-  color: #999999;
-  line-height: 1.2;
-
-  content: attr(data-placeholder);
-  display: block;
-  width: 100%;
-  position: absolute;
-  top: 16px;
-  left: 0px;
-  padding-left: 5px;
-
-  -webkit-transition: all 0.4s;
-  -o-transition: all 0.4s;
-  -moz-transition: all 0.4s;
-  transition: all 0.4s;
-}
-
-.input100:focus + .focus-input100::after {
-  top: -15px;
-}
-
-.input100:focus + .focus-input100::before {
-  width: 100%;
-}
-
-.has-val.input100 + .focus-input100::after {
-  top: -15px;
-}
-
-.has-val.input100 + .focus-input100::before {
-  width: 100%;
-}
-
-/*---------------------------------------------*/
-.btn-show-pass {
-  font-size: 15px;
-  color: #999999;
-
-  display: -webkit-box;
-  display: -webkit-flex;
-  display: -moz-box;
-  display: -ms-flexbox;
-  display: flex;
-  align-items: center;
-  position: absolute;
-  height: 100%;
-  top: 0;
-  right: 0;
-  padding-right: 5px;
-  cursor: pointer;
-  -webkit-transition: all 0.4s;
-  -o-transition: all 0.4s;
-  -moz-transition: all 0.4s;
-  transition: all 0.4s;
-}
-
-.btn-show-pass:hover {
-  color: #6a7dfe;
-  color: -webkit-linear-gradient(left, #21d4fd, #b721ff);
-  color: -o-linear-gradient(left, #21d4fd, #b721ff);
-  color: -moz-linear-gradient(left, #21d4fd, #b721ff);
-  color: linear-gradient(left, #21d4fd, #b721ff);
-}
-
-.btn-show-pass.active {
-  color: #6a7dfe;
-  color: -webkit-linear-gradient(left, #21d4fd, #b721ff);
-  color: -o-linear-gradient(left, #21d4fd, #b721ff);
-  color: -moz-linear-gradient(left, #21d4fd, #b721ff);
-  color: linear-gradient(left, #21d4fd, #b721ff);
-}
-
-
-
-/*------------------------------------------------------------------
-[ Button ]*/
-.container-login100-form-btn {
-  display: -webkit-box;
-  display: -webkit-flex;
-  display: -moz-box;
-  display: -ms-flexbox;
-  display: flex;
-  flex-wrap: wrap;
-  justify-content: center;
-  padding-top: 13px;
-}
-
-.wrap-login100-form-btn {
-  width: 100%;
-  display: block;
-  position: relative;
-  z-index: 1;
-  border-radius: 25px;
-  overflow: hidden;
-  margin: 0 auto;
-}
-
-.login100-form-bgbtn {
-  position: absolute;
-  z-index: -1;
-  width: 300%;
-  height: 100%;
-  background: #a64bf4;
-  background: -webkit-linear-gradient(right, #21d4fd, #b721ff, #21d4fd, #b721ff);
-  background: -o-linear-gradient(right, #21d4fd, #b721ff, #21d4fd, #b721ff);
-  background: -moz-linear-gradient(right, #21d4fd, #b721ff, #21d4fd, #b721ff);
-  background: linear-gradient(right, #21d4fd, #b721ff, #21d4fd, #b721ff);
-  top: 0;
-  left: -100%;
-
-  -webkit-transition: all 0.4s;
-  -o-transition: all 0.4s;
-  -moz-transition: all 0.4s;
-  transition: all 0.4s;
-}
-
-.login100-form-btn {
-  font-family: Poppins-Medium;
-  font-size: 15px;
-  color: #fff;
-  line-height: 1.2;
-  text-transform: uppercase;
-
-  display: -webkit-box;
-  display: -webkit-flex;
-  display: -moz-box;
-  display: -ms-flexbox;
-  display: flex;
-  justify-content: center;
-  align-items: center;
-  padding: 0 20px;
-  width: 100%;
-  height: 50px;
-  outline: none !important;
-  border: none;
-  background: transparent;
-}
-
-.login100-form-btn:hover {
-  cursor: pointer;
-}
-
-.wrap-login100-form-btn:hover .login100-form-bgbtn {
-  left: 0;
-}
-
-
-/*------------------------------------------------------------------
-[ Responsive ]*/
-
-@media (max-width: 576px) {
-  .wrap-login100 {
-    padding: 77px 15px 33px 15px;
-  }
-}
-
-
-
-/*------------------------------------------------------------------
-[ Alert validate ]*/
-
-.validate-input {
-  position: relative;
-}
-
-.alert-validate::before {
-  content: attr(data-validate);
-  position: absolute;
-  max-width: 70%;
-  background-color: #fff;
-  border: 1px solid #c80000;
-  border-radius: 2px;
-  padding: 4px 25px 4px 10px;
-  top: 50%;
-  -webkit-transform: translateY(-50%);
-  -moz-transform: translateY(-50%);
-  -ms-transform: translateY(-50%);
-  -o-transform: translateY(-50%);
-  transform: translateY(-50%);
-  right: 0px;
-  pointer-events: none;
-
-  font-family: Poppins-Regular;
-  color: #c80000;
-  font-size: 13px;
-  line-height: 1.4;
-  text-align: left;
-
-  visibility: hidden;
-  opacity: 0;
-
-  -webkit-transition: opacity 0.4s;
-  -o-transition: opacity 0.4s;
-  -moz-transition: opacity 0.4s;
-  transition: opacity 0.4s;
-}
-
-.alert-validate::after {
-  content: "\f06a";
-  font-family: FontAwesome;
-  font-size: 16px;
-  color: #c80000;
-
-  display: block;
-  position: absolute;
-  background-color: #fff;
-  top: 50%;
-  -webkit-transform: translateY(-50%);
-  -moz-transform: translateY(-50%);
-  -ms-transform: translateY(-50%);
-  -o-transform: translateY(-50%);
-  transform: translateY(-50%);
-  right: 5px;
-}
-
-.alert-validate:hover:before {
-  visibility: visible;
-  opacity: 1;
-}
-
-@media (max-width: 992px) {
-  .alert-validate::before {
-    visibility: visible;
-    opacity: 1;
-  }
-}
-
-/** util **/
-.p-b-26 {padding-bottom: 26px;}
-.p-b-48 {padding-bottom: 48px;}
-.p-t-115 {padding-top: 115px;}
-
-/**font**/
-/* .zmdi {
-  display: inline-block;
-  font: normal normal normal 14px/1 'Material-Design-Iconic-Font';
-      font-size: 14px;
-  font-size: inherit;
-  text-rendering: auto;
-  -webkit-font-smoothing: antialiased;
-  -moz-osx-font-smoothing: grayscale;
-}
-.zmdi-font::before {
-  content: '\f16a';
-}
-.login100-form-title i {
-  font-size: 60px;
-} */
-

Разница между файлами не показана из-за своего большого размера
+ 1 - 0
web_src/static/js/jessibuca/ff.js


BIN
web_src/static/js/jessibuca/ff.wasm


Разница между файлами не показана из-за своего большого размера
+ 1 - 0
web_src/static/js/jessibuca/ff.worker.js


Разница между файлами не показана из-за своего большого размера
+ 4602 - 0
web_src/static/js/jessibuca/index.js


BIN
web_src/static/js/jessibuca/logo.png