Spaces:
Paused
Paused
feat: replace Unsplash cover URLs with local assets/covers/ PNG paths
Browse files- Add COVERS_DIR and cover_path() helper for Gradio file-serving URLs
- load_books_from_stories() uses cover_path(slug) per story filename
- player_title_info initial HTML uses cover_path() f-string instead of hardcoded Unsplash URL
- demo.queue().launch() adds allowed_paths=["assets"] for Gradio to serve local images
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
app.py
CHANGED
|
@@ -4,6 +4,7 @@ import struct
|
|
| 4 |
import wave
|
| 5 |
import gradio as gr
|
| 6 |
import time
|
|
|
|
| 7 |
|
| 8 |
# Create directories for sample audio files
|
| 9 |
os.makedirs("sample_sounds", exist_ok=True)
|
|
@@ -65,27 +66,22 @@ for key, (path, dur, mel) in create_sound_library.items():
|
|
| 65 |
if not os.path.exists(path):
|
| 66 |
generate_chimes_wav(path, duration=dur, melody_type=mel)
|
| 67 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 68 |
def load_books_from_stories(stories_dir="stories"):
|
| 69 |
books = []
|
| 70 |
story_files = sorted(
|
| 71 |
f for f in os.listdir(stories_dir) if f.endswith(".txt")
|
| 72 |
) if os.path.isdir(stories_dir) else []
|
| 73 |
|
| 74 |
-
cover_urls = [
|
| 75 |
-
"https://images.unsplash.com/photo-1544947950-fa07a98d237f?auto=format&fit=crop&q=80&w=400",
|
| 76 |
-
"https://images.unsplash.com/photo-1512820790803-83ca734da794?auto=format&fit=crop&q=80&w=400",
|
| 77 |
-
"https://images.unsplash.com/photo-1476275466078-4007374efbbe?auto=format&fit=crop&q=80&w=400",
|
| 78 |
-
"https://images.unsplash.com/photo-1456513080510-7bf3a84b82f8?auto=format&fit=crop&q=80&w=400",
|
| 79 |
-
"https://images.unsplash.com/photo-1492052722242-2554d0e99e3a?auto=format&fit=crop&q=80&w=400",
|
| 80 |
-
"https://images.unsplash.com/photo-1474932430478-367dbb6832c1?auto=format&fit=crop&q=80&w=400",
|
| 81 |
-
"https://images.unsplash.com/photo-1456513080510-7bf3a84b82f8?auto=format&fit=crop&q=80&w=400",
|
| 82 |
-
"https://images.unsplash.com/photo-1495640388908-05fa85288e61?auto=format&fit=crop&q=80&w=400",
|
| 83 |
-
"https://images.unsplash.com/photo-1476275466078-4007374efbbe?auto=format&fit=crop&q=80&w=400",
|
| 84 |
-
"https://images.unsplash.com/photo-1512820790803-83ca734da794?auto=format&fit=crop&q=80&w=400",
|
| 85 |
-
]
|
| 86 |
-
|
| 87 |
for i, filename in enumerate(story_files):
|
| 88 |
title = filename.replace(".txt", "").replace("_", " ")
|
|
|
|
| 89 |
# Read first non-empty line as synopsis opener
|
| 90 |
synopsis = ""
|
| 91 |
try:
|
|
@@ -99,7 +95,7 @@ def load_books_from_stories(stories_dir="stories"):
|
|
| 99 |
"id": str(i + 1),
|
| 100 |
"title": title,
|
| 101 |
"author": "Public Domain",
|
| 102 |
-
"cover_url":
|
| 103 |
"voice_name": "Mom’s Voice",
|
| 104 |
"duration": 0,
|
| 105 |
"elapsed_time": 0,
|
|
@@ -462,11 +458,11 @@ with gr.Blocks(css=css_code, title="VoiceBook Gradio Hub") as demo:
|
|
| 462 |
)
|
| 463 |
player_load_btn = gr.Button("Load Story", variant="secondary", size="sm")
|
| 464 |
|
| 465 |
-
player_title_info = gr.HTML("""
|
| 466 |
<div style="text-align: center; margin-bottom: 24px; margin-top: 16px;">
|
| 467 |
-
<img src="
|
| 468 |
-
<h3 style="font-family: 'Playfair Display', Georgia, serif; font-size: 22px; margin:0; color:#FAF7F2;">
|
| 469 |
-
<p style="font-size: 12px; color: #94a3b8; font-style: italic; margin-top:2px;">
|
| 470 |
<span style="display: inline-block; background: rgba(245, 132, 31, 0.15); color: #ffd3a6; font-size: 10.5px; font-weight: 700; padding: 3px 8px; border-radius: 999px; margin-top: 8px;">Active Narrator: Mom's Voice</span>
|
| 471 |
</div>
|
| 472 |
""")
|
|
@@ -1011,4 +1007,4 @@ with gr.Blocks(css=css_code, title="VoiceBook Gradio Hub") as demo:
|
|
| 1011 |
|
| 1012 |
# Launch parameters configured for standard port and auto binding
|
| 1013 |
if __name__ == "__main__":
|
| 1014 |
-
demo.queue().launch()
|
|
|
|
| 4 |
import wave
|
| 5 |
import gradio as gr
|
| 6 |
import time
|
| 7 |
+
from pathlib import Path
|
| 8 |
|
| 9 |
# Create directories for sample audio files
|
| 10 |
os.makedirs("sample_sounds", exist_ok=True)
|
|
|
|
| 66 |
if not os.path.exists(path):
|
| 67 |
generate_chimes_wav(path, duration=dur, melody_type=mel)
|
| 68 |
|
| 69 |
+
COVERS_DIR = Path("assets/covers")
|
| 70 |
+
|
| 71 |
+
def cover_path(slug: str) -> str:
|
| 72 |
+
"""로컬 커버 이미지를 Gradio file-serving URL로 반환."""
|
| 73 |
+
p = COVERS_DIR / f"{slug}.png"
|
| 74 |
+
return f"/gradio_api/file={p.as_posix()}"
|
| 75 |
+
|
| 76 |
def load_books_from_stories(stories_dir="stories"):
|
| 77 |
books = []
|
| 78 |
story_files = sorted(
|
| 79 |
f for f in os.listdir(stories_dir) if f.endswith(".txt")
|
| 80 |
) if os.path.isdir(stories_dir) else []
|
| 81 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 82 |
for i, filename in enumerate(story_files):
|
| 83 |
title = filename.replace(".txt", "").replace("_", " ")
|
| 84 |
+
slug = filename.replace(".txt", "")
|
| 85 |
# Read first non-empty line as synopsis opener
|
| 86 |
synopsis = ""
|
| 87 |
try:
|
|
|
|
| 95 |
"id": str(i + 1),
|
| 96 |
"title": title,
|
| 97 |
"author": "Public Domain",
|
| 98 |
+
"cover_url": cover_path(slug),
|
| 99 |
"voice_name": "Mom’s Voice",
|
| 100 |
"duration": 0,
|
| 101 |
"elapsed_time": 0,
|
|
|
|
| 458 |
)
|
| 459 |
player_load_btn = gr.Button("Load Story", variant="secondary", size="sm")
|
| 460 |
|
| 461 |
+
player_title_info = gr.HTML(f"""
|
| 462 |
<div style="text-align: center; margin-bottom: 24px; margin-top: 16px;">
|
| 463 |
+
<img src="{cover_path('The_Adventures_of_Puss_in_Boots')}" style="width: 130px; height: 180px; object-fit: cover; border-radius: 12px; box-shadow: 0 4px 16px rgba(0,0,0,0.4); margin-bottom: 16px;" />
|
| 464 |
+
<h3 style="font-family: 'Playfair Display', Georgia, serif; font-size: 22px; margin:0; color:#FAF7F2;">Select a Story</h3>
|
| 465 |
+
<p style="font-size: 12px; color: #94a3b8; font-style: italic; margin-top:2px;">Choose a story above and press Load</p>
|
| 466 |
<span style="display: inline-block; background: rgba(245, 132, 31, 0.15); color: #ffd3a6; font-size: 10.5px; font-weight: 700; padding: 3px 8px; border-radius: 999px; margin-top: 8px;">Active Narrator: Mom's Voice</span>
|
| 467 |
</div>
|
| 468 |
""")
|
|
|
|
| 1007 |
|
| 1008 |
# Launch parameters configured for standard port and auto binding
|
| 1009 |
if __name__ == "__main__":
|
| 1010 |
+
demo.queue().launch(allowed_paths=["assets"])
|