This commit is contained in:
weipengfei 2023-12-08 18:42:55 +08:00
parent 7a72253f8b
commit 4bcecd3c49
33 changed files with 2346 additions and 6651 deletions

View File

@ -10,6 +10,7 @@
font-size: 16px;
}
</style>
<script src="/public/jessibuca.js"></script>
<script type="text/javascript">
window._AMapSecurityConfig = {
securityJsCode:'e8b6cb44e8e431d68052c8e10db99264',

350
package-lock.json generated
View File

@ -13,8 +13,12 @@
"axios": "^1.6.2",
"echarts": "^5.4.3",
"echarts-gl": "^2.0.9",
"flv-h265.js": "^1.7.4",
"flv.js": "^1.6.2",
"hls.js": "^1.4.13",
"mitt": "^3.0.1",
"pinia": "^2.1.7",
"video.js": "^8.6.1",
"vue": "^3.3.8",
"vue-router": "^4.2.5"
},
@ -617,6 +621,92 @@
"win32"
]
},
"node_modules/@videojs/http-streaming": {
"version": "3.7.0",
"resolved": "https://registry.npmmirror.com/@videojs/http-streaming/-/http-streaming-3.7.0.tgz",
"integrity": "sha512-5uLFKBL8CvD56dxxJyuxqB5CY0tdoa4SE9KbXakeiAy6iFBUEPvTr2YGLKEWvQ8Lojs1wl+FQndLdv+GO7t9Fw==",
"dependencies": {
"@babel/runtime": "^7.12.5",
"@videojs/vhs-utils": "4.0.0",
"aes-decrypter": "4.0.1",
"global": "^4.4.0",
"m3u8-parser": "^7.1.0",
"mpd-parser": "^1.2.2",
"mux.js": "7.0.1",
"video.js": "^7 || ^8"
},
"engines": {
"node": ">=8",
"npm": ">=5"
},
"peerDependencies": {
"video.js": "^7 || ^8"
}
},
"node_modules/@videojs/http-streaming/node_modules/m3u8-parser": {
"version": "7.1.0",
"resolved": "https://registry.npmmirror.com/m3u8-parser/-/m3u8-parser-7.1.0.tgz",
"integrity": "sha512-7N+pk79EH4oLKPEYdgRXgAsKDyA/VCo0qCHlUwacttQA0WqsjZQYmNfywMvjlY9MpEBVZEt0jKFd73Kv15EBYQ==",
"dependencies": {
"@babel/runtime": "^7.12.5",
"@videojs/vhs-utils": "^3.0.5",
"global": "^4.4.0"
}
},
"node_modules/@videojs/http-streaming/node_modules/m3u8-parser/node_modules/@videojs/vhs-utils": {
"version": "3.0.5",
"resolved": "https://registry.npmmirror.com/@videojs/vhs-utils/-/vhs-utils-3.0.5.tgz",
"integrity": "sha512-PKVgdo8/GReqdx512F+ombhS+Bzogiofy1LgAj4tN8PfdBx3HSS7V5WfJotKTqtOWGwVfSWsrYN/t09/DSryrw==",
"dependencies": {
"@babel/runtime": "^7.12.5",
"global": "^4.4.0",
"url-toolkit": "^2.2.1"
},
"engines": {
"node": ">=8",
"npm": ">=5"
}
},
"node_modules/@videojs/http-streaming/node_modules/mux.js": {
"version": "7.0.1",
"resolved": "https://registry.npmmirror.com/mux.js/-/mux.js-7.0.1.tgz",
"integrity": "sha512-Omz79uHqYpMP1V80JlvEdCiOW1hiw4mBvDh9gaZEpxvB+7WYb2soZSzfuSRrK2Kh9Pm6eugQNrIpY/Bnyhk4hw==",
"dependencies": {
"@babel/runtime": "^7.11.2",
"global": "^4.4.0"
},
"bin": {
"muxjs-transmux": "bin/transmux.js"
},
"engines": {
"node": ">=8",
"npm": ">=5"
}
},
"node_modules/@videojs/vhs-utils": {
"version": "4.0.0",
"resolved": "https://registry.npmmirror.com/@videojs/vhs-utils/-/vhs-utils-4.0.0.tgz",
"integrity": "sha512-xJp7Yd4jMLwje2vHCUmi8MOUU76nxiwII3z4Eg3Ucb+6rrkFVGosrXlMgGnaLjq724j3wzNElRZ71D/CKrTtxg==",
"dependencies": {
"@babel/runtime": "^7.12.5",
"global": "^4.4.0",
"url-toolkit": "^2.2.1"
},
"engines": {
"node": ">=8",
"npm": ">=5"
}
},
"node_modules/@videojs/xhr": {
"version": "2.6.0",
"resolved": "https://registry.npmmirror.com/@videojs/xhr/-/xhr-2.6.0.tgz",
"integrity": "sha512-7J361GiN1tXpm+gd0xz2QWr3xNWBE+rytvo8J3KuggFaLg+U37gZQ2BuPLcnkfGffy2e+ozY70RHC8jt7zjA6Q==",
"dependencies": {
"@babel/runtime": "^7.5.5",
"global": "~4.4.0",
"is-function": "^1.0.1"
}
},
"node_modules/@vitejs/plugin-vue": {
"version": "4.5.0",
"resolved": "https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-4.5.0.tgz",
@ -737,6 +827,39 @@
"resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.3.8.tgz",
"integrity": "sha512-8PGwybFwM4x8pcfgqEQFy70NaQxASvOC5DJwLQfpArw1UDfUXrJkdxD3BhVTMS+0Lef/TU7YO0Jvr0jJY8T+mw=="
},
"node_modules/@xmldom/xmldom": {
"version": "0.8.10",
"resolved": "https://registry.npmmirror.com/@xmldom/xmldom/-/xmldom-0.8.10.tgz",
"integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==",
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/aes-decrypter": {
"version": "4.0.1",
"resolved": "https://registry.npmmirror.com/aes-decrypter/-/aes-decrypter-4.0.1.tgz",
"integrity": "sha512-H1nh/P9VZXUf17AA5NQfJML88CFjVBDuGkp5zDHa7oEhYN9TTpNLJknRY1ie0iSKWlDf6JRnJKaZVDSQdPy6Cg==",
"dependencies": {
"@babel/runtime": "^7.12.5",
"@videojs/vhs-utils": "^3.0.5",
"global": "^4.4.0",
"pkcs7": "^1.0.4"
}
},
"node_modules/aes-decrypter/node_modules/@videojs/vhs-utils": {
"version": "3.0.5",
"resolved": "https://registry.npmmirror.com/@videojs/vhs-utils/-/vhs-utils-3.0.5.tgz",
"integrity": "sha512-PKVgdo8/GReqdx512F+ombhS+Bzogiofy1LgAj4tN8PfdBx3HSS7V5WfJotKTqtOWGwVfSWsrYN/t09/DSryrw==",
"dependencies": {
"@babel/runtime": "^7.12.5",
"global": "^4.4.0",
"url-toolkit": "^2.2.1"
},
"engines": {
"node": ">=8",
"npm": ">=5"
}
},
"node_modules/anymatch": {
"version": "3.1.3",
"resolved": "https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz",
@ -836,6 +959,11 @@
"node": ">=0.4.0"
}
},
"node_modules/dom-walk": {
"version": "0.1.2",
"resolved": "https://registry.npmmirror.com/dom-walk/-/dom-walk-0.1.2.tgz",
"integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w=="
},
"node_modules/echarts": {
"version": "5.4.3",
"resolved": "https://registry.npmmirror.com/echarts/-/echarts-5.4.3.tgz",
@ -857,6 +985,11 @@
"echarts": "^5.1.2"
}
},
"node_modules/es6-promise": {
"version": "4.2.8",
"resolved": "https://registry.npmmirror.com/es6-promise/-/es6-promise-4.2.8.tgz",
"integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w=="
},
"node_modules/esbuild": {
"version": "0.19.7",
"resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.19.7.tgz",
@ -911,6 +1044,24 @@
"node": ">=8"
}
},
"node_modules/flv-h265.js": {
"version": "1.7.4",
"resolved": "https://registry.npmmirror.com/flv-h265.js/-/flv-h265.js-1.7.4.tgz",
"integrity": "sha512-iPEi4kK+vvLqgq9yQDh6AMcHHM4GyENKXtBLfiokldraRkaRilg36JduAGbQjSZBsBSqNy0DNJM3UVyXYq6ZLw==",
"dependencies": {
"es6-promise": "^4.2.8",
"webworkify-webpack": "^2.1.5"
}
},
"node_modules/flv.js": {
"version": "1.6.2",
"resolved": "https://registry.npmmirror.com/flv.js/-/flv.js-1.6.2.tgz",
"integrity": "sha512-xre4gUbX1MPtgQRKj2pxJENp/RnaHaxYvy3YToVVCrSmAWUu85b9mug6pTXF6zakUjNP2lFWZ1rkSX7gxhB/2A==",
"dependencies": {
"es6-promise": "^4.2.8",
"webworkify-webpack": "^2.1.5"
}
},
"node_modules/follow-redirects": {
"version": "1.15.3",
"resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.3.tgz",
@ -963,12 +1114,31 @@
"node": ">= 6"
}
},
"node_modules/global": {
"version": "4.4.0",
"resolved": "https://registry.npmmirror.com/global/-/global-4.4.0.tgz",
"integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==",
"dependencies": {
"min-document": "^2.19.0",
"process": "^0.11.10"
}
},
"node_modules/hls.js": {
"version": "1.4.13",
"resolved": "https://registry.npmmirror.com/hls.js/-/hls.js-1.4.13.tgz",
"integrity": "sha512-7QGXXS0u/vu0mQqNPRBKR31ru4BLVabVSOnGaXoQZhMRNbfCNTPNJk9ToC0pzvRUfLK/71QjhQO2wdHrgbKeKg=="
},
"node_modules/immutable": {
"version": "4.3.4",
"resolved": "https://registry.npmmirror.com/immutable/-/immutable-4.3.4.tgz",
"integrity": "sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==",
"dev": true
},
"node_modules/individual": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/individual/-/individual-2.0.0.tgz",
"integrity": "sha512-pWt8hBCqJsUWI/HtcfWod7+N9SgAqyPEaF7JQjwzjn5vGrpg6aQ5qeAFQ7dx//UH4J1O+7xqew+gCeeFt6xN/g=="
},
"node_modules/is-binary-path": {
"version": "2.1.0",
"resolved": "https://registry.npmmirror.com/is-binary-path/-/is-binary-path-2.1.0.tgz",
@ -990,6 +1160,11 @@
"node": ">=0.10.0"
}
},
"node_modules/is-function": {
"version": "1.0.2",
"resolved": "https://registry.npmmirror.com/is-function/-/is-function-1.0.2.tgz",
"integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ=="
},
"node_modules/is-glob": {
"version": "4.0.3",
"resolved": "https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz",
@ -1011,6 +1186,35 @@
"node": ">=0.12.0"
}
},
"node_modules/keycode": {
"version": "2.2.0",
"resolved": "https://registry.npmmirror.com/keycode/-/keycode-2.2.0.tgz",
"integrity": "sha512-ps3I9jAdNtRpJrbBvQjpzyFbss/skHqzS+eu4RxKLaEAtFqkjZaB6TZMSivPbLxf4K7VI4SjR0P5mRCX5+Q25A=="
},
"node_modules/m3u8-parser": {
"version": "6.2.0",
"resolved": "https://registry.npmmirror.com/m3u8-parser/-/m3u8-parser-6.2.0.tgz",
"integrity": "sha512-qlC00JTxYOxawcqg+RB8jbyNwL3foY/nCY61kyWP+RCuJE9APLeqB/nSlTjb4Mg0yRmyERgjswpdQxMvkeoDrg==",
"dependencies": {
"@babel/runtime": "^7.12.5",
"@videojs/vhs-utils": "^3.0.5",
"global": "^4.4.0"
}
},
"node_modules/m3u8-parser/node_modules/@videojs/vhs-utils": {
"version": "3.0.5",
"resolved": "https://registry.npmmirror.com/@videojs/vhs-utils/-/vhs-utils-3.0.5.tgz",
"integrity": "sha512-PKVgdo8/GReqdx512F+ombhS+Bzogiofy1LgAj4tN8PfdBx3HSS7V5WfJotKTqtOWGwVfSWsrYN/t09/DSryrw==",
"dependencies": {
"@babel/runtime": "^7.12.5",
"global": "^4.4.0",
"url-toolkit": "^2.2.1"
},
"engines": {
"node": ">=8",
"npm": ">=5"
}
},
"node_modules/magic-string": {
"version": "0.30.5",
"resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.5.tgz",
@ -1041,11 +1245,63 @@
"node": ">= 0.6"
}
},
"node_modules/min-document": {
"version": "2.19.0",
"resolved": "https://registry.npmmirror.com/min-document/-/min-document-2.19.0.tgz",
"integrity": "sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==",
"dependencies": {
"dom-walk": "^0.1.0"
}
},
"node_modules/mitt": {
"version": "3.0.1",
"resolved": "https://registry.npmmirror.com/mitt/-/mitt-3.0.1.tgz",
"integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw=="
},
"node_modules/mpd-parser": {
"version": "1.2.2",
"resolved": "https://registry.npmmirror.com/mpd-parser/-/mpd-parser-1.2.2.tgz",
"integrity": "sha512-QCfB1koOoZw6E5La1cx+W/Yd0EZlRhHMqMr4TAJez0eRTuPDzPM5FWoiOqjyo37W+ISPLzmfJACSbJFEBjbL4Q==",
"dependencies": {
"@babel/runtime": "^7.12.5",
"@videojs/vhs-utils": "^3.0.5",
"@xmldom/xmldom": "^0.8.3",
"global": "^4.4.0"
},
"bin": {
"mpd-to-m3u8-json": "bin/parse.js"
}
},
"node_modules/mpd-parser/node_modules/@videojs/vhs-utils": {
"version": "3.0.5",
"resolved": "https://registry.npmmirror.com/@videojs/vhs-utils/-/vhs-utils-3.0.5.tgz",
"integrity": "sha512-PKVgdo8/GReqdx512F+ombhS+Bzogiofy1LgAj4tN8PfdBx3HSS7V5WfJotKTqtOWGwVfSWsrYN/t09/DSryrw==",
"dependencies": {
"@babel/runtime": "^7.12.5",
"global": "^4.4.0",
"url-toolkit": "^2.2.1"
},
"engines": {
"node": ">=8",
"npm": ">=5"
}
},
"node_modules/mux.js": {
"version": "7.0.2",
"resolved": "https://registry.npmmirror.com/mux.js/-/mux.js-7.0.2.tgz",
"integrity": "sha512-CM6+QuyDbc0qW1OfEjkd2+jVKzTXF+z5VOKH0eZxtZtnrG/ilkW/U7l7IXGtBNLASF9sKZMcK1u669cq50Qq0A==",
"dependencies": {
"@babel/runtime": "^7.11.2",
"global": "^4.4.0"
},
"bin": {
"muxjs-transmux": "bin/transmux.js"
},
"engines": {
"node": ">=8",
"npm": ">=5"
}
},
"node_modules/nanoid": {
"version": "3.3.7",
"resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.7.tgz",
@ -1124,6 +1380,17 @@
}
}
},
"node_modules/pkcs7": {
"version": "1.0.4",
"resolved": "https://registry.npmmirror.com/pkcs7/-/pkcs7-1.0.4.tgz",
"integrity": "sha512-afRERtHn54AlwaF2/+LFszyAANTCggGilmcmILUzEjvs3XgFZT+xE6+QWQcAGmu4xajy+Xtj7acLOPdx5/eXWQ==",
"dependencies": {
"@babel/runtime": "^7.5.5"
},
"bin": {
"pkcs7": "bin/cli.js"
}
},
"node_modules/postcss": {
"version": "8.4.31",
"resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.4.31.tgz",
@ -1137,6 +1404,14 @@
"node": "^10 || ^12 || >=14"
}
},
"node_modules/process": {
"version": "0.11.10",
"resolved": "https://registry.npmmirror.com/process/-/process-0.11.10.tgz",
"integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
"engines": {
"node": ">= 0.6.0"
}
},
"node_modules/proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
@ -1187,6 +1462,22 @@
"fsevents": "~2.3.2"
}
},
"node_modules/rust-result": {
"version": "1.0.0",
"resolved": "https://registry.npmmirror.com/rust-result/-/rust-result-1.0.0.tgz",
"integrity": "sha512-6cJzSBU+J/RJCF063onnQf0cDUOHs9uZI1oroSGnHOph+CQTIJ5Pp2hK5kEQq1+7yE/EEWfulSNXAQ2jikPthA==",
"dependencies": {
"individual": "^2.0.0"
}
},
"node_modules/safe-json-parse": {
"version": "4.0.0",
"resolved": "https://registry.npmmirror.com/safe-json-parse/-/safe-json-parse-4.0.0.tgz",
"integrity": "sha512-RjZPPHugjK0TOzFrLZ8inw44s9bKox99/0AZW9o/BEQVrJfhI+fIHMErnPyRa89/yRXUUr93q+tiN6zhoVV4wQ==",
"dependencies": {
"rust-result": "^1.0.0"
}
},
"node_modules/sass": {
"version": "1.69.5",
"resolved": "https://registry.npmmirror.com/sass/-/sass-1.69.5.tgz",
@ -1229,6 +1520,60 @@
"resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz",
"integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
},
"node_modules/url-toolkit": {
"version": "2.2.5",
"resolved": "https://registry.npmmirror.com/url-toolkit/-/url-toolkit-2.2.5.tgz",
"integrity": "sha512-mtN6xk+Nac+oyJ/PrI7tzfmomRVNFIWKUbG8jdYFt52hxbiReFAXIjYskvu64/dvuW71IcB7lV8l0HvZMac6Jg=="
},
"node_modules/video.js": {
"version": "8.6.1",
"resolved": "https://registry.npmmirror.com/video.js/-/video.js-8.6.1.tgz",
"integrity": "sha512-CNYVJ5WWIZ7bOhbkkfcKqLGoc6WsE3Ft2RfS1lXdQTWk8UiSsPW2Ssk2JzPCA8qnIlUG9os/faCFsYWjyu4JcA==",
"dependencies": {
"@babel/runtime": "^7.12.5",
"@videojs/http-streaming": "3.7.0",
"@videojs/vhs-utils": "^4.0.0",
"@videojs/xhr": "2.6.0",
"aes-decrypter": "^4.0.1",
"global": "4.4.0",
"keycode": "2.2.0",
"m3u8-parser": "^6.0.0",
"mpd-parser": "^1.0.1",
"mux.js": "^7.0.1",
"safe-json-parse": "4.0.0",
"videojs-contrib-quality-levels": "4.0.0",
"videojs-font": "4.1.0",
"videojs-vtt.js": "0.15.5"
}
},
"node_modules/videojs-contrib-quality-levels": {
"version": "4.0.0",
"resolved": "https://registry.npmmirror.com/videojs-contrib-quality-levels/-/videojs-contrib-quality-levels-4.0.0.tgz",
"integrity": "sha512-u5rmd8BjLwANp7XwuQ0Q/me34bMe6zg9PQdHfTS7aXgiVRbNTb4djcmfG7aeSrkpZjg+XCLezFNenlJaCjBHKw==",
"dependencies": {
"global": "^4.4.0"
},
"engines": {
"node": ">=14",
"npm": ">=6"
},
"peerDependencies": {
"video.js": "^8"
}
},
"node_modules/videojs-font": {
"version": "4.1.0",
"resolved": "https://registry.npmmirror.com/videojs-font/-/videojs-font-4.1.0.tgz",
"integrity": "sha512-X1LuPfLZPisPLrANIAKCknZbZu5obVM/ylfd1CN+SsCmPZQ3UMDPcvLTpPBJxcBuTpHQq2MO1QCFt7p8spnZ/w=="
},
"node_modules/videojs-vtt.js": {
"version": "0.15.5",
"resolved": "https://registry.npmmirror.com/videojs-vtt.js/-/videojs-vtt.js-0.15.5.tgz",
"integrity": "sha512-yZbBxvA7QMYn15Lr/ZfhhLPrNpI/RmCSCqgIff57GC2gIrV5YfyzLfLyZMj0NnZSAz8syB4N0nHXpZg9MyrMOQ==",
"dependencies": {
"global": "^4.3.1"
}
},
"node_modules/vite": {
"version": "5.0.2",
"resolved": "https://registry.npmmirror.com/vite/-/vite-5.0.2.tgz",
@ -1312,6 +1657,11 @@
"vue": "^3.2.0"
}
},
"node_modules/webworkify-webpack": {
"version": "2.1.5",
"resolved": "https://registry.npmmirror.com/webworkify-webpack/-/webworkify-webpack-2.1.5.tgz",
"integrity": "sha512-2akF8FIyUvbiBBdD+RoHpoTbHMQF2HwjcxfDvgztAX5YwbZNyrtfUMgvfgFVsgDhDPVTlkbb5vyasqDHfIDPQw=="
},
"node_modules/zrender": {
"version": "5.4.4",
"resolved": "https://registry.npmmirror.com/zrender/-/zrender-5.4.4.tgz",

View File

@ -14,8 +14,12 @@
"axios": "^1.6.2",
"echarts": "^5.4.3",
"echarts-gl": "^2.0.9",
"flv-h265.js": "^1.7.4",
"flv.js": "^1.6.2",
"hls.js": "^1.4.13",
"mitt": "^3.0.1",
"pinia": "^2.1.7",
"video.js": "^8.6.1",
"vue": "^3.3.8",
"vue-router": "^4.2.5"
},

1
public/decoder.js Normal file

File diff suppressed because one or more lines are too long

BIN
public/decoder.wasm Normal file

Binary file not shown.

1
public/jessibuca.js Normal file

File diff suppressed because one or more lines are too long

BIN
src/assets/ani/n.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
src/assets/ani/w.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 KiB

BIN
src/assets/ani/z.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

BIN
src/assets/img/border5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 824 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 632 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 465 B

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

83
src/components/ani.vue Normal file
View File

@ -0,0 +1,83 @@
<script setup>
</script>
<template>
<div class="ani">
<div class="a-box">
<img class="img" src="/src/assets/ani/w.png" alt="" />
<div class="center">
<img class="img2" src="/src/assets/ani/z.png" alt="" />
</div>
<div class="top">
<img class="img3" src="/src/assets/ani/n.png" alt="" />
</div>
</div>
</div>
</template>
<style scoped lang="scss">
.ani {
width: auto;
height: 100%;
}
.a-box {
width: 50rem;
height: 50rem;
position: relative;
transform: rotateX(75deg);
.img {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
animation: rotate 30s linear infinite; /* 使用 rotate 动画2秒完成一次线性运动无限循环 */
}
.center {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
display: flex;
justify-content: center;
align-items: center;
.img2 {
width: 100%;
height: 100%;
animation: rotateZ 8s linear infinite; /* 使用 rotate 动画2秒完成一次线性运动无限循环 */
}
}
.top {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
display: flex;
justify-content: center;
align-items: center;
.img3 {
width: 100%;
height: 100%;
}
}
}
@keyframes rotate {
0% {
transform: rotate(0deg); /* 初始角度为0度 */
}
100% {
transform: rotate(360deg); /* 最终角度为360度即完整的一圈 */
}
}
@keyframes rotateZ {
0% {
transform: rotate(360deg); /* 初始角度为0度 */
}
100% {
transform: rotate(0deg); /* 最终角度为360度即完整的一圈 */
}
}
</style>

367
src/components/videoFlv.vue Normal file
View File

@ -0,0 +1,367 @@
<template>
<div class="container-shell">
<div class="option" style="display: none">
<input
style="width: 50px"
type="number"
ref="buffer"
value="0.2"
@change="changeBuffer"
/>
<input
type="checkbox"
v-model="useMSE"
ref="vod"
@change="restartPlay('mse')"
/><span>MediaSource</span>
<input
type="checkbox"
v-model="useWCS"
ref="vod"
@change="restartPlay('wcs')"
/><span>webcodecs</span>
</div>
<div id="container" ref="container"></div>
<div class="input" style="display: none">
<div>输入URL</div>
<input type="input" autocomplete="on" ref="playUrl" v-model="playUrl" />
<button v-if="!playing" @click="play">播放</button>
<button v-else @click="pause">停止</button>
</div>
</div>
</template>
<script>
export default {
name: "DemoPlayer",
props: ['url'],
data () {
return {
playUrl: 'http://192.168.1.27/live/test.live.flv?secret=gqig2yfkkdpimic1uwzy1l5msio0eflm', //
jessibuca: null,
version: '',
wasm: false,
vc: "ff",
playing: false,
quieting: true,
loaded: false, // mute
showOperateBtns: false,
showBandwidth: false,
err: "",
speed: 0,
performance: "",
volume: 1,
rotate: 0,
useWCS: false,
useMSE: true,
useOffscreen: false,
recording: false,
recordType: 'webm',
scale: 0
};
},
mounted () {
this.create();
window.onerror = (msg) => (this.err = msg);
if (this.$props.url) this.playUrl = this.$props.url;
else console.error('请传入url')
setTimeout(() => {
this.play()
}, 2000)
},
unmounted () {
this.jessibuca.destroy();
},
methods: {
create (options) {
options = options || {};
this.jessibuca = new window.Jessibuca(
Object.assign(
{
container: this.$refs.container,
videoBuffer: Number(this.$refs.buffer.value), //
isResize: false,
useWCS: this.useWCS,
useMSE: this.useMSE,
text: "",
// background: "bg.jpg",
loadingText: "疯狂加载中...",
// hasAudio:false,
debug: true,
supportDblclickFullscreen: true,
showBandwidth: this.showBandwidth, //
operateBtns: {
fullscreen: this.showOperateBtns,
screenshot: this.showOperateBtns,
play: this.showOperateBtns,
audio: this.showOperateBtns,
},
vod: this.vod,
forceNoOffscreen: !this.useOffscreen,
isNotMute: true,
timeout: 10
},
options
)
);
var _this = this;
this.jessibuca.on("load", function () {
console.log("on load");
});
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 () {
console.log("on pause");
_this.playing = false;
});
this.jessibuca.on("play", function () {
console.log("on play");
_this.playing = true;
});
this.jessibuca.on("fullscreen", function (msg) {
console.log("on fullscreen", msg);
});
this.jessibuca.on("mute", function (msg) {
console.log("on mute", msg);
_this.quieting = msg;
});
this.jessibuca.on("mute", function (msg) {
console.log("on mute2", msg);
});
this.jessibuca.on("audioInfo", function (msg) {
console.log("audioInfo", 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('frame start');
})
this.jessibuca.on("performance", function (performance) {
var 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) {
console.log('kBps', kBps);
});
this.jessibuca.on("play", () => {
this.playing = true;
this.loaded = true;
this.quieting = this.jessibuca.isMute();
});
this.jessibuca.on('recordingTimestamp', (ts) => {
console.log('recordingTimestamp', ts);
})
// console.log(this.jessibuca);
},
play () {
// this.jessibuca.onPlay = () => (this.playing = true);
if (this.playUrl) {
this.jessibuca.play(this.playUrl);
}
},
mute () {
this.jessibuca.mute();
},
cancelMute () {
this.jessibuca.cancelMute();
},
pause () {
this.jessibuca.pause();
this.playing = false;
this.err = "";
this.performance = "";
},
volumeChange () {
this.jessibuca.setVolume(this.volume);
},
rotateChange () {
this.jessibuca.setRotate(this.rotate);
},
destroy () {
if (this.jessibuca) {
this.jessibuca.destroy();
}
this.create();
this.playing = false;
this.loaded = false;
this.performance = "";
},
fullscreen () {
this.jessibuca.setFullscreen(true);
},
clearView () {
this.jessibuca.clearView();
},
startRecord () {
const time = new Date().getTime();
this.jessibuca.startRecord(time, this.recordType);
},
stopAndSaveRecord () {
this.jessibuca.stopRecordAndSave();
},
screenShot () {
this.jessibuca.screenshot();
},
restartPlay (type) {
if (type === 'mse') {
this.useWCS = false;
this.useOffscreen = false;
} else if (type === 'wcs') {
this.useMSE = false
} else if (type === 'offscreen') {
this.useMSE = false
}
this.destroy();
setTimeout(() => {
this.play();
}, 100)
},
changeBuffer () {
this.jessibuca.setBufferTime(Number(this.$refs.buffer.value));
},
scaleChange () {
this.jessibuca.setScaleMode(this.scale);
},
},
};
</script>
<style>
.container-shell {
height: 100%;
width: 100%;
backdrop-filter: blur(5px);
/* background: hsla(0, 0%, 50%, 0.5);
padding: 30px 4px 10px 4px; */
/* border: 2px solid black; */
width: auto;
position: relative;
border-radius: 5px;
/* box-shadow: 0 10px 20px; */
}
.container-shell-title {
position: absolute;
color: darkgray;
top: 4px;
left: 10px;
text-shadow: 1px 1px black;
}
.tag-version {
}
#container {
background: rgba(13, 14, 27, 0.7);
width: 100%;
height: 100%;
}
.input {
display: flex;
align-items: center;
margin-top: 10px;
color: white;
place-content: stretch;
}
.input2 {
bottom: 0px;
}
.input input[type="input"] {
flex: auto;
}
.err {
position: absolute;
top: 40px;
left: 10px;
color: red;
}
.option {
position: absolute;
top: 4px;
right: 10px;
display: flex;
place-content: center;
font-size: 12px;
}
.option span {
color: white;
}
.page {
background: url(/bg.jpg);
background-repeat: no-repeat;
background-position: top;
}
/* @media (max-width: 720px) {
#container {
width: 90vw;
height: 52.7vw;
}
} */
</style>

View File

@ -10,6 +10,11 @@ const routes = [
path: '/delivery',
name: 'delivery',
component: () => import('../view/delivery/index.vue')
},
{
path: '/test',
name: 'test',
component: () => import('../view/test/index.vue')
}
]

80
src/utils/geo.js Normal file

File diff suppressed because one or more lines are too long

View File

@ -12,7 +12,7 @@ const initData = (data) => {
`-`,
`-`,
`-`,
`查看详情>`,
`<span class="btn">查看详情></span>`,
]
)
}
@ -40,6 +40,13 @@ const list = reactive({
rowNum: 9
})
const show = ref(false);
const clickList = (e) => {
console.log(e);
console.log(e.rowIndex);
show.value = true;
}
onMounted(() => {
initData();
})
@ -99,11 +106,61 @@ onMounted(() => {
<div class="c-box">
<dv-scroll-board
ref="scrollBoardRef"
@click="clickList"
:config="list"
style="width: 100%; height: 100%"
/>
</div>
</div>
<transition name="fade" appear>
<div class="box3" v-show="show">
<div class="head-title">
<img src="/src/assets/index_img/icon3.png" />
<span>设备警告事件</span>
</div>
<div class="info">
<div class="info-item">
<div class="tips">设备编号:</div>
<div>25566333</div>
</div>
<div class="info-item">
<div class="tips">设备名称:</div>
<div>甲烷监测设备</div>
</div>
<div class="info-item">
<div class="tips">警告事件:</div>
<div>2023-12-7 12:30</div>
</div>
</div>
<div class="info">
<div class="info-item">
<div class="tips">设备图片:</div>
<img src="/src/assets/index_img/icon2.png" alt="" />
</div>
<div class="info-item">
<div class="tips">警告原因:</div>
<div>甲烷含量超标, 同时浓度也超标了</div>
</div>
<div class="info-item" style="flex: 1">
<div class="tips">警告数据:</div>
<div>甲烷含量>1000ppm 浓度>120</div>
</div>
</div>
<div class="info">
<div class="info-item">
<div class="tips">解决方案:</div>
<div class="list">
<div>
确保良好的通风系统提供良好的通风以排除甲烷气体这可以包括安装有效的排气扇通风管道和通风设备以确保空气流动
检修和维护设备定期检查和维护可能产生甲烷泄漏的设备如管道阀门连接件等确保它们的密封性和操作正常及时修复任何泄漏
</div>
<div>1.优化饲养管理 2.粪便处理设施改</div>
</div>
</div>
</div>
<div class="btn" @click="show = false">关闭弹窗</div>
</div>
</transition>
<div class="border"></div>
</div>
</template>
@ -125,10 +182,12 @@ onMounted(() => {
.box-title {
width: 100%;
position: relative;
height: 2.2rem;
line-height: 2.2rem;
.text {
text-align: left;
font-family: "ifonts";
padding: 0.2rem 0.8rem;
padding: 0 0.8rem;
font-size: 1.1rem;
}
.bg {
@ -218,15 +277,94 @@ onMounted(() => {
.c-box {
height: 88%;
}
:deep(.btn) {
cursor: pointer;
}
}
.box3 {
min-height: 90%;
width: 50%;
position: absolute;
z-index: 99;
bottom: 4%;
right: 5%;
background-image: url(../../../assets/index_img/box4.png);
background-size: 100% 100%;
.btn {
position: absolute;
right: 6%;
top: 0;
width: 13%;
height: 8%;
display: flex;
justify-content: center;
align-items: center;
background-image: url(../../../assets/index_img/btn2.png);
background-size: 100% 100%;
font-size: 0.8rem;
cursor: pointer;
}
.head-title {
width: 100%;
max-height: 12%;
min-height: 2.5rem;
display: flex;
align-items: center;
font-size: 1rem;
font-family: "ifonts";
img {
height: 1rem;
width: auto;
margin-left: 2rem;
margin-right: 0.8rem;
margin-top: 0.2rem;
}
}
.info {
display: flex;
flex-wrap: nowrap;
box-sizing: border-box;
padding: 0 2rem;
margin-top: 1rem;
height: auto;
.info-item {
flex: 1;
flex-shrink: 0;
display: flex;
& > div {
text-align: start;
padding-right: 0.4rem;
box-sizing: border-box;
}
.tips {
flex-shrink: 0;
}
.list {
padding-bottom: 4rem;
}
}
}
}
.border {
background-image: url(../../../assets/img/border3.png);
background-size: 100% 100%;
height: 0.4rem;
height: 0.6rem;
width: 100%;
position: absolute;
top: 0;
right: 0;
}
}
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.5s;
}
.fade-enter,
.fade-leave-to {
opacity: 0;
}
</style>

View File

@ -1,7 +1,8 @@
<script setup>
import { onMounted, reactive, ref, inject, nextTick } from "vue";
import * as echarts from 'echarts';
import 'echarts-gl';
import { useRoute } from "vue-router";
import ani from "@/components/ani.vue";
import mitt from "@/utils/mitt";
import luxian from "@/assets/json/luxian.json";
import hejiang from "@/assets/json/hejiang.json";
@ -11,10 +12,21 @@ import jiangyang from "@/assets/json/jiangyang.json";
import longma from "@/assets/json/longma.json";
import naxi from "@/assets/json/naxi.json";
import { useAppStore } from "@/store/app.js";
import geoJSON from "@/utils/geo.js";
const appStore = useAppStore();
const route = useRoute();
let geoJson = JSON.parse(JSON.stringify(geoJSON));
const props = defineProps({
list: {
type: Object,
default: () => []
}
})
const mapType = reactive({
name: '',
json: ''
@ -31,36 +43,15 @@ const changeType = (name = 'luxian') => {
if (name == 'naxi') mapType.json = naxi;
}
let dataValue = [
{
name: '测试一', value: [105.38, 29.15, 0],
store: 2065, team: 33,
},
{
name: '测试二', value: [105.62, 29.05, 0],
store: 665, team: 895,
},
{
name: '测试三', value: [105.55, 29.10, 0],
store: 66, team: 5422,
},
{
name: '测试四', value: [105.70, 29.23, 0],
store: 9887, team: 1562,
},
{
name: '泸县', value: [105.372029, 29.141426, 0],
store: 9999, team: 1000,
},
]
let dataValue = []
const customFormatter = (params) => {
// console.log(params.data);
return `{img|${params.data.name}}\n{t|店铺${params.data.store}个, 团队${params.data.team}个}`
// return `{img|${params.data.street_name}}\n{t|${params.data.mer_count}, ${params.data.service_group_count}}`
return ''
}
const initDateValue = () => {
const initDataValue = () => {
dataValue.forEach(item => {
item.label = {
show: true, //
@ -100,42 +91,38 @@ const initMap = () => {
if (chart == null) {
chart = echarts.init(echartsRef.value);
}
echarts.registerMap(mapType.name, mapType.json);
let domImg = document.createElement("img");
domImg.style.height = '1000px';
domImg.style.width = "1000px";
domImg.src = 'https://lihai001.oss-cn-chengdu.aliyuncs.com/def/6b962202311291338462283.png';
echarts.registerMap(mapType.name, geoJson);
let option = {
animation: false,
title: {
text: route.query.name,
textStyle: {
color: "#fff",
fontSize: 22
},
top: '10%',
left: '10%'
},
//geo
geo3D: [
geo: [
{
map: mapType.name,
zoom: 1.0,
axisLine: {
show: false // false
},
label: {
show: false,
disabled: true,
color: '#fff',
fontSize: 25,
},
//
// emphasis: {
// itemStyle: {
// // color: '#546686', //
// borderColor: '#fff', //线00fcff 516a89
// borderWidth: 1,
// },
// label: {
// color: '#fff'
// }
// },
emphasis: {
itemStyle: {
// color: '#546686', //
borderColor: '#fff', //线00fcff 516a89
borderWidth: 1,
},
label: {
color: '#fff'
}
},
emphasis: {
disabled: true
},
@ -145,22 +132,119 @@ const initMap = () => {
// aspectScale:0.75, //
// roam: true, //
itemStyle: {
color: '#546686', //
borderColor: '#fff', //线00fcff 516a89
borderWidth: 1,
normal: {
// color: '#546686', //
borderColor: '#fff', //线00fcff 516a89
borderWidth: 1,
areaColor: "#3f5171",
shadowColor: "#5bdbf6",
shadowOffsetX: 5,
shadowOffsetY: 10,
// shadowBlur: 2
shadowBlur: 20,
},
},
},
//
{
map: mapType.name,
zlevel: -1,
zoom: 1.01, //
roam: false, //
show: true,
tooltip: {
show: false //
},
label: {
show: false
},
emphasis: {
disabled: true
},
select: {
disabled: true
},
itemStyle: {
normal: {
borderJoin: "round",
borderColor: "rgba(176,228,252,1)",
borderWidth: 3,
areaColor: "rgba(133,188,232,1)",
shadowColor: "rgba(133,188,232,.7)",
shadowOffsetX: 0,
shadowOffsetY: 0,
shadowBlur: 25,
},
emphasis: {
show: false,
},
},
regionHright: 1,
},
],
tooltip: {
trigger: 'item',
formatter: function (params) {
console.log(params);
if (params.data) {
return `<div
style="background-image: url(\'/src/assets/img/border5.png\');
background-size: 100% 100%;
display: flex;
justify-content: space-around;
align-items: center;
flex-direction: column;
width: 180px;
height: 80px;">
<div style="font-size: 12px;height: 15px;">基地名称</div>
<div style="font-size: 15px;font-family: 'ifonts';height: 50px;display: flex;
justify-content: center;
align-items: center;">${'泸县原生态养殖基地'}</div>
</div>`;
} else return '';
},
position: 'top',
// extraCssText: 'background-color: transparent; border: none;pdding: 0;', // CSS
backgroundColor: 'rgba(0, 156, 255, 0)', //
borderColor: "rgba(0, 156, 255, 0)",
padding: 0,
textStyle: {
color: '#fff'
}
},
series: [
{
type: "map",
map: mapType.name,
label: {
emphasis: {
color: 'rgba(0,0,0,0)' //
}
},
emphasis: {
disabled: false,
},
select: {
disabled: true
},
itemStyle: {
normal: {
areaColor: "#3f5171",
borderColor: "#5bdbf6",
borderWidth: 1,
},
emphasis: {
areaColor: '#0680ca', //
}
},
},
{
name: "",
type: "scatter",
coordinateSystem: "geo",
data: dataValue,
symbol: "image://https://lihai001.oss-cn-chengdu.aliyuncs.com/def/6eb37202311281655342626.png",
symbolSize: [40, 30],
hoverSymbolSize: [60, 45],
symbol: "image://https://lihai001.oss-cn-chengdu.aliyuncs.com/def/0a86a202312081638007996.png",
symbolSize: [30, 45],
hoverSymbolSize: [45, 60],
label: {
formatter: "",
position: "center",
@ -185,34 +269,34 @@ const initMap = () => {
}
}
},
]
],
}
// 使
chart.setOption(option);
}
//
chart.dispatchAction({
type: 'updateLayout',
rotation: Math.PI / 4, //
});
// 3D
chart.setOption({
grid3D: {},
xAxis3D: {},
yAxis3D: {},
zAxis3D: {}
});
const filterMap = () => {
geoJson.features = geoJson.features.filter((item) => {
return item.properties.name == route.query.name
})
}
onMounted(() => {
changeType(appStore.map_info);
initDateValue();
if (route.query.name) {
filterMap()
}
dataValue = props.list;
dataValue[0] = {
value: [105.36, 29.20]
}
changeType('luxian');
initDataValue();
initMap();
nextTick(() => {
mitt.on('map_info', e => {
changeType(e.pinyin);
initDateValue();
initDataValue();
initMap();
})
})
@ -222,7 +306,12 @@ onMounted(() => {
<template>
<div class="map">
<div class="echarts" ref="echartsRef"></div>
<div class="map-a">
<ani class="ani" />
</div>
<div class="map-e">
<div class="echarts" ref="echartsRef"></div>
</div>
</div>
</template>
@ -233,10 +322,31 @@ onMounted(() => {
display: flex;
justify-content: center;
align-items: center;
position: relative;
/* background-color: rgba($color: #fff, $alpha: 0.3); */
.echarts {
.map-a {
position: absolute;
bottom: -24%;
left: 0;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: flex-end;
}
.map-e {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
.echarts {
width: 100%;
height: 100%;
}
}
}
</style>

View File

@ -256,10 +256,12 @@ onMounted(() => {
.box-title {
width: 100%;
position: relative;
height: 2.2rem;
line-height: 2.2rem;
.text {
text-align: left;
font-family: "ifonts";
padding: 0.2rem 0.8rem;
padding: 0 0.8rem;
font-size: 1.1rem;
}
.bg {
@ -318,7 +320,7 @@ onMounted(() => {
background-image: url(../../../assets/img/border1.png);
background-size: 100% 100%;
height: 100%;
width: 0.4rem;
width: 0.6rem;
position: absolute;
top: 0;
right: 0;

View File

@ -46,10 +46,12 @@ onMounted(() => {
.box-title {
width: 100%;
position: relative;
height: 2.2rem;
line-height: 2.2rem;
.text {
text-align: left;
font-family: "ifonts";
padding: 0.2rem 0.8rem;
padding: 0 0.8rem;
font-size: 1.1rem;
}
.bg {
@ -81,7 +83,7 @@ onMounted(() => {
background-image: url(../../../assets/img/border2.png);
background-size: 100% 100%;
height: 100%;
width: 0.4rem;
width: 0.6rem;
position: absolute;
top: 0;
left: 0;

View File

@ -12,7 +12,7 @@ const initData = (data) => {
`-`,
`-`,
`-`,
`查看详情>`,
`<span class="btn">查看详情></span>`,
]
)
}
@ -40,6 +40,13 @@ const list = reactive({
rowNum: 9
})
const show = ref(false);
const clickList = (e) => {
console.log(e);
console.log(e.rowIndex);
show.value = true;
}
onMounted(() => {
initData();
})
@ -99,11 +106,61 @@ onMounted(() => {
<div class="c-box">
<dv-scroll-board
ref="scrollBoardRef"
@click="clickList"
:config="list"
style="width: 100%; height: 100%"
/>
</div>
</div>
<transition name="fade" appear>
<div class="box3" v-show="show">
<div class="head-title">
<img src="/src/assets/index_img/icon3.png" />
<span>设备警告事件</span>
</div>
<div class="info">
<div class="info-item">
<div class="tips">设备编号:</div>
<div>25566333</div>
</div>
<div class="info-item">
<div class="tips">设备名称:</div>
<div>甲烷监测设备</div>
</div>
<div class="info-item">
<div class="tips">警告事件:</div>
<div>2023-12-7 12:30</div>
</div>
</div>
<div class="info">
<div class="info-item">
<div class="tips">设备图片:</div>
<img src="/src/assets/index_img/icon2.png" alt="" />
</div>
<div class="info-item">
<div class="tips">警告原因:</div>
<div>甲烷含量超标, 同时浓度也超标了</div>
</div>
<div class="info-item" style="flex: 1">
<div class="tips">警告数据:</div>
<div>甲烷含量>1000ppm 浓度>120</div>
</div>
</div>
<div class="info">
<div class="info-item">
<div class="tips">解决方案:</div>
<div class="list">
<div>
确保良好的通风系统提供良好的通风以排除甲烷气体这可以包括安装有效的排气扇通风管道和通风设备以确保空气流动
检修和维护设备定期检查和维护可能产生甲烷泄漏的设备如管道阀门连接件等确保它们的密封性和操作正常及时修复任何泄漏
</div>
<div>1.优化饲养管理 2.粪便处理设施改</div>
</div>
</div>
</div>
<div class="btn" @click="show = false">关闭弹窗</div>
</div>
</transition>
<div class="border"></div>
</div>
</template>
@ -125,10 +182,12 @@ onMounted(() => {
.box-title {
width: 100%;
position: relative;
height: 2.2rem;
line-height: 2.2rem;
.text {
text-align: left;
font-family: "ifonts";
padding: 0.2rem 0.8rem;
padding: 0 0.8rem;
font-size: 1.1rem;
}
.bg {
@ -218,15 +277,94 @@ onMounted(() => {
.c-box {
height: 88%;
}
:deep(.btn) {
cursor: pointer;
}
}
.box3 {
min-height: 90%;
width: 50%;
position: absolute;
z-index: 99;
bottom: 4%;
right: 5%;
background-image: url(../../../assets/index_img/box4.png);
background-size: 100% 100%;
.btn {
position: absolute;
right: 6%;
top: 0;
width: 13%;
height: 8%;
display: flex;
justify-content: center;
align-items: center;
background-image: url(../../../assets/index_img/btn2.png);
background-size: 100% 100%;
font-size: 0.8rem;
cursor: pointer;
}
.head-title {
width: 100%;
max-height: 12%;
min-height: 2.5rem;
display: flex;
align-items: center;
font-size: 1rem;
font-family: "ifonts";
img {
height: 1rem;
width: auto;
margin-left: 2rem;
margin-right: 0.8rem;
margin-top: 0.2rem;
}
}
.info {
display: flex;
flex-wrap: nowrap;
box-sizing: border-box;
padding: 0 2rem;
margin-top: 1rem;
height: auto;
.info-item {
flex: 1;
flex-shrink: 0;
display: flex;
& > div {
text-align: start;
padding-right: 0.4rem;
box-sizing: border-box;
}
.tips {
flex-shrink: 0;
}
.list {
padding-bottom: 4rem;
}
}
}
}
.border {
background-image: url(../../../assets/img/border3.png);
background-size: 100% 100%;
height: 0.4rem;
height: 0.6rem;
width: 100%;
position: absolute;
top: 0;
right: 0;
}
}
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.5s;
}
.fade-enter,
.fade-leave-to {
opacity: 0;
}
</style>

View File

@ -1,7 +1,8 @@
<script setup>
import { onMounted, reactive, ref, inject, nextTick } from "vue";
import * as echarts from 'echarts';
import 'echarts-gl';
import { useRouter } from "vue-router";
import ani from "@/components/ani.vue";
import mitt from "@/utils/mitt";
import luxian from "@/assets/json/luxian.json";
import hejiang from "@/assets/json/hejiang.json";
@ -10,11 +11,20 @@ import gulin from "@/assets/json/gulin.json";
import jiangyang from "@/assets/json/jiangyang.json";
import longma from "@/assets/json/longma.json";
import naxi from "@/assets/json/naxi.json";
import geoJSON from "@/utils/geo.js";
import { useAppStore } from "@/store/app.js";
const appStore = useAppStore();
const router = useRouter();
const props = defineProps({
list: {
type: Object,
default: () => []
}
})
const mapType = reactive({
name: '',
json: ''
@ -31,36 +41,15 @@ const changeType = (name = 'luxian') => {
if (name == 'naxi') mapType.json = naxi;
}
let dataValue = [
{
name: '测试一', value: [105.38, 29.15, 0],
store: 2065, team: 33,
},
{
name: '测试二', value: [105.62, 29.05, 0],
store: 665, team: 895,
},
{
name: '测试三', value: [105.55, 29.10, 0],
store: 66, team: 5422,
},
{
name: '测试四', value: [105.70, 29.23, 0],
store: 9887, team: 1562,
},
{
name: '泸县', value: [105.372029, 29.141426, 0],
store: 9999, team: 1000,
},
]
let dataValue = []
const customFormatter = (params) => {
// console.log(params.data);
return `{img|${params.data.name}}\n{t|店铺${params.data.store}个, 团队${params.data.team}个}`
// return `{img|${params.data.street_name}}\n{t|${params.data.mer_count}, ${params.data.service_group_count}}`
return ''
}
const initDateValue = () => {
const initDataValue = () => {
dataValue.forEach(item => {
item.label = {
show: true, //
@ -100,42 +89,18 @@ const initMap = () => {
if (chart == null) {
chart = echarts.init(echartsRef.value);
}
echarts.registerMap(mapType.name, mapType.json);
let domImg = document.createElement("img");
domImg.style.height = '1000px';
domImg.style.width = "1000px";
domImg.src = 'https://lihai001.oss-cn-chengdu.aliyuncs.com/def/6b962202311291338462283.png';
echarts.registerMap(mapType.name, geoJSON);
let option = {
animation: false,
//geo
geo3D: [
geo: [
{
map: mapType.name,
zoom: 1.0,
axisLine: {
show: false // false
},
label: {
show: false,
disabled: true,
color: '#fff',
fontSize: 25,
},
//
// emphasis: {
// itemStyle: {
// // color: '#546686', //
// borderColor: '#fff', //线00fcff 516a89
// borderWidth: 1,
// },
// label: {
// color: '#fff'
// }
// },
emphasis: {
disabled: true
},
@ -145,22 +110,124 @@ const initMap = () => {
// aspectScale:0.75, //
// roam: true, //
itemStyle: {
color: '#546686', //
borderColor: '#fff', //线00fcff 516a89
borderWidth: 1,
normal: {
// color: '#546686', //
borderColor: '#fff', //线00fcff 516a89
borderWidth: 1,
areaColor: "#3f5171",
shadowColor: "#5bdbf6",
shadowOffsetX: 5,
shadowOffsetY: 10,
// shadowBlur: 2
shadowBlur: 20,
},
},
},
//
{
map: mapType.name,
zlevel: -1,
zoom: 1.01, //
roam: false, //
show: true,
tooltip: {
show: false //
},
label: {
show: false
},
emphasis: {
disabled: true
},
select: {
disabled: true
},
itemStyle: {
normal: {
borderJoin: "round",
borderColor: "rgba(176,228,252,1)",
borderWidth: 3,
areaColor: "rgba(133,188,232,1)",
shadowColor: "rgba(133,188,232,.7)",
shadowOffsetX: 0,
shadowOffsetY: 0,
shadowBlur: 25,
},
emphasis: {
show: false,
},
},
regionHright: 1,
},
],
tooltip: {
trigger: 'item',
formatter: function (params) {
let obj = dataValue.find(item => item.street_name == params.name);
if (!obj) {
obj = params.data
}
if (obj) {
return `<div
style="background-image: url(\'/src/assets/img/item-box.png\');
background-size: 100% 100%;
display: flex;
justify-content: space-evenly;
align-items: center;
width: 180px;
height: 80px;">
<div style="font-size: 15px;font-family: 'ifonts';">${obj?.street_name || ''}</div>
<div style="font-size: 12px;">
<p style="padding: 0;margin: 0">店铺:${obj?.mer_count || '0'}</p>
<p style="padding: 0;margin: 0">团队:${obj?.service_group_count || '0'}</p>
</div>
</div>`;
} else return '';
},
position: 'top',
// extraCssText: 'background-color: transparent; border: none;pdding: 0;', // CSS
backgroundColor: 'rgba(0, 156, 255, 0)', //
borderColor: "rgba(0, 156, 255, 0)",
padding: 0,
textStyle: {
color: '#fff'
}
},
series: [
{
type: "map",
map: mapType.name,
label: {
emphasis: {
show: false
},
color: 'rgba(0,0,0,0)'
},
emphasis: {
disabled: false,
},
select: {
disabled: true
},
itemStyle: {
normal: {
areaColor: "#3f5171",
borderColor: "#5bdbf6",
borderWidth: 1,
},
emphasis: {
areaColor: '#0680ca', //
}
},
},
{
name: "",
type: "scatter",
coordinateSystem: "geo",
data: dataValue,
symbol: "image://https://lihai001.oss-cn-chengdu.aliyuncs.com/def/6eb37202311281655342626.png",
symbolSize: [40, 30],
hoverSymbolSize: [60, 45],
symbol: "https://lihai001.oss-cn-chengdu.aliyuncs.com/def/0a86a202312081638007996.png",
symbolSize: [30, 45],
hoverSymbolSize: [45, 60],
label: {
formatter: "",
position: "center",
@ -185,34 +252,34 @@ const initMap = () => {
}
}
},
]
],
}
// 使
chart.setOption(option);
//
chart.dispatchAction({
type: 'updateLayout',
rotation: Math.PI / 4, //
});
// 3D
chart.setOption({
grid3D: {},
xAxis3D: {},
yAxis3D: {},
zAxis3D: {}
chart.on('click', function (params) {
if (params.componentType === 'series') {
if (params.seriesType === 'map') {
router.push({
path: '/delivery',
query: {
name: params.name
}
})
}
}
});
}
onMounted(() => {
changeType(appStore.map_info);
initDateValue();
dataValue = props.list;
changeType('luxian');
initDataValue();
initMap();
nextTick(() => {
mitt.on('map_info', e => {
changeType(e.pinyin);
initDateValue();
initDataValue();
initMap();
})
})
@ -222,7 +289,12 @@ onMounted(() => {
<template>
<div class="map">
<div class="echarts" ref="echartsRef"></div>
<div class="map-a">
<ani class="ani" />
</div>
<div class="map-e">
<div class="echarts" ref="echartsRef"></div>
</div>
</div>
</template>
@ -233,10 +305,30 @@ onMounted(() => {
display: flex;
justify-content: center;
align-items: center;
position: relative;
/* background-color: rgba($color: #fff, $alpha: 0.3); */
.echarts {
.map-a {
position: absolute;
bottom: -24%;
left: 0;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: flex-end;
}
.map-e {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
.echarts {
width: 100%;
height: 100%;
}
}
}
</style>

View File

@ -1,6 +1,7 @@
<script setup>
import { ref, reactive, onMounted } from "vue"
import * as echarts from 'echarts';
import videoFlv from "@/components/videoFlv.vue";
const initData = (data) => {
let arr = [];
@ -147,6 +148,8 @@ const initMap = () => {
chart2.setOption(option2);
}
const show = ref(false);
onMounted(() => {
initData();
initMap();
@ -185,7 +188,11 @@ onMounted(() => {
</div>
<div class="video">
<div class="left">
<img src="/src/assets/index_img/video.png" />
<!-- <img src="/src/assets/index_img/video.png" /> -->
<videoFlv
style="width: 100%; height: 100%"
url="http://192.168.1.27/live/test.live.flv?secret=gqig2yfkkdpimic1uwzy1l5msio0eflm"
/>
<div class="title">泸县原生态养殖基地</div>
</div>
<div class="right">
@ -203,7 +210,8 @@ onMounted(() => {
</div>
<div class="item">
<img src="/src/assets/index_img/video.png" />
<div class="title">泸县原生态养殖基地</div>
<!-- <div class="title">泸县原生态养殖基地</div> -->
<div class="btn" @click="show = true">查看全部</div>
</div>
</div>
</div>
@ -227,6 +235,20 @@ onMounted(() => {
</div>
</div>
</div>
<transition name="fade" appear>
<div class="box4" v-show="show">
<div class="vedio">
<div class="item" v-for="item in 4" :key="item">
<div class="name">
<img src="/src/assets/index_img/icon3.png" />
<span>泸县原生态养殖基地</span>
</div>
<img src="/src/assets/index_img/video.png" class="item-vedio" />
</div>
</div>
<div class="btn" @click="show = false">关闭弹窗</div>
</div>
</transition>
<div class="border"></div>
</div>
</template>
@ -250,10 +272,12 @@ onMounted(() => {
.box-title {
width: 100%;
position: relative;
height: 2.2rem;
line-height: 2.2rem;
.text {
text-align: left;
font-family: "ifonts";
padding: 0.2rem 0.8rem;
padding: 0 0.8rem;
font-size: 1.1rem;
}
.bg {
@ -269,7 +293,7 @@ onMounted(() => {
}
}
.box1 {
height: 34%;
height: 33%;
.tab {
display: flex;
justify-content: space-evenly;
@ -294,13 +318,24 @@ onMounted(() => {
}
}
.box2 {
height: 24%;
height: 25%;
.video {
height: 80%;
display: flex;
justify-content: space-between;
.title {
position: absolute;
left: 0;
bottom: 0;
width: 100%;
height: 20%;
display: flex;
justify-content: center;
align-items: center;
background-color: rgba($color: #000000, $alpha: 0.5);
}
.left {
width: 49%;
width: calc(50% - 0.6rem);
height: 100%;
position: relative;
font-size: 0.8rem;
@ -310,12 +345,39 @@ onMounted(() => {
display: flex;
height: 100%;
flex-wrap: wrap;
justify-content: space-between;
justify-content: space-evenly;
font-size: 0.6rem;
.item {
position: relative;
width: 48%;
height: 46%;
width: calc(50% - 0.3rem);
height: calc(50% - 0.3rem);
.btn {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: rgba(91, 219, 246, 0.4);
border: 0.1rem solid rgba(91, 219, 246, 1);
font-size: 0.8rem;
cursor: pointer;
width: 5rem;
height: 1.6rem;
border-radius: 1.6rem;
display: flex;
justify-content: center;
align-items: center;
}
&:nth-child(1) {
margin-right: 0.6rem;
}
&:nth-child(3) {
margin-right: 0.6rem;
margin-top: 0.6rem;
}
&:nth-child(4) {
margin-top: 0.6rem;
}
}
}
@ -323,11 +385,6 @@ onMounted(() => {
width: 100%;
height: 100%;
}
.title {
position: absolute;
left: 0;
bottom: 0;
}
}
}
.box3 {
@ -375,14 +432,105 @@ onMounted(() => {
}
}
}
.box4 {
position: absolute;
z-index: 99;
left: 0;
bottom: 0;
width: 96%;
height: calc(65% - 2.4rem);
background-image: url(../../../assets/index_img/box3.png);
background-size: 100% 100%;
.vedio {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
overflow-y: auto;
box-sizing: border-box;
margin: 3rem 2rem 1rem 0;
.item {
margin: 1rem 1rem 0 2rem;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.name {
width: 100%;
display: flex;
align-items: center;
margin-bottom: 0.5rem;
img {
height: 0.8rem;
width: auto;
margin-right: 0.5rem;
}
}
.item-vedio {
width: 94%;
height: 24vh;
}
}
}
.vedio::-webkit-scrollbar {
width: 0.6rem;
border-radius: 0.3rem;
background: linear-gradient(
to bottom,
rgba(0, 168, 255, 1),
rgba(75, 95, 219, 0.6)
);
}
.vedio::-webkit-scrollbar-track {
background: linear-gradient(
to bottom,
rgba(0, 168, 255, 1),
rgba(75, 95, 219, 0.6)
);
border-radius: 0.3rem;
}
.vedio::-webkit-scrollbar-thumb {
background-color: rgba(91, 219, 246, 1);
border-radius: 0.3rem;
}
.btn {
position: absolute;
top: 0;
right: 3%;
height: 4%;
width: 19%;
background-image: url(../../../assets/index_img/btn2.png);
background-size: 100% 100%;
display: flex;
justify-content: center;
align-items: center;
font-size: 0.9rem;
cursor: pointer;
}
}
.border {
background-image: url(../../../assets/img/border2.png);
background-size: 100% 100%;
height: 100%;
width: 0.4rem;
width: 0.6rem;
position: absolute;
top: 0;
right: 0;
}
}
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.5s;
}
.fade-enter,
.fade-leave-to {
opacity: 0;
}
</style>

View File

@ -87,10 +87,12 @@ onMounted(() => {
.box-title {
width: 100%;
position: relative;
height: 2.2rem;
line-height: 2.2rem;
.text {
text-align: left;
font-family: "ifonts";
padding: 0.2rem 0.8rem;
padding: 0 0.8rem;
font-size: 1.1rem;
}
.bg {
@ -166,7 +168,7 @@ onMounted(() => {
background-image: url(../../../assets/img/border1.png);
background-size: 100% 100%;
height: 100%;
width: 0.4rem;
width: 0.6rem;
position: absolute;
top: 0;
left: 0;

77
src/view/test/ani.vue Normal file
View File

@ -0,0 +1,77 @@
<script setup>
</script>
<template>
<div class="a-box">
<img class="img" src="/src/assets/ani/w.png" alt="" />
<div class="center">
<img class="img2" src="/src/assets/ani/z.png" alt="" />
</div>
<div class="top">
<img class="img3" src="/src/assets/ani/n.png" alt="" />
</div>
</div>
</template>
<style scoped lang="scss">
.a-box {
width: 800px;
height: 800px;
position: relative;
transform: rotateX(70deg);
.img {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
animation: rotate 30s linear infinite; /* 使用 rotate 动画2秒完成一次线性运动无限循环 */
}
.center {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
display: flex;
justify-content: center;
align-items: center;
.img2 {
width: 100%;
height: 100%;
animation: rotateZ 8s linear infinite; /* 使用 rotate 动画2秒完成一次线性运动无限循环 */
}
}
.top {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
display: flex;
justify-content: center;
align-items: center;
.img3 {
width: 100%;
height: 100%;
}
}
}
@keyframes rotate {
0% {
transform: rotate(0deg); /* 初始角度为0度 */
}
100% {
transform: rotate(360deg); /* 最终角度为360度即完整的一圈 */
}
}
@keyframes rotateZ {
0% {
transform: rotate(360deg); /* 初始角度为0度 */
}
100% {
transform: rotate(0deg); /* 最终角度为360度即完整的一圈 */
}
}
</style>

441
src/view/test/flvVedio.vue Normal file
View File

@ -0,0 +1,441 @@
<template>
<div class="root">
<div class="container-shell">
<div class="container-shell-title">jessibuca demo player <span class="tag-version" v-if="version">({{
version
}})</span></div>
<div class="option">
<span>缓冲():</span>
<input
style="width: 50px"
type="number"
ref="buffer"
value="0.2"
@change="changeBuffer"
/>
<input
type="checkbox"
v-model="useMSE"
ref="vod"
@change="restartPlay('mse')"
/><span>MediaSource</span>
<input
type="checkbox"
v-model="useWCS"
ref="vod"
@change="restartPlay('wcs')"
/><span>webcodecs</span>
</div>
<div id="container" ref="container"></div>
<div class="input">
<div>输入URL</div>
<input
type="input"
autocomplete="on"
ref="playUrl"
value=""
/>
<button v-if="!playing" @click="play">播放</button>
<button v-else @click="pause">停止</button>
</div>
<div class="input" v-if="loaded" style="line-height: 30px">
<button @click="destroy">销毁</button>
<button v-if="quieting" @click="cancelMute">取消静音</button>
<template v-else>
<button @click="mute">静音</button>
音量
<select v-model="volume" @change="volumeChange">
<option value="1">100</option>
<option value="0.75">75</option>
<option value="0.5">50</option>
<option value="0.25">25</option>
</select>
</template>
<span>旋转</span>
<select v-model="rotate" @change="rotateChange">
<option value="0">0</option>
<option value="90">90</option>
<option value="270">270</option>
</select>
<button @click="fullscreen">全屏</button>
<button @click="screenShot">截图</button>
<div style="line-height: 30px">
<input
type="checkbox"
ref="operateBtns"
v-model="showOperateBtns"
@change="restartPlay"
/><span></span>
<input
type="checkbox"
ref="operateBtns"
v-model="showBandwidth"
@change="restartPlay"
/><span></span>
<span v-if="performance">性能{{ performance }}</span>
</div>
</div>
<div class="input" v-if="loaded">
<input
type="checkbox"
ref="offscreen"
v-model="useOffscreen"
@change="restartPlay('offscreen')"
/><span></span>
<select v-model="scale" @change="scaleChange">
<option value="0">完全填充(拉伸)</option>
<option value="1">等比缩放</option>
<option value="2">完全填充(未拉伸)</option>
</select>
<button v-if="!playing" @click="clearView">清屏</button>
<template v-if="playing">
<select v-model="recordType">
<option value="webm">webm</option>
<option value="mp4">mp4</option>
</select>
<button v-if="!recording" @click="startRecord">录制</button>
<button v-if="!recording" @click="stopAndSaveRecord">暂停录制</button>
</template>
</div>
</div>
</div>
</template>
<script>
export default {
name: "DemoPlayer",
props: {},
data() {
return {
jessibuca: null,
version: '',
wasm: false,
vc: "ff",
playing: false,
quieting: true,
loaded: false, // mute
showOperateBtns: false,
showBandwidth: false,
err: "",
speed: 0,
performance: "",
volume: 1,
rotate: 0,
useWCS: false,
useMSE: true,
useOffscreen: false,
recording: false,
recordType: 'webm',
scale: 0
};
},
mounted() {
this.create();
window.onerror = (msg) => (this.err = msg);
},
unmounted() {
this.jessibuca.destroy();
},
methods: {
create(options) {
options = options || {};
this.jessibuca = new window.Jessibuca(
Object.assign(
{
container: this.$refs.container,
videoBuffer: Number(this.$refs.buffer.value), //
isResize: false,
useWCS: this.useWCS,
useMSE: this.useMSE,
text: "",
// background: "bg.jpg",
loadingText: "疯狂加载中...",
// hasAudio:false,
debug: true,
supportDblclickFullscreen: true,
showBandwidth: this.showBandwidth, //
operateBtns: {
fullscreen: this.showOperateBtns,
screenshot: this.showOperateBtns,
play: this.showOperateBtns,
audio: this.showOperateBtns,
},
vod: this.vod,
forceNoOffscreen: !this.useOffscreen,
isNotMute: true,
timeout: 10
},
options
)
);
var _this = this;
this.jessibuca.on("load", function () {
console.log("on load");
});
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 () {
console.log("on pause");
_this.playing = false;
});
this.jessibuca.on("play", function () {
console.log("on play");
_this.playing = true;
});
this.jessibuca.on("fullscreen", function (msg) {
console.log("on fullscreen", msg);
});
this.jessibuca.on("mute", function (msg) {
console.log("on mute", msg);
_this.quieting = msg;
});
this.jessibuca.on("mute", function (msg) {
console.log("on mute2", msg);
});
this.jessibuca.on("audioInfo", function (msg) {
console.log("audioInfo", 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('frame start');
})
this.jessibuca.on("performance", function (performance) {
var 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) {
console.log('kBps', kBps);
});
this.jessibuca.on("play", () => {
this.playing = true;
this.loaded = true;
this.quieting = this.jessibuca.isMute();
});
this.jessibuca.on('recordingTimestamp', (ts) => {
console.log('recordingTimestamp', ts);
})
// console.log(this.jessibuca);
},
play() {
// this.jessibuca.onPlay = () => (this.playing = true);
if (this.$refs.playUrl.value) {
this.jessibuca.play(this.$refs.playUrl.value);
}
},
mute() {
this.jessibuca.mute();
},
cancelMute() {
this.jessibuca.cancelMute();
},
pause() {
this.jessibuca.pause();
this.playing = false;
this.err = "";
this.performance = "";
},
volumeChange() {
this.jessibuca.setVolume(this.volume);
},
rotateChange() {
this.jessibuca.setRotate(this.rotate);
},
destroy() {
if (this.jessibuca) {
this.jessibuca.destroy();
}
this.create();
this.playing = false;
this.loaded = false;
this.performance = "";
},
fullscreen() {
this.jessibuca.setFullscreen(true);
},
clearView() {
this.jessibuca.clearView();
},
startRecord() {
const time = new Date().getTime();
this.jessibuca.startRecord(time, this.recordType);
},
stopAndSaveRecord() {
this.jessibuca.stopRecordAndSave();
},
screenShot() {
this.jessibuca.screenshot();
},
restartPlay(type) {
if (type === 'mse') {
this.useWCS = false;
this.useOffscreen = false;
} else if (type === 'wcs') {
this.useMSE = false
} else if (type === 'offscreen') {
this.useMSE = false
}
this.destroy();
setTimeout(() => {
this.play();
}, 100)
},
changeBuffer() {
this.jessibuca.setBufferTime(Number(this.$refs.buffer.value));
},
scaleChange() {
this.jessibuca.setScaleMode(this.scale);
},
},
};
</script>
<style>
.root {
display: flex;
place-content: center;
margin-top: 3rem;
}
.container-shell {
position: relative;
backdrop-filter: blur(5px);
background: hsla(0, 0%, 50%, 0.5);
padding: 30px 4px 10px 4px;
/* border: 2px solid black; */
width: auto;
position: relative;
border-radius: 5px;
box-shadow: 0 10px 20px;
}
.container-shell-title {
position: absolute;
color: darkgray;
top: 4px;
left: 10px;
text-shadow: 1px 1px black;
}
.tag-version {
}
#container {
background: rgba(13, 14, 27, 0.7);
width: 640px;
height: 398px;
}
.input {
display: flex;
align-items: center;
margin-top: 10px;
color: white;
place-content: stretch;
}
.input2 {
bottom: 0px;
}
.input input[type='input'] {
flex: auto;
}
.err {
position: absolute;
top: 40px;
left: 10px;
color: red;
}
.option {
position: absolute;
top: 4px;
right: 10px;
display: flex;
place-content: center;
font-size: 12px;
}
.option span {
color: white;
}
.page {
background: url(/bg.jpg);
background-repeat: no-repeat;
background-position: top;
}
@media (max-width: 720px) {
#container {
width: 90vw;
height: 52.7vw;
}
}
</style>

View File

@ -0,0 +1,54 @@
<template>
<div class="tunnelvideo">
<video
class="videosmall"
ref="videosmallone"
preload="auto"
muted
autoplay
type="rtmp/flv"
style="height: 500px; width: 1000px"
>
<source src="" />
</video>
</div>
</template>
<script setup>
import flvjs from 'flv.js';
import { onMounted, ref } from 'vue';
const videosmallone = ref(null)
const initPlayer = async () => {
if (flvjs.isSupported()) {
const flvPlayer = flvjs.createPlayer({
type: 'flv',
isLive: true, //
hasAudio: true, //
hasVideo: true, //
cors: true,
// enableStashBuffer: true, //
url: 'http://rtsp.lihaink.cn/live/test.live.flv?secret=YwDtp2llj80HA19JhMXL4Po99nsMAyNT' //
});
flvPlayer.attachMediaElement(videosmallone.value);
try {
flvPlayer.load()
flvPlayer.play()
// flvPlayer.pause()
} catch (err) {
// not do something
console.log(err);
}
} else {
console.error('不支持 flv.js');
}
}
onMounted(() => {
setTimeout(() => {
initPlayer()
}, 100)
})
</script>

9
src/view/test/index.vue Normal file
View File

@ -0,0 +1,9 @@
<template>
<!-- <JessibucaDemo /> -->
<ani />
</template>
<script setup>
import JessibucaDemo from './flvVedio.vue'
import ani from "./ani.vue"
</script>