Swift AVPlayer to ear speaker - swift

I've got a simple audio player that works great. I'm playing a remote URL MP3. My code:
#IBAction func playAudio(sender: AnyObject) {
let url = self.productAudio
let playerItem = AVPlayerItem( URL:NSURL( string:url ) )
player = AVPlayer(playerItem:playerItem)
player.
player.rate = 1.0;
player.play()
}
But the audio is outputed by the loud speaker. How can I play the audio through the ear speaker?

Swift 5.0
let session = AVAudioSession.sharedInstance()
do{
try session.setCategory(.playAndRecord)
try session.overrideOutputAudioPort(AVAudioSession.PortOverride.none)
try session.setActive(true)
} catch {
print ("\(#file) - \(#function) error: \(error.localizedDescription)")
}

Finally I found the answer...
I had to modify my Audio Session, and override the port. This is the code before the player code:
let session = AVAudioSession.sharedInstance()
var error: NSError?
session.setCategory(AVAudioSessionCategoryPlayAndRecord, error: &error)
session.overrideOutputAudioPort(AVAudioSessionPortOverride.None, error: &error)
session.setActive(true, error: &error)

Related

Unable to play http audio using avaudioplayer in swift 4

I am trying to play simple audio from http url using AVAudioPlayer however getting weird error . Here is the code
func playSound() {
do {
let url = URL(string: "http://<domain>/stream")
var player = AVAudioPlayer() //tied to initialize it as AVAudioPlayer! too
player = try AVAudioPlayer(contentsOf: url!)
player.prepareToPlay()
player.play()
} catch let error as NSError {
print(error.description)
}}
Error:
AddInstanceForFactory: No factory registered for id <CFUUID 0x6000030f4b00> F8BB1C28-BAE8-11D6-9C31-00039315CD46
Error Domain=NSOSStatusErrorDomain Code=2003334207 "(null)"
You have to make player as global variable:
var player = AVAudioPlayer()
// ...
func playSound() { // ...

AVAudioPlayer NSOSStatusErrorDomain error

As you may see, I'm trying to play audio obtained from a url. Where is the mistake?
The error seems to suggest that the audio from the url is not good...
//let play_url = "https://opus-server.herokuapp.com/asd.wav"
let play_url = "http://www.largesound.com/ashborytour/sound/brobob.mp3"
var audioPlayer: AVAudioPlayer?
#IBAction func play(_ sender: Any) {
let url = URL(string: play_url)!
do {
audioPlayer = try AVAudioPlayer(contentsOf: url)
audioPlayer?.play()
} catch {
print(error)
}
}
I expect AVAudioPlayer to play the audio. Instead, there is an error printed: Error Domain=NSOSStatusErrorDomain Code=2003334207 "(null)"

How to fix 'appendingPathComponent' is unavailable: Use appendingPathComponent on URL error

I'm working on a old Swift tutorial (Swift 2.0) that's posted on Ray Wenderlich's web site (https://www.raywenderlich.com/2185-how-to-make-a-letter-word-game-with-uikit-and-swift-part-3-3) and I'm running into an error when I tried to re-setup a function called "preloadAudioEffects" in Swift 4.2 . The error? appendingPathComponent' is unavailable: Use appendingPathComponent on URL instead.
I've tried to rename the old Swift code [Ex: NSBundle to Bundle , stringByAppendingPathComponent to appendingPathComponent()], but I'm still running into some syntax issues due to my inexperience with Swift.
This is the original code:
func preloadAudioEffects(effectFileNames:[String]) {
for effect in AudioEffectFiles {
//1 get the file path URL
let soundPath = NSBundle.mainBundle().resourcePath!.stringByAppendingPathComponent(effect)
let soundURL = NSURL.fileURLWithPath(soundPath)
//2 load the file contents
var loadError:NSError?
let player = AVAudioPlayer(contentsOfURL: soundURL, error: &loadError)
assert(loadError == nil, "Load sound failed")
//3 prepare the play
player.numberOfLoops = 0
player.prepareToPlay()
//4 add to the audio dictionary
audio[effect] = player
}
}
And this is what I've tried to do via following the suggestions in Xcode:
func preloadAudioEffects(effectFileNames:[String]) {
for effect in AudioEffectFiles {
//1 get the file path URL
let soundPath = Bundle.main.resourcePath!.appendingPathComponent(effect)
let soundURL = NSURL.fileURL(withPath: soundPath)
//2 load the file contents
var loadError:NSError?
let player = AVAudioPlayer(contentsOfURL: soundURL, error: &loadError)
assert(loadError == nil, "Load sound failed")
//3 prepare the play
player.numberOfLoops = 0
player.prepareToPlay()
//4 add to the audio dictionary
audio[effect] = player
}
}
Get the full path to the sound file and convert it to a URL by using NSURL.fileURLWithPath().
Call AVAudioPlayer(contentsOfURL:error:) to load a sound file in an audio player.
Set the numberOfLoops to zero so that the sound won’t loop at all. Call prepareToPlay() to preload the audio buffer for that sound.
Finally, save the player object in the audio dictionary, using the name of the file as the dictionary key.
Just replace resourcePath with resourceURL
let soundURL = Bundle.main.resourceURL!.appendingPathComponent(effect)
and you have to wrap the AVAudioPlayer initializer in a try block
func preloadAudioEffects(effectFileNames:[String]) {
for effect in AudioEffectFiles {
let soundURL = Bundle.main.resourceURL!.appendingPathComponent(effect)
//2 load the file contents
do {
let player = try AVAudioPlayer(contentsOf: soundURL)
//3 prepare the play
player.numberOfLoops = 0
player.prepareToPlay()
//4 add to the audio dictionary
audio[effect] = player
} catch { print(error) }
}
}

Can not play sound file Swift4

I'm trying play simple .wav file in my application.
Here is the code:
func alarmSound() {
var player: AVAudioPlayer?
guard let path = Bundle.main.path(forResource: "emergency021", ofType: "wav") else {
print("Can't find audio file")
return
}
let url = URL(fileURLWithPath: path)
do {
player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileType.wav.rawValue)
if let prepare = player?.prepareToPlay() {
print("Player prepared: \(prepare)")
}
player?.volume = 1.0
player?.play()
} catch {
print("Playing sound error: \(error)")
}
}
Everything ok, file in the bundle, url is ok, player prepared, but.. there is no any sound. I have tried .mp3 file - same result.
Any ideas, why?
Issue was declaring player: AVAudioPlayer locally in function body, when I moved it up to ViewController all works.

Check if AVAudioPlayer is playing

I've been trying to check if the AVAudioPlayer is currently playing, but when I try to do it in anyway it crashes.
I'm using stop button to stop the audio but when there is no audio playing it crashes.
How is it possible to check it in my stopaudio function ?
First I defined :
var audioPlayer = AVAudioPlayer()
I have stop button :
func stopaudio(sender: AnyObject){
audioPlayer.stop()
}
I tried to check like this :
if audioPlayer.playing{
audioPlayer.stop()
}
I am using the following code to play the audio :
var soundURL: NSURL = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("9", ofType: "m4a")!)!
var error:NSError?
audioPlayer = AVAudioPlayer(contentsOfURL: soundURL, error: &error)
audioPlayer.prepareToPlay()
audioPlayer.play()
The problem was because the AVAudioPlayer hasn't been initialized yet, so what i did to fix it is to initialize it and then stop it.
var soundURL: NSURL = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("013", ofType: "m4a")!)!
var error:NSError?
audioPlayer = AVAudioPlayer(contentsOfURL: soundURL, error: &error)
audioPlayer.stop()
Declare a function in the ViewController class:
func tryAudio() {
do {
try player = AVAudioPlayer(contentsOf: URL(fileURLWithPath: path!))
} catch {
//handle errors
}
}
call tryAudio() to initialize the player before player.stop()