feat: support inline event scripts
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user