英文:
Flutter Audioplayers delay
问题
我正在使用Flutter框架编写一个小游戏。
我正在使用audioplayers来处理声音。
这种方式在例如每秒调用2次时工作正常。
但是当我在下一秒内多次调用它超过5次时,声音会出现延迟,然后大约一秒后所有声音都会同时播放:) 这听起来很奇怪。
我还在我的iPhone上测试了来自GitHub的audioplayers示例。以低频率重复播放声音是可以的,但是当我尽可能快地重复点击按钮时,到某个时候会出现一些延迟,同样的情况也发生了。
是否有一种方法可以在播放下一个声音之前停止上一个声音,或者这不可能?
还有没有其他处理声音的想法?
这是我使用它的方式:
AudioCache upgradeSound = new AudioCache();
void playUpgradeSound() {
_playUpgradeSound(upgradeSound);
}
void _playUpgradeSound(AudioCache ac) async{
await ac.play('audio/upgr.mp3');
}
非常感谢!
英文:
I'm coding a small game with the Flutter Framework.
I'm using audioplayers for the Sounds.
It works fine like this, when calling it for example 2 times a second.
But whenn I call it more than 5 times and again in the next second at some point the sound has like a delay and then after a second or so all the sounds play at once That sounds weired.
I also tested the audioplayers example from github on my iphone. Repeating the sounds in low frequency is ok, but when I repeat clicking the button as fast as possible at some point it gets some delay and the same thing is happening.
Is there some way to stop the previous Sound before and then playing the next one or isnt this possible?
Or is there some other Idea how to deal with the sounds?
This is how I use it:
AudioCache upgradeSound = new AudioCache();
void playUpgradeSound() {
_playUpgradeSound(upgradeSound);
}
void _playUpgradeSound(AudioCache ac) async{
await ac.play('audio/upgr.mp3');
}
Thank you very much in advance
答案1
得分: 3
我通过使用单例类来解决类似的问题,第一次播放后,我可以获取状态,并停止之前的播放。
class Audio {
static final playerCache = AudioCache();
static AudioPlayer audioPlayer;
static void play(String audioName) async {
audioPlayer = await playerCache.play('$audioName.mp3');
}
static void stop() {
audioPlayer.stop();
}
}
...
child: IconButton(
onPressed: () {
try {
if (Audio.audioPlayer.state ==
AudioPlayerState.PLAYING) {
Audio.stop();
} else {
Audio.play('bid');
}
} catch (e) {
Audio.play('bid');
}
},
...
英文:
I solve similar problem by having singleton class, and after first play I can get the state, and I can stop previous play.
class Audio {
static final playerCache = AudioCache();
static AudioPlayer audioPlayer;
static void play(String audioName) async {
audioPlayer = await playerCache.play('$audioName.mp3');
}
static void stop() {
audioPlayer.stop();
}
}
...
child: IconButton(
onPressed: () {
try {
if (Audio.audioPlayer.state ==
AudioPlayerState.PLAYING) {
Audio.stop();
} else {
Audio.play('bid');
}
} catch (e) {
Audio.play('bid');
}
},
...
答案2
得分: 1
在其文档中有一行代码。
要使用低延迟 API,更适合于游戏声音,请使用:
AudioPlayer audioPlayer = AudioPlayer(mode: PlayerMode.LOW_LATENCY);
在此模式下,后端不会触发任何持续时间或位置更新。此外,无法使用 seek 方法设置音频到特定位置。此模式在 Web 上也不可用。
希望这对您有帮助。
英文:
There is a line of code in its own documentation.
> To use the low latency API, better for gaming sounds, use:
>
> AudioPlayer audioPlayer = AudioPlayer(mode: PlayerMode.LOW_LATENCY);
>
> In this mode the backend won't fire any duration or position updates. Also, it is not possible to use the seek method to set the audio a specific position. This mode is also not available on web.
I hope it is useful.
答案3
得分: 0
每个音频播放器只能播放它当前捕获的文件(就像它想要在那里写下一些东西一样),并阻止其他音频播放器捕获它。因此,如果您想要每秒点击按钮五次,并听到所有声音的同时声音以及之前声音的后声音,您需要五个新的音频播放器(哈希表<键:音频播放器()>),每个播放其自己的文件,每个来自自己的文件夹(如果文件名相同,将复制到临时目录)。音频播放器在其声音完成之前不会提供文件访问权限。或者您将不得不执行MyTableOfAudioplayers[i].dispose()以中断每个未完成的声音以停止播放,并返回文件的开放访问权限给其他音频播放器。
问题是由于对仍在播放的文件缺乏访问权限引起的(操作系统错误:文件正被另一个进程占用)。
结果要么是超过1 GB的内存泄漏和一个小文件夹,其中包含60 MB的音频文件,要么根本没有内存泄漏(只有120 MB的RAM),但有大量临时文件夹(例如60 MB * 10)。
而且在播放过程中不能执行.dispose(),否则会出现红屏或灰屏(严重错误,几乎是崩溃)。此外,如果不执行.dispose(),而执行.release(),那么音频播放器将不再能够访问其文件,即使您尝试将其还给它也不行。我们需要创建音频播放器的新副本,并将其添加到我们的音频播放器哈希表中。这是我理解发生情况的方式。如果有一种允许多个进程读取同一个文件而不会泄漏内存的方法,那将是最佳解决方案。
英文:
Each audio player can only play the file it currently captures (As if he wants to write something down there) and prevents another audio player from capturing it. Therefore, if you want to click on the button five times per second and hear the simultaneous sound of all sounds and the after sound from the previous ones, you need five new audio players (hash table <key:audioPlayer()>), each of which plays its own file, each from its own folder (each will be copied to a temporary directory if the filename is the same). The audio player will not give access to the file until its sound is completed. Or you will have to do MyTableOfAudioplayers[i].dispose() breaking off every unfinished sound to stop playback and return open access to the file to other audio players.
The problem is caused by the lack of access to the still-sounding file (OS error: file is busy by another process).
The result is either a memory leak of more than 1 GB and a small folder with 60 MB of audio files, or no memory leak at all (only 120 MB of RAM), but with a lot of temporary folders (for example 60 MB * 10).
And you can’t do .dispose() during playback, otherwise - a red or gray screen (a serious mistake, almost a crash). Also, if you do not .dispose(), but do .release(), then the Audio Player will no longer get access to its file, even if you try to return it to it. We need to create a new copy of the audio player, adding it to our audioPlayers hash table. This is how I understand what's going on. If there is a way to allow multiple processes to read the same file without leaking memory, then that WOULD BE the BEST solution.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论