瀏覽代碼

修改拉流代理表单

648540858 1 年之前
父節點
當前提交
15f44b0d23
共有 2 個文件被更改,包括 336 次插入104 次删除
  1. 217 0
      web_src/src/components/StreamProxyEdit.vue
  2. 119 104
      web_src/src/components/StreamProxyList.vue

+ 217 - 0
web_src/src/components/StreamProxyEdit.vue

@@ -0,0 +1,217 @@
+<template>
+  <div id="StreamProxyEdit" style="width: 100%">
+    <div class="page-header">
+      <div class="page-title">
+        <el-button icon="el-icon-back" size="mini" style="font-size: 20px; color: #000;" type="text" @click="close" ></el-button>
+        <el-divider direction="vertical"></el-divider>
+        编辑拉流代理信息
+      </div>
+      <div class="page-header-btn">
+        <div style="display: inline;">
+          <el-button icon="el-icon-close" size="mini" style="font-size: 20px; color: #000;" type="text" @click="close" ></el-button>
+        </div>
+      </div>
+    </div>
+    <el-tabs tab-position="left">
+      <el-tab-pane label="拉流代理信息">
+        <el-form ref="streamProxy" :rules="rules" :model="streamProxy" label-width="140px" style="width: 50%; margin: 0 auto">
+          <el-form-item label="类型" prop="type">
+            <el-select
+              v-model="streamProxy.type"
+              style="width: 100%"
+              placeholder="请选择代理类型"
+            >
+              <el-option label="默认" value="default"></el-option>
+              <el-option label="FFmpeg" value="ffmpeg"></el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="名称" prop="name">
+            <el-input v-model="streamProxy.name" clearable></el-input>
+          </el-form-item>
+          <el-form-item label="流应用名" prop="app">
+            <el-input v-model="streamProxy.app" clearable></el-input>
+          </el-form-item>
+          <el-form-item label="流ID" prop="stream">
+            <el-input v-model="streamProxy.stream" clearable></el-input>
+          </el-form-item>
+          <el-form-item label="拉流地址" prop="url" v-if="streamProxy.type=='default'">
+            <el-input v-model="streamProxy.url" clearable></el-input>
+          </el-form-item>
+          <el-form-item label="拉流地址" prop="srcUrl" v-if="streamProxy.type=='ffmpeg'">
+            <el-input v-model="streamProxy.srcUrl" clearable></el-input>
+          </el-form-item>
+          <el-form-item label="超时时间:毫秒" prop="timeoutMs" v-if="streamProxy.type=='ffmpeg'">
+            <el-input v-model="streamProxy.timeoutMs" clearable></el-input>
+          </el-form-item>
+          <el-form-item label="节点选择" prop="rtpType">
+            <el-select
+              v-model="streamProxy.mediaServerId"
+              @change="mediaServerIdChange"
+              style="width: 100%"
+              placeholder="请选择拉流节点"
+            >
+              <el-option
+                v-for="item in mediaServerList"
+                :key="item.id"
+                :label="item.id"
+                :value="item.id">
+              </el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="FFmpeg命令模板" prop="ffmpegCmdKey" v-if="streamProxy.type=='ffmpeg'">
+            <el-select
+              v-model="streamProxy.ffmpegCmdKey"
+              style="width: 100%"
+              placeholder="请选择FFmpeg命令模板"
+            >
+              <el-option
+                v-for="item in Object.keys(ffmpegCmdList)"
+                :key="item"
+                :label="ffmpegCmdList[item]"
+                :value="item">
+              </el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="国标编码" prop="gbId">
+            <el-input v-model="streamProxy.gbId" placeholder="设置国标编码可推送到国标" clearable></el-input>
+          </el-form-item>
+          <el-form-item label="拉流方式" prop="rtpType" v-if="streamProxy.type=='default'">
+            <el-select
+              v-model="streamProxy.rtpType"
+              style="width: 100%"
+              placeholder="请选择拉流方式"
+            >
+              <el-option label="TCP" value="0"></el-option>
+              <el-option label="UDP" value="1"></el-option>
+              <el-option label="组播" value="2"></el-option>
+            </el-select>
+          </el-form-item>
+
+          <el-form-item label="无人观看" prop="rtpType" >
+            <el-radio v-model="streamProxy.noneReader" label="0">不做处理</el-radio>
+            <el-radio v-model="streamProxy.noneReader" label="1">停用</el-radio>
+            <el-radio v-model="streamProxy.noneReader" label="2">移除</el-radio>
+          </el-form-item>
+          <el-form-item label="其他选项">
+            <div style="float: left;">
+              <el-checkbox label="启用" v-model="streamProxy.enable" ></el-checkbox>
+              <el-checkbox label="开启音频" v-model="streamProxy.enableAudio" ></el-checkbox>
+              <el-checkbox label="录制" v-model="streamProxy.enableMp4" ></el-checkbox>
+            </div>
+
+          </el-form-item>
+          <el-form-item>
+            <div style="float: right;">
+              <el-button type="primary" @click="onSubmit" :loading="dialogLoading" >保存</el-button>
+              <el-button @click="close">取消</el-button>
+            </div>
+
+          </el-form-item>
+        </el-form>
+      </el-tab-pane>
+      <el-tab-pane label="国标通道配置" v-if="streamProxy.id">
+        <CommonChannelEdit ref="commonChannelEdit" :dataForm="streamProxy" :cancel="close"></CommonChannelEdit>
+      </el-tab-pane>
+    </el-tabs>
+  </div>
+</template>
+
+<script>
+import CommonChannelEdit from './common/CommonChannelEdit'
+
+export default {
+  name: "channelEdit",
+  props: [ 'streamProxy', 'closeEdit'],
+  components: {
+    CommonChannelEdit,
+  },
+  created() {
+    console.log(this.streamPush)
+  },
+  data() {
+    return {
+      locading: false,
+      rules: {
+        name: [{ required: true, message: "请输入名称", trigger: "blur" }],
+        app: [{ required: true, message: "请输入应用名", trigger: "blur" }],
+        stream: [{ required: true, message: "请输入流ID", trigger: "blur" }],
+        url: [{ required: true, message: "请输入要代理的流", trigger: "blur" }],
+        srcUrl: [{ required: true, message: "请输入要代理的流", trigger: "blur" }],
+        timeoutMs: [{ required: true, message: "请输入FFmpeg推流成功超时时间", trigger: "blur" }],
+        ffmpegCmdKey: [{ required: false, message: "请输入FFmpeg命令参数模板(可选)", trigger: "blur" }],
+      },
+    };
+  },
+  methods: {
+    onSubmit: function () {
+      console.log(this.streamPush)
+      this.locading = true
+      if (this.streamPush.id) {
+        this.$axios({
+          method: 'post',
+          url: "/api/push/update",
+          data: this.streamPush
+        }).then((res) => {
+          if (res.data.code === 0) {
+            this.$message.success("保存成功");
+          }else {
+            this.$message.error(res.data.msg)
+          }
+        }).catch((error) => {
+          this.$message.error(error)
+        }).finally(()=>[
+          this.locading = false
+        ])
+      }else {
+        this.$axios({
+          method: 'post',
+          url: "/api/push/add",
+          data: this.streamPush
+        }).then((res) => {
+          if (res.data.code === 0) {
+            this.$message.success("保存成功");
+            this.streamPush = res.data.data
+          }else {
+            this.$message.error(res.data.msg)
+          }
+        }).catch((error) => {
+          this.$message.error(error)
+        }).finally(()=>[
+          this.locading = false
+        ])
+      }
+
+    },
+    close: function () {
+      this.closeEdit()
+    },
+    mediaServerIdChange:function (){
+      let that = this;
+      if (that.proxyParam.mediaServerId !== "auto"){
+        that.$axios({
+          method: 'get',
+          url:`/api/proxy/ffmpeg_cmd/list`,
+          params: {
+            mediaServerId: that.proxyParam.mediaServerId
+          }
+        }).then(function (res) {
+          that.ffmpegCmdList = res.data.data;
+          that.proxyParam.ffmpegCmdKey = Object.keys(res.data.data)[0];
+        }).catch(function (error) {
+          console.log(error);
+        });
+      }
+
+    },
+  },
+};
+</script>
+<style>
+.channel-form {
+  display: grid;
+  background-color: #FFFFFF;
+  padding: 1rem 2rem 0 2rem;
+  grid-template-columns: 1fr 1fr 1fr;
+  gap: 1rem;
+}
+</style>

+ 119 - 104
web_src/src/components/StreamProxyList.vue

@@ -1,113 +1,120 @@
 <template>
 	<div id="streamProxyList" style="width: 100%">
-    <div class="page-header">
-      <div class="page-title">拉流代理列表</div>
-      <div class="page-header-btn">
-        <el-button icon="el-icon-plus" size="mini" style="margin-right: 1rem;" type="primary" @click="addStreamProxy">添加代理</el-button>
-        <el-button v-if="false" icon="el-icon-search" size="mini" style="margin-right: 1rem;" type="primary" @click="addOnvif">搜索ONVIF</el-button>
-        <el-button icon="el-icon-refresh-right" circle size="mini" @click="refresh()"></el-button>
+
+    <div v-if="!streamProxy">
+      <div class="page-header">
+        <div class="page-title">拉流代理列表</div>
+        <div class="page-header-btn">
+          <el-button icon="el-icon-plus" size="mini" style="margin-right: 1rem;" type="primary" @click="addStreamProxy">添加代理</el-button>
+          <el-button v-if="false" icon="el-icon-search" size="mini" style="margin-right: 1rem;" type="primary" @click="addOnvif">搜索ONVIF</el-button>
+          <el-button icon="el-icon-refresh-right" circle size="mini" @click="refresh()"></el-button>
+        </div>
       </div>
-    </div>
-    <devicePlayer ref="devicePlayer"></devicePlayer>
-    <el-table :data="streamProxyList" style="width: 100%" :height="winHeight">
-      <el-table-column prop="name" label="名称" min-width="120" show-overflow-tooltip/>
-      <el-table-column prop="app" label="流应用名" min-width="120" show-overflow-tooltip/>
-      <el-table-column prop="stream" label="流ID" min-width="120" show-overflow-tooltip/>
-      <el-table-column label="流地址" min-width="400"  show-overflow-tooltip >
-        <template slot-scope="scope">
-          <div slot="reference" class="name-wrapper">
+      <devicePlayer ref="devicePlayer"></devicePlayer>
+      <el-table :data="streamProxyList" style="width: 100%" :height="winHeight">
+        <el-table-column prop="name" label="名称" min-width="120" show-overflow-tooltip/>
+        <el-table-column prop="app" label="流应用名" min-width="120" show-overflow-tooltip/>
+        <el-table-column prop="stream" label="流ID" min-width="120" show-overflow-tooltip/>
+        <el-table-column label="流地址" min-width="400"  show-overflow-tooltip >
+          <template slot-scope="scope">
+            <div slot="reference" class="name-wrapper">
 
-            <el-tag size="medium" v-if="scope.row.type == 'default'">
-              <i class="cpoy-btn el-icon-document-copy"  title="点击拷贝" v-clipboard="scope.row.url" @success="$message({type:'success', message:'成功拷贝到粘贴板'})"></i>
-              {{scope.row.url}}
-            </el-tag>
-            <el-tag size="medium" v-if="scope.row.type != 'default'">
-              <i class="cpoy-btn el-icon-document-copy"  title="点击拷贝" v-clipboard="scope.row.srcUrl" @success="$message({type:'success', message:'成功拷贝到粘贴板'})"></i>
-              {{scope.row.srcUrl}}
-            </el-tag>
-          </div>
-        </template>
-      </el-table-column>
-      <el-table-column prop="mediaServerId" label="流媒体" min-width="180" ></el-table-column>
-      <el-table-column label="类型" width="100" >
-        <template slot-scope="scope">
-          <div slot="reference" class="name-wrapper">
-            <el-tag size="medium">{{scope.row.type === "default"? "直接代理":"FFMPEG代理"}}</el-tag>
-          </div>
-        </template>
-      </el-table-column>
+              <el-tag size="medium" v-if="scope.row.type == 'default'">
+                <i class="cpoy-btn el-icon-document-copy"  title="点击拷贝" v-clipboard="scope.row.url" @success="$message({type:'success', message:'成功拷贝到粘贴板'})"></i>
+                {{scope.row.url}}
+              </el-tag>
+              <el-tag size="medium" v-if="scope.row.type != 'default'">
+                <i class="cpoy-btn el-icon-document-copy"  title="点击拷贝" v-clipboard="scope.row.srcUrl" @success="$message({type:'success', message:'成功拷贝到粘贴板'})"></i>
+                {{scope.row.srcUrl}}
+              </el-tag>
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column prop="mediaServerId" label="流媒体" min-width="180" ></el-table-column>
+        <el-table-column label="类型" width="100" >
+          <template slot-scope="scope">
+            <div slot="reference" class="name-wrapper">
+              <el-tag size="medium">{{scope.row.type === "default"? "直接代理":"FFMPEG代理"}}</el-tag>
+            </div>
+          </template>
+        </el-table-column>
 
-      <el-table-column prop="gbId" label="国标编码" min-width="180"  show-overflow-tooltip/>
-      <el-table-column label="状态" min-width="120" >
-        <template slot-scope="scope">
-          <div slot="reference" class="name-wrapper">
-            <el-tag size="medium" v-if="scope.row.status">在线</el-tag>
-            <el-tag size="medium" type="info" v-if="!scope.row.status">离线</el-tag>
-          </div>
-        </template>
-      </el-table-column>
-      <el-table-column label="启用" min-width="120" >
-        <template slot-scope="scope">
-          <div slot="reference" class="name-wrapper">
-            <el-tag size="medium" v-if="scope.row.enable">已启用</el-tag>
-            <el-tag size="medium" type="info" v-if="!scope.row.enable">未启用</el-tag>
-          </div>
-        </template>
-      </el-table-column>
-      <el-table-column prop="createTime" label="创建时间"  min-width="150" show-overflow-tooltip/>
-      <el-table-column label="音频" min-width="120" >
-        <template slot-scope="scope">
-          <div slot="reference" class="name-wrapper">
-            <el-tag size="medium" v-if="scope.row.enableAudio">已启用</el-tag>
-            <el-tag size="medium" type="info" v-if="!scope.row.enableAudio">未启用</el-tag>
-          </div>
-        </template>
-      </el-table-column>
-      <el-table-column label="录制" min-width="120" >
-        <template slot-scope="scope">
-          <div slot="reference" class="name-wrapper">
-            <el-tag size="medium" v-if="scope.row.enableMp4">已启用</el-tag>
-            <el-tag size="medium" type="info" v-if="!scope.row.enableMp4">未启用</el-tag>
-          </div>
-        </template>
-      </el-table-column>
-      <el-table-column label="无人观看" min-width="160" >
-        <template slot-scope="scope">
-          <div slot="reference" class="name-wrapper">
-            <el-tag size="medium" v-if="scope.row.enableRemoveNoneReader">移除</el-tag>
-            <el-tag size="medium" v-if="scope.row.enableDisableNoneReader">停用</el-tag>
-            <el-tag size="medium" type="info" v-if="!scope.row.enableRemoveNoneReader && !scope.row.enableDisableNoneReader">不做处理</el-tag>
-          </div>
-        </template>
-      </el-table-column>
+        <el-table-column prop="gbId" label="国标编码" min-width="180"  show-overflow-tooltip/>
+        <el-table-column label="状态" min-width="120" >
+          <template slot-scope="scope">
+            <div slot="reference" class="name-wrapper">
+              <el-tag size="medium" v-if="scope.row.status">在线</el-tag>
+              <el-tag size="medium" type="info" v-if="!scope.row.status">离线</el-tag>
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column label="启用" min-width="120" >
+          <template slot-scope="scope">
+            <div slot="reference" class="name-wrapper">
+              <el-tag size="medium" v-if="scope.row.enable">已启用</el-tag>
+              <el-tag size="medium" type="info" v-if="!scope.row.enable">未启用</el-tag>
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column prop="createTime" label="创建时间"  min-width="150" show-overflow-tooltip/>
+        <el-table-column label="音频" min-width="120" >
+          <template slot-scope="scope">
+            <div slot="reference" class="name-wrapper">
+              <el-tag size="medium" v-if="scope.row.enableAudio">已启用</el-tag>
+              <el-tag size="medium" type="info" v-if="!scope.row.enableAudio">未启用</el-tag>
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column label="录制" min-width="120" >
+          <template slot-scope="scope">
+            <div slot="reference" class="name-wrapper">
+              <el-tag size="medium" v-if="scope.row.enableMp4">已启用</el-tag>
+              <el-tag size="medium" type="info" v-if="!scope.row.enableMp4">未启用</el-tag>
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column label="无人观看" min-width="160" >
+          <template slot-scope="scope">
+            <div slot="reference" class="name-wrapper">
+              <el-tag size="medium" v-if="scope.row.enableRemoveNoneReader">移除</el-tag>
+              <el-tag size="medium" v-if="scope.row.enableDisableNoneReader">停用</el-tag>
+              <el-tag size="medium" type="info" v-if="!scope.row.enableRemoveNoneReader && !scope.row.enableDisableNoneReader">不做处理</el-tag>
+            </div>
+          </template>
+        </el-table-column>
 
 
-      <el-table-column label="操作" width="360"  fixed="right">
-        <template slot-scope="scope">
-          <el-button size="medium" icon="el-icon-video-play" type="text" v-if="scope.row.enable" @click="play(scope.row)">播放</el-button>
-          <el-divider direction="vertical"></el-divider>
-          <el-button size="medium" icon="el-icon-switch-button" type="text" v-if="scope.row.enable" @click="stop(scope.row)">停用</el-button>
-          <el-divider direction="vertical"></el-divider>
-          <el-button size="medium" icon="el-icon-check" type="text" :loading="scope.row.startBtnLoading" v-if="!scope.row.enable" @click="start(scope.row)">启用</el-button>
-          <el-divider v-if="!scope.row.enable" direction="vertical"></el-divider>
-          <el-button size="medium" icon="el-icon-delete" type="text" style="color: #f56c6c" @click="deleteStreamProxy(scope.row)">删除</el-button>
-          <el-button size="medium" icon="el-icon-cloudy" type="text" @click="queryCloudRecords(scope.row)">云端录像
-          </el-button>
-        </template>
-      </el-table-column>
-    </el-table>
-    <el-pagination
-      style="float: right"
-      @size-change="handleSizeChange"
-      @current-change="currentChange"
-      :current-page="currentPage"
-      :page-size="count"
-      :page-sizes="[15, 25, 35, 50]"
-      layout="total, sizes, prev, pager, next"
-      :total="total">
-    </el-pagination>
+        <el-table-column label="操作" width="360"  fixed="right">
+          <template slot-scope="scope">
+            <el-button size="medium" icon="el-icon-video-play" type="text" v-if="scope.row.enable" @click="play(scope.row)">播放</el-button>
+            <el-divider direction="vertical"></el-divider>
+            <el-button size="medium" icon="el-icon-position" type="text" @click="edit(scope.row)">
+              编辑
+            </el-button>
+            <el-button size="medium" icon="el-icon-switch-button" type="text" v-if="scope.row.enable" @click="stop(scope.row)">停用</el-button>
+            <el-divider direction="vertical"></el-divider>
+            <el-button size="medium" icon="el-icon-check" type="text" :loading="scope.row.startBtnLoading" v-if="!scope.row.enable" @click="start(scope.row)">启用</el-button>
+            <el-divider v-if="!scope.row.enable" direction="vertical"></el-divider>
+            <el-button size="medium" icon="el-icon-delete" type="text" style="color: #f56c6c" @click="deleteStreamProxy(scope.row)">删除</el-button>
+            <el-button size="medium" icon="el-icon-cloudy" type="text" @click="queryCloudRecords(scope.row)">云端录像
+            </el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+      <el-pagination
+        style="float: right"
+        @size-change="handleSizeChange"
+        @current-change="currentChange"
+        :current-page="currentPage"
+        :page-size="count"
+        :page-sizes="[15, 25, 35, 50]"
+        layout="total, sizes, prev, pager, next"
+        :total="total">
+      </el-pagination>
+    </div>
     <streamProxyEdit ref="streamProxyEdit" ></streamProxyEdit>
     <onvifEdit ref="onvifEdit" ></onvifEdit>
+    <StreamProxyEdit v-if="streamProxy" :streamProxy="streamProxy" :closeEdit="closeEdit" ></StreamProxyEdit>
 	</div>
 </template>
 
@@ -116,12 +123,14 @@
 	import onvifEdit from './dialog/onvifEdit.vue'
 	import devicePlayer from './dialog/devicePlayer.vue'
 	import uiHeader from '../layout/UiHeader.vue'
+  import StreamProxyEdit from "./StreamProxyEdit";
 	export default {
 		name: 'streamProxyList',
 		components: {
 			devicePlayer,
 			streamProxyEdit,
       onvifEdit,
+      StreamProxyEdit,
 			uiHeader
 		},
 		data() {
@@ -134,7 +143,8 @@
 				currentPage:1,
 				count:15,
 				total:0,
-        startBtnLoading: false
+        startBtnLoading: false,
+        streamProxy: null
 			};
 		},
 		computed: {
@@ -187,7 +197,8 @@
 				});
 			},
 			addStreamProxy: function(){
-				this.$refs.streamProxyEdit.openDialog(null, this.initData)
+				// this.$refs.streamProxyEdit.openDialog(null, this.initData)
+        this.streamProxy = {}
 			},
       addOnvif: function(){
         this.$axios({
@@ -214,7 +225,11 @@
         });
 
 			},
-			saveStreamProxy: function(){
+      edit: function(row){
+        this.streamProxy = row
+			},
+      closeEdit: function(row){
+        this.streamProxy = null
 			},
 			play: function(row){
 				let that = this;