Java音频无法在Linux中播放WAV文件 [英] Java audio fails to play wav file in Linux

查看:597
本文介绍了Java音频无法在Linux中播放WAV文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Linux上使用Java音频时遇到麻烦.这是Ubuntu 14.04上的OpenJDK 8.以下示例失败,其.wav文件通过此链接:

I am having trouble using Java audio on Linux. This is OpenJDK 8 on Ubuntu 14.04. The following sample fails with the .wav file from this link:

import java.net.URL;
import javax.sound.sampled.*;

public class PlaySound {

    public void play() throws Exception
    {
        // List all mixers and default mixer
        System.out.println("All mixers:");
        for (Mixer.Info m : AudioSystem.getMixerInfo())
        {
            System.out.println("    " + m);
        }

        System.out.println("Default mixer: " + AudioSystem.getMixer(null).getMixerInfo());

        URL url = getClass().getResource("drop.wav");
        Clip clip;

        AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(url);
        clip = AudioSystem.getClip();
        System.out.println("Clip format: " + clip.getFormat());
        clip.open(audioInputStream);

        clip.start();
        do { Thread.sleep(100); } while (clip.isRunning());
    }

    public static void main(String [] args) throws Exception {
        (new PlaySound()).play();
    }
}

这是结果:

All mixers:
    PulseAudio Mixer, version 0.02
    default [default], version 4.4.0-31-generic
    Intel [plughw:0,0], version 4.4.0-31-generic
    Intel [plughw:0,2], version 4.4.0-31-generic
    NVidia [plughw:1,3], version 4.4.0-31-generic
    NVidia [plughw:1,7], version 4.4.0-31-generic
    NVidia [plughw:1,8], version 4.4.0-31-generic
    NVidia [plughw:1,9], version 4.4.0-31-generic
    Port Intel [hw:0], version 4.4.0-31-generic
    Port NVidia [hw:1], version 4.4.0-31-generic
Default mixer: default [default], version 4.4.0-31-generic
Clip format: PCM_SIGNED unknown sample rate, 16 bit, stereo, 4 bytes/frame, big-endian
Exception in thread "main" java.lang.IllegalArgumentException: Invalid format
    at org.classpath.icedtea.pulseaudio.PulseAudioDataLine.createStream(PulseAudioDataLine.java:142)
    at org.classpath.icedtea.pulseaudio.PulseAudioDataLine.open(PulseAudioDataLine.java:99)
    at org.classpath.icedtea.pulseaudio.PulseAudioDataLine.open(PulseAudioDataLine.java:283)
    at org.classpath.icedtea.pulseaudio.PulseAudioClip.open(PulseAudioClip.java:402)
    at org.classpath.icedtea.pulseaudio.PulseAudioClip.open(PulseAudioClip.java:453)
    at PlaySound.play(PlaySound.java:22)
    at PlaySound.main(PlaySound.java:29)

显然,问题在于选择了PulseAudio混音器,由于某种原因,它无法播放.wav文件.

Apparently the problem is that the PulseAudio mixer is being selected, and for some reason it cannot play the .wav file.

如果我将AudioSystem.getClip()调用替换为AudioSystem.getClip(null),它将选择默认的混音器,那么它将起作用.

If I replace the AudioSystem.getClip() call with AudioSystem.getClip(null), which selects the default mixer, then it works.

如何确保选择了兼容的调音台?

How can I make sure that a compatible mixer is selected ?

更新:遵循@Dave的建议,循环浏览可用的混音器,直到找到具有兼容"格式的混音器,然后看到以下内容:

Update: Following the suggestion from @Dave to loop through the available mixers until I find one that has a "compatible" format, I see the following:

目标格式(来自AudioInputStream.getFormat())是:

PCM_SIGNED 44100.0 Hz, 16 bit, stereo, 4 bytes/frame, little-endian

我遍历所有混音器,每个混音器的源代码行和每个源代码行支持的格式,并获得以下匹配项:

I loop through all mixers, source lines for each mixer, and supported formats for each source line, and get the following match:

Mixer: PulseAudio Mixer, version 0.02
Source line: interface SourceDataLine supporting 42 audio formats, and buffers of 0 to 1000000 bytes
Format matches: PCM_SIGNED unknown sample rate, 16 bit, stereo, 4 bytes/frame, little-endian

得到一个匹配项(使用format.matches()),但仍然收到无效格式"异常.也许是因为匹配的格式显示为未知采样率",然后当我尝试打开剪辑时,它发现它实际上并不支持44100 Hz吗?

I do get a match (using format.matches()) yet I still get the "Invalid format" exception. Perhaps because the format that matched says "Unknown sample rate" and then when I try to open the clip, it finds that it does not actually support 44100 Hz ?

推荐答案

好像这里涉及两个独立的问题.

Looks like there are two separate issues involved here.

首先,依靠AudioSystem.getClip()并不是一个好主意,因为基本上不能保证该剪辑将能够处理wav文件的特定格式.而是应使用以下方法之一:

First, relying on AudioSystem.getClip() is not a good idea as basically there's no guarantee that the clip will be able to handle the specific format of the wav file. Instead, one of the following approaches should be used:

  • As suggested by @Dave: Loop through the available mixers and query if the target format is supported:

URL url = getClass().getResource("drop.wav");
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(url);
AudioFormat format = audioInputStream.getFormat();
DataLine.Info lineInfo = new DataLine.Info(Clip.class, format);

Mixer.Info selectedMixer = null;

for (Mixer.Info mixerInfo : AudioSystem.getMixerInfo()) {
    Mixer mixer = AudioSystem.getMixer(mixerInfo);
    if (mixer.isLineSupported(lineInfo)) {
        selectedMixer = mixerInfo;
        break;
    }
}

if (selectedMixer != null) {
    Clip clip = AudioSystem.getClip(selectedMixer); 
    [...]
}

  • 或者,按照@egorlitvinenko的建议建议,使用AudioSystem.getLine(DataLine.Info)获得具有所需功能的行.

  • Or, as suggested by @egorlitvinenko, use AudioSystem.getLine(DataLine.Info) to get a line with the desired capabilities.

    以上两种方法都应该"起作用.

    Both of the above approaches "should" work.

    最重要的是,PulseAudio还存在另一个问题,即存在一个可能会导致格式无效"异常的错误即使PulseAudio混音器实际上可以处理格式 .以下错误报告对此进行了描述(第二个错误报告包含解决方法):

    On top of that, there is an additional problem with PulseAudio, which is that there is a bug which may result in an "invalid format" exception even though the PulseAudio mixer can actually handle the format. This is described in the following bug reports (the second one contains workarounds):

    • https://icedtea.classpath.org/bugzilla/show_bug.cgi?id=3452 (my own)
    • https://icedtea.classpath.org/bugzilla/show_bug.cgi?id=2915

    这篇关于Java音频无法在Linux中播放WAV文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆