feat: support inline event scripts

This commit is contained in:
2026-04-25 14:32:30 +08:00
parent 05961eb700
commit aa548db980
5 changed files with 278 additions and 16 deletions
+123 -9
View File
@@ -36,9 +36,15 @@ const form = reactive<SystemSettings>({
autoStartRecordingOnLive: true,
pollingIntervalSeconds: 60,
enableEventScripts: false,
liveStartedScriptMode: "path",
liveStartedScriptPath: "",
liveStartedScriptContent: "",
liveEndedScriptMode: "path",
liveEndedScriptPath: "",
liveEndedScriptContent: "",
segmentCompletedScriptMode: "path",
segmentCompletedScriptPath: "",
segmentCompletedScriptContent: "",
eventScriptTimeoutSeconds: 60,
enableEmailNotification: false,
emailSmtpHost: "",
@@ -135,6 +141,11 @@ const eventScriptEnvironmentExamples = [
{ name: "LIVE_RECORDER_SESSION_STATUS", example: "Running", scope: "仅分片完成" }
];
const eventScriptModeOptions = [
{ label: "路径", value: "path" },
{ label: "脚本文本", value: "inline" }
];
const canSendTestEmail = computed(() =>
Boolean(form.emailSmtpHost.trim() && form.emailFromAddress.trim() && form.emailToAddresses.trim())
);
@@ -482,19 +493,91 @@ onMounted(loadSettings);
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="开播脚本路径">
<el-input v-model="form.liveStartedScriptPath" :disabled="!form.enableEventScripts" placeholder="/app/scripts/live-started.sh" />
</el-form-item>
<div class="event-script-section">
<div class="event-script-section__header">
<h4 class="event-script-section__title">开播</h4>
<el-radio-group v-model="form.liveStartedScriptMode" size="small" :disabled="!form.enableEventScripts">
<el-radio-button
v-for="option in eventScriptModeOptions"
:key="`live-started-${option.value}`"
:label="option.value">
{{ option.label }}
</el-radio-button>
</el-radio-group>
</div>
<el-form-item v-if="form.liveStartedScriptMode === 'path'" label="开播脚本路径">
<el-input
v-model="form.liveStartedScriptPath"
:disabled="!form.enableEventScripts"
placeholder="/app/scripts/live-started.sh" />
</el-form-item>
<el-form-item v-else label="开播脚本文本">
<el-input
v-model="form.liveStartedScriptContent"
:disabled="!form.enableEventScripts"
type="textarea"
:rows="6"
placeholder='echo "started: $LIVE_RECORDER_ROOM_ID"' />
</el-form-item>
</div>
</el-col>
<el-col :span="24">
<el-form-item label="下播脚本路径">
<el-input v-model="form.liveEndedScriptPath" :disabled="!form.enableEventScripts" placeholder="/app/scripts/live-ended.sh" />
</el-form-item>
<div class="event-script-section">
<div class="event-script-section__header">
<h4 class="event-script-section__title">下播</h4>
<el-radio-group v-model="form.liveEndedScriptMode" size="small" :disabled="!form.enableEventScripts">
<el-radio-button
v-for="option in eventScriptModeOptions"
:key="`live-ended-${option.value}`"
:label="option.value">
{{ option.label }}
</el-radio-button>
</el-radio-group>
</div>
<el-form-item v-if="form.liveEndedScriptMode === 'path'" label="下播脚本路径">
<el-input
v-model="form.liveEndedScriptPath"
:disabled="!form.enableEventScripts"
placeholder="/app/scripts/live-ended.sh" />
</el-form-item>
<el-form-item v-else label="下播脚本文本">
<el-input
v-model="form.liveEndedScriptContent"
:disabled="!form.enableEventScripts"
type="textarea"
:rows="6"
placeholder='echo "ended: $LIVE_RECORDER_ROOM_ID"' />
</el-form-item>
</div>
</el-col>
<el-col :span="24">
<el-form-item label="分片完成脚本路径">
<el-input v-model="form.segmentCompletedScriptPath" :disabled="!form.enableEventScripts" placeholder="/app/scripts/segment-completed.sh" />
</el-form-item>
<div class="event-script-section">
<div class="event-script-section__header">
<h4 class="event-script-section__title">分片完成</h4>
<el-radio-group v-model="form.segmentCompletedScriptMode" size="small" :disabled="!form.enableEventScripts">
<el-radio-button
v-for="option in eventScriptModeOptions"
:key="`segment-completed-${option.value}`"
:label="option.value">
{{ option.label }}
</el-radio-button>
</el-radio-group>
</div>
<el-form-item v-if="form.segmentCompletedScriptMode === 'path'" label="分片完成脚本路径">
<el-input
v-model="form.segmentCompletedScriptPath"
:disabled="!form.enableEventScripts"
placeholder="/app/scripts/segment-completed.sh" />
</el-form-item>
<el-form-item v-else label="分片完成脚本文本">
<el-input
v-model="form.segmentCompletedScriptContent"
:disabled="!form.enableEventScripts"
type="textarea"
:rows="8"
placeholder='echo "$LIVE_RECORDER_SEGMENT_FILE_PATH"' />
</el-form-item>
</div>
</el-col>
</el-row>
</el-form>
@@ -504,6 +587,10 @@ onMounted(loadSettings);
开播/下播脚本会带全部事件里的变量分片完成脚本会额外带分片路径弹幕路径时长文件大小任务状态这些值取不到时会传空字符串
</div>
<div class="event-script-help__intro">
脚本文本模式在 Linux Docker 中通过 <code>/bin/sh -c</code> 执行 Windows 中通过 <code>PowerShell -Command</code> 执行
</div>
<div class="event-script-example">
<div class="event-script-example__label">环境变量示例值</div>
<div class="event-script-example__grid">
@@ -734,6 +821,28 @@ onMounted(loadSettings);
margin-bottom: 12px;
}
.event-script-section {
padding: 16px;
border-radius: 10px;
border: 1px solid rgba(91, 110, 129, 0.12);
background: rgba(255, 255, 255, 0.72);
}
.event-script-section__header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
margin-bottom: 12px;
}
.event-script-section__title {
margin: 0;
font-size: 14px;
font-weight: 700;
color: #1e2937;
}
.event-script-example {
display: grid;
gap: 10px;
@@ -860,6 +969,11 @@ onMounted(loadSettings);
align-items: flex-start;
}
.event-script-section__header {
flex-direction: column;
align-items: flex-start;
}
.event-script-example__row {
grid-template-columns: 1fr;
gap: 4px;