1- import os
2- import uuid
3-
4- import anyio
51from openai import NOT_GIVEN , AsyncOpenAI
62
7- from astrbot .core import logger
8- from astrbot .core .provider .entities import ProviderType
9- from astrbot .core .provider .provider import STTProvider
10- from astrbot .core .provider .register import register_provider_adapter
11- from astrbot .core .utils .astrbot_path import get_astrbot_temp_path
12- from astrbot .core .utils .io import download_file
13- from astrbot .core .utils .media_utils import convert_audio_to_wav
14- from astrbot .core .utils .tencent_record_helper import (
15- convert_to_pcm_wav ,
16- tencent_silk_to_wav ,
17- )
18-
3+ from astrbot .core .utils .media_utils import MediaResolver
194
20- def _open_file_rb (path : str ):
21- return open (path , "rb" )
5+ from ..entities import ProviderType
6+ from ..provider import STTProvider
7+ from ..register import register_provider_adapter
228
239
2410@register_provider_adapter (
@@ -43,98 +29,18 @@ def __init__(
4329
4430 self .set_model (provider_config ["model" ])
4531
46- async def _get_audio_format (self , file_path ) -> str | None :
47- # 定义要检测的头部字节
48- silk_header = b"SILK"
49- amr_header = b"#!AMR"
50-
51- try :
52- async with await anyio .open_file (file_path , "rb" ) as f :
53- file_header = await f .read (8 )
54- except FileNotFoundError :
55- return None
56-
57- if silk_header in file_header :
58- return "silk"
59-
60- if amr_header in file_header :
61- return "amr"
62- return None
63-
6432 async def get_text (self , audio_url : str ) -> str :
6533 """Only supports mp3, mp4, mpeg, m4a, wav, webm"""
66- is_tencent = False
67- output_path = None
68-
69- if audio_url .startswith ("http" ):
70- if "multimedia.nt.qq.com.cn" in audio_url :
71- is_tencent = True
72-
73- temp_dir = get_astrbot_temp_path ()
74- path = os .path .join (
75- temp_dir ,
76- f"whisper_api_{ uuid .uuid4 ().hex [:8 ]} .input" ,
77- )
78- await download_file (audio_url , path )
79- audio_url = path
80-
81- if not await anyio .Path (audio_url ).exists ():
82- raise FileNotFoundError (f"文件不存在: { audio_url } " )
83-
84- lower_audio_url = audio_url .lower ()
85-
86- if lower_audio_url .endswith (".opus" ):
87- temp_dir = get_astrbot_temp_path ()
88- output_path = os .path .join (
89- temp_dir ,
90- f"whisper_api_{ uuid .uuid4 ().hex [:8 ]} .wav" ,
91- )
92- logger .info ("Converting opus file to wav using convert_audio_to_wav..." )
93- await convert_audio_to_wav (audio_url , output_path )
94- audio_url = output_path
95- elif (
96- lower_audio_url .endswith (".amr" )
97- or lower_audio_url .endswith (".silk" )
98- or is_tencent
99- ):
100- file_format = await self ._get_audio_format (audio_url )
101-
102- # 判断是否需要转换
103- if file_format in ["silk" , "amr" ]:
104- temp_dir = get_astrbot_temp_path ()
105- output_path = os .path .join (
106- temp_dir ,
107- f"whisper_api_{ uuid .uuid4 ().hex [:8 ]} .wav" ,
34+ async with MediaResolver (
35+ audio_url ,
36+ media_type = "audio" ,
37+ default_suffix = ".wav" ,
38+ ).as_path (target_format = "wav" ) as audio :
39+ with audio .open ("rb" ) as audio_file :
40+ result = await self .client .audio .transcriptions .create (
41+ model = self .model_name ,
42+ file = ("audio.wav" , audio_file ),
10843 )
109-
110- if file_format == "silk" :
111- logger .info (
112- "Converting silk file to wav using tencent_silk_to_wav..." ,
113- )
114- await tencent_silk_to_wav (audio_url , output_path )
115- elif file_format == "amr" :
116- logger .info (
117- "Converting amr file to wav using convert_to_pcm_wav..." ,
118- )
119- await convert_to_pcm_wav (audio_url , output_path )
120-
121- audio_url = output_path
122-
123- file_obj = await anyio .to_thread .run_sync (_open_file_rb , audio_url ) # type: ignore[call-arg]
124- try :
125- result = await self .client .audio .transcriptions .create (
126- model = self .model_name ,
127- file = ("audio.wav" , file_obj ),
128- )
129- finally :
130- file_obj .close ()
131-
132- # remove temp file
133- if output_path and await anyio .Path (output_path ).exists ():
134- try :
135- await anyio .Path (audio_url ).unlink ()
136- except Exception as e :
137- logger .error (f"Failed to remove temp file { audio_url } : { e } " )
13844 return result .text
13945
14046 async def terminate (self ):
0 commit comments