@ -72,102 +72,7 @@ public class ImContentServiceImpl extends ServiceImpl<ImContentMapper, ImContent
@@ -72,102 +72,7 @@ public class ImContentServiceImpl extends ServiceImpl<ImContentMapper, ImContent
@Override
@Transactional ( rollbackFor = Exception . class )
@SneakyThrows
public Map < String , Object > completions ( ImContent imContent , MultipartFile file ) {
SecurityUtils . openInterfaceTemporaryLoginSession ( imContent . getSendUserId ( ) ) ;
if ( imContent . getContentType ( ) . equals ( ImMessageTypeEnum . AUDIO . getValue ( ) ) ) {
Optional . ofNullable ( file ) . orElseThrow ( ( ) - > new CheckedException ( "当前语音文件为空,请检查后重试!" ) ) ;
OpenAiService openAiService = AiUtil . getOpenAiService ( ) ;
String speechName = "speech.mp3" ;
String sendFileName = IdUtil . simpleUUID ( ) + StrUtil . DOT + FileUtil . extName ( file . getOriginalFilename ( ) ) ;
String receiveFileName = IdUtil . simpleUUID ( ) + StrUtil . DOT + FileUtil . extName ( speechName ) ;
// 构建发送文件信息进行OSS存储
OssFile sendOssOssFile = new OssFile ( )
. setFileName ( sendFileName )
. setBucketName ( ossProperties . getBucketName ( ) )
. setOriginal ( file . getOriginalFilename ( ) )
. setType ( FileUtil . extName ( file . getOriginalFilename ( ) ) )
. setFileSize ( file . getSize ( ) )
. setMimeType ( file . getContentType ( ) ) ;
ossTemplate . putObject ( ossProperties . getBucketName ( ) , sendFileName , file . getContentType ( ) , file . getInputStream ( ) ) ;
String sendVoiceUrl = ossTemplate . getObjectURL ( ossProperties . getBucketName ( ) , sendFileName ) ;
sendOssOssFile . setAvailablePath ( sendVoiceUrl ) ;
fileService . save ( sendOssOssFile ) ;
imContent . setFiles ( sendOssOssFile . getId ( ) ) ;
File inputVoiceFile = File . createTempFile ( FileUtil . getPrefix ( file . getOriginalFilename ( ) ) , StrUtil . DOT + FileUtil . extName ( file . getOriginalFilename ( ) ) ) ;
File outputVoiceFile = File . createTempFile ( FileUtil . getPrefix ( speechName ) , StrUtil . DOT + FileUtil . extName ( speechName ) ) ;
ImContent receiveContent ;
OssFile receiveOssOssFile ;
try {
// 语音转文字
CreateTranscriptionRequest request = CreateTranscriptionRequest . builder ( )
. model ( "whisper-1" )
. language ( "zh" )
. build ( ) ;
FileUtil . writeBytes ( file . getBytes ( ) , inputVoiceFile ) ;
TranscriptionResult transcriptionResult = openAiService . createTranscription ( request , inputVoiceFile ) ;
imContent . setContent ( transcriptionResult . getText ( ) ) ;
// ai涡轮增压
receiveContent = askChatCompletion ( imContent ) ;
receiveContent . setContentType ( ImMessageTypeEnum . AUDIO . getValue ( ) ) ;
// 文字转语音
CreateSpeechRequest createSpeechRequest = CreateSpeechRequest . builder ( )
. model ( "tts-1" )
. input ( receiveContent . getContent ( ) )
. voice ( openAiConfigProperties . getVoice ( ) )
. responseFormat ( FileUtil . extName ( speechName ) )
. speed ( openAiConfigProperties . getSpeed ( ) )
. build ( ) ;
ResponseBody responseBody = openAiService . createSpeech ( createSpeechRequest ) ;
FileUtil . writeBytes ( responseBody . bytes ( ) , outputVoiceFile ) ;
// 获取输出音频时长
AudioFile outputAudioFile = AudioFileIO . read ( outputVoiceFile ) ;
long outputVoiceDuration = outputAudioFile . getAudioHeader ( ) . getTrackLength ( ) ;
// 构建发送文件信息进行OSS存储
receiveOssOssFile = new OssFile ( )
. setFileName ( receiveFileName )
. setBucketName ( ossProperties . getBucketName ( ) )
. setOriginal ( speechName )
. setType ( FileUtil . extName ( speechName ) )
. setFileSize ( responseBody . contentLength ( ) )
. setDuration ( outputVoiceDuration )
. setMimeType ( Objects . requireNonNull ( responseBody . contentType ( ) ) . toString ( ) ) ;
ossTemplate . putObject ( ossProperties . getBucketName ( ) , receiveFileName , Objects . requireNonNull ( responseBody . contentType ( ) ) . toString ( ) , FileUtil . getInputStream ( outputVoiceFile ) ) ;
String receiveVoiceUrl = ossTemplate . getObjectURL ( ossProperties . getBucketName ( ) , receiveFileName ) ;
receiveOssOssFile . setAvailablePath ( receiveVoiceUrl ) ;
fileService . save ( receiveOssOssFile ) ;
} catch ( Exception e ) {
throw new CheckedException ( e . getLocalizedMessage ( ) ) ;
} finally {
if ( inputVoiceFile . delete ( ) )
System . out . println ( "已成功删除临时输入语音文件!" ) ;
if ( outputVoiceFile . delete ( ) )
System . out . println ( "已成功删除临时输输出语音文件!" ) ;
}
// ai chat message build
receiveContent . setFiles ( receiveOssOssFile . getId ( ) ) ;
super . save ( receiveContent ) ;
Map < String , Object > result = Convert . toMap ( String . class , Object . class , receiveContent ) ;
result . putAll ( Convert . toMap ( String . class , Object . class , receiveOssOssFile ) ) ;
return result ;
} else {
// ai chat message build
ImContent receiveContent = askChatCompletion ( imContent ) ;
super . save ( receiveContent ) ;
return Convert . toMap ( String . class , Object . class , receiveContent ) ;
}
}
private ImContent askChatCompletion ( ImContent imContent ) {
public ImContent chatCompletions ( ImContent imContent ) {
if ( StrUtil . isBlank ( imContent . getContent ( ) ) ) {
throw new CheckedException ( "提问内容不能为空请检查!" ) ;
}
@ -195,25 +100,124 @@ public class ImContentServiceImpl extends ServiceImpl<ImContentMapper, ImContent
@@ -195,25 +100,124 @@ public class ImContentServiceImpl extends ServiceImpl<ImContentMapper, ImContent
return chatMessage ;
} ) . collect ( Collectors . toList ( ) ) ;
// 提问 消息
ChatMessage ask Message = new ChatMessage ( ChatMessageRole . USER . value ( ) , imContent . getContent ( ) ) ;
historyMessages . add ( ask Message) ;
// Completion 消息
ChatMessage completion Message = new ChatMessage ( ChatMessageRole . USER . value ( ) , imContent . getContent ( ) ) ;
historyMessages . add ( completion Message) ;
ChatCompletionResult chatCompletionResult = AiUtil . getChatCompletion ( historyMessages ) ;
List < ChatCompletionChoice > choiceList = chatCompletionResult . getChoices ( ) ;
if ( choiceList . isEmpty ( ) ) {
throw new CheckedException ( "Ai生成解析失败!" ) ;
throw new CheckedException ( "Ai生成内容 解析失败!" ) ;
}
// 构建AI生成消息
return new ImContent ( )
. setSendUserId ( imContent . getReceiveUserId ( ) )
. setSendTime ( LocalDateTime . now ( ) )
. setReceiveUserId ( SecurityUtils . getCasUser ( ) . getId ( ) )
. setReceiveTime ( LocalDateTime . now ( ) )
. setContent ( choiceList . get ( 0 ) . getMessage ( ) . getContent ( ) )
. setContentType ( ImMessageTypeEnum . TEXT . getValue ( ) ) ;
// ai chat message build
ImContent receiveContent = new ImContent ( )
. setSendUserId ( imContent . getReceiveUserId ( ) )
. setSendTime ( LocalDateTime . now ( ) )
. setReceiveUserId ( SecurityUtils . getCasUser ( ) . getId ( ) )
. setReceiveTime ( LocalDateTime . now ( ) )
. setContent ( choiceList . get ( 0 ) . getMessage ( ) . getContent ( ) )
. setContentType ( imContent . getContentType ( ) ) ;
super . save ( receiveContent ) ;
return receiveContent ;
}
@Override
@SneakyThrows
@Transactional ( rollbackFor = Exception . class )
public ImContent audioTranscriptions ( ImContent imContent , MultipartFile file ) {
Optional . ofNullable ( file ) . orElseThrow ( ( ) - > new CheckedException ( "当前语音文件为空,请检查后重试!" ) ) ;
OpenAiService openAiService = AiUtil . getOpenAiService ( ) ;
String sendFileName = IdUtil . simpleUUID ( ) + StrUtil . DOT + FileUtil . extName ( file . getOriginalFilename ( ) ) ;
File inputVoiceFile = File . createTempFile ( FileUtil . getPrefix ( file . getOriginalFilename ( ) ) , StrUtil . DOT + FileUtil . extName ( file . getOriginalFilename ( ) ) ) ;
try {
// 获取输入音频时长
FileUtil . writeBytes ( file . getBytes ( ) , inputVoiceFile ) ;
AudioFile inputAudioFile = AudioFileIO . read ( inputVoiceFile ) ;
long inputVoiceDuration = inputAudioFile . getAudioHeader ( ) . getTrackLength ( ) ;
// 构建发送文件信息进行OSS存储
OssFile sendOssOssFile = new OssFile ( )
. setFileName ( sendFileName )
. setBucketName ( ossProperties . getBucketName ( ) )
. setOriginal ( file . getOriginalFilename ( ) )
. setType ( FileUtil . extName ( file . getOriginalFilename ( ) ) )
. setDuration ( inputVoiceDuration )
. setFileSize ( file . getSize ( ) )
. setMimeType ( file . getContentType ( ) ) ;
ossTemplate . putObject ( ossProperties . getBucketName ( ) , sendFileName , file . getContentType ( ) , file . getInputStream ( ) ) ;
String sendVoiceUrl = ossTemplate . getObjectURL ( ossProperties . getBucketName ( ) , sendFileName ) ;
sendOssOssFile . setAvailablePath ( sendVoiceUrl ) ;
fileService . save ( sendOssOssFile ) ;
// 语音转文字
CreateTranscriptionRequest request = CreateTranscriptionRequest . builder ( )
. model ( "whisper-1" )
. language ( "zh" )
. build ( ) ;
TranscriptionResult transcriptionResult = openAiService . createTranscription ( request , inputVoiceFile ) ;
imContent . setContent ( transcriptionResult . getText ( ) ) ;
imContent . setFiles ( sendOssOssFile . getId ( ) ) ;
} catch ( Exception e ) {
throw new CheckedException ( e . getLocalizedMessage ( ) ) ;
} finally {
if ( inputVoiceFile . delete ( ) )
System . out . println ( "已成功删除临时输入语音文件!" ) ;
}
return imContent ;
}
@Override
@SneakyThrows
@Transactional ( rollbackFor = Exception . class )
public OssFile audioSpeech ( ImContent imContent ) {
Optional . ofNullable ( imContent . getId ( ) ) . orElseThrow ( ( ) - > new CheckedException ( "当前聊天内容ID必传,需要进行文件绑定请检查后重试!" ) ) ;
OpenAiService openAiService = AiUtil . getOpenAiService ( ) ;
String speechName = "speech.mp3" ;
String receiveFileName = IdUtil . simpleUUID ( ) + StrUtil . DOT + FileUtil . extName ( speechName ) ;
File outputVoiceFile = File . createTempFile ( FileUtil . getPrefix ( speechName ) , StrUtil . DOT + FileUtil . extName ( speechName ) ) ;
OssFile receiveOssOssFile ;
try {
// 文字转语音
CreateSpeechRequest createSpeechRequest = CreateSpeechRequest . builder ( )
. model ( "tts-1" )
. input ( imContent . getContent ( ) )
. voice ( openAiConfigProperties . getVoice ( ) )
. responseFormat ( FileUtil . extName ( speechName ) )
. speed ( openAiConfigProperties . getSpeed ( ) )
. build ( ) ;
ResponseBody responseBody = openAiService . createSpeech ( createSpeechRequest ) ;
FileUtil . writeBytes ( responseBody . bytes ( ) , outputVoiceFile ) ;
// 获取输出音频时长
AudioFile outputAudioFile = AudioFileIO . read ( outputVoiceFile ) ;
long outputVoiceDuration = outputAudioFile . getAudioHeader ( ) . getTrackLength ( ) ;
// 构建发送文件信息进行OSS存储
receiveOssOssFile = new OssFile ( )
. setFileName ( receiveFileName )
. setBucketName ( ossProperties . getBucketName ( ) )
. setOriginal ( speechName )
. setType ( FileUtil . extName ( speechName ) )
. setFileSize ( responseBody . contentLength ( ) )
. setDuration ( outputVoiceDuration )
. setMimeType ( Objects . requireNonNull ( responseBody . contentType ( ) ) . toString ( ) ) ;
ossTemplate . putObject ( ossProperties . getBucketName ( ) , receiveFileName , Objects . requireNonNull ( responseBody . contentType ( ) ) . toString ( ) , FileUtil . getInputStream ( outputVoiceFile ) ) ;
String receiveVoiceUrl = ossTemplate . getObjectURL ( ossProperties . getBucketName ( ) , receiveFileName ) ;
receiveOssOssFile . setAvailablePath ( receiveVoiceUrl ) ;
fileService . save ( receiveOssOssFile ) ;
// 给当前音频聊天内容绑定音频文件
super . update ( Wrappers . < ImContent > lambdaUpdate ( ) . eq ( ImContent : : getId , imContent . getId ( ) ) . set ( ImContent : : getFiles , receiveOssOssFile . getId ( ) ) ) ;
} catch ( Exception e ) {
throw new CheckedException ( e . getLocalizedMessage ( ) ) ;
} finally {
if ( outputVoiceFile . delete ( ) )
System . out . println ( "已成功删除临时输出语音文件!" ) ;
}
return receiveOssOssFile ;
}
}