Java音频处理之音频流转音频文件和获取音频播放时长详解
作者:大鱼>
这篇文章主要为大家详细介绍了如何使用Java实现音频流转音频文件和获取音频播放时长功能,文中的示例代码简洁易懂,有需要的小伙伴可以了解下
1.背景
最近对接了一款智能手表,手环,可以应用与老人与儿童监控,环卫工人监控,农场畜牧业监控,宠物监控等,其中用到了音频传输,通过平台下发语音包,发送远程命令录制当前设备音频并将音频分包传输到服务器上生成音频文件等。其中关于音频的一些简单操作封装成了工具包。
2.音频工具包
引入jaudiotagger,用来获取MP3格式的音频时长。
<dependency> <groupId>org</groupId> <artifactId>jaudiotagger</artifactId> <version>2.0.1</version> </dependency>
工具包代码:AudioUtils
package com.xxxx.common.utils; import lombok.extern.slf4j.Slf4j; import org.jaudiotagger.audio.AudioFileIO; import org.jaudiotagger.audio.mp3.MP3AudioHeader; import org.jaudiotagger.audio.mp3.MP3File; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.RandomAccessFile; /** * 音频处理工具类 * @author Mr.Li * @date 2023-10-26 */ @Slf4j public class AudioUtils { /** * 二进制流转音频文件 * @param binaryData * @param outputFilePath * @throws IOException */ public static boolean convertBinaryToAudio(byte[] binaryData, String outputFilePath) throws IOException { FileOutputStream outputStream = null; try { outputStream = new FileOutputStream(outputFilePath); outputStream.write(binaryData); return true; }catch (Exception e){ log.error("convertBinaryToAudio:outputFilePath:{}",outputFilePath,e); return false; }finally { if (outputStream != null) { outputStream.close(); } } } /** * 获取AMR格式音频长度 * @param file * @return * @throws IOException */ public static int 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++; } // 帧数*20 duration += frameCount * 20; } catch (Exception e){ log.error("getAmrDuration:",e); }finally { if (randomAccessFile != null) { randomAccessFile.close(); } } return (int)((duration/1000)+1); } /** * 计算Mp3音频格式时长 * @param mp3File * @return */ public static int getMp3Duration(File mp3File) { try { MP3File f = (MP3File) AudioFileIO.read(mp3File); MP3AudioHeader audioHeader = (MP3AudioHeader) f.getAudioHeader(); return audioHeader.getTrackLength(); } catch (Exception e) { log.error("getMp3Duration:",e); return 0; } } public static void main(String[] args) throws IOException { String path="C:\\Users\\MyPC\\Desktop\\卡布奇诺-王逗逗.mp3"; int duration = getMp3Duration(new File(path)); System.out.println(duration); } }
致力于物联网应用开发,目前有一套成熟的物联网底层服务与物联网设备管理系统,并提供API,WebHook,MQTT实现将数据实时有效的推送到客户的云平台,助力客户完成自己的SaaS平台开发。
3.知识延展
java 获取MP3文件播放时长
方法一:
代码简单:
public static int getMp3TrackLength(File mp3File) { try { MP3File f = (MP3File) AudioFileIO.read(mp3File); MP3AudioHeader audioHeader = (MP3AudioHeader)f.getAudioHeader(); return audioHeader.getTrackLength(); } catch(Exception e) { return -1; } }
maven 依赖包:
<dependency> <groupId>org</groupId> <artifactId>jaudiotagger</artifactId> <version>2.0.1</version> </dependency>
方法二:
获取网络资源音频时长:
这种方法是获取文件字节大小然后在用公式自己算的
BufferedInputStream bis = null; Bitstream bitstream = null; try { URL url = new URL("http://*********08.mp3"); HttpURLConnection urlConn = (HttpURLConnection) url.openConnection(); urlConn.connect(); //此url响应头中包含"Accept-Length"为字节数大小 String headerField = urlConn.getHeaderField("Accept-Length"); bis = new BufferedInputStream(urlConn.getInputStream()); bitstream = new Bitstream(bis); Header header = bitstream.readFrame(); int bitrate = header.bitrate(); //根据文件大小计算 字节数*8/码率/1000(毫秒值转秒) int timeLong = Integer.parseInt(headerField)*8/bitrate; System.out.println(timeLong); } catch (Exception e) { e.printStackTrace(); }finally { if (bis!=null){ try { bis.close(); } catch (IOException e) { e.printStackTrace(); } } if (bitstream!=null){ try { bitstream.close(); } catch (BitstreamException e) { e.printStackTrace(); } } }
BitStream的包在这里,maven引入
<dependency> <groupId>com.badlogicgames.jlayer</groupId> <artifactId>jlayer</artifactId> <version>1.0.2-gdx</version> </dependency>
方法三:
根据content length获取网络音频时长,有误差:
public static void main(String[] args) { try { long startTime=System.currentTimeMillis(); //获取开始时间 URL urlfile = new URL("http://resource.puxinwangxiao.com/b4ef18fe62948ab2528127c8c1357ddd.mp3"); //File file = new File("C:\\music\\test2.mp3"); //URL urlfile = file.toURI().toURL(); URLConnection con = urlfile.openConnection(); int b = con.getContentLength();// 得到音乐文件的总长度 BufferedInputStream bis = new BufferedInputStream(con.getInputStream()); Bitstream bt = new Bitstream(bis); Header h = bt.readFrame(); int time = (int) h.total_ms(b); System.out.println(time / 1000); long endTime1=System.currentTimeMillis(); //获取结束时间 System.out.println("所需时间: "+(endTime1-startTime)+"ms"); }catch (Exception e ){ System.out.println(e.getMessage()); } }
到此这篇关于Java音频处理之音频流转音频文件和获取音频播放时长详解的文章就介绍到这了,更多相关Java音频处理内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!