File size: 4,770 Bytes
5ae4c06
 
 
 
fa5d44d
b093de7
5ae4c06
fa5d44d
 
 
 
 
 
 
 
 
 
5ae4c06
 
 
 
 
fa5d44d
 
5ae4c06
 
 
 
 
b868660
03f1298
b868660
a4ad2c0
 
 
 
 
 
 
 
b868660
 
 
03f1298
5ae4c06
 
 
 
 
fa5d44d
5ae4c06
a6c95bf
5ae4c06
fa5d44d
5ae4c06
 
 
 
fa5d44d
5ae4c06
a6c95bf
5ae4c06
fa5d44d
5ae4c06
 
a6c95bf
5ae4c06
 
 
 
 
a4ad2c0
5ae4c06
a4ad2c0
 
 
 
 
 
 
367abd3
5ae4c06
 
fa5d44d
5ae4c06
 
 
fa5d44d
367abd3
a4ad2c0
 
 
 
 
 
 
5ae4c06
 
a4ad2c0
 
5ae4c06
 
 
 
 
 
 
 
fa5d44d
5ae4c06
 
 
 
 
 
a4ad2c0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5ae4c06
 
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
import os
from gtts import gTTS
import gradio as gr

# ์Šคํ† ๋ฆฌ ๋ฐ์ดํ„ฐ (ํ…์ŠคํŠธ + ์ด๋ฏธ์ง€ URL ํฌํ•จ)
image_base_url = "https://huggingface.co/spaces/englissi/englishstories/resolve/main/image/"
stories = [
    {"text": "Sam has a cat.", "image": f"{image_base_url}1.webp"},
    {"text": "The cat is fat and tan.", "image": f"{image_base_url}2.webp"},
    {"text": "Sam and the cat nap on a mat.", "image": f"{image_base_url}3.webp"},
    {"text": "Ben has a red pen.", "image": f"{image_base_url}4.webp"},
    {"text": "He pets a hen in a den.", "image": f"{image_base_url}5.webp"},
    {"text": "Tim sits and grins.", "image": f"{image_base_url}6.webp"},
    {"text": "A big pig digs in the mud.", "image": f"{image_base_url}7.webp"},
    {"text": "Dot the dog jogs and hops.", "image": f"{image_base_url}8.webp"},
    {"text": "Gus the pup has a cup.", "image": f"{image_base_url}9.webp"},
    {"text": "Fun in the sun is the best!", "image": f"{image_base_url}10.webp"}
]

# ์Œ์„ฑ ํŒŒ์ผ ์ƒ์„ฑ ํ•จ์ˆ˜ (gTTS ์ด์šฉ)
def generate_audio(text, filename="story.mp3"):
    try:
        repeated_text = " ".join([text] * 3)  # 3๋ฒˆ ๋ฐ˜๋ณตํ•ด์„œ ์ฝ๊ธฐ
        tts = gTTS(repeated_text, lang='en')
        tts.save(filename)
    except Exception as e:
        print("TTS ์ƒ์„ฑ ์˜ค๋ฅ˜:", e)
    return filename

# ์Šคํ† ๋ฆฌ ํ…์ŠคํŠธ๋ฅผ HTML ์Šคํƒ€์ผ๋กœ ํฌ๊ฒŒ ํ‘œ์‹œํ•˜๊ณ  ์ค‘์•™ ์ •๋ ฌํ•˜๋Š” ํ•จ์ˆ˜
def format_story_text(text):
    return f"""
    <div style='
        font-size:4em;
        font-weight:bold;
        text-align:center;
        color:#FF4500;
        font-family:sans-serif;
        margin: 20px 0;
    '>
        {text}
    </div>
    """

# ์ดˆ๊ธฐ ์Šคํ† ๋ฆฌ ๋กœ๋”ฉ ํ•จ์ˆ˜
def init_story():
    index = 0
    story = stories[index]
    text = story["text"]
    image = story["image"]
    audio_file = generate_audio(text, filename="story.mp3")
    return index, text, image, audio_file

# "๋‹ค์Œ" ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ ํ˜ธ์ถœ๋˜๋Š” ํ•จ์ˆ˜
def next_story(current_index):
    new_index = (current_index + 1) % len(stories)
    story = stories[new_index]
    text = story["text"]
    image = story["image"]
    audio_file = generate_audio(text, filename="story.mp3")
    return new_index, format_story_text(text), image, audio_file, text

# "์žฌ์ƒ" ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ ํ˜ธ์ถœ๋˜๋Š” ํ•จ์ˆ˜
def play_story(current_text):
    audio_file = generate_audio(current_text, filename="story.mp3")
    return audio_file

# ์ดˆ๊ธฐ ๋ฐ์ดํ„ฐ ์„ค์ •
init_index, init_text, init_image, init_audio = init_story()

# Gradio ์ธํ„ฐํŽ˜์ด์Šค ๊ตฌ์„ฑ
with gr.Blocks(title="๐Ÿ“š ๊ท€์—ฌ์šด ์Šคํ† ๋ฆฌ ์•ฑ") as demo:
    gr.Markdown(
        "<div style='text-align:center; font-size:2em; font-weight:bold;'>๐ŸŽˆ ์žฌ๋ฏธ์žˆ๋Š” ์˜์–ด ์Šคํ† ๋ฆฌ ํƒ€์ž„! ๐Ÿ“–</div>",
        unsafe_allow_html=True
    )
    
    gr.Markdown(
        "<div style='text-align:center; font-size:1.2em;'>๐Ÿฑ ๊ท€์—ฌ์šด ์ด์•ผ๊ธฐ์™€ ํ•จ๊ป˜ ์˜์–ด๋ฅผ ๋ฐฐ์›Œ๋ณด์•„์š”! <br> "
        "๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ ๋‹ค์Œ ์ด์•ผ๊ธฐ๋กœ ๋„˜์–ด๊ฐ€๊ณ , ์Œ์„ฑ์„ ๋“ค์œผ๋ฉฐ ๋”ฐ๋ผ ์ฝ์–ด๋ณด์„ธ์š”! ๐ŸŽต</div>",
        unsafe_allow_html=True
    )

    # ์ƒํƒœ๊ฐ’: ํ˜„์žฌ ์Šคํ† ๋ฆฌ ์ธ๋ฑ์Šค์™€ ํ˜„์žฌ ์Šคํ† ๋ฆฌ ํ…์ŠคํŠธ ์ €์žฅ
    state_index = gr.State(value=init_index)
    state_text = gr.State(value=init_text)

    # UI ์ปดํฌ๋„ŒํŠธ ์ƒ์„ฑ
    story_text = gr.Markdown(value=format_story_text(init_text), label="์Šคํ† ๋ฆฌ")

    story_image = gr.Image(
        value=init_image, label="์ด๋ฏธ์ง€", type="filepath", width=400, height=400,
        container=True
    )

    audio_output = gr.Audio(value=init_audio, label="๐ŸŽง ์Œ์„ฑ ์žฌ์ƒ", type="filepath", autoplay=True)

    with gr.Row():
        next_button = gr.Button("๐Ÿ‘‰ ๋‹ค์Œ ์ด์•ผ๊ธฐ", elem_id="next-btn")
        play_button = gr.Button("๐Ÿ”Š ๋‹ค์‹œ ๋“ฃ๊ธฐ", elem_id="play-btn")

    # "๋‹ค์Œ" ๋ฒ„ํŠผ ํด๋ฆญ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ
    next_button.click(
        fn=next_story,
        inputs=[state_index],
        outputs=[state_index, story_text, story_image, audio_output, state_text]
    )

    # "์žฌ์ƒ" ๋ฒ„ํŠผ ํด๋ฆญ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ
    play_button.click(
        fn=play_story,
        inputs=[state_text],
        outputs=[audio_output]
    )

# CSS ์Šคํƒ€์ผ ์ถ”๊ฐ€ (๊ท€์—ฌ์šด ํ…Œ๋งˆ)
demo.css = """
body {
    background-color: #FFFAF0; /* ๋”ฐ๋œปํ•œ ํฌ๋ฆผ์ƒ‰ ๋ฐฐ๊ฒฝ */
}

#next-btn {
    background-color: #FFD700; /* ๋…ธ๋ž€์ƒ‰ ๋ฒ„ํŠผ */
    font-size: 1.5em;
    font-weight: bold;
    border-radius: 20px;
    padding: 10px;
}

#play-btn {
    background-color: #90EE90; /* ์—ฐํ•œ ์ดˆ๋ก์ƒ‰ ๋ฒ„ํŠผ */
    font-size: 1.5em;
    font-weight: bold;
    border-radius: 20px;
    padding: 10px;
}

img {
    border-radius: 10px; /* ๋‘ฅ๊ทผ ํ…Œ๋‘๋ฆฌ */
    border: 5px solid #FFFFFF; /* ํฐ์ƒ‰ ํ…Œ๋‘๋ฆฌ */
}
"""

# ์•ฑ ์‹คํ–‰
demo.launch()