feat: 添加 Tauri Mac 原生应用支持
- 新增 mac-app/ 目录:Tauri 项目结构(Rust 外壳 + sidecar 进程管理)
- 前端添加 Tauri 环境检测,API 调用和 WebSocket 自动适配
- 后端支持 MEETING_DATA_DIR 环境变量指定数据目录
- 新增 /api/meetings/{id}/retranscribe 接口用于重新转录
- 修复轮询超时:2分钟→30分钟,适配长音频
- 添加 .gitignore 排除构建产物
This commit is contained in:
@@ -24,6 +24,18 @@ from database import init_db, Database
|
||||
from processor import MeetingProcessor, get_device, RealtimeTranscriber
|
||||
|
||||
|
||||
# 数据目录:优先使用环境变量(Tauri 打包后由 sidecar 设置),否则使用项目根目录
|
||||
def get_data_dir():
|
||||
env_dir = os.environ.get("MEETING_DATA_DIR")
|
||||
if env_dir:
|
||||
data_dir = os.path.join(env_dir, "data")
|
||||
else:
|
||||
project_root = os.path.dirname(os.path.abspath(__file__))
|
||||
data_dir = os.path.join(project_root, "data")
|
||||
os.makedirs(data_dir, exist_ok=True)
|
||||
return data_dir
|
||||
|
||||
|
||||
# 全局变量
|
||||
db: Database = None
|
||||
processor: MeetingProcessor = None
|
||||
@@ -146,8 +158,7 @@ async def upload_meeting(
|
||||
raise HTTPException(status_code=400, detail="不支持的文件类型")
|
||||
|
||||
# 保存文件
|
||||
project_root = os.path.dirname(os.path.abspath(__file__))
|
||||
data_dir = os.path.join(project_root, "data", "audio")
|
||||
data_dir = os.path.join(get_data_dir(), "audio")
|
||||
os.makedirs(data_dir, exist_ok=True)
|
||||
|
||||
ext = os.path.splitext(file.filename)[1] or ".mp3"
|
||||
@@ -177,6 +188,27 @@ async def upload_meeting(
|
||||
return meeting
|
||||
|
||||
|
||||
@app.post("/api/meetings/{meeting_id}/retranscribe")
|
||||
async def retranscribe_meeting(meeting_id: str):
|
||||
"""重新转录会议(用于卡在 processing 的会议)"""
|
||||
meeting = db.get_meeting(meeting_id)
|
||||
if not meeting:
|
||||
raise HTTPException(status_code=404, detail="会议不存在")
|
||||
|
||||
audio_path = meeting.get('audio_path')
|
||||
if not audio_path or not os.path.exists(audio_path):
|
||||
raise HTTPException(status_code=400, detail="音频文件不存在")
|
||||
|
||||
# 重置状态
|
||||
db.update_meeting(meeting_id=meeting_id, status="processing", segments=None)
|
||||
|
||||
# 重新入队
|
||||
task_queue.put((meeting_id, audio_path, meeting['title']))
|
||||
print(f"📋 重新转录任务已加入队列: {meeting['title']} (ID: {meeting_id})")
|
||||
|
||||
return {"message": "已重新加入转录队列", "meeting_id": meeting_id}
|
||||
|
||||
|
||||
@app.delete("/api/meetings/{meeting_id}")
|
||||
async def delete_meeting(meeting_id: str):
|
||||
"""删除会议"""
|
||||
@@ -440,8 +472,7 @@ async def realtime_transcribe(websocket: WebSocket, session_id: str):
|
||||
# 录音结束,保存会议
|
||||
if transcriber and audio_chunks:
|
||||
# 保存录音文件
|
||||
project_root = os.path.dirname(os.path.abspath(__file__))
|
||||
data_dir = os.path.join(project_root, "data", "audio")
|
||||
data_dir = os.path.join(get_data_dir(), "audio")
|
||||
os.makedirs(data_dir, exist_ok=True)
|
||||
|
||||
audio_filename = f"{datetime.now().strftime('%Y%m%d_%H%M%')}{session_id}.wav"
|
||||
|
||||
Reference in New Issue
Block a user