Files
dsProject/dsLightRag/static/Suno/music_progress.html
2025-08-21 15:11:13 +08:00

166 lines
9.1 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!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; }
/* 添加按钮容器样式 */
.button-container { display: flex; justify-content: center; gap: 15px; margin-top: 30px; }
</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>
<div class="button-container">
<a href="index.html" class="action-button back-button"><i class="fas fa-arrow-left"></i> 返回创作页</a>
</div>
</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;
}
// 轮询任务状态配置
const queryInterval = 3000; // 3秒查询一次
const maxQueries = 120; // 最多查询120次6分钟
let queryCount = 0; // 当前查询次数
const startTime = new Date().getTime(); // 开始时间
let progress = 0;
let timerId = null; // 用于存储setTimeout的ID
function checkTaskStatus() {
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;
}
fetch(`/api/suno/check_task_status?task_id=${taskId}`)
.then(response => response.json())
.then(data => {
queryCount++;
// 更新状态信息
const statusMessage = document.getElementById('statusMessage');
const progressFill = document.getElementById('progressFill');
const progressText = document.getElementById('progressText');
// 正确获取数据部分
const responseData = data.data || data;
if (responseData.status === 'error') {
statusMessage.innerHTML = `<i class="fas fa-exclamation-circle"></i> 生成失败: ${responseData.error || responseData.error_message || '未知错误'}`;
statusMessage.style.backgroundColor = '#ffebee';
statusMessage.style.borderColor = '#ef9a9a';
return;
}
statusMessage.innerHTML = `<i class="fas fa-spinner fa-spin"></i> ${data.message || '正在生成音乐...'}`;
// 更新进度条
if (responseData.progress) {
progress = Math.min(responseData.progress, 100);
} else if (responseData.status === 'completed') {
progress = 100;
} else {
// 扩展:任何非完成/非错误状态都更新模拟进度
// 计算进度比例 (查询次数/最大查询次数)限制在98%以内
const progressRatio = Math.min(0.98, queryCount / maxQueries);
// 使用平滑增长函数而不是线性增长
progress = 100 * (1 - Math.exp(-3 * progressRatio));
}
// 计算已等待时间
const elapsedTime = Math.round((new Date().getTime() - startTime) / 1000);
progressFill.style.width = `${progress}%`;
progressText.textContent = `${Math.round(progress)}%`;
statusMessage.innerHTML += ` (已等待${elapsedTime}秒)`;
// 任务完成
if (responseData.status === 'completed' || responseData.status === 'complete') {
statusMessage.innerHTML = '<i class="fas fa-check-circle"></i> 音乐生成完成!';
statusMessage.style.backgroundColor = '#e8f5e9';
statusMessage.style.borderColor = '#a5d6a7';
// 显示播放器
const playerContainer = document.getElementById('playerContainer');
playerContainer.style.display = 'block';
// 设置音乐标题和源
document.getElementById('musicTitle').textContent = responseData.title || '生成的音乐';
const audioSource = document.getElementById('audioSource');
audioSource.src = responseData.audio_url || '';
document.getElementById('audioPlayer').load();
// 清除定时器,确保不会有更多请求
if (timerId) {
clearTimeout(timerId);
timerId = null;
}
} else {
// 继续查询
timerId = setTimeout(checkTaskStatus, queryInterval);
}
})
.catch(error => {
console.error('检查任务状态失败:', error);
// 只有在任务未完成且未超时时才继续查询
if (queryCount < maxQueries && !isTaskCompleted) {
timerId = setTimeout(checkTaskStatus, queryInterval);
}
});
}
// 立即检查一次
checkTaskStatus();
});
</script>
</body>
</html>