添加依赖
<!-- MP3音频处理 -->
<dependency>
<groupId>javazoom</groupId>
<artifactId>jlayer</artifactId>
<version>1.0.1</version>
</dependency>
工具类如下
public class Mp3DurationUtil {
/**
* 计算 MP3 字节数组的时长(秒)
*/
public static double getDuration(byte[] mp3Bytes) throws Exception {
try (InputStream is = new ByteArrayInputStream(mp3Bytes)) {
return getDuration(is);
}
}
/**
* 计算 MP3 输入流的时长(秒)
*/
public static double getDuration(InputStream is) throws Exception {
Bitstream bitstream = new Bitstream(is);
Header header;
double ms = 0;
try {
while ((header = bitstream.readFrame()) != null) {
ms += header.ms_per_frame(); // 每帧时长(毫秒)
bitstream.closeFrame();
}
} finally {
bitstream.close();
}
return ms / 1000.0; // 转成秒
}
}
调用方式
/**
* 计算MP3文件时长
* 使用AudioSystem获取更准确的音频时长
*
* @param fileBytes MP3文件字节数组
* @return 时长(秒)
*/
private int calculateMp3Duration(byte[] fileBytes) {
try {
return (int) Mp3DurationUtil.getDuration(fileBytes);
} catch (Exception e) {
e.printStackTrace();
}
return calculateMp3DurationFallback(fileBytes);
}
备用方法
/**
* 备用的MP3时长计算方法
* 通过解析MP3帧头信息获取时长
*
* @param fileBytes MP3文件字节数组
* @return 时长(秒)
*/
private int calculateMp3DurationFallback(byte[] fileBytes) {
try {
// 查找MP3帧头并解析比特率
int totalFrames = 0;
int bitrate = 128000; // 默认比特率128kbps
int sampleRate = 44100; // 默认采样率44.1kHz
for (int i = 0; i < fileBytes.length - 4; i++) {
// 查找MP3帧同步字 (0xFF 0xFB 或 0xFF 0xFA)
if ((fileBytes[i] & 0xFF) == 0xFF &&
((fileBytes[i + 1] & 0xE0) == 0xE0)) {
// 解析帧头获取比特率和采样率
int frameHeader = ((fileBytes[i] & 0xFF) << 24) |
((fileBytes[i + 1] & 0xFF) << 16) |
((fileBytes[i + 2] & 0xFF) << 8) |
(fileBytes[i + 3] & 0xFF);
// 提取比特率索引 (位4-7)
int bitrateIndex = (frameHeader >> 12) & 0x0F;
// 提取采样率索引 (位10-11)
int sampleRateIndex = (frameHeader >> 10) & 0x03;
// 设置比特率和采样率(简化版本,只处理常用值)
if (bitrateIndex > 0 && bitrateIndex <= 14) {
bitrate = getBitrateFromIndex(bitrateIndex);
}
if (sampleRateIndex <= 2) {
sampleRate = getSampleRateFromIndex(sampleRateIndex);
}
totalFrames++;
// 跳过帧数据,避免重复计算
i += Math.max(1151, (bitrate * 144) / (sampleRate / 1000));
}
}
if (totalFrames > 0) {
// 计算时长:总帧数 * 每帧样本数 / 采样率
double durationSeconds = (totalFrames * 1152.0) / sampleRate;
log.info("备用方法计算时长: {} 秒 (帧数: {}, 采样率: {})", durationSeconds, totalFrames, sampleRate);
return Math.max(1, (int) Math.round(durationSeconds));
}
// 最后备用:使用文件大小估算
double estimatedDuration = (fileBytes.length * 8.0) / bitrate;
log.info("使用文件大小估算时长: {} 秒", estimatedDuration);
return Math.max(1, (int) Math.round(estimatedDuration));
} catch (Exception e) {
log.error("备用方法计算MP3时长失败", e);
// 返回默认值
return 0;
}
}
/**
* 根据比特率索引获取比特率
*/
private int getBitrateFromIndex(int index) {
// MP3比特率表 (kbps)
int[] bitrates = {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320};
if (index < bitrates.length) {
return bitrates[index] * 1000; // 转换为bps
}
return 128000; // 默认128kbps
}
/**
* 根据采样率索引获取采样率
*/
private int getSampleRateFromIndex(int index) {
// MP3采样率表 (Hz)
int[] sampleRates = {44100, 48000, 32000};
if (index < sampleRates.length) {
return sampleRates[index];
}
return 44100; // 默认44.1kHz
}
结果,可以获取准确