160 lines
5.6 KiB
HTML
160 lines
5.6 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="zh">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<title>数字人 API 测试</title>
|
|
<style>
|
|
body { font-family: Arial, sans-serif; margin: 20px; }
|
|
section { margin-bottom: 40px; padding: 15px; border: 1px solid #ccc; border-radius: 8px; }
|
|
input, textarea { width: 100%; margin: 8px 0; padding: 6px; }
|
|
button { margin-top: 5px; padding: 8px 14px; cursor: pointer; }
|
|
#log { white-space: pre-wrap; background: #f7f7f7; border: 1px solid #ccc; padding: 10px; margin-top: 20px; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<h1>数字人 API 测试页面</h1>
|
|
|
|
<!-- 数字人生成 -->
|
|
<section>
|
|
<h2>生成数字人</h2>
|
|
<label>语音文本:</label>
|
|
<textarea id="speech_text">你好,这是数字人生成测试。</textarea>
|
|
<label>样例视频 (文件名或路径):</label>
|
|
<input type="text" id="sample_video" value="sample_video.mp4">
|
|
<label>样例音频 (文件名或路径):</label>
|
|
<input type="text" id="sample_voice" value="sample_voice.wav">
|
|
<button onclick="submitDigitalHuman()">提交任务</button>
|
|
</section>
|
|
|
|
<!-- 视频转音频 -->
|
|
<section>
|
|
<h2>视频提取音频</h2>
|
|
<label>视频路径:</label>
|
|
<input type="text" id="video_path" value="sample_video.mp4">
|
|
<button onclick="submitExtractAudio()">提取音频</button>
|
|
</section>
|
|
|
|
<!-- 文件上传 -->
|
|
<section>
|
|
<h2>上传文件</h2>
|
|
<form id="uploadVideoForm">
|
|
<label>上传视频:</label>
|
|
<input type="file" name="file" id="video_file">
|
|
<input type="text" name="custom_name" placeholder="自定义文件名(可选)">
|
|
<button type="button" onclick="uploadFile('video')">上传视频</button>
|
|
</form>
|
|
|
|
<form id="uploadAudioForm">
|
|
<label>上传音频:</label>
|
|
<input type="file" name="file" id="audio_file">
|
|
<input type="text" name="custom_name" placeholder="自定义文件名(可选)">
|
|
<button type="button" onclick="uploadFile('audio')">上传音频</button>
|
|
</form>
|
|
</section>
|
|
|
|
<h2>日志输出</h2>
|
|
<div id="log">等待操作...</div>
|
|
|
|
<script>
|
|
const BASE_URL = "http://113.108.60.116:5001";
|
|
let pollInterval = null;
|
|
|
|
function log(msg) {
|
|
document.getElementById("log").innerText += "\n" + msg;
|
|
}
|
|
|
|
async function submitDigitalHuman() {
|
|
document.getElementById("log").innerText = "提交数字人任务...";
|
|
const speech_text = document.getElementById("speech_text").value;
|
|
const sample_video = document.getElementById("sample_video").value;
|
|
const sample_voice = document.getElementById("sample_voice").value;
|
|
|
|
try {
|
|
const resp = await fetch(`${BASE_URL}/api/digital_human/generate`, {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify({ speech_text, sample_video, sample_voice })
|
|
});
|
|
const data = await resp.json();
|
|
log("响应: " + JSON.stringify(data));
|
|
if (data.task_id) startPolling(data.task_id);
|
|
} catch (err) {
|
|
log("请求失败: " + err);
|
|
}
|
|
}
|
|
|
|
async function submitExtractAudio() {
|
|
document.getElementById("log").innerText = "提交提取音频任务...";
|
|
const video_path = document.getElementById("video_path").value;
|
|
|
|
try {
|
|
const resp = await fetch(`${BASE_URL}/api/video/extract_audio`, {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify({ video_path })
|
|
});
|
|
const data = await resp.json();
|
|
log("响应: " + JSON.stringify(data));
|
|
if (data.task_id) startPolling(data.task_id);
|
|
} catch (err) {
|
|
log("请求失败: " + err);
|
|
}
|
|
}
|
|
|
|
async function uploadFile(type) {
|
|
const form = new FormData();
|
|
const fileInput = document.getElementById(type + "_file");
|
|
if (!fileInput.files.length) {
|
|
log("请选择文件");
|
|
return;
|
|
}
|
|
form.append("file", fileInput.files[0]);
|
|
const customName = document.querySelector(`#upload${capitalize(type)}Form input[name="custom_name"]`).value;
|
|
if (customName) form.append("custom_name", customName);
|
|
|
|
try {
|
|
const resp = await fetch(`${BASE_URL}/api/upload/${type}`, {
|
|
method: "POST",
|
|
body: form
|
|
});
|
|
const data = await resp.json();
|
|
log("上传结果: " + JSON.stringify(data));
|
|
} catch (err) {
|
|
log("上传失败: " + err);
|
|
}
|
|
}
|
|
|
|
function startPolling(taskId) {
|
|
if (pollInterval) clearInterval(pollInterval);
|
|
pollInterval = setInterval(() => checkStatus(taskId), 2000);
|
|
}
|
|
|
|
async function checkStatus(taskId) {
|
|
try {
|
|
const resp = await fetch(`${BASE_URL}/api/task/status/${taskId}`);
|
|
const data = await resp.json();
|
|
log("任务状态: " + JSON.stringify(data));
|
|
if (data.status === "completed" || data.status === "failed") {
|
|
clearInterval(pollInterval);
|
|
if (data.result && data.result.download_url) {
|
|
const a = document.createElement("a");
|
|
a.href = BASE_URL + data.result.download_url;
|
|
a.textContent = "下载结果文件";
|
|
a.target = "_blank";
|
|
document.getElementById("log").appendChild(document.createElement("br"));
|
|
document.getElementById("log").appendChild(a);
|
|
}
|
|
}
|
|
} catch (err) {
|
|
log("查询失败: " + err);
|
|
clearInterval(pollInterval);
|
|
}
|
|
}
|
|
|
|
function capitalize(s) {
|
|
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
}
|
|
</script>
|
|
</body>
|
|
</html>
|