EEYatHo 앱 깎는 이야기

Swift ) TTS (Text To Speech) - EEYatHo iOS 본문

iOS, Swift/Feature

Swift ) TTS (Text To Speech) - EEYatHo iOS

EEYatHo 2022. 5. 5. 22:20
반응형

 

TTS ( Text To Speech )


Text To Speech : 말 그대로 문자열을, 목소리로 읽어주는 것을 말한다.

Swift 에서는 기본적으로 지원하는 기능을 사용하면 된다. ( AVSpeechSynthesizer )

 

 

 

SingleTon 으로 간단한 구현


Swift 에서 정말 간단하게 사용할 수 있도록 제공하고 있다.

 

AVFoundation 을 import 하고,

인터페이스 function 2개만 ( play, stop ) 구현하면 되는 수준.

 

간단하게 하기위해, language 를 ko-KR 로 고정했기에, 한국 발음만 나오게 된다.

 

import AVFoundation

class TTSManager {
    
    static let shared = TTSManager()
    
    private let synthesizer = AVSpeechSynthesizer()
    
    internal func play(_ string: String) {
        let utterance = AVSpeechUtterance(string: string)
        utterance.voice = AVSpeechSynthesisVoice(language: "ko-KR")
        utterance.rate = 0.4
        synthesizer.stopSpeaking(at: .immediate)
        synthesizer.speak(utterance)
    }
    
    internal func stop() {
        synthesizer.stopSpeaking(at: .immediate)
    }
}
TTSManager.shared.play("퇴근시켜주세요")
TTSManager.shared.stop()

 

 

 

 

 

목소리 언어 선택 with UserDefaults , ActionSheet


아래는 ActionSheet 로 유저에게 언어를 선택하게 하고, 선택한 값을 UserDefaults 로 저장하는 코드이다.

 

지원하는 language 를 얻어올 수 있고, ( AVSpeechSynthesisVoice.speechVoices() )

language 를 유저에게 보여줄 수 있게, 로컬라이징도 할 수 있다. ( "한국어(대한민국)" , "힌디어(인도)" 등 )

 

선택한 언어의 BCPCode 를 UserDefaults 에 저장한다. ( "ko-KR", "eu-AU" 등 )

TTS 에서 언어를 설정할 때, BCPCode 를 사용하기 때문이다.

 

 

extension TTSManager {
    
    internal func showTTSLanguageActionSheet(vc: UIViewController) {
        
        let actionSheet = UIAlertController(title: "TTS 언어를 선택해주세요", message: nil, preferredStyle: .actionSheet)
        
        let nowBCPCode = getTTSBCPCode()
        
        AVSpeechSynthesisVoice.speechVoices().forEach { voice in
            let BCPCode = voice.language
            var title = BCPCodeToTitle(BCPCode)
            
            var style = UIAlertAction.Style.default
            if BCPCode == nowBCPCode {
                title += " (적용 중)"
                style = .destructive
            }
            let action = UIAlertAction(title: title, style: style) { action in
                print(title)
                print(BCPCode)
                setTTSBCPCode(BCPCode)
            }
            actionSheet.addAction(action)
        }
        
        let cancel = UIAlertAction(title: "취소".localized(), style: .cancel)
        actionSheet.addAction(cancel)
        
        vc.present(actionSheet, animated: true, completion: nil)
    }
    
    /// 로컬라이징
    private func BCPCodeToTitle(_ BCPCode: String) -> String {
        let current = Locale.current.languageCode
        let language = NSLocale.init(localeIdentifier: current!)
        let title = language.displayName(forKey: NSLocale.Key.identifier, value: BCPCode)?.description
        return title ?? BCPCode
    }
    
    
    // MARK: - UserDefaults
    private func setTTSBCPCode(_ BCPCode: String) {
        UserDefaults.standard.setValue(BCPCode, forKey: "TTSBCPCode")
    }
    
    private func getTTSBCPCode() -> String {
        if let BCPCode = UserDefaults.standard.string(forKey: "TTSBCPCode") {
            return BCPCode
        } else {
            let defaultStr = "ko-KR"
            setTTSBCPCode(defaultStr)
            return defaultStr
        }
    }
}
TTSManager.shared.showTTSLanguageActionSheet(self)

 

 

 

Comments