如何确保两个音频之间的过渡是无缝的?
在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.
}
MediaPlayer :: pause确实有所帮助,但是在介绍性媒体结束与循环媒体开始之间存在非常明显的延迟。此外,循环媒体的结束与重复之间还有另一个明显的延迟。
我还尝试使用javafx.scene.media.AudioClip
,因为它据说比javafx.scene.media.MediaPlayer
的开销少。我写了自己的听众来告诉曲目何时结束(并在此之后立即开始循环播放),但是我仍然看到类似的延迟。
以下是我找到的一些类似帖子,但没有提供解决问题的方法:
JavaFX MediaPlayer playing background music loop with small intro music
这绝对是相关的(巧合的是,几乎 该帖子的周年纪念日),但我已经在使用.wav格式 媒体文件,但仍然会延迟。
与我使用Audioclip尝试过的类似,例如我使用了 安排执行者定时重播音频。 (我还在哪里 经历了延迟)。
最后,我在Audacity中测试了我的音频,使它们无缝过渡和循环。
针对这些类型的问题,有哪些推荐的解决方案?
编辑:
答案 0 :(得分:0)
AudioClip Javadocs状态,一个AudioClip表示一段音频,可以以最小的延迟播放并立即可用。但是,它也指出
但是,媒体对象更适合长时间播放的声音。这主要是因为AudioClip在内存中存储了整个声音的原始,未压缩的音频数据,这对于较长的音频剪辑而言可能会很大。 MediaPlayer将仅在内存中预滚动足够的解压缩音频数据以在短时间内播放,因此对于较长的剪辑(特别是压缩后的剪辑),其存储效率要高得多。
根据循环媒体的长度,AudioClip
可能更适合您。无需使用ScheduledExecutorService
来重放音频,您可以使用AudioClip.setCycleCount(AudioClip.INDEFINITE)
进行永久循环。
使用此信息,我相信您最好的选择是对介绍使用MediaPlayer
,然后利用MediaPlayer#setOnEndOfMedia
调用循环AudioClip
;简介和循环过渡之间的延迟可能很小,但此后是无缝的。
答案 1 :(得分:0)
我知道距您发布已经有一段时间了。找到答案了吗?我想知道您是否在玩loopPlayer
之前加载了introPlayer
,是否有帮助。
如果MediaPlayer的“监听器”有点呆板,也许切换到使用Java的SourceDataLine
和LineListener
来触发循环提示会更无缝地工作吗? (我将使用Clip
进行循环播放。)
最后的建议是,我有一个音频库AudioCue可用于此目的。库中包含一个AudioCueListener
,当提示结束时,该AudioCue
可以触发事件(例如开始播放另一个arr1 = [1,2,3,4,5,8,9,0,7,8,6]
arr2 = [6,5,7,2,3,4,5,9,1,22]
arr3 = [6,2,3,4,5,7]
)。但是该库的局限性要求您将音乐保存在内存中,并且源文件必须是.wav。