File size: 2,914 Bytes
857e7b5
 
 
9346a07
871ca5b
8a34b6e
9346a07
857e7b5
 
 
8a34b6e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
871ca5b
8a34b6e
871ca5b
 
 
 
857e7b5
 
 
871ca5b
857e7b5
 
871ca5b
857e7b5
 
871ca5b
8a34b6e
871ca5b
8a34b6e
 
871ca5b
 
8a34b6e
 
 
871ca5b
8a34b6e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
871ca5b
8a34b6e
871ca5b
8a34b6e
 
 
 
 
 
 
 
 
 
 
 
 
 
871ca5b
8a34b6e
871ca5b
8a34b6e
 
857e7b5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
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()