作成日: 2024-08-11
更新日: 2024-08-01

pythonでgTTSを呼び出し、text-to-speechを実現する

pythonでgTTSを呼び出し、text-to-speechを実現する

Dockerでpythonの実行環境を構築する

以下のDockerfileを用いて、pythonの実行環境を構築します。

FROM ubuntu:22.04
USER root
WORKDIR /root

ENV LANG ja_JP.UTF-8
ENV LANGUAGE ja_JP:ja
ENV LC_ALL ja_JP.UTF-8
ENV TZ JST-9
ENV TERM xterm
ARG python_version="3.12.4"

COPY requirements.txt /root/

# Set locale
RUN apt update -y \
    && apt install -y --no-install-recommends language-pack-ja-base \
    && locale-gen ja_JP.UTF-8 \
    && update-locale \
    && ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone \
    && apt update -y \
    && apt install -y --no-install-recommends tzdata

# Install packages
# Ref: https://github.com/pyenv/pyenv/wiki#suggested-build-environment
RUN apt update -y \
    && apt install -y --no-install-recommends \
    build-essential \
    curl \
    git \
    libbz2-dev \
    libdb-dev \
    libffi-dev \
    libgdbm-dev \
    liblzma-dev \
    libncursesw5-dev \
    libreadline-dev \
    libsqlite3-dev \
    libssl-dev \
    libxml2-dev \
    libxmlsec1-dev \
    tk-dev \
    uuid-dev \
    wget \
    xz-utils \
    zlib1g-dev \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

# Install Python
RUN cd /usr/local/src \
    && wget --no-check-certificate https://www.python.org/ftp/python/${python_version}/Python-${python_version}.tar.xz \
    && tar -Jxvf Python-${python_version}.tar.xz \
    && cd Python-${python_version} \
    && ./configure --with-ensurepip \
    && make \
    && make install

# Set alias
#RUN echo 'alias python=python3' >> ~/.bashrc
#RUN echo 'alias pip=pip3' >> ~/.bashrc
#RUN . ~/.bashrc

RUN pip3 install --upgrade pip \
    && pip3 install -r /root/requirements.txt \
    && pip3 install --upgrade setuptools \
    && apt autoremove -y

CMD ["bash"]

コンテナを起動して、作業を行います。

docker compose pull
docker compose build
docker compose up

pythonからgTTSを呼び出して、テキストから音声を取得し、mp3として保存する

まず、以下にコードを示します。

import logging
import os
import time
from gtts import gTTS

def generate_audio_with_gtts(text, output_path, language):
    try:
        tts = gTTS(text=text, lang=language)
        tts.save(output_path)
        time.sleep(1)  # APIリクエスト後に1秒待機
    except Exception as e:
        logging.error(f"gTTSエラー: {str(e)}")

def generate_audio_from_script(script_path, language):
    output_dir = os.path.dirname(script_path)
    temp_dir = os.path.join(output_dir, "temp_" + language)
    if not os.path.exists(temp_dir):
        os.makedirs(temp_dir)
    
    temp_files = []
    combined_audio = AudioSegment.empty()
    
    try:
        with open(script_path, 'r', encoding='utf-8') as f:
            lines = f.readlines() # script_pathから全体を読み込む
        
        for i, line in enumerate(tqdm(lines, desc="音声生成")):
            line = line.strip()
            if line:
                temp_output_path = os.path.join(temp_dir, f"temp_line_{i+1:03d}.mp3")
                generate_audio_with_gtts(line, temp_output_path, language)
                
                temp_files.append(temp_output_path)
                audio_segment = AudioSegment.from_mp3(temp_output_path)

                combined_audio += audio_segment
        
        # 統合されたオーディオを保存
        output_filename = f"script_{language}.mp3"
        output_path = os.path.join(output_dir, output_filename)
        combined_audio.export(output_path, format='mp3')
        
        logging.info(f"音声生成完了: {output_path}")
    except Exception as e:
        logging.error(f"エラー: 音声生成中に問題が発生しました: {script_path}, {str(e)}")
    finally:
        # 一時ファイルの削除
        for temp_file in temp_files:
            try:
                os.remove(temp_file)
            except Exception as e:
                logging.warning(f"一時ファイルの削除中にエラーが発生しました: {temp_file}, エラー: {str(e)}")
        os.rmdir(temp_dir)

やっていることは簡単です。

gTTSを呼び出してテキストを渡すと、ttsを返してくれます。

ttsにmp3のファイルのパスを渡すと、そのパスにitsのmp3ファイルを保存します。

gTTSに大きなデータを送るとエラーを返す可能性があるため、ファイルから1行ずつ取得して渡しています。

そのため、1行ずつ取得したmp3のファイルを統合するのにAudioSegmentを使っています。

今日はここまで。