Files
Meeting_Assistant/start.sh
egg 43c413c5ce feat: Upgrade Whisper model to medium and increase beam size
- Change default model from small to medium for better accuracy
- Increase beam_size from 5 to 8 for improved transcription quality
- Add Whisper environment variables to start.sh for centralized config

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-12 08:25:25 +08:00

406 lines
10 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
#
# Meeting Assistant - Startup Script
# 啟動前端、後端及 Sidecar 服務
#
set -e
# 顏色定義
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# 專案路徑
PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
BACKEND_DIR="$PROJECT_DIR/backend"
CLIENT_DIR="$PROJECT_DIR/client"
SIDECAR_DIR="$PROJECT_DIR/sidecar"
# Port 設定
BACKEND_PORT=8000
# Whisper 語音轉文字設定
export WHISPER_MODEL="medium" # 模型大小: tiny, base, small, medium, large
export WHISPER_DEVICE="cpu" # 執行裝置: cpu, cuda
export WHISPER_COMPUTE="int8" # 運算精度: int8, float16, float32
# PID 檔案
PID_FILE="$PROJECT_DIR/.running_pids"
# 函數:印出訊息
log_info() {
echo -e "${BLUE}[INFO]${NC} $1"
}
log_success() {
echo -e "${GREEN}[OK]${NC} $1"
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# 函數:檢查 port 是否被佔用
check_port() {
local port=$1
if lsof -i :$port > /dev/null 2>&1; then
return 0 # port 被佔用
else
return 1 # port 可用
fi
}
# 函數:釋放 port
release_port() {
local port=$1
if check_port $port; then
log_warn "Port $port 被佔用,嘗試釋放..."
local pid=$(lsof -t -i :$port 2>/dev/null)
if [ -n "$pid" ]; then
kill -9 $pid 2>/dev/null || true
sleep 1
log_success "Port $port 已釋放"
fi
fi
}
# 函數:檢查環境
check_environment() {
echo ""
echo "=========================================="
echo " Meeting Assistant 環境檢查"
echo "=========================================="
echo ""
local all_ok=true
# 檢查 Python
log_info "檢查 Python..."
if command -v python3 &> /dev/null; then
local py_version=$(python3 --version 2>&1)
log_success "Python: $py_version"
else
log_error "Python3 未安裝"
all_ok=false
fi
# 檢查 Node.js
log_info "檢查 Node.js..."
if command -v node &> /dev/null; then
local node_version=$(node --version)
log_success "Node.js: $node_version"
else
log_error "Node.js 未安裝"
all_ok=false
fi
# 檢查 npm
log_info "檢查 npm..."
if command -v npm &> /dev/null; then
local npm_version=$(npm --version)
log_success "npm: $npm_version"
else
log_error "npm 未安裝"
all_ok=false
fi
# 檢查後端虛擬環境
log_info "檢查後端虛擬環境..."
if [ -d "$BACKEND_DIR/venv" ]; then
log_success "後端虛擬環境: 存在"
else
log_error "後端虛擬環境不存在,請執行: cd backend && python3 -m venv venv"
all_ok=false
fi
# 檢查 Sidecar 虛擬環境
log_info "檢查 Sidecar 虛擬環境..."
if [ -d "$SIDECAR_DIR/venv" ]; then
log_success "Sidecar 虛擬環境: 存在"
else
log_warn "Sidecar 虛擬環境不存在(語音轉寫功能將無法使用)"
fi
# 檢查前端依賴
log_info "檢查前端依賴..."
if [ -d "$CLIENT_DIR/node_modules" ]; then
log_success "前端依賴: 已安裝"
else
log_error "前端依賴未安裝,請執行: cd client && npm install"
all_ok=false
fi
# 檢查後端 .env
log_info "檢查後端環境變數..."
if [ -f "$BACKEND_DIR/.env" ]; then
log_success "後端 .env: 存在"
else
log_warn "後端 .env 不存在,請複製 .env.example 並設定"
fi
# 檢查 Port 狀態
log_info "檢查 Port $BACKEND_PORT..."
if check_port $BACKEND_PORT; then
log_warn "Port $BACKEND_PORT 已被佔用"
else
log_success "Port $BACKEND_PORT: 可用"
fi
echo ""
if [ "$all_ok" = true ]; then
log_success "環境檢查通過!"
return 0
else
log_error "環境檢查失敗,請修正上述問題"
return 1
fi
}
# 函數:啟動後端
start_backend() {
log_info "啟動後端服務..."
# 釋放 port
release_port $BACKEND_PORT
cd "$BACKEND_DIR"
source venv/bin/activate
# 背景啟動 uvicorn
nohup uvicorn app.main:app --host 0.0.0.0 --port $BACKEND_PORT --reload > "$PROJECT_DIR/backend.log" 2>&1 &
local backend_pid=$!
echo "BACKEND_PID=$backend_pid" >> "$PID_FILE"
# 等待啟動(最多等待 15 秒)
local max_wait=15
local waited=0
log_info "等待後端服務啟動..."
while [ $waited -lt $max_wait ]; do
sleep 1
waited=$((waited + 1))
# 檢查健康狀態
if curl -s http://localhost:$BACKEND_PORT/api/health > /dev/null 2>&1; then
log_success "後端服務已啟動 (PID: $backend_pid, Port: $BACKEND_PORT)"
return 0
fi
done
# 最後再檢查一次 port 狀態
if check_port $BACKEND_PORT; then
log_success "後端服務已啟動 (PID: $backend_pid, Port: $BACKEND_PORT)"
else
log_error "後端服務啟動失敗,請檢查 backend.log"
return 1
fi
}
# 函數:啟動前端
start_frontend() {
log_info "啟動前端應用..."
cd "$CLIENT_DIR"
# 背景啟動 Electron它會自動管理 Sidecar
nohup npm start > "$PROJECT_DIR/frontend.log" 2>&1 &
local frontend_pid=$!
echo "FRONTEND_PID=$frontend_pid" >> "$PID_FILE"
sleep 2
log_success "前端應用已啟動 (PID: $frontend_pid)"
log_info "Sidecar 語音識別引擎將由 Electron 自動管理"
}
# 函數:停止所有服務
stop_all() {
echo ""
log_info "停止所有服務..."
# 讀取 PID 檔案並終止程序
if [ -f "$PID_FILE" ]; then
while IFS='=' read -r key pid; do
if [ -n "$pid" ] && kill -0 "$pid" 2>/dev/null; then
log_info "停止 $key (PID: $pid)..."
kill -TERM "$pid" 2>/dev/null || true
fi
done < "$PID_FILE"
rm -f "$PID_FILE"
fi
# 釋放 port
release_port $BACKEND_PORT
# 清理可能殘留的程序
pkill -f "uvicorn app.main:app" 2>/dev/null || true
pkill -f "electron ." 2>/dev/null || true
pkill -f "transcriber.py" 2>/dev/null || true
sleep 1
log_success "所有服務已停止"
}
# 函數:顯示狀態
show_status() {
echo ""
echo "=========================================="
echo " Meeting Assistant 服務狀態"
echo "=========================================="
echo ""
# 檢查後端
if check_port $BACKEND_PORT; then
local backend_pid=$(lsof -t -i :$BACKEND_PORT 2>/dev/null | head -1)
log_success "後端服務: 運行中 (PID: $backend_pid, Port: $BACKEND_PORT)"
else
log_warn "後端服務: 未運行"
fi
# 檢查 Electron
local electron_pid=$(pgrep -f "electron ." 2>/dev/null | head -1)
if [ -n "$electron_pid" ]; then
log_success "前端應用: 運行中 (PID: $electron_pid)"
else
log_warn "前端應用: 未運行"
fi
# 檢查 Sidecar
local sidecar_pid=$(pgrep -f "transcriber.py" 2>/dev/null | head -1)
if [ -n "$sidecar_pid" ]; then
log_success "Sidecar: 運行中 (PID: $sidecar_pid)"
else
log_warn "Sidecar: 未運行(將在前端需要時自動啟動)"
fi
echo ""
}
# 函數:顯示幫助
show_help() {
echo ""
echo "Meeting Assistant 啟動腳本"
echo ""
echo "用法: $0 [命令]"
echo ""
echo "命令:"
echo " start 啟動所有服務(後端 + 前端)"
echo " stop 停止所有服務並釋放 port"
echo " restart 重啟所有服務"
echo " status 顯示服務狀態"
echo " check 檢查環境設定"
echo " backend 僅啟動後端服務"
echo " frontend 僅啟動前端應用"
echo " logs 顯示日誌"
echo " help 顯示此幫助訊息"
echo ""
echo "範例:"
echo " $0 start # 啟動所有服務"
echo " $0 stop # 停止所有服務"
echo " $0 status # 查看狀態"
echo ""
}
# 函數:顯示日誌
show_logs() {
echo ""
echo "=========================================="
echo " Meeting Assistant 日誌"
echo "=========================================="
if [ -f "$PROJECT_DIR/backend.log" ]; then
echo ""
echo "--- 後端日誌 (最後 20 行) ---"
tail -20 "$PROJECT_DIR/backend.log"
fi
if [ -f "$PROJECT_DIR/frontend.log" ]; then
echo ""
echo "--- 前端日誌 (最後 20 行) ---"
tail -20 "$PROJECT_DIR/frontend.log"
fi
}
# 主程式
main() {
local command=${1:-help}
case $command in
start)
echo ""
echo "=========================================="
echo " Meeting Assistant 啟動中..."
echo "=========================================="
# 清理舊的 PID 檔案
rm -f "$PID_FILE"
if ! check_environment; then
exit 1
fi
echo ""
start_backend
start_frontend
echo ""
echo "=========================================="
log_success "Meeting Assistant 已啟動!"
echo "=========================================="
echo ""
echo " 後端 API: http://localhost:$BACKEND_PORT"
echo " API 文件: http://localhost:$BACKEND_PORT/docs"
echo ""
echo " 停止服務: $0 stop"
echo " 查看狀態: $0 status"
echo " 查看日誌: $0 logs"
echo ""
;;
stop)
stop_all
;;
restart)
stop_all
sleep 2
$0 start
;;
status)
show_status
;;
check)
check_environment
;;
backend)
release_port $BACKEND_PORT
rm -f "$PID_FILE"
start_backend
;;
frontend)
start_frontend
;;
logs)
show_logs
;;
help|--help|-h)
show_help
;;
*)
log_error "未知命令: $command"
show_help
exit 1
;;
esac
}
# 捕捉中斷信號
trap 'echo ""; log_info "收到中斷信號,停止服務..."; stop_all; exit 0' INT TERM
# 執行主程式
main "$@"