Audio is not playing without breakpoint - ios

The sound file is playing when i add breakpoints inside the below functions. But the sound file is not playing if i run the application without breakpoint.
I am calling this function in button click as Sound().playSounds()
import AVFoundation
class Sound {
private var audioplayer:AVAudioPlayer!
func playSounds()
{
if let path = Bundle.main.path(forResource: "Audio/ring.mp3", ofType: nil)
{
let url = URL(fileURLWithPath: path)
do {
self.audioplayer = try AVAudioPlayer(contentsOf: url)
self.audioplayer.numberOfLoops = 3
self.audioplayer.prepareToPlay()
self.audioplayer.play()
}
catch {
print("Couldn't load file")
}
}
}
}

Your Sound object gets deallocated before it has a chance to play a sound.
Store it where you are calling it from:
var sound = Sound()
// for example to play sound call
func playPressed(){
sound.playSounds()
}

Chane your player into a global variable like this. Otherwise it'll be a deadlock.
var audioplayer:AVAudioPlayer!
Also you may want to change your resource path extracting logic to below,
if let path = Bundle.main.path(forResource: "ring.mp3", ofType: "mp3")
Or you can directly use Bundle.main.url(forResource: withExtention) method.

Related

How do I synchronize background music and buttons?

An application writes. Music plays on the background of the application. And I want to stop and resume this music from every page of the application
But after pressing the music stop button on one page, the buttons on the other pages do not change.
And when I go back to the first page, the music starts all over again.
import Foundation
import AVFoundation
class Music {
static var audioPlayer : AVAudioPlayer?
enum SoundEffect {
case background
}
static func playSound(effect : SoundEffect) {
var soundFileName = ""
switch effect {
case.background:
soundFileName = "background"
}
let bundlePath = Bundle.main.path(forResource: soundFileName, ofType: "wav")
guard bundlePath != nil else {
print("Couldn't find sound file \(soundFileName) in the bundle")
return
}
do {
let soudURL = URL(fileURLWithPath: bundlePath!)
audioPlayer = try AVAudioPlayer(contentsOf: soudURL)
audioPlayer!.numberOfLoops = -1
audioPlayer?.prepareToPlay()
audioPlayer?.play()
} catch {
}
}
}
Al first check AVAudioPlayer is already initialize or not and after that check player is playing or stop.
if let audioPlayer = Music.audioPlayer, audioPlayer.playing {
audioPlayer.stop()
}

Swift 4: How to have a sound play over itself when a button is pushed?

So my current situation is that whenever I press a button, the sound will restart from the beginning and cut off the already playing sound. What I want is the sound to play over itself when I push the button, so if I push it a second time right after the first time, the second sound would play over the first one and not cut it off. Please let me know if you need clarification on what I need. Here is my code so far:
#IBAction func bull(_ sender: Any) {
let url = Bundle.main.url(forResource: "Bull", withExtension: "mp3")!
do
{
player = try AVAudioPlayer(contentsOf: url)
guard let player = player else { return }
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
player.prepareToPlay()
player.play()
}
catch let error
{
print(error.localizedDescription)
}
}
Thanks.
One player can play one sound at a time only. You probably have to do following
Create an array of players
var arrPlayer: [AVAudioPlayer] = []
And then inside your method do the following
let url = Bundle.main.url(forResource: "Bull", withExtension: "mp3")!
do
{
player = try AVAudioPlayer(contentsOf: url)
arrPlayer.append(player)
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryAmbient)
try AVAudioSession.sharedInstance().setActive(true)
arrPlayer.last?.prepareToPlay()
arrPlayer.last?.play()
}
catch let error
{
print(error.localizedDescription)
}

Music playing over the song when i return to the original VC

I am using xcode 9 and swift 4 for my app. In my app i have music playing in the viewDidLoad. When i exit the view controller to go to another View, it continues to play like it should. How ever, when i return to that view controller the song starts to play again. This song is overlapping the song that first loaded. Do you guys have any ideas on how to stop this from happening?
do
{
let audioPath = Bundle.main.path(forResource: "APP4", ofType: "mp3")
try player = AVAudioPlayer(contentsOf: NSURL(fileURLWithPath: audioPath!) as URL)
}
catch
{
//catch error
}
let session = AVAudioSession.sharedInstance()
do
{
try session.setCategory(AVAudioSessionCategoryPlayback)
}
catch
{
}
player.numberOfLoops = -1
player.play()
It starts playing again, because your viewDidLoad is called again, which asks it to play it again. A simplest fix would be to keep a static bool variable to keep track if you have already made this call.
static var isMusicPlaying: Bool = false
In your viewDidLoad, you can put code before the code that calls the play.
guard !isMusicPlaying else {
return
}
isMusicPlaying = true

iOS: audio files used in app sound harsher than when played outside the app

The audio files for our iOS app sound much worse when played through the app than when played outside the app. The sounds seem harsher and more "ecohy".
Here's our code for playing audio. Are we somehow altering the playback or natural sound of the audio?
Two of the audio files we're using can be found here:
private func createAudioPlayer(filename: String) -> AVAudioPlayer {
// Define file URL
let path = Bundle.main.path(forResource: filename, ofType: nil)
let url = URL(fileURLWithPath: path!)
// Create player
let audioPlayer: AVAudioPlayer!
do {
audioPlayer = try AVAudioPlayer(contentsOf: url)
} catch {
audioPlayer = nil
printError("Error creating audio player for \(url): \(error)")
logEvent("Audio Error", userData: nil)
}
// Print status
print("Created audio player for \(filename)")
// Return player
return audioPlayer
}
func play(file: AudioFileEnum) {
if let player = audioPlayers[file] {
if player.isPlaying {
player.pause()
}
player.currentTime = 0
player.play()
} else {
printError("Error finding audio player for \(file)")
}
}
Have you tried setting the volume on the audioPlayer object to something smaller, like 0.05f, and adjusting from there?

Swift - AVAudioPlayer not playing sound

I have a sound called speeding.mp3 and I am trying to make a AVAudioPayer instance with it by doing this in the root of the class:
let speedingAudioPlayer = try! AVAudioPlayer(contentsOfURL: NSBundle.mainBundle().URLForResource("speeding", withExtension: "mp3")!)
Then when I run the app it throws an error but I don't know why this is happening. The speeding.mp3 file is in the Bundle Resources drop down in Build Phases so it should find it fine. If I try to print out the URL in the simulator and paste it into Safari it loads and plays the file like normal. I am importing AVFoundation into the class and the framework into the project.
Use this code snippet to debug your error,
if let URL = NSBundle.mainBundle().URLForResource("speeding", withExtension: "mp3") {
do {
let speedingAudioPlayer = try AVAudioPlayer(contentsOfURL: URL)
} catch let error as NSError {
print(error.localizedDescription)
}
} else {
print("No such file exist")
}
I found another question where the var is placed outside the class because otherwise it would be deallocated by the phone.
AVAudioPlayer Object Sound Not Playing - Swift
import UIKit
import AVFoundation
class CustomAudioPlayer {
var audioPlayer : AVAudioPlayer!
override func viewDidLoad() {
super.viewDidLoad()
playSound("sound_file_name")
}
func playSound(soundName: String)
{
let alertSound = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource(soundName, ofType: "mp3")!)
do{
audioPlayer = try AVAudioPlayer(contentsOfURL:alertSound)
audioPlayer.prepareToPlay()
audioPlayer.play()
}catch {
print("Error getting the audio file")
}
}
}
Try this code for playing the sound.

Resources