如何用Java从just line in端口录制声音
我需要从线路输入端口捕捉声音,而不是麦克风如何用Java从just line in端口录制声音,java,javasound,Java,Javasound,我需要从线路输入端口捕捉声音,而不是麦克风 虽然我通过麦克风完成了录音,但我无法从线路输入端口或特定端口捕获声音。我该如何处理这个问题?熟悉这门课。另外,从它自己的Javadoc: 通过调用 具有适当DataLine.Info对象的混合器的getLine方法 具体地说,我还要检查返回的输出,以选择与您要查找的端口中的行相匹配的行。我也没有想到这一点,但您确实需要 mixer.getSourceLineInfo()因为这是来自mixer的视图。。。真让人困惑 targetDataLine是一条可记
虽然我通过麦克风完成了录音,但我无法从线路输入端口或特定端口捕获声音。我该如何处理这个问题?熟悉这门课。另外,从它自己的Javadoc: 通过调用 具有适当DataLine.Info对象的混合器的getLine方法
具体地说,我还要检查返回的输出,以选择与您要查找的端口中的行相匹配的行。我也没有想到这一点,但您确实需要
mixer.getSourceLineInfo()
因为这是来自mixer的视图。。。真让人困惑
targetDataLine是一条可记录的输入线,但要查看这些线可能来自何处,您需要查找混音器的端口(麦克风、线路输入、SPDIF),因此需要调用
mixer.getSourceLineInfo()
这只提供了端口。例如,它们可用于控制输入中的行_的录制音量,但不能直接从端口对象录制
你需要使用
DataLine.Info targetDataLineInfo=新的DataLine.Info(TargetDataLine.class,AudioFormat)
其中AudioFormat是一些用户定义的格式,如
audioFormat = new AudioFormat(
Encoding.PCM_SIGNED,
sampleRate,
bitRate,
monoOrStereo,
monoOrStereo * 2, //
sampleRate,
false);
然后从首选混音器中获取该行:
Mixer.getLine(audioFormat);
这会给你一条可记录的线,就像你可能已经做过的那样
我不知道的是,像你一样,如何选择一个端口,比如LINE_IN,并创建一个匹配的TargetDataLine,Port对象可以控制它,我已经搜索了又搜索
()
任何有工作经验的人都可以试试这个。如果它工作,让我知道,因为我不能完全自己测试我的笔记本电脑。 然后,您可以编写自己的函数来获取
PortMixer
,ActualMixer
以及具有指定输入类型和/或所需混音器的targetDataline
private void testGettingInput() {
//Check this out for interest
//http://www.java-forum.org/spiele-multimedia-programmierung/94699-java-sound-api-zuordnung-port-mixer-input-mixer.html
final String newLine = System.getProperty("line.separator");
final String inputTypeString = "LINE_IN"; // or COMPACT_DISC or MICROPHONE etc ...
final Port.Info myInputType = new Port.Info((Port.class), inputTypeString, true);
final AudioFormat af = new AudioFormat(
Encoding.PCM_SIGNED,
44100.0F,
16,
2,
2 * 2,
44100.0F,
false);
final DataLine.Info targetDataLineInfo = new DataLine.Info(TargetDataLine.class, af);
TargetDataLine targetDataLine;
//Go through the System audio mixers
for (Mixer.Info mixerInfo : AudioSystem.getMixerInfo()) {
try {
Mixer targetMixer = AudioSystem.getMixer(mixerInfo);
targetMixer.open();
//Check if it supports the desired format
if (targetMixer.isLineSupported(targetDataLineInfo)) {
System.out.println(mixerInfo.getName() + " supports recording @" + af);
//now go back and start again trying to match a mixer to a port
//the only way I figured how is by matching name, because
//the port mixer name is the same as the actual mixer with "Port " in front of it
// there MUST be a better way
for (Mixer.Info mifo : AudioSystem.getMixerInfo()) {
String port_string = "Port ";
if ((port_string + mixerInfo.getName()).equals(mifo.getName())) {
System.out.println("Matched Port to Mixer:" + mixerInfo.getName());
Mixer portMixer = AudioSystem.getMixer(mifo);
portMixer.open();
portMixer.isLineSupported((Line.Info) myInputType);
//now check the mixer has the right input type eg LINE_IN
if (portMixer.isLineSupported((Line.Info) myInputType)) {
//OK we have a supported Port Type for the Mixer
//This has all matched (hopefully)
//now just get the record line
//There should be at least 1 line, usually 32 and possible unlimited
// which would be "AudioSystem.Unspecified" if we ask the mixer
//but I haven't checked any of this
targetDataLine = (TargetDataLine) targetMixer.getLine(targetDataLineInfo);
System.out.println("Got TargetDataLine from :" + targetMixer.getMixerInfo().getName());
return;
}
}
}
System.out.println(newLine);
}
targetMixer.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行此命令,我得到:
正在尝试为:Realtek HD音频输入获取portMixer
Realtek HD音频输入支持录制@PCM_签名44100.0 Hz、16位、立体声、4字节/帧、little endian
混音器匹配端口:Realtek HD音频输入
Port Realtek HD音频输入不支持麦克风
Port Realtek高清音频输入,版本5.10
从:Realtek HD音频输入获取TargetDataLine
麦克风端口的控件:
麦克风音量控制,包括选择、麦克风增强、音量和平衡控制。
将混音器和输入类型首选项分别更改为“USB Sound Device”和“LINE_IN”,我得到以下结果:(注意,混音器名称中“Device”一词后面有8个空格,但它们不会显示在此网页上!)
正在尝试为:USB声音设备获取portMixer
正在尝试为:USB声音设备获取portMixer
USB声音设备支持录制@PCM_签名44100.0 Hz、16位、立体声、4字节/帧、little endian
混音器的匹配端口:USB声音设备
端口USB声音设备在
端口USB声音设备,版本0.16
已从以下位置获取TargetDataLine:USB声音设备
端口中的行\u的控件:
包含选择、静音、音量和平衡控件的线路控件。
这里USB声卡显示一个输入端口和一个输出端口,因此其中一个不支持LINE_in,这可能是因为它是一个输出,因此可能允许录制“立体声混音”或其他输出类型
希望这能起到作用,并对其他人有所帮助…因为Java文档相当模糊。。。
在Windows上测试过,但我认为Linux不会识别端口名,比如LINE_IN,所以您需要检查操作系统端口是什么,可能还有一些其他的事情,比如需要一个子字符串作为混音器名称等等。。。
在我的Linux上,麦克风被称为“捕获”
查看更多信息
任何错误的改进等让我知道
d07114915您使用的是什么平台?不同操作系统的Java声音内容略有不同。
import javax.sound.sampled.*;
/**
*
* @author d07114915
*
* Class to get a mixer with a specified recordable audio format from a specified port
* For instance get a 44.1kHz 16bit record line for a "line in" input
*/
public class MixerMatcher {
private static final String THE_INPUT_TYPE_I_WANT = "MICROPHONE";
private static final String THE_NAME_OF_THE_MIXER_I_WANT_TO_GET_THE_INPUT_FROM = "Realtek HD Audio Input";
private static final AudioFormat af = new AudioFormat(
AudioFormat.Encoding.PCM_SIGNED,
44100.0F,
16,
2,
2 * 2,
44100.0F,
false);
private static final DataLine.Info targetDataLineInfo = new DataLine.Info(TargetDataLine.class, af);
private static final Port.Info myInputType = new Port.Info((Port.class), THE_INPUT_TYPE_I_WANT, true);
private static TargetDataLine targetDataLine = null;
public static void main(String[] args) {
Mixer portMixer = null;
Mixer targetMixer = null;
try {
for (Mixer.Info mi : AudioSystem.getMixerInfo()) {
// System.out.println("-" +mi.getName() + "-");
if (mi.getName().equals(THE_NAME_OF_THE_MIXER_I_WANT_TO_GET_THE_INPUT_FROM)) {
System.out.println("Trying to get portMixer for :" + mi.getName());
portMixer = getPortMixerInfoFor(mi);
if (portMixer != null) {
System.out.println(portMixer.getMixerInfo().toString());
targetMixer = AudioSystem.getMixer(mi);
break;
}
}
}
if (targetMixer != null) {
targetMixer.open();
targetDataLine = (TargetDataLine) targetMixer.getLine(targetDataLineInfo);
System.out.println("Got TargetDataLine from :" + targetMixer.getMixerInfo().getName());
portMixer.open();
Port port = (Port) portMixer.getLine(myInputType);
port.open();
Control[] controls = port.getControls();
System.out.println((controls.length > 0 ? "Controls for the "+ THE_INPUT_TYPE_I_WANT + " port:" : "The port has no controls."));
for (Control c : controls) {
System.out.println(c.toString());
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
//return the portMixer that corresponds to TargetMixer
private static Mixer getPortMixerInfoFor(Mixer.Info mixerInfo) {
//Check this out for interest
//http://www.java-forum.org/spiele-multimedia-programmierung/94699-java-sound-api-zuordnung-port-mixer-input-mixer.html
try {
// get the requested mixer
Mixer targetMixer = AudioSystem.getMixer(mixerInfo);
targetMixer.open();
//Check if it supports the desired format
if (targetMixer.isLineSupported(targetDataLineInfo)) {
System.out.println(mixerInfo.getName() + " supports recording @ " + af);
//now go back and start again trying to match a mixer to a port
//the only way I figured how is by matching name, because
//the port mixer name is the same as the actual mixer with "Port " in front of it
// there MUST be a better way
for (Mixer.Info portMixerInfo : AudioSystem.getMixerInfo()) {
String port_string = "Port ";
if ((port_string + mixerInfo.getName()).equals(portMixerInfo.getName())) {
System.out.println("Matched Port to Mixer:" + mixerInfo.getName());
Mixer portMixer = AudioSystem.getMixer(portMixerInfo);
portMixer.open();
//now check the mixer has the right input type eg LINE_IN
boolean lineTypeSupported = portMixer.isLineSupported((Line.Info) myInputType);
System.out.println(portMixerInfo.getName() +" does " + (lineTypeSupported? "" : "NOT") + " support " + myInputType.getName());
if (lineTypeSupported) {
portMixer.close();
targetMixer.close();
return portMixer;
}
portMixer.close();
}
}
}
targetMixer.close();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}