Java音频剪辑#getFramePosition()在Raspberry Pi上非常慢
这个问题底部的代码片段在我的台式电脑上运行良好,调用Java音频剪辑#getFramePosition()在Raspberry Pi上非常慢,java,audio,raspberry-pi,Java,Audio,Raspberry Pi,这个问题底部的代码片段在我的台式电脑上运行良好,调用clip.getFramePosition()需要1毫秒或更短的时间。在运行Raspbian Stretch和JDK 8u191的Pi 3 Model B+上,调用相同的函数大约需要900毫秒。这似乎太慢了 实际上,我正试图通过JLayer播放MP3文件,但WAV文件也会出现问题,使用WAV文件更容易复制,因为不需要外部依赖项 CPU和内存 运行代码时,top报告的Pi的CPU和内存使用率从不超过10%。我还尝试将音频预加载到字节数组中,并播放
clip.getFramePosition()
需要1毫秒或更短的时间。在运行Raspbian Stretch和JDK 8u191的Pi 3 Model B+上,调用相同的函数大约需要900毫秒。这似乎太慢了
实际上,我正试图通过JLayer播放MP3文件,但WAV文件也会出现问题,使用WAV文件更容易复制,因为不需要外部依赖项
CPU和内存
运行代码时,top
报告的Pi的CPU和内存使用率从不超过10%。我还尝试将音频预加载到字节
数组中,并播放该数组而不是流。它也有同样的问题,因此这似乎不是磁盘I/O瓶颈
阻塞
在运行时,clip
对象是com.sun.media.sound.DirectAudioDevice.DirectDL
的一个实例,其getLongFramePosition()
方法具有一个调用本机
方法的同步块:
synchronized(this.lockNative) {
var1 = DirectAudioDevice.nGetBytePosition(this.id, this.isSournce, this.bytePosition);
}
所以可能有什么东西挡住了我的电话。然而,我认为在播放剪辑时查询其进度是合理的
可能是什么?
有人能解释一下这种缓慢吗?我是否误用了API,或者这只是Raspbian的Java音频实现的一个问题
更新#1:ubuntumate+Liberica
我试着用Liberica JRE 11对UbuntuMate运行代码,但速度仍然很慢
更新#2:外部声卡
我将一个外部USB声卡插入我的pi,并通过它播放音频。我没想到它能解决这个问题,它也没有
更新#3:直接使用JLayer
通过JLayerAdvancedPlayer
类而不是通过Java Sound API播放MP3会更好一些。获得进度需要50毫秒而不是900毫秒,但仍然非常缓慢
更新#4:使用Pi 3型号B
我有一个PI3模型B(不是B+)在周围。当运行最新的Raspbian时,它也有同样的问题。Raspbian Jessie(2016-03-18)的速度稍快(约700毫秒),但不多
示例代码
import java.io.File;
import java.io.InputStream;
import java.util.Date;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
public class Main {
public static void main(String[] args) throws Exception {
File file = new File("/home/pi/beat.wav");
AudioInputStream ais = AudioSystem.getAudioInputStream(file);
AudioFormat format = ais.getFormat();
Clip clip = AudioSystem.getClip();
clip.open(ais);
clip.start();
for (int i = 0; i < 100; i++) {
long start = new Date().getTime();
long pos = clip.getFramePosition();
long duration = new Date().getTime() - start;
System.out.println("Pos: " + pos + ", duration: " + duration);
Thread.sleep(10);
}
}
}
导入java.io.File;
导入java.io.InputStream;
导入java.util.Date;
导入javax.sound.sampled.AudioFormat;
导入javax.sound.sampled.AudioInputStream;
导入javax.sound.sampled.AudioSystem;
导入javax.sound.sampled.Clip;
公共班机{
公共静态void main(字符串[]args)引发异常{
File File=新文件(“/home/pi/beat.wav”);
AudioInputStream ais=AudioSystem.getAudioInputStream(文件);
AudioFormat=ais.getFormat();
Clip Clip=AudioSystem.getClip();
夹子。打开(ais);
clip.start();
对于(int i=0;i<100;i++){
长启动=新日期().getTime();
long pos=clip.getFramePosition();
长持续时间=新日期().getTime()-开始;
系统输出打印项次(“Pos:+Pos+”,持续时间:+duration);
睡眠(10);
}
}
}
new Date().getTime()
相当于System.currentTimeMillis()
。无法保证系统时钟实际具有毫秒精度。@greg-449这只是一个重现问题的片段。我从来没有找到解决这个问题的办法,所以我减少了损失,买了一台二手的MacMini来运行我的软件。仍然有兴趣找出为什么它在Pi上如此缓慢!