Signed-off-by: wuhaobin <2307299049@qq.com>
main
wuhaobin 4 months ago
parent 243f0dff59
commit 2eadfbe1aa

@ -16,6 +16,8 @@ import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import java.util.List;
import java.util.ArrayList;
@RestController
@RequestMapping("/api/clipping")
@ -291,6 +293,56 @@ public class AudioClippingController {
cleanupTempFiles(filePath1, filePath2, resultPath);
}
}
@PostMapping("/merge-multiple")
public ResponseEntity<?> mergeMultipleAudio(@RequestParam("files") MultipartFile[] files) {
List<String> filePaths = new ArrayList<>();
String resultPath = null;
try {
// 验证文件数量
if (files == null || files.length < 2) {
return ResponseEntity.badRequest().body(Map.of("error", "At least two audio files are required for merging"));
}
// 验证并保存所有文件
for (MultipartFile file : files) {
validateUploadedFile(file);
filePaths.add(saveUploadedFile(file));
}
// 执行合并操作
resultPath = audioProcessingService.mergeMultipleAudio(filePaths);
// 生成文件名
StringBuilder filenameBuilder = new StringBuilder("merged_");
for (int i = 0; i < files.length; i++) {
if (i > 0) filenameBuilder.append("_");
filenameBuilder.append(files[i].getOriginalFilename());
}
// 返回结果文件
return processAudioResult(resultPath, filenameBuilder.toString(), "merge");
} catch (IllegalArgumentException e) {
return ResponseEntity.badRequest().body(Map.of("error", e.getMessage()));
} catch (IOException e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(Map.of("error", "Audio processing failed: " + e.getMessage()));
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(Map.of("error", "Audio processing exception: " + e.getMessage()));
} finally {
// 清理临时文件
if (filePaths != null && !filePaths.isEmpty()) {
cleanupTempFiles(filePaths.toArray(new String[0]));
}
if (resultPath != null) {
cleanupTempFiles(resultPath);
}
}
}
@GetMapping("/test")
public ResponseEntity<Map<String, String>> test() {

@ -6,6 +6,7 @@ import javax.sound.sampled.*;
import java.io.*;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
// MP3解码相关导入
import javazoom.jl.decoder.Bitstream;
@ -500,44 +501,143 @@ public class AudioProcessingService {
* @return merged file path
*/
public String mergeAudio(String filePath1, String filePath2) throws Exception {
AudioInputStream stream1 = AudioSystem.getAudioInputStream(new File(filePath1));
AudioInputStream stream2 = AudioSystem.getAudioInputStream(new File(filePath2));
AudioFormat format1 = stream1.getFormat();
AudioFormat format2 = stream2.getFormat();
// 检测文件格式
String fileExtension1 = filePath1.toLowerCase();
String fileExtension2 = filePath2.toLowerCase();
// Check if audio formats are compatible
if (!format1.matches(format2)) {
throw new IllegalArgumentException("Audio formats are not compatible, cannot merge");
// 如果两个文件都是MP3格式使用MP3合并方法
if (fileExtension1.endsWith(".mp3") && fileExtension2.endsWith(".mp3")) {
return mergeMP3Audio(filePath1, filePath2);
} else {
// 其他格式使用原来的WAV合并方法
AudioInputStream stream1 = AudioSystem.getAudioInputStream(new File(filePath1));
AudioInputStream stream2 = AudioSystem.getAudioInputStream(new File(filePath2));
AudioFormat format1 = stream1.getFormat();
AudioFormat format2 = stream2.getFormat();
// Check if audio formats are compatible
if (!format1.matches(format2)) {
throw new IllegalArgumentException("Audio formats are not compatible, cannot merge");
}
// Read both audio files' data
byte[] audioData1 = stream1.readAllBytes();
byte[] audioData2 = stream2.readAllBytes();
stream1.close();
stream2.close();
// Merge audio data
byte[] mergedData = new byte[audioData1.length + audioData2.length];
System.arraycopy(audioData1, 0, mergedData, 0, audioData1.length);
System.arraycopy(audioData2, 0, mergedData, audioData1.length, audioData2.length);
// Create new audio stream
ByteArrayInputStream bais = new ByteArrayInputStream(mergedData);
AudioInputStream mergedStream = new AudioInputStream(bais, format1,
mergedData.length / format1.getFrameSize());
// Save merged file - use absolute path
File tempDir = new File(TEMP_DIR);
if (!tempDir.isAbsolute()) {
tempDir = new File(System.getProperty("user.dir"), TEMP_DIR);
}
String outputPath = new File(tempDir, "merge_" + System.currentTimeMillis() + ".wav").getAbsolutePath();
AudioSystem.write(mergedStream, AudioFileFormat.Type.WAVE, new File(outputPath));
mergedStream.close();
return outputPath;
}
}
/**
*
* @param filePaths
* @return
*/
public String mergeMultipleAudio(List<String> filePaths) throws Exception {
if (filePaths == null || filePaths.size() < 2) {
throw new IllegalArgumentException("At least two audio files are required for merging");
}
// Read both audio files' data
byte[] audioData1 = stream1.readAllBytes();
byte[] audioData2 = stream2.readAllBytes();
stream1.close();
stream2.close();
// Merge audio data
byte[] mergedData = new byte[audioData1.length + audioData2.length];
System.arraycopy(audioData1, 0, mergedData, 0, audioData1.length);
System.arraycopy(audioData2, 0, mergedData, audioData1.length, audioData2.length);
// Create new audio stream
ByteArrayInputStream bais = new ByteArrayInputStream(mergedData);
AudioInputStream mergedStream = new AudioInputStream(bais, format1,
mergedData.length / format1.getFrameSize());
// Save merged file - use absolute path
File tempDir = new File(TEMP_DIR);
if (!tempDir.isAbsolute()) {
tempDir = new File(System.getProperty("user.dir"), TEMP_DIR);
// 检查所有文件是否都是MP3格式
boolean allMP3 = true;
for (String filePath : filePaths) {
if (!filePath.toLowerCase().endsWith(".mp3")) {
allMP3 = false;
break;
}
}
String outputPath = new File(tempDir, "merge_" + System.currentTimeMillis() + ".wav").getAbsolutePath();
AudioSystem.write(mergedStream, AudioFileFormat.Type.WAVE, new File(outputPath));
mergedStream.close();
return outputPath;
if (allMP3) {
return mergeMultipleMP3Audio(filePaths);
} else {
// 对于混合格式使用WAV合并方法
List<AudioInputStream> streams = new ArrayList<>();
List<byte[]> audioDataList = new ArrayList<>();
AudioFormat baseFormat = null;
try {
// 读取所有音频文件
for (String filePath : filePaths) {
AudioInputStream stream = AudioSystem.getAudioInputStream(new File(filePath));
AudioFormat format = stream.getFormat();
if (baseFormat == null) {
baseFormat = format;
} else if (!baseFormat.matches(format)) {
throw new IllegalArgumentException("Audio formats are not compatible, cannot merge");
}
streams.add(stream);
audioDataList.add(stream.readAllBytes());
}
// 计算总数据长度
int totalLength = 0;
for (byte[] data : audioDataList) {
totalLength += data.length;
}
// 合并音频数据
byte[] mergedData = new byte[totalLength];
int currentPosition = 0;
for (byte[] data : audioDataList) {
System.arraycopy(data, 0, mergedData, currentPosition, data.length);
currentPosition += data.length;
}
// 创建新的音频流
if (baseFormat == null) {
throw new IOException("Unable to determine audio format, merge failed");
}
ByteArrayInputStream bais = new ByteArrayInputStream(mergedData);
AudioInputStream mergedStream = new AudioInputStream(bais, baseFormat,
mergedData.length / baseFormat.getFrameSize());
// 保存合并后的文件
File tempDir = new File(TEMP_DIR);
if (!tempDir.isAbsolute()) {
tempDir = new File(System.getProperty("user.dir"), TEMP_DIR);
}
String outputPath = new File(tempDir, "merge_multiple_" + System.currentTimeMillis() + ".wav").getAbsolutePath();
AudioSystem.write(mergedStream, AudioFileFormat.Type.WAVE, new File(outputPath));
mergedStream.close();
return outputPath;
} finally {
// 关闭所有流
for (AudioInputStream stream : streams) {
try {
stream.close();
} catch (IOException e) {
// 忽略关闭异常
}
}
}
}
}
/**
@ -805,7 +905,7 @@ public class AudioProcessingService {
}
/**
* Get MP3 frame data
* Get MP3 frame data
*/
private byte[] getFrameData(Bitstream bitstream, Header header) throws IOException {
// Get frame data
@ -819,4 +919,83 @@ public class AudioProcessingService {
return frameData;
}
/**
* MP3
* @param filePath1 MP3
* @param filePath2 MP3
* @return MP3
*/
private String mergeMP3Audio(String filePath1, String filePath2) throws IOException {
FileInputStream fis1 = new FileInputStream(filePath1);
FileInputStream fis2 = new FileInputStream(filePath2);
byte[] data1 = fis1.readAllBytes();
byte[] data2 = fis2.readAllBytes();
fis1.close();
fis2.close();
// 合并MP3数据
byte[] mergedData = new byte[data1.length + data2.length];
System.arraycopy(data1, 0, mergedData, 0, data1.length);
System.arraycopy(data2, 0, mergedData, data1.length, data2.length);
// 保存合并后的MP3文件
File tempDir = new File(TEMP_DIR);
if (!tempDir.isAbsolute()) {
tempDir = new File(System.getProperty("user.dir"), TEMP_DIR);
}
String outputPath = new File(tempDir, "merge_mp3_" + System.currentTimeMillis() + ".mp3").getAbsolutePath();
FileOutputStream fos = new FileOutputStream(outputPath);
fos.write(mergedData);
fos.close();
return outputPath;
}
/**
* MP3
* @param filePaths MP3
* @return MP3
*/
private String mergeMultipleMP3Audio(List<String> filePaths) throws IOException {
List<byte[]> audioDataList = new ArrayList<>();
// 读取所有MP3文件数据
for (String filePath : filePaths) {
FileInputStream fis = new FileInputStream(filePath);
byte[] data = fis.readAllBytes();
fis.close();
audioDataList.add(data);
}
// 计算总数据长度
int totalLength = 0;
for (byte[] data : audioDataList) {
totalLength += data.length;
}
// 合并MP3数据
byte[] mergedData = new byte[totalLength];
int currentPosition = 0;
for (byte[] data : audioDataList) {
System.arraycopy(data, 0, mergedData, currentPosition, data.length);
currentPosition += data.length;
}
// 保存合并后的MP3文件
File tempDir = new File(TEMP_DIR);
if (!tempDir.isAbsolute()) {
tempDir = new File(System.getProperty("user.dir"), TEMP_DIR);
}
String outputPath = new File(tempDir, "merge_multiple_mp3_" + System.currentTimeMillis() + ".mp3").getAbsolutePath();
FileOutputStream fos = new FileOutputStream(outputPath);
fos.write(mergedData);
fos.close();
return outputPath;
}
}
Loading…
Cancel
Save