reab5555 commited on
Commit
6eaba6d
·
verified ·
1 Parent(s): e74c95d

Upload 4 files

Browse files
Files changed (3) hide show
  1. apt.txt +1 -0
  2. converter_fw.py +174 -167
  3. requirements.txt +3 -3
apt.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ ffmpeg
converter_fw.py CHANGED
@@ -1,167 +1,174 @@
1
- import os
2
- import re
3
- import subprocess
4
- import torch
5
- from datetime import datetime
6
- from pathlib import Path
7
- from typing import List, Optional, Tuple
8
-
9
- class VideoConverter:
10
- def __init__(self):
11
- self.ffmpeg_path = os.path.join("ffmpeg", "bin", "ffmpeg.exe")
12
- self.gpu_available = torch.cuda.is_available()
13
- self.formats = ["MP4", "MKV", "AVI", "MOV", "WMV", "FLV", "MPEG"]
14
- self.codecs = [
15
- "H.264",
16
- "HEVC (H.265)",
17
- "MPEG-4 (Part 2)",
18
- "MPEG-2",
19
- "ProRes Proxy",
20
- "ProRes Light",
21
- "ProRes Standard",
22
- "ProRes HQ"
23
- ]
24
-
25
- def get_codec_params(self, codec: str) -> List[str]:
26
- codec_params = {
27
- "H.264": ["-c:v", "libx264", "-preset", "medium"],
28
- "HEVC (H.265)": ["-c:v", "libx265", "-preset", "medium"],
29
- "MPEG-4 (Part 2)": ["-c:v", "mpeg4"],
30
- "MPEG-2": ["-c:v", "mpeg2video"],
31
- "ProRes Proxy": ["-c:v", "prores_ks", "-profile:v", "0"],
32
- "ProRes Light": ["-c:v", "prores_ks", "-profile:v", "1"],
33
- "ProRes Standard": ["-c:v", "prores_ks", "-profile:v", "2"],
34
- "ProRes HQ": ["-c:v", "prores_ks", "-profile:v", "3"]
35
- }
36
- return codec_params.get(codec, ["-c:v", "libx264", "-preset", "medium"])
37
-
38
- def get_video_duration(self, input_path: str) -> float:
39
- cmd = [
40
- self.ffmpeg_path,
41
- "-i",
42
- input_path
43
- ]
44
- try:
45
- output = subprocess.check_output(cmd, stderr=subprocess.STDOUT, universal_newlines=True)
46
- for line in output.split('\n'):
47
- if "Duration" in line:
48
- time_str = line.split("Duration: ")[1].split(",")[0]
49
- h, m, s = time_str.split(':')
50
- return float(h) * 3600 + float(m) * 60 + float(s)
51
- except Exception as e:
52
- print(f"Error getting video duration: {e}")
53
- return 0
54
-
55
- def convert_video(
56
- self,
57
- input_path: str,
58
- output_format: str,
59
- codec: str,
60
- output_dir: str,
61
- progress_callback: Optional[callable] = None,
62
- output_filename: Optional[str] = None,
63
- output_resolution: str = "Same as input",
64
- output_bitrate: str = "auto",
65
- output_fps: str = "Same as input"
66
- ) -> Tuple[bool, str]:
67
- try:
68
- if not os.path.exists(input_path):
69
- return False, f"Input file does not exist: {Path(input_path).name}"
70
-
71
- if not os.path.exists(output_dir):
72
- os.makedirs(output_dir)
73
-
74
- output_path = os.path.join(output_dir, output_filename)
75
-
76
- # Base FFmpeg command
77
- cmd = [
78
- self.ffmpeg_path,
79
- "-y"
80
- ]
81
-
82
- # Add GPU acceleration if available
83
- if self.gpu_available:
84
- if codec in ["H.264", "HEVC (H.265)"]:
85
- cmd.extend(["-hwaccel", "cuda"])
86
-
87
- # Add input file
88
- cmd.extend([
89
- "-i", input_path
90
- ])
91
-
92
- # Add codec parameters
93
- cmd.extend(self.get_codec_params(codec))
94
-
95
- # Add scaling if necessary
96
- if output_resolution != "Same as input":
97
- resolution_map = {
98
- "3840x2160 (4K)": "3840:2160",
99
- "2560x1440 (1440p)": "2560:1440",
100
- "1920x1080 (1080p)": "1920:1080",
101
- "1280x720 (720p)": "1280:720",
102
- "854x480 (480p)": "854:480"
103
- }
104
- scale = resolution_map.get(output_resolution)
105
- if scale:
106
- cmd.extend(["-vf", f"scale={scale}"])
107
-
108
- # Add FPS if specified
109
- if output_fps != "Same as input":
110
- cmd.extend(["-r", output_fps])
111
-
112
- # Add bitrate or CRF settings
113
- if output_bitrate.lower() != "auto":
114
- cmd.extend(["-b:v", output_bitrate])
115
- else:
116
- # Use a default CRF value for quality
117
- cmd.extend(["-crf", "23"])
118
-
119
- # Optionally, you can add audio codec settings
120
- # cmd.extend(["-c:a", "aac", "-b:a", "128k"])
121
-
122
- # Add output file
123
- cmd.append(output_path)
124
-
125
- # Print the FFmpeg command for debugging
126
- print("FFmpeg command:", ' '.join(cmd))
127
-
128
- duration = self.get_video_duration(input_path)
129
- print(f"Video duration: {duration} seconds")
130
-
131
- process = subprocess.Popen(
132
- cmd,
133
- stdout=subprocess.PIPE,
134
- stderr=subprocess.STDOUT, # Combine stderr into stdout
135
- universal_newlines=True
136
- )
137
-
138
- while True:
139
- line = process.stdout.readline()
140
- if not line:
141
- if process.poll() is not None:
142
- break
143
- continue
144
-
145
- # Print the line for debugging
146
- print("FFmpeg output:", line.strip())
147
-
148
- if "frame=" in line and progress_callback and duration > 0:
149
- # Extract time from the output
150
- match = re.search(r'time=(\d+:\d+:\d+\.\d+)', line)
151
- if match:
152
- time_str = match.group(1)
153
- h, m, s = time_str.split(':')
154
- current_time = float(h) * 3600 + float(m) * 60 + float(s)
155
- progress = current_time / duration
156
- progress_callback(progress)
157
-
158
- process.wait()
159
-
160
- if process.returncode == 0:
161
- return True, f"Successfully converted: {output_filename}"
162
- else:
163
- error_output = process.stdout.read()
164
- return False, f"Error converting {Path(input_path).name}: FFmpeg error code {process.returncode}\n{error_output}"
165
-
166
- except Exception as e:
167
- return False, f"Error converting {Path(input_path).name}: {str(e)}"
 
 
 
 
 
 
 
 
1
+ import os
2
+ import re
3
+ import subprocess
4
+ import torch
5
+ from datetime import datetime
6
+ from pathlib import Path
7
+ from typing import List, Optional, Tuple
8
+ import platform
9
+
10
+ class VideoConverter:
11
+ def __init__(self):
12
+ # Check the operating system
13
+ if platform.system() == 'Windows':
14
+ # Windows-specific FFmpeg path
15
+ self.ffmpeg_path = os.path.join(os.getcwd(), "ffmpeg", "bin", "ffmpeg.exe")
16
+ else:
17
+ # On Linux, assume FFmpeg is installed and available in PATH
18
+ self.ffmpeg_path = "ffmpeg"
19
+ self.gpu_available = torch.cuda.is_available()
20
+ self.formats = ["MP4", "MKV", "AVI", "MOV", "WMV", "FLV", "MPEG"]
21
+ self.codecs = [
22
+ "H.264",
23
+ "HEVC (H.265)",
24
+ "MPEG-4 (Part 2)",
25
+ "MPEG-2",
26
+ "ProRes Proxy",
27
+ "ProRes Light",
28
+ "ProRes Standard",
29
+ "ProRes HQ"
30
+ ]
31
+
32
+ def get_codec_params(self, codec: str) -> List[str]:
33
+ codec_params = {
34
+ "H.264": ["-c:v", "libx264", "-preset", "medium"],
35
+ "HEVC (H.265)": ["-c:v", "libx265", "-preset", "medium"],
36
+ "MPEG-4 (Part 2)": ["-c:v", "mpeg4"],
37
+ "MPEG-2": ["-c:v", "mpeg2video"],
38
+ "ProRes Proxy": ["-c:v", "prores_ks", "-profile:v", "0"],
39
+ "ProRes Light": ["-c:v", "prores_ks", "-profile:v", "1"],
40
+ "ProRes Standard": ["-c:v", "prores_ks", "-profile:v", "2"],
41
+ "ProRes HQ": ["-c:v", "prores_ks", "-profile:v", "3"]
42
+ }
43
+ return codec_params.get(codec, ["-c:v", "libx264", "-preset", "medium"])
44
+
45
+ def get_video_duration(self, input_path: str) -> float:
46
+ cmd = [
47
+ self.ffmpeg_path,
48
+ "-i",
49
+ input_path
50
+ ]
51
+ try:
52
+ output = subprocess.check_output(cmd, stderr=subprocess.STDOUT, universal_newlines=True)
53
+ for line in output.split('\n'):
54
+ if "Duration" in line:
55
+ time_str = line.split("Duration: ")[1].split(",")[0]
56
+ h, m, s = time_str.split(':')
57
+ return float(h) * 3600 + float(m) * 60 + float(s)
58
+ except Exception as e:
59
+ print(f"Error getting video duration: {e}")
60
+ return 0
61
+
62
+ def convert_video(
63
+ self,
64
+ input_path: str,
65
+ output_format: str,
66
+ codec: str,
67
+ output_dir: str,
68
+ progress_callback: Optional[callable] = None,
69
+ output_filename: Optional[str] = None,
70
+ output_resolution: str = "Same as input",
71
+ output_bitrate: str = "auto",
72
+ output_fps: str = "Same as input"
73
+ ) -> Tuple[bool, str]:
74
+ try:
75
+ if not os.path.exists(input_path):
76
+ return False, f"Input file does not exist: {Path(input_path).name}"
77
+
78
+ if not os.path.exists(output_dir):
79
+ os.makedirs(output_dir)
80
+
81
+ output_path = os.path.join(output_dir, output_filename)
82
+
83
+ # Base FFmpeg command
84
+ cmd = [
85
+ self.ffmpeg_path,
86
+ "-y"
87
+ ]
88
+
89
+ # Add GPU acceleration if available
90
+ if self.gpu_available:
91
+ if codec in ["H.264", "HEVC (H.265)"]:
92
+ cmd.extend(["-hwaccel", "cuda"])
93
+
94
+ # Add input file
95
+ cmd.extend([
96
+ "-i", input_path
97
+ ])
98
+
99
+ # Add codec parameters
100
+ cmd.extend(self.get_codec_params(codec))
101
+
102
+ # Add scaling if necessary
103
+ if output_resolution != "Same as input":
104
+ resolution_map = {
105
+ "3840x2160 (4K)": "3840:2160",
106
+ "2560x1440 (1440p)": "2560:1440",
107
+ "1920x1080 (1080p)": "1920:1080",
108
+ "1280x720 (720p)": "1280:720",
109
+ "854x480 (480p)": "854:480"
110
+ }
111
+ scale = resolution_map.get(output_resolution)
112
+ if scale:
113
+ cmd.extend(["-vf", f"scale={scale}"])
114
+
115
+ # Add FPS if specified
116
+ if output_fps != "Same as input":
117
+ cmd.extend(["-r", output_fps])
118
+
119
+ # Add bitrate or CRF settings
120
+ if output_bitrate.lower() != "auto":
121
+ cmd.extend(["-b:v", output_bitrate])
122
+ else:
123
+ # Use a default CRF value for quality
124
+ cmd.extend(["-crf", "23"])
125
+
126
+ # Optionally, you can add audio codec settings
127
+ # cmd.extend(["-c:a", "aac", "-b:a", "128k"])
128
+
129
+ # Add output file
130
+ cmd.append(output_path)
131
+
132
+ # Print the FFmpeg command for debugging
133
+ print("FFmpeg command:", ' '.join(cmd))
134
+
135
+ duration = self.get_video_duration(input_path)
136
+ print(f"Video duration: {duration} seconds")
137
+
138
+ process = subprocess.Popen(
139
+ cmd,
140
+ stdout=subprocess.PIPE,
141
+ stderr=subprocess.STDOUT, # Combine stderr into stdout
142
+ universal_newlines=True
143
+ )
144
+
145
+ while True:
146
+ line = process.stdout.readline()
147
+ if not line:
148
+ if process.poll() is not None:
149
+ break
150
+ continue
151
+
152
+ # Print the line for debugging
153
+ print("FFmpeg output:", line.strip())
154
+
155
+ if "frame=" in line and progress_callback and duration > 0:
156
+ # Extract time from the output
157
+ match = re.search(r'time=(\d+:\d+:\d+\.\d+)', line)
158
+ if match:
159
+ time_str = match.group(1)
160
+ h, m, s = time_str.split(':')
161
+ current_time = float(h) * 3600 + float(m) * 60 + float(s)
162
+ progress = current_time / duration
163
+ progress_callback(progress)
164
+
165
+ process.wait()
166
+
167
+ if process.returncode == 0:
168
+ return True, f"Successfully converted: {output_filename}"
169
+ else:
170
+ error_output = process.stdout.read()
171
+ return False, f"Error converting {Path(input_path).name}: FFmpeg error code {process.returncode}\n{error_output}"
172
+
173
+ except Exception as e:
174
+ return False, f"Error converting {Path(input_path).name}: {str(e)}"
requirements.txt CHANGED
@@ -1,3 +1,3 @@
1
- gradio
2
- torch
3
- ffmpeg
 
1
+ gradio
2
+ torch
3
+ ffmpeg-python