MySafeCode commited on
Commit
b5c95fc
·
verified ·
1 Parent(s): c1a539d

Create app

Browse files
Files changed (1) hide show
  1. app +231 -0
app ADDED
@@ -0,0 +1,231 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import os
3
+ import tempfile
4
+ import shutil
5
+ from datetime import datetime
6
+ from pathlib import Path
7
+ import moviepy.editor as mp
8
+
9
+ def extract_audio(video_path, filename=None):
10
+ """Extract audio from video and save as MP3"""
11
+ if video_path is None:
12
+ return "❌ Please upload or record a video first!", None
13
+
14
+ # Generate filename if not provided
15
+ if not filename:
16
+ timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
17
+ if hasattr(video_path, 'name'):
18
+ original_name = Path(video_path.name).stem
19
+ filename = f"{original_name}_{timestamp}.mp3"
20
+ else:
21
+ filename = f"audio_{timestamp}.mp3"
22
+ elif not filename.endswith('.mp3'):
23
+ filename += '.mp3'
24
+
25
+ # Create temp directory for the audio file
26
+ temp_dir = tempfile.mkdtemp()
27
+ audio_path = os.path.join(temp_dir, filename)
28
+
29
+ try:
30
+ # Extract audio using moviepy
31
+ video = mp.VideoFileClip(video_path)
32
+ audio = video.audio
33
+
34
+ if audio is None:
35
+ return "❌ No audio found in the video!", None
36
+
37
+ # Write audio to file
38
+ audio.write_audiofile(audio_path, verbose=False, logger=None)
39
+
40
+ # Close the clips to free resources
41
+ audio.close()
42
+ video.close()
43
+
44
+ return f"✅ Audio extracted successfully: {filename}", audio_path
45
+
46
+ except Exception as e:
47
+ return f"❌ Error extracting audio: {str(e)}", None
48
+
49
+ def save_video(video_path, filename=None):
50
+ """Save video to a temporary file for download"""
51
+ if video_path is None:
52
+ return "❌ Please upload or record a video first!", None
53
+
54
+ # Generate filename if not provided
55
+ if not filename:
56
+ timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
57
+ if hasattr(video_path, 'name'):
58
+ original_name = Path(video_path.name).stem
59
+ filename = f"{original_name}_{timestamp}.mp4"
60
+ else:
61
+ filename = f"video_{timestamp}.mp4"
62
+ elif not filename.endswith('.mp4'):
63
+ filename += '.mp4'
64
+
65
+ # Create temp directory for the download file
66
+ temp_dir = tempfile.mkdtemp()
67
+ dest_path = os.path.join(temp_dir, filename)
68
+
69
+ try:
70
+ # Copy the video to temp location
71
+ if isinstance(video_path, str) and os.path.exists(video_path):
72
+ shutil.copy2(video_path, dest_path)
73
+ else:
74
+ # Handle Gradio's temporary file object
75
+ with open(video_path, 'rb') as src:
76
+ with open(dest_path, 'wb') as dst:
77
+ shutil.copyfileobj(src, dst)
78
+
79
+ return f"✅ Video ready for download: {filename}", dest_path
80
+
81
+ except Exception as e:
82
+ return f"❌ Error processing video: {str(e)}", None
83
+
84
+ def process_all(video_path, video_filename=None, audio_filename=None):
85
+ """Process both video and audio extraction"""
86
+ if video_path is None:
87
+ return "❌ Please upload or record a video first!", None, None, None, None
88
+
89
+ # Process video
90
+ video_status, video_file = save_video(video_path, video_filename)
91
+
92
+ # Process audio extraction
93
+ audio_status, audio_file = extract_audio(video_path, audio_filename)
94
+
95
+ # Combine status messages
96
+ combined_status = f"{video_status}\n{audio_status}"
97
+
98
+ return combined_status, video_file, audio_file
99
+
100
+ def clear_all():
101
+ """Clear all inputs and outputs"""
102
+ return None, None, None, "", None, None
103
+
104
+ def update_video_display(video_path):
105
+ """Update the video display when a new video is uploaded/recorded"""
106
+ if video_path:
107
+ return video_path, f"📹 Video loaded: {os.path.basename(video_path) if hasattr(video_path, 'name') else 'Recorded video'}"
108
+ return None, ""
109
+
110
+ # Create the Gradio interface
111
+ with gr.Blocks(title="🎥 Video Recorder with Audio Extraction") as demo:
112
+
113
+ gr.Markdown("""
114
+ # 🎥 Video Recorder with Audio Extraction
115
+ Record or upload a video, then download both the video file and extracted MP3 audio!
116
+ """)
117
+
118
+ with gr.Row():
119
+ with gr.Column(scale=1):
120
+ gr.Markdown("### 📤 Input")
121
+
122
+ video_input = gr.Video(
123
+ label="Record or Upload Video",
124
+ sources=["webcam", "upload"],
125
+ interactive=True,
126
+ include_audio=True,
127
+ height=300
128
+ )
129
+
130
+ with gr.Group():
131
+ gr.Markdown("**📁 Filename Options**")
132
+
133
+ video_filename = gr.Textbox(
134
+ label="Video Filename (optional)",
135
+ placeholder="my_video.mp4 or leave blank for auto-name",
136
+ info="Leave blank for automatic naming"
137
+ )
138
+
139
+ audio_filename = gr.Textbox(
140
+ label="Audio Filename (optional)",
141
+ placeholder="my_audio.mp3 or leave blank for auto-name",
142
+ info="Leave blank for automatic naming"
143
+ )
144
+
145
+ with gr.Row():
146
+ process_btn = gr.Button("📥 Process Video & Audio", variant="primary", scale=2)
147
+ clear_btn = gr.Button("🗑️ Clear All", variant="secondary", scale=1)
148
+
149
+ with gr.Column(scale=1):
150
+ gr.Markdown("### 📥 Output")
151
+
152
+ status_output = gr.Textbox(
153
+ label="Status",
154
+ value="👋 Ready to record or upload a video!",
155
+ interactive=False,
156
+ lines=5
157
+ )
158
+
159
+ video_display = gr.Video(
160
+ label="Video Preview",
161
+ interactive=False,
162
+ height=300
163
+ )
164
+
165
+ with gr.Tabs():
166
+ with gr.TabItem("🎬 Download Video"):
167
+ download_video = gr.File(
168
+ label="Download Video File",
169
+ interactive=False,
170
+ file_types=[".mp4", ".mov", ".avi", ".webm"]
171
+ )
172
+
173
+ with gr.TabItem("🎵 Download Audio"):
174
+ download_audio = gr.File(
175
+ label="Download MP3 Audio",
176
+ interactive=False,
177
+ file_types=[".mp3"]
178
+ )
179
+
180
+ # Update video display and status when video is uploaded/recorded
181
+ video_input.change(
182
+ fn=update_video_display,
183
+ inputs=[video_input],
184
+ outputs=[video_display, status_output]
185
+ )
186
+
187
+ # Process both video and audio
188
+ process_btn.click(
189
+ fn=process_all,
190
+ inputs=[video_input, video_filename, audio_filename],
191
+ outputs=[status_output, download_video, download_audio]
192
+ )
193
+
194
+ # Clear all inputs and outputs
195
+ clear_btn.click(
196
+ fn=clear_all,
197
+ outputs=[video_input, video_display, download_video, status_output, video_filename, audio_filename]
198
+ )
199
+
200
+ # Instructions
201
+ gr.Markdown("""
202
+ ## 📋 How to Use:
203
+ 1. **Record**: Click the webcam icon to record a video
204
+ 2. **Upload**: Click the upload button to select a video file
205
+ 3. **Optional**: Enter custom filenames for video and audio
206
+ 4. **Process**: Click "Process Video & Audio" to generate both files
207
+ 5. **Download**: Use the tabs to download video (MP4) or audio (MP3)
208
+
209
+ ## 📝 Notes:
210
+ - Supported video formats: MP4, MOV, AVI, WebM
211
+ - Audio is extracted and saved as MP3
212
+ - Videos are processed temporarily and can be downloaded immediately
213
+ - Use "Clear All" to start fresh
214
+
215
+ ## 🎵 Audio Extraction:
216
+ - Extracts audio track from video files
217
+ - Saves as high-quality MP3
218
+ - Works with any video that contains audio
219
+ """)
220
+
221
+ # Launch configuration
222
+ if __name__ == "__main__":
223
+ demo.launch(
224
+ theme="soft",
225
+ css="""
226
+ .gradio-container {max-width: 1000px !important;}
227
+ .video-container {border-radius: 10px; overflow: hidden;}
228
+ .status-box {background: #f0f7ff; padding: 15px; border-radius: 8px; border-left: 4px solid #4a90e2;}
229
+ .tabs {margin-top: 20px;}
230
+ """
231
+ )