How to make music play and stop with single button just like in itunes.When the button is pressed and same button pressed again should stop the music.
var audioplayer = AVaudioPlayer
#IBAction func play(_ sender: Any) {
do
{
audioPlayer = try AVAudioPlayer (contentsOf: URL.init(fileURLWithPath: Bundle.main.path(forResource: "bensound", ofType: "mp3")!))
audioPlayer.prepareToPlay()
audioPlayer.play()
audioPlayer.stop()
}
catch {
print ("error")
}
}
Obviously, this won't work:
audioPlayer.prepareToPlay()
audioPlayer.play() // this will just start playing the music and immediately stop it.
audioPlayer.stop()
You need an if statement and a variable indicating whether the music is playing.
Luckily, the variable that I was talking about already exists! You don't even need to declare it yourself! It is isPlaying, defined in AVAudioPlayer.
We just need to write the if statement. It is pretty simple,
If the music is playing, stop it, otherwise, start it
if audioplayer.isPlaying {
audioplayer.play()
} else {
audioplayer.stop()
}
Related
I am experiencing a slight delay between UIButton press and sound output (it seems to average about 0.05 seconds). I am currently implementing AVAudioPlayer. Is there a best way to play a sound instantaneously? I scoured the Internet but can't find a concrete answer.
For reference, my (simplified) code is as follows:
// Get sound url
let soundURL = URL(fileURLWithPath: Bundle.main.path(forResource: file, ofType: type)!)
// Audio Player
var audioPlayer: AVAudioPlayer!
do {
// Create audio player
audioPlayer = try AVAudioPlayer(contentsOf: soundURL)
}
catch let errMsg as NSError {
print("AVAudioPlayer error: \(errMsg.localizedDescription)")
}
// Prepare audio player to play
audioPlayer.prepareToPlay()
//...
#IBAction func btnPressed(_ sender: UIButton) {
audioPlayer.play()
}
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
I have implemented background music in my game using AVFoundation. However, when leaving the GameScene the music continues playing. I know that in viewControllers you can use viewWillDisappear but I can't find anything similar for GameScenes.
var audioPlayer = AVAudioPlayer()
let audioPath = Bundle.main.path(forResource: "electroDrive", ofType: "wav")
//.......//
//.......//
do {
try audioPlayer = AVAudioPlayer(contentsOf: URL(fileURLWithPath: audioPath!))
}
catch {
// process error
}
audioPlayer.play()
//Code to go to other scene
if viewController != nil {
self.viewController?.performSegue(withIdentifier: "push", sender: viewController)
}
Stop the AVAudioPlayer before segueing to the next Scene
Insert this before your segue code
audioPlayer.pause()
I am trying to add sound to my app. I would like it for when I tap a button, it plays a quick sound. However, when the button is tapped quickly and repeatedly, the sound does not work as well (It only plays 1 or 2 times when I tap the button 5 or 6 times). Here is my code in the button
player.play()
I have this outside
var player = AVAudioPlayer()
let audioPath = NSBundle.mainBundle().pathForResource("illuminati", ofType: "wav")
Viewdidload:
do {
try player = AVAudioPlayer(contentsOfURL: NSURL(fileURLWithPath: audioPath!))
} catch {}
How can I play the sound repeatedly better? Thanks.
The problem is that you are calling the play multiple time before the previous call finished. You need to keep track of how many times the user click the button and the play song one by one.
This is what you can do:
Use an integer in you class to keep track of number of times that the button is clicked
var numClicks = 0
var buttonClickTime:NSDate? = nil // The last time when the button is clicked
#IBAction func yourbuttonclickfunction() {
numClicks++;
buttonClickTime = NSDate()
player.play()
}
Register the delegate of AVAudioPlayerDelegate
do {
try player = AVAudioPlayer(contentsOfURL: NSURL(fileURLWithPath: audioPath!))
// Add this
player.delegate = self
} catch {}
In the delegate function, play the song again when the previous one reach the end:
optional func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer,
successfully flag: Bool)
{
if --numClicks > 0
{
let now = NSDate()
let duration = now.timeIntervalSinceDate(buttonClickTime!)
// If the button click was less than 0.5 seconds before
if duration < 0.5
{
// Play the song again
player.play();
}
}
}
The reason your sound only plays a few time is because the song plays until finished or until you stop it, even if you press the button multiple times in succession.
You could just stop the music manually, so before you press a button that plays a sound you say
player.stop()
and than
player.play()
Is that helping?
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...