java如何调用本地扬声器
各位看官可以关注博主个人博客,了解更多信息。
作者:Surpasser
链接地址:https://surpass.org.cn
前言
博主的毕设系统在做一个餐厅的点餐管理系统,在记性移动端页面开发的时候突发奇想做一个呼叫服务员,扬声器发声的一个功能类似于:“工作人员请注意,桌号8001顾客正在寻求帮助!”。
实现方式
接下来就对这个小功能进行分析和实现。先写一个Demo。
首先,我们需要一个dll作为辅助。这里解释一下dll的含义(DLL(Dynamic Link Library)文件为动态链接库文件,又称“应用百程序拓展”,是软件文件类型。在Windows中,许多应用程序并不是一个度完整的可执行文件,它们被分割成一些相知对独立的动态链接库,即DLL文件,放置于道系统中。当我们执行某一个程序时,相应的版DLL文件就会被调用。一个应用程序可使用权多个DLL文件,一个DLL文件也可能被不同的应用程序使用,这样的DLL文件被称为共享DLL文件)。
需要把
jacob-1.17-M2-x64.dll复制到C:\Windows\System32\目录下。我们也能看到目录下有很多的.dll文件。这里的文件大家自己百度下,很好找的。
使用maven项目导入坐标。
<!-- https://mvnrepository.com/artifact/net.sf.jacob-project/jacob -->
<dependency>
<groupId>net.sf.jacob-project</groupId>
<artifactId>jacob</artifactId>
<version>1.14.3</version>
</dependency>
测试类代码。
/**
* 文字转语音测试 jdk bin文件中需要导入jacob-1.17-M2-x64.dll
* 注意导包哈
* @date: 2020年2月25日 上午10:05:21
*/
public class Jacobtest { public static void main(String[] args) {
textToSpeech("工作人员请注意,桌号8001顾客正在寻求帮助!!");
} /**
* 语音转文字并播放
*
* @param text
*/
public static void textToSpeech(String text) {
ActiveXComponent ax = null;
try {
ax = new ActiveXComponent("Sapi.SpVoice"); // 运行时输出语音内容
Dispatch spVoice = ax.getObject();
// 音量 0-100
ax.setProperty("Volume", new Variant(100));
// 语音朗读速度 -10 到 +10
ax.setProperty("Rate", new Variant(0));
// 执行朗读
Dispatch.call(spVoice, "Speak", new Variant(text)); /* // 下面是构建文件流把生成语音文件 ax = new ActiveXComponent("Sapi.SpFileStream");
Dispatch spFileStream = ax.getObject(); ax = new ActiveXComponent("Sapi.SpAudioFormat");
Dispatch spAudioFormat = ax.getObject(); // 设置音频流格式
Dispatch.put(spAudioFormat, "Type", new Variant(22));
// 设置文件输出流格式
Dispatch.putRef(spFileStream, "Format", spAudioFormat);
// 调用输出 文件流打开方法,创建一个.wav文件
Dispatch.call(spFileStream, "Open", new Variant("./text.wav"), new Variant(3), new Variant(true));
// 设置声音对象的音频输出流为输出文件对象
Dispatch.putRef(spVoice, "AudioOutputStream", spFileStream);
// 设置音量 0到100
Dispatch.put(spVoice, "Volume", new Variant(100));
// 设置朗读速度
Dispatch.put(spVoice, "Rate", new Variant(-2));
// 开始朗读
Dispatch.call(spVoice, "Speak", new Variant(text)); // 关闭输出文件
Dispatch.call(spFileStream, "Close");
Dispatch.putRef(spVoice, "AudioOutputStream", null); spAudioFormat.safeRelease();
spFileStream.safeRelease();*/
spVoice.safeRelease();
ax.safeRelease(); } catch (Exception e) {
e.printStackTrace();
}
}
}
从测试类可以看出,这个方法既可以发声还能输出后缀为
.wav的文件,这是一个标准的多媒体文件。上述代码注释很清晰,就不解释了,自己看哈。测试成功,现在集成到自己的项目中。
另述
这里说到了调用扬声器发声,不放还可以想一下如何调用麦克风收音。
public class EngineeCore {
String filePath = "E:\\voice\\voice_cache.wav";
AudioFormat audioFormat;
TargetDataLine targetDataLine;
boolean flag = true;
private void stopRecognize() {
flag = false;
targetDataLine.stop();
targetDataLine.close();
}
private AudioFormat getAudioFormat() {
float sampleRate = 16000;
// 8000,11025,16000,22050,44100
int sampleSizeInBits = 16;
// 8,16
int channels = 1;
// 1,2
boolean signed = true;
// true,false
boolean bigEndian = false;
// true,false
return new AudioFormat(sampleRate, sampleSizeInBits, channels, signed, bigEndian);
}// end getAudioFormat
private void startRecognize() {
try {
// 获得指定的音频格式
audioFormat = getAudioFormat();
DataLine.Info dataLineInfo = new DataLine.Info(TargetDataLine.class, audioFormat);
targetDataLine = (TargetDataLine) AudioSystem.getLine(dataLineInfo);
// Create a thread to capture the microphone
// data into an audio file and start the
// thread running. It will run until the
// Stop button is clicked. This method
// will return after starting the thread.
flag = true;
new CaptureThread().start();
} catch (Exception e) {
e.printStackTrace();
} // end catch
}// end captureAudio method
class CaptureThread extends Thread {
public void run() {
AudioFileFormat.Type fileType = null;
File audioFile = new File(filePath);
fileType = AudioFileFormat.Type.WAVE;
//声音录入的权值
int weight = 2;
//判断是否停止的计数
int downSum = 0;
ByteArrayInputStream bais = null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
AudioInputStream ais = null;
try {
targetDataLine.open(audioFormat);
targetDataLine.start();
byte[] fragment = new byte[1024];
ais = new AudioInputStream(targetDataLine);
while (flag) {
targetDataLine.read(fragment, 0, fragment.length);
//当数组末位大于weight时开始存储字节(有声音传入),一旦开始不再需要判断末位
if (Math.abs(fragment[fragment.length-1]) > weight || baos.size() > 0) {
baos.write(fragment);
System.out.println("守卫:"+fragment[0]+",末尾:"+fragment[fragment.length-1]+",lenght"+fragment.length);
//判断语音是否停止
if(Math.abs(fragment[fragment.length-1])<=weight){
downSum++;
}else{
System.out.println("重置奇数");
downSum=0;
}
//计数超过20说明此段时间没有声音传入(值也可更改)
if(downSum>20){
System.out.println("停止录入");
break;
}
}
}
//取得录音输入流
audioFormat = getAudioFormat();
byte audioData[] = baos.toByteArray();
bais = new ByteArrayInputStream(audioData);
ais = new AudioInputStream(bais, audioFormat, audioData.length / audioFormat.getFrameSize());
//定义最终保存的文件名
System.out.println("开始生成语音文件");
AudioSystem.write(ais, AudioFileFormat.Type.WAVE, audioFile);
downSum = 0;
stopRecognize();
} catch (Exception e) {
e.printStackTrace();
} finally {
//关闭流
try {
ais.close();
bais.close();
baos.reset();
} catch (IOException e) {
e.printStackTrace();
}
}
}// end run
}// end inner class CaptureThread
这个测试没测试,偷个懒找的“哈哈”。
还有一点是Java操作语音文件.wav先不要研究了 :laugh and cry:,这里涉及到了语音识别,但是有百度那么些api,有兴趣的试试吧!
好了,在这里就结束了
更新
博主把自己的毕设项目打包放到自己的服务器上,这个扬声器出现了新的问题。
本来所有的基础都是在本地运行的,通过调用本地dll文件实现扬声器发声,现在部署到centOS上将会失去这个dll的支持,目前所存在的问题是如何不使用dll文件实现这个功能,中间借助了
.wav后缀的音视频文件。
- 如何在Linux上生成
.wav的文件。- 如何获取这个文件并输出。(解释一下,用餐顾客点击手机网页的菜单,然后再餐厅的主机来播放这个声音)
- 如何在输出主机不进行任何操作就能播放这个声音或者能够恢复之前的工作状态。
现在的临时解决办法是本地跑一个呼叫服务的接口,当需要这个功能的时候远程服务器调用本地跑的接口,进而实现餐厅主机发声。
这个和上面描述的并无差别,不一样的是存在了两台主机的调用(当然两台主机都应该链接网络,能够互相通信)
先写到这了,当有解决办法的时候再更新吧!
java如何调用本地扬声器的更多相关文章
- java中调用本地动态链接库(*.DLL)的两种方式详解和not found library、打包成jar,war包dll无法加载等等问题解决办法
我们经常会遇到需要java调用c++的案例,这里就java调用DLL本地动态链接库两种方式,和加载过程中遇到的问题进行详细介绍 1.通过System.loadLibrary("dll名称,不 ...
- Windows下Java如何调用本地获取mac地址
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import ...
- JAVA方法和本地方法(转载)
转载自:http://blog.sina.com.cn/s/blog_5b9b4abe01016zw0.html JAVA中有两种方法:JAVA方法和本地方法 JAVA方法是由JAVA编写的,编译 ...
- JNI编程(二) —— 让C++和Java相互调用(1)
自己在外面偷偷的算了下,又有将近两个月没更新过blog了.趁着今天有兴致,来更新JNI编程的第二篇文章.在第一篇里,大概介绍了JNI的特点.用途和优劣.并且做一个最简单的JNI的例子,不过说实话那个例 ...
- java方法和本地方法
java中的方法有两种,java方法和本地方法. java方法:是由java语言编写,编译成字节码,存储在class文件中的.java方法是与平台无关的. 本地方法:本地方法是由其他语言(如C.C++ ...
- java jni 调用c语言函数
今日在hibernate源代码中遇到了native关键词,甚是陌生,就查了点资料,对native是什么东西有了那么一点了解,并做一小记. native关键字说明其修饰的方法是一个原生态方法,方法对应的 ...
- java调用本地方法的时候报错 could not find the main class:xx.program will exit
如图所示,当在java调用本地方法的时候报错 我的解决办法是把dll文件放到System.out.println(System.getProperty("java.library.path& ...
- Android使用JNI(从java调用本地函数)
当编写一个混合有本地C代码和Java的应用程序时,需要使用Java本地接口(JNI)作为连接桥梁.JNI作为一个软件层和API,允许使用本地代码调用Java对象的方法,同时也允许在Java方法中调用本 ...
- [转载]java调用本地dos命令
在社区看到java调用本地dos命令的代码,特贴出来 String command = "ipconfig"; Runtime run = Runtime.getRuntime() ...
随机推荐
- ajax函数
使用三个函数是按ajax请求的处理 1.$.ajax() jQuery中实现ajax的核心函数 2.$.post() 使用post方式做ajax请求 3.$.get 使用get方式做ajax请求 $. ...
- 了解 Vue 的 Compsition API
在这篇文章中,我将讲讲 Vue 的 Composition API 为什么比之前的 Options API 要好,以及它是如何工作的. Options API 有什么问题 首先,这里不是要大家放弃 O ...
- java例题_28 冒泡排序
1 /*28 [程序 28 排序算法] 2 题目:对 10 个数进行排序 3 程序分析:可以利用选择法,即从后 9 个比较过程中,选择一个最小的与第一个元素交换, 下次类推, 4 即用第二个元素与后 ...
- 鸿蒙运行报错:Failure[INSTALL_PARSE_FAILED_USESDK_ERROR] Error while Deploying HAP
问题描述 近期,使用DevEco-Studio新建手机类型的工程,编译成功,发布到模拟器(鸿蒙P40)时出错,如下图: 原因分析 本地DevEco-Studio使用的SDK版本与设备(P40)不匹配导 ...
- Spring的循环依赖
本文简要介绍了循环依赖以及Spring解决循环依赖的过程 一.定义 循环依赖是指对象之间的循环依赖,即2个或以上的对象互相持有对方,最终形成闭环.这里的对象特指单例对象. 二.表现形式 对象之间的循环 ...
- CrashLoopBackOff的解决办法之一
问题来源 # kubectl get pods -n assembly NAME READY STATUS RESTARTS AGE alertmanager-858b7749c5-6jsfh 0/1 ...
- 百度开源中国(Java)面经
一.自我介绍 面试嘛,万年不变还是自我介绍,就说说你是干嘛的(专业是啥),为什么会选择该公司(说一说自己为何向往Java开发),再谈谈自己的优点(兴趣爱好).如果人家叫停了,就别一股脑接着讲了,停下来 ...
- JS基础学习第四天
对象(Object) 对象是JS中的引用数据类型对象是一种复合数据类型,在对象中可以保存多个不同数据类型的属性使用typeof检查一个对象时,会返回object 对象的分类: 1.内建对象- 由ES标 ...
- matlab结构体、数组和单元数组类型的创建
matlab结构体.数组和单元数组类型的创建 @ 目录 matlab结构体.数组和单元数组类型的创建 matlab结构体类型 数组类型 单元数组类型 matlab结构体类型 通过字段赋值创建结构体 创 ...
- JavaScript设计模式(一):单例模式
单例模式的定义与特点 单例(Singleton)模式的定义:指一个类只有一个实例,且该类能自行创建这个实例的一种模式.例如,Windows 中只能打开一个任务管理器,这样可以避免因打开多个任务管理器窗 ...