有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java无缝音频转换/循环

如何确保两段音频之间的过渡是无缝的

在JavaFX应用程序中,我使用javafx.scene.media.MediaPlayer播放一段介绍,这段介绍由主/循环段进行。媒体播放得很好,但问题是过渡和循环

以下是我目前正在做的事情:

private static void foo(final Media intro, final Media loop) {
        final MediaPlayer introPlayer = new MediaPlayer(intro);
        introPlayer.play();

        final MediaPlayer loopPlayer = new MediaPlayer(loop);
        loopPlayer.pause(); //  An attempt to load the media so it will be ready to be played.

        introPlayer.setOnEndOfMedia(loopPlayer::play());

        loopPlayer.setOnEndOfMedia(() -> loopPlayer.seek(Duration.ZERO));
        //loopPlayer.setCycleCount(Integer.MAX_VALUE); // Similar to the above line, but there is still a delay between loops.
    }

暂停确实有一些帮助,但在介绍媒体结束和循环媒体开始之间有一个非常明显的延迟。此外,在循环介质的结束和重复之间还有另一个明显的延迟

另外,我还尝试使用javafx.scene.media.AudioClip,因为据推测它的开销比javafx.scene.media.MediaPlayer小。我给自己的听众写了一封信,告诉他们曲目什么时候结束(然后立即开始循环),但我仍然看到了类似的延迟

以下是我发现的一些类似帖子,但没有提供问题的解决方案:

JavaFX MediaPlayer playing background music loop with small intro music

This one is definitely relevant (coincidentally, it is almost the anniversary of that post), but I am already using a .wav formatted media file and still experience a delay.

JavaFX AudioClip.play()

Which is similar to what I tried with the Audioclip, exept I used a scheduled executor to time when to replay the audio. (Where I still experienced a delay).

最后一点,我在Audacity中测试了我的音频,它们无缝地转换和循环

对于这些类型的问题,有哪些建议的解决方案

编辑:

  1. 在代码块中添加了一个附录,提到MediaPlayer::setCycleCount(整数)

共 (2) 个答案

  1. # 1 楼答案

    我知道你发帖子已经有一段时间了。你找到答案了吗?我想知道您是否在播放introPlayer之前加载了loopPlayer,如果这样有帮助的话

    如果MediaPlayer的“监听器”有点迟钝,那么切换到使用Java的SourceDataLine和用来触发循环提示的LineListener会更无缝地工作吗?(我将使用Clip进行循环播放。)

    最后一个建议是,我有一个音频库AudioCue可以用于此。该库包括一个AudioCueListener,当提示结束时,它可以触发一个事件(例如开始另一个AudioCue播放)。但由于库的局限性,您需要将音乐保存在内存中,并且源文件必须正确。wav's

  2. # 2 楼答案

    {a1}表示一个音频剪辑代表一段音频,可以以最小的延迟播放,并且可以立即使用。然而,它也指出

    Media objects are however better suited for long-playing sounds. This is primarily because AudioClip stores in memory the raw, uncompressed audio data for the entire sound, which can be quite large for long audio clips. A MediaPlayer will only have enough decompressed audio data pre-rolled in memory to play for a short amount of time so it is much more memory efficient for long clips, especially if they are compressed.

    根据循环介质的长度,AudioClip可能更适合您。您不需要使用ScheduledExecutorService来重放音频,而可以使用AudioClip.setCycleCount(AudioClip.INDEFINITE)来永久循环

    使用此信息,我相信您最好的选择是使用MediaPlayer作为介绍,然后使用MediaPlayer#setOnEndOfMedia调用循环AudioClip;在介绍和循环转换之间可能有一个小的延迟,但在那之后是无缝的