El sonido de AVAudioPlayer no se reproduce

En iOS 8 / Xcode 6 tenía una function que incluía un efecto de sonido. Ya no funciona en iOS 9 después de cambiar el código varias veces. Esto es lo que he intentado:

Original:

let bangSoundEffect = SKAction.playSoundFileNamed("Bang.mp3", waitForCompletion: false) runAction(bangSoundEffect) 

Otro bash:

 self.runAction(SKAction.playSoundFileNamed("Bang.mp3", waitForCompletion: false)) 

También:

 func playRocketExplosionSound(filename: String) { let url = NSBundle.mainBundle().URLForResource( filename, withExtension: nil) if (url == nil) { print("Could not find file: \(filename)") return } var error: NSError? = nil do { backgroundMusicPlayer = try AVAudioPlayer(contentsOfURL: url!) } catch let error1 as NSError { error = error1 backgroundMusicPlayer = nil } if backgroundMusicPlayer == nil { print("Could not create audio player: \(error!)") return} backgroundMusicPlayer.numberOfLoops = 1 backgroundMusicPlayer.prepareToPlay() backgroundMusicPlayer.play() } playRocketExplosionSound("Bang.mp3") 

Me estoy sacando el pelo. ¡Estoy usando el mismo código en una escena diferente para otro efecto de sonido y funciona bien! ¿Qué sucede mal? Me he dado count de que el efecto de sonido comienza a reproducirse a veces en el simulador, sin embargo, no se completa y arroja este error:

 2015-09-24 19:12:14.554 APPNAME[4982:270835] 19:12:14.553 ERROR: 177: timed out after 0.012s (735 736); mMajorChangePending=0 

No funciona en absoluto en dispositivos reales.

¿Cuál es el problema? Unesdoc.unesco.org

Posible problema con el file MP3

Es probable que el problema esté conectado con el file MP3 que está utilizando. El código funciona para otros sonidos, esto sugiere que el file MP3 podría estar dañado y AVAudioPlayer falla al decodificarlo. Puede intentar volver a codificar este file y ver si el problema persiste. O, incluso mejor, convertirlo a WAV .

Uso de WAV

La regla general del pulgar al crear efectos de sonido cortos para juegos, es usar WAV less que realmente sientas que necesitas recortar la grasa.

Los mejores juegos van a la calidad de producción de primera línea, por lo que graban y producen activos sin comprimir a 24bit / 48kHz . Los títulos con ambiciones levemente menores podrían grabar y producir en 16 / 44.1 , que es el estándar oficial para el audio de calidad de CD .

Esto tiene al less dos beneficios. Una es que el sonido tiene una mejor calidad. Segundo, la CPU no tiene que decodificar el file para reproducirlo.

testing esto:

 dispatch_async(dispatch_get_main_queue(), { (self.playRocketExplosionSound("Bang.mp3") }) 

ya no es seguro reproducir audio en subprocess secundario en iOS 9.

Archivo de datos corruptos | AVAudioPlayer fuera del scope


1. file de datos corrupto

Esto asegurará que haya encontrado el file:

  var backgroundMusicPlayer: AVAudioPlayer? = nil if let url = Bundle.main.url( forResource: "Bang", withExtension: "mp3") { do { try backgroundMusicPlayer = AVAudioPlayer(contentsOf: url) backgroundMusicPlayer!.play() } catch {} } return nil 

2. AVAudioPlayer fuera del scope

La variable que retiene backgroundMusicPlayer no debe salir del ámbito antes de que play() haya completado y regrese. Esto generalmente se logra mediante el uso de una variable de class:

 var backgroundMusicPlayer: AVAudioPlayer? = nil 

No haga esto: el sonido siguiente se reproducirá, en el mejor de los casos, outOfScopeDelay debido al scope local de var audioPlayer .

 let outOfScopeDelay = 0.5 do { var audioPlayer:AVAudioPlayer! // Incorrectly scoped variable try audioPlayer = AVAudioPlayer(contentsOf: audioRecorder.url) audioPlayer.play() Thread.sleep(forTimeInterval: outOfScopeDelay) } catch {} 

► Encuentra esta solución en GitHub y detalles adicionales sobre Swift Recipes .