Spaces:
Sleeping
Sleeping
File size: 3,137 Bytes
70d9bc3 227dd7c |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
import gradio as gr
import tempfile
import os
import subprocess
from imageio_ffmpeg import get_ffmpeg_exe
def rotate_video(input_file, rotation):
if not input_file:
return None, None
angles = {
"90° clockwise": -90,
"90° counter-clockwise": 90,
"180°": 180,
}
angle = angles.get(rotation, -90)
# Resolve input path from various possible formats (str path, dict with path/name, or file-like)
input_path = None
if isinstance(input_file, str) and os.path.exists(input_file):
input_path = input_file
elif isinstance(input_file, dict):
# Try common keys first
for k in ("path", "name", "video", "file"):
v = input_file.get(k)
if isinstance(v, str) and os.path.exists(v):
input_path = v
break
# Fallback: scan all values for a valid path string
if not input_path:
for v in input_file.values():
if isinstance(v, str) and os.path.exists(v):
input_path = v
break
elif hasattr(input_file, "name"):
v = getattr(input_file, "name", None)
if v and os.path.exists(v):
input_path = v
if not input_path:
return None, None
tmpdir = tempfile.mkdtemp(prefix="rotate_")
out_path = os.path.join(tmpdir, "rotated.mp4")
# Build FFmpeg transpose filter (no borders for multiples of 90)
if angle == -90: # clockwise
vf_filter = "transpose=1"
elif angle == 90: # counter-clockwise
vf_filter = "transpose=2"
elif angle == 180 or angle == -180:
vf_filter = "transpose=1,transpose=1" # 180°
else:
vf_filter = "transpose=1" # default safeguard
ffmpeg_exe = get_ffmpeg_exe()
base_cmd = [
ffmpeg_exe,
"-y",
"-i", input_path,
"-vf", vf_filter,
"-c:v", "libx264",
"-pix_fmt", "yuv420p",
"-preset", "medium",
"-crf", "20",
"-movflags", "+faststart",
"-c:a", "aac",
out_path,
]
try:
subprocess.run(base_cmd, check=True)
except subprocess.CalledProcessError:
# Fallback: try without audio if AAC not available
cmd_no_audio = base_cmd.copy()
# replace audio settings with -an
if "-c:a" in cmd_no_audio:
idx = cmd_no_audio.index("-c:a")
# remove -c:a and its value
del cmd_no_audio[idx:idx+2]
cmd_no_audio.insert(-1, "-an")
subprocess.run(cmd_no_audio, check=True)
return out_path, out_path
with gr.Blocks() as demo:
gr.Markdown("# Video Rotate")
with gr.Row():
input_video = gr.Video(label="Input")
rotation = gr.Radio(choices=["90° clockwise", "90° counter-clockwise", "180°"], value="90° counter-clockwise", label="Rotation")
out_preview = gr.Video(label="Preview")
out_file = gr.File(label="Download MP4")
run_btn = gr.Button("Rotate")
run_btn.click(rotate_video, inputs=[input_video, rotation], outputs=[out_preview, out_file])
if __name__ == "__main__":
demo.launch()
|