# -*- coding:utf-8 -*- """songrate standalone service - 音乐评估 GPU 服务 (端口 8900)""" import json import os import sys import tempfile import asyncio from ahserver.webapp import webapp from ahserver.serverenv import ServerEnv from appPublic.registerfunction import RegisterFunction from appPublic.log import debug # Add songrate package to path sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)))) from songrate.evaluator import evaluate_song async def do_evaluate(request, *args, **kw): """POST /api/evaluate - 评估歌曲""" env = request._run_ns pkw = env.params_kw scene = getattr(pkw, 'scene', 'pop') or 'pop' filepath = getattr(pkw, 'filepath', '') or '' audio_path = getattr(pkw, 'audio_path', '') or '' if not filepath: filepath = audio_path if not filepath: return json.dumps({"error": "missing filepath or audio_path"}, ensure_ascii=False) # If it's a relative/web path, resolve to local if not os.path.isabs(filepath): from ahserver.filestorage import FileStorage fs = FileStorage() filepath = fs.realPath(filepath) if not os.path.exists(filepath): return json.dumps({"error": f"file not found: {filepath}"}, ensure_ascii=False) # Run evaluation in thread pool (GPU bound) from concurrent.futures import ThreadPoolExecutor loop = asyncio.get_event_loop() with ThreadPoolExecutor(max_workers=1) as pool: result = await loop.run_in_executor(pool, evaluate_song, filepath, scene) return json.dumps(result, ensure_ascii=False) def init(): rf = RegisterFunction() rf.register('evaluate', do_evaluate) debug('songrate service initialized') if __name__ == '__main__': webapp(init)