|
import gradio as gr |
|
import requests |
|
import subprocess |
|
import shutil |
|
import uuid |
|
import json |
|
import os |
|
|
|
API_BASE = "https://zpdic.ziphil.com/api/v0" |
|
|
|
def get_word_json(api_key, dict_id, word_number): |
|
try: |
|
url = f"{API_BASE}/dictionary/{dict_id}/word/{int(word_number)}" |
|
resp = requests.get(url, headers={"X-Api-Key": api_key}) |
|
return resp.json() |
|
except Exception as e: |
|
return {"error": str(e)} |
|
|
|
def get_example_json(api_key, dict_id, example_number): |
|
try: |
|
url = f"{API_BASE}/dictionary/{dict_id}/example/{int(example_number)}" |
|
resp = requests.get(url, headers={"X-Api-Key": api_key}) |
|
return resp.json() |
|
except Exception as e: |
|
return {"error": str(e)} |
|
|
|
def speak_ipa_to_wav(ipa_text, pitch, speed): |
|
if not ipa_text.strip(): |
|
return "❌ IPAが入力されていません。", None |
|
|
|
out_path = f"/tmp/{uuid.uuid4().hex}.wav" |
|
|
|
try: |
|
subprocess.run([ |
|
"espeak-ng", |
|
"-v", "en", |
|
"-p", str(pitch), |
|
"-s", str(speed), |
|
"-w", out_path, |
|
f"[[{ipa_text}]]" |
|
], check=True) |
|
return f"✅ 発音完了: {ipa_text}", out_path |
|
except subprocess.CalledProcessError as e: |
|
return f"❌ 発音エラー: {e}", None |
|
|
|
with gr.Blocks() as demo: |
|
gr.Markdown("## 🎙️ IPA読み上げ + ZpDIC API表示ツール(Docker対応)") |
|
|
|
with gr.Row(): |
|
api_key = gr.Textbox(label="🔑 APIキー", type="password") |
|
dict_id = gr.Textbox(label="📘 辞書ID") |
|
|
|
with gr.Tab("📋 単語JSONを表示"): |
|
word_num = gr.Number(label="🔢 単語番号", precision=0) |
|
fetch_word_btn = gr.Button("📥 単語JSONを取得") |
|
word_json = gr.JSON(label="単語データ") |
|
|
|
with gr.Tab("📋 例文JSONを表示"): |
|
example_num = gr.Number(label="🔢 例文番号", precision=0) |
|
fetch_example_btn = gr.Button("📥 例文JSONを取得") |
|
example_json = gr.JSON(label="例文データ") |
|
|
|
with gr.Tab("🎤 IPA直接読み上げ"): |
|
ipa_input = gr.Textbox(label="🎧 IPAを入力 (例: hɛˈloʊ wɜːrld)", lines=2) |
|
with gr.Row(): |
|
pitch = gr.Slider(0, 99, value=50, label="🎵 ピッチ") |
|
speed = gr.Slider(80, 300, value=150, label="🏃 速度") |
|
speak_btn = gr.Button("▶ 音声ファイル生成") |
|
result = gr.Textbox(label="📣 結果") |
|
audio = gr.Audio(label="🔊 音声", type="filepath") |
|
|
|
fetch_word_btn.click( |
|
get_word_json, |
|
inputs=[api_key, dict_id, word_num], |
|
outputs=word_json |
|
) |
|
|
|
fetch_example_btn.click( |
|
get_example_json, |
|
inputs=[api_key, dict_id, example_num], |
|
outputs=example_json |
|
) |
|
|
|
speak_btn.click( |
|
speak_ipa_to_wav, |
|
inputs=[ipa_input, pitch, speed], |
|
outputs=[result, audio] |
|
) |
|
|
|
demo.launch() |