Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/384.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 多次使用AudioSystem.getAudioInputStream的nullPointerException_Java_Audio_Nullpointerexception_Mp3_Decode - Fatal编程技术网

Java 多次使用AudioSystem.getAudioInputStream的nullPointerException

Java 多次使用AudioSystem.getAudioInputStream的nullPointerException,java,audio,nullpointerexception,mp3,decode,Java,Audio,Nullpointerexception,Mp3,Decode,几天来,我一直在寻找解码MP3、更改采样并将其重新编码为MP3的方法。 现在这是可行的,我把它放在一个循环中,因为我需要多次重复这个过程 “速率”是一个浮动变量,表示我将乘以音频文件速度的多少 这里的上下文是当我多次调用我的函数时: private void passRates() throws Exception { for (Float rate : this.rates) { String audio = "Some file name.mp

几天来,我一直在寻找解码MP3、更改采样并将其重新编码为MP3的方法。 现在这是可行的,我把它放在一个循环中,因为我需要多次重复这个过程

“速率”是一个浮动变量,表示我将乘以音频文件速度的多少

这里的上下文是当我多次调用我的函数时:

    private void passRates() throws Exception {
        for (Float rate : this.rates) {
            String audio = "Some file name.mp3"
            createAudio(audio, rate);
                for (Beatmap beatmap : this.currentBeatmaps) {
                    createRate(beatmap, audio, rate);
            }
        }
    }
createAudio()函数调用一个类“ConvertMP3”,该类创建一个新的音频文件,其中会发生nullPointerException

这里是马车的部分:

        AudioInputStream in = AudioSystem.getAudioInputStream(this.source);
        AudioFormat baseFormat = in.getFormat();
        AudioFormat decodedFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
            baseFormat.getSampleRate(),
            16,
            baseFormat.getChannels(),
            baseFormat.getChannels() * 2,
            baseFormat.getSampleRate(),
            false);
        AudioInputStream din = AudioSystem.getAudioInputStream(decodedFormat, in);
调用AudioSystem.getAudioInputStream()的最后一行仅适用于第一次迭代。所有迭代都是针对同一个音频文件进行的,每个迭代的每个参数都是“新的”,所以我不明白为什么会出现空值

以下是错误日志的最后一段:

mai 18, 2017 6:57:18 PM beatmaptweaker.menus.MultipleRate 
jButtonStartRatingMouseClicked
GRAVE: null
java.lang.NullPointerException
at javax.sound.sampled.AudioFormat.matches(AudioFormat.java:450)
at javax.sound.sampled.spi.FormatConversionProvider.isConversionSupported(FormatConversionProvider.java:169)
at javax.sound.sampled.AudioSystem.getAudioInputStream(AudioSystem.java:968)
at beatmaptweaker.customClasses.ConvertMP3.newRatedMusicFile(ConvertMP3.java:56)
比较两个AudioFormat对象(调用getAudioInputStream之前刚刚实例化的对象,在循环的每次迭代中都完全相同)时,似乎会触发此错误

所以我被困在这里,我希望有人能明白这一点:/

更新1:我没有在代码中关闭AudioInpuStream。既然我这么做了,它还是不起作用

更新2:错误来自javax.sound.sampled.AudioFormat内部,因为它检查一组格式,但不验证它们是否为null,从而导致崩溃。我无法覆盖该类,因为当我尝试在javax.sound.sampled.spi.FormatConversionProvider中获取格式时,如果我不使用默认类,它将返回一个空数组

以下是不检查null的代码:

    public boolean isConversionSupported(AudioFormat targetFormat, AudioFormat sourceFormat){

         AudioFormat targetFormats[] = getTargetFormats( targetFormat.getEncoding(), sourceFormat );

        for(int i=0; i<targetFormats.length; i++) {
            if( targetFormat.matches( targetFormats[i] ) ) {
                return true;
            }
        }
        return false;
    }

    public boolean matches(AudioFormat format) {
        if (format.getEncoding().equals(getEncoding())
                && (format.getChannels() == AudioSystem.NOT_SPECIFIED
                    || format.getChannels() == getChannels())
                && (format.getSampleRate() == (float)AudioSystem.NOT_SPECIFIED
                    || format.getSampleRate() == getSampleRate())
                && (format.getSampleSizeInBits() == AudioSystem.NOT_SPECIFIED
                    || format.getSampleSizeInBits() == getSampleSizeInBits())
                && (format.getFrameRate() == (float)AudioSystem.NOT_SPECIFIED
                    || format.getFrameRate() == getFrameRate())
                && (format.getFrameSize() == AudioSystem.NOT_SPECIFIED
                    || format.getFrameSize() == getFrameSize())
                && (getSampleSizeInBits() <= 8
                    || format.isBigEndian() == isBigEndian())) {
            return true;
        }
        return false;
    }
支持公共布尔值IsConversion(AudioFormat targetFormat、AudioFormat sourceFormat){
AudioFormat targetFormats[]=getTargetFormats(targetFormat.getEncoding(),sourceFormat);

对于(inti=0;iOk),经过数小时的搜索,我终于解决了我的问题

事实上,AudioInputStream或任何东西在转换时不知何故被耗尽了(是的,当类处理变量时,这很烦人--)

无论如何,我所做的是在做我的事情之前把它转换成一个ByteArray。 这是我的新循环:

private void passRates() throws Exception {
    for (Float rate : this.rates) {
        AudioInputStream in = null;
        in = AudioSystem.getAudioInputStream(new File(this.directory + currentBeatmaps.get(0).getAudioFileName()));
        AudioFormat baseFormat = in.getFormat();
        AudioFormat decodedFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
                baseFormat.getSampleRate(),
                16,
                baseFormat.getChannels(),
                baseFormat.getChannels() * 2,
                baseFormat.getSampleRate(),
                false);
        AudioInputStream din2 = AudioSystem.getAudioInputStream(decodedFormat, in);

        long length = din2.getFrameLength();
        byte[] bytes = IOUtils.toByteArray(din2);
        in.close();
        InputStream is1 = new ByteArrayInputStream(bytes);

        AudioInputStream din = new AudioInputStream(
                is1,
                decodedFormat,
                length
        );
        String audio = this.jInputAudioFilename.getText() + " x" + Float.toString(rate) + ".mp3";
        createAudio(din, this.directory, audio, rate);
        for (Beatmap beatmap : this.currentBeatmaps) {
            createRate(beatmap, audio, rate);
        }
    }
}
我不认为这是优化或任何事情,但这是完美的作品


注意:这在某些MP3文件中似乎不起作用。我导入了一些库并创建了AudioInputStream,但当帧长度未知时,IOUtils.toByteArray()会陷入无限循环中,因为它正在等待EOF。

如果您总是使用相同的音频文件,为什么不使用createAudio()呢函数从for循环中调用,并在for循环之前创建一次?因为我需要我的函数ConvertMP3.newRatedMusicFile()要独立,它只需要一个目录、一个源、一个目标和一个浮点数。将来这首歌可能会改变:/I看不到第一个循环和下一个代码段之间的关系。如果这应该是
createAudio
方法的一部分,则不清楚它对参数做了什么,或者它是如何改变的对象的状态,最明显的是,
this.source
被初始化或修改。this.source是我正在转换的“文件”,它在整个循环中不会改变,只会被读取,不会被写入