简体   繁体   English

SKAction playSoundFileNamed在500 mp3时失败

[英]SKAction playSoundFileNamed failed at 500 mp3

In my application I need to use a lot of short different mp3s (about 500 items one by one) 在我的应用程序中,我需要使用许多简短的不同mp3(一一对应约500个项目)

So I use SKAction playSoundFileNamed 所以我用SKAction playSoundFileNamed

After ~200 sounds it crashed with 'Failed to load resource - Resource s234.mp3 can not be loaded'. 大约200声后,它崩溃,提示“无法加载资源-无法加载资源s234.mp3”。 Memory rises to 70mb. 内存增加到70mb。

How to avoid this? 如何避免这种情况?

What I tried: 我试过的

  1. recreate sound in every iteration 在每次迭代中重新创建声音

     SKAction *mySound=[SKAction playSoundFileNamed:aa waitForCompletion:YES]; 
  2. create the one variable in the beggining of .m 在.m开头创建一个变量

     SKAction *mySound; 

and reuse it in iterations 并在迭代中重复使用

    mySound=[SKAction playSoundFileNamed:aa waitForCompletion:YES];

2. load all sounds to array once at start 2.开始时将所有声音加载到数组

for (int j=0;j<500;j++){
        NSString *aa=[NSString stringWithFormat:@"s%d.mp3", j];
        [item.sounds addObject:[SKAction playSoundFileNamed:aa waitForCompletion:YES]];
    }

...but never changed - it crashes and can't load mp3. ...但从未更改-它崩溃了,无法加载mp3。

How to clean this memory leaks? 如何清除此内存泄漏?

EDITED I also tried to turn off ARC and manually dealloc it every time. 编辑我还尝试关闭ARC,并每次手动对其进行重新分配。 Nothing changed. 没有改变。

You may be better off with a "proper" sound engine. 使用“适当的”声音引擎可能会更好。 You could use AVAudioPlayer or even better, ObjectAL (already included in Kobold Kit ). 您可以使用AVAudioPlayer或什至更好的ObjectAL (已经包含在Kobold Kit中 )。 That way you have more control over preloading and caching the sound files, and treating streaming audio (MP3) differently from short-lived sound effects (usually CAF or WAV). 这样,您可以更好地控制声音文件的预加载和缓存,以及将流音频(MP3)与短暂的声音效果(通常是CAF或WAV)区别对待。

For very short sound files, say shorter than 5 seconds, MP3 isn't ideal. 对于非常短的声音文件(例如少于5秒),MP3并不理想。 You should try CAF/WAV instead. 您应该尝试使用CAF / WAV。

And do consider how much your sound files use in memory. 并考虑一下您的声音文件在内存中使用了多少。 Say each mp3 file is buffered into a 250 KB buffer, times 500, then that uses over 120 MB of memory. 假设每个mp3文件都被缓冲到250 KB的缓冲区中,乘以500,然后占用了120 MB以上的内存。 Do not look at the size of the mp3 file because it's a compressed format, and will likely be buffered uncompressed. 不要看mp3文件的大小,因为它是压缩格式,并且很可能未经压缩就被缓冲。

This little ditty right here will allow you to use a regular old SKAction but customize the playback in code. 这个小技巧可以让您使用常规的旧SKAction,但可以通过代码自定义播放。

https://github.com/pepelkod/iOS-Examples/tree/master/PlaySoundWithVolume https://github.com/pepelkod/iOS-Examples/tree/master/PlaySoundWithVolume

+(SKAction*)playSoundFileNamed:(NSString*)fileName atVolume:(CGFloat)volume waitForCompletion:(BOOL)wait{
// setup audio
NSString*   nameOnly = [fileName stringByDeletingPathExtension];
NSString*   extension = [fileName pathExtension];
NSURL *soundPath = [[NSURL alloc] initFileURLWithPath:[[NSBundle mainBundle] pathForResource:nameOnly ofType:extension]];
AVAudioPlayer *player = [[AVAudioPlayer alloc]initWithContentsOfURL:soundPath error:NULL];
[player setVolume:volume];
[player prepareToPlay];

SKAction*   playAction = [SKAction runBlock:^{
    [player play];
}];
if(wait == YES){
    SKAction*   waitAction = [SKAction waitForDuration:player.duration];
    SKAction* groupActions = [SKAction group:@[playAction, waitAction]];
    return groupActions;
}
return playAction;

} }

I think you're running out of file descriptors. 我认为您的文件描述符用完了。 What i've found is that every time playSoundFileNamed is run the sound file is opened and never closed... so the file descriptor is not released. 我发现,每次运行playSoundFileNamed时,声音文件都是打开的,永远不会关闭...因此文件描述符不会释放。

My testing in instruments leads me to believe there's about 250 available file descriptors. 我在乐器上进行的测试使我相信大约有250个可用的文件描述符。 And my research tells me that not only file access uses them up but other things too. 我的研究告诉我,不仅文件访问耗尽了它们,其他东西也耗尽了。 So I think your ~200 sound files sounds just about right to crash. 因此,我认为您的〜200个声音文件听起来差不多要崩溃了。 Whenever a sound file is the next file that Xcode is trying to access I get nothing from the debugger, but when the next file is a png (I have way more art then sounds) it gives, 每当声音文件是Xcode尝试访问的下一个文件时,我都无法从调试器中获得任何信息,但是当下一个文件是png(我有更多的声音的话),它就会发出声音,

error = 24 (Too many open files) 错误= 24(打开的文件过多)

I found the error while play testing and switching back to my menu scene from the game play scene every time I lost. 我在进行游戏测试时发现错误,并且每次我迷路时都从游戏场景切换回菜单场景。 So normally it didn't matter but running the init method for the game play scene over and over was piling up these open sound files. 因此,通常没关系,但是反复为游戏场景运行init方法会堆积这些打开的声音文件。

I've searched and searched for a way to close these files but have come up with nothing. 我已经搜索并寻找了一种关闭这些文件的方法,但没有解决任何问题。 I'm thinking of implementing a singleton to run my sound and moving all of the playSoundFileNamed calls into it so they only ever get called once. 我正在考虑实现一个单例来运行我的声音,并将所有playSoundFileNamed调用移入其中,以便它们只被调用一次。 I think this is a bug from Apple. 我认为这是Apple的错误。 These files should be closing with ARC. 这些文件应使用ARC关闭。 Has anyone found anything similar? 有没有人发现类似的东西?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM