@@ -12,6 +12,8 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired ;
import org.springframework.beans.factory.annotation.Value ;
import org.springframework.stereotype.Service ;
import com.fasterxml.jackson.databind.ObjectMapper ;
import com.fasterxml.jackson.databind.JsonNode ;
import java.time.LocalDateTime ;
import java.util.ArrayList ;
@@ -171,54 +173,83 @@ public class TtsRequestLogServiceImpl implements ITtsRequestLogService {
log . info ( " 语音识别完成 - result: {} " , result ) ;
long processingTime = System . currentTimeMillis ( ) - startTime ;
if ( result . getOutput ( ) ! = null ) {
// 解析识别结果 - 从JSON中提取文本
if ( result . getResults ( ) ! = null & & ! result . getResults ( ) . isEmpty ( ) ) {
// 解析识别结果 - 从results中获取transcriptionUrl并下载识别结果
String fullText = " " ;
Double duration = 0 . 0 ;
List < AsrResponse . AsrResult > asrResults = new ArrayList < > ( ) ;
try {
// 从输出中提取文本和 时长信息
if ( result . getOutput ( ) . toString ( ) . contains ( " \" text \" " ) ) {
// 简单解析JSON获取文本
String outputStr = result . getOutput ( ) . toString ( ) ;
int textStart = outputStr . indexOf ( " \" text \" : \" " ) + 8 ;
int textEnd = outputStr . indexOf ( " \" " , textStart ) ;
if ( text Start > 7 & & textEnd > textStart ) {
fullText = output Str. substring ( textStart , textEnd ) ;
// 从usage中获取 时长信息
if ( result . getUsage ( ) ! = null ) {
// 从usage对象中获取duration, usage通常是一个JsonObject
try {
Str ing usageStr = result . getUsage ( ) . toString ( ) ;
if ( usageStr . contains ( " \" duration \" " ) ) {
int duration Start = usageStr . indexOf ( " \" duration \" : " ) + 11 ;
int durationEnd = usage Str. indexOf ( " , " , durationStart ) ;
if ( durationEnd = = - 1 ) {
durationEnd = usageStr . indexOf ( " } " , durationStart ) ;
}
if ( durationStart > 10 & & durationEnd > durationStart ) {
duration = Double . parseDouble ( usageStr . substring ( durationStart , durationEnd ) . trim ( ) ) ;
}
}
} catch ( Exception e ) {
log . warn ( " 解析usage中的duration失败: {} " , e . getMessage ( ) ) ;
}
}
// 提取时长信息
i f ( result . getOutput ( ) . toString ( ) . contains ( " \" duration \" " ) ) {
String outputStr = result . getOutput ( ) . toString ( ) ;
int durationStart = outputStr . indexOf ( " \" duration \" : " ) + 11 ;
int durationEnd = outputStr . indexOf ( " , " , durationStart ) ;
if ( durationEnd = = - 1 ) {
durationEnd = outputStr . indexOf ( " } " , durationStart ) ;
}
if ( durationStart > 10 & & durationEnd > durationStart ) {
// 遍历所有结果, 获取transcriptionUrl并下载识别文本
for ( TranscriptionTaskResult taskResult : result . getResults ( ) ) {
if ( taskResult . getTranscriptionUrl ( ) ! = null ) {
try {
duration = Double . parseDouble ( outputStr . substring ( durationStart , durationEnd ) . trim ( ) ) ;
} catch ( NumberFormatException e ) {
duration = 0 . 0 ;
// 从transcriptionUrl下载识别结果
String transcriptionResult = downloadTranscriptionResult ( taskResult . getTranscriptionUrl ( ) ) ;
log . info ( " transcriptionResult: {} " , transcriptionResult ) ;
if ( transcriptionResult ! = null & & ! transcriptionResult . trim ( ) . isEmpty ( ) ) {
// 解析transcription结果JSON
String extractedText = parseTranscriptionResult ( transcriptionResult ) ;
if ( extractedText ! = null & & ! extractedText . trim ( ) . isEmpty ( ) ) {
fullText + = extractedText ;
// 输出识别文本到控制台
System . out . println ( " === 语音识别结果 === " ) ;
System . out . println ( " 任务ID: " + taskId ) ;
System . out . println ( " 识别文本: " + extractedText ) ;
System . out . println ( " ================== " ) ;
// 创建结果对象
AsrResponse . AsrResult asrResult = new AsrResponse . AsrResult ( ) ;
asrResult . setText ( extractedText ) ;
asrResult . setStartTime ( 0 . 0 ) ;
asrResult . setEndTime ( duration ) ;
asrResults . add ( asrResult ) ;
}
}
} catch ( Exception e ) {
log . warn ( " 下载transcription结果失败: {} " , e . getMessage ( ) ) ;
}
}
}
} catch ( Exception e ) {
log . warn ( " 解析ASR结果时出错: {} " , e . getMessage ( ) ) ;
}
List < AsrResponse . AsrResult > asrResults = new ArrayList < > ( ) ;
// 创建简单的结果对象
AsrResponse . AsrResult asrResult = new AsrResponse . AsrResult ( ) ;
asrResult . setText ( fullText ) ;
asrResult . setStartTime ( 0 . 0 ) ;
asrResult . setEndTime ( duration ) ;
asrResults . add ( asrResult ) ;
if ( fullText . trim ( ) . isEmpty ( ) ) {
log . warn ( " ASR识别结果为空 - TaskId: {} " , taskId ) ;
return AsrResponse . error ( " 语音识别结果为空 " ) ;
}
log . info ( " 语音识别完成 - 识别文本长度: {}, 处理时间: {}ms " , fullText . length ( ) , processingTime ) ;
// 如果提供了TTS日志ID, 则保存识别文本到数据库
if ( request . getId ( ) ! = null & & ! request . getId ( ) . trim ( ) . isEmpty ( ) ) {
saveRecognizedTextToDatabase ( request . getId ( ) , fullText ) ;
}
return AsrResponse . success ( fullText , asrResults , duration , processingTime , taskId , requestId ) ;
} else {
log . warn ( " ASR识别结果为空 - TaskId: {} " , taskId ) ;
@@ -235,4 +266,135 @@ public class TtsRequestLogServiceImpl implements ITtsRequestLogService {
public boolean isAsrServiceAvailable ( ) {
return asrEnabled & & apiKey ! = null & & ! apiKey . trim ( ) . isEmpty ( ) ;
}
/**
* 下载transcription结果
*/
private String downloadTranscriptionResult ( String transcriptionUrl ) {
try {
log . info ( " 开始下载transcription结果, URL: {} " , transcriptionUrl ) ;
// 使用简单的URL连接下载transcription结果, 避免HttpClient依赖问题
java . net . URL url = new java . net . URL ( transcriptionUrl ) ;
java . net . HttpURLConnection connection = ( java . net . HttpURLConnection ) url . openConnection ( ) ;
// 设置请求头
connection . setRequestMethod ( " GET " ) ;
connection . setRequestProperty ( " User-Agent " , " Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 " ) ;
connection . setRequestProperty ( " Accept " , " application/json " ) ;
connection . setConnectTimeout ( 30000 ) ; // 30秒连接超时
connection . setReadTimeout ( 60000 ) ; // 60秒读取超时
int responseCode = connection . getResponseCode ( ) ;
if ( responseCode = = 200 ) {
// 读取响应内容
StringBuilder result = new StringBuilder ( ) ;
try ( java . io . BufferedReader reader = new java . io . BufferedReader (
new java . io . InputStreamReader ( connection . getInputStream ( ) , java . nio . charset . StandardCharsets . UTF_8 ) ) ) {
String line ;
while ( ( line = reader . readLine ( ) ) ! = null ) {
result . append ( line ) . append ( " \ n " ) ;
}
}
String responseBody = result . toString ( ) . trim ( ) ;
log . info ( " 成功下载transcription结果, 长度: {} 字符 " , responseBody . length ( ) ) ;
return responseBody ;
} else {
log . warn ( " 下载transcription结果失败, 状态码: {} " , responseCode ) ;
return null ;
}
} catch ( Exception e ) {
log . error ( " 下载transcription结果异常: {} " , e . getMessage ( ) , e ) ;
return null ;
}
}
/**
* 解析transcription结果JSON, 提取识别文本
*/
private String parseTranscriptionResult ( String transcriptionJson ) {
try {
// 使用Jackson解析JSON
ObjectMapper mapper = new ObjectMapper ( ) ;
JsonNode rootNode = mapper . readTree ( transcriptionJson ) ;
log . info ( " 开始解析transcription JSON " ) ;
// 根据阿里云ASR返回的JSON结构解析
// 阿里云返回的结构: {"transcripts": [{"text": "识别的文本", "sentences": [...]}]}
JsonNode transcriptsNode = rootNode . get ( " transcripts " ) ;
if ( transcriptsNode ! = null & & transcriptsNode . isArray ( ) & & transcriptsNode . size ( ) > 0 ) {
JsonNode firstTranscript = transcriptsNode . get ( 0 ) ;
JsonNode textNode = firstTranscript . get ( " text " ) ;
if ( textNode ! = null & & ! textNode . isNull ( ) ) {
String text = textNode . asText ( ) ;
log . info ( " 成功提取识别文本: {} " , text ) ;
return text ;
}
}
// 如果没有transcripts字段, 尝试其他可能的字段结构
JsonNode resultsNode = rootNode . get ( " results " ) ;
if ( resultsNode ! = null & & resultsNode . isArray ( ) ) {
StringBuilder textBuilder = new StringBuilder ( ) ;
for ( JsonNode resultNode : resultsNode ) {
JsonNode textNode = resultNode . get ( " text " ) ;
if ( textNode ! = null & & ! textNode . isNull ( ) ) {
String text = textNode . asText ( ) ;
textBuilder . append ( text ) . append ( " " ) ;
log . info ( " 提取到文本片段: {} " , text ) ;
}
}
String fullText = textBuilder . toString ( ) . trim ( ) ;
if ( ! fullText . isEmpty ( ) ) {
log . info ( " 完整识别文本: {} " , fullText ) ;
return fullText ;
}
}
// 如果没有results字段, 尝试直接获取text字段
JsonNode textNode = rootNode . get ( " text " ) ;
if ( textNode ! = null & & ! textNode . isNull ( ) ) {
String text = textNode . asText ( ) ;
log . info ( " 直接获取文本: {} " , text ) ;
return text ;
}
// 如果都没有, 记录JSON结构用于调试
log . warn ( " 未找到预期的文本字段, JSON结构: {} " , rootNode . toString ( ) ) ;
return null ;
} catch ( Exception e ) {
log . error ( " 解析transcription结果JSON失败: {} " , e . getMessage ( ) , e ) ;
return null ;
}
}
/**
* 保存识别文本到数据库
*/
private void saveRecognizedTextToDatabase ( String ttsLogId , String recognizedText ) {
try {
// 根据ID查询TTS请求日志
TtsRequestLog ttsLog = ttsRequestLogMapper . selectById ( ttsLogId ) ;
if ( ttsLog ! = null ) {
// 将识别文本保存到inputText字段
ttsLog . setInputText ( recognizedText ) ;
ttsLog . setInputLength ( recognizedText . length ( ) ) ;
ttsLog . setUpdateTime ( LocalDateTime . now ( ) ) ;
// 保存到数据库
int updateResult = ttsRequestLogMapper . updateById ( ttsLog ) ;
if ( updateResult > 0 ) {
log . info ( " 成功保存识别文本到数据库, TTS日志ID: {}, 文本长度: {} " , ttsLogId , recognizedText . length ( ) ) ;
} else {
log . warn ( " 保存识别文本到数据库失败, TTS日志ID: {} " , ttsLogId ) ;
}
} else {
log . warn ( " 未找到对应的TTS请求日志, ID: {} " , ttsLogId ) ;
}
} catch ( Exception e ) {
log . error ( " 保存识别文本到数据库异常: {} " , e . getMessage ( ) , e ) ;
}
}
}