Java音頻處理之音頻流轉(zhuǎn)音頻文件和獲取音頻播放時長詳解
1.背景
最近對接了一款智能手表,手環(huán),可以應(yīng)用與老人與兒童監(jiān)控,環(huán)衛(wèi)工人監(jiān)控,農(nóng)場畜牧業(yè)監(jiān)控,寵物監(jiān)控等,其中用到了音頻傳輸,通過平臺下發(fā)語音包,發(fā)送遠(yuǎn)程命令錄制當(dāng)前設(shè)備音頻并將音頻分包傳輸?shù)椒?wù)器上生成音頻文件等。其中關(guān)于音頻的一些簡單操作封裝成了工具包。
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 {
/**
* 二進(jìn)制流轉(zhuǎn)音頻文件
* @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();
// 設(shè)置初始位置
int pos = 6;
// 初始幀數(shù)
int frameCount = 0;
int packedPos = -1;
// 初始數(shù)據(jù)值
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++;
}
// 幀數(shù)*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);
}
}
致力于物聯(lián)網(wǎng)應(yīng)用開發(fā),目前有一套成熟的物聯(lián)網(wǎng)底層服務(wù)與物聯(lián)網(wǎng)設(shè)備管理系統(tǒng),并提供API,WebHook,MQTT實現(xiàn)將數(shù)據(jù)實時有效的推送到客戶的云平臺,助力客戶完成自己的SaaS平臺開發(fā)。
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>方法二:
獲取網(wǎng)絡(luò)資源音頻時長:
這種方法是獲取文件字節(jié)大小然后在用公式自己算的
BufferedInputStream bis = null;
Bitstream bitstream = null;
try {
URL url = new URL("http://*********08.mp3");
HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
urlConn.connect();
//此url響應(yīng)頭中包含"Accept-Length"為字節(jié)數(shù)大小
String headerField = urlConn.getHeaderField("Accept-Length");
bis = new BufferedInputStream(urlConn.getInputStream());
bitstream = new Bitstream(bis);
Header header = bitstream.readFrame();
int bitrate = header.bitrate();
//根據(jù)文件大小計算 字節(jié)數(shù)*8/碼率/1000(毫秒值轉(zhuǎn)秒)
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>方法三:
根據(jù)content length獲取網(wǎng)絡(luò)音頻時長,有誤差:
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(); //獲取結(jié)束時間
System.out.println("所需時間: "+(endTime1-startTime)+"ms");
}catch (Exception e ){
System.out.println(e.getMessage());
}
}到此這篇關(guān)于Java音頻處理之音頻流轉(zhuǎn)音頻文件和獲取音頻播放時長詳解的文章就介紹到這了,更多相關(guān)Java音頻處理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
idea向System.getenv()添加系統(tǒng)環(huán)境變量的操作
這篇文章主要介紹了idea向System.getenv()添加系統(tǒng)環(huán)境變量的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-06-06
淺析Java語言中狀態(tài)模式的優(yōu)點(diǎn)
狀態(tài)模式允許對象在內(nèi)部狀態(tài)改變時改變它的行為,對象看起來好像修改了它的類。這個模式將狀態(tài)封裝成獨(dú)立的類,并將動作委托到 代表當(dāng)前狀態(tài)的對象,我們知道行為會隨著內(nèi)部狀態(tài)而改變2023-02-02
spring使用validation參數(shù)及全局異常檢測方式
本文主要介紹了Java的數(shù)據(jù)校驗規(guī)范validation-api,包括其定義的注解和HibernateValidator的實現(xiàn),還介紹了spring-boot-starter-validation的使用,可以讓開發(fā)者在SpringBoot應(yīng)用中簡化數(shù)據(jù)校驗的功能2025-02-02
Java中的Opencv簡介與開發(fā)環(huán)境部署方法
OpenCV是一個開源的計算機(jī)視覺和圖像處理庫,提供了豐富的圖像處理算法和工具,它支持多種圖像處理和計算機(jī)視覺算法,可以用于物體識別與跟蹤、圖像分割與邊緣檢測、圖像特征提取與描述等應(yīng)用,本文介紹Java中的Opencv簡介與開發(fā)環(huán)境部署方法,感興趣的朋友一起看看吧2025-01-01
對SpringBoot項目Jar包進(jìn)行加密防止反編譯的方案
最近項目要求部署到其他公司的服務(wù)器上,但是又不想將源碼泄露出去,要求對正式環(huán)境的啟動包進(jìn)行安全性處理,防止客戶直接通過反編譯工具將代碼反編譯出來,本文介紹了如何對SpringBoot項目Jar包進(jìn)行加密防止反編譯,需要的朋友可以參考下2024-08-08
SpringCloudGateway 網(wǎng)關(guān)登錄校驗實現(xiàn)思路
文章介紹了在微服務(wù)架構(gòu)中使用Spring Cloud Gateway進(jìn)行登錄校驗的方法,通過在網(wǎng)關(guān)層面進(jìn)行登錄校驗,并將用戶信息通過請求頭傳遞給下游微服務(wù),解決了每個微服務(wù)都需要獨(dú)立進(jìn)行登錄校驗的問題,此外,還討論了如何在微服務(wù)之間傳遞用戶信息2024-11-11
SpringBoot大學(xué)心理服務(wù)系統(tǒng)實現(xiàn)流程分步講解
本系統(tǒng)主要論述了如何使用JAVA語言開發(fā)一個大學(xué)生心理服務(wù)系統(tǒng) ,本系統(tǒng)將嚴(yán)格按照軟件開發(fā)流程進(jìn)行各個階段的工作,采用B/S架構(gòu),面向?qū)ο缶幊趟枷脒M(jìn)行項目開發(fā)2022-09-09

