File size: 8,784 Bytes
d83b57c 6567ae9 d83b57c 76e6c8b d83b57c 78eae19 b32dded 3328834 4811698 6eeced8 d83b57c 2297f9b 7be90a2 b32dded 6567ae9 ded38ea 2297f9b 6567ae9 b32dded 6567ae9 b32dded 6567ae9 c841491 b32dded 4811698 b32dded f4a8b85 4811698 6567ae9 4811698 b32dded 6eeced8 b32dded 3ab04ba b32dded 7f4c045 b32dded 7f4c045 b32dded 7f4c045 b32dded c841491 b32dded 7be90a2 b32dded 7be90a2 b32dded c841491 b32dded de205c3 b32dded de205c3 b32dded 78eae19 b32dded de205c3 b32dded de205c3 4280e2f de205c3 b32dded d83b57c 55f9dd1 b32dded 4811698 b32dded 1e988b2 b32dded 55f9dd1 b32dded 6567ae9 d83b57c b32dded d83b57c |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 |
import os
import asyncio
import subprocess
import uuid
import glob
import shutil
import gradio as gr
allowed_extensions = [
".3g2", ".3gp", ".3gpp", ".avi", ".cavs", ".dv", ".dvr", ".flv", ".m2ts",
".m4v", ".mkv", ".mod", ".mov", ".mp4", ".mpeg", ".mpg", ".mts", ".mxf",
".ogg", ".rm", ".rmvb", ".swf", ".ts", ".vob", ".webm", ".wmv", ".wtv",
".ogv", ".opus", ".aac", ".ac3", ".aif", ".aifc", ".aiff", ".amr", ".au",
".caf", ".dss", ".flac", ".m4a", ".m4b", ".mp3", ".oga", ".voc", ".wav",
".weba", ".wma"
]
os.system("chmod +x fdkaac") # Make sure fdkaac is executable
accel = 'auto'
video_base_opts = ['-crf', '63', '-c:v', 'libx264', '-tune', 'zerolatency']
UPLOAD_FOLDER = 'uploads'
CONVERTED_FOLDER = 'converted'
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
os.makedirs(CONVERTED_FOLDER, exist_ok=True)
async def run_subprocess(cmd, use_fdkaac=False):
env = os.environ.copy()
if use_fdkaac:
env["LD_LIBRARY_PATH"] = os.path.abspath("./") + ":" + env.get("LD_LIBRARY_PATH", "")
print(f"[DEBUG] Running command:\n{' '.join(cmd)}\n")
process = await asyncio.create_subprocess_exec(
*cmd,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
env=env
)
stdout, stderr = await process.communicate()
if process.returncode != 0:
print(f"[ERROR] Command failed:\n{stderr.decode()}\n")
raise subprocess.CalledProcessError(process.returncode, cmd, stderr.decode())
print(f"[DEBUG] Command succeeded:\n{stdout.decode()}\n")
return stdout.decode(), stderr.decode()
async def convert_video_task(input_path, downscale, faster, use_mp3, audio_only, custom_bitrate, video_bitrate):
if audio_only:
if use_mp3:
# Directly convert to MP3 via ffmpeg
output_audio = os.path.join(CONVERTED_FOLDER, f"{uuid.uuid4()}.mp3")
ffmpeg_audio_cmd = [
'ffmpeg', '-y', '-i', input_path,
'-c:a', 'libmp3lame', '-b:a', '8k', '-ar', '24000', '-ac', '1',
output_audio
]
await run_subprocess(ffmpeg_audio_cmd)
return output_audio, None
else:
# Convert to WAV, then AAC via fdkaac
audio_wav = os.path.join(CONVERTED_FOLDER, f"{uuid.uuid4()}.wav")
audio_output = os.path.join(CONVERTED_FOLDER, f"{uuid.uuid4()}.m4a")
await run_subprocess([
'ffmpeg', '-y', '-i', input_path, '-ac', '1', '-ar', '8000', audio_wav
])
await run_subprocess([
'./fdkaac', '-b', '1k', '-C', '-f', '2', '-G', '1', '-w', '8000',
'-o', audio_output, audio_wav
], use_fdkaac=True)
os.remove(audio_wav)
return audio_output, None
# Video conversion paths
if use_mp3:
output_video = os.path.join(CONVERTED_FOLDER, f"{uuid.uuid4()}.mp4")
ffmpeg_video_cmd = [
'ffmpeg', '-y', '-hwaccel', accel, '-i', input_path
]
if custom_bitrate:
ffmpeg_video_cmd += ['-b:v', f"{int(video_bitrate)}k"]
else:
ffmpeg_video_cmd += video_base_opts
if faster:
ffmpeg_video_cmd.extend(['-preset', 'ultrafast'])
ffmpeg_video_cmd += [
'-c:a', 'libmp3lame', '-b:a', '8k', '-ar', '24000', '-ac', '1',
output_video
]
await run_subprocess(ffmpeg_video_cmd)
return None, output_video
# AAC video + fdkaac audio merge
audio_wav = os.path.join(CONVERTED_FOLDER, f"{uuid.uuid4()}.wav")
audio_output = os.path.join(CONVERTED_FOLDER, f"{uuid.uuid4()}.m4a")
video_output = os.path.join(CONVERTED_FOLDER, f"{uuid.uuid4()}.mp4")
await run_subprocess([
'ffmpeg', '-y', '-i', input_path, '-ac', '1', '-ar', '8000', audio_wav
])
await run_subprocess([
'./fdkaac', '-b', '1k', '-C', '-f', '2', '-G', '1', '-w', '8000',
'-o', audio_output, audio_wav
], use_fdkaac=True)
video_cmd = ['ffmpeg', '-y', '-hwaccel', accel, '-i', input_path]
if downscale:
video_cmd += ['-vf', 'scale=-2:144']
if custom_bitrate:
video_cmd += ['-b:v', f"{int(video_bitrate)}k"]
else:
video_cmd += video_base_opts
if faster:
video_cmd.extend(['-preset', 'ultrafast'])
video_cmd += ['-an', video_output]
await run_subprocess(video_cmd)
merged_output = os.path.join(CONVERTED_FOLDER, f"{uuid.uuid4()}.mp4")
await run_subprocess([
'ffmpeg', '-y', '-i', video_output, '-i', audio_output, '-c', 'copy', merged_output
])
for f in [audio_wav, audio_output, video_output]:
try:
os.remove(f)
except FileNotFoundError:
pass
return None, merged_output
async def process_conversion(use_youtube, youtube_url, video_file, downscale, faster, use_mp3, audio_only, custom_bitrate, video_bitrate):
try:
if use_youtube:
if not youtube_url:
return "Error: YouTube URL required.", None
yt_uuid = str(uuid.uuid4())
yt_out = os.path.join(UPLOAD_FOLDER, yt_uuid + ".%(ext)s")
yt_cmd = ['yt-dlp', '-o', yt_out, '-f', 'b', youtube_url]
await run_subprocess(yt_cmd)
pattern = os.path.join(UPLOAD_FOLDER, yt_uuid + ".*")
files = glob.glob(pattern)
if not files:
return "Download failed.", None
input_path = files[0]
else:
if not video_file:
return "No video provided.", None
ext = os.path.splitext(video_file.name)[1].lower()
if ext not in allowed_extensions:
return f"Unsupported file type: {ext}", None
input_path = os.path.join(UPLOAD_FOLDER, f"{uuid.uuid4()}{ext}")
shutil.copy2(video_file.name, input_path)
audio_out, video_out = await convert_video_task(
input_path, downscale, faster, use_mp3, audio_only, custom_bitrate, video_bitrate
)
if audio_only:
return audio_out, audio_out
return video_out, video_out
except Exception as e:
return f"Error: {str(e)}", None
def convert_video(*args):
return asyncio.run(process_conversion(*args))
with gr.Blocks(theme=gr.themes.Default(primary_hue="rose")) as demo:
gr.Markdown("""
# **Low Quality Video Inator**
Upload a video or paste a YouTube URL below, then tweak the settings.
**Note:** YouTube downloads almost never work on HuggingFace.
""")
with gr.Group():
with gr.Row():
use_youtube = gr.Checkbox(label="π Use YouTube URL (usually broken here)", value=False)
youtube_url = gr.Textbox(label="YouTube URL", placeholder="Paste YouTube URL here")
video_file = gr.File(label="π Upload Video File", file_types=[
".3g2", ".3gp", ".3gpp", ".avi", ".cavs", ".dv", ".dvr", ".flv", ".m2ts", ".m4v",
".mkv", ".mod", ".mov", ".mp4", ".mpeg", ".mpg", ".mts", ".mxf", ".ogg", ".rm",
".rmvb", ".swf", ".ts", ".vob", ".webm", ".wmv", ".wtv", ".ogv", ".opus", ".aac",
".ac3", ".aif", ".aifc", ".aiff", ".amr", ".au", ".caf", ".dss", ".flac", ".m4a",
".m4b", ".mp3", ".oga", ".voc", ".wav", ".weba", ".wma"
])
gr.Markdown("### βοΈ **Conversion Settings**")
with gr.Group():
with gr.Row():
downscale = gr.Checkbox(label="Downscale Video to 144p", value=False)
faster = gr.Checkbox(label="Faster Video Compression (pixelated, faster)", value=False)
with gr.Row():
use_mp3 = gr.Checkbox(label="Use MP3 Audio (better compatibility, AAC is lower quality)", value=False)
audio_only = gr.Checkbox(label="Audio Only (no video output)", value=False)
with gr.Row():
custom_bitrate = gr.Checkbox(label="Use Custom Video Bitrate", value=False)
video_bitrate = gr.Number(label="Video Bitrate (kbps)", visible=False)
custom_bitrate.change(
lambda checked: gr.update(visible=checked),
inputs=[custom_bitrate],
outputs=[video_bitrate]
)
convert_button = gr.Button("Convert Now", variant="primary")
gr.Markdown("### **Conversion Preview**")
video_preview = gr.Video(label="Preview Output")
gr.Markdown("### **Download Your Masterpiece**")
file_download = gr.File(label="Download Result")
convert_button.click(
convert_video,
inputs=[
use_youtube, youtube_url, video_file,
downscale, faster, use_mp3, audio_only,
custom_bitrate, video_bitrate
],
outputs=[video_preview, file_download]
)
demo.launch() |