Browse Source

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

pull/129/head
64850858 3 years ago
parent
commit
e48ef997c0
  1. 48
      sql/mysql.sql
  2. 2
      src/main/java/com/genersoft/iot/vmp/VManageBootstrap.java
  3. 2
      src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java
  4. 2
      src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java
  5. 12
      src/main/java/com/genersoft/iot/vmp/gb28181/session/VideoStreamSessionManager.java
  6. 6
      src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java
  7. 5
      src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java
  8. 1
      src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
  9. 51
      src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java
  10. 3
      web_src/index.html
  11. 39
      web_src/package-lock.json
  12. 2
      web_src/package.json
  13. 8
      web_src/src/components/channelList.vue
  14. 6
      web_src/src/components/dialog/devicePlayer.vue
  15. 296
      web_src/src/components/dialog/jessibuca.vue
  16. 2
      web_src/src/router/index.js
  17. 4
      web_src/static/css/font-awesome.min.css
  18. 1655
      web_src/static/css/iconfont.css
  19. BIN
      web_src/static/css/iconfont.woff2
  20. 396
      web_src/static/css/login.css
  21. 1
      web_src/static/js/jessibuca/ff.js
  22. BIN
      web_src/static/js/jessibuca/ff.wasm
  23. 1
      web_src/static/js/jessibuca/ff.worker.js
  24. 4602
      web_src/static/js/jessibuca/index.js
  25. BIN
      web_src/static/js/jessibuca/logo.png

48
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
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
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";

2
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
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;
}
}

6
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java

@ -34,6 +34,7 @@ public class ZLMRTPServerFactory {
if (currentStreams == null) {
currentStreams = new HashMap<>();
JSONObject jsonObject = zlmresTfulUtils.listRtpServer();
if (jsonObject != null) {
JSONArray data = jsonObject.getJSONArray("data");
if (data != null) {
for (int i = 0; i < data.size(); i++) {
@ -42,6 +43,7 @@ public class ZLMRTPServerFactory {
}
}
}
}
// 已经在推流
if (currentStreams.get(streamId) != null) {
Map<String, Object> closeRtpServerParam = new HashMap<>();
@ -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;
}

5
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());
}
}
}

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();
}

51
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;
}
}

3
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>

39
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": {

2
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",

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}`,

6
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
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>

2
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

4
web_src/static/css/font-awesome.min.css

File diff suppressed because one or more lines are too long

1655
web_src/static/css/iconfont.css

File diff suppressed because it is too large

BIN
web_src/static/css/iconfont.woff2

Binary file not shown.

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
web_src/static/js/jessibuca/ff.js

File diff suppressed because one or more lines are too long

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

Binary file not shown.

1
web_src/static/js/jessibuca/ff.worker.js

@ -0,0 +1 @@
var initializedJS=false;var Module={};function threadPrintErr(){var text=Array.prototype.slice.call(arguments).join(" ");console.error(text)}function threadAlert(){var text=Array.prototype.slice.call(arguments).join(" ");postMessage({cmd:"alert",text:text,threadId:Module["_pthread_self"]()})}var err=threadPrintErr;this.alert=threadAlert;Module["instantiateWasm"]=function(info,receiveInstance){var instance=new WebAssembly.Instance(Module["wasmModule"],info);Module["wasmModule"]=null;receiveInstance(instance);return instance.exports};function moduleLoaded(){}this.onmessage=function(e){try{if(e.data.cmd==="load"){Module["wasmModule"]=e.data.wasmModule;Module["wasmMemory"]=e.data.wasmMemory;Module["buffer"]=Module["wasmMemory"].buffer;Module["ENVIRONMENT_IS_PTHREAD"]=true;if(typeof e.data.urlOrBlob==="string"){importScripts(e.data.urlOrBlob)}else{var objectUrl=URL.createObjectURL(e.data.urlOrBlob);importScripts(objectUrl);URL.revokeObjectURL(objectUrl)}moduleLoaded()}else if(e.data.cmd==="objectTransfer"){Module["PThread"].receiveObjectTransfer(e.data)}else if(e.data.cmd==="run"){Module["__performance_now_clock_drift"]=performance.now()-e.data.time;Module["__emscripten_thread_init"](e.data.threadInfoStruct,0,0);var max=e.data.stackBase;var top=e.data.stackBase+e.data.stackSize;Module["establishStackSpace"](top,max);Module["_emscripten_tls_init"]();Module["PThread"].receiveObjectTransfer(e.data);Module["PThread"].setThreadStatus(Module["_pthread_self"](),1);if(!initializedJS){Module["___embind_register_native_and_builtin_types"]();initializedJS=true}try{var result=Module["invokeEntryPoint"](e.data.start_routine,e.data.arg);if(!Module["getNoExitRuntime"]())Module["PThread"].threadExit(result)}catch(ex){if(ex==="Canceled!"){Module["PThread"].threadCancel()}else if(ex!="unwind"){if(ex instanceof Module["ExitStatus"]){if(Module["getNoExitRuntime"]()){}else{Module["PThread"].threadExit(ex.status)}}else{Module["PThread"].threadExit(-2);throw ex}}}}else if(e.data.cmd==="cancel"){if(Module["_pthread_self"]()){Module["PThread"].threadCancel()}}else if(e.data.target==="setimmediate"){}else if(e.data.cmd==="processThreadQueue"){if(Module["_pthread_self"]()){Module["_emscripten_current_thread_process_queued_calls"]()}}else{err("worker.js received unknown command "+e.data.cmd);err(e.data)}}catch(ex){err("worker.js onmessage() captured an uncaught exception: "+ex);if(ex&&ex.stack)err(ex.stack);throw ex}};

4602
web_src/static/js/jessibuca/index.js

File diff suppressed because one or more lines are too long

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Loading…
Cancel
Save