在平时开发过程中可能遇到需要上传相关音频文件到后台,并且计算各种音频文件的时长,因此对三种音频格式(mp3、amr和wav)的时长计算进行了简单的调研,现将相关实现记录一下,也方便需要的朋友查看。
(1)mp3文件时长计算
在计算mp3文件时长需要依赖一个外部jar包,如下,如果你使用的是maven构建,那么在pom.xml中引入如下依赖:
<dependency>
<groupId>org</groupId>
<artifactId>jaudiotagger</artifactId>
<version>2.0.3</version>
</dependency>
下面是使用示例代码Mp3FileTimeLengthSample.java:
package com.majing.learning.fileuploadclient.filetime;
import java.io.File;
import org.jaudiotagger.audio.AudioFileIO;
import org.jaudiotagger.audio.mp3.MP3AudioHeader;
import org.jaudiotagger.audio.mp3.MP3File;
public class Mp3FileTimeLengthSample {
public static int getDuration(String position) {
int length = 0;
try {
MP3File mp3File = (MP3File) AudioFileIO.read(new File(position));
MP3AudioHeader audioHeader = (MP3AudioHeader) mp3File.getAudioHeader();
// length = audioHeader.getPreciseTrackLength();
length = audioHeader.getTrackLength();//单位为秒
audioHeader.getBitRate();
audioHeader.getSampleRate();
audioHeader.getChannels();
audioHeader.getPreciseTrackLength();
return length;
} catch (Exception e) {
e.printStackTrace();
}
return length;
}
public static void main(String[] args) {
String position = "D:/tmp/fileuploaddir/咱们结婚吧.mp3";
long start = System.currentTimeMillis();
System.out.println(getDuration(position));
long end = System.currentTimeMillis();
System.out.println("计算共用时:"+(end-start));
}
}
(2)amr文件时长计算
下面是计算amr文件的时长方式,通过网络咨询查询来的,通过测试好像没什么问题,有问题的话评论区反馈一下哈。
package com.majing.learning.fileuploadclient.filetime;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
public class AmrFileTimeLengthSample {
public static long getAmrDuration(File file) throws IOException {
long duration = -1;
int[] packedSize = { 12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0 };
RandomAccessFile randomAccessFile = null;
try {
randomAccessFile = new RandomAccessFile(file, "rw");
long length = file.length();//文件的长度
int pos = 6;//设置初始位置
int frameCount = 0;//初始帧数
int packedPos = -1;
byte[] datas = new byte[1];//初始数据值
while (pos <= length) {
randomAccessFile.seek(pos);
if (randomAccessFile.read(datas, 0, 1) != 1) {
duration = length > 0 ? ((length - 6) / 650) : 0;
break;
}
packedPos = (datas[0] >> 3) & 0x0F;
pos += packedSize[packedPos] + 1;
frameCount++;
}
duration += frameCount * 20;//帧数*20
} finally {
if (randomAccessFile != null) {
randomAccessFile.close();
}
}
return duration;
}
public static void main(String[] args) throws IOException {
System.out.println(getAmrDuration(new File("D:/tmp/fileuploaddir/咱们结婚吧.amr")));
}
}
(3)wav文件时长计算
对于wav格式的音频文件,这里列举两种方式,一种是已知各种参数(如采样率,通道数等),还有一种就是不知道,直接使用JDK中的相关工具类。
下面给出相关测试用例WavFileTimeLengthSample.java:
package com.majing.learning.fileuploadclient.filetime;
import java.io.File;
import java.net.URL;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
public class WavFileTimeLengthSample {
/**
* 获取音频文件时长
*
* @param wavFilePath wav文件路径,支持本地和网络HTTP路径
* @return 时长/豪秒,可 /1000D 得到秒
* @throws Exception
*/
public static long getMillisecondLengthForWav(String wavFilePath) throws Exception {
if (wavFilePath == null || wavFilePath.length() == 0) {
return 0;
}
String bath = wavFilePath.split(":")[0];
Clip clip = AudioSystem.getClip();
AudioInputStream ais;
if ("http".equals(bath.toLowerCase())||"https".equals(bath.toLowerCase())) {
ais = AudioSystem.getAudioInputStream(new URL(wavFilePath));
} else {
ais = AudioSystem.getAudioInputStream(new File(wavFilePath));
}
clip.open(ais);
return clip.getMicrosecondLength()/1000;
}
public static long getMillisecondLengthByCalculate(long fileByteLength, long sampleFreq, long sampleBits, int channel){
return (fileByteLength*8*1000)/(sampleFreq*sampleBits*channel);
}
public static void main(String[] args) throws Exception {
//对于其他方式转换的wav文件,客户端APP录制的wav文件都可以正常计算
String wavUrl = "D:/tmp/fileuploaddir/咱们结婚吧.wav";
long microsecondLengthForWav = getMillisecondLengthForWav(wavUrl);
System.out.println("通过JDK自带工具类: "+microsecondLengthForWav);
//只能对于该种采样率、比特率的文件才能计算准确
File file = new File(wavUrl);
long microsecondLengthByCalculate = getMillisecondLengthByCalculate(file.length(), 16000, 16, 1);
System.out.println("通过公式计算: "+microsecondLengthByCalculate);
}
}
至此,三种音频格式的时长计算便基本可以获取到了,如果实现上有问题欢迎留言反馈,对于其他格式的音频文件时长获取也欢迎反馈说明,谢谢。