본문 바로가기
IOS

Swift 애플 스피치 이용하여 STT 만들어보기.

by 일용직 코딩노동자 2023. 3. 29.
728x90
반응형

우선 info에 권한을 넣어줄게요.

 

  <key>NSAppleMusicUsageDescription</key>
  <string>앱에서 음성 인식을 사용하기 위해 마이크에 접근해야 합니다.</string>
  <key>NSMicrophoneUsageDescription</key>
  <string>앱에서 마이크를 사용하여 음성 인식을 처리합니다.</string>
  <key>NSSpeechRecognitionUsageDescription</key>
  <string>앱에서 마이크를 사용하여 음성 인식을 처리합니다.</string>

그리고 import 및 전역셋팅 해주겠습니다.

 

import Speech
import AVFoundation

private let speechRecognizer = SFSpeechRecognizer(locale: Locale.init(identifier: "ko-KR"))
private var recognitionRequest: SFSpeechAudioBufferRecognitionRequest?
private var recognitionTask: SFSpeechRecognitionTask?
private let audioEngine = AVAudioEngine()

@IBOutlet weak var resultText: UILabel! //변환된 텍스트 보여주는 라벨
@IBOutlet weak var startBtn: UIButton!  //음성인식 시작 및 종료 버튼

한국어로 하기위해서 ko-KR로 셋팅해줍니다.

class ViewController: UIViewController, SFSpeechRecognizerDelegate {
	override func viewDidLoad() {
        super.viewDidLoad()
        speechRecognizer?.delegate = self
    }
}

대리자 설정해줍니다.

 

그다음에 함수하나 정의해줍니다.

 func startRecording() {
        
        if recognitionTask != nil {
            recognitionTask?.cancel()
            recognitionTask = nil
        }
        
        let audioSession = AVAudioSession.sharedInstance()
        do {
            try audioSession.setCategory(AVAudioSession.Category.record)
            try audioSession.setMode(AVAudioSession.Mode.measurement)
            try audioSession.setActive(true, options: .notifyOthersOnDeactivation)
        }
        catch {}
      
        recognitionRequest = SFSpeechAudioBufferRecognitionRequest()
        
        let inputNode = audioEngine.inputNode
           
        guard let recognitionRequest = recognitionRequest else {
            fatalError("")
        }
        
        recognitionRequest.shouldReportPartialResults = true
        
        recognitionTask = speechRecognizer?.recognitionTask(with: recognitionRequest, resultHandler: { (result, error) in
            
            var isFinal = false
            
            if result != nil {
                print("변환된 음성 : ",result?.bestTranscription.formattedString)
                self.resultText.text = result?.bestTranscription.formattedString
                isFinal = (result?.isFinal)!
            }
            
            if isFinal {
                self.audioEngine.stop()
                inputNode.removeTap(onBus: 0)
                
                self.recognitionRequest = nil
                self.recognitionTask = nil
                
                self.startBtn.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 {}
    }

recognitionRequest.shouldReportPartialResults = true 
true   : 말하는 즉시 append되어 바로바로 변환되어서 보여집니다.

false : 음성인식을 종료시키면 한번에 변환되어 보여집니다.

 

inputNode.installTap에서 마이크를 통해 들어온 음성 PCM 데이터를 받습니다.

그리고나서

recognitionTask = speechRecognizer?.recognitionTask

(with: recognitionRequest, resultHandler: { (result, error) in

에서 result에 변환된 텍스트의 정보가 있습니다.

 

이제 버튼 클릭이벤트에

 

if audioEngine.isRunning { // 현재 음성인식이 수행중이라면
    audioEngine.stop() // 오디오 입력을 중단한다.
    recognitionRequest?.endAudio() // 음성인식 역시 중단
    startBtn.isEnabled = false
    startBtn.setTitle("말하기!", for: .normal)
}
else {
    startRecording()
    startBtn.setTitle("말하기 멈추기", for: .normal)
}

이렇게 넣어주시면 끝납니다.

728x90
반응형

댓글