线程出现错误:JAVA
问题描述:
我在应用程序(附加代码)下运行并单击jToggleButton
以启动编码功能(音频捕捉)并成功运行。当我再次单击jToggleButton
停止该功能(音频捕捉)后,它会停止。但在第二次点击之后,Netbeans输出终端会显示一些错误。所以,我试图找出问题所在,但仍然无法确定代码出了什么问题。我希望,我可以从这里获得帮助,而且我只是一名Java初学者。所以如果帮我修改这段代码,对我的理解会更有帮助。线程出现错误:JAVA
错误日志:
javax.sound.sampled.LineUnavailableException: line with format PCM_SIGNED 8000.0 Hz, 16 bit, mono, 2 bytes/frame, big-endian not supported.
at com.sun.media.sound.DirectAudioDevice$DirectDL.implOpen(DirectAudioDevice.java:513)
at com.sun.media.sound.AbstractDataLine.open(AbstractDataLine.java:121)
at com.sun.media.sound.AbstractDataLine.open(AbstractDataLine.java:153)
at javaapplication1.NewJFrame1$2.run(NewJFrame1.java:83)
at java.lang.Thread.run(Thread.java:745)
应用的总码
package javaapplication1;
import java.io.ByteArrayOutputStream;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.TargetDataLine;
public class NewJFrame1 extends javax.swing.JFrame {
public NewJFrame1() {
initComponents();
}
@SuppressWarnings("unchecked")
private void initComponents() {
jPanel1 = new javax.swing.JPanel();
jToggleButton1 = new javax.swing.JToggleButton();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jPanel1.setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());
jToggleButton1.setText("jToggleButton1");
jToggleButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jToggleButton1ActionPerformed(evt);
}
});
jPanel1.add(jToggleButton1, new org.netbeans.lib.awtextra.AbsoluteConstraints(130, 70, -1, -1));
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
);
pack();
}
private void jToggleButton1ActionPerformed(java.awt.event.ActionEvent evt) {
Thread t = new Thread(new Runnable()
{
@Override
public void run()
{
AudioFormat format = new AudioFormat(8000.0f, 16, 1, true, true);
{TargetDataLine microphone;
SourceDataLine speakers;
try {
microphone = AudioSystem.getTargetDataLine(format);
DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
microphone = (TargetDataLine) AudioSystem.getLine(info);
microphone.open(format);
ByteArrayOutputStream out = new ByteArrayOutputStream();
int numBytesRead;
int CHUNK_SIZE = 1024;
byte[] data = new byte[microphone.getBufferSize()/5];
microphone.start();
DataLine.Info dataLineInfo = new DataLine.Info(SourceDataLine.class, format);
speakers = (SourceDataLine) AudioSystem.getLine(dataLineInfo);
speakers.open(format);
speakers.start();
while(jToggleButton1.isSelected()){
numBytesRead = microphone.read(data, 0, CHUNK_SIZE);
speakers.write(data, 0, numBytesRead);
}
speakers.drain();
speakers.close();
microphone.close();
} catch (LineUnavailableException e) {
e.printStackTrace();
}
}
}
});
t.start();
}
}
public static void main(String args[]) {
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(NewJFrame1.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(NewJFrame1.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(NewJFrame1.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(NewJFrame1.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new NewJFrame1().setVisible(true);
}
});
}
// Variables declaration
private javax.swing.JPanel jPanel1;
private javax.swing.JToggleButton jToggleButton1;
}
答
您无论切换状态的开始一个新的线程。只有切换到“开”时,您才应该这样做。否则,新线程将尝试打开麦克风的I/O,这可能是不可能的,因为它仍然由第一个线程使用。
Thread t = ...
之前做if(!jToggleButton1.isSelected()) return;
哪一个是线83? – Fildor
@Fildor,tnx您的关注。第83行是这样的: microphone.open(format); – user7560586
刚刚看到:每次切换,你开始一个新的线程...不好!只有当它切换到“开”时,才会开始一个新的。如果你检查这个,它可能已经解决了这个问题。 – Fildor