user:
次のコードのエラーを修正してください。
# ==============================================================================
# 1. 必要なライブラリのインストール
# ==============================================================================
!pip install gTTS pydub
!pip install --upgrade gtts
# ※ pydubで音声結合を行うため、システム側のffmpegをインストールします
!apt-get install -y ffmpeg
import os
from datetime import datetime
from gtts import gTTS
from pydub import AudioSegment
# ==============================================================================
# 2. 文例データ(ここだけ書き換え可能)
# ==============================================================================
# ==============================================================================
# 3. 音声ファイルの生成と結合処理
# ==============================================================================
# 出力用の一時フォルダと最終的な結合音声オブジェクトの初期化
os.makedirs("temp_audio", exist_ok=True)
combined_audio = AudioSegment.empty()
# センテンス間の無音時間を定義(ミリ秒単位)
silence_short = AudioSegment.silent(duration=800) # 同じ文の中の言語の切り替え時の間(0.8秒)
silence_long = AudioSegment.silent(duration=1500) # 次の番号の文へ移る時の間(1.5秒)
print("音声の生成と結合を開始します。しばらくお待ちください(約1〜2分かかります)...")
for idx, (zh_text, en_text) in enumerate(sentences_data, 1):
# ファイル名用のパス定義
zh_path = f"temp_audio/zh_{idx}.mp3"
en_path = f"temp_audio/en_{idx}.mp3"
# 1. 中国語(女性・台湾/繁体字向けの自然なアクセント 'zh-TW')の生成
tts_zh = gTTS(text=zh_text, lang='zh-TW', slow=False)
tts_zh.save(zh_path)
# 2. 英語(女性・標準英語 'en')の生成
tts_en = gTTS(text=en_text, lang='en', slow=False)
tts_en.save(en_path)
# pydubで音声として読み込み
audio_zh = AudioSegment.from_mp3(zh_path)
audio_en = AudioSegment.from_mp3(en_path)
# 指示通りの順序で結合: 文X(中) -> 文X(英) -> 文X(中) -> 文X(英)
sentence_block = (
audio_zh + silence_short +
audio_en + silence_short +
audio_zh + silence_short +
audio_en
)
# 全体の音声オブジェクトに、長めの無音(文の区切り)を挟んで追加
if idx == 1:
combined_audio += sentence_block
else:
combined_audio += silence_long + sentence_block
if idx % 10 == 0:
print(f"進捗: {idx} / 80 文が完了しました...")
# ==============================================================================
# 4. 最終ファイルの保存とダウンロード
# ==============================================================================
date_str = datetime.now().strftime("%Y%m%d")
output_filename = f"{date_str}_中国語・英語リピート学習音声80選.mp3"
print("すべての音声を結合しています。ファイルをエクスポート中...")
# 高音質な128kbpsのmp3として保存
combined_audio.export(output_filename, format="mp3", bitrate="128k")
print(f"保存が完了しました: {output_filename}")
# Google ColabからPCへ自動ダウンロードを走らせる
from google.colab import files
files.download(output_filename)
print("ダウンロードが開始されました。")
エラーメッセージは次の通りです。
音声の生成と結合を開始します。しばらくお待ちください(約1〜2分かかります)...
WARNING:gtts.lang:'zh-TW' has been deprecated, falling back to 'zh-TW'. This fallback will be removed in a future version.
WARNING:gtts.lang:'zh-TW' has been deprecated, falling back to 'zh-TW'. This fallback will be removed in a future version.
---------------------------------------------------------------------------
gTTSError Traceback (most recent call last)
/tmp/ipykernel_441/774351411.py in <cell line: 0>()
40 # 2. 英語(女性・標準英語 'en')の生成
41 tts_en = gTTS(text=en_text, lang='en', slow=False)
---> 42 tts_en.save(en_path)
43
44 # pydubで音声として読み込み
2 frames
/usr/local/lib/python3.12/dist-packages/gtts/tts.py in stream(self)
298 # Request successful, good response,
299 # no audio stream in response
--> 300 raise gTTSError(tts=self, response=r)
301 log.debug("part-%i created", idx)
302
gTTSError: 200 (OK) from TTS API. Probable cause: Unknown
ChatGPT:
はい。今回のエラーは、pydubやffmpegではなく、gTTS → Google TTS API の通信部分で起きています。
特に、
gTTSError: 200 (OK) from TTS API. Probable cause: Unknown
というのがポイントです。HTTPとしては 200 OK が返っているのに、gTTSが期待した音声データとして解釈できなかった状態です。
また、もう一つ修正した方がいい点があります。
lang='zh-TW'
について、
WARNING:gtts.lang:'zh-TW' has been deprecated
が出ています。現在のgTTSでは台湾中国語の扱いが変わっているため、ここも整理した方が安全です。
おすすめの修正版
以下のように、gTTSのバージョンを固定し、TTS生成をリトライする仕組みを入れるのがおすすめです。
さらに、同じ中国語・英語音声を2回ずつ生成する必要はありません。現在のコードは、
中国語 → 英語 → 同じ中国語 → 同じ英語
なので、最初に生成したMP3をそのまま2回使えばOKです。
# ==============================================================================
# 1. 必要なライブラリのインストール
# ==============================================================================
!pip install -q "gTTS==2.5.4" pydub
!apt-get install -y ffmpeg
import os
import time
import shutil
from datetime import datetime
from gtts import gTTS
from pydub import AudioSegment
# ==============================================================================
# 2. 文例データ
# ==============================================================================
# ここに sentences_data を設定してください
#
# 例:
#
# sentences_data = [
# ("你好,今天我們來學習經濟學。", "Hello, today we will study economics."),
# ("什麼是國內生產總值?", "What is gross domestic product?"),
# ]
# ==============================================================================
# 3. TTS音声を安全に生成する関数
# ==============================================================================
def create_tts(text, lang, output_path, max_retries=5):
"""
gTTSで音声を生成する。
Google TTS APIの一時的なエラーに備えてリトライする。
"""
for attempt in range(1, max_retries + 1):
try:
print(
f" 音声生成: {lang} "
f"(試行 {attempt}/{max_retries})"
)
tts = gTTS(
text=text,
lang=lang,
slow=False
)
tts.save(output_path)
# ファイルが正常に生成されたか確認
if os.path.exists(output_path):
file_size = os.path.getsize(output_path)
if file_size > 1000:
print(f" OK: {output_path} ({file_size:,} bytes)")
return True
raise RuntimeError("音声ファイルが正常に生成されませんでした。")
except Exception as e:
print(f" エラー: {e}")
if os.path.exists(output_path):
os.remove(output_path)
if attempt < max_retries:
wait_time = attempt * 3
print(
f" {wait_time}秒待ってから再試行します..."
)
time.sleep(wait_time)
else:
print(
f" 【失敗】{lang}: "
f"{max_retries}回試行しましたが失敗しました。"
)
return False
return False
# ==============================================================================
# 4. 一時フォルダの準備
# ==============================================================================
temp_dir = "temp_audio"
# 前回の途中生成ファイルを削除
if os.path.exists(temp_dir):
shutil.rmtree(temp_dir)
os.makedirs(temp_dir, exist_ok=True)
combined_audio = AudioSegment.empty()
# ==============================================================================
# 5. 無音時間
# ==============================================================================
silence_short = AudioSegment.silent(
duration=800
)
silence_long = AudioSegment.silent(
duration=1500
)
# ==============================================================================
# 6. 音声生成と結合
# ==============================================================================
print(
"音声の生成と結合を開始します。"
"しばらくお待ちください..."
)
total = len(sentences_data)
for idx, (zh_text, en_text) in enumerate(sentences_data, 1):
print(f"\n===== {idx} / {total} =====")
zh_path = f"{temp_dir}/zh_{idx}.mp3"
en_path = f"{temp_dir}/en_{idx}.mp3"
# --------------------------------------------------------------------------
# 中国語
# --------------------------------------------------------------------------
#
# 台湾向け中国語。
# zh-TW の警告が出る場合は、gTTSの仕様変更の影響を受ける可能性があります。
#
# まず zh-TW で試します。
# --------------------------------------------------------------------------
zh_success = create_tts(
zh_text,
"zh-TW",
zh_path
)
if not zh_success:
raise RuntimeError(
f"{idx}番目の中国語音声の生成に失敗しました。"
)
# --------------------------------------------------------------------------
# 英語
# --------------------------------------------------------------------------
en_success = create_tts(
en_text,
"en",
en_path
)
if not en_success:
raise RuntimeError(
f"{idx}番目の英語音声の生成に失敗しました。"
)
# --------------------------------------------------------------------------
# MP3を読み込む
# --------------------------------------------------------------------------
audio_zh = AudioSegment.from_mp3(zh_path)
audio_en = AudioSegment.from_mp3(en_path)
# --------------------------------------------------------------------------
# 中国語 → 英語 → 中国語 → 英語
#
# 既に生成した音声を再利用するので、
# 同じ音声を2回生成する必要はありません。
# --------------------------------------------------------------------------
sentence_block = (
audio_zh
+ silence_short
+ audio_en
+ silence_short
+ audio_zh
+ silence_short
+ audio_en
)
# --------------------------------------------------------------------------
# 全体に追加
# --------------------------------------------------------------------------
if idx == 1:
combined_audio += sentence_block
else:
combined_audio += (
silence_long
+ sentence_block
)
if idx % 10 == 0 or idx == total:
print(
f"\n進捗: {idx} / {total} 文が完了しました。"
)
# ==============================================================================
# 7. MP3として保存
# ==============================================================================
date_str = datetime.now().strftime("%Y%m%d")
output_filename = (
f"{date_str}_中国語・英語リピート学習音声"
f"{total}選.mp3"
)
print("\nすべての音声を結合しています。")
print("MP3ファイルをエクスポート中...")
combined_audio.export(
output_filename,
format="mp3",
bitrate="128k"
)
print(
f"\n保存が完了しました:\n"
f"{output_filename}"
)
# ==============================================================================
# 8. Google Colabからダウンロード
# ==============================================================================
from google.colab import files
files.download(output_filename)
print("ダウンロードを開始しました。")
今回のエラーで重要なところ
実は、エラーが出た場所はここです。
tts_en = gTTS(text=en_text, lang='en', slow=False)
tts_en.save(en_path)
つまり、
中国語TTS
↓
成功
↓
英語TTS
↓
Google TTS API
↓
200 OK
↓
gTTSが音声として認識できない
↓
gTTSError
という流れです。
ffmpegは今回のエラー原因ではありません。
pydubがMP3を読み込むところまで到達していません。
もう一つ重要な改善点
元コードでは毎回、
audio_zh
audio_en
audio_zh
audio_en
を作るために、実際には中国語・英語を2回ずつGoogle TTSに送る設計にしているように見えます。
しかし、
audio_zh + silence + audio_en + silence + audio_zh + silence + audio_en
とすれば、1回生成した音声データを再利用できます。
これはかなり重要です。
80文なら、
- 元の設計:最大 320回 TTS生成
- 修正版:160回 TTS生成
になります。
Google TTS APIへのアクセス回数を半分にできるので、今回のような一時的なAPIエラーにも遭遇しにくくなります。
さらに安定させるなら
80文を一気に実行する場合、私はもう一段改善して、
「生成済みMP3は残して、途中でColabがエラーになっても途中から再開できる」
方式にするのをおすすめします。
例えば、
temp_audio/
├── zh_1.mp3
├── en_1.mp3
├── zh_2.mp3
├── en_2.mp3
├── ...
├── zh_80.mp3
└── en_80.mp3
としておけば、35番でGoogle TTSが落ちても、1~34番をもう一度生成する必要がありません。
80文の中国語・英語リピート教材をColabで作る用途なら、この「途中再開可能版」がかなり実用的です。
user:
ありがとうございました。今回の内容をブログに記録したいので、タイトルを考えてください。
ChatGPT:
もちろんです。今回の内容なら、**「Colab × gTTS × pydubで音声教材を自動生成する」**という技術要素と、gTTSのAPIエラーをどう直したかの両方がタイトルに入ると、後から検索もしやすいです。
技術ブログらしいタイトル
- Google ColabでgTTSの「200 OKなのにgTTSError」が発生したときの原因と対処法
- gTTSで音声教材を自動生成する ― Google TTS APIエラーとリトライ処理への対応
- Python・gTTS・pydubで中国語&英語のリピート学習音声を自動生成する
- Google Colab × gTTS × pydubで音声教材を作る ― gTTSErrorの原因と改善方法
- gTTSの「200 (OK) from TTS API」でハマった話 ― Google Colabで安定して音声生成する方法
今回のブログ内容に特に合いそうなもの
「Google Colab × gTTS × pydubで音声教材を自動生成する ― gTTSError『200 OK』の原因とリトライ処理」
これが一番おすすめです。
「何を作った記事なのか」→ 音声教材の自動生成
「何を使ったのか」→ Google Colab / gTTS / pydub
「どんな問題を解決したのか」→ gTTSError 200 OK
が全部タイトルから分かります。
少しシリーズ感を出すなら、
「Pythonで音声教材を作る!Google Colab × gTTS × pydub ― gTTSError『200 OK』を攻略する」
もかなりブログ向きです。