#!/usr/bin/env python3 """ FUNASR语音识别备用方案 使用speech_recognition库进行本地语音识别 如果speech_recognition库不可用,降级使用pydub和SpeechRecognition """ import json import sys import argparse import os from pathlib import Path from datetime import datetime def recognize_with_funasr(audio_path: str, language: str = 'zh', enable_word_timestamp: bool = True): """ 使用FUNASR本地模型进行语音识别 """ try: from funasr import AutoModel model = AutoModel( model="paraformer-zh", # 中文模型 vad_model="fsmn-vad", # 语音活动检测 vad_kwargs={"max_single_segment_time": 30000}, device="cpu" # 使用CPU,避免GPU依赖 ) res = model.generate( input=audio_path, cache={}, language=language, merge_consecutive_texts=False ) # 转换为标准格式 segments = [] current_time = 0.0 for item in res: if isinstance(item, dict) and 'text' in item: text = item['text'] # 估算时长(假设每个字0.5秒) duration = len(text) * 0.5 segment = { 'text': text, 'start': current_time, 'end': current_time + duration, 'words': [] } # 如果启用词级时间戳 if enable_word_timestamp and isinstance(item, dict) and 'details' in item: words = item['details'] for word_info in words: word = { 'word': word_info.get('text', ''), 'start': word_info.get('start', 0) / 1000, # 转换为秒 'end': word_info.get('end', 0) / 1000, 'confidence': word_info.get('confidence', 0.0) } segment['words'].append(word) segments.append(segment) current_time += duration return { 'segments': segments, 'language': language, 'duration': current_time } except ImportError: return recognize_with_speech_recognition(audio_path, language, enable_word_timestamp) def recognize_with_speech_recognition(audio_path: str, language: str = 'zh', enable_word_timestamp: bool = True): """ 使用SpeechRecognition库作为备用方案 支持Google Cloud Speech API、Sphinx等 """ try: import speech_recognition as sr recognizer = sr.Recognizer() # 支持多种音频格式 if audio_path.endswith('.wav'): with sr.AudioFile(audio_path) as source: audio = recognizer.record(source) else: # 对于其他格式,首先需要转换为WAV # 这里假设音频已经被转换为WAV with sr.AudioFile(audio_path) as source: audio = recognizer.record(source) # 尝试使用Google Cloud Speech Recognition(需要网络) try: text = recognizer.recognize_google(audio, language='zh-CN' if language == 'zh' else language) # 转换为标准格式 segments = [{ 'text': text, 'start': 0.0, 'end': 5.0, # 默认5秒 'words': [] }] return { 'segments': segments, 'language': language, 'duration': 5.0 } except sr.UnknownValueError: raise Exception("无法识别音频内容") except sr.RequestError as e: raise Exception(f"Google Speech Recognition请求失败: {e}") except ImportError: return recognize_with_pydub(audio_path, language, enable_word_timestamp) def recognize_with_pydub(audio_path: str, language: str = 'zh', enable_word_timestamp: bool = True): """ 如果都不可用,提供一个有用的错误信息 """ raise Exception( f"语音识别失败。需要安装以下至少一个库:\n" f"1. pip install funasr torch torchaudio\n" f"2. pip install SpeechRecognition pydub\n" f"3. 或者配置FUNASR HTTP服务 (FUNASR_API_URL环境变量)" ) def split_audio_into_segments(audio_path: str, segment_duration: int = 30): """ 将长音频分割成短段进行识别(避免超时) """ try: from pydub import AudioSegment audio = AudioSegment.from_file(audio_path) total_duration = len(audio) # 毫秒 segments = [] for i in range(0, total_duration, segment_duration * 1000): segment = audio[i:i + segment_duration * 1000] segments.append(segment) return segments except ImportError: raise Exception("需要安装pydub库: pip install pydub") def main(): parser = argparse.ArgumentParser(description='语音识别脚本') parser.add_argument('--audio', required=True, help='音频文件路径') parser.add_argument('--language', default='zh', help='语言代码(zh或en)') parser.add_argument('--enable-word-timestamp', default='1', help='是否启用词级时间戳') args = parser.parse_args() if not os.path.exists(args.audio): print(json.dumps({ 'success': False, 'error': f"音频文件不存在: {args.audio}" })) sys.exit(1) try: enable_word_timestamp = args.enable_word_timestamp == '1' # 尝试多种识别方式 result = recognize_with_funasr( args.audio, args.language, enable_word_timestamp ) print(json.dumps(result)) sys.exit(0) except Exception as e: print(json.dumps({ 'success': False, 'error': str(e), 'timestamp': datetime.now().isoformat() })) sys.exit(1) if __name__ == '__main__': main()