| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818 |
- <!DOCTYPE html>
- <html lang=zh-CN>
- <head>
- <meta charset="utf-8" />
- <meta name="viewport"
- content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
- <title>监控详情页</title>
- <link href="https://unpkg.com/video.js@7.10.2/dist/video-js.min.css" rel="stylesheet" />
- <style type="text/css">
- body {
- margin: 0;
- background-color: #f3f3f3;
- }
- span.vjs-control-text {
- display: none;
- }
- /* iframe {
- width: 375px;
- height: 667px;
- background-color: #fff;
- box-sizing: content-box;
- border: none;
- } */
- .btn-box {
- margin-top: 20px;
- display: flex;
- flex-direction: row;
- justify-content: space-around;
- align-items: center;
- }
- .btn-container {
- position: relative;
- }
- .videoBtnPlay {
- position: absolute;
- height: 100px;
- width: 100px;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- }
- .more,
- .less {
- flex: 1
- }
- img {
- width: 100%;
- }
- .direc {
- width: 150px;
- height: 150px;
- background: url('https://s3.hnyfwlw.com/webstaticimg/bigdata_app/image/monitor/1.png');
- background-size: 100% auto;
- background-repeat: no-repeat;
- position: relative;
- display: flex;
- justify-content: center;
- align-items: center;
- }
- .direc div {
- width: 50px;
- height: 50px;
- position: absolute;
- }
- .photo {
- font-size: 30px;
- color: #4ec467;
- padding: 16px;
- }
- .top {
- top: 0;
- left: 50px
- }
- .bottom {
- bottom: 0;
- left: 50px
- }
- .left {
- left: 0;
- top: 50px
- }
- .right {
- right: 0;
- top: 50px
- }
- #box {
- height: 300px;
- width: 100%;
- background: #000;
- overflow: hidden;
- }
- #dialog {
- display: none;
- min-width: 200px;
- line-height: 80px;
- background: rgba(0, 0, 0, .8);
- color: #fff;
- text-align: center;
- position: absolute;
- left: 50%;
- margin-left: -100px;
- border-radius: 4px;
- z-index: 999;
- top: 50%;
- margin-top: -40px;
- }
- .imgBtn {
- position: absolute;
- width: 100%;
- padding: 10px;
- bottom: 0;
- left: 0;
- text-align: center;
- color: #338cd9;
- font-size: 16px;
- box-sizing: border-box;
- display: flex;
- justify-content: center;
- gap: 16px;
- }
- .imgBtn div {
- /* padding: 0 16px; */
- }
- .imgBtn img {
- display: inline-block;
- width: 20px;
- height: 20px;
- vertical-align: middle;
- margin-right: 2px;
- margin-bottom: 3px;
- }
- .imgBtnDgp {
- display: none;
- }
- </style>
- </head>
- <body>
- <div class="btn-container">
- <div id="box"> </div>
- <div class="videoBtnPlay">
- <img src="https://webstaticimg.oss-cn-hangzhou.aliyuncs.com/bigdata_app/img/wxplayer.png" />
- </div>
- </div>
- <div id="dialog">
- </div>
- <div class="btn-box">
- <div class="more" ontouchstart="_configCamera('move', 8)" ontouchend="_stopConfigCamera()">
- <image src="https://s3.hnyfwlw.com/webstaticimg/bigdata_app/image/monitor/3.png" mode="widthFix">
- </image>
- </div>
- <div class="direc">
- <div class="top" ontouchstart="_configCamera('move', 0)" ontouchend="_stopConfigCamera()">
- </div>
- <div class="bottom" ontouchstart="_configCamera('move', 1)" ontouchend="_stopConfigCamera()">
- </div>
- <p class="photo yficonfont icon-paizhao-xianxing" ontouchstart="_configCamera('takephoto', '')">
- </p>
- <div class="left" ontouchstart="_configCamera('move', 2)" ontouchend="_stopConfigCamera()">
- </div>
- <div class="right" ontouchstart="_configCamera('move', 3)" ontouchend="_stopConfigCamera()">
- </div>
- </div>
- <div class="less" ontouchstart="_configCamera('move', 9)" ontouchend="_stopConfigCamera()">
- <image src="https://s3.hnyfwlw.com/webstaticimg/bigdata_app/image/monitor/2.png" mode="widthFix">
- </image>
- </div>
- </div>
- <div class="imgBtn">
- <div class="imgBtnCamrea"> <img src="https://webstaticimg.oss-cn-hangzhou.aliyuncs.com/bigdata_app/img/img_icon.png" />查看图片</div>
- <div class="imgBtnDgp"><img src="https://webstaticimg.oss-cn-hangzhou.aliyuncs.com/bigdata_app/img/img_icon.png" />查看光谱图片</div>
- </div>
- </body>
- <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
- <!-- 微信 JS-SDK 如果不需要兼容小程序,则无需引用此 JS 文件。 -->
- <!-- <script type="text/javascript" src="//res.wx.qq.com/open/js/jweixin-1.4.0.js"></script> -->
- <!-- uni 的 SDK -->
- <script type="text/javascript" src="https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.2.js"></script>
- <script src="https://unpkg.com/video.js@7.10.2/dist/video.min.js"></script>
- <script type="module">
- import Player from 'https://wx.hnyfwlw.com/wexin/videoPlayer/videoPlay-js.js'
- // const domin = 'https://wx.hnyfwlw.com'
- const domin = 'http://218.28.198.186:10508'
- // 检测HLS支持
- function checkHLSSupport() {
- const video = document.createElement('video');
- return video.canPlayType('application/vnd.apple.mpegurl') !== '' ||
- video.canPlayType('application/x-mpegURL') !== '';
- }
-
- // 加载HLS.js库(如果需要)
- function loadHLSJS() {
- return new Promise((resolve, reject) => {
- if (window.Hls) {
- resolve();
- return;
- }
-
- const script = document.createElement('script');
- script.src = 'https://cdn.jsdelivr.net/npm/hls.js@latest';
- script.onload = () => {
- console.log('HLS.js加载完成');
- resolve();
- };
- script.onerror = reject;
- document.head.appendChild(script);
- });
- }
-
- let player = null
- let stopTimer = 0
-
- // 更安全的URL参数解析
- function getUrlParam(name) {
- const urlParams = new URLSearchParams(window.location.search)
- return urlParams.get(name) || ''
- }
-
- var device_id = getUrlParam('device_id')
- var accessToken = getUrlParam('accessToken')
- var videoType = getUrlParam('videoType')
- var token = accessToken
-
- console.log('解析结果:', { device_id, accessToken, videoType })
- console.log('视频类型检查:', videoType, videoType === 'dgp')
- // 通用错误处理函数
- function showError(message, duration = 3000) {
- $('#dialog').html(message).stop().show(500).delay(duration).hide(500);
- $('.videoBtnPlay').show();
- }
-
- // 安全的JSON解析
- function safeParseJSON(str) {
- try {
- return JSON.parse(str);
- } catch(e) {
- console.warn('JSON解析失败,尝试eval:', e);
- try {
- return eval('(' + str + ')');
- } catch(e2) {
- console.error('数据解析完全失败:', e2);
- return null;
- }
- }
- }
-
- // 验证API响应
- function validateAPIResponse(res, apiName = 'API') {
- console.log(`${apiName}响应:`, res);
-
- if (!res) {
- console.error(`${apiName}响应为空`);
- return { valid: false, error: '服务器无响应' };
- }
-
- if (res.message && res.message !== '') {
- console.error(`${apiName}返回错误:`, res.message);
- return { valid: false, error: res.message };
- }
-
- if (!res.data) {
- console.error(`${apiName}返回数据为空`);
- return { valid: false, error: '返回数据为空' };
- }
-
- return { valid: true, data: res.data };
- }
-
- // 获取可用的视频源
- function getAvailableVideoSource(data, preferredType = 'hls') {
- const sources = {
- hls: data.hls,
- hlsHd: data.hlsHd,
- rtmp: data.rtmp,
- rtsp: data.rtsp
- };
-
- console.log('可用视频源:', sources);
-
- // 优先使用指定类型
- if (sources[preferredType] && sources[preferredType] !== 'undefined' && sources[preferredType] !== '') {
- return { source: sources[preferredType], type: preferredType };
- }
-
- // 按优先级查找可用源
- const priority = ['hls', 'hlsHd', 'rtmp', 'rtsp'];
- for (const type of priority) {
- if (sources[type] && sources[type] !== 'undefined' && sources[type] !== '') {
- return { source: sources[type], type: type };
- }
- }
-
- return { source: null, type: null };
- }
-
- // 检查设备状态
- function checkDeviceStatus() {
- console.log('检查设备状态...');
- $('#dialog').html('检查设备状态...').stop().show();
-
- return $.ajax({
- type: "POST",
- url: `${domin}/api/api_gateway?method=device.device_manage.get_device_info`,
- data: {
- device_id: device_id,
- token: token
- },
- timeout: 5000
- }).then((res) => {
- console.log('设备状态响应:', res);
- if (res && res.message === '' && res.data) {
- const deviceInfo = typeof res.data === 'string' ? safeParseJSON(res.data) : res.data;
- console.log('设备信息:', deviceInfo);
- return deviceInfo;
- } else {
- throw new Error(res.message || '获取设备信息失败');
- }
- }).catch((error) => {
- console.error('设备状态检查失败:', error);
- showError('设备状态检查失败: ' + (error.message || '网络错误'));
- throw error;
- });
- }
-
- window._configCamera = configCamera;
- window._stopConfigCamera = stopConfigCamera;
- window._postPic = postPic;
-
- // 确保DOM加载完成后再执行jQuery操作
- $(document).ready(function() {
- // 初始化HLS支持
- if (!checkHLSSupport()) {
- console.log('浏览器不支持原生HLS,加载HLS.js');
- loadHLSJS().catch(e => {
- console.error('HLS.js加载失败:', e);
- });
- }
-
- if (videoType == 'dgp') {
- $('.imgBtnDgp').show()
- } else {
- $('.imgBtnDgp').hide()
- }
-
- $('.photo').click(() => {
- // 拍照功能
- })
- })
- function configCamera(ctrl, movenum) {
- if (ctrl == "takephoto") {
- if (player) {
- // 云联的拍照特殊处理
- player.screenshot('yunlianPlayer')
- } else {
- $('#dialog').html('拍照指令正在下发,请等待...').stop().show(50)
- let url = `${domin}/api/api_gateway?method=camera.camera_manage.camera_takephoto`
- if (videoType == 'dgp') {
- url = `${domin}/api/api_gateway?method=camera.camera_manage.multi_camera_takephoto`
- }
- $.ajax({
- type: "POST",
- url: url,
- data: {
- device_id: device_id,
- token
- }
- }).then((res) => {
- if (res.data == true) {
- $('#dialog').html('拍照成功').stop().show(500).delay(1000).hide(500)
- } else {
- $('#dialog').html(res.message).stop().show(500).delay(1000).hide(500)
- }
- });
- }
- } else {
- let url = `${domin}/api/api_gateway?method=camera.camera_manage.ctrl_camera`
- let postData = {
- device_id: device_id,
- token
- }
- if (videoType == 'dgp') {
- url = `${domin}/api/api_gateway?method=camera.camera_manage.multi_ctrl_camera`
- postData.ctrl = movenum
- } else {
- postData.ctrl = ctrl
- postData.movenum = movenum
- }
- //上下左右、放大、缩小
- $.ajax({
- type: "POST",
- url: url,
- data: postData
- }).then((res) => {
- $('#dialog').html('指令下发成功,请等待...').stop().show(500).delay(3000).hide(500)
- })
- }
- }
- function stopConfigCamera() {
- if (videoType == 'dgp') {
- if(stopTimer) clearTimeout(stopTimer)
- stopTimer = setTimeout(()=>{
- $.ajax({
- type: "POST",
- url: "http://47.110.79.22:9000/api/api_gateway?method=camera.camera_manage.mulit_stop_move",
- data: {
- device_id: device_id,
- token
- },
- });
- },3000)
-
- } else {
- $.ajax({
- type: "POST",
- url: "http://47.110.79.22:9000/api/api_gateway?method=camera.camera_manage.ctrl_camera",
- data: {
- device_id: device_id,
- ctrl: "stop",
- token
- },
- });
- }
- }
- function postPic(file) {
- let form = new FormData()
- form.append('img_file', file)
- form.append('device_id', device_id)
- form.append('token', token)
- $.ajax({
- type: "POST",
- url: "http://47.110.79.22:9000/api/api_gateway?method=camera.camera_manage.save_camera_photo",
- contentType: false,
- processData: false,
- data: form
- }).then((res) => {
- if (res.message == '') {
- $('#dialog').html('拍照成功').stop().show(500).delay(1500).hide(500)
- } else {
- $('#dialog').html(res.data.message).stop().show(500).delay(1500).hide(500)
- }
- });
- }
- async function initYunlianPlayer(videoURL) {
- var playHtml =
- `<div id="yunlianPlayer" style="width: 100%;height: 300px;overflow: hidden;"></div>`;
- $("#box").html(playHtml)
- player = new Player(['yunlianPlayer'], {
- playFileOver: () => {
- console.log('播放结束')
- },
- playError: (id, e) => {
- console.log('播放错误', id, e)
- },
- talkStart: () => {
- console.log('对讲开始')
- },
- runtimeInitializedCallBack: () => {
- console.log('播放器初始化完成')
- },
- captureCallback: (id, data) => {
- // console.log('截图返回的数据', data.buffer)
- const blob = new Blob([data], {
- type: 'image/jpeg'
- })
- _postPic(blob)
- }
- })
- await player.init()
- setTimeout(() => {
- player.play('yunlianPlayer', {
- streamURL: videoURL,
- channelId: '0',
- bitStream: '0',
- isLive: true
- })
- }, 1000)
- }
- $('.videoBtnPlay').click(function() {
- $('.videoBtnPlay').hide()
- console.log(videoType,'videoTypevideoType')
-
- // 显示加载提示
- $('#dialog').html('正在获取视频流...').stop().show();
-
- // 先检查设备状态(可选,如果API支持的话)
- // checkDeviceStatus().then(() => {
- if (videoType == 'dgp') {
- $.ajax({
- type: "POST",
- url: "http://47.110.79.22:9000/api/api_gateway?method=camera.camera_manage.multi_addr_camera",
- data: {
- device_id: device_id,
- token
- },
- timeout: 15000 // 15秒超时
- }).then((res) => {
- $('#dialog').hide(); // 隐藏加载提示
-
- const validation = validateAPIResponse(res, 'DGP视频流API');
- if (!validation.valid) {
- showError(validation.error);
- return;
- }
-
- let data = validation.data;
- if (typeof data == 'string') {
- data = safeParseJSON(data);
- if (!data) {
- showError('DGP数据解析失败');
- return;
- }
- }
-
- console.log('DGP解析后的数据:', data);
-
- // 获取可用的视频源(DGP优先使用rtmp)
- const videoSource = getAvailableVideoSource(data, 'rtmp');
-
- if (!videoSource.source) {
- console.error('DGP没有找到可用的视频源');
- showError('设备可能离线或未配置视频流,请检查设备状态');
- return;
- }
-
- console.log(`使用${videoSource.type}视频源:`, videoSource.source);
-
- console.log(`使用${videoSource.type}视频源:`, videoSource.source);
-
- const hlsHdSrc = videoSource.source;
-
- var playHtml =
- `<video id="myPlayer" poster='' controls playsInline webkit-playsinline style="width:100%; height:100%;"></video>`;
- $("#box").html(playHtml)
-
- var myVideo = videojs(`myPlayer`, {
- controls: true,
- autoplay: false,
- preload: 'metadata',
- sources: [{
- type: videoSource.type === 'rtmp' ? 'rtmp/flv' : 'application/x-mpegURL',
- src: hlsHdSrc,
- }],
- html5: {
- hls: {
- enableLowInitialPlaylist: true,
- smoothQualityChange: true,
- overrideNative: true
- }
- }
- }, function onPlayerReady() {
- console.log('DGP播放器准备完成');
- // 延迟播放,确保源加载完成
- setTimeout(() => {
- myVideo.play().catch(e => {
- console.error('DGP播放失败:', e);
- showError('DGP视频播放失败: ' + e.message);
- });
- }, 500);
- });
-
- // 添加错误处理
- myVideo.on('error', function(e) {
- console.error('DGP Video.js错误:', e, myVideo.error());
- const error = myVideo.error();
- let errorMsg = 'DGP视频播放出错';
-
- if (error) {
- switch(error.code) {
- case 1:
- errorMsg = 'DGP视频加载被中止';
- break;
- case 2:
- errorMsg = 'DGP网络错误导致视频下载失败';
- break;
- case 3:
- errorMsg = 'DGP视频解码失败';
- break;
- case 4:
- errorMsg = 'DGP视频格式不支持或视频源无效';
- break;
- default:
- errorMsg = 'DGP未知播放错误';
- }
- }
-
- showError(errorMsg);
- });
-
- myVideo.on('play', function() {
- console.log('DGP开始播放')
- });
-
- myVideo.on('loadstart', function() {
- console.log('DGP开始加载视频');
- });
-
- myVideo.on('canplay', function() {
- console.log('DGP视频可以播放');
- });
- })
- } else {
- $.ajax({
- type: "POST",
- // url: "http://47.110.79.22:9000/api/api_gateway?method=camera.camera_manage.multi_addr_camera",
- url: "http://192.168.1.107:8000/api/api_gateway?method=camera.camera_manage.multi_addr_camera",
- data: {
- device_id: device_id,
- token
- // device_id: 'FA8690323-1',
- // token: localStorage.getItem('session_key')
- }
- }).then((res) => {
- console.log('API响应:', res);
- if (res && res.message == '') {
- var data = null
- if (typeof res.data == 'string') {
- data = safeParseJSON(res.data);
- } else {
- data = res.data;
- }
-
- if (!data) {
- showError('数据解析失败');
- return;
- }
-
- console.log('解析后的数据:', data);
- console.log('数据字段检查:', {
- type_id: data.type_id,
- hls: data.hls,
- hlsHd: data.hlsHd,
- rtsp: data.rtsp,
- rtmp: data.rtmp
- });
-
- if (data.type_id == 2) {
- // 大华云联
- if (!data.rtsp || data.rtsp === 'undefined' || data.rtsp === '') {
- console.error('RTSP视频源无效:', data.rtsp);
- showError('RTSP视频源获取失败,请检查设备配置');
- return;
- }
- initYunlianPlayer(data.rtsp)
- } else {
- let hlsHdSrc = data.type_id == 0 ? data.hls : data.hlsHd;
-
- console.log('选择的视频源字段:', data.type_id == 0 ? 'hls' : 'hlsHd');
- console.log('视频源值:', hlsHdSrc);
-
- // 如果主要源无效,尝试备用源
- if (!hlsHdSrc || hlsHdSrc === 'undefined' || hlsHdSrc === '') {
- console.warn('主要视频源无效,尝试备用源');
- hlsHdSrc = data.hls || data.hlsHd || data.rtmp || data.rtsp;
- console.log('备用视频源:', hlsHdSrc);
- }
-
- // 验证视频源
- if (!hlsHdSrc || hlsHdSrc === 'undefined' || hlsHdSrc === '') {
- console.error('所有视频源都无效:', {
- hls: data.hls,
- hlsHd: data.hlsHd,
- rtmp: data.rtmp,
- rtsp: data.rtsp
- });
- showError('视频源获取失败,请检查设备是否在线或联系管理员');
- return;
- }
-
- console.log('视频源:', hlsHdSrc);
-
- var playHtml =
- `<video id="myPlayer" poster='' controls playsInline webkit-playsinline style="width:100%; height:100%;"></video>`;
- $("#box").html(playHtml)
-
- var myVideo = videojs(`myPlayer`, {
- controls: true,
- autoplay: false,
- preload: 'metadata',
- sources: [{
- type: 'application/x-mpegURL',
- src: hlsHdSrc,
- }],
- html5: {
- hls: {
- enableLowInitialPlaylist: true,
- smoothQualityChange: true,
- overrideNative: true
- }
- }
- }, function onPlayerReady() {
- console.log('播放器准备完成');
- setTimeout(() => {
- myVideo.play().catch(e => {
- console.error('播放失败:', e);
- $('#dialog').html('视频播放失败: ' + e.message).stop().show(500).delay(3000).hide(500);
- $('.videoBtnPlay').show();
- });
- }, 500);
- });
-
- // 添加错误处理
- myVideo.on('error', function(e) {
- console.error('Video.js错误:', e, myVideo.error());
- const error = myVideo.error();
- let errorMsg = '视频播放出错';
-
- if (error) {
- switch(error.code) {
- case 1:
- errorMsg = '视频加载被中止';
- break;
- case 2:
- errorMsg = '网络错误导致视频下载失败';
- break;
- case 3:
- errorMsg = '视频解码失败';
- break;
- case 4:
- errorMsg = '视频格式不支持或视频源无效';
- break;
- default:
- errorMsg = '未知播放错误';
- }
- }
-
- $('#dialog').html(errorMsg).stop().show(500).delay(3000).hide(500);
- $('.videoBtnPlay').show();
- });
-
- myVideo.on('play', function() {
- console.log('开始播放')
- });
-
- myVideo.on('loadstart', function() {
- console.log('开始加载视频');
- });
-
- myVideo.on('canplay', function() {
- console.log('视频可以播放');
- });
- }
- } else {
- alert(res.message)
- }
- })
- }
- })
- document.addEventListener('UniAppJSBridgeReady', function() {
- $('.imgBtnCamrea').click(function() {
- // if (player) {
- // player.close('yunlianPlayer')
- // player = null
- // }
- uni.navigateTo({
- url: '/pages/monitor/imagelist?id=' + device_id
- })
- })
- $('.imgBtnDgp').click(function() {
- // if (player) {
- // player.close('yunlianPlayer')
- // player = null
- // }
- uni.navigateTo({
- url: '/pages/monitor/dgpImagelist?id=' + device_id
- })
- })
- });
- </script>
- </html>
|