dseditor commited on
Commit
ac5e4c8
·
verified ·
1 Parent(s): 6055ccb

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +80 -0
  2. requirements.txt +1 -0
app.py ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import subprocess
3
+ import os
4
+ import tempfile
5
+
6
+ def extract_last_frame(video_file):
7
+ if video_file is None:
8
+ return None, "請上傳影片檔案"
9
+
10
+ try:
11
+ # 創建臨時輸出檔案
12
+ output_path = tempfile.mktemp(suffix='.jpg')
13
+
14
+ # 使用 ffmpeg 獲取影片總幀數並提取最後一幀
15
+ # 先獲取影片時長
16
+ duration_cmd = [
17
+ 'ffprobe',
18
+ '-v', 'error',
19
+ '-show_entries', 'format=duration',
20
+ '-of', 'default=noprint_wrappers=1:nokey=1',
21
+ video_file
22
+ ]
23
+
24
+ duration_result = subprocess.run(duration_cmd, capture_output=True, text=True)
25
+ duration = float(duration_result.stdout.strip())
26
+
27
+ # 提取最後一幀 (從最後0.1秒處提取)
28
+ extract_cmd = [
29
+ 'ffmpeg',
30
+ '-sseof', '-0.1',
31
+ '-i', video_file,
32
+ '-update', '1',
33
+ '-frames:v', '1',
34
+ '-q:v', '2',
35
+ output_path,
36
+ '-y'
37
+ ]
38
+
39
+ subprocess.run(extract_cmd, check=True, capture_output=True)
40
+
41
+ if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
42
+ return output_path, "成功提取最後一幀!"
43
+ else:
44
+ return None, "提取失敗,請確認影片格式正確"
45
+
46
+ except subprocess.CalledProcessError as e:
47
+ return None, f"處理錯誤: {str(e)}"
48
+ except Exception as e:
49
+ return None, f"發生錯誤: {str(e)}"
50
+
51
+ # 創建 Gradio 界面
52
+ with gr.Blocks(title="影片最後一幀提取器") as demo:
53
+ gr.Markdown("# 影片最後一幀提取器")
54
+ gr.Markdown("上傳影片(最大 100MB),自動提取最後一幀為 JPEG 圖片")
55
+
56
+ with gr.Row():
57
+ with gr.Column():
58
+ video_input = gr.Video(
59
+ label="上傳影片",
60
+ max_length=None,
61
+ height=400
62
+ )
63
+ extract_btn = gr.Button("提取最後一幀", variant="primary")
64
+
65
+ with gr.Column():
66
+ image_output = gr.Image(
67
+ label="最後一幀",
68
+ type="filepath",
69
+ height=400
70
+ )
71
+ status_output = gr.Textbox(label="狀態", interactive=False)
72
+
73
+ extract_btn.click(
74
+ fn=extract_last_frame,
75
+ inputs=[video_input],
76
+ outputs=[image_output, status_output]
77
+ )
78
+
79
+ if __name__ == "__main__":
80
+ demo.launch()
requirements.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ gradio