118 lines
6.6 KiB
Python
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.

# ------------
# 导入所需模块和函数
# ------------
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() # 执行转录函数