Android 上使用 SoundPool 实现无缝循环?

发布于 2024-12-22 20:32:17 字数 320 浏览 2 评论 0原文

我尝试使用 SoundPool 类循环短(20kb)、无间隙 ogg 文件,但在硬件测试时无法获得一致的结果。它总是使用模拟器完美播放,但当我在 Nexus 1 或 Samsumg Galaxy Tab 10.1 上测试时,每个循环点都会听到爆音或点击声。非常奇怪的是,虽然应用程序启动后保持一致,但每次重新启动应用程序时,点击次数都略有不同,并且在极少数情况下(在平板电脑上更频繁),循环播放正确。

使用 MediaPlayer 的结果也好不了多少。期望在 Android 上无缝播放音频循环是不合理的吗?肯定有人有类似的功能可以正常工作吗?如果是这样,我很想看看它是如何工作的例子。

谢谢!

I am trying to loop short (20kb), gapless ogg files with the SoundPool class and cannot get consistent results while testing on hardware. It always plays back perfectly using the emulator but when I test on a Nexus 1, or on a Samsumg Galaxy Tab 10.1 there are audible pops or clicks at every loop point. What is very strange is that while consistent once the application has started, the clicks are slightly different every time I restart the app and on rare occasions (more frequently on the tablet) the loop plays correctly.

The results are no better using MediaPlayer. Is it unreasonable to expect gapless playback of audio loops on android? Surely someone has similar functionality working properly? If so I would love to see an example of how it works.

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(3

撧情箌佬 2024-12-29 20:32:17

我使用了一种对单个文件效果很好的 hack:

HACK_loopTimer = new Timer();
HACK_loopTask = new TimerTask() {               
    @Override public void run() {
        mMediaPlayer.seekTo(0);
    }
};
long waitingTime = mMediaPlayer.getDuration()-mHackLoopingPreview;
HACK_loopTimer.schedule(HACK_loopTask, waitingTime, waitingTime);

只需将 mHackLoopingPreview 设置为合理的数量即可;我用的是 100ms,效果很好。我必须承认,这是一个不太理想且丑陋的解决方案,但至少它完成了它的工作。

I used a hack that works fine for single files:

HACK_loopTimer = new Timer();
HACK_loopTask = new TimerTask() {               
    @Override public void run() {
        mMediaPlayer.seekTo(0);
    }
};
long waitingTime = mMediaPlayer.getDuration()-mHackLoopingPreview;
HACK_loopTimer.schedule(HACK_loopTask, waitingTime, waitingTime);

Just set mHackLoopingPreview to a reasonable amount; I'm using 100ms and it is working fine. I have to agree that this is a less than ideal and ugly solution, but at least it does its job.

明天过后 2024-12-29 20:32:17

我找到了其他解决方案:

afd = assetManager.openFd(nameSound);

player.setDataSource(afd.getFileDescriptor(),
                     afd.getStartOffset(), afd.getLength() - 1000);
afd.close();
player.prepare();
player.setLooping(true);
player.start();

您只需定义持续时间少 1000(1ms),而不是总持续时间。是的,结果是问题!!!!

I found other solution:

afd = assetManager.openFd(nameSound);

player.setDataSource(afd.getFileDescriptor(),
                     afd.getStartOffset(), afd.getLength() - 1000);
afd.close();
player.prepare();
player.setLooping(true);
player.start();

You only need to define the duration 1000(1ms) less instead that the total duration. Y eso es todo, problema resuelto!!!!

古镇旧梦 2024-12-29 20:32:17

这听起来像是一种逃避,但你可以尝试两件事,其中第一件事对我有用。

  1. 以 48kHz 采样率和 48Kbit/s 制作 ogg 格式的音频文件(这对我有用)

  2. 您可以创建 2 个 MediaPlayer 对象,并且(就像 @Beowulf Bjornson 的答案)大约 <= 100ms 在 MediaPlayer #1 之前启动 MediaPlayer #2结束并在整个时间之间交替。

希望来到这里的人们尝试一下我所说的,因为我花了大约 3 天的时间试图解决这个问题,结果却惊讶地发现没有一种开箱即用的方法可以完美地做到这一点。

This might sound like a cop out but there are a 2 things you can try, the first of which worked for me.

  1. Make you audio files ogg format at 48kHz sample rate and 48Kbit/s (This worked for me)

  2. You can create 2 MediaPlayer Objects and (just like the @Beowulf Bjornson 's answer) approximately <= 100ms start MediaPlayer #2 just before MediaPlayer #1 ends and alternate between the entire time.

Hope people that come here tries what I've said because I've wasted about 3 days trying to figure this out only to be amazed that there isn't an out of the box way to do this flawlessly.

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