Note: The file is large, so Google Drive may display a warning before download. This is normal.
Overview
Speak PDF는 사용자가 선택한 PDF 파일의 텍스트를 음성으로 변환해주는 데스크톱 애플리케이션입니다. Google Cloud Text-to-Speech(TTS) API를 활용하여 자연스러운 음성을 생성하며, Tkinter 기반의 직관적인 인터페이스를 통해 파일 선택부터 미리보기, 음성 설정, 오디오 저장까지 한 번에 처리할 수 있도록 개발했습니다.
System & Interface Design
Class Diagram
메인 App 클래스를 중심으로 기능별 프레임(Title, PDFUpload, PDFPreview, TTS)을 모듈화하여 설계했습니다.
Information Architecture
사용자 경험(UX)을 고려하여 좌측에는 시각적 정보(PDF 미리보기)를, 우측에는 기능적 제어(TTS 설정 및 텍스트 확인)를 배치했습니다.
- PDF 업로드 및 미리보기:
pdf2image를 통해 PDF 페이지를 이미지로 렌더링하여 사용자에게 시각적 피드백을 제공합니다. - 음성 설정: 페이지 범위 지정, 4가지 음성 옵션(한/영, 남/여) 선택, 재생 및 일시정지 기능을 제공합니다.
- 텍스트 출력: PDF에서 추출된 원문 텍스트를 실시간으로 확인할 수 있습니다.
Implementation
Tech Stack
Language: Python
GUI: Tkinter
PDF Processing: PyMuPDF(fitz), pdf2image
Audio: Pygame
API: Google Cloud TTS (Wavenet voice)
Concurrency: Threading
Key Implementation Details
- Google TTS API 연동: SynthesisInput, VoiceSelectionParams를 설정하여 요청을 보내고, 응답으로 받은 바이너리 데이터를 MP3 파일로 저장하여 재생합니다.
- 멀티스레딩(Multithreading): 네트워크 통신과 오디오 재생은 시간이 소요되는 작업입니다. 이를 메인 스레드에서 처리하면 UI가 멈추는(Freeze) 현상이 발생하므로, threading 모듈을 사용하여 백그라운드에서 처리하도록 구현했습니다.
- 오디오 제어:
pygame.mixer를 활용해 재생 상태를 추적하고, 하나의 버튼으로 일시정지(Pause)와 재개(Resume)를 전환하는 토글 로직을 구현했습니다.
Problem Solving Process
Problem
일부 PDF에서 텍스트를 추출하는 과정에서 단어 사이의 공백이 사라지고 “ThisIsExample”처럼 글자가 붙어서 추출되는 현상이 발생했습니다.
Solution
PyPDF2 대신 PDF의 내부 레이아웃을 더 정교하게 분석하는 PyMuPDF(fitz)로 라이브러리를 교체했습니다. page.get_text() 메서드를 통해 줄바꿈과 공백이 보존된 고품질의 텍스트를 얻을 수 있었습니다.
Result
Future Improvements
- GUI에서 오류 알림
API 인증 오류가 발생 시 UI 상에서 메시지 띄우기 - 정밀한 재생 제어
재생 바 등을 통해 재생 위치를 조정하는 기능 추가 - 파일 저장 포맷 다양화
MP3 외에 WAV, 또는 자막을 입힌 영상(mp4) 저장 옵션 제공하기 - 보이스 선택 시 샘플 오디오 미리 듣기 추가
Conclusion
이번 프로젝트를 통해 Google Cloud API의 인증 체계와 클라이언트-서버 간의 데이터 주고받는 과정을 깊이 있게 이해할 수 있었습니다. 특히 GUI 프로그램에서 사용자 경험을 결정짓는 핵심은 ‘응답성’이라는 것을 깨달았으며, 이를 위해 멀티스레딩을 적재적소에 활용하는 법을 익혔습니다. 앞으로는 더 복잡한 문서 구조(표, 이미지 내 텍스트 등)도 정확히 인식할 수 있도록 OCR 기능을 추가해보고 싶습니다.
reference
Text-to-Speech documentation: https://cloud.google.com/text-to-speech/do
Posted on: June 03, 2025