Java处理音频

news/2024/11/30 1:29:53/

一、Java中如何调用电脑麦克风?

我最近在开发一款电脑的智能语音交互程序时(类似于智能手机上的小爱),我们要捕获声音,然后交给语音识别接口就行识别,那么问题来了,我们应该如何捕获声音呢?也就是说Java中如何调用麦克风,进行音频的输入呢?

Java 中提供的底层类库javax.sound。我们需要引入相关的类库,就可以调用 JDK 封装好的调用麦克风的方法。

代码如下:

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.TargetDataLine;//读取麦克风数据
AudioFormat audioFormat = new AudioFormat(16000.0F, 16, 1, true, false);
DataLine.Info info = new DataLine.Info(TargetDataLine.class, audioFormat);
TargetDataLine targetDataLine = (TargetDataLine) AudioSystem.getLine(info);
targetDataLine.open(audioFormat);
targetDataLine.start();int nByte = 0;
final int bufSize = 3200;
byte[] buffer = new byte[bufSize];
while ((nByte = targetDataLine.read(buffer, 0, bufSize)) > 0) {//直接发送麦克风数据流// 这个方法是把音频以二进制流的方式发送到语音识别接口上transcriber.send(buffer, nByte);
}

targetDataLine.read(buffer, 0, bufSize)才是真正的开始把音频读入到电脑内存中。

二、Java中如何播放音频文件?

从上面的代码中,我们会了如何调用麦克风,把音频读取到内存中。因为我做的是智能语音交互程序,不光要能识别我们讲的话,还要能处理我们的话,处理完还要回应我们,也就是说我们还要用到语音合成,把获取到的音频流播放出来。这里说一下自己子在项目中遇到的一个坑。因为语音合成接口是分段响应二进制音频流的,如果我们直接播放,就会造成声音卡顿。所以这里我们最好是先把音频流存储到本地电脑上,也就是保存为音频格式文件,然后再播放,就不会有卡顿现象。当然这样会有IO操作,如果我们实时播放音频流就不会有IO操作,在性能上更优。

Java 调用扬声器进行播放代码如下:

public static void playAudio() {// 从文件中获取音频的文件格式AudioFileFormat fileFormat;DataLine.Info info;SourceDataLine sourceDataLine;try {FileInputStream fis = new FileInputStream("tts_test.wav");fileFormat = AudioSystem.getAudioFileFormat(new File("tts_test.wav"));info = new DataLine.Info(SourceDataLine.class, fileFormat.getFormat());sourceDataLine = (SourceDataLine) AudioSystem.getLine(info);sourceDataLine.open(fileFormat.getFormat());sourceDataLine.start();byte[] bytes = new byte[1024];while (fis.read(bytes) > 0) {sourceDataLine.write(bytes, 0, bytes.length);}} catch (UnsupportedAudioFileException | IOException | LineUnavailableException e) {e.printStackTrace();}
}

这里需要注意:在new byte[]时,创建的空间必须是偶数,否则会报异常。这里的new byte[]是创建一个缓存,根据上面代码的意思是创建了1024字节的缓存,也就是每次从硬盘中加载1024字节内容进内存中。同时需要注意,并不是说这个偶数填的越大越好,太大会造成内存溢出。其实这里还可以使用fis.available()大小的缓存。

sourceDataLine.write(bytes, 0, bytes.length)才是真正的开始把音频写出到扬声器中。

三、Java如何播放音频流?

上面提到的是使用Java播放本地电脑中的音频文件,那如果我们要播放网络或接口中传过来的音频流,我们应该如何播放呢?

Java 播放实时音频流代码:

import java.io.IOException;
import java.io.InputStream;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.SourceDataLine;public class AudioPlayer {private InputStream stream;private AudioFormat format;private AudioInputStream audioInputStream;private SourceDataLine line;public AudioPlayer(InputStream stream, AudioFormat format) {this.stream = stream;this.format = format;}public void play() throws IOException {audioInputStream = new AudioInputStream(stream, format, AudioSystem.NOT_SPECIFIED);DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);try {line = (SourceDataLine) AudioSystem.getLine(info);line.open(format);line.start();} catch (Exception e) {e.printStackTrace();return;}byte[] buffer = new byte[1024];int n = 0;while (n != -1) {n = audioInputStream.read(buffer, 0, buffer.length);if (n > 0) {line.write(buffer, 0, n);}}line.drain();line.stop();line.close();audioInputStream.close();}
}

调用上面写的播放器类中的播放方法。

InputStream is = new ByteArrayInputStream(bytesArray);
AudioFormat format = new AudioFormat(16000.0F, 16, 1, true, false);
AudioPlayer player = new AudioPlayer(is, format);
player.play();

要注意音频格式,必须要写正确的音频格式才能正常播放。

这里给大家扩展一下知识,因为语音合成的回调方法中的参数是java.nio.ByteBuffer,所以我们要想办法将其转为字节输入流。

第一步:先把byteBuffer转为字节数组。

byte[] bytesArray = new byte[byteBuffer.remaining()];
byteBuffer.get(bytesArray, 0, bytesArray.length);

第二步:把字节数组转为字节流。

InputStream is = new ByteArrayInputStream(bytesArray);

http://www.ppmy.cn/news/561447.html

相关文章

音频的预处理

1分帧 语音信号为短时平稳信号,取一小段可以看做是平稳的所以要加窗,并且相邻两帧之间有一部分重叠原因是:语音信号是时变的,在短时范围内特征变化较小,所以作为稳态来处理;但超出这短时范围语音信号就有变化了。在相…

怎样把网页上的音频转换成mp3格式?试试这几个转换方法

大家平时喜欢听音乐吗?我经常会在网上保存一些不错的音频到设备上,这样子就方便我可以随时播放了。那你们有遇到过该音频格式不支持播放的情况吗?这种情况是因为播放器兼容的音频格式比较少,需要我们将音频格式转换成播放器兼容的…

音频处理六:(音频的反FFT)

程序设计六:音频的反FFT 一:需求分析 ​ FFT变换是将信号从时域转换到频域,这样在时域复杂的信号转换到频域看起来就方便容易了很多。但有时候也需要将频域信号转换到时域,所以这时运用到IFFT变换。 逆向快速傅里叶变换(IFFT)的…

音轨分离软件 Spleeter 使用教程及踩过的坑

Spleeter 是由法国音乐流媒体公司 Deezer 开发并在 Github 上开源的音轨分离软件,可用于非专业场景下的音乐的人声和各种乐器声分离。 下面是安装教程,请在命令行或 anaconda prompt 上运行代码: conda install -c conda-forge ffmpeg libsn…

你知道怎样音频转文字吗?3个方法教你音频转文字怎么操作

工作时我们偶尔会收到别人发来的音频信息或音频资料,但是我们刚好没带耳机,不便将音频打开播放出来。但又担心是很重要的事情,或需要立即整理的资料文件,怎么办呢?这个时候,我们可以利用音频转文字这个方法…

音频淡入淡出效果——解决音频突变的爆音问题

使用软件调节音量时如果音量之间的步进太大,声音突变,就能听到明显的爆音,尤其以单音音频更为明显,类似的问题还在声音起播、暂停、结束、快进快退时经常会出现,这个时候一般需要对音频进行渐入渐出的效果处理。 先来…

使用批处理文件和mkvtoolnix批量修改默认音轨和音轨属性并重新混流

工具和版本 windows10 x64 MkvToolNix v73 待输出的Mkv格式文件,要求是同类型的文件,比如从迅雷下载下来同一来源的连续剧 步骤 一、添加文件 打开MkvToolNix GUI,添加输入文件,选中一个待输出的文件A 二、编辑音轨 选中音…

浏览器不能默认播放音频处理

原文链接:http://www.luyixian.cn/news_show_311603.aspx 复制代码到js中 修改资源路径即可 //浏览器适用 contextClass window.AudioContext window.AudioContext || window.webkitAudioContext || window.mozAudioContext || window.msAudioContext;try…