Merge pull request #210 from jamebal/dev

perf: 优化视频转码配置
This commit is contained in:
jmal 2024-06-29 17:43:08 +08:00 committed by GitHub
commit 5c144b8298
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 224 additions and 20 deletions

View File

@ -29,6 +29,13 @@ export default {
data
})
},
cancelTranscodeTask(data) {
return request({
url: '/cloud/setting/transcode/cancel-task',
method: 'put',
data
})
},
syncUser(params) {
return request({
url: '/user/setting/sync',
@ -162,3 +169,11 @@ export function getTaskProgress(params) {
params
})
}
export function getTranscodeStatus(params) {
return request({
url: '/cloud/transcode/status',
method: 'get',
params
})
}

View File

@ -54,6 +54,7 @@ function onMessage(msg) {
const eventMapping = {
synced: 'msg/synced',
taskProgress: 'msg/taskProgress',
transcodeStatus: 'msg/transcodeStatus',
uploaderChunkSize: 'uploaderChunkSize',
};

View File

@ -214,4 +214,11 @@ a:hover {
}
}
}
.form-item-flex {
display: flex;
align-items: center;
>>> .el-icon-question {
padding: 5px;
font-size: 1rem;
}
}

View File

@ -65,11 +65,23 @@ export function formatVideo(videoInfo) {
if (videoInfo['bitrate']) {
videoStr += `\r\n码率: ${videoInfo['bitrate']}`
}
if (videoInfo['frameRate']) {
videoStr += `\r\n帧率: ${videoInfo['frameRate']} fps`
}
if (videoInfo['format']) {
videoStr += `\r\n格式: ${videoInfo['format']}`
}
if (videoInfo['duration']) {
videoStr += `\r\n时长: ${videoInfo['duration']}`
}
if (videoInfo['toBitrate']) {
videoStr += `\r\n转码后的码率: ${videoInfo['toBitrate']} kbps`
}
if (videoInfo['toFrameRate']) {
videoStr += `\r\n转码后的帧率: ${videoInfo['toFrameRate']} fps`
}
if (videoInfo['toHeight']) {
videoStr += `\r\n转码后的高度: ${videoInfo['toHeight']}`
}
return videoStr
}

View File

@ -3,25 +3,120 @@
<el-form :rules="rules" ref="transcodeConfigForm" :model="configFormData" label-width="120px" size="small"
style="width: 520px" autocomplete="off">
<el-form-item label="功能状态" prop="enable">
<el-select v-model="configFormData.enable">
<el-option
v-for="item in configEnableOptions"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
<el-switch
v-model="configFormData.enable"
active-text="启用"
active-color="#13ce66"
inactive-color="#ff4949"
inactive-text="禁用">
</el-switch>
</el-form-item>
<el-form-item label="最大线程数" prop="maxThreads">
<div class="form-item-flex">
<el-input-number v-model="configFormData.maxThreads" :min="1" :max="8" label="最大线程数"></el-input-number>
<div>
<el-tooltip class="item" effect="dark" content="最多同时的转码的任务数, 默认为1(可根据具体硬件配置酌情增加)" placement="top">
<i class="el-icon-question"></i>
</el-tooltip>
</div>
</div>
</el-form-item>
<el-divider content-position="left">转码条件, 以下三个条件满足其一即可</el-divider>
<el-form-item label="码率(kbps)" prop="bitrateCond">
<div class="form-item-flex">
<el-input placeholder="2500" v-model.number="configFormData.bitrateCond"></el-input>
<div>
<el-tooltip class="item" effect="dark" content="转码条件: 视频码率(kbps), 默认 2500 kbps, 小于该值则不转码" placement="top">
<i class="el-icon-question"></i>
</el-tooltip>
</div>
</div>
</el-form-item>
<el-form-item label="高度" prop="height">
<div class="form-item-flex">
<el-input placeholder="720" v-model.number="configFormData.heightCond"></el-input>
<div>
<el-tooltip class="item" effect="dark" content="转码条件: 视频高度(视频宽度, 默认随高度等比例缩放), 默认 720, 小于该值则不转码" placement="top">
<i class="el-icon-question"></i>
</el-tooltip>
</div>
</div>
</el-form-item>
<el-form-item label="帧率" prop="height">
<div class="form-item-flex">
<el-input placeholder="30" v-model.number="configFormData.frameRateCond"></el-input>
<div>
<el-tooltip class="item" effect="dark" content="转码条件: 视频帧率, 默认 30 fps, 小于该值则不转码" placement="top">
<i class="el-icon-question"></i>
</el-tooltip>
</div>
</div>
</el-form-item>
<el-divider content-position="left">转码参数</el-divider>
<el-form-item label="目标码率(kbps)" prop="bitrate">
<el-input placeholder="2500" v-model.number="configFormData.bitrate"></el-input>
<span class="form-instruction">默认2500 kbps,小于该值则不转码</span>
<div class="form-item-flex">
<el-input placeholder="2500" v-model.number="configFormData.bitrate"></el-input>
<div>
<el-tooltip class="item" effect="dark" content="转码后的视频码率(kbps),默认 2500 kbps" placement="top">
<i class="el-icon-question"></i>
</el-tooltip>
</div>
</div>
</el-form-item>
<el-form-item label="目标高度" prop="height">
<el-input placeholder="720" v-model.number="configFormData.height"></el-input>
<span class="form-instruction">默认720,小于该值则不转码(视频宽度则默认随高度等比例缩放)</span>
<div class="form-item-flex">
<el-input placeholder="720" v-model.number="configFormData.height"></el-input>
<div>
<el-tooltip class="item" effect="dark" content="转码后的视频高度, 默认720(视频宽度则默认随高度等比例缩放)" placement="top">
<i class="el-icon-question"></i>
</el-tooltip>
</div>
</div>
</el-form-item>
<el-form-item label="目标帧率" prop="height">
<div class="form-item-flex">
<el-input placeholder="30" v-model.number="configFormData.frameRate"></el-input>
<div>
<el-tooltip class="item" effect="dark" content="转码后的视频帧率, 默认 30 fps" placement="top">
<i class="el-icon-question"></i>
</el-tooltip>
</div>
</div>
</el-form-item>
<el-form-item label="vtt缩略图数量" prop="vttThumbnailCount">
<div class="form-item-flex">
<el-input placeholder="60" v-model.number="configFormData.vttThumbnailCount"></el-input>
<div>
<el-tooltip class="item" effect="dark" content="vtt缩略图数量, 默认 60 张" placement="top">
<i class="el-icon-question"></i>
</el-tooltip>
</div>
</div>
</el-form-item>
<el-form-item label="是否重新转码" prop="isReTranscode">
<div class="form-item-flex">
<el-switch v-model="configFormData.isReTranscode"></el-switch>
<div>
<el-tooltip class="item" effect="dark" content="转码参数变化后对已经转码过的视频重新转码, 默认开启" placement="top">
<i class="el-icon-question"></i>
</el-tooltip>
</div>
</div>
</el-form-item>
<el-form-item>
<el-button type="primary" v-loading="saveConfigLoading" @click="saveConfig">保存配置</el-button>
<div class="transcode-status">
<el-button v-if="transcodeStatus.waitingTranscodingCount > 0 || transcodeStatus.transcodingCount > 0" type="warning" v-loading="cancelTaskLoading" @click="cancelTask">取消任务</el-button>
<el-button v-else type="primary" v-loading="saveConfigLoading" @click="saveConfig">保存配置</el-button>
<div>
<span v-if="transcodeStatus.waitingTranscodingCount > 0"><b>{{transcodeStatus.waitingTranscodingCount}}</b>个视频等待转码 </span>
<span v-if="transcodeStatus.transcodingCount > 0"> <b>{{transcodeStatus.transcodingCount}}</b>个视频正在转码中</span>
</div>
</div>
</el-form-item>
</el-form>
</div>
@ -29,7 +124,8 @@
<script>
import settingApi from "@/api/setting-api";
import settingApi, { getTranscodeStatus } from '@/api/setting-api'
import { mapState } from 'vuex'
export default {
name: 'TranscodeConfig',
@ -40,14 +136,34 @@ export default {
},
},
computed: {
...mapState(['message'])
},
watch: {
message(msg) {
if (msg.event === 'msg/transcodeStatus') {
this.transcodeStatus = msg.data.body
}
}
},
data() {
return {
saveConfigLoading: false,
cancelTaskLoading: false,
configFormData: {
enable: true,
bitrate: undefined,
height: undefined
height: undefined,
frameRate: undefined,
bitrateCond: undefined,
maxThreads: undefined,
heightCond: undefined,
frameRateCond: undefined,
vttThumbnailCount: undefined,
isReTranscode: undefined
},
transcodeStatus: {
waitingTranscodingCount: 0,
transcodingCount: 0
},
configEnableOptions: [{
value: true,
@ -68,6 +184,9 @@ export default {
},
mounted() {
this.getTranscodeConfig()
getTranscodeStatus().then(res => {
this.transcodeStatus = res.data
})
},
methods: {
getTranscodeConfig() {
@ -77,18 +196,44 @@ export default {
},
saveConfig() {
this.saveConfigLoading = true
settingApi.setTranscodeConfig(this.configFormData).then(() => {
settingApi.setTranscodeConfig(this.configFormData).then((res) => {
if (res.data > 0) {
this.transcodeStatus.waitingTranscodingCount = res.data
}
this.saveConfigLoading = false
this.$message.success('保存成功')
}).catch(() => {
this.saveConfigLoading = false
})
},
cancelTask() {
this.$confirm('确定要取消转码任务吗?可能导致转码后的视频不完整', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.doCancelTask()
})
},
doCancelTask() {
this.cancelTaskLoading = true
settingApi.cancelTranscodeTask().then(() => {
this.$message.success('取消成功')
this.cancelTaskLoading = false
}).catch(() => {
this.cancelTaskLoading = false
})
}
}
}
</script>
<style lang="scss" scoped>
@import "src/styles/setting";
.transcode-status {
display: flex;
justify-content: space-between;
}
.container {
padding: 0 !important;
}

View File

@ -10,7 +10,13 @@
</div>
<div>
<div class="setting-title-desc">
<div class="setting-title-desc-text">OCR识别任务和视频转码任务</div>
<div class="title-status">
<div class="setting-title-desc-text">OCR识别任务和视频转码任务</div>
<div>
<span v-if="transcodeStatus.waitingTranscodingCount > 0"><b>{{transcodeStatus.waitingTranscodingCount}}</b>个视频等待转码 </span>
<span v-if="transcodeStatus.transcodingCount > 0"> <b>{{transcodeStatus.transcodingCount}}</b>个视频正在转码中</span>
</div>
</div>
<el-divider></el-divider>
</div>
<task-progress :data="taskProgressDataList"></task-progress>
@ -22,23 +28,37 @@
<script>
import TaskProgress from "@/components/TaskProgress/index.vue";
import {getTaskProgress} from "@/api/setting-api";
import { getTaskProgress, getTranscodeStatus } from '@/api/setting-api'
import { mapState } from 'vuex'
export default {
components: { TaskProgress },
data() {
return {
taskProgressDataList: [],
transcodeStatus: {
waitingTranscodingCount: 0,
transcodingCount: 0
}
}
},
mounted() {
getTaskProgress().then(res => {
this.taskProgressDataList = res.data
})
getTranscodeStatus().then(res => {
this.transcodeStatus = res.data
})
},
computed: {
...mapState(['message'])
},
watch: {
message(msg) {
if (msg.event === 'msg/transcodeStatus') {
this.transcodeStatus = msg.data.body
}
}
},
methods: {
}
@ -47,7 +67,11 @@ export default {
<style lang="scss" scoped>
@import "src/styles/setting";
.title-status {
display: flex;
align-items: baseline;
justify-content: space-between;
}
.progress {
margin-top: 5px;
>>> .el-card__header {