我在 Kotlin 中有一个简单的音频测试程序,它使用Clip
:
import java.io.File
import java.util.concurrent.CountDownLatch
import javax.sound.sampled.AudioSystem
fun main(args: Array<String>) {
println("Getting clip...")
val clip = AudioSystem.getClip()
println("Opening clip...")
clip.open(AudioSystem.getAudioInputStream(File("/path/to/my/audio/file.wav")))
println("Adding line listener...")
clip.addLineListener {
println("[ line listener ] $it")
}
println("Starting clip...")
clip.start()
Thread.sleep(500)
println("Stopping clip...")
clip.stop()
Thread.sleep(1000)
println("Restarting clip...")
clip.start()
// wait forever so we can see any more line listener events
val latch = CountDownLatch(1)
latch.await()
}
我的音频文件长 1.1 秒。我希望这个程序播放文件的前 0.5 秒,暂停 1 秒,然后播放完文件。当播放开始时,我希望收到一个START
LineListener 事件,当播放停止/暂停时,我希望收到一个STOP
LineListener 事件。我还希望START
在取消暂停剪辑时收到另一个事件,并在STOP
到达文件末尾时收到最终事件。但是,我的输出看起来像:
Getting clip...
Opening clip...
Adding line listener...
Starting clip...
[ line listener ] Start event from line com.sun.media.sound.DirectAudioDevice$DirectClip@6afa9656
Stopping clip...
[ line listener ] Stop event from line com.sun.media.sound.DirectAudioDevice$DirectClip@6afa9656
Restarting clip...
我可以听到音频文件按预期停止、暂停和完成播放,但在重新启动剪辑后我没有收到任何 LineListener 事件。如果我不暂停并重新启动剪辑,我会正确收到文件结束STOP
事件。
为什么我在恢复剪辑后看不到任何 LineListener 事件?
编辑:
如果我添加这一行
clip.framePosition = clip.framePosition
紧随其后clip.stop()
,Thread.sleep(1000)
问题消失, LineListener 收到预期的事件:
Getting clip...
Opening clip...
Adding line listener...
Starting clip...
[ line listener ] Start event from line com.sun.media.sound.DirectAudioDevice$DirectClip@3ddc3924
Stopping clip...
[ line listener ] Stop event from line com.sun.media.sound.DirectAudioDevice$DirectClip@3ddc3924
Restarting clip...
[ line listener ] Start event from line com.sun.media.sound.DirectAudioDevice$DirectClip@3ddc3924
[ line listener ] Stop event from line com.sun.media.sound.DirectAudioDevice$DirectClip@3ddc3924
这是 Clip 实现中的错误吗?