Swift - Avaudioplayer, Sound Doesn't Play Correctly

Swift - AVAudioPlayer, sound doesn't play correctly

You already provided the correct solution to your problem and that would be #2; to have a class-level audioPlayer property. Why is this so?
Well, that's because in the code you setup the player, start the playback, show the pop-up and after everything is done, the method exits its scope. The automated memory management (ARC) works so that any local variables get released when you exit the scope of that variable. If you consider that sound playback is asynchronous (eg. it will play without blocking the main thread), you exit the scope before the audio player is finished playing the sound. ARC notices that audioPlayer is a local variable and releases it at that point, but the sound is not done playing yet.

I hope I was clear enough, if not feel free to ask more!

AVAudioPlayer doesn't play sound when MPMusicPlayerController is playing on iOS

Feeling stupid. The phones were set to silent mode. For some reason, it can play the sounds or the music on silent, but it can't play them both together.

Swift 2 - AVAudioPlayer not playing audio

Here is an example that will work. I am not sure where, in relation to the rest of your code, you have the code that you've shown above. Make sure your device volume is not on silent and is turned up...

 //declare these as instance variables
var AudioURL = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("FileName", ofType: "mp3")!)
var AudioPlayer = AVAudioPlayer()

//inside viewDidLoad establish your AVAudioSession and configure the AudioPlayer with the contents of URL
override func viewDidLoad() {
super.viewDidLoad()

do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
//print("AVAudioSession Category Playback OK")
do {
try AVAudioSession.sharedInstance().setActive(true)
//print("AVAudioSession is Active")
} catch let error as NSError {
print(error.localizedDescription)
}
} catch let error as NSError {
print(error.localizedDescription)
}


do {
try AudioPlayer = AVAudioPlayer(contentsOfURL: AudioURL, fileTypeHint: nil)
} catch {
print("errorin do-try-catch")
}
}

//play audio
@IBAction func playAudio(sender: AnyObject){
AudioPlayer.play()
}

AVAudioPlayer doesn't play the first time

Just so this is closed up and anyone who has the same problem knows this was solved. Like Markov said it was fixed by adding this line of code

try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, withOptions: AVAudioSessionCategoryOptions.MixWithOthers)

The total looks like this

piece of code that loads the sounds

func loadSounds(){
do{
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, withOptions: AVAudioSessionCategoryOptions.MixWithOthers)
try audioPlayerL = AVAudioPlayer(contentsOfURL: startListening!)
try audioPlayerE = AVAudioPlayer(contentsOfURL: doneListening!)
}
catch{
print("error")
}
audioPlayerL.delegate = self
audioPlayerL.prepareToPlay()
audioPlayerE.delegate = self
audioPlayerE.prepareToPlay()
}

method that is being called to play the sounds

func playSound(){
if(startedListening == true){
audioPlayerL.play()
}
else{
audioPlayerE.play()
}
}

AVAudioPlayer not playing any sound

I found the solution and it's related to something I didn't mention and didn't think about: I'm compiling with Automatic Reference Counting (ARC).

ARC inserts a release call to the audio player, so it's deallocated right after leaving the method where it is created. It has nothing to do with AVAudioPlayer but with ARC.

In order to solve this issue, I just created an AVAudioPlayer attribute to the class that deals with sounds so that it is not released anymore by ARC. Well, at least, it's not released until the instance of this class is released.

For more information about ARC, refer to Automatic Reference Counting: Zeroing Weak References with details on why I had this issue.

Why AVAudioPlayer has no sound?

SwiftUI is picky about what you can do in an initializer for a View struct like this. A more reliable option is to move the loading into an ObservableObject:

class AudioManager : ObservableObject {
var audioPlayer : AVAudioPlayer?

func loadAudio(filename: String) {
guard let path = Bundle.main.path(forResource: filename, ofType: "mp3") else {
print("[shark]", filename + "is not found")
return
}
do {
audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: path))
} catch {
print("[shark], audioPlayer cannot load", path, error)
}
}

func playAudio() {
audioPlayer?.play()
}
}

struct ContentView: View {
var shortname: String = ""
var id: Int = 0
@ObservedObject var audioManager = AudioManager()


var body: some View {

Text("good")
.onAppear {
let fileName = self.shortname.lowercased() + "-" + String(id)
audioManager.loadAudio(filename: fileName)
audioManager.playAudio()
}
}
}

This plays for me on Xcode 12.3 and iOS 14



Related Topics



Leave a reply



Submit