10

I have simple AVAudioPlayer in my iphone app, it works, but output should be phone speaker instead of headphone. I found similiar topic here , but don't know how to 'translate' that to swift (AudioSessionSetProperty is confusing me)?

var audioPlayer = AVAudioPlayer(data: fileData, error: &playbackError) 
//fileData is url to file

if let player = audioPlayer{
    player.delegate = self

    if(player.prepareToPlay() && player.play()){
         println("Started playing the recorded audio")
    } else {
         println("Could not play the audio")
    }
}
clemens
  • 16,716
  • 11
  • 50
  • 65
Marko
  • 2,021
  • 4
  • 16
  • 18

7 Answers7

22

I can understand how this is confusing as I just figured out the answer. So AudioSessionSetProperty was deprecated in iOS 7.

Add this:

session.overrideOutputAudioPort(AVAudioSessionPortOverride.Speaker, error: nil)

Make sure to call AVAudioSession.sharedInstance() first.

clemens
  • 16,716
  • 11
  • 50
  • 65
ohhmaar
  • 336
  • 2
  • 3
17

In Swift 3 or 4:

let audioSession = AVAudioSession.sharedInstance()

do {
    try audioSession.overrideOutputAudioPort(AVAudioSessionPortOverride.speaker)
} catch let error as NSError {
    print("audioSession error: \(error.localizedDescription)")
}

To avoid the OSStatus error -50 (mentioned by user462990 in the comments), overrideOutputAudioPort has to be called after setting the session category (code below).

do {
    try session.setCategory(AVAudioSessionCategoryPlayAndRecord)
} catch let error as NSError {
    print("setCategory error: \(error.localizedDescription)")
}
clemens
  • 16,716
  • 11
  • 50
  • 65
kauai
  • 489
  • 1
  • 6
  • 9
  • Could you please show this code integrated into Marko's code? I see an AVAudioPlayer in his code and an AVAudioSession in yours. How do these tie together? I tried adding your code into my project but keep getting errors. – Trev14 Sep 09 '17 at 22:08
  • I am using exactly this code but I'm getting an error on execution "The operation couldn’t be completed. (OSStatus error -50.)" any ideas? – user462990 Jan 04 '18 at 15:54
  • Here is a bit more of an explanation of what I found and what solved things for me when trying to implement a Navigation style prompt to car stereo or phone speaker if nothing connected to the phone. Hope this helps someone else https://ossh.com.au/design-and-technology/software-development/iphone-navigation-type-audio-prompts/ – Duncan Groenewald Jun 02 '18 at 09:28
9

try these function.they are work charming.

func SetSessionPlayerOn()
{
    do {
        try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayAndRecord)
    } catch _ {
    }
    do {
        try AVAudioSession.sharedInstance().setActive(true)
    } catch _ {
    }
    do {
        try AVAudioSession.sharedInstance().overrideOutputAudioPort(AVAudioSessionPortOverride.speaker)
    } catch _ {
    }
}
func SetSessionPlayerOff()
{
    do {
        try AVAudioSession.sharedInstance().setActive(false)
    } catch _ {
    }
}
Ali Pishvaee
  • 303
  • 5
  • 7
  • You Just Need To Call The SetSessionPlayerOn() Whenever You need. – Ali Pishvaee Mar 01 '18 at 19:05
  • Is there a way to change from speaker to built-in earpiece. I'm working on audio call but by default it's on speaker and there's no way I can manage to change. – Neeraj Joshi Dec 28 '18 at 14:29
  • Have You tried the above code with replacement of boolean value with their negative value? @Nij – Ali Pishvaee Dec 30 '18 at 12:56
  • Yes and that makes the speaker off. What i want is to activate earpiece which is near to front camera. **NOTE: I am using opentok library for making video/audio call.** – Neeraj Joshi Dec 31 '18 at 06:14
  • I also want to implement built-in earpiece on Opentok library for making audio call. Can anyone help me on this. – Aayushi Jul 31 '20 at 11:42
1
  func SetEarSepeakerOn()
    {
        do {
            try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayAndRecord)
        } catch _ {
        }
        do {
            try AVAudioSession.sharedInstance().setActive(true)
        } catch _ {
        }
        do {
            try AVAudioSession.sharedInstance().overrideOutputAudioPort(AVAudioSessionPortOverride.none)
        } catch _ {
        }
    }
Sachin Kishore
  • 324
  • 3
  • 8
1

swift 5

    func setSessionPlayerOn() {
        do {
            try AVAudioSession.sharedInstance().setCategory(.playAndRecord)
        } catch _ {
        }
        do {
            try AVAudioSession.sharedInstance().setActive(true)
        } catch _ {

        }
        do {
            try AVAudioSession.sharedInstance().overrideOutputAudioPort(.speaker)
        } catch _ {

        }
    }
Ahmed Safadi
  • 4,402
  • 37
  • 33
1

You may set the audio session defaults to the built-in speaker instead of the receiver during the session setup.

        do {
            // 1) Configure your audio session category, options, and mode
            try session.setCategory(AVAudioSessionCategoryPlayAndRecord, mode: AVAudioSessionModeVoiceChat, options: [.defaultToSpeaker])
            // 2) Activate your audio session to enable your custom configuration
            try session.setActive(true)
        } catch let error as NSError {
            print("Failed to set the audio session category and mode: \(error.localizedDescription)")
        }
0

Swift 5

All of these answers are either outdated or not permanent solutions.

As the docs describe, If you’d prefer to permanently enable this behavior, you should instead set the category’s defaultToSpeaker option like so:

try recordingSession.setCategory(.playAndRecord, mode: .default, options: [.defaultToSpeaker])

Setting this option routes to the speaker rather than the receiver if no other accessory such as headphones are in use.

Eric
  • 569
  • 4
  • 21