1. はじめに
数か月前から英語の勉強を始め、試験を受ける必要も出てきたため、ここしばらく英語学習に取り組んでいます。とはいえ、学生時代から英語だけはどうしても苦手で、ずっと避けてきた科目です。それでももう逃げられなくなり、本格的に勉強を始めたものの、なかなか思うように進みませんでした。
そんな中で出会ったのが「Jump-start」という本です。短い英語のフレーズを聞きながら、自分で話してみたり、シャドーイングしたりして覚える内容で、実際にやってみたところ非常に効率が良いことに気づきました。この方法なら英単語の学習にも応用できるのでは?と思い、試してみたのが今回の記事です。
やったことはシンプルで、まず生成AIを使って英単語を含む短い英文を作成し、それをExcelに一覧化し、さらにその一覧をPythonで音声化し、ウォークマンで聞けるようにした——というのが今回の記事の内容です。
2. 実施環境
CPU: CORE i5 8th Gen
メモリ: 8GB
OS: Windows 11 22H2
3. 事前準備
以下の構成のエクセルファイルを生成AIを使って作成します。
私は最初の1列目だけを自分で作成し、その後は生成AIに指示を出してリストを作成しました。
指示内容としては、「以下の構成で、出力形式はタブ区切り(TSV)とし、Excelに直接貼り付けられる形で出力すること」というものです。
- 2列目:主要な品詞(例:動詞、名詞、形容詞、副詞など。複数ある場合は主要なものを1つ)
- 3列目:日本語訳(簡潔な意味)
- 4列目:その単語を使った自然な英語の例文(現在形・一般文で)
- 5列目:その例文の自然な日本語訳
作成した英単語リストの一部:
| English | Part of Speech | Japanese | Example Sentence | Japanese Translation |
|---|---|---|---|---|
| provide | 動詞 | 提供する | The school provides lunch for all students. | 学校は全生徒に昼食を提供する。 |
| provide | 名詞 | 提供 | The provision of clean water is essential for health. | 清潔な水の提供は健康に不可欠である。 |
| merchant | 名詞 | 商人 | That merchant sells spices from around the world. | その商人は世界中から香辛料を仕入れて販売している。 |
| needle | 名詞 | 針 | She threaded the needle carefully before sewing. | 彼女は縫う前に慎重に針に糸を通した。 |
| fasten | 動詞 | 締める | Please fasten your seatbelt before takeoff. | 離陸前にシートベルトを締めてください。 |
| mental | 形容詞 | 心の | He has strong mental resilience to overcome challenges. | 彼は困難を乗り越える強い精神的レジリエンスを持っている。 |
4.モジュールのインストール
既にインストールされている場合は不要ですが、今回のコードは以下のモジュールが必要です。
pip install ffmpeg-python
pip install edge-tts pandas openpyxl pydub
5. 作成したプログラム
今回の記事では以下の特徴を持つプログラムを作成しました。
-
作成したExcelファイルから、英単語・日本語訳・例文などを読み込み、Edge TTSを使用して音声ファイル(MP3)を自動生成
-
行番号の順に、1️⃣ 英単語 → 2️⃣ 日本語訳 → 3️⃣ 日本語例文 → 4️⃣ 英語例文の順で音声ファイルを生成
-
単調な音声にならないよう、20語(行)ごとに男性・女性の話者を交互に切り替え
-
出力された音声ファイルは、out_edge_tts_split フォルダ内に保存。ファイル名には「行番号+英単語+内容種別(例:_en_word, _ja_example)」が含まれる
import asyncio
import re
from pathlib import Path
import math
import pandas as pd
import edge_tts
IN_XLSX = "入力のエクセル.xlsx"
SHEET = 0
OUT_DIR = Path("out_edge_tts_split")
# 列インデックス(0始まり)
COL_EN_WORD = 0 # A: 英単語
COL_JA_MEAN = 2 # C: 日本語訳
COL_JA_EX_SENT = 4 # E: 例文の日本語訳
COL_EN_EX_SENT = 3 # D: 例文の英語
BLOCK_SIZE = 20 # 20行ごとに男女切替
# 英語ボイス(男性/女性)
EN_MALE, EN_FEMALE = "en-US-GuyNeural", "en-US-JennyNeural"
# 日本語ボイス(男性/女性)
JA_MALE, JA_FEMALE = "ja-JP-KeitaNeural", "ja-JP-NanamiNeural"
def slugify(s: str, maxlen: int = 40) -> str:
s = re.sub(r"\s+", "_", str(s).strip())
s = re.sub(r"[^A-Za-z0-9_\-]", "", s)
return (s[:maxlen] or "item").lower()
def pick_voice_pair(block_index: int, is_japanese: bool):
"""20行ごとに男女切替。英/日で別々に判定。"""
if is_japanese:
return (JA_MALE if block_index % 2 == 0 else JA_FEMALE)
else:
return (EN_MALE if block_index % 2 == 0 else EN_FEMALE)
def norm(x) -> str:
if x is None:
return ""
if isinstance(x, float) and math.isnan(x):
return ""
return str(x).strip()
async def tts_save(text: str, voice: str, path: Path):
if not text:
return False
path.parent.mkdir(parents=True, exist_ok=True)
comm = edge_tts.Communicate(text=text, voice=voice)
with open(path, "wb") as f:
async for chunk in comm.stream():
if chunk["type"] == "audio":
f.write(chunk["data"])
return True
async def main():
OUT_DIR.mkdir(parents=True, exist_ok=True)
# ヘッダ有無を簡易判定
df_probe = pd.read_excel(IN_XLSX, sheet_name=SHEET, header=None)
first = df_probe.iloc[0].astype(str).str.lower().tolist()
has_header = any(k in " ".join(first) for k in ["ja", "en", "japanese", "english", "英語", "日本語", "word", "meaning", "単語"])
if has_header:
df = pd.read_excel(IN_XLSX, sheet_name=SHEET) # ヘッダあり
rows = list(df.itertuples(index=False))
get = lambda row, idx: row[idx]
base_idx = 2
else:
df = df_probe
rows = list(df.itertuples(index=False))
get = lambda row, idx: row[idx]
base_idx = 1
en_playlist = []
ja_playlist = []
for i, row in enumerate(rows, start=base_idx):
en_word = norm(get(row, COL_EN_WORD) if len(row) > COL_EN_WORD else "")
ja_mean = norm(get(row, COL_JA_MEAN) if len(row) > COL_JA_MEAN else "")
ja_ex_sent = norm(get(row, COL_JA_EX_SENT) if len(row) > COL_JA_EX_SENT else "")
en_ex_sent = norm(get(row, COL_EN_EX_SENT) if len(row) > COL_EN_EX_SENT else "")
if not any([en_word, ja_mean, ja_ex_sent, en_ex_sent]):
print(f"[SKIP] 行{i}: 空行")
continue
# 20行ごと性別切替(英・日で別々)
en_block = (i - base_idx) // BLOCK_SIZE
ja_block = en_block
en_voice = pick_voice_pair(en_block, is_japanese=False)
ja_voice = pick_voice_pair(ja_block, is_japanese=True)
# ファイル名ベース
base_slug = slugify(en_word) or f"row{i}"
# --- 英(A→D)を別々に保存 ---
en_files_this_row = []
if en_word:
p = OUT_DIR / f"{i:04d}_{base_slug}_1_en_word.mp3"
ok = await tts_save(en_word, en_voice, p)
if ok:
en_files_this_row.append(p.name)
if en_ex_sent:
p = OUT_DIR / f"{i:04d}_{base_slug}_4_en_example.mp3"
ok = await tts_save(en_ex_sent, en_voice, p)
if ok:
en_files_this_row.append(p.name)
# --- 日(C→E)を別々に保存 ---
ja_files_this_row = []
if ja_mean:
p = OUT_DIR / f"{i:04d}_{base_slug}_2_mean.mp3"
ok = await tts_save(ja_mean, ja_voice, p)
if ok:
ja_files_this_row.append(p.name)
if ja_ex_sent:
p = OUT_DIR / f"{i:04d}_{base_slug}_3_ja_example.mp3"
ok = await tts_save(ja_ex_sent, ja_voice, p)
if ok:
ja_files_this_row.append(p.name)
# プレイリスト(行ごと順番を担保)
en_playlist.extend(en_files_this_row)
ja_playlist.extend(ja_files_this_row)
print(f"[OK] 行{i} EN:{en_voice} JA:{ja_voice} "
f"(en_files={len(en_files_this_row)}, ja_files={len(ja_files_this_row)})")
# プレイリスト出力
if en_playlist:
with open(OUT_DIR / "playlist_en.m3u", "w", encoding="utf-8") as f:
f.write("#EXTM3U\n")
for name in en_playlist:
f.write(name + "\n")
if ja_playlist:
with open(OUT_DIR / "playlist_ja.m3u", "w", encoding="utf-8") as f:
f.write("#EXTM3U\n")
for name in ja_playlist:
f.write(name + "\n")
print("完成:", OUT_DIR)
if __name__ == "__main__":
asyncio.run(main())
6. 実行
python make_vocab_edge_tts.py
実行後、out_edge_tts_split/ フォルダに以下のようなファイルが生成されます。
0001_hello_1_en_word.mp3
0001_hello_2_mean.mp3
0001_hello_3_ja_example.mp3
0001_hello_4_en_example.mp3
playlist_en.m3u
playlist_ja.m3u
- 1〜20行目:男性声
- 21〜40行目:女性声
- 41〜60行目:男性声 …のように交互に切り替わります。
7. 結果やまとめ
このプログラムを使うことで、英単語帳のExcelファイルから音声付きの語彙学習素材を作成し、ウォークマンなどのデバイスで再生できるようになりました。発音やイントネーションに多少の違和感がある部分もありますが、個人の英語学習用としては十分に実用的だと思いました(あくまで私の感想です)。
また、英語音声を聞きながら同じ内容を文字で確認すると、学習効果が高まるとも言われています。そのため、次のステップとしては、今回作成した英単語・例文のExcelファイルから、電子書籍として読めるPDF教材を作成していきたいと考えています。