Java springboot 获取MP3时长

最近有一个需求  是上传 MP3音频 并且要保存时长

针对获取时长在网上找了很多方法 

1. 参考网址 : https://www.jb51.net/article/134203.htm

这也是网上说的最多的方法

public void method2() {
        File file = new File("D:\test.mp3");
        try {
            MP3File f = (MP3File)AudioFileIO.read(file);
            MP3AudioHeader audioHeader = (MP3AudioHeader)f.getAudioHeader();
            System.out.println(audioHeader.getTrackLength());    
        } catch(Exception e) {
            e.printStackTrace();
        }
}

结果 : 我测试的这个test.mp3 播放时显示的时长是164秒   这个方法测试出来居然只有 600+秒????

2. 使用javasound api:参考 : https://blog.csdn.net/suifengerye/article/details/97113146

public void method1() {
        File file = new File("D:\test.mp3");
long total = 0;

try {
AudioFileFormat aff
= AudioSystem.getAudioFileFormat(file);
Map props
= aff.properties();

if (props.containsKey("duration")) {
total
= (long) Math.round((((Long) props.get("duration")).longValue()) / 1000);
}
System.out.println(total
/ 1000);
}
catch (Exception e) {
e.printStackTrace();
}
}

结果 同一个音频 返回的值居然是 6秒???  但我同事测试出来又是正常的

3. 然后我在晚上找到了这个  本地跑来是很完美的  没有问题

 /**
     * 获取播放时长
     *
     * @param file
     * @return
     */
    public Integer getDuration(File file) {
        Clip clip = null;
        log.info("开始获取MP3播放时长== 1 ");
        try {
            clip = AudioSystem.getClip();
        } catch (LineUnavailableException e) {
            log.info("开始获取MP3播放时长异常 1" +e.getMessage());
            e.printStackTrace();
        }
        AudioInputStream ais = null;
        log.info("开始获取MP3播放时长== 2");
        try {
            ais = AudioSystem.getAudioInputStream(file);
        } catch (UnsupportedAudioFileException e) {
            e.printStackTrace();
            log.info("开始获取MP3播放时长异常 2" +e.getMessage());
        } catch (IOException e) {
            e.printStackTrace();
            log.info("开始获取MP3播放时长异常 2.1" +e.getMessage());
        }
        log.info("开始获取MP3播放时长== 3");
        try {
            clip.open(ais);
        } catch (LineUnavailableException e) {
            log.info("开始获取MP3播放时长异常 3" +e.getMessage());
            e.printStackTrace();
        } catch (IOException e) {
            log.info("开始获取MP3播放时长异常 3.1" +e.getMessage());
            e.printStackTrace();
        }
        log.info("打印获取MP3播放开始" );
        Double v = clip.getMicrosecondLength() / 1000000D;
        log.info("打印获取MP3播放时长" + v.intValue());
        return v.intValue();
    }

但是当部署到服务器使用的时候  日志打印来看  

clip = AudioSystem.getClip();
进入这个方法后就没有反应了 也没有报错
由于时间急就没有详细的查看问题 选择了再次换方法
4. 最后选择了这个 参考网址 : https://blog.csdn.net/suifengerye/article/details/97113146

经测试 本地和 服务器都没有问题

import it.sauronsoftware.jave.Encoder;
import it.sauronsoftware.jave.MultimediaInfo;
import org.apache.http.entity.ContentType;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Service;
import org.springframework.util.ResourceUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;


/**
 * describe
 *
 * @author HuangLinPan
 * @date 2021/09/17
 */
@Service
public class FileUploadUtil {




//    public static void main(String[] args) throws Exception {
//        File pdfFile = new File("D:\xiaoyan2120test.mp3");
//        long videoDuration = getVideoDuration(pdfFile);
//        System.out.println(videoDuration);
//
//    }

    /**
     * 获取时长
     *
     * @param pdfFile 音频/视频文件
     * @return
     */
    public  long getVideoDuration(File pdfFile) throws Exception {
        FileInputStream fileInputStream = null;
        try {
            fileInputStream = new FileInputStream(pdfFile);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        MultipartFile multipartFile = new MockMultipartFile(pdfFile.getName(), pdfFile.getName(),
                ContentType.APPLICATION_OCTET_STREAM.toString(), fileInputStream);
        long duration = 0;

        File source = new File(getFilePath() + multipartFile.getOriginalFilename());
        multipartFile.transferTo(source);
        Encoder encoder = new Encoder();
        MultimediaInfo info = encoder.getInfo(source);
        duration = info.getDuration();
        if (source.exists()) {
            source.delete();
        }
        return duration / 1000;




    }

    /**
     * 获取路径
     *
     * @return
     * @throws Exception
     */
    private static String getFilePath() throws Exception {
        //获取当前文件的根路径
        File path = new File(ResourceUtils.getURL("classpath:").getPath());
        if (!path.exists()) {
            path = new File("");
        }

        //盘符路径
        StringBuilder codeUrl = new StringBuilder();
        codeUrl.append(path.getAbsolutePath()).append("/static/video/");
        File file = new File(codeUrl.toString());
        if (!file.exists()) {
            file.mkdirs();
        }
        return codeUrl.toString();
    }

}

由于本项目我得到的是一个文件所在地址

所以涉及到了将File转化为MultipartFile的操作  参考: https://www.jb51.net/article/197182.htm

import java.io.File;
import java.io.FileInputStream;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.mock.web.MockMultipartFile;
import org.apache.http.entity.ContentType;
  
File pdfFile = new File("D://test.pdf");
FileInputStream fileInputStream = new FileInputStream(pdfFile);
MultipartFile multipartFile = new MockMultipartFile(pdfFile.getName(), pdfFile.getName(),
   ContentType.APPLICATION_OCTET_STREAM.toString(), fileInputStream);
<dependency>
  <groupId>org.apache.httpcomponents</groupId>
  <artifactId>httpcore</artifactId>
  <version>4.4.9</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-test</artifactId>
  <version>5.1.6.RELEASE</version>
</dependency>

总结 : 能实现的方法有很多 找到自己合适的就好

原文地址:https://www.cnblogs.com/huanglp/p/15305319.html