BoxOfColors commited on
Commit
ae7de9b
·
1 Parent(s): 7827e41

Fix: restore transcode-on-upload for browser preview; mux already re-encodes so no conflict

Browse files
Files changed (1) hide show
  1. app.py +41 -3
app.py CHANGED
@@ -156,6 +156,35 @@ def strip_audio_from_video(video_path: str, output_path: str) -> None:
156
  overwrite_output=True, quiet=True
157
  )
158
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
159
 
160
  # ------------------------------------------------------------------ #
161
  # Temp directory registry — tracks dirs for cleanup on new generation #
@@ -2555,7 +2584,7 @@ with gr.Blocks(title="Generate Audio for Video", css=_SLOT_CSS, js=_GLOBAL_JS) a
2555
  with gr.Tab("TARO"):
2556
  with gr.Row():
2557
  with gr.Column(scale=1):
2558
- taro_video = gr.Video(label="Input Video", format="mp4")
2559
  taro_seed = gr.Number(label="Seed (-1 = random)", value=-1, precision=0, elem_id="taro_seed")
2560
  taro_cfg = gr.Slider(label="CFG Scale", minimum=1, maximum=15, value=8.0, step=0.5, elem_id="taro_cfg")
2561
  taro_steps = gr.Slider(label="Sampling Steps", minimum=10, maximum=50, value=25, step=1, elem_id="taro_steps")
@@ -2620,7 +2649,7 @@ with gr.Blocks(title="Generate Audio for Video", css=_SLOT_CSS, js=_GLOBAL_JS) a
2620
  with gr.Tab("MMAudio"):
2621
  with gr.Row():
2622
  with gr.Column(scale=1):
2623
- mma_video = gr.Video(label="Input Video", format="mp4")
2624
  mma_prompt = gr.Textbox(label="Prompt", placeholder="e.g. footsteps on gravel", elem_id="mma_prompt")
2625
  mma_neg = gr.Textbox(label="Negative Prompt", value="music", placeholder="music, speech", elem_id="mma_neg")
2626
  mma_seed = gr.Number(label="Seed (-1 = random)", value=-1, precision=0, elem_id="mma_seed")
@@ -2674,7 +2703,7 @@ with gr.Blocks(title="Generate Audio for Video", css=_SLOT_CSS, js=_GLOBAL_JS) a
2674
  with gr.Tab("HunyuanFoley"):
2675
  with gr.Row():
2676
  with gr.Column(scale=1):
2677
- hf_video = gr.Video(label="Input Video", format="mp4")
2678
  hf_prompt = gr.Textbox(label="Prompt", placeholder="e.g. rain hitting a metal roof", elem_id="hf_prompt")
2679
  hf_neg = gr.Textbox(label="Negative Prompt", value="noisy, harsh", elem_id="hf_neg")
2680
  hf_seed = gr.Number(label="Seed (-1 = random)", value=-1, precision=0, elem_id="hf_seed")
@@ -2723,6 +2752,15 @@ with gr.Blocks(title="Generate Audio for Video", css=_SLOT_CSS, js=_GLOBAL_JS) a
2723
  hf_slot_vids, hf_slot_waves,
2724
  )
2725
 
 
 
 
 
 
 
 
 
 
2726
  # ---- Cross-tab video sync ----
2727
  _sync = lambda v: (gr.update(value=v), gr.update(value=v))
2728
  taro_video.change(fn=_sync, inputs=[taro_video], outputs=[mma_video, hf_video])
 
156
  overwrite_output=True, quiet=True
157
  )
158
 
159
+ def _transcode_for_browser(video_path: str) -> str:
160
+ """Re-encode uploaded video to H.264/AAC MP4 so the browser preview widget can play it.
161
+
162
+ Returns the transcoded path on success, or the original path if transcoding fails.
163
+ Only called on upload — not during generation.
164
+ """
165
+ if video_path is None:
166
+ return video_path
167
+ try:
168
+ probe = ffmpeg.probe(video_path)
169
+ has_audio = any(s["codec_type"] == "audio" for s in probe.get("streams", []))
170
+ out_path = video_path.rsplit(".", 1)[0] + "_preview.mp4"
171
+ kwargs = dict(
172
+ vcodec="libx264", preset="fast", crf=18,
173
+ pix_fmt="yuv420p", movflags="+faststart",
174
+ )
175
+ if has_audio:
176
+ kwargs["acodec"] = "aac"
177
+ kwargs["audio_bitrate"] = "128k"
178
+ else:
179
+ kwargs["an"] = None
180
+ ffmpeg.input(video_path).output(out_path, **kwargs).run(
181
+ overwrite_output=True, quiet=True
182
+ )
183
+ return out_path
184
+ except Exception as e:
185
+ print(f"[transcode_for_browser] failed, using original: {e}")
186
+ return video_path
187
+
188
 
189
  # ------------------------------------------------------------------ #
190
  # Temp directory registry — tracks dirs for cleanup on new generation #
 
2584
  with gr.Tab("TARO"):
2585
  with gr.Row():
2586
  with gr.Column(scale=1):
2587
+ taro_video = gr.Video(label="Input Video")
2588
  taro_seed = gr.Number(label="Seed (-1 = random)", value=-1, precision=0, elem_id="taro_seed")
2589
  taro_cfg = gr.Slider(label="CFG Scale", minimum=1, maximum=15, value=8.0, step=0.5, elem_id="taro_cfg")
2590
  taro_steps = gr.Slider(label="Sampling Steps", minimum=10, maximum=50, value=25, step=1, elem_id="taro_steps")
 
2649
  with gr.Tab("MMAudio"):
2650
  with gr.Row():
2651
  with gr.Column(scale=1):
2652
+ mma_video = gr.Video(label="Input Video")
2653
  mma_prompt = gr.Textbox(label="Prompt", placeholder="e.g. footsteps on gravel", elem_id="mma_prompt")
2654
  mma_neg = gr.Textbox(label="Negative Prompt", value="music", placeholder="music, speech", elem_id="mma_neg")
2655
  mma_seed = gr.Number(label="Seed (-1 = random)", value=-1, precision=0, elem_id="mma_seed")
 
2703
  with gr.Tab("HunyuanFoley"):
2704
  with gr.Row():
2705
  with gr.Column(scale=1):
2706
+ hf_video = gr.Video(label="Input Video")
2707
  hf_prompt = gr.Textbox(label="Prompt", placeholder="e.g. rain hitting a metal roof", elem_id="hf_prompt")
2708
  hf_neg = gr.Textbox(label="Negative Prompt", value="noisy, harsh", elem_id="hf_neg")
2709
  hf_seed = gr.Number(label="Seed (-1 = random)", value=-1, precision=0, elem_id="hf_seed")
 
2752
  hf_slot_vids, hf_slot_waves,
2753
  )
2754
 
2755
+ # ---- Browser-safe transcode on upload ----
2756
+ # Gradio serves the original uploaded file to the browser preview widget,
2757
+ # so H.265 sources show as blank. We re-encode to H.264 on upload and feed
2758
+ # the result back so the preview plays. mux_video_audio already re-encodes
2759
+ # to H.264 during generation, so no double-conversion conflict.
2760
+ taro_video.upload(fn=_transcode_for_browser, inputs=[taro_video], outputs=[taro_video])
2761
+ mma_video.upload(fn=_transcode_for_browser, inputs=[mma_video], outputs=[mma_video])
2762
+ hf_video.upload(fn=_transcode_for_browser, inputs=[hf_video], outputs=[hf_video])
2763
+
2764
  # ---- Cross-tab video sync ----
2765
  _sync = lambda v: (gr.update(value=v), gr.update(value=v))
2766
  taro_video.change(fn=_sync, inputs=[taro_video], outputs=[mma_video, hf_video])