2025. 2. 5. 14:27ㆍFramework, Library
지난 글에서는 음성을 텍스트로 변환하는 기능인 STT (Speech-To-Text)를 iOS에서 구현하는 방법에 대해 배웠습니다.
Apple에서 STT 기술을 지원하는 Speech와 오디오 권한을 위한 AVFoundation 프레임워크를 사용해,
STT 기능을 iOS 애플리케이션에서 구현했던 코드 설명은 아래 링크를 통해 자세하게 확인할 수 있습니다 ^__^
[Speech] iOS에서 음성-텍스트 변환 기능 STT (Speech-To-Text) 구현하기
Apple의 Speech Framework 이해하기지난 학기 학교 캡스톤 프로젝트에서 구현했던 기술을 이제서야 글로 옮기려고 해요!간략하게 내용을 소개하고 넘어가자면, 지난 학기 프로젝트는 이라는 주제로
mini-min-dev.tistory.com
TTS (Text-To-Speech) 구현 코드부터!
이번 글에서는 위와 반대로 텍스트를 음성으로 변환하는 기능, TTS (Text-To-Speech) 기능을 구현해보려고 해요!
TTS 기능을 구현하는 코드는 STT에 비해 매우 간단합니다.
예전 글들과는 다르게 이번에는 TTS 기능을 구현하기 위한 코드가 어떻게 되는지부터 무작정 살펴볼게요!
- 텍스트를 음성으로 변환하고 재생하는데 사용되는 AVSpeechSynthesizer 객체는 AVFoundation 프레임워크에서 제공합니다.
- AVSpeechUtterance 객체에서 음성 합성을 위한 텍스트나 관련 속성들을 정의합니다.
- 앞에서 정의된 AVSpeechUtterance 객체를 AVSpeechSynthesizer에게 전달해 음성을 재생합니다.
import AVFoundation
final class TTSManager {
private let synthesizer = AVSpeechSynthesizer()
func speak(
text: String,
language: String = "ko-KR",
rate: Float = AVSpeechUtteranceDefaultSpeechRate
) {
let utterance = AVSpeechUtterance(string: text)
utterance.voice = AVSpeechSynthesisVoice(language: language)
utterance.rate = rate
synthesizer.speak(utterance)
}
}
실제 사용시에는 위에서 정의한 TTSManager 객체를 정의하고,
해당 클래스 내부에 있는 메서드 speak(text:) 파라미터에 텍스트를 전달해주기만 하면 음성이 재생됩니다!
*해당 메서드에서 Speech의 언어 설정 (voice)이나 음성 출력 속도 (rate) 같은 속성들은 파라미터 기본값을 지정해주고 있습니다.
엄청 간단하네요!
그럼 이제 위 코드에서 설명했던 AVSpeechSynthesizer, AVSpeechUtterance 등의 AVFoundation에서 제공해 주는 클래스.
그리고 그 외의 여러 TTS 관련된 속성들은 어떤 것들이 있는지 조금 더 자세하게 살펴볼까요?
private let ttsManager = TTSManager()
// TTS 기능 구현이 필요한 부분에 아래 코드를 추가
ttsManager.speak(text: "읽게 하고 싶은 텍스트 입력")
AVSpeechSynthesizer
💡 An object that produces synthesized speech from text utterances and enables monitoring or controlling of ongoing speech.
= 텍스트 발화로부터 합성된 음성을 만들고, 진행중인 음성에 대해 모니터링과 제어를 담당하는 객체입니다.
AVSpeechSynthesizer는 쉽게 말해
텍스트가 들어오면, 그 텍스트를 음성으로 합성해서 만드는 역할 + 그 음성을 재생하거나 멈추는 등의 제어를 수행하는 역할을 갖고 있는 객체입니다.
이때, 들어온 텍스트는 내부적으로 발화 (utterance)를 큐에 추가하여, 순차적으로 처리/관리되고 있죠!

위에서 말하기 시작을 위한 speak(text:) 메서드 외에도,
음성을 재개하거나, 일시정지하거나, 정지할 수 있도록 Control 할 수 있는 메서드는 아래와 같은 것들이 있습니다.
// 일시 정지된 지점에서 다시 시작
synthesizer.continueSpeaking()
// 일시 정지 (.immediate 즉시중단 / .word 단어 말하기 이후 중단)
synthesizer.pauseSpeaking(at: .immediate)
// 정지 (.immediate 즉시중단 / .word 단어 말하기 이후 중단)
synthesizer.stopSpeaking(at: .immediate)
이어서 AVSpeechSynthesizeDelegate에서는
음성 합성의 시작 (didStart)과 끝 (didFinish), 일시정지 (didPause), 재개 (didContinue), 취소 (didCancel) 등의 작업에 이벤트를 추적할 수 있도록 도와주는 델리게이트 메서드를 지원하고 있습니다.
synthesizer.delegate = self
func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didStart utterance: AVSpeechUtterance) {
print("말하기 시작!")
}
func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didFinish utterance: AVSpeechUtterance) {
print("말하기 종료!")
}
func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didPause utterance: AVSpeechUtterance) {
print("말하기 일시 정지!")
}
func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didContinue utterance: AVSpeechUtterance) {
print("말하기 다시 재개!")
}
func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didCancel utterance: AVSpeechUtterance) {
print("말하기 다시 재개!")
}
델리게이트 메서드 중 speechSynthesizer(_: willSpeakRangeOfSpeechString: utterance:)을 사용하면,
현재 SpeechSynthesizer가 읽고 있는 텍스트의 범위나 단어가 어떤 것인지 추적할 수도 있습니다.
func speechSynthesizer(
_ synthesizer: AVSpeechSynthesizer,
willSpeakRangeOfSpeechString characterRange: NSRange,
utterance: AVSpeechUtterance
) {
let attributedString = NSMutableAttributedString(string: utterance.speechString)
attributedString.addAttribute(.foregroundColor, value: UIColor.red, range: characterRange)
label.attributedText = attributedString
print("현재 읽히고 있는 텍스트 범위: \(characterRange)")
}
AVSpeechUtterance
💡 An object that encapsulates the text for speech synthesis and parameters that affect the speech.
= 음성 합성을 위한 텍스트와, 음성에 영향을 미치는 파라미터를 캡슐화하는 객체입니다.
하지만 위의 AVSpeechSynthesizer만으로는
"어떤 음성을 만들어야 하는지" "어떻게 음성을 만들어야 하는지"와 같은 구체적인 정보를 알 수 없습니다. 정의하지 않았기 때문이죠.
즉, 음성 합성기 (AVSpeechSynthesizer)에 위와 같은 구체적인 정보를 담아서 전달하는 객체가 하나 필요한데요.
그것이 바로 AVSpeechUtterance 클래스입니다.
쉽게 말하면, SpeechSynthesizer가 어떻게 동작할지를 정의하는 역할이라고 생각하면 됩니다!
- 발화 (Utterance) 정의 - "어떤 텍스트"를 음성으로 변환시키고 싶은지를 설정해야할겁니다!
- 음성 합성 (SpeechSynthesizer) 시 고려해야 하는 속성을 지정 - 말하기 속도, 높낮이, 목소리 크기 등을 지정해야겠죠?
- 언어 및 목소리 (AVSpeechSynthesisVoice) 설정 - 어떤 언어를 말할 것이고, 그중 어느 목소리를 지정할지도 정의해야겠네요!
간단하게 Utterance 객체가 담당하는 역할을 살펴봤는데,
이제 코드로도 어떻게 정의하는지 / 각 구체적인 속성은 어떻게 되는지도 자세하게 살펴봐야겠죠? 이번에는 표로 정리해 보겠습니다!
각 속성은 "utterance객체.속성이름"의 형태로 지정할 수 있습니다!
speechString | 음성으로 변환하고자 하는 텍스트 | String 타입 |
voice | 음성으로 사용할 목소리 | AVSpeechSynthesisVoice 타입 (init 메서드의 language 파라미터로 언어 타입을 지정할 수 있습니다!) |
pitchMultiplier | 음성의 음조 (높낮이) | 기본값은 1.0 / 낮은 0.5부터 높은 2.0 범위까지의 Float 타입 |
volume | 음성의 볼륨 | 기본값은 1.0 / 음소거 상태의 0.0부터 최대 1.0까지의 Float 타입 |
rate | 음성 말하기 속도 | 기본값은 AVSpeechUtteranceDefaultSpeechRate 0.0~1.0 범위의 Float 타입으로 지정할 수 있으며, Maximum, Minimum 값도 별도의 객체로 지정 가능 |
preUtteranceDelay | 말하기 전 대기시간 | TimeInterval 타입 |
postUtteranceDelay | 말하기가 끝난 이후 대기시간 | TimeInterval 타입 |
AVSpeechSynthesizer와 AVSpeechUtterance를 활용한 TTS 기능을 구현하는 것도 이제 할 수 있겠죠??
짧았던 이번 글은 여기까지입니다 ^__^
Reference
AVSpeechSynthesizer | Apple Developer Documentation
An object that produces synthesized speech from text utterances and enables monitoring or controlling of ongoing speech.
developer.apple.com
AVSpeechUtterance | Apple Developer Documentation
An object that encapsulates the text for speech synthesis and parameters that affect the speech.
developer.apple.com