浏览代码

暂存,国标语音对讲接口制作
add: 推流控制,添加isUsePs控制是否启用ps流

kindring 2 年之前
父节点
当前提交
67063304ee

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java

@@ -105,7 +105,7 @@ public interface ISIPCommander {
 	 * @param device  视频设备
 	 * @param channelId  预览通道
 	 */
-	void playStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, ZlmHttpHookSubscribe.Event event, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException;
+	void playStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId,int isUsePs, ZlmHttpHookSubscribe.Event event, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException;
 
 	/**
 	 * 请求回放视频流

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

@@ -310,11 +310,13 @@ public class SIPCommander implements ISIPCommander {
      *
      * @param device     视频设备
      * @param channelId  预览通道
+     * @param isUsePs    是否启用ps
      * @param event      hook订阅
      * @param errorEvent sip错误订阅
      */
     @Override
     public void playStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId,
+                              int isUsePs,
                               ZlmHttpHookSubscribe.Event event, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException {
         String stream = ssrcInfo.getStream();
 
@@ -371,6 +373,9 @@ public class SIPCommander implements ISIPCommander {
                 content.append("m=video " + ssrcInfo.getPort() + " RTP/AVP 96 97 98 99\r\n");
             }
             content.append("a=recvonly\r\n");
+            if(isUsePs == 1){
+                content.append("a=rtpmap:96 PS/90000\r\n");
+            }
             content.append("a=rtpmap:96 PS/90000\r\n");
             content.append("a=rtpmap:98 H264/90000\r\n");
             content.append("a=rtpmap:97 MPEG4/90000\r\n");

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

@@ -27,10 +27,10 @@ public interface IPlayService {
 
     void onPublishHandlerForPlay(MediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid);
 
-    void play(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId,
+    void play(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId,int isUsePs,
               ZlmHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent,
               InviteTimeOutCallback timeoutCallback, String uuid);
-    PlayResult play(MediaServerItem mediaServerItem, String deviceId, String channelId, ZlmHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent, Runnable timeoutCallback);
+    PlayResult play(MediaServerItem mediaServerItem, String deviceId, String channelId,int isUsePs, ZlmHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent, Runnable timeoutCallback);
 
     public PlayResult openBroadcast(MediaServerItem mediaServerItem,String deviceId,String audioStreamId,ZlmHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent,
                               Runnable timeoutCallback);

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

@@ -116,9 +116,8 @@ public class PlayServiceImpl implements IPlayService {
 
 
 
-    // todo 模仿play接口开启 rtp 推流接口
     @Override
-    public PlayResult play(MediaServerItem mediaServerItem, String deviceId, String channelId,
+    public PlayResult play(MediaServerItem mediaServerItem, String deviceId, String channelId,int isUsePs,
                            ZlmHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent,
                            Runnable timeoutCallback) {
         if (mediaServerItem == null) {
@@ -218,7 +217,7 @@ public class PlayServiceImpl implements IPlayService {
             }
             SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, device.isSsrcCheck(), false);
             logger.info(JSONObject.toJSONString(ssrcInfo));
-            play(mediaServerItem, ssrcInfo, device, channelId, (mediaServerItemInUse, response)->{
+            play(mediaServerItem, ssrcInfo, device, channelId,isUsePs, (mediaServerItemInUse, response)->{
                 if (hookEvent != null) {
                     hookEvent.response(mediaServerItem, response);
                 }
@@ -253,6 +252,7 @@ public class PlayServiceImpl implements IPlayService {
 
     @Override
     public void play(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId,
+                     int isUsePs,
                      ZlmHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent,
                      InviteTimeOutCallback timeoutCallback, String uuid) {
 
@@ -292,7 +292,7 @@ public class PlayServiceImpl implements IPlayService {
             return;
         }
         try {
-            cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInuse, JSONObject response) -> {
+            cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId, isUsePs, (MediaServerItem mediaServerItemInuse, JSONObject response) -> {
                 logger.info("收到订阅消息: " + response.toJSONString());
                 System.out.println("停止超时任务: " + timeOutTaskKey);
                 dynamicTask.stop(timeOutTaskKey);

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

@@ -76,14 +76,14 @@ public class PlayController {
 	@Operation(summary = "开始点播")
 	@Parameter(name = "deviceId", description = "设备国标编号", required = true)
 	@Parameter(name = "channelId", description = "通道国标编号", required = true)
+	@Parameter(name = "isUsePs" ,description = "是否启用ps",required = false)
 	@GetMapping("/start/{deviceId}/{channelId}")
 	public DeferredResult<WVPResult<String>> play(@PathVariable String deviceId,
-													   @PathVariable String channelId) {
-
+													   @PathVariable String channelId,@RequestParam int isUsePs) {
 		// 获取可用的zlm
 		Device device = storager.queryVideoDevice(deviceId);
 		MediaServerItem newMediaServerItem = playService.getNewMediaServerItem(device);
-		PlayResult playResult = playService.play(newMediaServerItem, deviceId, channelId, null, null, null);
+		PlayResult playResult = playService.play(newMediaServerItem, deviceId, channelId,isUsePs, null, null, null);
 		return playResult.getResult();
 	}
 

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

@@ -93,7 +93,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)
@@ -123,13 +123,13 @@ media:
     # [必须修改] zlm服务器唯一id,用于触发hook时区别是哪台服务器,general.mediaServerId
     id: your_server_id
     # [必须修改] zlm服务器的内网IP
-    ip: szgpay.ticp.net
+    ip: 192.168.1.203
     # [可选] 返回流地址时的ip,置空使用 media.ip
-    stream-ip: szgpay.ticp.net
+    stream-ip: 192.168.1.203
     #stream-ip: 192.168.1.203
     #stream-ip: 113.88.194.58
     # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip
-    sdp-ip: szgpay.ticp.net
+    sdp-ip: 192.168.1.203
     #sdp-ip: 192.168.1.203
     #sdp-ip: 113.88.194.58
     # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip

+ 11 - 1
web_src/config/index.js

@@ -3,7 +3,7 @@
 // see http://vuejs-templates.github.io/webpack for documentation.
 
 const path = require('path')
-const baseUrl = "https://192.168.31.174:29001"
+const baseUrl = "https://192.168.1.26:29001"
 module.exports = {
   dev: {
 
@@ -31,6 +31,16 @@ module.exports = {
           Referer: baseUrl
         }
       },
+      '/debug/zlmServer': {
+        target: "https://szgpay.ticp.net:29010",
+        changeOrigin: true,
+        secure: false,
+        pathRewrite: {
+          '^/debug/zlmServer': ''
+        },headers: {
+          Referer: baseUrl
+        }
+      },
       '/aiLib':{
         target: baseUrl,
         secure: false,

+ 5 - 0
web_src/package-lock.json

@@ -2252,6 +2252,11 @@
         "randomfill": "^1.0.3"
       }
     },
+    "crypto-js": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz",
+      "integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw=="
+    },
     "css-color-names": {
       "version": "0.0.4",
       "resolved": "https://registry.npm.taobao.org/css-color-names/download/css-color-names-0.0.4.tgz",

+ 64 - 7
web_src/src/components/common/microphone.vue

@@ -28,7 +28,12 @@ export default {
       // record
       mediaRecord: null,
       isRecording: false,
-
+      player: null
+    }
+  },
+  beforeDestroy() {
+    if(this.player){
+      this.player.close();
     }
   },
   methods:{
@@ -52,7 +57,8 @@ export default {
       })
     },
     async startRecordAudio(){
-      let err,stream;
+      let err,stream,res;
+
       if(!this.mediaStream){
         [err,stream] = await handle(this.queryMediaStream());
         if(err){
@@ -73,6 +79,36 @@ export default {
         let app = "broadcast";
         let stream = `audio${this.deviceId}`
         let zlmSdpUrl = `/zlmServer/index/api/webrtc?app=${app}&stream=${stream}&type=push&sign=${pushKey}`;
+
+        let ffmpegStreamId = `ff_audio${this.deviceId}`
+        let audioStreamUrl = `webrtc://${hookHost}/${app}/${stream}`
+        let dstUrl = `rtsp://127.0.0.1/${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:"",
+          src_url: audioStreamUrl,
+          dst_url: dstUrl,
+          timeout_ms: 30,
+          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(
           {
 
@@ -88,7 +124,31 @@ export default {
             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'){
+            // 连接成功添加ffmpeg 推流代理
+            [err,res] = await handle(this.$axios({
+              method: 'post',
+              url: ffmpegStreamProxyUrl,
+              data:addFFmpegSourceData
+            }));
+            if(err){
+              this.$message.error(err.message);
+              console.log("[创建拉流代理] ")
+              console.log(err);
+            }
+            console.log(res);
+            [err,res] = await  handle(this.sendBroaderCast(ffmpegStreamId));
+
+          }else{
+
+          }
+        });
         player.on(ZLMRTCClient.Events.WEBRTC_ICE_CANDIDATE_ERROR,function(e)
         {// ICE 协商出错
           console.log('ICE 协商出错')
@@ -118,11 +178,7 @@ export default {
           console.log('获取本地流失败')
         });
 
-        player.on(ZLMRTCClient.Events.WEBRTC_ON_CONNECTION_STATE_CHANGE,function(state)
-        {// RTC 状态变化 ,详情参考 https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/connectionState
-          console.log('当前状态==>',state)
-        });
-        await this.sendBroaderCast(stream);
+
 
       }
       if(!this.isQueryAllowAudio){
@@ -159,6 +215,7 @@ export default {
       }
 
     }
+
   }
 }
 </script>