RandomPersonRR commited on
Commit
de205c3
Β·
verified Β·
1 Parent(s): 4280e2f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +37 -63
app.py CHANGED
@@ -36,24 +36,22 @@ async def run_subprocess(cmd, use_fdkaac=False):
36
 
37
  async def convert_video_task(input_path, downscale, faster, use_mp3, audio_only, custom_bitrate, video_bitrate, progress):
38
  if use_mp3:
39
- progress.update(1, desc="Converting audio to MP3...")
40
  output_audio = os.path.join(CONVERTED_FOLDER, f"{uuid.uuid4()}.mp3")
 
41
  ffmpeg_audio_cmd = [
42
  'ffmpeg', '-y', '-i', input_path, '-vn',
43
  '-c:a', 'libmp3lame', '-b:a', '8k', '-ar', '24000', '-ac', '1',
44
  output_audio
45
  ]
46
  if audio_only:
47
- # Audio-only MP3
48
  await run_subprocess(ffmpeg_audio_cmd)
49
  return output_audio, None
50
  else:
51
- # Video+MP3, no splitting; encode video with MP3 audio embedded
52
  output_video = os.path.join(CONVERTED_FOLDER, f"{uuid.uuid4()}.mp4")
 
53
  ffmpeg_video_cmd = [
54
  'ffmpeg', '-y', '-hwaccel', accel, '-i', input_path
55
  ]
56
-
57
  if custom_bitrate:
58
  ffmpeg_video_cmd += ['-b:v', f"{int(video_bitrate)}k"]
59
  else:
@@ -68,120 +66,97 @@ async def convert_video_task(input_path, downscale, faster, use_mp3, audio_only,
68
  await run_subprocess(ffmpeg_video_cmd)
69
  return None, output_video
70
 
71
- # fdkaac path: Split, compress audio, merge
 
72
  audio_wav = os.path.join(CONVERTED_FOLDER, f"{uuid.uuid4()}.wav")
73
  audio_output = os.path.join(CONVERTED_FOLDER, f"{uuid.uuid4()}.m4a")
74
  video_output = os.path.join(CONVERTED_FOLDER, f"{uuid.uuid4()}.mp4")
75
 
76
- # Extract mono WAV audio
77
- progress.update(1, desc="Splitting Audio and Video...")
78
  await run_subprocess([
79
  'ffmpeg', '-y', '-i', input_path, '-ac', '1', '-ar', '8000', audio_wav
80
  ])
81
 
82
- # Compress WAV with fdkaac
83
- progress.update(1, desc="Converting audio to AAC which is lower quality...")
84
  await run_subprocess([
85
  './fdkaac', '-b', '1k', '-C', '-f', '2', '-G', '1', '-w', '8000',
86
  '-o', audio_output, audio_wav
87
  ], use_fdkaac=True)
88
 
89
- # Compress video without audio
90
- progress.update(1, desc="Making the video quality lower...")
91
  video_cmd = [
92
  'ffmpeg', '-y', '-hwaccel', accel, '-i', input_path
93
  ]
94
-
95
  if downscale:
96
  video_cmd += ['-vf', 'scale=-2:144']
97
-
98
  if custom_bitrate:
99
  video_cmd += ['-b:v', f"{int(video_bitrate)}k"]
100
  else:
101
  video_cmd += video_base_opts
102
  if faster:
103
  video_cmd.extend(['-preset', 'ultrafast'])
104
-
105
  video_cmd += ['-an', video_output]
106
  await run_subprocess(video_cmd)
107
 
108
  if audio_only:
109
  return audio_output, None
110
 
111
- # Merging video + audio
112
- progress.update(1, desc="Mixing audio and video together...")
113
  merged_output = os.path.join(CONVERTED_FOLDER, f"{uuid.uuid4()}.mp4")
114
  await run_subprocess([
115
  'ffmpeg', '-y', '-i', video_output, '-i', audio_output, '-c', 'copy', merged_output
116
  ])
117
 
118
- # Cleanup intermediates
119
  for f in [audio_wav, audio_output, video_output]:
120
  try:
121
  os.remove(f)
122
  except FileNotFoundError:
123
  pass
124
 
 
125
  return None, merged_output
126
 
127
  async def process_conversion(use_youtube, youtube_url, video_file, downscale, faster, use_mp3, audio_only, custom_bitrate, video_bitrate, progress=gr.Progress()):
128
  try:
129
- with progress.tqdm(total=5, desc="Starting...") as pbar:
130
- if use_youtube:
131
- pbar.update(1, desc="Downloading video...")
132
- if not youtube_url:
133
- return "Error: YouTube URL required.", None
134
- yt_uuid = str(uuid.uuid4())
135
- yt_out = os.path.join(UPLOAD_FOLDER, yt_uuid + ".%(ext)s")
136
- yt_cmd = ['yt-dlp', '-o', yt_out, '-f', 'b', youtube_url]
137
- await run_subprocess(yt_cmd)
138
- pattern = os.path.join(UPLOAD_FOLDER, yt_uuid + ".*")
139
- files = glob.glob(pattern)
140
- if not files:
141
- return "Download failed.", None
142
- input_path = files[0]
143
- else:
144
- pbar.update(1, desc="Preparing input video...")
145
- if not video_file:
146
- return "No video provided.", None
147
- ext = os.path.splitext(video_file.name)[1]
148
- input_path = os.path.join(UPLOAD_FOLDER, f"{uuid.uuid4()}{ext}")
149
- shutil.copy2(video_file.name, input_path)
150
-
151
- if use_mp3:
152
- pbar.update(1, desc="Converting audio to MP3...")
153
- else:
154
- pbar.update(1, desc="Converting audio to AAC which is lower quality...")
155
-
156
- audio_out, video_out = await convert_video_task(
157
- input_path, downscale, faster, use_mp3, audio_only, custom_bitrate, video_bitrate, progress=pbar
158
- )
159
-
160
- if not use_mp3:
161
- pbar.update(1, desc="Making the video quality lower...")
162
-
163
- pbar.update(1, desc="Finishing up...")
164
 
165
- if audio_only:
166
- return audio_out, audio_out
167
- return video_out, video_out
168
  except Exception as e:
169
  return f"Error: {str(e)}", None
170
 
171
- def convert_video(*args):
172
- return asyncio.run(process_conversion(*args))
173
-
174
- # Gradio Interface (Now With Custom Bitrate)
175
  with gr.Blocks(theme=gr.themes.Default(primary_hue="rose")) as demo:
176
  gr.Markdown("""
177
  # **Low Quality Video Inator**
178
-
179
  Upload a video or paste a YouTube URL below, then tweak the settings to your liking.
180
  """)
181
 
182
  with gr.Group():
183
  with gr.Row():
184
- use_youtube = gr.Checkbox(label="πŸ”— Use YouTube URL (Useless on Huggingface, works when ran locally probably.)", value=False)
185
  youtube_url = gr.Textbox(label="YouTube URL", placeholder="Paste YouTube URL here")
186
  video_file = gr.File(label="πŸ“ Upload Video File")
187
 
@@ -197,7 +172,6 @@ with gr.Blocks(theme=gr.themes.Default(primary_hue="rose")) as demo:
197
  custom_bitrate = gr.Checkbox(label="Custom Video Bitrate", value=False)
198
  video_bitrate = gr.Number(label="Bitrate (kbps)", visible=False)
199
 
200
- # Show/hide bitrate field
201
  custom_bitrate.change(
202
  lambda checked: gr.update(visible=checked),
203
  inputs=[custom_bitrate],
@@ -213,7 +187,7 @@ with gr.Blocks(theme=gr.themes.Default(primary_hue="rose")) as demo:
213
  file_download = gr.File(label="Download Result")
214
 
215
  convert_button.click(
216
- convert_video,
217
  inputs=[
218
  use_youtube, youtube_url, video_file,
219
  downscale, faster, use_mp3, audio_only,
 
36
 
37
  async def convert_video_task(input_path, downscale, faster, use_mp3, audio_only, custom_bitrate, video_bitrate, progress):
38
  if use_mp3:
 
39
  output_audio = os.path.join(CONVERTED_FOLDER, f"{uuid.uuid4()}.mp3")
40
+ await progress(0.1, desc="Converting audio to MP3...")
41
  ffmpeg_audio_cmd = [
42
  'ffmpeg', '-y', '-i', input_path, '-vn',
43
  '-c:a', 'libmp3lame', '-b:a', '8k', '-ar', '24000', '-ac', '1',
44
  output_audio
45
  ]
46
  if audio_only:
 
47
  await run_subprocess(ffmpeg_audio_cmd)
48
  return output_audio, None
49
  else:
 
50
  output_video = os.path.join(CONVERTED_FOLDER, f"{uuid.uuid4()}.mp4")
51
+ await progress(0.3, desc="Making the video quality lower...")
52
  ffmpeg_video_cmd = [
53
  'ffmpeg', '-y', '-hwaccel', accel, '-i', input_path
54
  ]
 
55
  if custom_bitrate:
56
  ffmpeg_video_cmd += ['-b:v', f"{int(video_bitrate)}k"]
57
  else:
 
66
  await run_subprocess(ffmpeg_video_cmd)
67
  return None, output_video
68
 
69
+ # AAC (fdkaac) path
70
+ await progress(0.1, desc="Splitting Audio and Video...")
71
  audio_wav = os.path.join(CONVERTED_FOLDER, f"{uuid.uuid4()}.wav")
72
  audio_output = os.path.join(CONVERTED_FOLDER, f"{uuid.uuid4()}.m4a")
73
  video_output = os.path.join(CONVERTED_FOLDER, f"{uuid.uuid4()}.mp4")
74
 
 
 
75
  await run_subprocess([
76
  'ffmpeg', '-y', '-i', input_path, '-ac', '1', '-ar', '8000', audio_wav
77
  ])
78
 
79
+ await progress(0.3, desc="Converting audio to AAC which is lower quality...")
 
80
  await run_subprocess([
81
  './fdkaac', '-b', '1k', '-C', '-f', '2', '-G', '1', '-w', '8000',
82
  '-o', audio_output, audio_wav
83
  ], use_fdkaac=True)
84
 
85
+ await progress(0.6, desc="Making the video quality lower...")
 
86
  video_cmd = [
87
  'ffmpeg', '-y', '-hwaccel', accel, '-i', input_path
88
  ]
 
89
  if downscale:
90
  video_cmd += ['-vf', 'scale=-2:144']
 
91
  if custom_bitrate:
92
  video_cmd += ['-b:v', f"{int(video_bitrate)}k"]
93
  else:
94
  video_cmd += video_base_opts
95
  if faster:
96
  video_cmd.extend(['-preset', 'ultrafast'])
 
97
  video_cmd += ['-an', video_output]
98
  await run_subprocess(video_cmd)
99
 
100
  if audio_only:
101
  return audio_output, None
102
 
103
+ await progress(0.9, desc="Mixing audio and video together...")
 
104
  merged_output = os.path.join(CONVERTED_FOLDER, f"{uuid.uuid4()}.mp4")
105
  await run_subprocess([
106
  'ffmpeg', '-y', '-i', video_output, '-i', audio_output, '-c', 'copy', merged_output
107
  ])
108
 
 
109
  for f in [audio_wav, audio_output, video_output]:
110
  try:
111
  os.remove(f)
112
  except FileNotFoundError:
113
  pass
114
 
115
+ await progress(1.0)
116
  return None, merged_output
117
 
118
  async def process_conversion(use_youtube, youtube_url, video_file, downscale, faster, use_mp3, audio_only, custom_bitrate, video_bitrate, progress=gr.Progress()):
119
  try:
120
+ if use_youtube:
121
+ if not youtube_url:
122
+ return "Error: YouTube URL required.", None
123
+ yt_uuid = str(uuid.uuid4())
124
+ yt_out = os.path.join(UPLOAD_FOLDER, yt_uuid + ".%(ext)s")
125
+ await progress(0, desc="Downloading from YouTube...")
126
+ yt_cmd = ['yt-dlp', '-o', yt_out, '-f', 'b', youtube_url]
127
+ await run_subprocess(yt_cmd)
128
+ pattern = os.path.join(UPLOAD_FOLDER, yt_uuid + ".*")
129
+ files = glob.glob(pattern)
130
+ if not files:
131
+ return "Download failed.", None
132
+ input_path = files[0]
133
+ else:
134
+ if not video_file:
135
+ return "No video provided.", None
136
+ ext = os.path.splitext(video_file.name)[1]
137
+ input_path = os.path.join(UPLOAD_FOLDER, f"{uuid.uuid4()}{ext}")
138
+ shutil.copy2(video_file.name, input_path)
139
+
140
+ audio_out, video_out = await convert_video_task(
141
+ input_path, downscale, faster, use_mp3, audio_only, custom_bitrate, video_bitrate, progress
142
+ )
 
 
 
 
 
 
 
 
 
 
 
 
143
 
144
+ if audio_only:
145
+ return audio_out, audio_out
146
+ return video_out, video_out
147
  except Exception as e:
148
  return f"Error: {str(e)}", None
149
 
150
+ # Gradio Interface
 
 
 
151
  with gr.Blocks(theme=gr.themes.Default(primary_hue="rose")) as demo:
152
  gr.Markdown("""
153
  # **Low Quality Video Inator**
 
154
  Upload a video or paste a YouTube URL below, then tweak the settings to your liking.
155
  """)
156
 
157
  with gr.Group():
158
  with gr.Row():
159
+ use_youtube = gr.Checkbox(label="πŸ”— Use YouTube URL (experimental)", value=False)
160
  youtube_url = gr.Textbox(label="YouTube URL", placeholder="Paste YouTube URL here")
161
  video_file = gr.File(label="πŸ“ Upload Video File")
162
 
 
172
  custom_bitrate = gr.Checkbox(label="Custom Video Bitrate", value=False)
173
  video_bitrate = gr.Number(label="Bitrate (kbps)", visible=False)
174
 
 
175
  custom_bitrate.change(
176
  lambda checked: gr.update(visible=checked),
177
  inputs=[custom_bitrate],
 
187
  file_download = gr.File(label="Download Result")
188
 
189
  convert_button.click(
190
+ process_conversion,
191
  inputs=[
192
  use_youtube, youtube_url, video_file,
193
  downscale, faster, use_mp3, audio_only,