import webrtcvad
import pyaudio
import tempfile
import wave
import time

def record_audio():
    print("Press enter to start!")
    input()
    # 参数配置
    FORMAT = pyaudio.paInt16  # 16-bit 位深
    CHANNELS = 1              # 单声道
    RATE = 48000              # 16kHz 采样率
    FRAME_DURATION = 30       # 每帧时长（ms）
    FRAME_SIZE = int(RATE * FRAME_DURATION / 3000)  # 每帧采样数
    SILENCE_TIMEOUT = 1.0     # 静音超时（秒）后停止
    MIN_SPEECH_DURATION = 1.0 # 最短录制时间（秒），避免误触发

    temp_wav_file = tempfile.NamedTemporaryFile(delete=False, suffix='.wav')
    temp_wav_path = temp_wav_file.name
    print(temp_wav_path)

    vad = webrtcvad.Vad()
    vad.set_mode(1)

    pa = pyaudio.PyAudio()
    stream = pa.open(
        format=FORMAT,
        channels=CHANNELS,
        rate=RATE,
        input=True,
        frames_per_buffer=FRAME_SIZE
    )

    # 变量初始化
    frames = []                # 存储录制的音频帧
    speech_detected = False    # 是否已检测到人声
    last_speech_time = time.time()  # 最后检测到人声的时间


    try:
        while True:
            # 读取一帧音频数据
            frame = stream.read(FRAME_SIZE, exception_on_overflow=False)
            
            # VAD 检测是否含人声
            is_speech = vad.is_speech(frame, RATE)
            # print(is_speech)
            if is_speech:
                # 检测到人声，更新最后活动时间
                last_speech_time = time.time()
                if not speech_detected:
                    speech_detected = True
                    print("检测到语音，开始录制...")
            
            # # 如果已经开始录制，保存音频帧
            # if speech_detected:
            frames.append(frame)
            
            # 静音超时判断（且满足最短录制时间）
            current_time = time.time()
            if (speech_detected and 
                current_time - last_speech_time > SILENCE_TIMEOUT and
                current_time - last_speech_time > MIN_SPEECH_DURATION):
                print(f"静音超过 {SILENCE_TIMEOUT} 秒，停止录制。")
                break

    except KeyboardInterrupt:
        print("手动中断录制。")
    finally:
        # 停止并关闭音频流
        stream.stop_stream()
        stream.close()
        pa.terminate()

        if len(frames) > 0:
            with wave.open(temp_wav_path, "wb") as wf:
                wf.setnchannels(CHANNELS)
                wf.setsampwidth(pa.get_sample_size(FORMAT))
                wf.setframerate(RATE)
                wf.writeframes(b"".join(frames))
            print("音频已保存为 temp_wav_file")
            return temp_wav_path