'commit'
This commit is contained in:
@@ -204,50 +204,52 @@ async def check_task_status(task_id: str = Query(..., description="音乐生成
|
|||||||
logger.info("音乐生成已完成!")
|
logger.info("音乐生成已完成!")
|
||||||
logger.info(f"音频URL: {audio_url}")
|
logger.info(f"音频URL: {audio_url}")
|
||||||
|
|
||||||
# 新增:下载音频文件并上传到OBS
|
# 新增:检查是否已经上传到OBS
|
||||||
try:
|
if "obs_url" not in task_info or not task_info["obs_url"]:
|
||||||
# 使用UUID生成唯一文件名
|
# 新增:下载音频文件并上传到OBS
|
||||||
unique_id = uuid.uuid4()
|
try:
|
||||||
object_key = f"HuangHai/JiMeng/{unique_id}.mp3"
|
# 使用UUID生成唯一文件名
|
||||||
|
unique_id = uuid.uuid4()
|
||||||
|
object_key = f"HuangHai/JiMeng/{unique_id}.mp3"
|
||||||
|
|
||||||
# 临时文件保存路径
|
# 临时文件保存路径
|
||||||
temp_file_path = os.path.join(os.path.dirname(__file__), f"{unique_id}.mp3")
|
temp_file_path = os.path.join(os.path.dirname(__file__), f"{unique_id}.mp3")
|
||||||
|
|
||||||
# 下载URL内容到临时文件
|
# 下载URL内容到临时文件
|
||||||
logger.info(f"开始下载URL内容: {audio_url}")
|
logger.info(f"开始下载URL内容: {audio_url}")
|
||||||
with requests.get(audio_url, stream=True, timeout=3600) as r:
|
with requests.get(audio_url, stream=True, timeout=3600) as r:
|
||||||
r.raise_for_status()
|
r.raise_for_status()
|
||||||
with open(temp_file_path, 'wb') as f:
|
with open(temp_file_path, 'wb') as f:
|
||||||
for chunk in r.iter_content(chunk_size=8192):
|
for chunk in r.iter_content(chunk_size=8192):
|
||||||
f.write(chunk)
|
f.write(chunk)
|
||||||
logger.info(f"URL内容下载完成,保存至: {temp_file_path}")
|
logger.info(f"URL内容下载完成,保存至: {temp_file_path}")
|
||||||
|
|
||||||
# 上传文件到OBS
|
# 上传文件到OBS
|
||||||
from Util.ObsUtil import ObsUploader # 导入ObsUploader
|
from Util.ObsUtil import ObsUploader # 导入ObsUploader
|
||||||
obs_uploader = ObsUploader()
|
obs_uploader = ObsUploader()
|
||||||
logger.info(f"开始上传文件到OBS: {temp_file_path}\n对象键: {object_key}")
|
logger.info(f"开始上传文件到OBS: {temp_file_path}\n对象键: {object_key}")
|
||||||
|
|
||||||
# 正确处理元组返回值
|
# 正确处理元组返回值
|
||||||
success, response_info = obs_uploader.upload_file(
|
success, response_info = obs_uploader.upload_file(
|
||||||
file_path=temp_file_path,
|
file_path=temp_file_path,
|
||||||
object_key=object_key
|
object_key=object_key
|
||||||
)
|
)
|
||||||
|
|
||||||
if success:
|
if success:
|
||||||
# 构造OBS URL
|
# 构造OBS URL
|
||||||
from Config.Config import OBS_SERVER, OBS_BUCKET
|
from Config.Config import OBS_SERVER, OBS_BUCKET
|
||||||
obs_url = f"https://{OBS_BUCKET}.{OBS_SERVER}/{object_key}"
|
obs_url = f"https://{OBS_BUCKET}.{OBS_SERVER}/{object_key}"
|
||||||
logger.info(f"文件上传成功,OBS URL: {obs_url}")
|
logger.info(f"文件上传成功,OBS URL: {obs_url}")
|
||||||
task_info["obs_url"] = obs_url
|
task_info["obs_url"] = obs_url
|
||||||
task_info["object_key"] = object_key
|
task_info["object_key"] = object_key
|
||||||
else:
|
else:
|
||||||
error_msg = f"上传失败: {str(response_info)}"
|
error_msg = f"上传失败: {str(response_info)}"
|
||||||
logger.error(error_msg)
|
logger.error(error_msg)
|
||||||
finally:
|
finally:
|
||||||
# 清理临时文件
|
# 清理临时文件
|
||||||
if os.path.exists(temp_file_path):
|
if os.path.exists(temp_file_path):
|
||||||
os.remove(temp_file_path)
|
os.remove(temp_file_path)
|
||||||
logger.info(f"临时文件已删除: {temp_file_path}")
|
logger.info(f"临时文件已删除: {temp_file_path}")
|
||||||
# 新增结束
|
# 新增结束
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
Binary file not shown.
@@ -22,6 +22,8 @@
|
|||||||
.audio-player { width: 100%; margin-top: 20px; }
|
.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 { 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; }
|
.back-button:hover { background-color: #2980b9; }
|
||||||
|
/* 添加按钮容器样式 */
|
||||||
|
.button-container { display: flex; justify-content: center; gap: 15px; margin-top: 30px; }
|
||||||
</style>
|
</style>
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||||||
</head>
|
</head>
|
||||||
@@ -49,7 +51,9 @@
|
|||||||
</audio>
|
</audio>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a href="index.html" class="back-button"><i class="fas fa-arrow-left"></i> 返回创作页</a>
|
<div class="button-container">
|
||||||
|
<a href="index.html" class="action-button back-button"><i class="fas fa-arrow-left"></i> 返回创作页</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@@ -63,14 +67,26 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 轮询任务状态
|
// 轮询任务状态配置
|
||||||
let progressInterval;
|
const queryInterval = 3000; // 3秒查询一次
|
||||||
|
const maxQueries = 120; // 最多查询120次(6分钟)
|
||||||
|
let queryCount = 0; // 当前查询次数
|
||||||
|
const startTime = new Date().getTime(); // 开始时间
|
||||||
let progress = 0;
|
let progress = 0;
|
||||||
|
let timerId = null; // 用于存储setTimeout的ID
|
||||||
|
|
||||||
function checkTaskStatus() {
|
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}`)
|
fetch(`/api/suno/check_task_status?task_id=${taskId}`)
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
|
queryCount++;
|
||||||
// 更新状态信息
|
// 更新状态信息
|
||||||
const statusMessage = document.getElementById('statusMessage');
|
const statusMessage = document.getElementById('statusMessage');
|
||||||
const progressFill = document.getElementById('progressFill');
|
const progressFill = document.getElementById('progressFill');
|
||||||
@@ -80,7 +96,6 @@
|
|||||||
const responseData = data.data || data;
|
const responseData = data.data || data;
|
||||||
|
|
||||||
if (responseData.status === 'error') {
|
if (responseData.status === 'error') {
|
||||||
clearInterval(progressInterval);
|
|
||||||
statusMessage.innerHTML = `<i class="fas fa-exclamation-circle"></i> 生成失败: ${responseData.error || responseData.error_message || '未知错误'}`;
|
statusMessage.innerHTML = `<i class="fas fa-exclamation-circle"></i> 生成失败: ${responseData.error || responseData.error_message || '未知错误'}`;
|
||||||
statusMessage.style.backgroundColor = '#ffebee';
|
statusMessage.style.backgroundColor = '#ffebee';
|
||||||
statusMessage.style.borderColor = '#ef9a9a';
|
statusMessage.style.borderColor = '#ef9a9a';
|
||||||
@@ -94,21 +109,22 @@
|
|||||||
progress = Math.min(responseData.progress, 100);
|
progress = Math.min(responseData.progress, 100);
|
||||||
} else if (responseData.status === 'completed') {
|
} else if (responseData.status === 'completed') {
|
||||||
progress = 100;
|
progress = 100;
|
||||||
} else if (responseData.status === 'processing') {
|
} else {
|
||||||
// 改进模拟进度增加逻辑
|
// 扩展:任何非完成/非错误状态都更新模拟进度
|
||||||
if (progress < 95) {
|
// 计算进度比例 (查询次数/最大查询次数),限制在98%以内
|
||||||
progress += 0.5;
|
const progressRatio = Math.min(0.98, queryCount / maxQueries);
|
||||||
} else if (progress < 100) {
|
// 使用平滑增长函数而不是线性增长
|
||||||
progress += 0.1;
|
progress = 100 * (1 - Math.exp(-3 * progressRatio));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 计算已等待时间
|
||||||
|
const elapsedTime = Math.round((new Date().getTime() - startTime) / 1000);
|
||||||
progressFill.style.width = `${progress}%`;
|
progressFill.style.width = `${progress}%`;
|
||||||
progressText.textContent = `${Math.round(progress)}%`;
|
progressText.textContent = `${Math.round(progress)}%`;
|
||||||
|
statusMessage.innerHTML += ` (已等待${elapsedTime}秒)`;
|
||||||
|
|
||||||
// 任务完成
|
// 任务完成
|
||||||
if (responseData.status === 'completed') {
|
if (responseData.status === 'completed') {
|
||||||
clearInterval(progressInterval);
|
|
||||||
statusMessage.innerHTML = '<i class="fas fa-check-circle"></i> 音乐生成完成!';
|
statusMessage.innerHTML = '<i class="fas fa-check-circle"></i> 音乐生成完成!';
|
||||||
statusMessage.style.backgroundColor = '#e8f5e9';
|
statusMessage.style.backgroundColor = '#e8f5e9';
|
||||||
statusMessage.style.borderColor = '#a5d6a7';
|
statusMessage.style.borderColor = '#a5d6a7';
|
||||||
@@ -122,18 +138,26 @@
|
|||||||
const audioSource = document.getElementById('audioSource');
|
const audioSource = document.getElementById('audioSource');
|
||||||
audioSource.src = responseData.audio_url || '';
|
audioSource.src = responseData.audio_url || '';
|
||||||
document.getElementById('audioPlayer').load();
|
document.getElementById('audioPlayer').load();
|
||||||
|
|
||||||
|
// 清除定时器,确保不会有更多请求
|
||||||
|
if (timerId) {
|
||||||
|
clearTimeout(timerId);
|
||||||
|
timerId = null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 继续查询
|
||||||
|
timerId = setTimeout(checkTaskStatus, queryInterval);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
console.error('检查任务状态失败:', error);
|
console.error('检查任务状态失败:', error);
|
||||||
|
// 出现错误时也继续查询
|
||||||
|
timerId = setTimeout(checkTaskStatus, queryInterval);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 立即检查一次
|
// 立即检查一次
|
||||||
checkTaskStatus();
|
checkTaskStatus();
|
||||||
|
|
||||||
// 然后每3秒检查一次
|
|
||||||
progressInterval = setInterval(checkTaskStatus, 3000);
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
Reference in New Issue
Block a user