- 在命令分类中添加视频操作命令,支持视频压缩、视频转GIF、音频提取、视频剪切、视频旋转/翻转、添加水印、视频合并、视频调速、视频分辨率调整、视频格式转换、视频裁剪、导出图片序列、生成缩略图

This commit is contained in:
fofolee
2025-01-28 01:13:46 +08:00
parent 31a543d0c5
commit 70e01a53d8
11 changed files with 2590 additions and 7 deletions

View File

@@ -179,15 +179,22 @@ export default defineComponent({
},
getAllInputValues(argvs) {
const flatArgvs = [];
if (!argvs) return flatArgvs;
argvs.forEach((item) => {
if (!item) return;
if (isVarInputVal(item) && item.value) {
flatArgvs.push(stringifyVarInputVal(item));
} else if (typeof item === "number") {
flatArgvs.push(item.toString());
} else if (Array.isArray(item)) {
flatArgvs.push(...this.getAllInputValues(item));
} else if (typeof item === "object") {
flatArgvs.push(...this.getAllInputValues(Object.values(item)));
} else if (typeof item === "object" && item !== null) {
const values = Object.values(item);
if (values.length > 0) {
flatArgvs.push(...this.getAllInputValues(values));
}
}
});
return flatArgvs;
@@ -226,7 +233,7 @@ export default defineComponent({
},
mounted() {
const argvs = this.modelValue.argvs || this.defaultArgvs;
if (!this.modelValue.code) {
if (!this.modelValue.code && Array.isArray(argvs)) {
this.updateModelValue(this.funcName, argvs);
}
},

View File

@@ -0,0 +1,181 @@
<template>
<BorderLabel
:label="label"
:icon="icon"
:model-value="false"
class="time-input"
>
<div class="row q-col-gutter-sm items-center">
<!-- -->
<div class="col-4">
<q-input
v-model="hours"
dense
borderless
:placeholder="'00'"
@update:model-value="updateTime"
@blur="formatInput('hours')"
maxlength="2"
class="time-field"
>
<template v-slot:append>
<div class="text-caption"></div>
</template>
</q-input>
</div>
<!-- -->
<div class="col-4">
<q-input
v-model="minutes"
dense
borderless
:placeholder="'00'"
@update:model-value="updateTime"
@blur="formatInput('minutes')"
maxlength="2"
class="time-field"
>
<template v-slot:append>
<div class="text-caption"></div>
</template>
</q-input>
</div>
<!-- -->
<div class="col-4">
<q-input
v-model="seconds"
dense
borderless
:placeholder="'00'"
@update:model-value="updateTime"
@blur="formatInput('seconds')"
maxlength="2"
class="time-field"
>
<template v-slot:append>
<div class="text-caption"></div>
</template>
</q-input>
</div>
</div>
</BorderLabel>
</template>
<script>
import BorderLabel from "./BorderLabel.vue";
export default {
name: "TimeInput",
components: {
BorderLabel,
},
props: {
modelValue: {
type: String,
default: "00:00:00",
},
label: {
type: String,
default: "",
},
icon: {
type: String,
default: "",
},
iconClickable: {
type: Boolean,
default: false,
},
placeholder: {
type: String,
default: "00:00:00",
},
},
data() {
return {
hours: "00",
minutes: "00",
seconds: "00",
};
},
watch: {
modelValue: {
immediate: true,
handler(newVal) {
if (newVal) {
const parts = newVal.split(":");
if (parts.length === 3) {
this.hours = parts[0];
this.minutes = parts[1];
this.seconds = parts[2];
}
}
},
},
},
methods: {
// 更新时间
updateTime() {
const formattedTime = `${this.hours}:${this.minutes}:${this.seconds}`;
this.$emit("update:model-value", formattedTime);
},
// 格式化输入
formatInput(field) {
const value = this[field];
let num = parseInt(value) || 0;
// 限制范围
switch (field) {
case "hours":
num = Math.min(Math.max(num, 0), 99);
break;
case "minutes":
case "seconds":
num = Math.min(Math.max(num, 0), 59);
break;
}
// 格式化为两位数
this[field] = num.toString().padStart(2, "0");
this.updateTime();
},
},
};
</script>
<style scoped>
.time-input {
width: 100%;
height: 36px;
}
.time-input :deep(.content) {
padding: 0 8px;
}
.time-field {
font-size: 13px;
}
.time-input :deep(.border-label) {
margin-top: 0;
}
/* 文本居中显示 */
.time-input :deep(.q-field__native) {
text-align: center;
padding: 0;
height: 34px;
}
.time-input :deep(.q-field__control) {
padding: 0 4px;
height: 34px;
}
/* 调整单位标签样式 */
.time-input :deep(.q-field__append) {
padding-left: 0;
height: 34px;
}
</style>

View File

@@ -22,6 +22,7 @@ import ButtonGroup from "components/composer/common/ButtonGroup.vue";
import ControlInput from "components/composer/common/ControlInput.vue";
import CheckGroup from "components/composer/common/CheckGroup.vue";
import CheckButton from "components/composer/common/CheckButton.vue";
import TimeInput from "components/composer/common/TimeInput.vue";
import { QInput, QSelect, QToggle, QCheckbox } from "quasar";
const CodeEditor = defineAsyncComponent(() =>
import("components/composer/common/CodeEditor.vue")
@@ -42,6 +43,7 @@ export default defineComponent({
QInput,
QSelect,
QCheckbox,
TimeInput,
CodeEditor,
},
props: {

View File

@@ -19,6 +19,7 @@ import { statusCommands } from "./statusCommands";
import { macosCommands } from "./macosCommands";
import { scriptCommands } from "./scriptCommands";
import { browserCommands } from "./browserCommands";
import { videoCommands } from "./videoCommands";
const platformCommands = {
win32: [windowsCommands],
@@ -32,6 +33,7 @@ export const commandCategories = [
systemCommands,
audioCommands,
imageCommands,
...(utools.runFFmpeg ? [videoCommands] : []),
utoolsCommands,
...platformCommands[window.processPlatform],
browserCommands,

File diff suppressed because it is too large Load Diff

View File

@@ -131,7 +131,5 @@ export function generateCode(flow) {
const finalCode = code.join("\n");
console.log(finalCode);
return finalCode;
}