Pārlūkot izejas kodu

修改语音对讲功能界面,新增获取推流参数接口

kindring 2 gadi atpakaļ
vecāks
revīzija
633bbb2a4a

+ 15 - 12
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java

@@ -530,8 +530,11 @@ public class SIPCommander implements ISIPCommander {
         content.append("s=Play\r\n");
         content.append("c=IN IP4 " + mediaServerItem.getSdpIp() + "\r\n");
         content.append("t=" + 0 + " "+ 0 + "\r\n");
-        content.append("m=audio " + ssrcInfo.getPort() + " TCP/RTP/AVP 8\r\n");
+        content.append("m=audio " + ssrcInfo.getPort() + " TCP/RTP/AVP 0 8\r\n");
         content.append("a=sendonly\r\n");
+//        content.append("a=rtpmap:8 PCMA/8000\r\n");
+        // webrtc 的sdp定义的音频格式
+        content.append("a=rtpmap:0 PCMU/8000/1\r\n");
         content.append("a=rtpmap:8 PCMA/8000\r\n");
         content.append("a=setup:passive\r\n");
         content.append("y=" + ssrcInfo.getSsrc() + "\r\n");//ssrc
@@ -552,17 +555,17 @@ public class SIPCommander implements ISIPCommander {
         try {
             CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
                     : udpSipProvider.getNewCallId();
-            dynamicTask.startDelay(callIdHeader.getCallId(), () -> {
-                logger.info("Ack 等待超时");
-                // 释放 zlm 的推流端口
-                mediaServerService.releaseSsrc(mediaServerItem.getId(), _ssrc );
-                // todo 等待 broadcast invite的 200 sdp 超时  回复bye
-//                try {
-//                    cmderFroPlatform.streamByeCmd(platform, callIdHeader.getCallId());
-//                } catch (SipException | InvalidArgumentException | ParseException e) {
-//                    logger.error("[命令发送失败] 语音广播 发送BYE: {}", e.getMessage());
-//                }
-            }, 60 * 1000);
+//            dynamicTask.startDelay(callIdHeader.getCallId(), () -> {
+//                logger.info("Ack 等待超时");
+//                // 释放 zlm 的推流端口
+//                mediaServerService.releaseSsrc(mediaServerItem.getId(), _ssrc );
+//                // todo 等待 broadcast invite的 200 sdp 超时  回复bye
+////                try {
+////                    cmderFroPlatform.streamByeCmd(platform, callIdHeader.getCallId());
+////                } catch (SipException | InvalidArgumentException | ParseException e) {
+////                    logger.error("[命令发送失败] 语音广播 发送BYE: {}", e.getMessage());
+////                }
+//            }, 60 * 1000);
 //            testInviteRequestProcessor.responseBroadcastSdpACK(serverTransaction,
 //                    sdpContent,
 //                    device.getDeviceId(),

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

@@ -26,4 +26,6 @@ public interface IUserService {
     PageInfo<User> getUsers(int page, int count);
 
     int changePushKey(int id, String pushKey);
+
+    String getPushKey(int id);
 }

+ 9 - 0
src/main/java/com/genersoft/iot/vmp/service/impl/UserServiceImpl.java

@@ -79,4 +79,13 @@ public class UserServiceImpl implements IUserService {
     public int changePushKey(int id, String pushKey) {
         return userMapper.changePushKey(id,pushKey);
     }
+
+    @Override
+    public String getPushKey(int id) {
+        List<User> users = userMapper.getPushKey(id);
+        if (!users.isEmpty()) {
+            return users.get(0).getPushKey();
+        }
+        return null;
+    }
 }

+ 3 - 0
src/main/java/com/genersoft/iot/vmp/storager/dao/UserMapper.java

@@ -62,4 +62,7 @@ public interface UserMapper {
 
     @Update("update user set pushKey=#{pushKey} where id=#{id}")
     int changePushKey(int id, String pushKey);
+
+    @Select("select u.id,u.pushKey from user as u where id=#{id}")
+    List<User> getPushKey(int id);
 }

+ 26 - 1
src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java

@@ -4,14 +4,17 @@ import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.genersoft.iot.vmp.VManageBootstrap;
 import com.genersoft.iot.vmp.common.VersionPo;
+import com.genersoft.iot.vmp.conf.MediaConfig;
 import com.genersoft.iot.vmp.conf.SipConfig;
 import com.genersoft.iot.vmp.conf.UserSetting;
 import com.genersoft.iot.vmp.conf.VersionInfo;
 import com.genersoft.iot.vmp.conf.exception.ControllerException;
+import com.genersoft.iot.vmp.conf.security.SecurityUtils;
 import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe;
 import com.genersoft.iot.vmp.media.zlm.dto.IHookSubscribe;
 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
 import com.genersoft.iot.vmp.service.IMediaServerService;
+import com.genersoft.iot.vmp.service.IUserService;
 import com.genersoft.iot.vmp.utils.SpringBeanFactory;
 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
 import gov.nist.javax.sip.SipStackImpl;
@@ -56,10 +59,14 @@ public class ServerController {
     @Value("${server.port}")
     private int serverPort;
 
-
+    @Autowired
+    private MediaConfig mediaConfig;
     @Autowired
     private ThreadPoolTaskExecutor taskExecutor;
 
+    @Autowired
+    private IUserService userService;
+
     @GetMapping(value = "/media_server/list")
     @ResponseBody
     @Operation(summary = "流媒体服务列表")
@@ -195,6 +202,24 @@ public class ServerController {
         return jsonObject;
     }
 
+    @GetMapping(value = "/pushConfig")
+    @Operation(summary = "获取配置信息")
+    @Parameter(name = "type", description = "配置类型(sip, base)", required = true)
+    @ResponseBody
+    public JSONObject getPushConfig(){
+        JSONObject jsonObject = new JSONObject();
+        String httpsHook = "https://"+mediaConfig.getIp() +":"+ mediaConfig.getHttpSSlPort();
+        String httpHook = "http://"+mediaConfig.getIp() +":"+ mediaConfig.getHttpPort();
+        // 获取zlm的hook端口
+        jsonObject.put("httpsHook",httpsHook);
+        jsonObject.put("httpHook",httpHook);
+        // 获取pushKey的值
+        int currenRoleId = SecurityUtils.getUserInfo().getRole().getId();
+        String pushKey = userService.getPushKey(currenRoleId);
+        jsonObject.put("pushKey",pushKey);
+        return jsonObject;
+    }
+
     @GetMapping(value = "/hooks")
     @ResponseBody
     @Operation(summary = "获取当前所有hook")

+ 5 - 5
src/main/resources/application.yml

@@ -97,7 +97,7 @@ sip:
     # [必须修改] 本机的IP, 必须是网卡上的IP,用于sip下协议栈监听ip,如果监听所有设置为0.0.0.0
     monitor-ip: 0.0.0.0
     # [必须修改] 本机的IP
-    ip: kindring.cn
+    ip: 192.168.1.26
     # [可选] 28181服务监听的端口
     port: 29000
     # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007)
@@ -127,13 +127,13 @@ media:
     # [必须修改] zlm服务器唯一id,用于触发hook时区别是哪台服务器,general.mediaServerId
     id: your_server_id
     # [必须修改] zlm服务器的内网IP
-    ip: 119.91.250.126
+    ip: 192.168.1.60
     # [可选] 返回流地址时的ip,置空使用 media.ip
-    stream-ip: kindring.cn
+    stream-ip: 192.168.1.60
     #stream-ip: 192.168.1.203
     #stream-ip: 113.88.194.58
     # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip
-    sdp-ip: kindring.cn
+    sdp-ip: 192.168.1.60
     #sdp-ip: 192.168.1.203
     #sdp-ip: 113.88.194.58
     # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip
@@ -141,7 +141,7 @@ media:
     # [必须修改] zlm服务器的http.port
     http-port: 15070
     # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置
-    http-ssl-port:
+    http-ssl-port: 29010
     # [可选] zlm服务器的rtmp.port, 置空使用zlm配置文件配置
     rtmp-port:
     # [可选] zlm服务器的rtmp.sslport, 置空使用zlm配置文件配置

+ 2 - 2
web_src/config/index.js

@@ -3,8 +3,8 @@
 // see http://vuejs-templates.github.io/webpack for documentation.
 
 const path = require('path')
-const baseUrl = "https://192.168.31.250:29001"
-const ZLMServer = "https://kindring.cn:29010"
+const baseUrl = "https://192.168.1.26:29001"
+const ZLMServer = "https://192.168.1.60:29010"
 module.exports = {
   dev: {
 

+ 33 - 3
web_src/src/components/common/DeviceTree.vue

@@ -1,10 +1,13 @@
 <template>
   <div id="DeviceTree" style="width: 100%;height: 100%; background-color: #FFFFFF; overflow: auto">
     <el-container>
-      <el-header>设备列表</el-header>
+      <el-header>设备列表
+        <el-button icon="el-icon-refresh-right" circle size="mini" :loading="isLoading"
+                                 @click="reloadDeviceTree"></el-button>
+      </el-header>
       <el-main style="background-color: #ffffff;">
         <div class="device-tree-main-box">
-          <el-tree ref="gdTree" :props="defaultProps" :load="loadNode" lazy @node-click="handleNodeClick"@node-contextmenu="handleContextMenu" node-key="id" style="min-width: 100%; display:inline-block !important;">
+          <el-tree ref="gdTree" :props="defaultProps" :load="loadNode" lazy @node-click="handleNodeClick" @node-contextmenu="handleContextMenu" node-key="id" style="min-width: 100%; display:inline-block !important;">
             <span class="custom-tree-node" slot-scope="{ node, data }" style="width: 100%">
               <span v-if="node.data.type === 0 && node.data.online" title="在线设备" class="device-online iconfont icon-jiedianleizhukongzhongxin2"></span>
               <span v-if="node.data.type === 0 && !node.data.online " title="离线设备" class="device-offline iconfont icon-jiedianleizhukongzhongxin2"></span>
@@ -44,11 +47,38 @@ export default {
             children: 'children',
             label: 'name',
             isLeaf: 'isLeaf'
-          }
+          },
+          isLoading: false,
         };
     },
     props: ['device', 'onlyCatalog', 'clickEvent', 'contextMenuEvent'],
     methods: {
+      reloadDeviceTree(){
+        this.isLoading = true;
+        const tree = this.$refs.gdTree.root; // root在this.$refs.tree中找到
+        this.deviceService.getAllDeviceList((data)=> {
+          console.log(data)
+          this.isLoading = false;
+          if (data.length > 0) {
+            let nodeList = []
+            for (let i = 0; i < data.length; i++) {
+              console.log(data[i].name)
+              let node = {
+                name: data[i].name || data[i].deviceId,
+                isLeaf: false,
+                id: data[i].deviceId,
+                type: data[i].online,
+                online: data[i].online === 1,
+                userData: data[i]
+              }
+              nodeList.push(node);
+            }
+            tree.setData(nodeList);
+          } else {
+            tree.setData([]);
+          }
+        })
+      },
       handleNodeClick(data,node,element) {
         let deviceNode = this.$refs.gdTree.getNode(data.userData.deviceId)
         if(typeof (this.clickEvent) == "function") {

+ 130 - 173
web_src/src/components/common/microphone.vue

@@ -1,7 +1,7 @@
 <template>
-  <div class="microPhone">
-    <div class="mic" @mousedown="mouseDownHandle" @mouseup="mouseUpHandle">
-      {{isRecording?'录音中...':'开始录音'}}
+  <div :class="sizeClass" >
+    <div class="mic" @mousedown="mouseDownHandle" @mouseup="mouseUpHandle" :title="isRecording?'录音中...':'开始录音'">
+      <i :class="`el-icon-${isRecording?'microphone':'turn-off-microphone'}`"></i>
     </div>
   </div>
 </template>
@@ -11,231 +11,176 @@ import handle from "@/until/handle";
 import {sleep} from "@/until/time";
 import ZLMRTCClient from "@/assets/ZLMRTCClient";
 import CryptoJS from "crypto-js"
+
 export default {
   name: "microphone.vue",
   props:{
-    size: "default",
+    size: {default:"medium"},
     deviceId: {required:true},
     channelId: {required:true},
-    hookProtocol: {default:"https"},
-    hookHost: {default:""}
+    httpsHook: {default:""},
+    httpHook: {default:""},
+    pushKey: {default:""},
+    enableDebug: {default: false}
   },
   data(){
     return {
-      // 是否已经请求到 audio
-      isQueryAllowAudio:false,
+      iconStyle: "",
       // 音频流
       audioStream: null,
       // record
       mediaRecord: null,
       isRecording: false,
-      player: null
+      player: null,
+      mediaStream: null,
+      audioConnected: false,
+    }
+  },
+  computed: {
+    sizeClass() {
+      return {
+        'microPhone':true,
+        'large': this.size === 'large', 'medium': this.size === 'medium', 'small': this.size === 'small'}
     }
   },
+  beforeMount() {
+    this.initAudioApplications();
+  },
   beforeDestroy() {
     if(this.player){
       this.player.close();
+      this.player = null;
+      this.mediaStream = null;
     }
   },
-  methods:{
+  methods: {
+    /**
+     * 初始化app应用
+     */
+    initAudioApplications(){
+      this.player = null;
+      this.mediaStream = null;
+      this.audioConnected = false;
+    },
     // 录音按钮按下
-    mouseDownHandle(){
-      this.startRecordAudio();
+    mouseDownHandle() {
+      if (this.audioConnected) {
+        // 取消静音音频轨道
+        if(this.mediaStream){
+          let audioStream = this.mediaStream.getAudioTracks();
+          audioStream.forEach(track=>{
+            track.enabled = false;
+          });
+        }else{
+          this.$message.error("无法获取音频流!");
+        }
+      }else{
+        // 未创建webrtc 连接
+        this.startRecordAudio();
+      }
     },
     // 录音按钮抬起
-    mouseUpHandle(){
+    mouseUpHandle() {
       this.isRecording = false;
-    },
-    queryMediaStream(){
-      return new Promise((resolve, reject) => {
-        navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia
-        navigator.getUserMedia({audio:true , video:false } ,
-          (stream) => {
-            resolve(stream);
-        }, (error) => {
-          reject(error);
+      // 静音音频轨道
+      if (this.audioConnected && this.mediaStream) {
+        let audioStream = this.mediaStream.getAudioTracks();
+        audioStream.forEach(track => {
+          track.enabled = false;
         });
-      })
+      }
     },
-    async startRecordAudio(){
-      let err,stream,res;
 
-      if(!this.mediaStream){
-        [err,stream] = await handle(this.queryMediaStream());
-        if(err){
-          this.$message.error('获取音频设备失败!');
-          // return;
-        }
-        this.isQueryAllowAudio = true
-        let hookProtocol = this.hookProtocol;
-        let hookHost = this.hookHost;
-        let pushKey = "3e80d1762a324d5b0ff636e0bd16f1e3";
+    async startRecordAudio() {
+      let err, stream, res;
+      if (!this.mediaStream) {
+        let httpHook = this.hookProtocol;
+        let pushKey = this.pushKey;
         pushKey = CryptoJS.MD5(pushKey);
-        if(!hookProtocol){
-          hookProtocol = "http"
-        }
-        if(!hookHost){
-          hookHost = "szgpay.ticp.net:29010"
-        }
+        let serverHost = `${hookProtocol}://${hookHost}`
         let app = "rtc";
-        let stream = `${this.deviceId}`
-        let zlmSdpUrl = `/zlmServer/index/api/webrtc?app=${app}&stream=${stream}&type=push&sign=${pushKey}`;
+        let stream = `audio${this.deviceId}`
+        // webrtc 请求推流 url
+        let zlmSdpUrl = `${serverHost}/index/api/webrtc?app=${app}&stream=${stream}&type=push&sign=${pushKey}`;
+        // webrtc 拉流地址
+        let playAudioStreamUrl = `${serverHost}/index/api/webrtc?app=${app}&stream=${stream}&type=play`;
+        console.log(playAudioStreamUrl);
 
-        let ffmpegStreamId = `ff_audio${this.deviceId}`
-        let audioStreamUrl = `webrtc://${hookHost}/${app}/${stream}`
-        let dstUrl = `rtsp://127.0.0.1:11554/${app}/${ffmpegStreamId}`;
-        let playAudioStreamUrl = `https://192.168.1.203:29010/index/api/webrtc?app=${app}&stream=${stream}&type=play`;
-        console.log(audioStreamUrl)
-        console.log(playAudioStreamUrl)
-
-        //secret	Y	api操作密钥(配置文件配置),如果操作ip是127.0.0.1,则不需要此参数
-        // src_url	Y	FFmpeg拉流地址,支持任意协议或格式(只要FFmpeg支持即可)
-        // dst_url	Y	FFmpeg rtmp推流地址,一般都是推给自己,例如rtmp://127.0.0.1/live/stream_form_ffmpeg
-        //   timeout_ms	Y	FFmpeg推流成功超时时间
-        // enable_hls	Y	是否开启hls录制
-        // enable_mp4	Y	是否开启mp4录制
-        // ffmpeg_cmd_key
-        let addFFmpegSourceData = {
-          secret:"035c73f7-bb6b-4889-a715-d9eb2d1925cc",
-          src_url: audioStreamUrl,
-          dst_url: dstUrl,
-          timeout_ms: 15000,
-          enable_hls: 0,
-          enable_mp4: 0,
-        }
-        let ffmpegStreamProxyUrl = `/zlmServer/index/api/addFFmpegSource`
-        ffmpegStreamProxyUrl += `?secret=${addFFmpegSourceData.secret}`
-        // ffmpegStreamProxyUrl += `&src_url=${addFFmpegSourceData.src_url}`
-        // ffmpegStreamProxyUrl += `&dst_url=${addFFmpegSourceData.dst_url}`
-        // ffmpegStreamProxyUrl += `&timeout_ms=${addFFmpegSourceData.timeout_ms}`
-        // ffmpegStreamProxyUrl += `&enable_hls=${addFFmpegSourceData.enable_hls}`
-        // ffmpegStreamProxyUrl += `&enable_mp4=${addFFmpegSourceData.enable_mp4}`
         let player = new ZLMRTCClient.Endpoint(
           {
-
             // element: document.getElementById('video'),// video 标签
             debug: true,// 是否打印日志
-            zlmsdpUrl:zlmSdpUrl,//流地址
-            simulcast:false,
-            useCamera:false,
-            audioEnable:true,
-            videoEnable:false,
-            recvOnly:false,
-            resolution:{w:0,h:0},
-            usedatachannel:false,
+            zlmsdpUrl: zlmSdpUrl,//流地址
+            simulcast: false,
+            useCamera: false,
+            audioEnable: true,
+            videoEnable: false,
+            recvOnly: false,
+            resolution: {w: 0, h: 0},
+            usedatachannel: false,
           }
         );
         this.player = player;
-        console.log(player);
-        player.on(ZLMRTCClient.Events.WEBRTC_ON_CONNECTION_STATE_CHANGE,async (state)=>
-        {// RTC 状态变化 ,详情参考 https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/connectionState
-          console.log('当前状态==>',state);
-          console.log(ffmpegStreamProxyUrl);
-          if(state === 'connected'){
-            console.log(player);
-            console.log(player._localStream.id);
-            // if(player._localStream && player._localStream.id){
-            //   stream = player._localStream.id;
-            // }
+        // console.log(player);
+        player.on(ZLMRTCClient.Events.WEBRTC_ON_CONNECTION_STATE_CHANGE, async (state) => {// RTC 状态变化 ,详情参考 https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/connectionState
+          console.log('当前状态==>', state);
+          if (state === 'connected') {
+            // 等待1秒
             await sleep(1000);
-            [err,res] = await  handle(this.sendBroaderCast(stream));
-
-            if(err){
-              this.$message.error(err.message);
-              console.log("[发送broadCast信息] 失败")
-              console.log(err);
-              player.close();
+            [err, res] = await handle(this.sendBroaderCast(stream));
+            if (err) {
+              this.audioStartFailed(err,`与设备交互错误信息失败${err.message}`)
+              this.mediaStream = null;
+              return player.close();
             }
-
-            // 连接成功添加ffmpeg 推流代理
-            // [err,res] = await handle(this.$axios({
-            //   baseURL: "/",
-            //   method: 'post',
-            //   url: ffmpegStreamProxyUrl,
-            //   data:addFFmpegSourceData
-            // }));
-            // if(err){
-            //   this.$message.error(err.message);
-            //   console.log("[创建拉流代理] ")
-            //   console.log(err);
-            // }
-            // console.log(res);
-
-
-          }else{
-
+            this.audioConnected = true;
+            console.log('创建音视频通道成功');
+          } else if(state === 'close'){
+            this.$message.warning("webrtc连接断开");
+            this.audioConnected = false;
           }
         });
-        player.on(ZLMRTCClient.Events.WEBRTC_ICE_CANDIDATE_ERROR,function(e)
-        {// ICE 协商出错
-          console.log('ICE 协商出错')
+        player.on(ZLMRTCClient.Events.WEBRTC_ICE_CANDIDATE_ERROR,  (e)=> {
+          this.audioStartFailed(e,"ICE 协商出错");
         });
-
-        player.on(ZLMRTCClient.Events.WEBRTC_ON_REMOTE_STREAMS,function(e)
-        {//获取到了远端流,可以播放
-          console.log('播放成功',e.streams)
+        // player.on(ZLMRTCClient.Events.WEBRTC_ON_REMOTE_STREAMS, function (e) {//获取到了远端流,可以播放
+        //   console.log('播放成功', e.streams)
+        // });
+        player.on(ZLMRTCClient.Events.WEBRTC_OFFER_ANWSER_EXCHANGE_FAILED,  (e)=> {
+          this.audioStartFailed(e,"offer anwser 交换失败");
         });
-
-        player.on(ZLMRTCClient.Events.WEBRTC_OFFER_ANWSER_EXCHANGE_FAILED,function(e)
-        {// offer anwser 交换失败
-          console.log('offer anwser 交换失败',e)
-          stop();
+        player.on(ZLMRTCClient.Events.WEBRTC_ON_LOCAL_STREAM,  (s)=> {
+          console.log("获取到了本地流");
+          this.mediaStream = s;
         });
-
-        player.on(ZLMRTCClient.Events.WEBRTC_ON_LOCAL_STREAM,function(s)
-        {// 获取到了本地流
-
-          // document.getElementById('selfVideo').srcObject=s;
-          // document.getElementById('selfVideo').muted = true;
-          //console.log('offer anwser 交换失败',e)
-        });
-
-        player.on(ZLMRTCClient.Events.CAPTURE_STREAM_FAILED,function(s)
-        {// 获取本地流失败
-          console.log('获取本地流失败')
+        player.on(ZLMRTCClient.Events.CAPTURE_STREAM_FAILED,  (s)=> {
+          this.audioStartFailed(s,"获取音频信息失败,请检查是否有麦克风");
         });
-
-
-
       }
-      if(!this.isQueryAllowAudio){
-        return this.$message.error('无法获取音频!');
-      }
-
       this.isRecording = true;
-      // 通知设备开始推流
-      // 开始录音并推送音频至 wvp 服务器 || 或者推送至 zlm
-      // 暂定wvp开启
-    // todo 开始录音,并且每隔500ms发送音频文件给wvp
     },
-    async stopRecordAudio(){
-    //  todo 停止录音
+    async stopRecordAudio() {
+      //  todo 停止录音
+    },
+    audioStartFailed(e,msg){
+      if(this.enableDebug){
+        console.log(msg);
+        console.log(e);
+        console.log("-------");
+      }
+      this.$message.error(msg);
     },
     // 通知设备开启推流
-    async sendBroaderCast(stream){
+    sendBroaderCast(stream) {
       let url = `/api/play/broadcast`
-      url+=`?deviceId=${this.deviceId}&channel=${this.channelId}&stream=${stream}`;
-      let [err,res] = await handle(this.$axios({
+      url += `?deviceId=${this.deviceId}&stream=${stream}`;
+      return this.$axios({
         method: 'get',
         url: url
-      }));
-      this.clickCount = 0;
-      if(err){
-        console.error(err)
-        console.warn(err.message)
-      }
-      let response = res.data;
-
-      console.log(res);
-      if(response.code !== 0){
-        this.player.close();
-        return this.$message.error(response.msg);
-
-      }
-
+      });
     }
-
   }
+
 }
 </script>
 
@@ -245,4 +190,16 @@ export default {
   justify-content: center;
   align-items: center;
 }
+.microPhone .mic{
+  width: 100%;
+  height: 100%;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+
+.small{width: 25px;height:25px;font-size: 1.8rem;}
+.medium{width: 40px;height:40px;font-size: 2.2rem;}
+.large{width: 60px;height:60px;font-size: 2.6rem;}
+.huge{width: 80px;height:80px;font-size: 2.8rem;}
 </style>

+ 36 - 3
web_src/src/components/common/ptzControl.vue

@@ -1,7 +1,11 @@
 <template>
   <div style="display: flex; justify-content: left;">
     <div class="control-mic">
-      <microphone :channel-id="channelId" :device-id="deviceId"></microphone>
+      <microphone :channel-id="channelId" :device-id="deviceId" :enable-debug="enableDebug"
+                  :http-hook="httpHook"
+                  :https-hook="httpsHook"
+                  :push-key="pushKey"
+      ></microphone>
     </div>
     <div class="control-wrapper">
       <div class="control-btn control-top" @mousedown="ptzControlHandleDown('up')" @mouseup="ptzControlHandleUp('up')">
@@ -107,6 +111,7 @@ export default {
   },
   data(){
     return {
+      enableDebug: true,
       isLoading: false,
       tabActiveName: 'control',
       controSpeed: 30,
@@ -125,8 +130,14 @@ export default {
       isLongClick: false,// 是否为连续点击
       isPress: false,// 是否为长按
       isSendAutoMove: false,// 是否为长按命令倒计时中
+      pushKey: "",
+      httpsHook: "",
+      httpHook: "",
     }
   },
+  beforeMount() {
+    this.queryPushParam();
+  },
   methods:{
     timeSendFocus(){
       queryTimer = setTimeout(async ()=>{
@@ -335,15 +346,37 @@ export default {
       }));
       this.clickCount = 0;
       if(err){console.error(err)}
+    },
+    async queryPushParam(){
+      let url = `/api/server/pushConfig`
+      let [err,res] = await handle(this.$axios({
+        method: 'get',
+        url: url
+      }));
+      if(err){
+        console.error(err)
+        return this.$message.error(err.message);
+      }
+      console.log(res);
+      let response = res.data;
+      if(response.code === 0){
+        this.httpsHook = response.data["httpsHook"];
+        this.httpHook = response.data["httpHook"];
+        this.pushKey = response.data["pushKey"];
+      }else{
+        this.$message.warning(res.msg)
+      }
+
     }
-  }
+  },
+
 }
 </script>
 
 <style scoped>
 .control-mic{
   width: 4rem;
-  height: 100%;
+  /*height: 100%;*/
   display: flex;
   justify-content: center;
   align-items: center;