// 使用公共类型定义 import type { AudioItem, TranscriptionResult, TranscriptionResponse, TranscriptionData } from '@gold/config/types' /** * API 服务接口(需要从应用层注入) */ interface ApiService { videoToCharacters: (data: { fileLinkList: string[] }) => Promise<{ data: string }> } // 全局 API 服务实例(由应用层设置) let apiServiceInstance: ApiService | null = null /** * 设置 API 服务实例 * @param service - API 服务对象 */ export function setApiService(service: ApiService) { apiServiceInstance = service } /** * 将音频列表转换为文本转录 * @param list - 音频项列表 * @param apiService - API 服务实例(可选,如果已通过 setApiService 设置则不需要) * @returns 转录结果数组 * @throws 当转录过程出错时抛出错误 * * @example * const audioList = [{ audio_url: 'https://example.com/audio.mp3' }] * const transcriptions = await getVoiceText(audioList) * console.log(transcriptions) // [{ key: 'url', value: 'transcribed text' }] */ export async function getVoiceText( list: AudioItem[], apiService?: ApiService ): Promise { // 使用传入的 apiService 或全局实例 const service = apiService || apiServiceInstance if (!service) { throw new Error('getVoiceText: 需要提供 API 服务实例。请使用 setApiService() 设置或传入 apiService 参数') } // 调用API将视频转换为文本 const ret = await service.videoToCharacters({ fileLinkList: list.map(item => item.audio_url), }) // 解析响应数据 const data: string = ret.data const rst: TranscriptionResponse = JSON.parse(data) const transcription_url: string[] = rst.results.map(item => item.transcription_url) // 并行获取所有转录内容 const transcriptions: TranscriptionResult[] = await Promise.all( (transcription_url || []).filter(Boolean).map(async (url: string): Promise => { try { const resp: Response = await fetch(url) const contentType: string = resp.headers.get('content-type') || '' const value: string = contentType.includes('application/json') ? JSON.stringify(await resp.json()) : await resp.text() const parsed: TranscriptionData = JSON.parse(value) return { key: url, audio_url: parsed.file_url, value: parsed.transcripts?.[0]?.text || '' } } catch (e: unknown) { console.warn('获取转写内容失败:', url, e) return { key: url, value: '' } } }) ) return transcriptions } /** * Hook 返回值接口 */ interface UseVoiceTextReturn { getVoiceText: (list: AudioItem[], apiService?: ApiService) => Promise } /** * 语音文本转换 Hook * @param apiService - API 服务实例(可选,如果已通过 setApiService 设置则不需要) * @returns 包含 getVoiceText 方法的对象 * * @example * // 方式一:使用全局设置的 API 服务 * setApiService(myApiService) * const { getVoiceText } = useVoiceText() * const result = await getVoiceText(audioList) * * @example * // 方式二:传入 API 服务实例 * const { getVoiceText } = useVoiceText() * const result = await getVoiceText(audioList, myApiService) */ export default function useVoiceText(apiService?: ApiService): UseVoiceTextReturn { return { getVoiceText: (list: AudioItem[]) => getVoiceText(list, apiService) } }