JT808,JT1078协议,Java获取音频数据播放时长
在java编程中,可以根据 .wav 或者PCM 字节的长度,算出音频数据播放的时长。
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音频:
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;// 播放 AACSourceDataLine 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 转 AACtry{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) {// 转换成 WAVInputStream 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();// 转换成 AACoutputStream.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();}