Coding 공부/Python

Python으로 음성 인식 응용 프로그램 만들기

CBJH 2024. 8. 7.
728x90
반응형

안녕하세요! 오늘은 Python을 사용해서 오디오 파일을 텍스트로 변환하는 멋진 응용 프로그램을 만들어볼 거예요. 이 프로그램은 GUI(그래픽 사용자 인터페이스)를 통해 사용자가 쉽게 사용할 수 있도록 만들어졌답니다. 프로그래밍을 모르는 친구들도 손쉽게 사용할 수 있게 하는 게 이번 프로젝트의 목표였어요!

 

왜 이 프로그램을 만들었나요?

 

요즘 긴 회의나 강의를 녹음해두고 나중에 텍스트로 변환하는 일이 많잖아요? 하지만 많은 온라인 서비스가 회원 가입이나 카드 정보를 요구해서 불편했죠. 그래서 제가 직접 이 프로그램을 만들어봤습니다. 이제 여러분도 친구들도 이 프로그램을 사용해서 무료로 텍스트 변환을 해볼 수 있습니다!

 

준비물: 필요한 라이브러리 설치하기

 

먼저, 프로그램을 실행하기 위해 몇 가지 라이브러리가 필요해요. 터미널(또는 명령 프롬프트)에 아래 명령어를 입력해 설치해 주세요.

pip install SpeechRecognition pydub
pip install pyaudio
  • SpeechRecognition: 음성을 텍스트로 변환하는 데 사용해요.
  • pydub: 오디오 파일을 조작하는 데 사용됩니다.
  • PyAudio: 오디오 처리를 지원하는 라이브러리입니다.

 

Google Web Speech API 사용

무료 사용

  • SpeechRecognition 라이브러리의 recognize_google 메서드는 Google Web Speech API를 사용합니다.
  • 이 API는 별도의 API 키 설정 없이 바로 사용할 수 있으며, Google에서 제공하는 웹 기반 음성 인식 기능을 무료로 활용할 수 있습니다.

제한 사항

  • 사용량 제한: 무료로 제공되지만, 사용량에 제한이 있을 수 있습니다. 특히, 과도한 요청이 있을 경우 실패할 수 있습니다.
  • 오디오 길이 제한: 일반적으로 이 API는 1분 미만의 짧은 오디오 파일에 최적화되어 있습니다. 긴 오디오 파일을 처리하려면 파일을 적절히 조각내어야 합니다.
  • 네트워크 연결 필요: 이 API는 인터넷을 통해 Google 서버에 요청을 보내기 때문에 네트워크 연결이 필요합니다.

 

GUI 프로그램 만들기

 

이제 본격적으로 프로그램을 만들어볼까요? 우리는 tkinter를 사용해서 간단한 GUI를 만들어 볼 거예요.

import tkinter as tk
from tkinter import filedialog, messagebox, scrolledtext
from tkinter import ttk  # ttk 모듈 추가
import speech_recognition as sr
from pydub import AudioSegment
from pydub.silence import split_on_silence
import os
import threading
import tempfile
import time  # time 모듈 임포트

def convert_audio(file_path):
    try:
        # 임시 폴더 생성
        with tempfile.TemporaryDirectory() as tempdir:
            # 오디오 파일 변환 (mp4 -> wav)
            audio = AudioSegment.from_file(file_path, format="mp4")
            audio = audio.set_frame_rate(16000)  # 16kHz로 샘플링 레이트 설정
            audio = audio.set_sample_width(2)    # LINEAR16 형식
            audio = audio.set_channels(1)        # 모노 채널
            audio = audio.normalize()            # 오디오 정규화
            audio += 6  # 6dB 증폭
            wav_file_path = os.path.join(tempdir, "converted_audio.wav")
            audio.export(wav_file_path, format="wav")

            # 음성 인식 초기화
            recognizer = sr.Recognizer()

            # 오디오 파일을 로드
            audio = AudioSegment.from_wav(wav_file_path)

            # 오디오 파일을 일정한 길이로 조각
            chunks = split_on_silence(
                audio,
                min_silence_len=500,
                silence_thresh=-40,
                keep_silence=250
            )

            full_text = ""
            total_chunks = len(chunks)

            for i, chunk in enumerate(chunks):
                # 10ms의 침묵 추가
                chunk_silent = AudioSegment.silent(duration=10)
                audio_chunk = chunk_silent + chunk + chunk_silent
                chunk_file = os.path.join(tempdir, f"chunk_{i}.wav")
                audio_chunk.export(chunk_file, format="wav")

                with sr.AudioFile(chunk_file) as source:
                    recognizer.adjust_for_ambient_noise(source, duration=0.5)
                    audio_data = recognizer.record(source)

                    success = False
                    retry_count = 3
                    for attempt in range(retry_count):
                        try:
                            # 한국어 인식 설정
                            text = recognizer.recognize_google(audio_data, language='ko-KR')
                            full_text += text + "\n\n"  # 각 chunk마다 1줄씩 띄워쓰기
                            success = True
                            break
                        except sr.UnknownValueError:
                            print(f"오디오를 인식할 수 없습니다: chunk {i}")
                            break
                        except sr.RequestError as e:
                            print(f"Google Web Speech API 요청 중 오류 발생 (재시도 {attempt + 1}/{retry_count}): {e}")
                            # 재시도 간격
                            time.sleep(1)

                    if not success:
                        print(f"오디오 조각 {i} 변환 실패")

                # 진행 상황 업데이트
                progress = int(((i + 1) / total_chunks) * 100)
                progress_var.set(progress)
                progress_label.config(text=f"진행 상황: {progress}%")
                root.update_idletasks()

            # 변환된 텍스트 출력
            output_text.delete(1.0, tk.END)
            output_text.insert(tk.END, full_text)
            messagebox.showinfo("완료", "오디오 변환이 완료되었습니다.")

    except Exception as e:
        messagebox.showerror("오류", f"오디오 변환 중 오류가 발생했습니다: {e}")

def select_file():
    file_path = filedialog.askopenfilename(filetypes=[("MP4 files", "*.mp4"), ("All files", "*.*")])
    if file_path:
        file_entry.delete(0, tk.END)
        file_entry.insert(tk.END, file_path)

def start_conversion():
    file_path = file_entry.get()
    if not file_path:
        messagebox.showwarning("경고", "파일을 선택해주세요.")
        return

    messagebox.showinfo("변환 시작", "변환을 시작합니다.")
    
    # 별도의 스레드에서 변환 실행
    conversion_thread = threading.Thread(target=convert_audio, args=(file_path,))
    conversion_thread.start()

# GUI 초기화
root = tk.Tk()
root.title("오디오 변환기")
root.geometry("600x400")

# 파일 선택
file_frame = tk.Frame(root)
file_frame.pack(pady=10)

file_label = tk.Label(file_frame, text="파일 경로:")
file_label.pack(side=tk.LEFT, padx=5)

file_entry = tk.Entry(file_frame, width=50)
file_entry.pack(side=tk.LEFT, padx=5)

file_button = tk.Button(file_frame, text="파일 선택", command=select_file)
file_button.pack(side=tk.LEFT, padx=5)

# 변환 버튼
convert_button = tk.Button(root, text="변환 시작", command=start_conversion, width=20)
convert_button.pack(pady=20)

# 진행 상황
progress_var = tk.IntVar()
progress_bar = ttk.Progressbar(root, variable=progress_var, maximum=100)  # ttk.Progressbar 사용
progress_bar.pack(fill=tk.X, padx=20, pady=10)

progress_label = tk.Label(root, text="진행 상황: 0%")
progress_label.pack()

# 변환된 텍스트 레이블
output_label = tk.Label(root, text="Speech-to-Text")
output_label.pack()

# 변환된 텍스트 출력
output_text = scrolledtext.ScrolledText(root, wrap=tk.WORD, height=10)
output_text.pack(fill=tk.BOTH, padx=20, pady=10, expand=True)

# GUI 실행
root.mainloop()

 

프로그램 설명

  1. 파일 선택하기
    • 사용자는 "파일 선택" 버튼을 클릭하여 변환할 mp4 파일을 선택할 수 있어요.
  2. 변환 시작하기
    • "변환 시작" 버튼을 클릭하면, 선택한 파일이 오디오로 변환되고, 텍스트로 인식되어 출력됩니다. 변환 진행 상황도 실시간으로 확인할 수 있어요!
  3. 진행 상황 표시
    • 변환 과정 중에 진행률을 퍼센트로 표시해줍니다. 여러분은 변환이 얼마나 진행되었는지 쉽게 알 수 있습니다.
  4. 변환된 텍스트 출력
    • 변환이 완료되면 변환된 텍스트가 프로그램에 표시됩니다. 변환된 내용을 바로 확인할 수 있어요.

 

실행 파일로 만들기

 

이제 만든 코드를 실행 파일로 만들어서, 프로그래밍을 모르는 친구들도 사용할 수 있게 해볼까요? PyInstaller를 사용하면 됩니다.

  1. 터미널(또는 명령 프롬프트)에서 다음 명령어를 실행합니다:
    • --onefile: 하나의 실행 파일로 만들어 줍니다.
    • --windowed: 콘솔 창 없이 GUI로 실행합니다.
  2. 이 명령을 실행하면 dist 폴더 안에 실행 파일이 생성됩니다. 이제 이 파일을 친구에게 공유해 주세요!
pyinstaller --onefile --windowed your_script.py

 

 

응용프로그램 구글 드라이브 링크 : https://drive.google.com/file/d/1crvm0HgGdFwCd65WmCnCaJ5sh_bVgjEa/view?usp=drive_link

 

마무리

 

오늘은 Python과 GUI를 사용해 오디오 파일을 텍스트로 변환하는 프로그램을 만들어봤습니다. 이 프로그램 덕분에 프로그래밍을 모르는 친구도 쉽고 빠르게 음성 인식을 할 수 있게 되었어요. 앞으로도 유용한 프로그램을 많이 만들어보세요! 궁금한 점이 있으면 언제든지 댓글로 물어봐 주세요. 😊

댓글