Java實(shí)現(xiàn)音頻添加自定義時(shí)長(zhǎng)靜音的示例代碼
前言
本文提供一個(gè)可以給一個(gè)wav音頻添加自定義時(shí)長(zhǎng)靜音的工具類。正好工作中用到,所以正好分享分享。
Maven依賴
<dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>30.1.1-jre</version> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.5.2</version> </dependency>
代碼
package ai.guiji.csdn.tools; import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.IoUtil; import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.URLUtil; import com.google.common.base.Joiner; import com.google.common.primitives.Bytes; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.stream.LongStream; /** @Author 劍客阿良_ALiang @Date 2022/1/26 14:27 @Description: wav添加靜音時(shí)長(zhǎng)工具 */ public class WavAddSilenceUtils { /** * 根據(jù)PCM文件構(gòu)建wav的header字段 * * @param srate Sample rate - 8000, 16000, etc. * @param channel Number of channels - Mono = 1, Stereo = 2, etc.. * @param format Number of bits per sample (16 here) * @throws IOException */ public static byte[] buildWavHeader(int dataLength, int srate, int channel, int format) throws IOException { byte[] header = new byte[44]; long totalDataLen = dataLength + 36; long bitrate = srate * channel * format; header[0] = 'R'; header[1] = 'I'; header[2] = 'F'; header[3] = 'F'; header[4] = (byte) (totalDataLen & 0xff); header[5] = (byte) ((totalDataLen >> 8) & 0xff); header[6] = (byte) ((totalDataLen >> 16) & 0xff); header[7] = (byte) ((totalDataLen >> 24) & 0xff); header[8] = 'W'; header[9] = 'A'; header[10] = 'V'; header[11] = 'E'; header[12] = 'f'; header[13] = 'm'; header[14] = 't'; header[15] = ' '; header[16] = (byte) format; header[17] = 0; header[18] = 0; header[19] = 0; header[20] = 1; header[21] = 0; header[22] = (byte) channel; header[23] = 0; header[24] = (byte) (srate & 0xff); header[25] = (byte) ((srate >> 8) & 0xff); header[26] = (byte) ((srate >> 16) & 0xff); header[27] = (byte) ((srate >> 24) & 0xff); header[28] = (byte) ((bitrate / 8) & 0xff); header[29] = (byte) (((bitrate / 8) >> 8) & 0xff); header[30] = (byte) (((bitrate / 8) >> 16) & 0xff); header[31] = (byte) (((bitrate / 8) >> 24) & 0xff); header[32] = (byte) ((channel * format) / 8); header[33] = 0; header[34] = 16; header[35] = 0; header[36] = 'd'; header[37] = 'a'; header[38] = 't'; header[39] = 'a'; header[40] = (byte) (dataLength & 0xff); header[41] = (byte) ((dataLength >> 8) & 0xff); header[42] = (byte) ((dataLength >> 16) & 0xff); header[43] = (byte) ((dataLength >> 24) & 0xff); return header; } /** * 默認(rèn)寫入的pcm數(shù)據(jù)是16000采樣率,16bit,可以按照需要修改 * * @param filePath * @param pcmData */ public static boolean writeToFile(String filePath, byte[] pcmData) { BufferedOutputStream bos = null; try { bos = new BufferedOutputStream(new FileOutputStream(filePath)); byte[] header = buildWavHeader(pcmData.length, 16000, 1, 16); bos.write(header, 0, 44); bos.write(pcmData); bos.close(); return true; } catch (Exception e) { e.printStackTrace(); } finally { if (bos != null) { try { bos.close(); } catch (IOException e) { e.printStackTrace(); } } } return false; } /** * 增加延時(shí)靜音 * * @param filePath 音頻地址 * @param tmpDirPath 臨時(shí)目錄地址 * @param delayTime 延時(shí)時(shí)長(zhǎng),單位毫秒 * @return 最終文件地址 * @throws Exception 異常 */ public static String delayWav(String filePath, String tmpDirPath, Long delayTime) throws Exception { byte[] bytes; if (filePath.startsWith("http")) { bytes = IoUtil.readBytes(URLUtil.getStream(new URL(filePath))); } else { bytes = FileUtil.readBytes(filePath); } List<Byte> resultByte = new ArrayList<>(Bytes.asList(Arrays.copyOfRange(bytes, 44, bytes.length))); LongStream.range(0, (long) (delayTime * 32)).forEach(x -> resultByte.add((byte) 0)); String resultPath = Joiner.on(File.separator).join(Arrays.asList(tmpDirPath, IdUtil.simpleUUID() + ".wav")); writeToFile(resultPath, Bytes.toArray(resultByte)); return resultPath; } public static void main(String[] args) throws Exception { System.out.println(delayWav("http://xxxx/xxx.wav", "C:\\Users\\huyi\\Desktop\\", 10000L)); } }
代碼說(shuō)明:
1、delayWav方法參數(shù)分別為wav音頻文件地址(可以支持http的url地址)、臨時(shí)文件目錄地址、延時(shí)靜音時(shí)長(zhǎng)(單位毫秒)
2、對(duì)wav的要求默認(rèn)為:采樣率16K、單聲道??梢詤⒖?Java實(shí)現(xiàn)生成自定義時(shí)長(zhǎng)的靜音音頻
對(duì)需要處理的音頻參數(shù)調(diào)整。
3、生成uuid的隨機(jī)文件名,避免重復(fù)。
驗(yàn)證一下
下面是準(zhǔn)備的音頻
執(zhí)行結(jié)果
執(zhí)行后音頻
OK,加了10秒的靜音。
到此這篇關(guān)于Java實(shí)現(xiàn)音頻添加自定義時(shí)長(zhǎng)靜音的示例代碼的文章就介紹到這了,更多相關(guān)Java音頻添加靜音內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- java實(shí)現(xiàn)切割wav音頻文件的方法詳解【附外部jar包下載】
- Java利用讀寫的方式實(shí)現(xiàn)音頻播放代碼實(shí)例
- 使用Java和ffmpeg把音頻和視頻合成視頻的操作方法
- java僅用30行代碼就實(shí)現(xiàn)了視頻轉(zhuǎn)音頻的批量轉(zhuǎn)換
- java 音頻轉(zhuǎn)換wav格式標(biāo)準(zhǔn)音頻的操作
- Java輕松使用工具類實(shí)現(xiàn)獲取MP3音頻時(shí)長(zhǎng)
- Java?工具類實(shí)現(xiàn)音頻音量提升
- Java實(shí)現(xiàn)生成自定義時(shí)長(zhǎng)的靜音音頻
相關(guān)文章
SpringBoot整合Elasticsearch7.2.0的實(shí)現(xiàn)方法
這篇文章主要介紹了SpringBoot整合Elasticsearch7.2.0的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08MyBatis實(shí)現(xiàn)MySQL批量插入的示例代碼
本文主要介紹了MyBatis實(shí)現(xiàn)MySQL批量插入的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05feign調(diào)用中文參數(shù)被encode編譯的問(wèn)題
這篇文章主要介紹了feign調(diào)用中文參數(shù)被encode編譯的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03Java 實(shí)現(xiàn)倒計(jì)時(shí)功能(由秒計(jì)算天、小時(shí)、分鐘、秒)
最近做項(xiàng)目遇到這樣的需求,天、小時(shí)、分鐘、秒的數(shù)值都是隔開的,服務(wù)器端只返回一個(gè)時(shí)間戳長(zhǎng)度,怎么實(shí)現(xiàn)這樣的功能呢?下面小編給大家?guī)?lái)了Java 實(shí)現(xiàn)倒計(jì)時(shí)功能的方案,需要的朋友參考下吧2018-01-01Ubuntu下配置Tomcat服務(wù)器以及設(shè)置自動(dòng)啟動(dòng)的方法
這篇文章主要介紹了Ubuntu下配置Tomcat服務(wù)器以及設(shè)置自動(dòng)啟動(dòng)的方法,適用于Java的web程序開發(fā),需要的朋友可以參考下2015-10-10Simple Java Mail郵件發(fā)送實(shí)現(xiàn)過(guò)程解析
這篇文章主要介紹了Simple Java Mail郵件發(fā)送實(shí)現(xiàn)過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-11-11關(guān)于Controller 層返回值的公共包裝類的問(wèn)題
本文給大家介紹Controller 層返回值的公共包裝類-避免每次都包裝一次返回-InitializingBean增強(qiáng),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧2021-09-09