Spaces:
Running on Zero
Running on Zero
Commit ·
8429f30
1
Parent(s): 7a2a7f5
transcode_for_browser: return new path in fresh tmp dir to beat Gradio probe race
Browse files
app.py
CHANGED
|
@@ -159,8 +159,10 @@ def strip_audio_from_video(video_path: str, output_path: str) -> None:
|
|
| 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 |
-
|
| 163 |
-
|
|
|
|
|
|
|
| 164 |
Only called on upload — not during generation.
|
| 165 |
"""
|
| 166 |
if video_path is None:
|
|
@@ -173,9 +175,14 @@ def _transcode_for_browser(video_path: str) -> str:
|
|
| 173 |
if video_streams and video_streams[0].get("codec_name") == "h264":
|
| 174 |
print(f"[transcode_for_browser] already H.264, skipping")
|
| 175 |
return video_path
|
| 176 |
-
# Write to a
|
| 177 |
-
#
|
| 178 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 179 |
kwargs = dict(
|
| 180 |
vcodec="libx264", preset="fast", crf=18,
|
| 181 |
pix_fmt="yuv420p", movflags="+faststart",
|
|
@@ -186,13 +193,11 @@ def _transcode_for_browser(video_path: str) -> str:
|
|
| 186 |
else:
|
| 187 |
kwargs["an"] = None
|
| 188 |
# map 0:v:0 explicitly to skip non-video streams (e.g. data/timecode tracks)
|
| 189 |
-
ffmpeg.input(video_path).output(
|
| 190 |
overwrite_output=True, quiet=True
|
| 191 |
)
|
| 192 |
-
|
| 193 |
-
|
| 194 |
-
print(f"[transcode_for_browser] transcoded to H.264 in-place: {video_path}")
|
| 195 |
-
return video_path
|
| 196 |
except Exception as e:
|
| 197 |
print(f"[transcode_for_browser] failed, using original: {e}")
|
| 198 |
return video_path
|
|
|
|
| 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 a NEW path in a fresh /tmp/gradio/ subdirectory. Gradio probes the
|
| 163 |
+
returned path fresh, sees H.264, and serves it directly without its own
|
| 164 |
+
slow fallback converter. The in-place overwrite approach loses the race
|
| 165 |
+
because Gradio probes the original path at upload time before this callback runs.
|
| 166 |
Only called on upload — not during generation.
|
| 167 |
"""
|
| 168 |
if video_path is None:
|
|
|
|
| 175 |
if video_streams and video_streams[0].get("codec_name") == "h264":
|
| 176 |
print(f"[transcode_for_browser] already H.264, skipping")
|
| 177 |
return video_path
|
| 178 |
+
# Write to a fresh gradio-served temp dir so Gradio re-probes from scratch
|
| 179 |
+
# and never sees the H.265 source for this returned value.
|
| 180 |
+
import hashlib as _hashlib, os as _os
|
| 181 |
+
basename = _os.path.basename(video_path)
|
| 182 |
+
tag = _hashlib.sha256((video_path + "_h264").encode()).hexdigest()
|
| 183 |
+
out_dir = f"/tmp/gradio/{tag}"
|
| 184 |
+
_os.makedirs(out_dir, exist_ok=True)
|
| 185 |
+
out_path = _os.path.join(out_dir, basename)
|
| 186 |
kwargs = dict(
|
| 187 |
vcodec="libx264", preset="fast", crf=18,
|
| 188 |
pix_fmt="yuv420p", movflags="+faststart",
|
|
|
|
| 193 |
else:
|
| 194 |
kwargs["an"] = None
|
| 195 |
# map 0:v:0 explicitly to skip non-video streams (e.g. data/timecode tracks)
|
| 196 |
+
ffmpeg.input(video_path).output(out_path, map="0:v:0", **kwargs).run(
|
| 197 |
overwrite_output=True, quiet=True
|
| 198 |
)
|
| 199 |
+
print(f"[transcode_for_browser] transcoded to H.264: {out_path}")
|
| 200 |
+
return out_path
|
|
|
|
|
|
|
| 201 |
except Exception as e:
|
| 202 |
print(f"[transcode_for_browser] failed, using original: {e}")
|
| 203 |
return video_path
|