allow ajust sentences
This commit is contained in:
@@ -106,6 +106,10 @@ dialog::backdrop { background: rgb(20 25 28 / 55%); }
|
||||
.sentence-scroll { max-height: calc(100vh - 120px); overflow: auto; }
|
||||
.sentence-scroll textarea { width: min(600px, 45vw); min-width: 260px; min-height: 58px; resize: vertical; padding: 7px; border: 1px solid #b8c0c7; border-radius: 3px; }
|
||||
.sentence-scroll select { min-width: 90px; }
|
||||
.boundary-control { display: inline-flex; align-items: center; gap: 4px; margin-left: 6px; white-space: nowrap; }
|
||||
.boundary-control button { min-height: 24px; padding: 2px 6px; font-size: 11px; line-height: 1; }
|
||||
.boundary-time { display: inline-block; min-width: 56px; text-align: center; font-variant-numeric: tabular-nums; }
|
||||
.boundary-status { min-width: 26px; color: #a12622; font-size: 11px; }
|
||||
|
||||
@media (max-width: 820px) {
|
||||
.topbar { align-items: stretch; flex-direction: column; padding: 14px 16px; }
|
||||
|
||||
@@ -91,6 +91,6 @@
|
||||
</div>
|
||||
</dialog>
|
||||
|
||||
<script src="/static/admin.js?v=manual-split-v1" defer></script>
|
||||
<script src="/static/admin.js?v=boundary-adjust-v1" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -239,9 +239,13 @@ function sentenceRow(video, sentence) {
|
||||
}
|
||||
});
|
||||
saveContainer.append(save);
|
||||
const timeContainer = document.createElement("td");
|
||||
const startLabel = document.createElement("span");
|
||||
startLabel.textContent = formatDuration(sentence.start_ms);
|
||||
timeContainer.append(startLabel, " — ", boundaryControl(video, sentence));
|
||||
row.append(
|
||||
textCell(String(sentence.index + 1)),
|
||||
textCell(`${formatDuration(sentence.start_ms)} - ${formatDuration(sentence.end_ms)}`),
|
||||
timeContainer,
|
||||
textContainer,
|
||||
languageContainer,
|
||||
saveContainer,
|
||||
@@ -249,6 +253,50 @@ function sentenceRow(video, sentence) {
|
||||
return row;
|
||||
}
|
||||
|
||||
function boundaryControl(video, sentence) {
|
||||
const container = document.createElement("div");
|
||||
container.className = "boundary-control";
|
||||
const label = document.createElement("span");
|
||||
label.className = "boundary-time";
|
||||
label.textContent = formatDuration(sentence.end_ms);
|
||||
const status = document.createElement("span");
|
||||
status.className = "boundary-status";
|
||||
|
||||
async function adjust(deltaMs, changedButton) {
|
||||
const buttons = [minus, plus];
|
||||
buttons.forEach((item) => { item.disabled = true; });
|
||||
status.textContent = "";
|
||||
try {
|
||||
await api(
|
||||
`/api/v1/admin/videos/${video.video_hash}/sentences/${sentence.index}/boundary`,
|
||||
{
|
||||
method: "PUT",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ delta_ms: deltaMs }),
|
||||
},
|
||||
);
|
||||
await openSentences(video);
|
||||
} catch (error) {
|
||||
elements.serviceState.textContent = `分割点调整失败: ${error.message}`;
|
||||
status.textContent = "失败";
|
||||
buttons.forEach((item) => { item.disabled = false; });
|
||||
window.setTimeout(() => { status.textContent = ""; }, 1800);
|
||||
}
|
||||
if (changedButton) {
|
||||
window.setTimeout(() => {
|
||||
changedButton.textContent = deltaMs < 0 ? "−0.1" : "+0.1";
|
||||
}, 900);
|
||||
}
|
||||
}
|
||||
|
||||
const minus = button("−0.1", (event) => adjust(event.shiftKey ? -10 : -100, minus));
|
||||
const plus = button("+0.1", (event) => adjust(event.shiftKey ? 10 : 100, plus));
|
||||
minus.title = "结束点提前 0.1 秒;按住 Shift 微调 0.01 秒";
|
||||
plus.title = "结束点延后 0.1 秒;按住 Shift 微调 0.01 秒";
|
||||
container.append(minus, label, plus, status);
|
||||
return container;
|
||||
}
|
||||
|
||||
async function reprocess(videoHash) {
|
||||
try {
|
||||
await api(`/api/v1/admin/videos/${videoHash}/process`, { method: "POST" });
|
||||
|
||||
Reference in New Issue
Block a user