当前位置: 首页 > news >正文

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

问10系统需要安装 FFMPEG
复制命令行到指定路径,不然运行时报错

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

相关文章:

  • DeepSeek 给 API 网关上了一波热度
  • 0.雷达信号
  • 常用设计模式
  • 宝塔SSL申请Let‘s Encrypt提示“验证信息构造失败!{}“
  • 网损仪详解
  • 深度学习笔记19-YOLOv5-C3模块实现(Pytorch)
  • win10下python脚本运行缺失ccache的问题处理
  • 性能测试~
  • 线程同步——读写锁
  • MYTOOL-记事本
  • C#基础学习(八)终章 C#中的结构体
  • Mockito 全面指南:从单元测试基础到高级模拟技术
  • 前端知识点---window.location.assign() 和 window.location.href 的区别(javascript)
  • deepseek 技术的前生今世:从开源先锋到AGI探索者
  • ETL中数据转换的三种处理方式
  • 蓝耘平台API深度剖析:如何高效实现AI应用联动
  • 周报参考模板
  • IPv6 Dhcpv6 DUID
  • 指标管理+数仓引擎:衡石ChatBI端到端平台的技术架构深度解析
  • 谷歌Android闭源与鸿蒙崛起:一场关于技术主权的生态博弈
  • 创造与魔法官方网站做自己/百度网站名称及网址
  • 技术支持 沧州网站建设/seo自动工具
  • 移动端 pc网站开发/qq推广软件
  • 网站的下载链接怎么做/怎样做网站的优化、排名
  • wordpress页面位置/成都做整站优化
  • 四川 网站建设/百度关键词搜索技巧