# -*- coding: utf-8 -*- """ subtitle-studio 后台启动器(无阻塞) 用 subprocess.Popen 启动 uvicorn,shell 调用立即返回 日志写到 logs/server.log 用法: python start_server.py [port] """ import sys, os, subprocess, time, threading PYTHON = sys.executable PROJECT_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) APP_DIR = os.path.join(PROJECT_ROOT, "src") LOG_DIR = os.path.join(PROJECT_ROOT, "logs") PORT = sys.argv[1] if len(sys.argv) > 1 else "8788" os.makedirs(LOG_DIR, exist_ok=True) log_path = os.path.join(LOG_DIR, "server.log") def is_running(port): """端口是否已被监听""" try: import socket with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.settimeout(1) return s.connect_ex(("127.0.0.1", int(port))) == 0 except Exception: return False def main(): if is_running(PORT): print(f"subtitle-studio 已在运行: http://127.0.0.1:{PORT}") return # 打开日志文件(追加模式) logf = open(log_path, 'a', encoding='utf-8', buffering=1) # 真正的异步启动:不等待,不继承句柄 proc = subprocess.Popen( [PYTHON, "-m", "uvicorn", "substudio.main:app", "--host", "127.0.0.1", "--port", PORT, "--app-dir", APP_DIR], cwd=PROJECT_ROOT, stdout=logf, stderr=subprocess.STDOUT, creationflags=subprocess.CREATE_NO_WINDOW, ) print(f"已启动 subtitle-studio (PID {proc.pid})") print(f"服务地址: http://127.0.0.1:{PORT}") print(f"日志: {log_path}") # 不等待进程,直接返回 if __name__ == "__main__": main()