| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375 |
- <template>
- <div class="video-settings">
- <!-- 主码流 -->
- <fieldset class="stream-section">
- <legend>Main Stream</legend>
- <div class="form-item">
- <span class="form-item__label">Resolution:</span>
- <div class="form-item__control">
- <el-select v-model="mainStream.MainResolution">
- <el-option v-for="item in mainResolutionOptions" :key="item.value" :label="item.label" :value="item.value" />
- </el-select>
- </div>
- </div>
- <div class="form-item">
- <span class="form-item__label">Encoding Format:</span>
- <div class="form-item__control">
- <el-select v-model="mainStream.encodeType">
- <el-option v-for="item in encodeTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
- </el-select>
- </div>
- </div>
- <div class="form-item">
- <span class="form-item__label">Frame Rate:</span>
- <div class="form-item__control">
- <el-select v-model="mainStream.MainFps">
- <el-option v-for="item in frameRateOptions" :key="item.value" :label="item.label" :value="item.value" />
- </el-select>
- </div>
- </div>
- <div class="form-item">
- <span class="form-item__label">Bitrate:</span>
- <div class="form-item__control">
- <el-input-number v-model="mainStream.MainBitRate" :min="1024" :max="3072" :controls="false" />
- <span class="form-item__hint">(1024,3072)</span>
- </div>
- </div>
- <div class="form-item">
- <span class="form-item__label">Bitrate Control:</span>
- <div class="form-item__control">
- <el-select v-model="mainStream.MainEcdFmat">
- <el-option v-for="item in bitRateControlOptions" :key="item.value" :label="item.label" :value="item.value" />
- </el-select>
- </div>
- </div>
- <div class="form-item">
- <span class="form-item__label">I-Frame Interval:</span>
- <div class="form-item__control">
- <el-input-number v-model="mainStream.MainFrameTime" :min="100" :max="200" :controls="false" />
- <span class="form-item__hint">(100,200)</span>
- </div>
- </div>
- </fieldset>
- <!-- 子码流 -->
- <fieldset class="stream-section">
- <legend>Sub Stream</legend>
- <div class="form-item">
- <span class="form-item__label">Resolution:</span>
- <div class="form-item__control">
- <el-select v-model="subStream.SecondResolution">
- <el-option v-for="item in subResolutionOptions" :key="item.value" :label="item.label" :value="item.value" />
- </el-select>
- </div>
- </div>
- <div class="form-item">
- <span class="form-item__label">Encoding Format:</span>
- <div class="form-item__control">
- <el-select v-model="subStream.encodeType">
- <el-option v-for="item in encodeTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
- </el-select>
- </div>
- </div>
- <div class="form-item">
- <span class="form-item__label">Frame Rate:</span>
- <div class="form-item__control">
- <el-select v-model="subStream.SecondFps">
- <el-option v-for="item in frameRateOptions" :key="item.value" :label="item.label" :value="item.value" />
- </el-select>
- </div>
- </div>
- <div class="form-item">
- <span class="form-item__label">Bitrate:</span>
- <div class="form-item__control">
- <el-input-number v-model="subStream.SecondBitRate" :min="1024" :max="3072" :controls="false" />
- <span class="form-item__hint">(1024,3072)</span>
- </div>
- </div>
- <div class="form-item">
- <span class="form-item__label">Bitrate Control:</span>
- <div class="form-item__control">
- <el-select v-model="subStream.SecondEcdFmat">
- <el-option v-for="item in bitRateControlOptions" :key="item.value" :label="item.label" :value="item.value" />
- </el-select>
- </div>
- </div>
- <div class="form-item">
- <span class="form-item__label">I-Frame Interval:</span>
- <div class="form-item__control">
- <el-input-number v-model="subStream.SecondFrameTime" :min="100" :max="200" :controls="false" />
- <span class="form-item__hint">(100,200)</span>
- </div>
- </div>
- </fieldset>
- <!-- 实时模式 -->
- <!-- <div class="realtime-section">
- <span class="form-item__label">实时模式:</span>
- <el-checkbox v-model="realtimeMode" />
- <span class="realtime-tip">(开启后,夜视动态效果好,但可能会影响静态图像效果)</span>
- </div> -->
- <!-- 底部按钮 -->
- <div class="btn-wrapper">
- <el-button round class="btn-reset" @click="resetDefaults">Restore Defaults</el-button>
- <el-button round type="primary" class="btn-save" @click="saveParams">Save</el-button>
- </div>
- </div>
- </template>
- <script setup lang="ts">
- import { reactive, ref, onMounted } from 'vue'
- import { ElMessage } from 'element-plus'
- import { getVideoEncodePara, putVideoEncodePara } from '@/api/setting'
- // 主码流参数
- const mainStream = reactive({
- MainResolution: 5,
- encodeType: 0,
- MainFps: 25,
- MainBitRate: 3072,
- MainEcdFmat: 0,
- MainFrameTime: 100
- })
- // 子码流参数
- const subStream = reactive({
- SecondResolution: 0,
- encodeType: 0,
- SecondFps: 25,
- SecondBitRate: 3072,
- SecondEcdFmat: 0,
- SecondFrameTime: 100
- })
- // 实时模式
- const realtimeMode = ref(false)
- // 主码流分辨率选项
- const mainResolutionOptions = [
- { value: 5, label: '2880*1620 (5M)' },
- { value: 4, label: '2560*1440 (4M)' },
- { value: 3, label: '2304*1296 (3M)' },
- { value: 2, label: '1920*1080 (1080P)' },
- { value: 1, label: '1280*720 (720P)' },
- { value: 0, label: '640*360' },
- ]
- // 子码流分辨率选项
- const subResolutionOptions = [
- { value: 0, label: '640*360' },
- ]
- // 编码格式选项
- const encodeTypeOptions = [
- { value: 0, label: 'H264' },
- // { value: 1, label: 'H265' }
- ]
- // 帧率选项
- const frameRateOptions = [
- { value: 10, label: '10' },
- { value: 11, label: '11' },
- { value: 12, label: '12' },
- { value: 13, label: '13' },
- { value: 14, label: '14' },
- { value: 15, label: '15' },
- { value: 16, label: '16' },
- { value: 17, label: '17' },
- { value: 18, label: '18' },
- { value: 19, label: '19' },
- { value: 20, label: '20' },
- { value: 21, label: '21' },
- { value: 22, label: '22' },
- { value: 23, label: '23' },
- { value: 24, label: '24' },
- { value: 25, label: '25' },
- ]
- // 码率控制选项
- const bitRateControlOptions = [
- { value: 0, label: 'AVBR' },
- { value: 1, label: 'CBR' }
- ]
- // 恢复默认设置
- async function resetDefaults() {
- // 主码流
- mainStream.MainResolution = 5
- mainStream.encodeType = 0
- mainStream.MainFps = 25
- mainStream.MainBitRate = 3072
- mainStream.MainEcdFmat = 0
- mainStream.MainFrameTime = 100
- // 子码流
- subStream.SecondResolution = 0
- subStream.encodeType = 0
- subStream.SecondFps = 25
- subStream.SecondBitRate = 3072
- subStream.SecondEcdFmat = 0
- subStream.SecondFrameTime = 100
- // realtimeMode.value = false
- await saveParams()
- }
- // 获取视频编码参数
- async function fetchParams() {
- try {
- const res = await getVideoEncodePara()
- if (res.data) {
- const d = res.data
- // 主码流
- if (d.MainResolution !== undefined) mainStream.MainResolution = d.MainResolution
- // if (d.mainEncodeType !== undefined) mainStream.encodeType = d.mainEncodeType
- if (d.MainFps !== undefined) mainStream.MainFps = d.MainFps
- if (d.MainBitRate !== undefined) mainStream.MainBitRate = d.MainBitRate
- if (d.MainEcdFmat !== undefined) mainStream.MainEcdFmat = d.MainEcdFmat
- if (d.MainFrameTime !== undefined) mainStream.MainFrameTime = d.MainFrameTime
- // // 子码流
- if (d.SecondResolution !== undefined) subStream.SecondResolution = d.SecondResolution
- // if (d.subEncodeType !== undefined) subStream.encodeType = d.subEncodeType
- if (d.SecondFps !== undefined) subStream.SecondFps = d.SecondFps
- if (d.SecondBitRate !== undefined) subStream.SecondBitRate = d.SecondBitRate
- if (d.SecondEcdFmat !== undefined) subStream.SecondEcdFmat = d.SecondEcdFmat
- if (d.SecondFrameTime !== undefined) subStream.SecondFrameTime = d.SecondFrameTime
- // // 实时模式
- // if (d.realtimeMode !== undefined) realtimeMode.value = !!d.realtimeMode
- }
- } catch (e) {
- console.error('获取视频编码参数失败:', e)
- }
- }
- // 保存参数
- async function saveParams() {
- try {
- const data = {
- MainResolution: mainStream.MainResolution,
- // mainEncodeType: mainStream.encodeType,
- MainFps: mainStream.MainFps,
- MainBitRate: mainStream.MainBitRate,
- MainEcdFmat: mainStream.MainEcdFmat,
- MainFrameTime: mainStream.MainFrameTime,
- SecondResolution: subStream.SecondResolution,
- // subEncodeType: subStream.encodeType,
- SecondFps: subStream.SecondFps,
- SecondBitRate: subStream.SecondBitRate,
- SecondEcdFmat: subStream.SecondEcdFmat,
- SecondFrameTime: subStream.SecondFrameTime,
- // realtimeMode: realtimeMode.value ? 1 : 0
- }
- const res = await putVideoEncodePara(data)
- if (res.data === 'ok\n') {
- ElMessage.success('Save Successful')
- }
- } catch (e) {
- ElMessage.warning('Save Failed')
- }
- }
- onMounted(() => {
- fetchParams()
- })
- </script>
- <style scoped lang="scss">
- .video-settings {
- padding: 10px 20px;
- }
- .stream-section {
- border: 1px solid #eee;
- border-radius: 4px;
- padding: 20px 30px;
- margin-bottom: 20px;
- legend {
- font-size: 14px;
- color: #606266;
- padding: 0 8px;
- }
- }
- .form-item {
- display: flex;
- align-items: center;
- margin-bottom: 10px;
- &__label {
- flex: 0 0 120px;
- text-align: right;
- font-size: 13px;
- color: #606266;
- padding-right: 5px;
- }
- &__control {
- display: flex;
- align-items: center;
- gap: 10px;
- .el-select {
- width: 220px;
- }
- .el-input-number {
- width: 220px;
- :deep(.el-input__inner) {
- text-align: left;
- }
- }
- }
- &__hint {
- font-size: 13px;
- color: #909399;
- }
- }
- .realtime-section {
- display: flex;
- align-items: center;
- padding: 20px 0;
- border-top: 1px solid #eee;
- .form-item__label {
- flex: 0 0 100px;
- text-align: right;
- font-size: 13px;
- color: #606266;
- padding-right: 10px;
- }
- .realtime-tip {
- font-size: 12px;
- color: #909399;
- margin-left: 8px;
- }
- }
- .btn-wrapper {
- display: flex;
- // justify-content: space-between;
- gap: 200px;
- padding-top: 20px;
- .btn-reset {
- border-color: #409EFF;
- color: #409EFF;
- &:hover {
- background-color: #409EFF;
- color: #fff;
- }
- }
- .btn-save {
- min-width: 100px;
- }
- }
- </style>
|