Java实现生成自定义时长的静音音频

目录
  • Maven依赖
  • 代码
  • 参数说明和使用方法
  • 总结

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采样分辨率为例,具体参数原理,下面有说明。

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 {

  /**
   * 根据PCM文件构建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;
  }

  /**
   * 默认写入的pcm数据是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);
  }

运行结果:

使用ffmpeg查看

参数说明和使用方法

1、构造原理

构造一个wav主要分为两个部分,头文件和数据文件。那么只需要构造一个全是静音的音频数据包,在加上头就可以构造出一个静音文件。

所以代码的主要逻辑就是构造数据包->封装文件头。

2、怎么1毫秒的静音包如何构建呢?

这里首先要知道的是,音频采样率、采样分辨率和声道的概念。

这里分享一个简单的说明链接: 详解RIFF和WAVE音频文件格式

而静音就是每个采样到的音频包里面的内容都是由(byte)0构成的。

3、那么每毫秒的音频包对应多少个(byte)0呢?

这里有个公式:采样率 x 声道数 x 采样分辨率 / 8

参考链接: http://soundfile.sapp.org/doc/WaveFormat/

举个例子:如果你要生成32k采样率、双声道、16bits的静音,每毫秒需要构建几个比特0呢?

按照公式: result = 32000 x 2 x 16 / 8000 = 128 (为什么是8000,因为我们算的是毫秒,原公式单位为秒)

那么就可以把代码中的

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

修改为:

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

同时需要把头文件的格式也调整一下:

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

修改为:

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

总结

当然生成静音的方法有很多,比如使用sox在ubuntu上一行命令就行。不过如果需要在工程化项目中,对原始音频做静音拼接组装,那么你看懂了我上面的逻辑,就应该知道如何实现了吧。只要读取音频中的数据包,然后往后面添加需要静音时长的静音数据包,重新封装头,就可以得到了。

这里附上ubuntu上sox生成静音的命令供大家参考.

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

以上就是Java实现生成自定义时长的静音音频的详细内容,更多关于Java自定义静音音频的资料请关注我们其它相关文章!

(0)

相关推荐

  • Java利用读写的方式实现音频播放代码实例

    这篇文章主要介绍了Java利用读写的方式实现音频播放代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 public static void main(String[] args) { Audiotest at = new Audiotest("我在测试时,这里必须是盘符的音频文件"); at.start(); } import java.io.File; import java.io.IOException; import ja

  • java 音频转换wav格式标准音频的操作

    目录 简述 环境依赖 maven依赖 ffmpeg依赖 工具类代码 总结 简述 该工具类主要是为了将各类音频转为wav标准格式,其中可以调节采样率.声道数等指标.主要是使用ffmpeg命令进行转换. 环境依赖 maven依赖 <dependency> <groupId>org.bytedeco</groupId> <artifactId>javacv-platform</artifactId> <version>1.5.5</v

  • Java 工具类实现音频音量提升

    目录 前言 Maven依赖 代码 验证一下 前言 本文提供将音频提升音量的java工具类代码,一如既往的实用主义分享. Maven依赖 <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.7.15</version> </dependency> <dependency> &l

  • Java实现在Word中嵌入多媒体(视频、音频)文件

    目录 Jar导入(2种方法)  嵌入多媒体文件 注意事项 Word中可将Office(Word/Excel/PowerPoint).PDF.txt等文件作为OLE对象插入到文档中,双击该对象可直接访问或编辑该文件,除了以上常见的文件格式对象,也可以插入多媒体文件,如视频.音频等.本篇文章将对此作相关介绍. Jar导入(2种方法) 1.通过 Maven 安装 在pom.xml中配置如下内容导入: <repositories> <repository> <id>com.e-

  • 使用Java和ffmpeg把音频和视频合成视频的操作方法

    FFmpeg是一个开源免费跨平台的视频和音频流方案,属于自由软件,采用LGPL或GPL许可证(依据你选择的组件).它提供了录制.转换以及流化音视频的完整解决方案.它包含了非常先进的音频/视频编解码库libavcodec,为了保证高可移植性和编解码质量,libavcodec里很多codec都是从头开发的. FFmpeg是一套可以用来记录.转换数字音频.视频,并能将其转化为流的开源计算机程序.它包括了目前领先的音/视频编码库libavcodec. FFmpeg是在Linux下开发出来的,但它可以在包

  • Java轻松使用工具类实现获取MP3音频时长

    获取mp3格式音频时长. Maven依赖 <dependency> <groupId>org</groupId> <artifactId>jaudiotagger</artifactId> <version>2.0.1</version> </dependency> 代码 import org.jaudiotagger.audio.AudioFileIO; import org.jaudiotagger.aud

  • java仅用30行代码就实现了视频转音频的批量转换

    本功能实现需要用到第三方jar包 jave,JAVE 是java调用FFmpeg的封装工具. spring boot项目pom文件中添加以下依赖 <!-- https://mvnrepository.com/artifact/ws.schild/jave-core --> <dependency> <groupId>ws.schild</groupId> <artifactId>jave-core</artifactId> <v

  • Java实现生成自定义时长的静音音频

    目录 Maven依赖 代码 参数说明和使用方法 总结 Maven依赖 <dependency> <groupId>org</groupId> <artifactId>jaudiotagger</artifactId> <version>2.0.1</version> </dependency> <dependency> <groupId>com.google.guava</grou

  • Java实现音频添加自定义时长静音的示例代码

    目录 前言 Maven依赖 代码 验证一下 前言 本文提供一个可以给一个wav音频添加自定义时长静音的工具类.正好工作中用到,所以正好分享分享. Maven依赖 <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>30.1.1-jre</version> </dependency> &l

  • Java编程实现获取mp3时长及播放mp3文件的方法

    本文实例讲述了Java编程实现获取mp3时长及播放mp3文件的方法.分享给大家供大家参考,具体如下: 所需包为jaudiotagger-2.2.6-SNAPSHOT.jar 和jl1.0.1.jar . import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import org.jaudiotagger.audio.AudioFileIO; import org.jaudi

  • Java通过调用FFMPEG获取视频时长

    FFmpeg是一套可以用来记录.转换数字音频.视频,并能将其转化为流的开源计算机程序.采用LGPL或GPL许可证.它提供了录制.转换以及流化音视频的完整解决方案.它包含了非常先进的音频/视频编解码库libavcodec,为了保证高可移植性和编解码质量,libavcodec里很多codec都是从头开发的. 由此看来FFmpeg很强大,很多主流的音频.视频处理软件都使用了FFmpeg. FFmpeg下载下来解压,cmd进入到FFmpeg.exe目录中,即可在命令行下进行各种操作,查看视频信息命令:f

  • Java获取视频时长、大小的示例

    项目中有这样一个需求,网页上上传了一个视频,需要获取此视频的时长.大小,把这两个数据返回给前台在页面显示.后台使用的是springboot框架,项目部署在linux上面.下面是核心代码:     1.pom文件中需要导入的jar包依赖 (分为两部分:核心包.ffmpeg包两部分,ffmpeg包又分为Windows环境以及Linux环境,同时又区分32位系统以及64位系统.针对于不同的运行环境要导入不同的包,这一点对于开发.测试环境为Window而生产环境为Linux的情况,尤其要注意需要导入所有

  • JAVA多线程之实现用户任务排队并预估排队时长

    目录 实现流程 排队论简介 代码具体实现 接口测试 补充知识 BlockingQueue 阻塞与非阻塞 实现流程 初始化一定数量的任务处理线程和缓存线程池,用户每次调用接口,开启一个线程处理. 假设初始化5个处理器,代码执行 BlockingQueue.take 时候,每次take都会处理器队列就会减少一个,当处理器队列为空时,take就是阻塞线程,当用户处理某某任务完成时候,调用资源释放接口,在处理器队列put 一个处理器对象,原来阻塞的take ,就继续执行. 排队论简介 排队论是研究系统随

  • 使用java生成json时产生栈溢出错误问题及解决方案

    目录 java生成json时产生栈溢出错误 环境 这里会出现栈溢出错误 json转换时出现栈内存溢出 java生成json时产生栈溢出错误 环境 java + hibernate +html 本来,java中使用json事件很正常的事,但小心有的地方有点“坎儿”. 比如,在java中建立了json对象想传到前台去: List<Comment> commentsList = commentMng.findByArticleId(articleid); JSONArray jsonMembers

  • Java获取视频时长及截取帧截图详解

    前言 只是最近碰到有这方面的项目需求,所以简单 Mark 下本文.下面的示例是参考过他人分享的文章,之后本人再自行实践.调整和测试过的,希望对有这方面需求的人有所帮助. 示例 添加依赖 <dependency> <groupId>org.bytedeco</groupId> <artifactId>javacv-platform</artifactId> <version>1.4.4</version> </depe

  • java随机生成一个名字和对应拼音的方法

    本文实例讲述了java随机生成一个名字和对应拼音的方法.分享给大家供大家参考.具体如下: package com.cn.wangk.util.name; import java.util.Random; import com.cn.wangk.util.StrTools; public class ChineseName { String[] sName = new String[95]; String[] Name = new String[79]; private String Names;

随机推荐