录音机:默认扬声器播放

Voice Recorder: speaker playback by default

我制作了一个通过耳机播放的录音机;但是,我想通过扬声器播放。我添加了以下 (Swift 4):

let audioSession = AVAudioSession.sharedInstance()

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

当我初始化应用程序时,我可以通过扬声器播放以前的录音;然而,一旦我录制了一个新的语音备忘录,播放就会回到耳机。我查找了解决方案,但它们都引用了 setCategory,它在 Swift 4.

中引发错误

有谁知道如何将录制的回放默认设置为扬声器?

这是我的完整视图控制器:

import UIKit
import AVFoundation

class ViewController2: UIViewController, AVAudioRecorderDelegate, UITableViewDelegate, UITableViewDataSource {


// Setting up Table View
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return numberOfRecords
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
    cell.textLabel?.text = String(indexPath.row + 1)
    return cell
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let path = getDirectory().appendingPathComponent("\(indexPath.row + 1).m4a")

    do {
        audioPlayer = try AVAudioPlayer(contentsOf: path)
        audioPlayer.play()
    }

    catch {

    }
}


var audioPlayer : AVAudioPlayer!
var recordingSession : AVAudioSession!
var audioRecorder : AVAudioRecorder!

var numberOfRecords : Int = 0

@IBOutlet weak var buttonLabel: UIButton!
@IBOutlet weak var myTableView: UITableView!

@IBAction func record(_ sender: Any) {
    // Check if we have an active recorder
    if audioRecorder == nil {
        numberOfRecords += 1
        let filename = getDirectory().appendingPathComponent("\(numberOfRecords).m4a")

        let settings = [AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
                        AVSampleRateKey: 12000,
                        AVNumberOfChannelsKey: 1,
                        AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue]

        // Start audio recording
        do {
            audioRecorder = try AVAudioRecorder(url: filename, settings: settings)
            audioRecorder.delegate = self
            audioRecorder.record()

            //buttonLabel.setTitle("Stop", for: .normal)
        }

        catch {
            displayAlert(title: "Oops!", message: "Recording failed")
        }
    }
    else {
        // Stop audio recording
        audioRecorder.stop()
        audioRecorder = nil

        UserDefaults.standard.set(numberOfRecords, forKey: "myNumber")
        myTableView.reloadData()

        //buttonLabel.setTitle("Start", for: .normal)
    }

}

override func viewDidLoad() {
    super.viewDidLoad()

    // Setting up Recording session
    recordingSession = AVAudioSession.sharedInstance()

    if let number : Int = UserDefaults.standard.object(forKey: "myNumber") as? Int {
        numberOfRecords = number
    }

    AVAudioSession.sharedInstance().requestRecordPermission { (hasPermission) in
        if hasPermission {
            print ("Accepted")
        }
    }

    // Play speaker instead of earpiece
    let audioSession = AVAudioSession.sharedInstance()

    do {
        try audioSession.overrideOutputAudioPort(AVAudioSession.PortOverride.speaker)

    } catch let error as NSError {
        print("Audio Session error: \(error.localizedDescription)")
    }


    // Gesture recognizers

    let leftSwipe = UISwipeGestureRecognizer(target: self, action: #selector(swipeAction(swipe:)))
    leftSwipe.direction = UISwipeGestureRecognizer.Direction.left
    self.view.addGestureRecognizer(leftSwipe)

    let rightSwipe = UISwipeGestureRecognizer(target: self, action: #selector(swipeAction(swipe:)))
    rightSwipe.direction = UISwipeGestureRecognizer.Direction.right
    self.view.addGestureRecognizer(rightSwipe)

    let upSwipe = UISwipeGestureRecognizer(target: self, action: #selector(swipeAction(swipe:)))
    upSwipe.direction = UISwipeGestureRecognizer.Direction.up
    self.view.addGestureRecognizer(upSwipe)

}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}


// Function that gets path to directory
func getDirectory() -> URL {
    let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
    let documentDirectory = paths[0]
    return documentDirectory
}

// Function that displays an alert
func displayAlert(title: String, message: String) {
    let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
    alert.addAction(UIAlertAction(title: "dismiss", style: .default, handler: nil))
    present(alert, animated: true, completion: nil)
}

do catch 语句需要在 if 而不是 else 中,而不是在 viewDidLoad () 部分。

// Setting up Table View
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return numberOfRecords
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
    cell.textLabel?.text = String(indexPath.row + 1)
    return cell
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let path = getDirectory().appendingPathComponent("\(indexPath.row + 1).m4a")

    do {
        audioPlayer = try AVAudioPlayer(contentsOf: path)
        audioPlayer.play()
    }

    catch {

    }
}


var audioPlayer : AVAudioPlayer!
var recordingSession : AVAudioSession!
var audioRecorder : AVAudioRecorder!

var numberOfRecords : Int = 0

@IBOutlet weak var buttonLabel: UIButton!
@IBOutlet weak var myTableView: UITableView!

@IBAction func record(_ sender: Any) {
    // Check if we have an active recorder
    if audioRecorder == nil {
        numberOfRecords += 1
        let filename = getDirectory().appendingPathComponent("\(numberOfRecords).m4a")

        let settings = [AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
                        AVSampleRateKey: 12000,
                        AVNumberOfChannelsKey: 1,
                        AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue]

        // Start audio recording
        do {
            audioRecorder = try AVAudioRecorder(url: filename, settings: settings)
            audioRecorder.delegate = self
            audioRecorder.record()

            //buttonLabel.setTitle("Stop", for: .normal)
        }

        catch {
            displayAlert(title: "Oops!", message: "Recording failed")
        }

        // Play speaker instead of earpiece
        let audioSession = AVAudioSession.sharedInstance()

        do {
            try audioSession.overrideOutputAudioPort(AVAudioSessionPortOverride.speaker)

        } catch let error as NSError {
            print("Audio Session error: \(error.localizedDescription)")
        }


    }
    else {
        // Stop audio recording
        audioRecorder.stop()
        audioRecorder = nil

        UserDefaults.standard.set(numberOfRecords, forKey: "myNumber")
        myTableView.reloadData()

        //buttonLabel.setTitle("Start", for: .normal)
    }

}

override func viewDidLoad() {
    super.viewDidLoad()

    // Setting up Recording session
    recordingSession = AVAudioSession.sharedInstance()

    if let number : Int = UserDefaults.standard.object(forKey: "myNumber") as? Int {
        numberOfRecords = number
    }

    AVAudioSession.sharedInstance().requestRecordPermission { (hasPermission) in
        if hasPermission {
            print ("Accepted")
        }
    }



    // Gesture recognizers

    let leftSwipe = UISwipeGestureRecognizer(target: self, action: #selector(swipeAction(swipe:)))
    leftSwipe.direction = UISwipeGestureRecognizerDirection.left
    self.view.addGestureRecognizer(leftSwipe)

    let rightSwipe = UISwipeGestureRecognizer(target: self, action: #selector(swipeAction(swipe:)))
    rightSwipe.direction = UISwipeGestureRecognizerDirection.right
    self.view.addGestureRecognizer(rightSwipe)

    let upSwipe = UISwipeGestureRecognizer(target: self, action: #selector(swipeAction(swipe:)))
    upSwipe.direction = UISwipeGestureRecognizerDirection.up
    self.view.addGestureRecognizer(upSwipe)

}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}


// Function that gets path to directory
func getDirectory() -> URL {
    let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
    let documentDirectory = paths[0]
    return documentDirectory
}

// Function that displays an alert
func displayAlert(title: String, message: String) {
    let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
    alert.addAction(UIAlertAction(title: "dismiss", style: .default, handler: nil))
    present(alert, animated: true, completion: nil)
}