声音和显示同步问题
我有一个播放 mp3 文件的应用程序,我正在尝试与我们为声音播放列出的某些时间同步更新自定义字段(有点像卡拉 OK 效果)。我正在使用 Handler
来安排这些更新。在我的自定义字段类中,我定义了一个 Runnable
,它应该在正确的时间运行更新:
private final Runnable mTrigger = new Runnable() {
@Override
public void run() {
int now = mPlayer.getCurrentPosition();
if (mState == STATE_PLAYING && mUpdateAction != null) {
if (mTriggerTime - now > MAX_PREMATURE_TRIGGER) {
// Sound is lagging too much; reschedule this trigger
mHandler.postDelayed(this, mTriggerTime - now);
} else {
// Run the update
mUpdateAction.run();
}
}
}
};
当我调用 mPlayer.start()
时,我通过以下方式安排第一次更新调用mHandler.postDelayed(mTrigger, timeToFirstUpdate)
。每个更新操作决定下一次更新是什么并安排它(通过调用 mHandler.postDelayed(mTrigger, timeToNextUpdate) )。更新时间通常相隔几百毫秒。
问题在于,虽然某些更新会在预定时间迅速发生,但其他更新可能会延迟 200 毫秒或更多,这对用户来说是相当明显的。在这些更新之间,除了播放声音之外,我没有在我的应用程序中执行任何操作。 (没有后台工作线程;没有其他显示更新。)延迟似乎是随机的,并且每次都有很大差异。
我没想到 postDelayed
的时间安排会这么不精确!我不知道这是模拟器问题还是我的方法有问题。声音播放是否会扰乱 UI 线程循环的计时?我是否应该将计时移至后台线程(从后台线程调用 mPlayer.getCurrentPosition() 是否安全)?还有别的事吗?
I have an app that plays an mp3 file and I'm trying to update a custom field in synchrony with certain times we have tabulated for the sound playback (kind of like a karaoke effect). I'm using a Handler
to schedule these updates. In my custom field class, I define a Runnable
that is supposed to run the update at the right time:
private final Runnable mTrigger = new Runnable() {
@Override
public void run() {
int now = mPlayer.getCurrentPosition();
if (mState == STATE_PLAYING && mUpdateAction != null) {
if (mTriggerTime - now > MAX_PREMATURE_TRIGGER) {
// Sound is lagging too much; reschedule this trigger
mHandler.postDelayed(this, mTriggerTime - now);
} else {
// Run the update
mUpdateAction.run();
}
}
}
};
When I call mPlayer.start()
I schedule the first update by calling mHandler.postDelayed(mTrigger, timeToFirstUpdate)
. Each update action decides what the next update will be and schedules it (by calling mHandler.postDelayed(mTrigger, timeToNextUpdate)
). The updates times are typically a few hundred milliseconds apart.
The problem is that, while some updates are happening promptly at the scheduled times, others can be delayed by 200 milliseconds or more, which is quite noticeable to the user. I'm not doing anything in my app between these updates other than playing the sound. (No background worker threads; no other display updates.) The delays appear to be random and vary considerably each time through.
I didn't think that the timing for postDelayed
would be this imprecise! I don't know if this is an emulator issue or a problem with my approach. Does sound playback screw up the timing of the UI thread loop? Should I move the timing into a background thread (and is it safe to call mPlayer.getCurrentPosition()
from a background thread)? Something else?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
经过多次实验,看来问题出在模拟器上。当我在更快的工作站上运行所有内容时,问题似乎就消失了。
After much experimenting, it seems like the problem is the emulator. When I ran everything on a speedier workstation, the problem seems to have gone away.