首页 > 编程语言 >Java 音频处理,音频流转音频文件,获取音频播放时长

Java 音频处理,音频流转音频文件,获取音频播放时长

时间:2023-10-28 10:05:18浏览次数:35  
标签:outputStream Java int 音频 音频文件 return IOException import


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平台开发。


标签:outputStream,Java,int,音频,音频文件,return,IOException,import
From: https://blog.51cto.com/u_12846753/8065016

相关文章

  • 你知道Java21中的顺序集合吗?
    大家好,我是老七,点个关注吧,将持续更新更多精彩内容!在Java21中,处理集合的方式得到了改进,因为三个新的接口已经融入了现有的类型层次结构。这些顺序集合为我们提供了一个统一的API来访问第一个和最后一个元素,并以相反的顺序处理集合。为了更好地理解顺序集合是什么,让我们回顾一下集合......
  • java redis 短信业务应用
    javaredis短信业务应用短信业务场景:根据实际业务来通知客户,在短信的MQ中新增字段:是否需要发送短信的标识,短信微服务可以接收到MQ后根据该字段来判断是否发送。如果发送端MQ的事件的操作是分开的,比如步骤1:修改订单,步骤2:产生修改后的费用去支付,在支付成功之后才发送该MQ消息。......
  • Java提升技术,进阶为高级开发和架构师的路线
    简介Java怎样提升技术?怎样进阶为高级开发和架构师?本文介绍靠谱的成长路线。首先点明,只写业务代码是无法成长技术的。提升技术的两个方法是:有技术大佬带有技术大佬的资料本文介绍靠谱的技术进阶资料,让你比其他人更有竞争力!Java设计模式实战链接:这里用生活例子帮助理解模式的思维,用实......
  • Java提升技术,进阶为高级开发和架构师的路线
    ​ 原文网址:Java提升技术,进阶为高级开发和架构师的路线-CSDN博客简介Java怎样提升技术?怎样进阶为高级开发和架构师?本文介绍靠谱的成长路线。首先点明,只写业务代码是无法成长技术的。提升技术的两个方法是:有技术大佬带有技术大佬的资料本文介绍靠谱的技术进阶资料,让你比......
  • JAVA - Obejects api
    packagecom.demo2;importcom.demo.Demo1;importjava.util.Objects;publicclassTest{publicstaticvoidmain(String[]args){Stringname=null;StringreturnName=Objects.requireNonNullElse(name,"张三");//第一个参数不为空......
  • 探究tf卡(内存卡)在音频播放器中的播放顺序【指金正音频播放器之类的设备】
    首先,【同一个文件路径下的】音频文件,肯定是按复制进tf卡(小卡)的时间顺序,来确定播放顺序的;与音频文件的名字叫什么毫无关系,即使名字前面加序号也毫无用处。 【在同一路径下的】音频文件和文件夹之间,优先播放音频文件,然后是文件夹。 【在同一路径下的】文件夹和文件夹之间,是按......
  • Java学习总结
    一、Java开发入门1.1、Java概述1.1.1、什么是Java1.1.2、Java语言的特点1)简单易用2)安全可靠3)跨平台 通过Java虚拟机(JVM)可以在不同的操作系统(如Windows、Linux)上运行Java,从而实现跨平台的特性4)面向对象5)支持多线程1.2、JDK的使用1.2.1、什么是JDK JDK、JRE和JVM三者之间的关系 1)JD......
  • Java基础 Lock 锁
     代码示例:packagepojo;importjava.util.concurrent.locks.Lock;importjava.util.concurrent.locks.ReentrantLock;publicclassTicketextendsThread{publicstaticIntegerticket=1;//创建锁的对象staticLocklock=newReentrantLock();@Override......
  • Java基础 同步方法
    同步代码块就是把一段代码给锁起来,这样就可以解决多线程操作共享数据时带来的数据安全问题但是如果我们想要把一个方法里面所有的代码全都锁起来,就没有必要用同步代码块了,我们可以直接把synchronized加在方法上,这个方法就叫做同步方法 同步方法的格式:修饰符 synchroniz......
  • 学习如何新建java项目
    java的程序的运行机制编译型:全局翻译解释型:实时更新 在idea写下hello,world[破解激活码] IDEA2023.2.3最新激活码,注册码(亲测好用)-异常教程(exception.site) 新建一个文件夹 在文件夹新建一个class  Java语法创建一个新项目(重要)project->Empty......