问10系统需要安装 FFMPEG
win10环境安装
下载 FFmpeg:
访问官方构建:https://www.gyan.dev/ffmpeg/builds/
下载 "ffmpeg-git-full.7z"(最新完整版)
解压文件:
使用 7-Zip 解压到你想安装的目录,例如 C:\ffmpeg
设置环境变量:
右键"此电脑" → 属性 → 高级系统设置 → 环境变量
在"系统变量"中找到 Path → 编辑 → 新建
添加 FFmpeg 的 bin 目录路径,例如:C:\ffmpeg\bin
点击确定保存所有更改
复制命令行到指定路径,不然运行时报错
try {
File javeDir = new File(System.getProperty("user.home") + "/AppData/Local/Temp/jave");
javeDir.mkdirs();
File target = new File(javeDir, "ffmpeg-amd64-3.3.1.exe");
if (!target.exists()) {
Files.copy(
Paths.get("D:\\tool\\ffmpeg\\bin\\ffmpeg.exe"),
target.toPath(),
StandardCopyOption.REPLACE_EXISTING
);
}
} catch (IOException e) {
e.printStackTrace();
}
转码服务
package com.race.APPControl.service;
import com.race.APPControl.service.impl.LocalSysFileServiceImpl;
import com.race.system.api.domain.SysFile;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import ws.schild.jave.*;
import ws.schild.jave.encode.AudioAttributes;
import ws.schild.jave.encode.EncodingAttributes;
import ws.schild.jave.process.ProcessLocator;
import ws.schild.jave.process.ffmpeg.DefaultFFMPEGLocator;
import java.io.*;
import java.net.URL;
import java.nio.file.Files;
import java.util.Base64;
@Service
@Slf4j
public class WavToMp3Service {
@Autowired
private LocalSysFileServiceImpl localSysFileService;
// 自定义FFMPEG定位器
private static final ProcessLocator CUSTOM_FFMPEG_LOCATOR = new DefaultFFMPEGLocator() {
public String getExecutablePath() {
return "D:\\tool\\ffmpeg\\bin\\ffmpeg.exe";
}
};
public SysFile convertAndUpload(String base64Wav) {
try {
byte[] wavBytes = decodeBase64(base64Wav);
byte[] mp3Bytes = convertWavToMp3(wavBytes);
MultipartFile mp3File = createMultipartFile(mp3Bytes);
String fileUrl = localSysFileService.uploadFile(mp3File);
SysFile result = new SysFile();
result.setName(fileUrl);
return result;
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("WAV to MP3 conversion and upload failed", e);
}
}
private byte[] decodeBase64(String base64) {
String encodedData = base64.contains(",")
? base64.split(",")[1]
: base64;
return Base64.getDecoder().decode(encodedData);
}
private byte[] convertWavToMp3(byte[] wavBytes) throws IOException {
File tempWav = File.createTempFile("temp", ".wav");
File tempMp3 = File.createTempFile("temp", ".mp3");
try {
Files.write(tempWav.toPath(), wavBytes);
// 使用自定义的FFMPEG定位器创建编码器
Encoder encoder = new Encoder(CUSTOM_FFMPEG_LOCATOR);
AudioAttributes audio = new AudioAttributes();
audio.setCodec("libmp3lame");
audio.setBitRate(128000);
audio.setChannels(2);
audio.setSamplingRate(44100);
EncodingAttributes attrs = new EncodingAttributes();
attrs.setOutputFormat("mp3");
attrs.setAudioAttributes(audio);
encoder.encode(new MultimediaObject(tempWav), tempMp3, attrs);
return Files.readAllBytes(tempMp3.toPath());
} catch (EncoderException e) {
throw new IOException("音频转换失败", e);
} finally {
tempWav.delete();
tempMp3.delete();
}
}
private MultipartFile createMultipartFile(byte[] fileContent) {
return new MultipartFile() {
@Override
public String getName() {
return "audio.mp3";
}
@Override
public String getOriginalFilename() {
return "audio.mp3";
}
@Override
public String getContentType() {
return "audio/mpeg";
}
@Override
public boolean isEmpty() {
return fileContent == null || fileContent.length == 0;
}
@Override
public long getSize() {
return fileContent.length;
}
@Override
public byte[] getBytes() throws IOException {
return fileContent;
}
@Override
public InputStream getInputStream() throws IOException {
return new ByteArrayInputStream(fileContent);
}
@Override
public void transferTo(File dest) throws IOException, IllegalStateException {
Files.write(dest.toPath(), fileContent);
}
// 修正这里 - 使用正确的Resource类型
@Override
public org.springframework.core.io.Resource getResource() {
return new ByteArrayResource(fileContent) {
@Override
public String getFilename() {
return getOriginalFilename();
}
@Override
public URL getURL() throws IOException {
return null; // 明确返回null表示无URL
}
};
}
};
}
}
文件上传service
package com.race.APPControl.service.impl;
import com.race.APPControl.common.FileUploadUtils;
import com.race.APPControl.service.ISysFileService;
import com.race.system.api.domain.SysFile;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
/**
* 本地文件存储
*
* @author race
*/
@Slf4j
@Primary
@Service
public class LocalSysFileServiceImpl implements ISysFileService
{
/**
* 资源映射路径 前缀
*/
@Value("${file.prefix}")
public String localFilePrefix;
//private static final Logger log = LoggerFactory.getLogger(SysFileController.class);
/**
* 域名或本机访问地址
*/
@Value("${file.domain}")
public String domain;
/**
* 上传文件存储在本地的根路径
*/
@Value("${file.path}")
private String localFilePath;
@Value("${file.pathSJY}")
private String localFilePathSJY;
@Value("${file.uploadFilePath}")
private String uploadFilePath;
/** 偏移纬度 */
@Value("${file.uploadFileUrl}")
private String uploadFileUrl;
/**
* 本地文件上传接口
*
* @param file 上传的文件
* @return 访问地址
* @throws Exception
*/
@Override
public String uploadFile(MultipartFile file) throws Exception
{
String name = FileUploadUtils.upload(localFilePath, file);
String url = domain + localFilePrefix + name;
return url;
}
/**
* 本地文件上传接口
*
* @param file 上传的文件
* @return 访问地址
* @throws Exception
*/
@Override
public SysFile uploadSJY(MultipartFile file) throws Exception
{
SysFile filess= new SysFile();
String name = FileUploadUtils.uploadSJY(localFilePathSJY, file);
filess.setName(localFilePathSJY+name);
// String url = domain + localFilePrefix + name;
return filess;
}
@Override
public SysFile uploadBase64(String base64) {
log.info("uploadFilePath"+uploadFilePath);
log.info("uploadFileUrl"+uploadFileUrl);
// log.info("图片图片"+base64);
return FileUploadUtils.uploadBase64(base64,uploadFilePath,uploadFileUrl);
}
}