|
|
@ -13,6 +13,7 @@ import com.cloud.kicc.common.security.util.SecurityUtils; |
|
|
|
import com.cloud.kicc.system.api.entity.ImContent; |
|
|
|
import com.cloud.kicc.system.api.entity.ImContent; |
|
|
|
import com.cloud.kicc.system.api.entity.OssFile; |
|
|
|
import com.cloud.kicc.system.api.entity.OssFile; |
|
|
|
import com.cloud.kicc.system.api.enums.ImMessageTypeEnum; |
|
|
|
import com.cloud.kicc.system.api.enums.ImMessageTypeEnum; |
|
|
|
|
|
|
|
import com.cloud.kicc.system.config.OpenAiConfigProperties; |
|
|
|
import com.cloud.kicc.system.mapper.ImContentMapper; |
|
|
|
import com.cloud.kicc.system.mapper.ImContentMapper; |
|
|
|
import com.cloud.kicc.system.service.FileService; |
|
|
|
import com.cloud.kicc.system.service.FileService; |
|
|
|
import com.cloud.kicc.system.service.IImContentService; |
|
|
|
import com.cloud.kicc.system.service.IImContentService; |
|
|
@ -30,7 +31,8 @@ import com.theokanning.openai.service.OpenAiService; |
|
|
|
import lombok.RequiredArgsConstructor; |
|
|
|
import lombok.RequiredArgsConstructor; |
|
|
|
import lombok.SneakyThrows; |
|
|
|
import lombok.SneakyThrows; |
|
|
|
import okhttp3.ResponseBody; |
|
|
|
import okhttp3.ResponseBody; |
|
|
|
import org.bytedeco.javacv.FFmpegFrameGrabber; |
|
|
|
import org.jaudiotagger.audio.AudioFile; |
|
|
|
|
|
|
|
import org.jaudiotagger.audio.AudioFileIO; |
|
|
|
import org.springframework.stereotype.Service; |
|
|
|
import org.springframework.stereotype.Service; |
|
|
|
import org.springframework.transaction.annotation.Transactional; |
|
|
|
import org.springframework.transaction.annotation.Transactional; |
|
|
|
import org.springframework.web.multipart.MultipartFile; |
|
|
|
import org.springframework.web.multipart.MultipartFile; |
|
|
@ -61,6 +63,8 @@ public class ImContentServiceImpl extends ServiceImpl<ImContentMapper, ImContent |
|
|
|
|
|
|
|
|
|
|
|
private final OssTemplate ossTemplate; |
|
|
|
private final OssTemplate ossTemplate; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private final OpenAiConfigProperties openAiConfigProperties; |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public IPage<Map<String, Object>> listHistoryMessage(Page page, ImContent imContent) { |
|
|
|
public IPage<Map<String, Object>> listHistoryMessage(Page page, ImContent imContent) { |
|
|
|
return baseMapper.listHistoryMessage(page, imContent); |
|
|
|
return baseMapper.listHistoryMessage(page, imContent); |
|
|
@ -92,64 +96,74 @@ public class ImContentServiceImpl extends ServiceImpl<ImContentMapper, ImContent |
|
|
|
fileService.save(sendOssOssFile); |
|
|
|
fileService.save(sendOssOssFile); |
|
|
|
imContent.setFiles(sendOssOssFile.getId()); |
|
|
|
imContent.setFiles(sendOssOssFile.getId()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
File inputVoiceFile = File.createTempFile(sendFileName, StrUtil.DOT + FileUtil.extName(file.getOriginalFilename())); |
|
|
|
|
|
|
|
File outputVoiceFile = File.createTempFile(sendFileName, StrUtil.DOT + FileUtil.extName(file.getOriginalFilename())); |
|
|
|
|
|
|
|
ImContent receiveContent; |
|
|
|
|
|
|
|
OssFile receiveOssOssFile; |
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
|
|
|
|
// 语音转文字
|
|
|
|
// 语音转文字
|
|
|
|
File voiceFile = File.createTempFile(sendFileName, StrUtil.DOT + FileUtil.extName(file.getOriginalFilename())); |
|
|
|
|
|
|
|
CreateTranscriptionRequest request = CreateTranscriptionRequest.builder() |
|
|
|
CreateTranscriptionRequest request = CreateTranscriptionRequest.builder() |
|
|
|
.model("whisper-1") |
|
|
|
.model("whisper-1") |
|
|
|
.language("zh") |
|
|
|
.language("zh") |
|
|
|
.build(); |
|
|
|
.build(); |
|
|
|
FileUtil.writeBytes(file.getBytes(), voiceFile); |
|
|
|
FileUtil.writeBytes(file.getBytes(), inputVoiceFile); |
|
|
|
TranscriptionResult transcriptionResult = openAiService.createTranscription(request, voiceFile); |
|
|
|
TranscriptionResult transcriptionResult = openAiService.createTranscription(request, inputVoiceFile); |
|
|
|
if (voiceFile.delete()) { |
|
|
|
|
|
|
|
System.out.println("已成功删除临时文件!"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
imContent.setContent(transcriptionResult.getText()); |
|
|
|
imContent.setContent(transcriptionResult.getText()); |
|
|
|
ImContent content = askChatCompletion(imContent); |
|
|
|
|
|
|
|
content.setContentType(ImMessageTypeEnum.AUDIO.getValue()); |
|
|
|
// ai涡轮增压
|
|
|
|
|
|
|
|
receiveContent = askChatCompletion(imContent); |
|
|
|
|
|
|
|
receiveContent.setContentType(ImMessageTypeEnum.AUDIO.getValue()); |
|
|
|
|
|
|
|
|
|
|
|
// 文字转语音
|
|
|
|
// 文字转语音
|
|
|
|
CreateSpeechRequest createSpeechRequest = CreateSpeechRequest.builder() |
|
|
|
CreateSpeechRequest createSpeechRequest = CreateSpeechRequest.builder() |
|
|
|
.model("tts-1") |
|
|
|
.model("tts-1") |
|
|
|
.input(content.getContent()) |
|
|
|
.input(receiveContent.getContent()) |
|
|
|
.voice("nova") |
|
|
|
.voice(openAiConfigProperties.getVoice()) |
|
|
|
.responseFormat(FileUtil.extName(speechName)) |
|
|
|
.responseFormat(FileUtil.extName(speechName)) |
|
|
|
.speed(1.0) |
|
|
|
.speed(1.0) |
|
|
|
.build(); |
|
|
|
.build(); |
|
|
|
ResponseBody responseBody = openAiService.createSpeech(createSpeechRequest); |
|
|
|
ResponseBody responseBody = openAiService.createSpeech(createSpeechRequest); |
|
|
|
|
|
|
|
FileUtil.writeBytes(responseBody.bytes(), outputVoiceFile); |
|
|
|
|
|
|
|
|
|
|
|
// 获取音频时长
|
|
|
|
// 获取输出音频时长
|
|
|
|
FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(responseBody.byteStream()); |
|
|
|
AudioFile outputAudioFile = AudioFileIO.read(outputVoiceFile); |
|
|
|
grabber.start(); |
|
|
|
long outputVoiceDuration = outputAudioFile.getAudioHeader().getTrackLength(); |
|
|
|
long durationInSec = grabber.getFormatContext().duration() / 1000000; |
|
|
|
|
|
|
|
grabber.close(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 构建发送文件信息进行OSS存储
|
|
|
|
// 构建发送文件信息进行OSS存储
|
|
|
|
OssFile receiveOssOssFile = new OssFile() |
|
|
|
receiveOssOssFile = new OssFile() |
|
|
|
.setFileName(receiveFileName) |
|
|
|
.setFileName(receiveFileName) |
|
|
|
.setBucketName(ossProperties.getBucketName()) |
|
|
|
.setBucketName(ossProperties.getBucketName()) |
|
|
|
.setOriginal(speechName) |
|
|
|
.setOriginal(speechName) |
|
|
|
.setType(FileUtil.extName(speechName)) |
|
|
|
.setType(FileUtil.extName(speechName)) |
|
|
|
.setFileSize(responseBody.contentLength()) |
|
|
|
.setFileSize(responseBody.contentLength()) |
|
|
|
.setDuration(durationInSec) |
|
|
|
.setDuration(outputVoiceDuration) |
|
|
|
.setMimeType(Objects.requireNonNull(responseBody.contentType()).toString()); |
|
|
|
.setMimeType(Objects.requireNonNull(responseBody.contentType()).toString()); |
|
|
|
ossTemplate.putObject(ossProperties.getBucketName(), receiveFileName, Objects.requireNonNull(responseBody.contentType()).toString(), responseBody.byteStream()); |
|
|
|
ossTemplate.putObject(ossProperties.getBucketName(), receiveFileName, Objects.requireNonNull(responseBody.contentType()).toString(), FileUtil.getInputStream(outputVoiceFile)); |
|
|
|
String receiveVoiceUrl = ossTemplate.getObjectURL(ossProperties.getBucketName(), receiveFileName); |
|
|
|
String receiveVoiceUrl = ossTemplate.getObjectURL(ossProperties.getBucketName(), receiveFileName); |
|
|
|
receiveOssOssFile.setAvailablePath(receiveVoiceUrl); |
|
|
|
receiveOssOssFile.setAvailablePath(receiveVoiceUrl); |
|
|
|
fileService.save(receiveOssOssFile); |
|
|
|
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回复聊天记录
|
|
|
|
// ai chat message build
|
|
|
|
content.setFiles(receiveOssOssFile.getId()); |
|
|
|
receiveContent.setFiles(receiveOssOssFile.getId()); |
|
|
|
super.save(content); |
|
|
|
super.save(receiveContent); |
|
|
|
|
|
|
|
Map<String, Object> result = Convert.toMap(String.class, Object.class, receiveContent); |
|
|
|
Map<String, Object> result = Convert.toMap(String.class, Object.class, content); |
|
|
|
|
|
|
|
result.putAll(Convert.toMap(String.class, Object.class, receiveOssOssFile)); |
|
|
|
result.putAll(Convert.toMap(String.class, Object.class, receiveOssOssFile)); |
|
|
|
return result; |
|
|
|
return result; |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
// 保存AI回复聊天记录
|
|
|
|
|
|
|
|
ImContent content = askChatCompletion(imContent); |
|
|
|
// ai chat message build
|
|
|
|
super.save(content); |
|
|
|
ImContent receiveContent = askChatCompletion(imContent); |
|
|
|
return Convert.toMap(String.class, Object.class, content); |
|
|
|
super.save(receiveContent); |
|
|
|
|
|
|
|
return Convert.toMap(String.class, Object.class, receiveContent); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|