from flask import Flask, jsonify, request
import subprocess
import threading
import time
import os
from datetime import datetime
import schedule

app = Flask(__name__)

# 配置参数
RTSP_URL = "rtsp://10.68.66.174/audio"
RECORD_DURATION_MINUTES = 60  # 录制时长（分钟）
REST_DURATION_MINUTES = 20    # 休息时长（分钟）
START_HOUR = 8               # 开始时间（小时）
END_HOUR = 20                # 结束时间（小时）
OUTPUT_DIR = "./"            # 输出目录

# 录制状态
recording_state = {
    "is_recording": False,
    "current_file": None,
    "start_time": None,
    "total_recorded": 0,
    "schedule_next": None
}

def get_output_path():
    """生成带时间戳的文件名"""
    timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
    return os.path.join(OUTPUT_DIR, f"rtsp_{timestamp}.wav")

def is_within_schedule():
    """检查当前是否在有效时间段内"""
    current_hour = datetime.now().hour
    return START_HOUR <= current_hour < END_HOUR

def record_audio():
    """执行音频录制"""
    if recording_state["is_recording"]:
        print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] 正在录制中，跳过本次录制")
        return
    
    if not is_within_schedule():
        print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] 不在有效时间段内（8:00-20:00），跳过本次录制")
        return
    
    output_file = get_output_path()
    print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] 开始录制: {output_file}")
    
    recording_state["is_recording"] = True
    recording_state["current_file"] = output_file
    recording_state["start_time"] = datetime.now()
    
    try:
        # 使用 ffmpeg 录制
        cmd = [
            'ffmpeg',
            '-rtsp_transport', 'tcp',
            '-i', RTSP_URL,
            '-t', str(RECORD_DURATION_MINUTES * 60),
            '-acodec', 'pcm_s16le',
            '-ar', '16000',
            '-ac', '1',
            '-y',
            output_file
        ]
        
        process = subprocess.Popen(
            cmd,
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
            universal_newlines=True
        )
        
        # 监控录制进度
        start_time = time.time()
        while process.poll() is None:
            if os.path.exists(output_file):
                size_mb = os.path.getsize(output_file) / (1024 * 1024)
                elapsed = time.time() - start_time
                print(f"\r进度: {int(elapsed)}秒 / {RECORD_DURATION_MINUTES * 60}秒, 大小: {size_mb:.2f}MB", end='')
            time.sleep(1)
        
        print()  # 换行
        
        # 录制完成
        if os.path.exists(output_file):
            size_mb = os.path.getsize(output_file) / (1024 * 1024)
            recording_state["total_recorded"] += 1
            print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] 录制完成: {output_file} ({size_mb:.2f}MB)")
        else:
            print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] 录制失败")
            
    except Exception as e:
        print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] 录制错误: {e}")
    finally:
        recording_state["is_recording"] = False
        recording_state["current_file"] = None
        recording_state["start_time"] = None
        
        # 录制完成后，在有效时间段内等待 REST_DURATION_MINUTES 分钟
        if is_within_schedule():
            print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] 进入休息模式，等待 {REST_DURATION_MINUTES} 分钟...")
            time.sleep(REST_DURATION_MINUTES * 60)
            print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] 休息结束")
        else:
            # 不在有效时间段，等待到下一个有效时间段
            now = datetime.now()
            if now.hour >= END_HOUR:
                # 等待到明天早上 8 点
                from datetime import timedelta
                next_day = now + timedelta(days=1)
                target = next_day.replace(hour=START_HOUR, minute=0, second=0, microsecond=0)
            else:
                # 等待到今天早上 8 点
                target = now.replace(hour=START_HOUR, minute=0, second=0, microsecond=0)
            
            wait_seconds = (target - now).total_seconds()
            print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] 不在有效时间段，等待 {wait_seconds/3600:.1f} 小时...")
            time.sleep(wait_seconds)

def schedule_recording():
    """定时录制任务"""
    thread = threading.Thread(target=record_audio, daemon=True)
    thread.start()

def run_scheduler():
    """运行定时器"""
    # 设置定时任务：每小时整点录制
    schedule.every().hour.at(":00").do(schedule_recording)
    
    print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] 定时录制服务已启动")
    print(f"  - 录制时长: {RECORD_DURATION_MINUTES} 分钟")
    print(f"  - 休息时长: {REST_DURATION_MINUTES} 分钟")
    print(f"  - 有效时段: {START_HOUR}:00 - {END_HOUR}:00")
    print("-" * 50)
    
    while True:
        schedule.run_pending()
        time.sleep(1)

# Flask 路由
@app.route('/')
def index():
    """主页"""
    return jsonify({
        "service": "RTSP Audio Recorder",
        "status": "running" if recording_state["is_recording"] else "idle",
        "config": {
            "rtsp_url": RTSP_URL,
            "record_duration": f"{RECORD_DURATION_MINUTES} minutes",
            "rest_duration": f"{REST_DURATION_MINUTES} minutes",
            "schedule": f"{START_HOUR}:00 - {END_HOUR}:00"
        }
    })

@app.route('/status')
def status():
    """获取录制状态"""
    return jsonify({
        "is_recording": recording_state["is_recording"],
        "current_file": recording_state["current_file"],
        "start_time": recording_state["start_time"].isoformat() if recording_state["start_time"] else None,
        "total_recorded": recording_state["total_recorded"],
        "current_time": datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
        "is_in_schedule": is_within_schedule()
    })

@app.route('/start')
def start_recording():
    """手动开始录制"""
    if recording_state["is_recording"]:
        return jsonify({"status": "error", "message": "正在录制中"})
    
    thread = threading.Thread(target=record_audio, daemon=True)
    thread.start()
    
    return jsonify({"status": "success", "message": "开始录制"})

@app.route('/stop')
def stop_recording():
    """手动停止录制（终止 ffmpeg 进程）"""
    if not recording_state["is_recording"]:
        return jsonify({"status": "error", "message": "当前没有在录制"})
    
    # 查找并终止 ffmpeg 进程
    try:
        subprocess.run(['taskkill', '/f', '/im', 'ffmpeg.exe'], capture_output=True)
        recording_state["is_recording"] = False
        return jsonify({"status": "success", "message": "已停止录制"})
    except Exception as e:
        return jsonify({"status": "error", "message": str(e)})

@app.route('/files')
def list_files():
    """列出已录制的文件"""
    files = []
    for f in os.listdir(OUTPUT_DIR):
        if f.endswith('.wav') and f.startswith('rtsp_'):
            path = os.path.join(OUTPUT_DIR, f)
            files.append({
                "name": f,
                "size": os.path.getsize(path),
                "modified": datetime.fromtimestamp(os.path.getmtime(path)).isoformat()
            })
    return jsonify({"files": files})

if __name__ == '__main__':
    # 确保输出目录存在
    os.makedirs(OUTPUT_DIR, exist_ok=True)
    
    # 启动定时器线程
    scheduler_thread = threading.Thread(target=run_scheduler, daemon=True)
    scheduler_thread.start()
    
    # 启动 Flask 服务
    print(f"\n{'='*50}")
    print(f"RTSP 音频录制服务")
    print(f"{'='*50}")
    app.run(host='0.0.0.0', port=5000, debug=False, use_reloader=False)
