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

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

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


http://www.kler.cn/a/613834.html

相关文章:

  • 第 4 章 | Solidity安全 权限控制漏洞全解析
  • GelSight视触觉3D显微系统在透明材料检测中的应用
  • Go红队开发—CLI框架(二)
  • 网络华为HCIA+HCIP 防火墙
  • SpringBoot第一节
  • 当编程语言有了人格
  • HCIP(TCP)(2)
  • 「HTML5+Canvas实战」星际空战游戏开发 - 纯前端实现 源码即开即用【附演示视频】
  • 2025 年中国家电零售与创新趋势解析:以旧换新国补激活需求,AI 技术渗透至研发、供应链、营销
  • 优秀的 React 入门开源项目推荐
  • 蓝桥杯第 12 天 109 国赛第一题 分考场(干了一个小时的题)
  • CSS3学习教程,从入门到精通,CSS3 定位布局页面知识点及案例代码(18)
  • C++类与对象的第一个简单的实战练习-3.24笔记
  • 20250328易灵思FPGA的烧录器FT4232_DL的驱动安装
  • Citus源码(1)分布式表行为测试
  • 【Mac】npm error Error: EACCES: permission denied, mkdir‘/Users/...
  • 第十三届蓝桥杯国赛电子类单片机学习记录(客观题)
  • HCIP笔记整理
  • 2025年春招-Linux面经
  • 从零开始跑通3DGS教程:(一)数据(采集)