# ------------ # 导入所需模块和函数 # ------------ import json # 导入JSON处理模块 import os # 导入操作系统模块 from core.utils import * # 导入核心工具函数 try: from core.asr_backend.demucs_vl import demucs_audio # 导入Demucs音频分离功能(可选) except ImportError: demucs_audio = None # Demucs不可用时的占位符 from core.asr_backend.audio_preprocess import process_transcription, convert_video_to_audio, split_audio, save_results, normalize_audio_volume # 导入音频预处理相关函数 # 重构后删除了ytdlp模块,视频文件路径由主程序提供 # from core._1_ytdlp import find_video_files from core.utils.models import * # 导入模型相关工具 # ------------ # 音频转录主函数 # ------------ @check_file_exists(_2_CLEANED_CHUNKS) # 检查清理后的音频片段文件是否存在的装饰器 def transcribe(): # ------------ # 步骤1: 视频转音频 # ------------ # 重构后由主程序保证视频文件在output目录下 video_files = [f for f in os.listdir('output') if f.endswith(('.mp4', '.avi', '.mov', '.mkv'))] if not video_files: raise FileNotFoundError("在output目录下没有找到视频文件") video_file = os.path.join('output', video_files[0]) # 使用第一个找到的视频文件 convert_video_to_audio(video_file) # 将视频文件转换为音频文件 # ------------ # 步骤2: Demucs人声分离 # ------------ if load_key("demucs") and demucs_audio is not None: # 检查是否启用Demucs音频分离且模块可用 demucs_audio() # 执行音频分离,提取人声 vocal_audio = normalize_audio_volume(_VOCAL_AUDIO_FILE, _VOCAL_AUDIO_FILE, format="mp3") # 标准化人声音频音量 else: vocal_audio = _RAW_AUDIO_FILE # 如果未启用分离或模块不可用,直接使用原始音频文件 # ------------ # 步骤3: 音频分割 # ------------ segments = split_audio(_RAW_AUDIO_FILE) # 将音频文件分割成多个时间段 # ------------ # 步骤4: 按片段转录音频 # ------------ all_results = [] # 初始化结果列表存储所有转录结果 runtime = load_key("whisper.runtime") # 获取whisper运行时配置 if runtime == "local": # 如果使用本地模型 from core.asr_backend.whisperX_local import transcribe_audio as ts # 导入本地转录函数 rprint("[cyan]🎤 Transcribing audio with local model...[/cyan]") # 打印本地模型转录提示 elif runtime == "cloud": # 如果使用云端API from core.asr_backend.whisperX_302 import transcribe_audio_302 as ts # 导入302云端转录函数 rprint("[cyan]🎤 Transcribing audio with 302 API...[/cyan]") # 打印云端API转录提示 elif runtime == "elevenlabs": # 如果使用ElevenLabs API from core.asr_backend.elevenlabs_asr import transcribe_audio_elevenlabs as ts # 导入ElevenLabs转录函数 rprint("[cyan]🎤 Transcribing audio with ElevenLabs API...[/cyan]") # 打印ElevenLabs API转录提示 for start, end in segments: # 遍历每个音频片段的开始和结束时间 result = ts(_RAW_AUDIO_FILE, vocal_audio, start, end) # 对当前片段进行转录 all_results.append(result) # 将转录结果添加到结果列表 # ------------ # 步骤5: 合并转录结果 # ------------ combined_result = {'segments': []} # 初始化合并结果字典 for result in all_results: # 遍历所有转录结果 combined_result['segments'].extend(result['segments']) # 将每个结果的segments部分合并到总结果中 # ------------ # 步骤6: 处理和保存结果 # ------------ df = process_transcription(combined_result) # 将合并后的转录结果处理成DataFrame格式 save_results(df) # 保存处理后的转录结果到文件 # # ------------ # # 步骤7: 保存标准化的JSON格式结果(用于语义切割模块) # # ------------ # save_asr_result_json(combined_result) # 保存符合重构标准的JSON格式结果 # ------------ # 新增函数:保存标准化的ASR结果为JSON格式 # ------------ # def save_asr_result_json(transcription_result): # """ # 将ASR转录结果保存为标准化的JSON格式 # Args: # transcription_result: Whisper转录的原始结果,包含segments列表 # """ # asr_result = [] # # 遍历所有segments,提取文本和时间戳信息 # for i, segment in enumerate(transcription_result.get('segments', [])): # # 提取基本信息 # text = segment.get('text', '').strip() # start = float(segment.get('start', 0)) # end = float(segment.get('end', 0)) # # 过滤掉空文本的片段 # if text: # asr_result.append({ # "id": i, # "text": text, # "start": start, # "end": end # }) # # 保存到JSON文件 # os.makedirs('output', exist_ok=True) # with open(_ASR_RESULT, 'w', encoding='utf-8') as f: # json.dump(asr_result, f, ensure_ascii=False, indent=2) # rprint(f"[green]📄 ASR result saved to {_ASR_RESULT} with {len(asr_result)} segments[/green]") if __name__ == "__main__": # 主程序入口 transcribe() # 执行转录函数