perf: 优化视频转码配置

This commit is contained in:
jmal 2024-06-25 16:07:54 +08:00
parent 08c9a16899
commit 92aff31e5a
6 changed files with 220 additions and 19 deletions

View File

@ -29,6 +29,13 @@ export default {
data data
}) })
}, },
cancelTranscodeTask(data) {
return request({
url: '/cloud/setting/transcode/cancel-task',
method: 'put',
data
})
},
syncUser(params) { syncUser(params) {
return request({ return request({
url: '/user/setting/sync', url: '/user/setting/sync',
@ -162,3 +169,11 @@ export function getTaskProgress(params) {
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 = { const eventMapping = {
synced: 'msg/synced', synced: 'msg/synced',
taskProgress: 'msg/taskProgress', taskProgress: 'msg/taskProgress',
transcodeStatus: 'msg/transcodeStatus',
uploaderChunkSize: 'uploaderChunkSize', 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']) { if (videoInfo['bitrate']) {
videoStr += `\r\n码率: ${videoInfo['bitrate']}` videoStr += `\r\n码率: ${videoInfo['bitrate']}`
} }
if (videoInfo['frameRate']) {
videoStr += `\r\n帧率: ${videoInfo['frameRate']} fps`
}
if (videoInfo['format']) { if (videoInfo['format']) {
videoStr += `\r\n格式: ${videoInfo['format']}` videoStr += `\r\n格式: ${videoInfo['format']}`
} }
if (videoInfo['duration']) { if (videoInfo['duration']) {
videoStr += `\r\n时长: ${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 return videoStr
} }

View File

@ -3,25 +3,120 @@
<el-form :rules="rules" ref="transcodeConfigForm" :model="configFormData" label-width="120px" size="small" <el-form :rules="rules" ref="transcodeConfigForm" :model="configFormData" label-width="120px" size="small"
style="width: 520px" autocomplete="off"> style="width: 520px" autocomplete="off">
<el-form-item label="功能状态" prop="enable"> <el-form-item label="功能状态" prop="enable">
<el-select v-model="configFormData.enable"> <el-switch
<el-option v-model="configFormData.enable"
v-for="item in configEnableOptions" active-text="启用"
:key="item.value" active-color="#13ce66"
:label="item.label" inactive-color="#ff4949"
:value="item.value"> inactive-text="禁用">
</el-option> </el-switch>
</el-select>
</el-form-item> </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-form-item label="目标码率(kbps)" prop="bitrate">
<el-input placeholder="2500" v-model.number="configFormData.bitrate"></el-input> <div class="form-item-flex">
<span class="form-instruction">默认2500 kbps,小于该值则不转码</span> <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>
<el-form-item label="目标高度" prop="height"> <el-form-item label="目标高度" prop="height">
<el-input placeholder="720" v-model.number="configFormData.height"></el-input> <div class="form-item-flex">
<span class="form-instruction">默认720,小于该值则不转码(视频宽度则默认随高度等比例缩放)</span> <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-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-item>
</el-form> </el-form>
</div> </div>
@ -29,7 +124,8 @@
<script> <script>
import settingApi from "@/api/setting-api"; import settingApi, { getTranscodeStatus } from '@/api/setting-api'
import { mapState } from 'vuex'
export default { export default {
name: 'TranscodeConfig', name: 'TranscodeConfig',
@ -40,14 +136,34 @@ export default {
}, },
}, },
computed: { computed: {
...mapState(['message'])
},
watch: {
message(msg) {
if (msg.event === 'msg/transcodeStatus') {
this.transcodeStatus = msg.data.body
}
}
}, },
data() { data() {
return { return {
saveConfigLoading: false, saveConfigLoading: false,
cancelTaskLoading: false,
configFormData: { configFormData: {
enable: true, enable: true,
bitrate: undefined, 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: [{ configEnableOptions: [{
value: true, value: true,
@ -68,6 +184,9 @@ export default {
}, },
mounted() { mounted() {
this.getTranscodeConfig() this.getTranscodeConfig()
getTranscodeStatus().then(res => {
this.transcodeStatus = res.data
})
}, },
methods: { methods: {
getTranscodeConfig() { getTranscodeConfig() {
@ -83,12 +202,35 @@ export default {
}).catch(() => { }).catch(() => {
this.saveConfigLoading = false 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> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@import "src/styles/setting";
.transcode-status {
display: flex;
justify-content: space-between;
}
.container { .container {
padding: 0 !important; padding: 0 !important;
} }

View File

@ -10,7 +10,13 @@
</div> </div>
<div> <div>
<div class="setting-title-desc"> <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> <el-divider></el-divider>
</div> </div>
<task-progress :data="taskProgressDataList"></task-progress> <task-progress :data="taskProgressDataList"></task-progress>
@ -22,23 +28,37 @@
<script> <script>
import TaskProgress from "@/components/TaskProgress/index.vue"; 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 { export default {
components: { TaskProgress }, components: { TaskProgress },
data() { data() {
return { return {
taskProgressDataList: [], taskProgressDataList: [],
transcodeStatus: {
waitingTranscodingCount: 0,
transcodingCount: 0
}
} }
}, },
mounted() { mounted() {
getTaskProgress().then(res => { getTaskProgress().then(res => {
this.taskProgressDataList = res.data this.taskProgressDataList = res.data
}) })
getTranscodeStatus().then(res => {
this.transcodeStatus = res.data
})
}, },
computed: { computed: {
...mapState(['message'])
}, },
watch: { watch: {
message(msg) {
if (msg.event === 'msg/transcodeStatus') {
this.transcodeStatus = msg.data.body
}
}
}, },
methods: { methods: {
} }
@ -47,7 +67,11 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
@import "src/styles/setting"; @import "src/styles/setting";
.title-status {
display: flex;
align-items: baseline;
justify-content: space-between;
}
.progress { .progress {
margin-top: 5px; margin-top: 5px;
>>> .el-card__header { >>> .el-card__header {