Reputation: 277
below is the code representing a file for an audio player. I'm trying to utilize it for playing sounds in my program. I don't want to put a AVPlayer function in every view controller to play repeatable sounds, so I'm looking for a way to put everything in one place and call to the specific function (music, click, intro) when needed
import UIKit
import AVFoundation
class player: UIViewController
{
var music:Bool = true
var sound:Bool = true
var intro:Bool = true
var soundPlayer: AVAudioPlayer?
var clickPlayer: AVAudioPlayer?
var musicPlayer : AVAudioPlayer?
{
get
{
let appDelegate = UIApplication.shared.delegate as! AppDelegate
return appDelegate.musicPlayer
}
set
{
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.musicPlayer = newValue
}
}
func playSound(title: String, format: String)
{
if sound == true
{
guard let url = Bundle.main.url(forResource: title, withExtension: format)
else { return }
do
{
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
try AVAudioSession.sharedInstance().setActive(true)
soundPlayer = try AVAudioPlayer(contentsOf: url)
soundPlayer?.play()
}
catch let error
{
print(error.localizedDescription)
}
}
}
func playClick()
{
if sound == true
{
guard let url = Bundle.main.url(forResource: "click", withExtension: "mp3")
else { return }
do
{
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
try AVAudioSession.sharedInstance().setActive(true)
let clickPlayer = try AVAudioPlayer(contentsOf: url)
clickPlayer.play()
}
catch let error
{
print(error.localizedDescription)
}
}
}
func playMusic()
{
if music == true
{
guard let url = Bundle.main.url(forResource: "ambientMusic", withExtension: "mp3")
else { return }
do
{
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
try AVAudioSession.sharedInstance().setActive(true)
musicPlayer = try AVAudioPlayer(contentsOf: url)
musicPlayer?.play()
musicPlayer?.numberOfLoops = -1
}
catch let error
{
print(error.localizedDescription)
}
}
}
}
Different file:
@IBAction func play(_ sender: Any)
{
player().playClick()
performSegue(withIdentifier: "menuToIntro", sender: self)
}
But it doesn't play anything. Just prints log AQDefaultDevice (173): skipping input stream 0 0 0x0
Upvotes: 1
Views: 240
Reputation: 277
Ok, found an issue. It is necessary in my case to store a player as a property or other variable that won't get destroyed. That's why the logs - sound was played but immediately terminated. I fixed it by declaring AVAudioPlayers in AppDelegate
Upvotes: 1
Reputation: 247
From discussion here this is a bug with the Xcode simulator and you should try going to Edit Scheme > Run > Arguments and adding environment variable OS_ACTIVITY_MODE, value disable.
Upvotes: 1