cap / client-v3.html
ADXabhi's picture
Upload 7 files
a8e28bb verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Caption Burner V3</title>
<style>
body {
background: #111;
color: white;
get_font-family: sans-serif;
display: flex;
justify-content: center;
padding-top: 50px;
}
.box {
width: 500px;
padding: 20px;
border: 1px solid #333;
border-radius: 8px;
background: #222;
}
input,
select,
button {
width: 100%;
margin-bottom: 10px;
padding: 10px;
box-sizing: border-box;
}
button {
background: limegreen;
cursor: pointer;
border: none;
font-weight: bold;
}
pre {
background: #000;
padding: 10px;
font-size: 0.8rem;
overflow: auto;
}
</style>
</head>
<body>
<div class="box">
<h2>🔥 Caption Layer Generator</h2>
<label>Space URL</label>
<input id="serverUrl" value="https://adxabhi-cap.hf.space" placeholder="Space URL">
<label>Style</label>
<select id="styleSelector">
<option value="hormozi">Hormozi (Yellow)</option>
<option value="netflix">Netflix (Red)</option>
<option value="neon">Neon (Glowing)</option>
</select>
<label>Transcript JSON</label>
<textarea id="transcriptBox" rows="10" style="width:100%; background:#111; color:#0f0; font-family:monospace;">[
{ "text": "THIS IS", "start": 0.0, "end": 1.0 },
{ "text": "A TRANSPARENT", "start": 1.0, "end": 2.5 },
{ "text": "OVERLAY", "start": 2.5, "end": 4.0 }
]</textarea>
<button onclick="testConnection()" style="background:#555">Test Connection</button>
<button onclick="start()">Generate Layer</button>
<div id="status">Waiting...</div>
<div id="resultArea" style="margin-top:20px;"></div>
</div>
<script>
async function testConnection() {
const server = document.getElementById('serverUrl').value.trim().replace(/\/$/, "");
const status = document.getElementById('status');
status.innerText = `Testing GET ${server}/ ...`;
try {
const res = await fetch(`${server}/`);
const txt = await res.text();
status.innerText = `Server OK: ${res.status} (${txt})`;
} catch (e) {
status.innerText = `Connection Failed: ${e.message}`;
}
}
async function start() {
const server = document.getElementById('serverUrl').value.trim().replace(/\/$/, "");
const style = document.getElementById('styleSelector').value;
const transcriptText = document.getElementById('transcriptBox').value;
const status = document.getElementById('status');
const resArea = document.getElementById('resultArea');
let transcript;
try {
transcript = JSON.parse(transcriptText);
} catch (e) {
alert("Invalid JSON!");
return;
}
status.innerText = `POSTing to ${server}/jobs ...`;
resArea.innerHTML = "";
try {
const res = await fetch(`${server}/jobs`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
video_url: "dummy",
transcript: transcript,
style: style
})
});
if (!res.ok) {
const txt = await res.text();
status.innerText = `Error ${res.status}: ${txt}`;
console.error("Fetch Error:", res.status, txt);
return;
}
const data = await res.json();
const jobId = data.job_id;
console.log("Job ID:", jobId);
const interval = setInterval(async () => {
const r = await fetch(`${server}/jobs/${jobId}`);
const job = await r.json();
status.innerText = `Status: ${job.status} (${job.progress})`;
if (job.status === 'completed') {
clearInterval(interval);
const url = job.result[0];
const assUrl = job.result[1];
resArea.innerHTML = `
<p style="color:#0f0">Success!</p>
<a href="${url}" target="_blank" style="color:yellow; word-break:break-all;">VIDEO: ${url}</a>
<br>
<a href="${assUrl}" target="_blank" style="color:cyan; word-break:break-all;">DEBUG ASS: ${assUrl}</a>
<br><br>
<video src="${url}" controls style="width:100%; background: checkerboard;"></video>
`;
}
if (job.status === 'failed') {
clearInterval(interval);
status.innerText = "Error: " + job.error;
}
}, 3000);
} catch (e) {
status.innerText = `Network Error: ${e.message}`;
console.error(e);
}
}
</script>
</body>
</html>