设为首页收藏本站
网站公告 | 这是第一条公告
     

 找回密码
 立即注册
缓存时间22 现在时间22 缓存数据 关关难过关关过,夜夜难熬夜夜熬。万般皆苦,悲欢自渡,他人难悟。晚安!

关关难过关关过,夜夜难熬夜夜熬。万般皆苦,悲欢自渡,他人难悟。晚安!

查看: 725|回复: 0

Java音频处理之音频流转音频文件和获取音频播放时长详解

[复制链接]

  离线 

TA的专栏

  • 打卡等级:常驻代表
  • 打卡总天数:35
  • 打卡月天数:1
  • 打卡总奖励:445
  • 最近打卡:2025-12-09 09:00:23
等级头衔

等級:晓枫资讯-上等兵

在线时间
0 小时

积分成就
威望
0
贡献
419
主题
377
精华
0
金钱
1667
积分
866
注册时间
2023-2-10
最后登录
2025-12-9

发表于 2025-8-27 20:59:40 | 显示全部楼层 |阅读模式

1.背景

最近对接了一款智能手表,手环,可以应用与老人与儿童监控,环卫工人监控,农场畜牧业监控,宠物监控等,其中用到了音频传输,通过平台下发语音包,发送远程命令录制当前设备音频并将音频分包传输到服务器上生成音频文件等。其中关于音频的一些简单操作封装成了工具包。

2.音频工具包

引入jaudiotagger,用来获取MP3格式的音频时长。

  1. <dependency>
  2. <groupId>org</groupId>
  3. <artifactId>jaudiotagger</artifactId>
  4. <version>2.0.1</version>
  5. </dependency>
复制代码

工具包代码:AudioUtils

  1. package com.xxxx.common.utils;
  2. import lombok.extern.slf4j.Slf4j;
  3. import org.jaudiotagger.audio.AudioFileIO;
  4. import org.jaudiotagger.audio.mp3.MP3AudioHeader;
  5. import org.jaudiotagger.audio.mp3.MP3File;
  6. import java.io.File;
  7. import java.io.FileOutputStream;
  8. import java.io.IOException;
  9. import java.io.RandomAccessFile;
  10. /**
  11. * 音频处理工具类
  12. * @author Mr.Li
  13. * @date 2023-10-26
  14. */
  15. @Slf4j
  16. public class AudioUtils {
  17. /**
  18. * 二进制流转音频文件
  19. * @param binaryData
  20. * @param outputFilePath
  21. * @throws IOException
  22. */
  23. public static boolean convertBinaryToAudio(byte[] binaryData, String outputFilePath) throws IOException {
  24. FileOutputStream outputStream = null;
  25. try {
  26. outputStream = new FileOutputStream(outputFilePath);
  27. outputStream.write(binaryData);
  28. return true;
  29. }catch (Exception e){
  30. log.error("convertBinaryToAudio:outputFilePath:{}",outputFilePath,e);
  31. return false;
  32. }finally {
  33. if (outputStream != null) {
  34. outputStream.close();
  35. }
  36. }
  37. }
  38. /**
  39. * 获取AMR格式音频长度
  40. * @param file
  41. * @return
  42. * @throws IOException
  43. */
  44. public static int getAmrDuration(File file) throws IOException {
  45. long duration = -1;
  46. int[] packedSize = { 12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0,
  47. 0, 0 };
  48. RandomAccessFile randomAccessFile = null;
  49. try {
  50. randomAccessFile = new RandomAccessFile(file, "rw");
  51. // 文件的长度
  52. long length = file.length();
  53. // 设置初始位置
  54. int pos = 6;
  55. // 初始帧数
  56. int frameCount = 0;
  57. int packedPos = -1;
  58. // 初始数据值
  59. byte[] datas = new byte[1];
  60. while (pos <= length) {
  61. randomAccessFile.seek(pos);
  62. if (randomAccessFile.read(datas, 0, 1) != 1) {
  63. duration = length > 0 ? ((length - 6) / 650) : 0;
  64. break;
  65. }
  66. packedPos = (datas[0] >> 3) & 0x0F;
  67. pos += packedSize[packedPos] + 1;
  68. frameCount++;
  69. }
  70. // 帧数*20
  71. duration += frameCount * 20;
  72. } catch (Exception e){
  73. log.error("getAmrDuration:",e);
  74. }finally {
  75. if (randomAccessFile != null) {
  76. randomAccessFile.close();
  77. }
  78. }
  79. return (int)((duration/1000)+1);
  80. }
  81. /**
  82. * 计算Mp3音频格式时长
  83. * @param mp3File
  84. * @return
  85. */
  86. public static int getMp3Duration(File mp3File) {
  87. try {
  88. MP3File f = (MP3File) AudioFileIO.read(mp3File);
  89. MP3AudioHeader audioHeader = (MP3AudioHeader) f.getAudioHeader();
  90. return audioHeader.getTrackLength();
  91. } catch (Exception e) {
  92. log.error("getMp3Duration:",e);
  93. return 0;
  94. }
  95. }
  96. public static void main(String[] args) throws IOException {
  97. String path="C:\\Users\\MyPC\\Desktop\\卡布奇诺-王逗逗.mp3";
  98. int duration = getMp3Duration(new File(path));
  99. System.out.println(duration);
  100. }
  101. }
复制代码

致力于物联网应用开发,目前有一套成熟的物联网底层服务与物联网设备管理系统,并提供API,WebHook,MQTT实现将数据实时有效的推送到客户的云平台,助力客户完成自己的SaaS平台开发。

3.知识延展

java 获取MP3文件播放时长

方法一:

代码简单:

  1. public static int getMp3TrackLength(File mp3File) {
  2. try {
  3. MP3File f = (MP3File) AudioFileIO.read(mp3File);
  4. MP3AudioHeader audioHeader = (MP3AudioHeader)f.getAudioHeader();
  5. return audioHeader.getTrackLength();
  6. } catch(Exception e) {
  7. return -1;
  8. }
  9. }
复制代码

maven 依赖包:

  1. <dependency>
  2. <groupId>org</groupId>
  3. <artifactId>jaudiotagger</artifactId>
  4. <version>2.0.1</version>
  5. </dependency>
复制代码

方法二:

获取网络资源音频时长:

这种方法是获取文件字节大小然后在用公式自己算的

  1. BufferedInputStream bis = null;
  2. Bitstream bitstream = null;
  3. try {
  4. URL url = new URL("http://*********08.mp3");
  5. HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
  6. urlConn.connect();
  7. //此url响应头中包含"Accept-Length"为字节数大小
  8. String headerField = urlConn.getHeaderField("Accept-Length");
  9. bis = new BufferedInputStream(urlConn.getInputStream());
  10. bitstream = new Bitstream(bis);
  11. Header header = bitstream.readFrame();
  12. int bitrate = header.bitrate();
  13. //根据文件大小计算 字节数*8/码率/1000(毫秒值转秒)
  14. int timeLong = Integer.parseInt(headerField)*8/bitrate;
  15. System.out.println(timeLong);
  16. } catch (Exception e) {
  17. e.printStackTrace();
  18. }finally {
  19. if (bis!=null){
  20. try {
  21. bis.close();
  22. } catch (IOException e) {
  23. e.printStackTrace();
  24. }
  25. }
  26. if (bitstream!=null){
  27. try {
  28. bitstream.close();
  29. } catch (BitstreamException e) {
  30. e.printStackTrace();
  31. }
  32. }
  33. }
复制代码

BitStream的包在这里,maven引入

  1. <dependency>
  2. <groupId>com.badlogicgames.jlayer</groupId>
  3. <artifactId>jlayer</artifactId>
  4. <version>1.0.2-gdx</version>
  5. </dependency>
复制代码

方法三:

根据content length获取网络音频时长,有误差:

  1. public static void main(String[] args) {
  2. try {
  3. long startTime=System.currentTimeMillis(); //获取开始时间
  4. URL urlfile = new URL("http://resource.puxinwangxiao.com/b4ef18fe62948ab2528127c8c1357ddd.mp3");
  5. //File file = new File("C:\\music\\test2.mp3");
  6. //URL urlfile = file.toURI().toURL();
  7. URLConnection con = urlfile.openConnection();
  8. int b = con.getContentLength();// 得到音乐文件的总长度
  9. BufferedInputStream bis = new BufferedInputStream(con.getInputStream());
  10. Bitstream bt = new Bitstream(bis);
  11. Header h = bt.readFrame();
  12. int time = (int) h.total_ms(b);
  13. System.out.println(time / 1000);
  14. long endTime1=System.currentTimeMillis(); //获取结束时间
  15. System.out.println("所需时间: "+(endTime1-startTime)+"ms");
  16. }catch (Exception e ){
  17. System.out.println(e.getMessage());
  18. }
  19. }
复制代码

到此这篇关于Java音频处理之音频流转音频文件和获取音频播放时长详解的文章就介绍到这了,更多相关Java音频处理内容请搜索晓枫资讯以前的文章或继续浏览下面的相关文章希望大家以后多多支持晓枫资讯!


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
晓枫资讯-科技资讯社区-免责声明
免责声明:以上内容为本网站转自其它媒体,相关信息仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同其观点或证实其内容的真实性。
      1、注册用户在本社区发表、转载的任何作品仅代表其个人观点,不代表本社区认同其观点。
      2、管理员及版主有权在不事先通知或不经作者准许的情况下删除其在本社区所发表的文章。
      3、本社区的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,举报反馈:点击这里给我发消息进行删除处理。
      4、本社区一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
      5、以上声明内容的最终解释权归《晓枫资讯-科技资讯社区》所有。
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~
严禁发布广告,淫秽、色情、赌博、暴力、凶杀、恐怖、间谍及其他违反国家法律法规的内容。!晓枫资讯-社区
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|晓枫资讯--科技资讯社区 本站已运行

CopyRight © 2022-2025 晓枫资讯--科技资讯社区 ( BBS.yzwlo.com ) . All Rights Reserved .

晓枫资讯--科技资讯社区

本站内容由用户自主分享和转载自互联网,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。

如有侵权、违反国家法律政策行为,请联系我们,我们会第一时间及时清除和处理! 举报反馈邮箱:点击这里给我发消息

Powered by Discuz! X3.5

快速回复 返回顶部 返回列表