Update app.py
Browse files
app.py
CHANGED
|
@@ -73,22 +73,19 @@ def clear_paragraphs():
|
|
| 73 |
return [""]
|
| 74 |
|
| 75 |
def add_paragraph(paragraphs):
|
| 76 |
-
paragraphs
|
| 77 |
-
paragraphs.append("")
|
| 78 |
-
return paragraphs
|
| 79 |
|
| 80 |
def remove_paragraph(paragraphs):
|
| 81 |
-
paragraphs = paragraphs.copy()
|
| 82 |
if len(paragraphs) > 1:
|
| 83 |
-
paragraphs
|
| 84 |
-
|
|
|
|
| 85 |
|
| 86 |
-
def
|
| 87 |
# 回傳一組 Textbox 元件
|
| 88 |
return [gr.Textbox(value=p, label=f"段落{i+1}內容", lines=3, interactive=True) for i, p in enumerate(paragraphs)]
|
| 89 |
|
| 90 |
def collect_paragraphs(*args):
|
| 91 |
-
# 收集所有段落內容
|
| 92 |
return list(args)
|
| 93 |
|
| 94 |
async def main():
|
|
@@ -120,32 +117,35 @@ async def main():
|
|
| 120 |
with gr.Tab("播客製作"):
|
| 121 |
gr.Markdown("### 📝 多段腳本輸入(可自由增減段落)")
|
| 122 |
paragraphs_state = gr.State([""])
|
| 123 |
-
paragraphs_container = gr.Column()
|
| 124 |
|
| 125 |
-
#
|
| 126 |
-
|
| 127 |
-
|
| 128 |
-
|
| 129 |
|
| 130 |
add_btn = gr.Button("新增段落")
|
| 131 |
remove_btn = gr.Button("刪除段落")
|
| 132 |
clear_all_btn = gr.Button("全部清空")
|
| 133 |
|
| 134 |
-
|
| 135 |
-
|
| 136 |
-
|
|
|
|
| 137 |
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
clear_all_btn.click(
|
|
|
|
|
|
|
|
|
|
| 149 |
|
| 150 |
# 參數設定
|
| 151 |
voice_input2 = gr.Dropdown(voices, label="選擇語音", value="zh-CN-XiaoxiaoNeural")
|
|
@@ -157,11 +157,8 @@ async def main():
|
|
| 157 |
podcast_btn = gr.Button("生成播客")
|
| 158 |
podcast_output = gr.Audio(type="filepath", label="生成的播客音檔")
|
| 159 |
|
| 160 |
-
|
| 161 |
-
return list(args)
|
| 162 |
-
|
| 163 |
def on_podcast_btn_click(*args):
|
| 164 |
-
# args: 段落內容 + 參數
|
| 165 |
n = len(paragraphs_state.value)
|
| 166 |
scripts = list(args[:n])
|
| 167 |
voice = args[n]
|
|
@@ -172,9 +169,9 @@ async def main():
|
|
| 172 |
desc = args[n+5]
|
| 173 |
return asyncio.run(podcast_produce(scripts, voice, rate, pitch, bgm, title, desc))
|
| 174 |
|
| 175 |
-
#
|
| 176 |
def get_inputs():
|
| 177 |
-
return [tb for tb in
|
| 178 |
|
| 179 |
podcast_btn.click(
|
| 180 |
fn=on_podcast_btn_click,
|
|
|
|
| 73 |
return [""]
|
| 74 |
|
| 75 |
def add_paragraph(paragraphs):
|
| 76 |
+
return paragraphs + [""]
|
|
|
|
|
|
|
| 77 |
|
| 78 |
def remove_paragraph(paragraphs):
|
|
|
|
| 79 |
if len(paragraphs) > 1:
|
| 80 |
+
return paragraphs[:-1]
|
| 81 |
+
else:
|
| 82 |
+
return paragraphs
|
| 83 |
|
| 84 |
+
def render_paragraphs(paragraphs):
|
| 85 |
# 回傳一組 Textbox 元件
|
| 86 |
return [gr.Textbox(value=p, label=f"段落{i+1}內容", lines=3, interactive=True) for i, p in enumerate(paragraphs)]
|
| 87 |
|
| 88 |
def collect_paragraphs(*args):
|
|
|
|
| 89 |
return list(args)
|
| 90 |
|
| 91 |
async def main():
|
|
|
|
| 117 |
with gr.Tab("播客製作"):
|
| 118 |
gr.Markdown("### 📝 多段腳本輸入(可自由增減段落)")
|
| 119 |
paragraphs_state = gr.State([""])
|
|
|
|
| 120 |
|
| 121 |
+
# 動態段落區塊
|
| 122 |
+
with gr.Column() as paragraph_column:
|
| 123 |
+
# 初始渲染
|
| 124 |
+
paragraph_boxes = render_paragraphs([""])
|
| 125 |
|
| 126 |
add_btn = gr.Button("新增段落")
|
| 127 |
remove_btn = gr.Button("刪除段落")
|
| 128 |
clear_all_btn = gr.Button("全部清空")
|
| 129 |
|
| 130 |
+
# 段落增減/清空時,重新渲染段落區塊
|
| 131 |
+
def update_paragraph_ui(paragraphs):
|
| 132 |
+
paragraph_column.children = render_paragraphs(paragraphs)
|
| 133 |
+
return gr.update()
|
| 134 |
|
| 135 |
+
add_btn.click(
|
| 136 |
+
lambda p: (add_paragraph(p), update_paragraph_ui(add_paragraph(p))),
|
| 137 |
+
inputs=paragraphs_state,
|
| 138 |
+
outputs=[paragraphs_state, paragraph_column]
|
| 139 |
+
)
|
| 140 |
+
remove_btn.click(
|
| 141 |
+
lambda p: (remove_paragraph(p), update_paragraph_ui(remove_paragraph(p))),
|
| 142 |
+
inputs=paragraphs_state,
|
| 143 |
+
outputs=[paragraphs_state, paragraph_column]
|
| 144 |
+
)
|
| 145 |
+
clear_all_btn.click(
|
| 146 |
+
lambda: (clear_paragraphs(), update_paragraph_ui(clear_paragraphs())),
|
| 147 |
+
outputs=[paragraphs_state, paragraph_column]
|
| 148 |
+
)
|
| 149 |
|
| 150 |
# 參數設定
|
| 151 |
voice_input2 = gr.Dropdown(voices, label="選擇語音", value="zh-CN-XiaoxiaoNeural")
|
|
|
|
| 157 |
podcast_btn = gr.Button("生成播客")
|
| 158 |
podcast_output = gr.Audio(type="filepath", label="生成的播客音檔")
|
| 159 |
|
| 160 |
+
# 播客合成
|
|
|
|
|
|
|
| 161 |
def on_podcast_btn_click(*args):
|
|
|
|
| 162 |
n = len(paragraphs_state.value)
|
| 163 |
scripts = list(args[:n])
|
| 164 |
voice = args[n]
|
|
|
|
| 169 |
desc = args[n+5]
|
| 170 |
return asyncio.run(podcast_produce(scripts, voice, rate, pitch, bgm, title, desc))
|
| 171 |
|
| 172 |
+
# 動態收集段落內容
|
| 173 |
def get_inputs():
|
| 174 |
+
return [tb for tb in paragraph_column.children] + [voice_input2, rate_input2, pitch_input2, bgm_input, podcast_title, podcast_desc]
|
| 175 |
|
| 176 |
podcast_btn.click(
|
| 177 |
fn=on_podcast_btn_click,
|