index.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. <template>
  2. <div class="video-settings">
  3. <!-- 主码流 -->
  4. <fieldset class="stream-section">
  5. <legend>Main Stream</legend>
  6. <div class="form-item">
  7. <span class="form-item__label">Resolution:</span>
  8. <div class="form-item__control">
  9. <el-select v-model="mainStream.MainResolution">
  10. <el-option v-for="item in mainResolutionOptions" :key="item.value" :label="item.label" :value="item.value" />
  11. </el-select>
  12. </div>
  13. </div>
  14. <div class="form-item">
  15. <span class="form-item__label">Encoding Format:</span>
  16. <div class="form-item__control">
  17. <el-select v-model="mainStream.encodeType">
  18. <el-option v-for="item in encodeTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
  19. </el-select>
  20. </div>
  21. </div>
  22. <div class="form-item">
  23. <span class="form-item__label">Frame Rate:</span>
  24. <div class="form-item__control">
  25. <el-select v-model="mainStream.MainFps">
  26. <el-option v-for="item in frameRateOptions" :key="item.value" :label="item.label" :value="item.value" />
  27. </el-select>
  28. </div>
  29. </div>
  30. <div class="form-item">
  31. <span class="form-item__label">Bitrate:</span>
  32. <div class="form-item__control">
  33. <el-input-number v-model="mainStream.MainBitRate" :min="1024" :max="3072" :controls="false" />
  34. <span class="form-item__hint">(1024,3072)</span>
  35. </div>
  36. </div>
  37. <div class="form-item">
  38. <span class="form-item__label">Bitrate Control:</span>
  39. <div class="form-item__control">
  40. <el-select v-model="mainStream.MainEcdFmat">
  41. <el-option v-for="item in bitRateControlOptions" :key="item.value" :label="item.label" :value="item.value" />
  42. </el-select>
  43. </div>
  44. </div>
  45. <div class="form-item">
  46. <span class="form-item__label">I-Frame Interval:</span>
  47. <div class="form-item__control">
  48. <el-input-number v-model="mainStream.MainFrameTime" :min="100" :max="200" :controls="false" />
  49. <span class="form-item__hint">(100,200)</span>
  50. </div>
  51. </div>
  52. </fieldset>
  53. <!-- 子码流 -->
  54. <fieldset class="stream-section">
  55. <legend>Sub Stream</legend>
  56. <div class="form-item">
  57. <span class="form-item__label">Resolution:</span>
  58. <div class="form-item__control">
  59. <el-select v-model="subStream.SecondResolution">
  60. <el-option v-for="item in subResolutionOptions" :key="item.value" :label="item.label" :value="item.value" />
  61. </el-select>
  62. </div>
  63. </div>
  64. <div class="form-item">
  65. <span class="form-item__label">Encoding Format:</span>
  66. <div class="form-item__control">
  67. <el-select v-model="subStream.encodeType">
  68. <el-option v-for="item in encodeTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
  69. </el-select>
  70. </div>
  71. </div>
  72. <div class="form-item">
  73. <span class="form-item__label">Frame Rate:</span>
  74. <div class="form-item__control">
  75. <el-select v-model="subStream.SecondFps">
  76. <el-option v-for="item in frameRateOptions" :key="item.value" :label="item.label" :value="item.value" />
  77. </el-select>
  78. </div>
  79. </div>
  80. <div class="form-item">
  81. <span class="form-item__label">Bitrate:</span>
  82. <div class="form-item__control">
  83. <el-input-number v-model="subStream.SecondBitRate" :min="1024" :max="3072" :controls="false" />
  84. <span class="form-item__hint">(1024,3072)</span>
  85. </div>
  86. </div>
  87. <div class="form-item">
  88. <span class="form-item__label">Bitrate Control:</span>
  89. <div class="form-item__control">
  90. <el-select v-model="subStream.SecondEcdFmat">
  91. <el-option v-for="item in bitRateControlOptions" :key="item.value" :label="item.label" :value="item.value" />
  92. </el-select>
  93. </div>
  94. </div>
  95. <div class="form-item">
  96. <span class="form-item__label">I-Frame Interval:</span>
  97. <div class="form-item__control">
  98. <el-input-number v-model="subStream.SecondFrameTime" :min="100" :max="200" :controls="false" />
  99. <span class="form-item__hint">(100,200)</span>
  100. </div>
  101. </div>
  102. </fieldset>
  103. <!-- 实时模式 -->
  104. <!-- <div class="realtime-section">
  105. <span class="form-item__label">实时模式:</span>
  106. <el-checkbox v-model="realtimeMode" />
  107. <span class="realtime-tip">(开启后,夜视动态效果好,但可能会影响静态图像效果)</span>
  108. </div> -->
  109. <!-- 底部按钮 -->
  110. <div class="btn-wrapper">
  111. <el-button round class="btn-reset" @click="resetDefaults">Restore Defaults</el-button>
  112. <el-button round type="primary" class="btn-save" @click="saveParams">Save</el-button>
  113. </div>
  114. </div>
  115. </template>
  116. <script setup lang="ts">
  117. import { reactive, ref, onMounted } from 'vue'
  118. import { ElMessage } from 'element-plus'
  119. import { getVideoEncodePara, putVideoEncodePara } from '@/api/setting'
  120. // 主码流参数
  121. const mainStream = reactive({
  122. MainResolution: 5,
  123. encodeType: 0,
  124. MainFps: 25,
  125. MainBitRate: 3072,
  126. MainEcdFmat: 0,
  127. MainFrameTime: 100
  128. })
  129. // 子码流参数
  130. const subStream = reactive({
  131. SecondResolution: 0,
  132. encodeType: 0,
  133. SecondFps: 25,
  134. SecondBitRate: 3072,
  135. SecondEcdFmat: 0,
  136. SecondFrameTime: 100
  137. })
  138. // 实时模式
  139. const realtimeMode = ref(false)
  140. // 主码流分辨率选项
  141. const mainResolutionOptions = [
  142. { value: 5, label: '2880*1620 (5M)' },
  143. { value: 4, label: '2560*1440 (4M)' },
  144. { value: 3, label: '2304*1296 (3M)' },
  145. { value: 2, label: '1920*1080 (1080P)' },
  146. { value: 1, label: '1280*720 (720P)' },
  147. { value: 0, label: '640*360' },
  148. ]
  149. // 子码流分辨率选项
  150. const subResolutionOptions = [
  151. { value: 0, label: '640*360' },
  152. ]
  153. // 编码格式选项
  154. const encodeTypeOptions = [
  155. { value: 0, label: 'H264' },
  156. // { value: 1, label: 'H265' }
  157. ]
  158. // 帧率选项
  159. const frameRateOptions = [
  160. { value: 10, label: '10' },
  161. { value: 11, label: '11' },
  162. { value: 12, label: '12' },
  163. { value: 13, label: '13' },
  164. { value: 14, label: '14' },
  165. { value: 15, label: '15' },
  166. { value: 16, label: '16' },
  167. { value: 17, label: '17' },
  168. { value: 18, label: '18' },
  169. { value: 19, label: '19' },
  170. { value: 20, label: '20' },
  171. { value: 21, label: '21' },
  172. { value: 22, label: '22' },
  173. { value: 23, label: '23' },
  174. { value: 24, label: '24' },
  175. { value: 25, label: '25' },
  176. ]
  177. // 码率控制选项
  178. const bitRateControlOptions = [
  179. { value: 0, label: 'AVBR' },
  180. { value: 1, label: 'CBR' }
  181. ]
  182. // 恢复默认设置
  183. async function resetDefaults() {
  184. // 主码流
  185. mainStream.MainResolution = 5
  186. mainStream.encodeType = 0
  187. mainStream.MainFps = 25
  188. mainStream.MainBitRate = 3072
  189. mainStream.MainEcdFmat = 0
  190. mainStream.MainFrameTime = 100
  191. // 子码流
  192. subStream.SecondResolution = 0
  193. subStream.encodeType = 0
  194. subStream.SecondFps = 25
  195. subStream.SecondBitRate = 3072
  196. subStream.SecondEcdFmat = 0
  197. subStream.SecondFrameTime = 100
  198. // realtimeMode.value = false
  199. await saveParams()
  200. }
  201. // 获取视频编码参数
  202. async function fetchParams() {
  203. try {
  204. const res = await getVideoEncodePara()
  205. if (res.data) {
  206. const d = res.data
  207. // 主码流
  208. if (d.MainResolution !== undefined) mainStream.MainResolution = d.MainResolution
  209. // if (d.mainEncodeType !== undefined) mainStream.encodeType = d.mainEncodeType
  210. if (d.MainFps !== undefined) mainStream.MainFps = d.MainFps
  211. if (d.MainBitRate !== undefined) mainStream.MainBitRate = d.MainBitRate
  212. if (d.MainEcdFmat !== undefined) mainStream.MainEcdFmat = d.MainEcdFmat
  213. if (d.MainFrameTime !== undefined) mainStream.MainFrameTime = d.MainFrameTime
  214. // // 子码流
  215. if (d.SecondResolution !== undefined) subStream.SecondResolution = d.SecondResolution
  216. // if (d.subEncodeType !== undefined) subStream.encodeType = d.subEncodeType
  217. if (d.SecondFps !== undefined) subStream.SecondFps = d.SecondFps
  218. if (d.SecondBitRate !== undefined) subStream.SecondBitRate = d.SecondBitRate
  219. if (d.SecondEcdFmat !== undefined) subStream.SecondEcdFmat = d.SecondEcdFmat
  220. if (d.SecondFrameTime !== undefined) subStream.SecondFrameTime = d.SecondFrameTime
  221. // // 实时模式
  222. // if (d.realtimeMode !== undefined) realtimeMode.value = !!d.realtimeMode
  223. }
  224. } catch (e) {
  225. console.error('获取视频编码参数失败:', e)
  226. }
  227. }
  228. // 保存参数
  229. async function saveParams() {
  230. try {
  231. const data = {
  232. MainResolution: mainStream.MainResolution,
  233. // mainEncodeType: mainStream.encodeType,
  234. MainFps: mainStream.MainFps,
  235. MainBitRate: mainStream.MainBitRate,
  236. MainEcdFmat: mainStream.MainEcdFmat,
  237. MainFrameTime: mainStream.MainFrameTime,
  238. SecondResolution: subStream.SecondResolution,
  239. // subEncodeType: subStream.encodeType,
  240. SecondFps: subStream.SecondFps,
  241. SecondBitRate: subStream.SecondBitRate,
  242. SecondEcdFmat: subStream.SecondEcdFmat,
  243. SecondFrameTime: subStream.SecondFrameTime,
  244. // realtimeMode: realtimeMode.value ? 1 : 0
  245. }
  246. const res = await putVideoEncodePara(data)
  247. if (res.data === 'ok\n') {
  248. ElMessage.success('Save Successful')
  249. }
  250. } catch (e) {
  251. ElMessage.warning('Save Failed')
  252. }
  253. }
  254. onMounted(() => {
  255. fetchParams()
  256. })
  257. </script>
  258. <style scoped lang="scss">
  259. .video-settings {
  260. padding: 10px 20px;
  261. }
  262. .stream-section {
  263. border: 1px solid #eee;
  264. border-radius: 4px;
  265. padding: 20px 30px;
  266. margin-bottom: 20px;
  267. legend {
  268. font-size: 14px;
  269. color: #606266;
  270. padding: 0 8px;
  271. }
  272. }
  273. .form-item {
  274. display: flex;
  275. align-items: center;
  276. margin-bottom: 10px;
  277. &__label {
  278. flex: 0 0 120px;
  279. text-align: right;
  280. font-size: 13px;
  281. color: #606266;
  282. padding-right: 5px;
  283. }
  284. &__control {
  285. display: flex;
  286. align-items: center;
  287. gap: 10px;
  288. .el-select {
  289. width: 220px;
  290. }
  291. .el-input-number {
  292. width: 220px;
  293. :deep(.el-input__inner) {
  294. text-align: left;
  295. }
  296. }
  297. }
  298. &__hint {
  299. font-size: 13px;
  300. color: #909399;
  301. }
  302. }
  303. .realtime-section {
  304. display: flex;
  305. align-items: center;
  306. padding: 20px 0;
  307. border-top: 1px solid #eee;
  308. .form-item__label {
  309. flex: 0 0 100px;
  310. text-align: right;
  311. font-size: 13px;
  312. color: #606266;
  313. padding-right: 10px;
  314. }
  315. .realtime-tip {
  316. font-size: 12px;
  317. color: #909399;
  318. margin-left: 8px;
  319. }
  320. }
  321. .btn-wrapper {
  322. display: flex;
  323. // justify-content: space-between;
  324. gap: 200px;
  325. padding-top: 20px;
  326. .btn-reset {
  327. border-color: #409EFF;
  328. color: #409EFF;
  329. &:hover {
  330. background-color: #409EFF;
  331. color: #fff;
  332. }
  333. }
  334. .btn-save {
  335. min-width: 100px;
  336. }
  337. }
  338. </style>