springboot 实现base64格式wav转码并保存

发布于:2025-03-29 ⋅ 阅读:(31) ⋅ 点赞:(0)

问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);
    }
}


网站公告

今日签到

点亮在社区的每一天
去签到