使用 Linux PulseAudio 时无法关闭 Java 音频剪辑
Posted
技术标签:
【中文标题】使用 Linux PulseAudio 时无法关闭 Java 音频剪辑【英文标题】:Java audio Clip cannot be closed when using Linux PulseAudio 【发布时间】:2018-02-01 12:15:46 【问题描述】:我正在尝试在 Java 应用程序中播放声音,但该应用程序实际上从未终止,因为即使在尝试 close 用于播放声音的 Clip
实例之后,PulseAudio Eventloop 线程仍在运行:
import java.io.File;
import java.io.IOException;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.Audiosystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineEvent;
import javax.sound.sampled.LineListener;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
final class AudioClipTest
public static void main(String[] args) throws UnsupportedAudioFileException, IOException, LineUnavailableException
try (AudioInputStream instream = AudioSystem.getAudioInputStream(new File("resources/test-sound.wav")))
final AudioFormat format = instream.getFormat();
final Clip clip = (Clip) AudioSystem.getLine(new DataLine.Info(Clip.class, format));
clip.addLineListener(new LineListener()
@Override
public void update(final LineEvent event)
if (event.getType() == LineEvent.Type.STOP)
System.out.println("Finished playing audio.");
event.getLine().close();
// FIXME: This line is never reached on Linux with
// PulseAudio
System.out.println("Closed audio data line.");
);
clip.open(instream);
clip.start();
在我的Linux机器上†,上面的main方法播放相关的声音,打印出来
播放完毕。
然后挂起,而在 Windows‡ 机器上打印
播放完毕。
关闭音频数据线。
并正确退出。
Linux 机器上实际使用的Clip
实现是org.classpath.icedtea.pulseaudio.PulseAudioClip
,而在Windows 上是com.sun.media.sound.DirectAudioDevice.DirectClip
; 这是怎么回事? — PulseAudioClip.close()
在做什么却没有返回?
†发行版: Linux Mint 18.1; 内核: 4.4.0-92-generic x86_64; OpenJDK: 8u131-b11-2ubuntu1.16.04.3; PulseAudio: 1:8.0-ubuntu3.3
‡发行版: Windows 10 Pro; 版本: 1703; 操作系统构建: 15063.540 x64; Oracle JDK: 1.8.0_144-b01; DirectX: 版本 12
【问题讨论】:
【参考方案1】:解决此问题的一种可能方法是使用 Alsa(用户空间)API 通过 Java 播放音频。 alsa 用户空间 API 将重定向到 PulseAudio(或其他 API/混音器),因此您仍应获得正确的音频。
编辑$JAVA_HOME/jre/lib/sound.properties
并注释掉与org.classpath.icedtea.pulseaudio
相关的所有内容并添加以下内容:
javax.sound.sampled.Clip=com.sun.media.sound.DirectAudioDeviceProvider
javax.sound.sampled.Port=com.sun.media.sound.PortMixerProvider
javax.sound.sampled.SourceDataLine=com.sun.media.sound.DirectAudioDeviceProvider
javax.sound.sampled.TargetDataLine=com.sun.media.sound.DirectAudioDeviceProvider
另外,请针对您的发行版的 openjdk 包提交错误。 PulseAudio/Java 绑定多年来一直不受支持,应该被删除。
【讨论】:
以上是关于使用 Linux PulseAudio 时无法关闭 Java 音频剪辑的主要内容,如果未能解决你的问题,请参考以下文章