Swift - Music from in app to system on button click - ios

At the moment I have a check in my app to see if iTunes is playing, and if it is, to proceed with iTunes music and not play the in game music. If iTunes is not playing anything, then to play the in game music.
I am trying to incorporate this into 2 functions and have a button that switches between:
Play iTunes rather in game music
Play in game music rather iTunes
This is currently in my viewDidLoad()
let check = isPlaying()
let path = NSBundle.mainBundle().pathForResource("music.mp3", ofType: nil)!
let url = NSURL(fileURLWithPath: path)
do {
if check == false {
let sound = try AVAudioPlayer(contentsOfURL: url)
music = sound
sound.play()
}
} catch { }
The isPlaying() function
func isPlaying() -> Bool {
let musicPlayer = MPMusicPlayerController.systemMusicPlayer()
if musicPlayer.playbackState == MPMusicPlaybackState.Playing {
ingame = false;
return true
}
return false
}
I tried to incorporate the previous code into a function that will be triggered by a button:
func playInGameMusic() {
let path = NSBundle.mainBundle().pathForResource("music.mp3", ofType: nil)!
let url = NSURL(fileURLWithPath: path)
do {
let sound = try AVAudioPlayer(contentsOfURL: url)
music = sound
sound.play()
ingame = true
} catch { }
}
However, I have no idea how to go about my playSystemMusic() function. Is there a way to resume iTunes from within my app? I understand their is an MPMusicPlayerController class, but I am not sure what I am supposed to use to make iTunes play from a button within my app.
Any guidance is appreciated, thanks.

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()
}

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

Background Music Stop/Mute on iOS

I'm creating my first app. I have an app with music playing in the background with the following code:
var backgroundMusicPlayer = AVAudioPlayer()
override func viewDidLoad() {
super.viewDidLoad()
//background Music
func playBackgroundMusic(filename: String) {
let url = NSBundle.mainBundle().URLForResource(filename, withExtension: nil)
guard let newURL = url else {
print("Could not find file: \(filename)")
return
}
do {
backgroundMusicPlayer = try AVAudioPlayer(contentsOfURL: newURL)
backgroundMusicPlayer.numberOfLoops = -1
backgroundMusicPlayer.prepareToPlay()
backgroundMusicPlayer.play()
} catch let error as NSError {
print(error.description)
}
}
playBackgroundMusic("Starship.wav")
}
So what should I do in order to stop/mute the background music when I switch to another ViewController? Should I do this my FirstViewController or SecondViewController?
Obviously, I don't want the sound to be off in the SecondViewController as I have other stuff that will be playing there.
To mute sound I simply mute the volume.
backgroundMusicPlayer.volume = 0
and set it to normal if I want sound
backgroundMusicPlayer.volume = 1
If you just want to pause music you can call
backgroundMusicPlayer.pause()
To resume you call
backgroundMusicPlayer.resume()
If you want to stop music and reset it to the beginning you say this
backgroundMusicPlayer.stop()
backgroundMusicPlayer.currentTime = 0
backgroundMusicPlayer.prepareToPlay()
Did you also consider putting your music into a singleton class so its easier to play music in your different viewControllers.
Not sure this is what you are looking for as your question is a bit vague.

How to let background music continue?

I want to allow a player to use their music in my game, so I want to know how to detect if the player is playing music from his music library so I can let his music continue playing and if not let my music play in the background.
I use this code to play music in my GameViewController:
let bgMusicURL: NSURL = NSBundle.mainBundle().URLForResource("Squart-GameMusic", withExtension: "wav")!
do {
Data.GameMusic = try AVAudioPlayer(contentsOfURL: bgMusicURL, fileTypeHint: nil)
} catch {
return print("no music file")
}
Data.GameMusic.numberOfLoops = 1
Data.GameMusic.prepareToPlay()
Data.GameMusic.play()
The problem is that when I try to play music from Music Library the sound stops and it lets my app play music instead of the Music Library.
Check whether the music is playing or not in the background like this
if MPMusicPlayerController.systemMusicPlayer().playbackState == .Playing {
print("Music is playing")
} else {
print("Play your music")
}
Don't forget to import:
import MediaPlayer
And if you want to play the sound simultaneously then use this code to play the sound file
func playSound {
var soundID: SystemSoundID = 0
let soundURL = CFBundleCopyResourceURL(CFBundleGetMainBundle(), "myFileName", "mp3", nil)
AudioServicesCreateSystemSoundID(soundURL, &soundID)
AudioServicesPlaySystemSound(soundID)
}

How to stop background music with button and if/else in Swift?

In my game I added a button to the GameScene and played music:
let url = NSBundle.mainBundle().URLForResource("Happy Background Music", withExtension: "mp3")
let bgMusic = AVAudioPlayer(contentsOfURL: url, error: nil)
#IBAction func SoundOnOff(sender: UIButton) {
bgMusic.numberOfLoops = -1
bgMusic.play()
}
and the music played, but I want to add an if so when the button is pressed the music will stop. What if should I write?
Change your code with this,
let url = NSBundle.mainBundle().URLForResource("Happy Background Music", withExtension: "mp3")
do{
let bgMusic = try AVAudioPlayer(contentsOfURL: url!)
}catch{
print(error)
}
#IBAction func SoundOnOff(sender: UIButton) {
if bgMusic.playing {
bgMusic.stop()
} else {
self.bgMusic.play()
}
}
Edit: Description
playing- Property
-A Boolean value that indicates whether the audio player is playing (true) or not (false). (read-only)
AVAudioPlayer has a built-in property playing, which you can use to decide whether to play or pause the music:
#IBAction func SoundOnOff(sender: UIButton) {
if bgMusic.playing {
bgMusic.pause()
} else {
bgMusic.numberOfLoops = -1
bgMusic.play()
}
}
Just seen that this is only available in iOS9 and later. So if you're targeting iOS9 then this is possible.
If you're using SpriteKit to write your game I would recommend using the SKAudioNode class to play your BGMusic.
let url = NSBundle.mainBundle().URLForResource("Happy Background Music", withExtension: "mp3")
let audioNode = SKAudioNode(URL:url)
audioNode.positional = false
audioNode.autoplayLooped = true
self.addChild(audioNode)
To pause the music you create an SKAction ...
let pauseAction = SKAction.pause()
audioNode.runAction(pauseAction)
You can resume it also but just trying to find the code for that...

Resources