我创建了一个我正在尝试实现的准系统版本,希望删除代码可以揭示问题所在,然而,我仍然收到同样的错误让我意识到我的逻辑存在根本性的错误我看不到。
这是(仅)类:
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import javax.sound.sampled.*;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class CaptureDemo extends JFrame
{
private JPanel panel = new JPanel();
private JButton capture;
private JButton stop;
private JButton play;
private boolean running;
private ByteArrayOutputStream out;
private Thread captureThread;
private Thread playThread;
private DataLine.Info info;
private AudioFormat format;
private TargetDataLine line;
public CaptureDemo()
{
super ("Audio Capture/Playback Demo");
initGUI();
}
private void initGUI()
{
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
capture = new JButton("Capture");
stop = new JButton("Stop");
play = new JButton("Play");
capture.setEnabled(true);
stop.setEnabled(false);
play.setEnabled(false);
ActionListener captureListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
capture.setEnabled(false);
stop.setEnabled(true);
play.setEnabled(false);
captureAudio();
}
};
capture.addActionListener(captureListener);
panel.add(capture, BorderLayout.NORTH);
ActionListener stopListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
capture.setEnabled(true);
stop.setEnabled(false);
play.setEnabled(true);
running = false;
}
};
stop.addActionListener(stopListener);
panel.add(stop, BorderLayout.CENTER);
ActionListener playListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
playAudio();
}
};
play.addActionListener(playListener);
panel.add(play, BorderLayout.SOUTH);
this.add(panel);
this.setAlwaysOnTop(true);
}
private void captureAudio()
{
try
{
if (captureThread != null && captureThread.isAlive() )
captureThread.interrupt();
format = getFormat();
info = new DataLine.Info(TargetDataLine.class, format);
line = (TargetDataLine) AudioSystem.getLine(info);
line.open(format);
line.start();
Runnable RunnerOne = new Runnable()
{
int bufferSize = (int)format.getSampleRate() * format.getFrameSize();
byte buffer[] = new byte[bufferSize];
public void run()
{
out = new ByteArrayOutputStream();
running = true;
try
{
while (running) {
int count = line.read(buffer, 0, buffer.length);
if (count > 0)
out.write(buffer, 0, count);
}
out.close();
}
catch (Exception e)
{
System.out.println("Error: " + e.getMessage());
e.printStackTrace();
}
}
};
captureThread = new Thread (RunnerOne);
captureThread.start();
}
catch (Exception e)
{
System.out.println("Error: " + e.getMessage());
e.printStackTrace();
}
}
private void playAudio()
{
try
{
if (playThread != null && playThread.isAlive() )
playThread.interrupt();
byte audio[] = out.toByteArray();
InputStream input = new ByteArrayInputStream(audio);
format = getFormat();
final AudioInputStream ais = new AudioInputStream(input, format, audio.length / format.getFrameSize());
info = new DataLine.Info( SourceDataLine.class, format);
final SourceDataLine Sline = (SourceDataLine) AudioSystem.getLine(info);
Sline.open(format);
Sline.start();
//<editor-fold defaultstate="collapsed" desc="RUNNABLE FOR AUDIO PLAY">
Runnable PlaySoundRunnable = new Runnable()
{
int bufferSize = (int) format.getSampleRate() * format.getFrameSize();
byte buffer[] = new byte[bufferSize];
public void run()
{
try
{
int count;
while ((count = ais.read (buffer, 0, buffer.length)) != -1) {
if (count > 0) {
Sline.write(buffer, 0, count);
}
}
Sline.drain();
Sline.close();
}
catch (Exception e)
{
System.out.println("Error: " + e.getMessage());
e.printStackTrace();
}
}
};
playThread = new Thread(PlaySoundRunnable);
playThread.start();
//</editor-fold>
}
catch (Exception e)
{
System.out.println("Error: " + e);
e.printStackTrace();
}
}
private AudioFormat getFormat()
{
float sampleRate = 32000;
int sampleSizeInBits = 8;
int channels = 1;
boolean signed = false;
boolean bigEndian = true;
return new AudioFormat(sampleRate, sampleSizeInBits, channels, signed, bigEndian);
}
public static void main (String[] args)
{
JFrame demo = new CaptureDemo();
demo.pack();
demo.setVisible(true);
}
}
好的,这就是问题所在:程序在第一次运行时完全按照我想要的方式运行,在按下捕获按钮时捕获音频,在单击停止按钮时停止捕获,最后在按下播放时播放按钮。完美。
但是,当您尝试再次捕获(不重新运行程序)时会出现问题,这会引发异常:
Error: line with format PCM_UNSIGNED 32000.0 Hz, 8 bit, mono, 1 bytes/frame, not supported.
javax.sound.sampled.LineUnavailableException: line with format PCM_UNSIGNED 32000.0 Hz, 8 bit, mono, 1 bytes/frame, not supported.
at com.sun.media.sound.DirectAudioDevice$DirectDL.implOpen(DirectAudioDevice.java:513)
at com.sun.media.sound.AbstractDataLine.open(AbstractDataLine.java:124)
at com.sun.media.sound.AbstractDataLine.open(AbstractDataLine.java:156)
at CaptureDemo.captureAudio(CaptureDemo.java:93)
at CaptureDemo.access$300(CaptureDemo.java:14)
at CaptureDemo$1.actionPerformed(CaptureDemo.java:52)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2341)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
at java.awt.Component.processMouseEvent(Component.java:6505)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
at java.awt.Component.processEvent(Component.java:6270)
at java.awt.Container.processEvent(Container.java:2229)
at java.awt.Component.dispatchEventImpl(Component.java:4861)
at java.awt.Container.dispatchEventImpl(Container.java:2287)
at java.awt.Component.dispatchEvent(Component.java:4687)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4492)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422)
at java.awt.Container.dispatchEventImpl(Container.java:2273)
at java.awt.Window.dispatchEventImpl(Window.java:2719)
at java.awt.Component.dispatchEvent(Component.java:4687)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:703)
at java.awt.EventQueue.access$000(EventQueue.java:102)
at java.awt.EventQueue$3.run(EventQueue.java:662)
at java.awt.EventQueue$3.run(EventQueue.java:660)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
at java.awt.EventQueue$4.run(EventQueue.java:676)
at java.awt.EventQueue$4.run(EventQueue.java:674)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:673)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:244)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:163)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:151)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:147)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:139)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:97)
任何想法?
聚苯乙烯。我刚刚开始使用java,如果你指出我做的其他不良做法,我将不胜感激:)
编辑: 我设法最终解决了这个问题,愚蠢的是我在重新创建并打开之前没有先关闭该行,该行仍然在使用但不知何故抛出格式unsupoorted错误...
if (line != null && line.isOpen() )
line.close()