最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java實(shí)現(xiàn)生成自定義時長的靜音音頻

 更新時間:2022年01月27日 08:35:01   作者:劍客阿良_ALiang  
這篇文章主要介紹了如何通過Java實(shí)現(xiàn)一個音頻工具類,可以實(shí)現(xiàn)生成一段自定義時長(精確到毫秒)的wav音頻。感興趣的小伙伴可以了解一下

Maven依賴

        <dependency>
            <groupId>org</groupId>
            <artifactId>jaudiotagger</artifactId>
            <version>2.0.1</version>
        </dependency>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>30.1.1-jre</version>
        </dependency>

代碼

以16k采樣率,單聲道,16bits采樣分辨率為例,具體參數(shù)原理,下面有說明。

import com.google.common.primitives.Bytes;

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;

/** @Author huyi @Date 2021/9/30 15:33 @Description: 靜音音頻工具類 */
public class SilenceAudioUtils {

? /**
? ?* 根據(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;
? }

? /**
? ?* 生成靜音音頻
? ?*
? ?* @param filePath 輸出文件地址
? ?* @param duration 音頻時長
? ?*/
? public static void makeSilenceWav(String filePath, Long duration) {
? ? List<Byte> oldBytes = new ArrayList<>();
? ? IntStream.range(0, (int) (duration * 32)).forEach(x -> oldBytes.add((byte) 0));
? ? writeToFile(filePath, Bytes.toArray(oldBytes));
? }

? public static void main(String[] args) {
? ? makeSilenceWav("E:/csdn/1.wav", 5000L);
? }

運(yùn)行結(jié)果:

使用ffmpeg查看

參數(shù)說明和使用方法

1、構(gòu)造原理

構(gòu)造一個wav主要分為兩個部分,頭文件和數(shù)據(jù)文件。那么只需要構(gòu)造一個全是靜音的音頻數(shù)據(jù)包,在加上頭就可以構(gòu)造出一個靜音文件。

所以代碼的主要邏輯就是構(gòu)造數(shù)據(jù)包->封裝文件頭。

2、怎么1毫秒的靜音包如何構(gòu)建呢?

這里首先要知道的是,音頻采樣率、采樣分辨率和聲道的概念。

這里分享一個簡單的說明鏈接: 詳解RIFF和WAVE音頻文件格式

而靜音就是每個采樣到的音頻包里面的內(nèi)容都是由(byte)0構(gòu)成的。

3、那么每毫秒的音頻包對應(yīng)多少個(byte)0呢?

這里有個公式:采樣率 x 聲道數(shù) x 采樣分辨率 / 8

參考鏈接: http://soundfile.sapp.org/doc/WaveFormat/

舉個例子:如果你要生成32k采樣率、雙聲道、16bits的靜音,每毫秒需要構(gòu)建幾個比特0呢?

按照公式: result = 32000 x 2 x 16 / 8000 = 128 (為什么是8000,因?yàn)槲覀兯愕氖呛撩?,原公式單位為?

那么就可以把代碼中的

IntStream.range(0, (int) (duration * 32)).forEach(x -> oldBytes.add((byte) 0));

修改為:

IntStream.range(0, (int) (duration * 128)).forEach(x -> oldBytes.add((byte) 0));

同時需要把頭文件的格式也調(diào)整一下:

byte[] header = buildWavHeader(pcmData.length, 16000, 1, 16);

修改為:

byte[] header = buildWavHeader(pcmData.length, 32000, 2, 16);

總結(jié)

當(dāng)然生成靜音的方法有很多,比如使用sox在ubuntu上一行命令就行。不過如果需要在工程化項(xiàng)目中,對原始音頻做靜音拼接組裝,那么你看懂了我上面的邏輯,就應(yīng)該知道如何實(shí)現(xiàn)了吧。只要讀取音頻中的數(shù)據(jù)包,然后往后面添加需要靜音時長的靜音數(shù)據(jù)包,重新封裝頭,就可以得到了。

這里附上ubuntu上sox生成靜音的命令供大家參考.

sox -n -r 16000 -b 16 -c 1 -L silence.wav trim 0.0 5.000

以上就是Java實(shí)現(xiàn)生成自定義時長的靜音音頻的詳細(xì)內(nèi)容,更多關(guān)于Java自定義靜音音頻的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論

民乐县| 宁明县| 新余市| 德阳市| 诸城市| 五家渠市| 仪征市| 梧州市| 安国市| 荔浦县| 普兰县| 黄大仙区| 垦利县| 同心县| 澜沧| 德州市| 恩平市| 前郭尔| 康平县| 宁城县| 香河县| 沛县| 聂荣县| 靖边县| 兴文县| 方城县| 永顺县| 益阳市| 莱芜市| 永丰县| 山西省| 台东市| 武清区| 平阳县| 准格尔旗| 诏安县| 宕昌县| 南江县| 普洱| 武义县| 卫辉市|