Natkat1 commited on
Commit
d605fc8
·
verified ·
1 Parent(s): 4e0a803

Upload folder using huggingface_hub

Browse files
Files changed (2) hide show
  1. requirements.txt +5 -0
  2. utils.py +163 -0
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ gradio>=6.0.0
2
+ ffmpeg-python>=0.2.0
3
+ yt-dlp>=2024.12.13
4
+ Pillow>=10.0.0
5
+ numpy>=1.24.0
utils.py ADDED
@@ -0,0 +1,163 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import tempfile
3
+ import ffmpeg
4
+ import yt_dlp
5
+ from pathlib import Path
6
+ from typing import Optional, List
7
+
8
+ # Global list to track temp files for cleanup
9
+ _temp_files: List[str] = []
10
+
11
+ def cleanup_temp_files():
12
+ """Clean up temporary files created during processing"""
13
+ global _temp_files
14
+ for temp_file in _temp_files:
15
+ try:
16
+ if os.path.exists(temp_file):
17
+ os.unlink(temp_file)
18
+ except Exception:
19
+ pass
20
+ _temp_files.clear()
21
+
22
+ def download_from_url(url: str) -> Optional[str]:
23
+ """
24
+ Download media from URL using yt-dlp
25
+
26
+ Args:
27
+ url: URL to download from
28
+
29
+ Returns:
30
+ Path to downloaded file or None if failed
31
+ """
32
+ try:
33
+ # Create temp directory
34
+ temp_dir = tempfile.mkdtemp()
35
+
36
+ # Configure yt-dlp options
37
+ ydl_opts = {
38
+ 'format': 'best[ext=mp4]/best',
39
+ 'outtmpl': os.path.join(temp_dir, '%(id)s.%(ext)s'),
40
+ 'quiet': True,
41
+ 'no_warnings': True,
42
+ 'extract_flat': False,
43
+ }
44
+
45
+ with yt_dlp.YoutubeDL(ydl_opts) as ydl:
46
+ # Extract info and download
47
+ info = ydl.extract_info(url, download=True)
48
+ if not info:
49
+ return None
50
+
51
+ # Find downloaded file
52
+ video_id = info.get('id', '')
53
+ ext = info.get('ext', 'mp4')
54
+ downloaded_file = os.path.join(temp_dir, f"{video_id}.{ext}")
55
+
56
+ if os.path.exists(downloaded_file):
57
+ _temp_files.append(downloaded_file)
58
+ return downloaded_file
59
+
60
+ return None
61
+
62
+ except Exception as e:
63
+ print(f"Download error: {e}")
64
+ return None
65
+
66
+ def convert_media_file(input_path: str, output_format: str) -> Optional[str]:
67
+ """
68
+ Convert media file to target format using ffmpeg
69
+
70
+ Args:
71
+ input_path: Path to input file
72
+ output_format: Target format (e.g., 'mp4', 'mp3')
73
+
74
+ Returns:
75
+ Path to converted file or None if failed
76
+ """
77
+ try:
78
+ # Create output path
79
+ temp_dir = tempfile.mkdtemp()
80
+ base_name = Path(input_path).stem
81
+ output_path = os.path.join(temp_dir, f"{base_name}.{output_format}")
82
+
83
+ # Determine if we need audio-only conversion
84
+ audio_formats = ["mp3", "wav", "aac", "flac", "ogg", "m4a", "wma", "opus", "aiff"]
85
+ is_audio_only = output_format in audio_formats
86
+
87
+ # Build ffmpeg command based on output format
88
+ if is_audio_only:
89
+ # Extract audio only
90
+ stream = ffmpeg.input(input_path)
91
+ audio = stream.audio
92
+ stream = ffmpeg.output(audio, output_path, **{'q:a': 0, 'map_a': 0})
93
+ else:
94
+ # Full video conversion
95
+ if output_format == "gif":
96
+ # Special handling for GIF
97
+ stream = ffmpeg.input(input_path)
98
+ stream = ffmpeg.output(
99
+ stream,
100
+ output_path,
101
+ vf="fps=10,scale=320:-1:flags=lanczos",
102
+ **{'loop': 0}
103
+ )
104
+ else:
105
+ # Standard video conversion
106
+ stream = ffmpeg.input(input_path)
107
+ stream = ffmpeg.output(stream, output_path, **{'c:v': 'libx264', 'crf': 23})
108
+
109
+ # Run conversion
110
+ ffmpeg.run(stream, overwrite_output=True, quiet=True)
111
+
112
+ if os.path.exists(output_path):
113
+ _temp_files.append(output_path)
114
+ return output_path
115
+
116
+ return None
117
+
118
+ except ffmpeg.Error as e:
119
+ print(f"FFmpeg error: {e}")
120
+ return None
121
+ except Exception as e:
122
+ print(f"Conversion error: {e}")
123
+ return None
124
+
125
+ def get_media_info(file_path: str) -> dict:
126
+ """
127
+ Get media file information using ffmpeg
128
+
129
+ Args:
130
+ file_path: Path to media file
131
+
132
+ Returns:
133
+ Dictionary with media info
134
+ """
135
+ try:
136
+ probe = ffmpeg.probe(file_path)
137
+ video_streams = [stream for stream in probe['streams'] if stream['codec_type'] == 'video']
138
+ audio_streams = [stream for stream in probe['streams'] if stream['codec_type'] == 'audio']
139
+
140
+ info = {
141
+ 'duration': float(probe['format'].get('duration', 0)),
142
+ 'size': int(probe['format'].get('size', 0)),
143
+ 'bitrate': int(probe['format'].get('bit_rate', 0)),
144
+ 'has_video': len(video_streams) > 0,
145
+ 'has_audio': len(audio_streams) > 0,
146
+ }
147
+
148
+ if video_streams:
149
+ info['video_codec'] = video_streams[0].get('codec_name')
150
+ info['width'] = video_streams[0].get('width')
151
+ info['height'] = video_streams[0].get('height')
152
+ info['fps'] = eval(video_streams[0].get('r_frame_rate', '0'))
153
+
154
+ if audio_streams:
155
+ info['audio_codec'] = audio_streams[0].get('codec_name')
156
+ info['sample_rate'] = audio_streams[0].get('sample_rate')
157
+ info['channels'] = audio_streams[0].get('channels')
158
+
159
+ return info
160
+
161
+ except Exception as e:
162
+ print(f"Error getting media info: {e}")
163
+ return {}