MPEGEndFrame / app.py
dseditor's picture
Upload 2 files
ac5e4c8 verified
raw
history blame
2.49 kB
import gradio as gr
import subprocess
import os
import tempfile
def extract_last_frame(video_file):
if video_file is None:
return None, "請上傳影片檔案"
try:
# 創建臨時輸出檔案
output_path = tempfile.mktemp(suffix='.jpg')
# 使用 ffmpeg 獲取影片總幀數並提取最後一幀
# 先獲取影片時長
duration_cmd = [
'ffprobe',
'-v', 'error',
'-show_entries', 'format=duration',
'-of', 'default=noprint_wrappers=1:nokey=1',
video_file
]
duration_result = subprocess.run(duration_cmd, capture_output=True, text=True)
duration = float(duration_result.stdout.strip())
# 提取最後一幀 (從最後0.1秒處提取)
extract_cmd = [
'ffmpeg',
'-sseof', '-0.1',
'-i', video_file,
'-update', '1',
'-frames:v', '1',
'-q:v', '2',
output_path,
'-y'
]
subprocess.run(extract_cmd, check=True, capture_output=True)
if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
return output_path, "成功提取最後一幀!"
else:
return None, "提取失敗,請確認影片格式正確"
except subprocess.CalledProcessError as e:
return None, f"處理錯誤: {str(e)}"
except Exception as e:
return None, f"發生錯誤: {str(e)}"
# 創建 Gradio 界面
with gr.Blocks(title="影片最後一幀提取器") as demo:
gr.Markdown("# 影片最後一幀提取器")
gr.Markdown("上傳影片(最大 100MB),自動提取最後一幀為 JPEG 圖片")
with gr.Row():
with gr.Column():
video_input = gr.Video(
label="上傳影片",
max_length=None,
height=400
)
extract_btn = gr.Button("提取最後一幀", variant="primary")
with gr.Column():
image_output = gr.Image(
label="最後一幀",
type="filepath",
height=400
)
status_output = gr.Textbox(label="狀態", interactive=False)
extract_btn.click(
fn=extract_last_frame,
inputs=[video_input],
outputs=[image_output, status_output]
)
if __name__ == "__main__":
demo.launch()