音频问题

This commit is contained in:
Lilixu007 2026-03-06 18:59:17 +08:00
parent 16c66112ef
commit b2ca26e64c
6 changed files with 184 additions and 12 deletions

12
add_generation_quota.sql Normal file
View File

@ -0,0 +1,12 @@
-- 为用户 ID=91, username=18888888888 增加 1000 次生成次数
-- 执行时间: 2026-03-06
-- 更新用户的视频生成次数,增加 1000 次
UPDATE nf_user
SET video_gen_remaining = video_gen_remaining + 1000
WHERE id = 91 AND username = '18888888888';
-- 验证更新结果
SELECT id, username, nickname, video_gen_remaining, video_gen_reset_date
FROM nf_user
WHERE id = 91;

42
check_song_library.sql Normal file
View File

@ -0,0 +1,42 @@
-- 检查歌曲库中的音频文件 URL
-- 查找可能有问题的歌曲记录
-- 1. 查看所有歌曲的音频 URL
SELECT
id,
title,
audio_url,
status,
gender,
duration_sec,
createtime
FROM nf_song_library
WHERE deletetime IS NULL
ORDER BY id DESC
LIMIT 20;
-- 2. 查找最近失败的任务相关的歌曲
SELECT
gt.id as task_id,
gt.status as task_status,
gt.payload,
gt.error_message,
sl.id as song_id,
sl.title as song_title,
sl.audio_url,
gt.created_at
FROM nf_generation_task gt
LEFT JOIN nf_song_library sl ON JSON_EXTRACT(gt.payload, '$.song_id') = sl.id
WHERE gt.task_type = 'sing'
AND gt.status = 'failed'
ORDER BY gt.created_at DESC
LIMIT 10;
-- 3. 统计有问题的 URL 模式
SELECT
SUBSTRING_INDEX(audio_url, '/', 5) as url_prefix,
COUNT(*) as count
FROM nf_song_library
WHERE deletetime IS NULL
AND status = 1
GROUP BY url_prefix;

46
fix_song_audio_urls.sql Normal file
View File

@ -0,0 +1,46 @@
-- 修复歌曲库中不存在的音频文件
-- 方案:临时禁用这些有问题的歌曲,或者更新为可用的音频 URL
-- 1. 查看当前有问题的歌曲audio_url 包含 20260126 或 20260117
SELECT
id,
title,
artist,
audio_url,
status,
gender
FROM nf_song_library
WHERE deletetime IS NULL
AND (audio_url LIKE '%/20260126/%' OR audio_url LIKE '%/20260117/%')
ORDER BY id;
-- 2. 临时禁用这些歌曲(推荐方案)
-- 取消下面的注释来执行
/*
UPDATE nf_song_library
SET status = 0
WHERE deletetime IS NULL
AND (audio_url LIKE '%/20260126/%' OR audio_url LIKE '%/20260117/%');
*/
-- 3. 或者使用外部 URL如果有的话
-- 例如:使用 www.bensound.com 的测试音频
/*
UPDATE nf_song_library
SET audio_url = 'https://www.bensound.com/bensound-music/bensound-dreams.mp3'
WHERE id = 11 AND title = 'Dreams';
*/
-- 4. 查看可用的歌曲(使用外部 URL 的)
SELECT
id,
title,
artist,
audio_url,
status,
gender
FROM nf_song_library
WHERE deletetime IS NULL
AND status = 1
AND (audio_url LIKE 'http%' AND audio_url NOT LIKE '%/uploads/%')
ORDER BY id;

View File

@ -1,5 +1,12 @@
DATABASE_URL=mysql+pymysql://root:rootx77@localhost:3306/fastadmin?charset=utf8mb4
USER_INFO_API=http://127.0.0.1:30100/api/user_basic/get_user_basic
DATABASE_URL=mysql+pymysql://fastadmin:root@1.15.149.240:3306/fastadmin?charset=utf8mb4
USER_INFO_API=http://1.15.149.240:30100/api/user_basic/get_user_basic
# 语音通话超时设置(秒)- 增加到120秒以适应ASR+LLM+TTS处理时间
VOICE_CALL_IDLE_TIMEOUT=120
VOICE_CALL_IDLE_TIMEOUT=120
# OSS 配置 - 用于文件存储和访问
ALIYUN_OSS_ACCESS_KEY_ID=LTAI5tBzjogJDx4JzRYoDyEM
ALIYUN_OSS_ACCESS_KEY_SECRET=43euicRkkzlLjGTYzFYkTupcW7N5w3
ALIYUN_OSS_BUCKET_NAME=hello12312312
ALIYUN_OSS_ENDPOINT=https://oss-cn-hangzhou.aliyuncs.com
ALIYUN_OSS_CDN_DOMAIN=https://hello12312312.oss-cn-hangzhou.aliyuncs.com

View File

@ -174,13 +174,35 @@ def _semaphore_guard(semaphore: threading.BoundedSemaphore):
def _cdnize(url: Optional[str]) -> Optional[str]:
"""
将相对路径补全为可访问 URL优先使用 CDN其次 bucket+endpoint最后兜底固定域名
将相对路径补全为可访问 URL
策略
1. 如果已经是完整 URL直接返回
2. 如果是相对路径先检查本地文件是否存在
3. 如果本地文件存在返回本地路径 /uploads/ 开头
4. 如果本地文件不存在转换为 OSS URL
"""
import os
if not url:
return url
cleaned = url.strip()
# 如果已经是完整 URL直接返回
if cleaned.startswith("http://") or cleaned.startswith("https://"):
return cleaned
# 检查本地文件是否存在
local_base_path = "/www/wwwroot/1.15.149.240_30100/public"
local_file_path = os.path.join(local_base_path, cleaned.lstrip("/"))
if os.path.exists(local_file_path):
# 本地文件存在,返回本地路径标识
logger.info(f"找到本地文件: {local_file_path},使用本地路径")
return cleaned if cleaned.startswith("/") else f"/{cleaned}"
# 本地文件不存在,转换为 OSS URL
logger.info(f"本地文件不存在: {local_file_path},尝试使用 OSS URL")
# 去掉首个斜杠,防止双斜杠
cleaned = cleaned.lstrip("/")
if settings.ALIYUN_OSS_CDN_DOMAIN:
@ -270,6 +292,31 @@ def _resolve_sing_prompts(model: str) -> tuple[str, str]:
def _download_to_path(url: str, target_path: str):
import os
import shutil
# 检查是否是本地文件路径(以 /uploads/ 开头)
if url.startswith("/uploads/") or url.startswith("uploads/"):
# 本地文件路径,直接复制
# 假设本地文件存储在 /www/wwwroot/1.15.149.240_30100/public/ 目录下
local_base_path = "/www/wwwroot/1.15.149.240_30100/public"
source_path = os.path.join(local_base_path, url.lstrip("/"))
logger.info(f"检测到本地文件路径,从 {source_path} 复制到 {target_path}")
if not os.path.exists(source_path):
logger.error(f"本地文件不存在: {source_path}")
raise HTTPException(status_code=404, detail=f"本地文件不存在: {url}")
try:
shutil.copy2(source_path, target_path)
logger.info(f"本地文件复制成功: {source_path} -> {target_path}")
return
except Exception as exc:
logger.error(f"本地文件复制失败: {exc}")
raise HTTPException(status_code=500, detail="本地文件复制失败") from exc
# HTTP/HTTPS URL通过网络下载
try:
logger.info(f"开始下载文件: {url}")
resp = requests.get(url, stream=True, timeout=30)
@ -372,8 +419,13 @@ def _ensure_emo_detect_cache(
def _probe_media_duration(path: str) -> Optional[float]:
ffprobe_path = _ffprobe_bin()
if not ffprobe_path:
logger.error("ffprobe 命令未找到,无法获取音频时长")
return None
command = [
_ffprobe_bin(),
ffprobe_path,
"-v",
"error",
"-show_entries",
@ -382,21 +434,34 @@ def _probe_media_duration(path: str) -> Optional[float]:
"default=noprint_wrappers=1:nokey=1",
path,
]
logger.info(f"执行 ffprobe 命令: {' '.join(command)}")
try:
result = subprocess.run(command, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
except FileNotFoundError:
except FileNotFoundError as e:
logger.error(f"ffprobe 命令未找到: {e}")
return None
except subprocess.CalledProcessError:
except subprocess.CalledProcessError as e:
logger.error(f"ffprobe 执行失败: {e}, stderr: {e.stderr.decode('utf-8', errors='ignore')}")
return None
raw = result.stdout.decode("utf-8", errors="ignore").strip()
logger.info(f"ffprobe 输出: {raw}")
if not raw:
logger.error("ffprobe 返回空结果")
return None
try:
duration = float(raw)
except ValueError:
except ValueError as e:
logger.error(f"无法解析时长值: {raw}, 错误: {e}")
return None
if duration <= 0:
logger.error(f"时长值无效: {duration}")
return None
logger.info(f"音频时长: {duration}")
return duration

View File

@ -1,8 +1,8 @@
// Windows 本地开发 - 混合架构
export const baseURL = 'http://192.168.1.141:30100' // PHP 处理用户管理和界面
// export const baseURL = 'http://1.15.149.240:30100' // PHP 处理用户管理和界面
export const baseURLPy = 'http://192.168.1.141:30101' // FastAPI 处理 AI 功能
// export const baseURLPy = 'http://1.15.149.240:30101' // FastAPI 处理 AI 功能
// export const baseURL = 'http://192.168.1.141:30100' // PHP 处理用户管理和界面
export const baseURL = 'http://1.15.149.240:30100' // PHP 处理用户管理和界面
// export const baseURLPy = 'http://192.168.1.141:30101' // FastAPI 处理 AI 功能
export const baseURLPy = 'http://1.15.149.240:30101' // FastAPI 处理 AI 功能
// 远程服务器 - 需要时取消注释
// export const baseURL = 'http://1.15.149.240:30100'