在java编程中,可以根据 .wav 或者PCM 字节的长度,算出音频数据播放的时长。
java
try
{
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(new File("F:\\20250926_101326.wav"));
AudioFormat format = audioInputStream.getFormat();
// 算法一
long frames = audioInputStream.getFrameLength(); // 帧总数
float frameRate = format.getFrameRate(); // 每秒播放的帧数
float durationInSeconds = frames / frameRate;
// 时长(秒)= 文件大小(字节) / 采样率 / 采样通道 / 每个采样点几个字节
// 时长(秒)= 文件字节数 ÷ (采样率 × 声道数 × 每个采样点字节数)
long fileLength = audioInputStream.getFrameLength() * format.getFrameSize();
float sampleRate = format.getSampleRate();
int channels = format.getChannels();
int bitDepth = format.getSampleSizeInBits() / 8; // 每个样本多少位
BigDecimal pcmDur1 = new BigDecimal(fileLength)
.divide(new BigDecimal(sampleRate),11, RoundingMode.HALF_UP)
.divide(new BigDecimal(channels),11,RoundingMode.HALF_UP)
.divide(new BigDecimal(bitDepth),11, RoundingMode.HALF_UP);
BigDecimal pcmDur2 = new BigDecimal(fileLength).divide(new BigDecimal(sampleRate * channels * bitDepth),11,RoundingMode.HALF_UP);
}
catch (Exception xx) {
String xvx = "";
}
实时解码AAC音频:
java
import net.sourceforge.jaad.aac.Decoder;
import net.sourceforge.jaad.aac.SampleBuffer;
import net.sourceforge.jaad.adts.ADTSDemultiplexer;
import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.sound.sampled.*;
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.ShortBuffer;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
// 播放 AAC
SourceDataLine line1 = null;
byte[] b1;
try {
final ADTSDemultiplexer adts = new ADTSDemultiplexer(new FileInputStream("F:\\kk001.aac"));
final Decoder dec = new Decoder(adts.getDecoderSpecificInfo());
final SampleBuffer buf = new SampleBuffer();
while(true) {
b1 = adts.readNextFrame();
dec.decodeFrame(b1, buf);
if(line1==null) {
final AudioFormat aufmt = new AudioFormat(buf.getSampleRate(), buf.getBitsPerSample(), buf.getChannels(), true, true);
line1 = AudioSystem.getSourceDataLine(aufmt);
line1.open();
line1.start();
}
b1 = buf.getData();
line1.write(b1, 0, b1.length);
}
} catch (Exception ex) {
if(line1!=null) {
line1.stop();
line1.close();
}
}
// PCM 转 AAC
try{
AudioFormat format = new AudioFormat(Float.valueOf(8000), 16, 1, true, false);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(outputStream, format.getChannels());
recorder.setSampleRate((int)format.getSampleRate()); // 设置采样率
recorder.setFrameRate(format.getFrameRate()); // 设置帧率与原始设备相同
recorder.setAudioCodec(avcodec.AV_CODEC_ID_PCM_S16LE);
recorder.setAudioCodecName("aac");
recorder.setFormat("adts");
recorder.start();
TargetDataLine line = (TargetDataLine) AudioSystem.getLine(new DataLine.Info(TargetDataLine.class, format));
line.open(format);
line.start();
int sampleRate = (int) format.getSampleRate();
int numChannels = format.getChannels();
byte[] buffer = new byte[sampleRate * numChannels];
int times = 0;
while (!Thread.interrupted() && times < 200) {
times++;
int nBytesRead = 0;
while (nBytesRead == 0) {
nBytesRead = line.read(buffer, 0, line.available());
}
int nSamplesRead = nBytesRead / 2;
short[] samples = new short[nSamplesRead];
ByteBuffer.wrap(buffer).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(samples);
ShortBuffer sBuff = ShortBuffer.wrap(samples, 0, nSamplesRead);
recorder.recordSamples(sampleRate, numChannels, sBuff);
}
recorder.flush();
byte[] result = outputStream.toByteArray();
Files.write(Paths.get("F:\\ddd.aac"), result, StandardOpenOption.CREATE);
String yy = "yy";
}catch (Exception ec) {
String yy = "yy";
}
// 实时接收数据并转码,存储
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try {
// 前端传PCM数据转WAV: sampleRate:采样率,sampleSizeInBits:采样位数,channels:声道数 1=单声道 2=双声道,signed:数据有无符号,bigEndian:是否为大端模式
AudioFormat pcmFormat = new AudioFormat(8000, 16, 1, true, false);
outputStream.write(pcmData);
byte[] result = outputStream.toByteArray();
Integer len2 = result.length;
if(len2 > 100 * 1364) {
// 转换成 WAV
InputStream testInputStream = new ByteArrayInputStream(result);
AudioInputStream testAudioInputStream = new AudioInputStream(testInputStream,pcmFormat, result.length );
OutputStream fos = Files.newOutputStream(Paths.get("F:\\test01.wav"), StandardOpenOption.CREATE);
AudioSystem.write(testAudioInputStream, AudioFileFormat.Type.WAVE, fos);
testAudioInputStream.close();
fos.close();
// 转换成 AAC
outputStream.reset(); // 清空数据
}
InputStream inputStream = new ByteArrayInputStream(pcmData);
AudioInputStream audioInputStream = new AudioInputStream(inputStream, pcmFormat, pcmData.length );
// 前端传 wav 格式的数据,可以直接读取
// AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(inputStream);
// 直接播放
// Clip clip = AudioSystem.getClip();
// clip.open(audioInputStream);
// clip.start();
// inputStream.close(); //关闭流
} catch (Exception ee) {
String xx = ee.getMessage();
ee.getStackTrace();
}