简体   繁体   中英

Java Seamless Audio Transition/Loop

How can you ensure the transition between two pieces of audio is seamless?

In a JavaFX application, I am using the javafx.scene.media.MediaPlayer to play an intro-piece, which is proceeded by the main/looping-piece. The media is played just fine, but the issue is the transition and loop.

Here is what I am currently doing:

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.
    }

The MediaPlayer::pause does help some, but there is a very noticeable delay between the end of the intro media and the start of the looping media. Furthermore, there is another noticeable delay between the end of the looping media and the repeat.

I additionally tried using javafx.scene.media.AudioClip , since it supposedly has less overhead than a javafx.scene.media.MediaPlayer . I wrote my own listener to tell when the track ended (and to immediately thereafter start the looping piece), but I still saw a similar delay.

Here were some similar posts I found, but did not provide a solution to the problem:

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).

And, as a final note, I have tested my audio in Audacity, where they transitioned and looped seamlessly.

What are some recommended solutions for these types of problems?

Edit:

  1. Added an addendum to the code-block, mentioning MediaPlayer::setCycleCount(Integer)

The AudioClip Javadocs state that an AudioClip represents a segment of audio that can be played with minimal latency and are usable immediately. However, it also states

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.

Depending on the length of the looping media, an AudioClip might be better suited for you. Instead of needing a ScheduledExecutorService to replay the audio, you can use AudioClip.setCycleCount(AudioClip.INDEFINITE) to loop forever.

Using this info, I believe your best bet is to use a MediaPlayer for the intro and then utilize MediaPlayer#setOnEndOfMedia to call the looping AudioClip ; possibly having a small delay between the intro and looping transition but seamless after that.

I realize it's been a while since you posted. Have you found an answer? I am wondering if you loaded loopPlayer before playing introPlayer , if that would help.

If MediaPlayer's "listener" is just kind of sluggish, maybe switching to using Java's SourceDataLine with a LineListener used to trigger the looping cue would work more seamlessly? (I would use a Clip for the looping playback.)

Last suggestion, I have an audio library AudioCue that could work for this. The library includes an AudioCueListener that can trigger an event (such as starting another AudioCue playing) when a cue ends. But limitations of the library would require that you hold your music in memory, and that the source files be .wav's.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM