声音和显示同步问题

发布于 2024-10-22 05:38:10 字数 1231 浏览 6 评论 0原文

我有一个播放 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

旧城烟雨 2024-10-29 05:38:10

经过多次实验,看来问题出在模拟器上。当我在更快的工作站上运行所有内容时,问题似乎就消失了。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文