Files
dsProject/dsLightRag/static/Suno/music_progress.html

173 lines
9.5 KiB
HTML
Raw Normal View History

2025-08-21 14:24:35 +08:00
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>音乐生成进度</title>
<style>
* {
margin: 0; padding: 0; box-sizing: border-box;
font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif;
}
body { background-color: #f5f7fa; color: #333; line-height: 1.6; }
.container { max-width: 800px; margin: 50px auto; padding: 20px; background-color: white; border-radius: 10px; box-shadow: 0 2px 15px rgba(0,0,0,0.05); }
h1 { font-size: 2rem; margin-bottom: 30px; color: #3498db; text-align: center; }
.progress-container { margin: 40px 0; }
.progress-title { margin-bottom: 15px; font-weight: 500; font-size: 1.1rem; }
.progress-bar { height: 20px; background-color: #f1f1f1; border-radius: 10px; overflow: hidden; position: relative; }
.progress-fill { height: 100%; background: linear-gradient(90deg, #3498db, #8e44ad); border-radius: 10px; transition: width 0.3s; width: 0%; }
.progress-text { position: absolute; top: 0; right: 10px; line-height: 20px; color: white; font-weight: bold; }
.status-message { margin-top: 20px; padding: 15px; border-radius: 6px; background-color: #f8f9fa; border: 1px solid #eee; text-align: center; }
.player-container { margin-top: 40px; display: none; }
.audio-player { width: 100%; margin-top: 20px; }
.back-button { display: block; margin: 30px auto 0; padding: 12px 30px; background-color: #3498db; color: white; border: none; border-radius: 6px; cursor: pointer; font-size: 16px; transition: background 0.3s; text-align: center; text-decoration: none; max-width: 200px; }
.back-button:hover { background-color: #2980b9; }
2025-08-21 15:06:32 +08:00
/* 添加按钮容器样式 */
.button-container { display: flex; justify-content: center; gap: 15px; margin-top: 30px; }
2025-08-21 14:24:35 +08:00
</style>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
</head>
<body>
<div class="container">
<h1><i class="fas fa-music"></i> 音乐生成进度</h1>
<div class="progress-container">
<div class="progress-title">生成进度</div>
<div class="progress-bar">
<div class="progress-fill" id="progressFill"><span class="progress-text" id="progressText">0%</span></div>
</div>
</div>
<div class="status-message" id="statusMessage">
<i class="fas fa-spinner fa-spin"></i> 正在准备生成音乐...
</div>
<div class="player-container" id="playerContainer">
<h2 style="text-align: center; margin-bottom: 20px;">音乐已生成完成</h2>
<div id="musicTitle" style="text-align: center; font-size: 1.2rem; margin-bottom: 10px;"></div>
<audio id="audioPlayer" class="audio-player" controls>
<source id="audioSource" type="audio/mpeg">
您的浏览器不支持音频元素。
</audio>
</div>
2025-08-21 15:06:32 +08:00
<div class="button-container">
<a href="index.html" class="action-button back-button"><i class="fas fa-arrow-left"></i> 返回创作页</a>
</div>
2025-08-21 14:24:35 +08:00
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
// 获取URL中的任务ID
const urlParams = new URLSearchParams(window.location.search);
const taskId = urlParams.get('task_id');
if (!taskId) {
document.getElementById('statusMessage').innerHTML = '<i class="fas fa-exclamation-circle"></i> 无效的任务ID';
return;
}
2025-08-21 15:06:32 +08:00
// 轮询任务状态配置
const queryInterval = 3000; // 3秒查询一次
const maxQueries = 120; // 最多查询120次6分钟
let queryCount = 0; // 当前查询次数
const startTime = new Date().getTime(); // 开始时间
2025-08-21 14:24:35 +08:00
let progress = 0;
2025-08-21 15:06:32 +08:00
let timerId = null; // 用于存储setTimeout的ID
2025-08-21 14:24:35 +08:00
function checkTaskStatus() {
2025-08-21 15:06:32 +08:00
if (queryCount >= maxQueries) {
const elapsedTime = Math.round((new Date().getTime() - startTime) / 1000);
document.getElementById('statusMessage').innerHTML = `<i class="fas fa-exclamation-circle"></i> 音乐生成超时(已等待${elapsedTime}秒),您可以稍后在历史记录中查看,或重新生成。`;
document.getElementById('progressText').textContent = '生成超时';
return;
}
2025-08-21 14:24:35 +08:00
fetch(`/api/suno/check_task_status?task_id=${taskId}`)
.then(response => response.json())
.then(data => {
2025-08-21 15:06:32 +08:00
queryCount++;
2025-08-21 14:24:35 +08:00
// 更新状态信息
const statusMessage = document.getElementById('statusMessage');
const progressFill = document.getElementById('progressFill');
const progressText = document.getElementById('progressText');
2025-08-21 14:50:28 +08:00
// 正确获取数据部分
const responseData = data.data || data;
if (responseData.status === 'error') {
statusMessage.innerHTML = `<i class="fas fa-exclamation-circle"></i> 生成失败: ${responseData.error || responseData.error_message || '未知错误'}`;
2025-08-21 14:24:35 +08:00
statusMessage.style.backgroundColor = '#ffebee';
statusMessage.style.borderColor = '#ef9a9a';
return;
}
statusMessage.innerHTML = `<i class="fas fa-spinner fa-spin"></i> ${data.message || '正在生成音乐...'}`;
// 更新进度条
2025-08-21 14:50:28 +08:00
if (responseData.progress) {
progress = Math.min(responseData.progress, 100);
} else if (responseData.status === 'completed') {
2025-08-21 14:24:35 +08:00
progress = 100;
2025-08-21 15:06:32 +08:00
} else {
// 扩展:任何非完成/非错误状态都更新模拟进度
// 计算进度比例 (查询次数/最大查询次数)限制在98%以内
const progressRatio = Math.min(0.98, queryCount / maxQueries);
// 使用平滑增长函数而不是线性增长
progress = 100 * (1 - Math.exp(-3 * progressRatio));
2025-08-21 14:24:35 +08:00
}
2025-08-21 15:06:32 +08:00
// 计算已等待时间
const elapsedTime = Math.round((new Date().getTime() - startTime) / 1000);
2025-08-21 14:24:35 +08:00
progressFill.style.width = `${progress}%`;
2025-08-21 14:50:28 +08:00
progressText.textContent = `${Math.round(progress)}%`;
2025-08-21 15:06:32 +08:00
statusMessage.innerHTML += ` (已等待${elapsedTime}秒)`;
2025-08-21 14:24:35 +08:00
// 任务完成
2025-08-21 15:11:13 +08:00
if (responseData.status === 'completed' || responseData.status === 'complete') {
2025-08-21 14:24:35 +08:00
statusMessage.innerHTML = '<i class="fas fa-check-circle"></i> 音乐生成完成!';
statusMessage.style.backgroundColor = '#e8f5e9';
statusMessage.style.borderColor = '#a5d6a7';
2025-08-21 16:39:15 +08:00
// 确保进度为100%
progress = 100;
const progressFill = document.getElementById('progressFill');
const progressText = document.getElementById('progressText');
progressFill.style.width = `${progress}%`;
progressText.textContent = `${Math.round(progress)}%`;
2025-08-21 14:24:35 +08:00
// 显示播放器
const playerContainer = document.getElementById('playerContainer');
playerContainer.style.display = 'block';
// 设置音乐标题和源
2025-08-21 14:50:28 +08:00
document.getElementById('musicTitle').textContent = responseData.title || '生成的音乐';
2025-08-21 14:24:35 +08:00
const audioSource = document.getElementById('audioSource');
2025-08-21 14:50:28 +08:00
audioSource.src = responseData.audio_url || '';
2025-08-21 14:24:35 +08:00
document.getElementById('audioPlayer').load();
2025-08-21 15:06:32 +08:00
// 清除定时器,确保不会有更多请求
if (timerId) {
clearTimeout(timerId);
timerId = null;
}
} else {
// 继续查询
timerId = setTimeout(checkTaskStatus, queryInterval);
2025-08-21 14:24:35 +08:00
}
})
.catch(error => {
console.error('检查任务状态失败:', error);
2025-08-21 15:11:13 +08:00
// 只有在任务未完成且未超时时才继续查询
if (queryCount < maxQueries && !isTaskCompleted) {
timerId = setTimeout(checkTaskStatus, queryInterval);
}
2025-08-21 14:24:35 +08:00
});
}
// 立即检查一次
checkTaskStatus();
});
</script>
</body>
</html>