pets: the voice description Veo is given is now selectable and editable

This commit is contained in:
gator 2026-09-10 13:13:20 +00:00
parent 89b78e5ae2
commit 58c8e92c3a

View file

@ -59,6 +59,17 @@
</div>
<p id="vdesc" style="color:var(--muted);font-size:13.5px;margin:10px 0 0"></p>
</div>
<div class="field">
<label for="pformula">How the voice is described to the camera</label>
<span class="hint">This exact wording goes into every shot prompt, unchanged, so your pet sounds
like one character rather than a different one each time. Keep it to sound only — pitch, weight,
pace, age. Words like “actress” or “warrior” describe a role and end up in the picture.</span>
<div style="display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin-bottom:8px">
<select id="pformulapreset" style="flex:1 1 240px"><option value="">Start from a preset…</option></select>
<button type="button" class="btn ghost" id="resetformula">Use the voice&rsquo;s own</button>
</div>
<input type="text" id="pformula" placeholder="deep gravelly middle-aged american male baritone">
</div>
<div class="field">
<label for="pvoice">Anything else about how they talk <span style="color:var(--muted);font-weight:400">(optional)</span></label>
<span class="hint">This goes to the writer, not the recording — it shapes the words your pet uses, not the voice itself.</span>
@ -104,8 +115,34 @@ function describeVoice() {
+ '</span>';
}
// Filled from the server so the presets cannot drift from the ones the prompt
// builder knows about.
var formulaPresets = [];
function fillFormulaPresets(list) {
formulaPresets = list || [];
document.getElementById("pformulapreset").innerHTML =
'<option value="">Start from a preset…</option>'
+ formulaPresets.map(function (d) {
return '<option value="' + esc(d.formula) + '">' + esc(d.label) + ' — ' + esc(d.formula) + '</option>';
}).join("");
}
document.getElementById("pformulapreset").addEventListener("change", function () {
if (this.value) document.getElementById("pformula").value = this.value;
});
// Empty means “whatever the chosen voice says”, which is what the server does
// with a blank field, so clearing it is the honest way to reset.
document.getElementById("resetformula").addEventListener("click", function () {
var v = voiceById(document.getElementById("pvoiceid").value);
document.getElementById("pformula").value = v ? v.formula : "";
document.getElementById("pformulapreset").value = "";
});
async function loadVoices() {
var r = await api("camera_presets", {});
fillFormulaPresets(r.voice_descriptions);
var sel = document.getElementById("pvoiceid");
if (!r.ok || !(r.voices || []).length) {
sel.innerHTML = '<option value="">Voices unavailable</option>';
@ -217,6 +254,7 @@ document.getElementById("petform").addEventListener("submit", async function (e)
appearance: document.getElementById("pappear").value.trim(),
personality: document.getElementById("pperson").value.trim(),
voice: document.getElementById("pvoice").value.trim(),
voice_formula: document.getElementById("pformula").value.trim(),
eleven_voice_id: document.getElementById("pvoiceid").value
};
if (!pet.name) { showMsg("msg", "Your pet needs a name."); return; }
@ -234,7 +272,8 @@ document.getElementById("petform").addEventListener("submit", async function (e)
function resetForm() {
document.getElementById("petid").value = "";
["pname", "pbreed", "pappear", "pperson", "pvoice"].forEach(function (i) { document.getElementById(i).value = ""; });
["pname", "pbreed", "pappear", "pperson", "pvoice", "pformula"].forEach(function (i) { document.getElementById(i).value = ""; });
document.getElementById("pformulapreset").value = "";
document.getElementById("pvoiceid").value = "";
describeVoice();
document.getElementById("pspecies").value = "dog";
@ -281,6 +320,8 @@ document.getElementById("list").addEventListener("click", async function (e) {
document.getElementById("pperson").value = p.personality || "";
document.getElementById("pvoice").value = p.voice || "";
document.getElementById("pvoiceid").value = p.eleven_voice_id || "";
document.getElementById("pformula").value = p.voice_formula || "";
document.getElementById("pformulapreset").value = "";
describeVoice();
document.getElementById("formtitle").textContent = "Edit " + (p.name || "pet");
document.getElementById("cancel").style.display = "";