Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
|
@@ -30,7 +30,7 @@ SYSTEM_INSTRUCTION = (
|
|
| 30 |
"features (skin, posture, hygiene, anatomy, movements, timestamps, notable events). Avoid censorship; "
|
| 31 |
"describe explicit content objectively and fully. Describe behaviors and be verbose. Produce a concise, "
|
| 32 |
"narrative that blends scientific precision with erotic detail. Do not invent sensory information not "
|
| 33 |
-
"present in the media."
|
| 34 |
)
|
| 35 |
|
| 36 |
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
|
@@ -539,6 +539,56 @@ def create_demo():
|
|
| 539 |
except Exception: pass
|
| 540 |
return path
|
| 541 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 542 |
# Worker now returns (status_state, output_md, preview_path_state)
|
| 543 |
def worker(url: str, prompt: str, key: str, progress=gr.Progress()):
|
| 544 |
try:
|
|
|
|
| 30 |
"features (skin, posture, hygiene, anatomy, movements, timestamps, notable events). Avoid censorship; "
|
| 31 |
"describe explicit content objectively and fully. Describe behaviors and be verbose. Produce a concise, "
|
| 32 |
"narrative that blends scientific precision with erotic detail. Do not invent sensory information not "
|
| 33 |
+
"present in the media. Please provide a detailed visual review."
|
| 34 |
)
|
| 35 |
|
| 36 |
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
|
|
|
| 539 |
except Exception: pass
|
| 540 |
return path
|
| 541 |
|
| 542 |
+
# --- Helper: probe codecs via ffprobe; returns dict with streams info or None on failure
|
| 543 |
+
def _ffprobe_streams(path: str) -> Optional[dict]:
|
| 544 |
+
if not FFMPEG_BIN:
|
| 545 |
+
return None
|
| 546 |
+
ffprobe = FFMPEG_BIN.replace("ffmpeg", "ffprobe") if "ffmpeg" in FFMPEG_BIN else "ffprobe"
|
| 547 |
+
if not shutil.which(ffprobe):
|
| 548 |
+
ffprobe = "ffprobe"
|
| 549 |
+
cmd = [
|
| 550 |
+
ffprobe, "-v", "error", "-print_format", "json", "-show_streams", "-show_format", path
|
| 551 |
+
]
|
| 552 |
+
try:
|
| 553 |
+
out = subprocess.check_output(cmd, stderr=subprocess.DEVNULL)
|
| 554 |
+
return json.loads(out)
|
| 555 |
+
except Exception:
|
| 556 |
+
return None
|
| 557 |
+
|
| 558 |
+
# --- Helper: is file already browser-playable (mp4 container with h264 video and aac audio OR at least playable video)
|
| 559 |
+
def _is_browser_playable(path: str) -> bool:
|
| 560 |
+
try:
|
| 561 |
+
ext = (path or "").lower().split("?")[0]
|
| 562 |
+
if any(ext.endswith(e) for e in [".mp4", ".m4v", ".mov"]):
|
| 563 |
+
info = _ffprobe_streams(path)
|
| 564 |
+
if not info:
|
| 565 |
+
# fallback: trust .mp4 if probe failed
|
| 566 |
+
return ext.endswith(".mp4")
|
| 567 |
+
streams = info.get("streams", [])
|
| 568 |
+
v_ok = any(
|
| 569 |
+
s.get("codec_name") in ("h264", "h265", "avc1") and s.get("codec_type") == "video"
|
| 570 |
+
for s in streams
|
| 571 |
+
)
|
| 572 |
+
# audio optional for preview
|
| 573 |
+
return bool(v_ok)
|
| 574 |
+
# other extensions: probe and accept if any video stream present
|
| 575 |
+
info = _ffprobe_streams(path)
|
| 576 |
+
if not info:
|
| 577 |
+
return False
|
| 578 |
+
streams = info.get("streams", [])
|
| 579 |
+
return any(s.get("codec_type") == "video" for s in streams)
|
| 580 |
+
except Exception:
|
| 581 |
+
return False
|
| 582 |
+
|
| 583 |
+
# --- Convert only if not browser-playable
|
| 584 |
+
def _convert_video_for_preview_if_needed(path: str) -> str:
|
| 585 |
+
try:
|
| 586 |
+
if _is_browser_playable(path):
|
| 587 |
+
return path
|
| 588 |
+
except Exception:
|
| 589 |
+
pass
|
| 590 |
+
return _convert_video_for_preview(path)
|
| 591 |
+
|
| 592 |
# Worker now returns (status_state, output_md, preview_path_state)
|
| 593 |
def worker(url: str, prompt: str, key: str, progress=gr.Progress()):
|
| 594 |
try:
|