使用 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 音频剪辑的主要内容,如果未能解决你的问题,请参考以下文章

ubuntu18.04 PulseAudio蓝牙耳机开启mic的解决办法

解决Kali Linux没有声音

在linux中播放一个wav文件[关闭]

Linux中的HFP / HSP配置文件[关闭]

yocto 中的 Pulseaudio 构建问题

解决kali linux 2016.2实体机安装后root用户没有声音