Multiple Audio Files In One ViewController With Button - ios

Want to play multiple audio files in the same ViewController. When a user clicks on Button1 the file1.mp3 should be loaded into ViewController and when user hit play same should play and for button2 file2.mp3 should load and play.
I know how to do this for a single file but for multiple files I have to create ViewController again and again which is so hard. This is my code for single file
#IBAction func buttonPressed(_ sender: UIButton) {
if player.isPlaying {
player.stop()
sender.setImage(UIImage(named:"play.png"),for: .normal)
} else {
player.delegate = self
player.play()
player.numberOfLoops = 107
sender.setImage(UIImage(named:"pause.png"),for: .normal)
}
}
do {
let audioPlayer = Bundle.main.path(forResource: "chalisa", ofType: "mp3")
try player = AVAudioPlayer(contentsOf: NSURL(fileURLWithPath: audioPlayer!) as URL)
}catch {
//ERROR
}

You can use Tableview List all songs Name and Play Button use to Multiple audio files use in one viewcontroller
import AVFoundation
//MARK:- Variable Declaration
var player: AVAudioPlayer?
func playMusic() {
guard let url = Bundle.main.url(forResource: "chalisa", withExtension: "mp3") else { return }
do {
try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default)
try AVAudioSession.sharedInstance().setActive(true)
player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileType.mp3.rawValue)
/* iOS 10 and earlier require the following line:
player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileTypeMPEGLayer3) */
guard let player = player else { return }
player.play()
} catch let error {
print(error.localizedDescription)
}
}

Related

Play random sounds from my projects in Swift 5

I'm new in iOS. I have written this code, which plays only one audio file when tapping a UIButton. I would like to play multiple sound randomly. How to set it? Thank you!
import UIKit
import AVFoundation
class ViewController: UIViewController {
var audioPlayer: AVAudioPlayer!
#IBAction func playButtonPressed(_ sender: UIButton) {
if let soundURL = Bundle.main.url(forResource: "kompilacja", withExtension: "mp3") {
do {
audioPlayer = try AVAudioPlayer(contentsOf: soundURL)
}
catch {
print(error)
}
audioPlayer.play()
}else{
print("Karwasz twarz! Brak pliku audio, Panie!")
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
}
Put all of your sound file names in an array and use the randomElement method to choose your sound.
#IBAction func playButtonPressed(_ sender: UIButton) {
let sounds = ["kompilacja", "another sound", "yet another sound"]
guard let sound = sounds.randomElement(),
let soundURL = Bundle.main.url(forResource: sound, withExtension: "mp3") else { return }
do {
audioPlayer = try AVAudioPlayer(contentsOf: soundURL)
}
catch {
print(error)
}
audioPlayer.play()
}

Playing sounds with multiple play buttons in iOS

I have to play three types of wav file one at a time. When I click on the Play button in Enter region it plays a sound named "EnterRegion.wav" and clicking on Exit Region play button plays "ExitRegion.wav" audio file.
But for the play button of the Immediate, it plays a sound repeatedly until I press the Stop button.
Both first and second Play buttons are working perfectly for me but when I click on play button in Immediate, it plays sound for the first time but when I click on other play buttons and come back to Immediate play button again, the application throws exceptions. This happens the same when I press stop button and come back to the play button of immediate section. My sample app screenshot and code sample which is in Swift 4 is as below.
import UIKit
import AVFoundation
class ViewController: UIViewController {
var engine: AVAudioEngine!
var enterWavFile: AVAudioFile!
var audioPlayerNode : AVAudioPlayerNode!
var immediaAudioPlayerNode: AVAudioPlayerNode!
var exitWavFile: AVAudioFile!
var flatlineWavFile:AVAudioFile!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
engine = AVAudioEngine()
enterWavFile = try? AVAudioFile(forReading: NSURL.fileURL(withPath:
Bundle.main.path(forResource: "EnterRegion", ofType: "wav")!))
exitWavFile = try? AVAudioFile(forReading: NSURL.fileURL(withPath:
Bundle.main.path(forResource: "ExitRegion", ofType: "wav")!))
flatlineWavFile = try? AVAudioFile(forReading: NSURL.fileURL(withPath:
Bundle.main.path(forResource: "Immediate", ofType: "wav")!))
}
#IBAction func playEnterRegionSound(_ sender: UIButton) {
playSound(audioFile: enterWavFile)
}
#IBAction func playExitRegion(_ sender: UIButton) {
playSound(audioFile: exitWavFile)
}
func playSound(audioFile: AVAudioFile) {
audioPlayerNode = AVAudioPlayerNode()
if(audioPlayerNode.isPlaying){
audioPlayerNode.stop()
}
if(engine.isRunning){
engine.stop()
engine.reset()
}
engine.attach(audioPlayerNode)
engine.connect(audioPlayerNode, to: engine.mainMixerNode, format: audioFile.processingFormat)
audioPlayerNode.scheduleFile(audioFile, at: nil, completionHandler: nil)
// Start the audio engine
engine.prepare()
try! engine.start()
audioPlayerNode.play()
}
#IBAction func playImmediateFlatline(_ sender: UIButton) {
immediaAudioPlayerNode = AVAudioPlayerNode()
if(immediaAudioPlayerNode.isPlaying){
print("immediateAudioPlayerNode Playing")
immediaAudioPlayerNode.stop()
}
if(engine.isRunning){
print("engine Running")
engine.stop()
engine.reset()
}
let audioFileBuffer = AVAudioPCMBuffer(pcmFormat: flatlineWavFile.processingFormat, frameCapacity: AVAudioFrameCount( flatlineWavFile.length))!
try? flatlineWavFile.read(into: audioFileBuffer)
engine.attach(immediaAudioPlayerNode)
engine.connect(immediaAudioPlayerNode, to: engine.mainMixerNode, format: flatlineWavFile.processingFormat)
immediaAudioPlayerNode.scheduleBuffer(audioFileBuffer, at: nil, options: AVAudioPlayerNodeBufferOptions.loops, completionHandler: nil)
// Start the audio engine
engine.prepare()
try! engine.start()
immediaAudioPlayerNode.play()
}
#IBAction func stopImmediateFlatline(_ sender: UIButton) {
if (immediaAudioPlayerNode.isPlaying){
print("immediateAudioPlayerNode playing")
immediaAudioPlayerNode.pause()
}
if(engine.isRunning){
print("engine Running")
engine.stop()
engine.reset()
}
}
}
I am unable to locate why this is happening and could you please help me to fix the issue or any suggestions.
code for playing the sound
var player1: AVAudioPlayer?
var player2: AVAudioPlayer?
var player3: AVAudioPlayer?
func playSound() {
guard let url = Bundle.main.url(forResource: "Music", withExtension: "wav") else { return }
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
try AVAudioSession.sharedInstance().setActive(true)
/* The following line is required for the player to work on iOS 11. Change the file type accordingly*/
player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileType.mp3.rawValue)
/* iOS 10 and earlier require the following line:
player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileTypeMPEGLayer3) */
guard let player = player else { return }
// read this line of code for you to play the wav file you wanted to play ang then trigger it using a button.
player.play()
} catch let error {
print(error.localizedDescription)
}
}

Using a UITapGestureRecognizer to play/pause audio

This seems like a fairly simple task, but have been trying for a while to figure it out... I have set up a UITapGestureRecognizer to play an audio file from the bundle. That works well, but I would like to have the user be able to tap the item again and have the audio stop. Basically have the ability to start and replay the audio by tapping the object with single taps.
#IBAction func page1Tapped(_ sender: UITapGestureRecognizer) {
let url:URL = Bundle.main.url(forResource: "Opening Solo", withExtension: "mp3")!
do {
audioPlayer = try AVAudioPlayer(contentsOf: url, fileTypeHint: nil)
} catch {
return
}
audioPlayer.prepareToPlay()
audioPlayer.play()
if audioPlayer.isPlaying {
audioPlayer.stop()
} else {
audioPlayer.play()
}
}
Here is the function that I have created. The audio only plays and just restarts at 0 with every tap at this point.
Any help is incredibly appreciated!!
This because every click creates a new re-assings the old instance , you can declare the player as instance variable
var audioPlayer:AVAudioPlayer?
and check it's value before assigning
if audioPlayer == nil
{
audioPlayer = try AVAudioPlayer(contentsOf: url, fileTypeHint: nil)
audioPlayer.play()
}
else
{
if audioPlayer.isPlaying {
audioPlayer.stop()
} else {
audioPlayer.play()
}
}

Control audio on lock screen using AVAudioPlayer

I have background mode active for audio and I use this method to play files, but I can't control them when the screen is locked.
func loadSound(resource: String, soundExtension: String) {
guard let url = Bundle.main.url(forResource: resource, withExtension: soundExtension) else {
return
}
UIApplication.shared.beginReceivingRemoteControlEvents()
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
try AVAudioSession.sharedInstance().setActive(true)
player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileType.mp3.rawValue)
} catch let error {
print(error.localizedDescription)
}
}
For someone with the same problem, call this method in the question method
fileprivate let remoteCommandCenter = MPRemoteCommandCenter.shared()
func activateControlCenterCommands() {
remoteCommandCenter.playCommand.addTarget(self, action: #selector(handlePlayCommandEvent(_:)))
remoteCommandCenter.pauseCommand.addTarget(self, action: #selector(handlePauseCommandEvent(_:)))
remoteCommandCenter.playCommand.isEnabled = true
remoteCommandCenter.pauseCommand.isEnabled = true
}

MP3 File Not Playing On Button Select

For simplicity, assume this View says alphabet letters in button when you click on said button.
I have been attempting to play the audio files associated with each button, but the files never play. The buttons, individually, are never given outlets, but they are all connected to the function on Touch Up Inside.
class UIAlphabetController: UIViewController, AVAudioPlayerDelegate{
#IBAction func PlaySound(Sender: UIButton) {
let soundname:String = Sender.currentTitle!
var player: AVAudioPlayer?
let url = Bundle.main.url(forResource: soundname, withExtension: "mp3")
do {
player = try AVAudioPlayer(contentsOf: url!)
guard let player = player else { return }
player.prepareToPlay()
player.play()
} catch let error { print(error.localizedDescription) }
}
}
Since I have had this problem, the AQDefaultDevice (188): skipping input stream 0 0 0x0 message has been coming up. On testing with breakpoints, both soundname and url have expected values.
Does anybody have any idea as to how to fix this?
Move your instance of AVAudioPlayer outside of the method. If you do this it will keep player around long enough to play the sound. The reason it's not working is because it trashes the player instance after the method is complete because it thinks you are done using it.
class UIAlphabetController: UIViewController, AVAudioPlayerDelegate {
var player: AVAudioPlayer?
#IBAction func PlaySound(Sender: UIButton) {
let soundname:String = Sender.currentTitle!
let url = Bundle.main.url(forResource: soundname, withExtension: "mp3")
do {
player = try AVAudioPlayer(contentsOf: url!)
guard let player = player else { return }
player.prepareToPlay()
player.play()
} catch let error { print(error.localizedDescription) }
}
}

Resources