- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在编写一个函数,使用 TargetDataLine 捕获大约 7.5 秒的音频剪辑。代码执行并呈现一个“input.wav”文件,但是当我播放它时没有声音。
如本文底部的代码所示,我的方法是执行以下操作:
到目前为止我尝试了什么:
更改音频格式。最初,我使用的是另一个 AudioFormat 构造函数,它也采用文件类型(第一个参数是 AudioFormat.Encoding.PCM_SIGNED 等)。我的采样率为 44100、16 位、2 个 channel 和另一种格式的小端设置,产生了相同的结果。
更改我的辅助线程和主线程上的命令顺序(即在备用位置执行 TLine.open() 或 start())。
检查我的辅助线程是否真正启动。
作为引用,我在 Mac OS Big Sur 上使用 IntelliJ。
public static void captureAudio() {
try {
AudioFormat f = new AudioFormat(22050, 8, 1, false, false);
DataLine.Info secure = new DataLine.Info(TargetDataLine.class, f);
if (!AudioSystem.isLineSupported(secure)) {
System.err.println("Unsupported Line");
}
TargetDataLine tLine = (TargetDataLine)AudioSystem.getLine(secure);
System.out.println("Starting recording...");
tLine.open(f);
tLine.start();
File writeTo = new File("input.wav");
Thread t = new Thread(){
public void run() {
try {
AudioInputStream is = new AudioInputStream(tLine);
AudioSystem.write(is, AudioFileFormat.Type.WAVE, writeTo);
} catch(IOException e) {
System.err.println("Encountered system I/O error in recording:");
e.printStackTrace();
}
}
};
t.start();
Thread.sleep(7500);
tLine.stop();
tLine.close();
System.out.println("Recording has ended.");
} catch(Exception e) {
e.printStackTrace();
}
}
更新 1:一些新的测试和结果
我的麦克风和扬声器都可以与其他应用程序一起使用 - 使用 QuickTimePlayer 录制工作音频。
我围绕我的 TargetDataLines 是什么以及它们之间的关系做了很多测试。我运行了以下代码:
public static void main(String[] args) {
AudioFormat f = new AudioFormat(48000, 16, 2, true, false);
//DataLine.Info inf = new DataLine.Info(SourceDataLine.class, f);
try {
TargetDataLine line = AudioSystem.getTargetDataLine(f);
DataLine.Info test = new DataLine.Info(TargetDataLine.class, f);
TargetDataLine other = (TargetDataLine)AudioSystem.getLine(test);
String output = line.equals(other) ? "Yes" : "No";
if (output.equals("No")) {
System.out.println(other.toString());
}
System.out.println(line.toString());
System.out.println("_______________________________");
for (Mixer.Info i : AudioSystem.getMixerInfo()) {
Line.Info[] tli = AudioSystem.getMixer(i).getTargetLineInfo();
if (tli.length != 0) {
Line comp = AudioSystem.getLine(tli[0]);
System.out.println(comp.toString() + ":" +i.getName());
if (comp.equals(line) || comp.equals(other)) {
System.out.println("The TargetDataLine is from " + i.getName());
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
长话短说,我收到的 TargetDataLineTargetDataLine line = AudioSystem.getTargetDataLine(f);
和TargetDataLine 其他 = (TargetDataLine)AudioSystem.getLine(new DataLine.Info(TargetDataLine.class, f));
不同,而且,不匹配与我的系统混音器关联的任何 TargetDataLine。
上面代码的输出是这样的(第一行分别是other
和line
):
com.sun.media.sound.DirectAudioDevice$DirectTDL@cc34f4d
com.sun.media.sound.DirectAudioDevice$DirectTDL@17a7cec2
_______________________________
com.sun.media.sound.PortMixer$PortMixerPort@79fc0f2f:Port MacBook Pro Speakers
com.sun.media.sound.PortMixer$PortMixerPort@4d405ef7:Port ZoomAudioDevice
com.sun.media.sound.DirectAudioDevice$DirectTDL@3f91beef:Default Audio Device
com.sun.media.sound.DirectAudioDevice$DirectTDL@1a6c5a9e:MacBook Pro Microphone
com.sun.media.sound.DirectAudioDevice$DirectTDL@37bba400:ZoomAudioDevice
我使用以下方法收集所有 TargetDataLines:
public static ArrayList<Line.Info> allTDL() {
ArrayList<Line.Info> all = new ArrayList<>();
for (Mixer.Info i : AudioSystem.getMixerInfo()) {
Line.Info[] tli = AudioSystem.getMixer(i).getTargetLineInfo();
if (tli.length != 0) {
for (int f = 0; f < tli.length; f += 1) {
all.add(tli[f]);
}
}
}
return all;
}
我的捕获/录制音频方法保持不变,只是将格式切换为 AudioFormat f = new AudioFormat(48000, 16, 2, true, false);
,将录制时间更改为 5000毫秒,并将方法 header 编写为 public static void recordAudio(Line.Info inf)
这样我就可以用它的信息单独加载每个 TargetDataLine。
然后我执行了以下代码来旋转 TargetDataLines:
public static void main(String[] args) {
for (Line.Info inf : allTDL()) {
recordAudio(inf);
try {
Thread.sleep(5000);
} catch(Exception e) {
e.printStackTrace();
}
if (!soundless(loadAsBytes("input.wav"))) {
System.out.println("The recording with " + inf.toString() + " has sound!");
}
System.out.println("The last recording with " + inf.toString() + " was soundless.");
}
}
}
输出是这样的:
Recording...
Was unable to cast com.sun.media.sound.PortMixer$PortMixerPort@506e1b77 to a TargetDataLine.
End recording.
The last recording with SPEAKER target port was soundless.
Recording...
Was unable to cast com.sun.media.sound.PortMixer$PortMixerPort@5e9f23b4 to a TargetDataLine.
End recording.
The last recording with ZoomAudioDevice target port was soundless.
Recording...
End recording.
The last recording with interface TargetDataLine supporting 8 audio formats, and buffers of at least 32 bytes was soundless.
Recording...
End recording.
The last recording with interface TargetDataLine supporting 8 audio formats, and buffers of at least 32 bytes was soundless.
Recording...
End recording.
The last recording with interface TargetDataLine supporting 14 audio formats, and buffers of at least 32 bytes was soundless.
TL;DR 每个 TargetDataLine 的音频都没有声音。为了完整起见,这里有 soundless
和 loadAsBytes
函数:
public static byte[] loadAsBytes(String name) {
assert name.contains(".wav");
ByteArrayOutputStream out = new ByteArrayOutputStream();
File retrieve = new File("src/"+ name);
try {
InputStream input = AudioSystem.getAudioInputStream(retrieve);
int read;
byte[] b = new byte[1024];
while ((read = input.read(b)) > 0) {
out.write(b, 0, read);
}
out.flush();
byte[] full = out.toByteArray();
return full;
} catch(UnsupportedAudioFileException e) {
System.err.println("The File " + name + " is unsupported on this system.");
e.printStackTrace();
} catch (IOException e) {
System.err.println("Input-Output Exception on retrieval of file " + name);
e.printStackTrace();
}
return null;
}
static boolean soundless(byte[] s) {
if (s == null) {
return true;
}
for (int i = 0; i < s.length; i += 1) {
if (s[i] != 0) {
return false;
}
}
return true;
}
除了不允许 Java 访问音频线路的操作系统怪癖之外,我不太确定此时可能出现的问题,但我不知道如何解决这个问题 - 查看系统偏好设置' 允许访问的任何明显方式。我认为这可能必须使用终端命令来完成,但也不确定我必须在那里执行哪些命令。
最佳答案
我没有发现您显示的代码有任何问题。我还没有尝试在我的系统上测试它。 (Linux, Eclipse)
在我看来,您的代码与 this tutorial 非常匹配.作者 Nam Ha Minh 非常认真地回答问题。您可以尝试他的确切代码示例,如果他的版本也不适合您,请咨询他。
但首先,生成的 .wav 文件的大小是多少?文件大小是否与您录制期间的预期数据量相匹配?如果是这样,您确定您的麦克风有数据传入吗?南有another code example逐步读取录制的声音并将其放入内存中。基本上,不是使用 AudioInputStream
作为 AudioSystem.write
方法的参数,而是对 AudioInputStream 执行多个
并直接检查传入的数据。这可能有助于解决问题是发生在流程的传入部分还是传出部分。read
方法调用
我对格式的了解不够了解 Mac 的处理方式是否不同。我很惊讶您将格式设置为 unsigned。出于有限的目的,我坚持使用“CD 质量立体声”并在所有关键时刻都签署了 PCM。
编辑:根据反馈,问题似乎是传入线没有返回数据。通过查看其他类似的教程,似乎有几个人在他们的 Mac 系统上遇到了同样的问题。
首先要验证的是:您的麦克风是否适用于其他应用程序?
就后续步骤而言,我会尝试验证所选行。可以枚举/检查暴露给 java 的行。教程Accessing Audio System Resources有一些关于如何做到这一点的基本信息。看起来 AudioSystem.getMixerInfo()
将返回可以检查的可用混音器列表。也许 AudioSystem.getTargetLineInfo()
会更切题。
我想当您获取 TargetDataLine
时使用的默认 Line
或 Port
可能不是正在运行的那个麦克风。如果一个特定的线路或端口被证明是你需要的,那么它可以通过 overridden getTargetDataLine method 明确指定。 .
我读到可能有一个安全策略需要处理。我不完全理解代码,但如果那是问题所在,大概会抛出一个 Exception
。也许 MacO 有新的安全措施,以防止外部程序偷偷打开麦克风线?
如果您确实解决了这个问题,请务必发布答案并将其标记为已解决。对于很多人来说,这似乎是一个活生生的问题。
关于Java TargetDataLine 没有接收到任何音频?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65660266/
我正在编写一个具有以下签名的 Java 方法。 void Logger(Method method, Object[] args); 如果一个方法(例如 ABC() )调用此方法 Logger,它应该
我是 Java 新手。 我的问题是我的 Java 程序找不到我试图用作的图像文件一个 JButton。 (目前这段代码什么也没做,因为我只是得到了想要的外观第一的)。这是我的主课 代码: packag
好的,今天我在接受采访,我已经编写 Java 代码多年了。采访中说“Java 垃圾收集是一个棘手的问题,我有几个 friend 一直在努力弄清楚。你在这方面做得怎么样?”。她是想骗我吗?还是我的一生都
我的 friend 给了我一个谜语让我解开。它是这样的: There are 100 people. Each one of them, in his turn, does the following
如果我将使用 Java 5 代码的应用程序编译成字节码,生成的 .class 文件是否能够在 Java 1.4 下运行? 如果后者可以工作并且我正在尝试在我的 Java 1.4 应用程序中使用 Jav
有关于why Java doesn't support unsigned types的问题以及一些关于处理无符号类型的问题。我做了一些搜索,似乎 Scala 也不支持无符号数据类型。限制是Java和S
我只是想知道在一个 java 版本中生成的字节码是否可以在其他 java 版本上运行 最佳答案 通常,字节码无需修改即可在 较新 版本的 Java 上运行。它不会在旧版本上运行,除非您使用特殊参数 (
我有一个关于在命令提示符下执行 java 程序的基本问题。 在某些机器上我们需要指定 -cp 。 (类路径)同时执行java程序 (test为java文件名与.class文件存在于同一目录下) jav
我已经阅读 StackOverflow 有一段时间了,现在我才鼓起勇气提出问题。我今年 20 岁,目前在我的家乡(罗马尼亚克卢日-纳波卡)就读 IT 大学。足以介绍:D。 基本上,我有一家提供簿记应用
我有 public JSONObject parseXML(String xml) { JSONObject jsonObject = XML.toJSONObject(xml); r
我已经在 Java 中实现了带有动态类型的简单解释语言。不幸的是我遇到了以下问题。测试时如下代码: def main() { def ks = Map[[1, 2]].keySet()
一直提示输入 1 到 10 的数字 - 结果应将 st、rd、th 和 nd 添加到数字中。编写一个程序,提示用户输入 1 到 10 之间的任意整数,然后以序数形式显示该整数并附加后缀。 public
我有这个 DownloadFile.java 并按预期下载该文件: import java.io.*; import java.net.URL; public class DownloadFile {
我想在 GUI 上添加延迟。我放置了 2 个 for 循环,然后重新绘制了一个标签,但这 2 个 for 循环一个接一个地执行,并且标签被重新绘制到最后一个。 我能做什么? for(int i=0;
我正在对对象 Student 的列表项进行一些测试,但是我更喜欢在 java 类对象中创建硬编码列表,然后从那里提取数据,而不是连接到数据库并在结果集中选择记录。然而,自从我这样做以来已经很长时间了,
我知道对象创建分为三个部分: 声明 实例化 初始化 classA{} classB extends classA{} classA obj = new classB(1,1); 实例化 它必须使用
我有兴趣使用 GPRS 构建车辆跟踪系统。但是,我有一些问题要问以前做过此操作的人: GPRS 是最好的技术吗?人们意识到任何问题吗? 我计划使用 Java/Java EE - 有更好的技术吗? 如果
我可以通过递归方法反转数组,例如:数组={1,2,3,4,5} 数组结果={5,4,3,2,1}但我的结果是相同的数组,我不知道为什么,请帮助我。 public class Recursion { p
有这样的标准方式吗? 包括 Java源代码-测试代码- Ant 或 Maven联合单元持续集成(可能是巡航控制)ClearCase 版本控制工具部署到应用服务器 最后我希望有一个自动构建和集成环境。
我什至不知道这是否可能,我非常怀疑它是否可能,但如果可以,您能告诉我怎么做吗?我只是想知道如何从打印机打印一些文本。 有什么想法吗? 最佳答案 这里有更简单的事情。 import javax.swin
我是一名优秀的程序员,十分优秀!