[:en]How to record speech to text and then play
First of all, add "Privacy - Microphone Usage Description" line and "Privacy - Speech Recognition Usage Description" line to Info.plist file as follows:
Then copy and past the following code to your project
// // Speech.swift // SpeechToText // // Created by Inventlinks on 15-09-2019. // Copyright © 2019 Inventlinks. All rights reserved. // import UIKit import Speech import AVFoundation class ViewController: UIViewController, AVAudioRecorderDelegate { @IBOutlet weak var recordDisplay: UIButton! @IBOutlet weak var playDisplay: UIButton! @IBOutlet weak var textView: UITextView! // Audio section var file:Int = 0 var AudioPlayer:AVAudioPlayer! var AudioSession:AVAudioSession! var AudioRecorder:AVAudioRecorder! // Speech to Text section var lang: String = "en-US" var SpeechRecognitionTask: SFSpeechRecognitionTask? var RecognitionRequest: SFSpeechAudioBufferRecognitionRequest? var AudioEngine = AVAudioEngine() var SpeechRecognizer = SFSpeechRecognizer(locale: Locale.init(identifier: "en-US")) override func viewDidLoad() { super.viewDidLoad() // Initialize AudioSession AudioSession = AVAudioSession.sharedInstance() // to solve 'required condition is false: IsFormatSampleRateAndChannelCountValid(format)' do { try AVAudioSession.sharedInstance().setCategory(.playAndRecord, mode: .default, options: []) try AVAudioSession.sharedInstance().setActive(true) } catch { print(error) } // To get permission from user AVAudioSession.sharedInstance().requestRecordPermission{(hasPermission) in if hasPermission { self.textView.text = "Ready to speak?" } } // To check any saved file? if let number:Int = UserDefaults.standard.object(forKey: "recording") as? Int { file = number } // Speech to Text Section recordDisplay.isEnabled = false SpeechRecognizer?.delegate = self as? SFSpeechRecognizerDelegate SpeechRecognizer = SFSpeechRecognizer(locale: Locale.init(identifier: lang)) SFSpeechRecognizer.requestAuthorization { (authStatus) in var isButtonEnabled = false switch authStatus { case .authorized: isButtonEnabled = true case .restricted: isButtonEnabled = false print("Restricted") case .notDetermined: isButtonEnabled = false print("notdetermined") case .denied: isButtonEnabled = false print("Access denied") @unknown default: break // ... } OperationQueue.main.addOperation() { self.recordDisplay.isEnabled = isButtonEnabled } } } // Audio Section Function that gets path to directory func getDirectory() -> URL { let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask) let documentDirectory = paths[0] return documentDirectory } @IBAction func englishBTN(_ sender: Any) { lang = "en-US" SpeechRecognizer = SFSpeechRecognizer(locale: Locale.init(identifier: lang)) textView.text = "Ready to speak?" } @IBAction func japaneseBTN(_ sender: Any) { lang = "ja-JP" SpeechRecognizer = SFSpeechRecognizer(locale: Locale.init(identifier: lang)) textView.text = "Ready to speak?" } @IBAction func recordBTN(_ sender: Any) { // Speech To Text section SpeechRecognizer = SFSpeechRecognizer(locale: Locale.init(identifier: lang)) if AudioEngine.isRunning { self.AudioEngine.stop() self.RecognitionRequest?.endAudio() } else { startSpeechRecording() } startAudioRecording() } func startAudioRecording() { // Audio Section: If active file saved? if AudioRecorder == nil{ file = 1 let filename = getDirectory().appendingPathComponent("\(file).m4a") let settings = [AVSampleRateKey: 12000, AVNumberOfChannelsKey: 1, AVFormatIDKey: Int(kAudioFormatMPEG4AAC), AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue] // Start audio recording do{ AudioRecorder = try AVAudioRecorder(url: filename, settings: settings) AudioRecorder.delegate = self AudioRecorder.record() recordDisplay.setTitle("STOP", for: .normal) print("recording now") } catch { showAlert(title: "Error", message: "Please try again") } } else{ // Stopping audio recording AudioRecorder.stop() AudioRecorder = nil // To save recording UserDefaults.standard.set(file, forKey: "recording") recordDisplay.setTitle("Start", for: .normal) // Starting playing let path = getDirectory().appendingPathComponent("\(file).m4a") print("file\(file)") do { AudioPlayer = try AVAudioPlayer(contentsOf: path) AudioPlayer.play() // Only play once AudioPlayer?.numberOfLoops = 0 // Set the volume of playback here. AudioPlayer?.volume = 10.0 print("playing now") } catch { showAlert(title: "Error", message: "Please try again") } } } func startSpeechRecording() { // Cancel the previous task if it's running. if SpeechRecognitionTask != nil { SpeechRecognitionTask?.cancel() SpeechRecognitionTask = nil } RecognitionRequest = SFSpeechAudioBufferRecognitionRequest() let inputNode = AudioEngine.inputNode guard let RecognitionRequest = RecognitionRequest else { fatalError("Error in Recognition") } RecognitionRequest.shouldReportPartialResults = true SpeechRecognitionTask = SpeechRecognizer?.recognitionTask(with: RecognitionRequest, resultHandler: { (result, error) in var FinalResult = false if result != nil { self.textView.text = result?.bestTranscription.formattedString FinalResult = (result?.isFinal)! } if error != nil || FinalResult { self.RecognitionRequest = nil self.SpeechRecognitionTask = nil self.AudioEngine.stop() inputNode.removeTap(onBus: 0) self.recordDisplay.isEnabled = true } }) let recordingFormat = inputNode.outputFormat(forBus: 0) inputNode.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { (buffer, when) in self.RecognitionRequest?.append(buffer) } AudioEngine.prepare() do { try AudioEngine.start() } catch { print("AudioEngine didn't initialize") } } func speechRecognizer(_ speechRecognizer: SFSpeechRecognizer, availabilityDidChange available: Bool) { if available { recordDisplay.isEnabled = true } else { recordDisplay.isEnabled = false } } @IBAction func playBTN(_ sender: Any) { let path = getDirectory().appendingPathComponent("\(file).m4a") do { AudioPlayer = try AVAudioPlayer(contentsOf: path) AudioPlayer.play() // Only play once AudioPlayer?.numberOfLoops = 0 // Set the volume of playback here. AudioPlayer?.volume = 10.0 print("play button pressed now") } catch { showAlert(title: "Error", message: "Please try again") } } // To display Alert Message func showAlert(title:String, message:String) { let alert = UIAlertController(title: title, message: message, preferredStyle: .alert) alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil)) present(alert, animated: true, completion: nil) } } }
[:]