Spaces:
Running
Running
File size: 3,643 Bytes
2c19cb5 105e5dd 147c80a 105e5dd dd81a22 147c80a 105e5dd 147c80a 105e5dd 147c80a 105e5dd ccea871 147c80a 105e5dd 147c80a 105e5dd 147c80a 105e5dd 147c80a 105e5dd ccea871 105e5dd 147c80a c79f358 147c80a 419ec35 105e5dd 419ec35 105e5dd dd81a22 147c80a ccea871 105e5dd dd81a22 cab48b5 dd81a22 147c80a 105e5dd e7c74c6 ccea871 cab48b5 147c80a ccea871 e7c74c6 cab48b5 e7c74c6 105e5dd ccea871 4383f3c cba744e 4e4befa cba744e 0809817 147c80a 419ec35 c25ac20 ccea871 105e5dd ccea871 105e5dd 2c19cb5 cab48b5 c25ac20 e7c74c6 |
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 |
import os
import yt_dlp
import gradio as gr
import re
import subprocess
from pydub import AudioSegment
os.makedirs("downloads", exist_ok=True)
def sanitize_filename(filename):
"""Sanitize filenames by replacing special characters."""
return re.sub(r'[^a-zA-Z0-9_-]', '_', filename)
def process_youtube_or_audio(url, uploaded_audio, start_time, end_time):
"""Downloads or processes audio, trims it, and exports ringtones."""
try:
filename, song_name = None, None
if url:
ydl_opts = {
'format': 'bestaudio/best',
'outtmpl': 'downloads/%(title)s.%(ext)s',
'cookiefile': 'cookies.txt'
}
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
info = ydl.extract_info(url, download=True)
filename = ydl.prepare_filename(info)
song_name = sanitize_filename(info['title'])
elif uploaded_audio is not None:
filename = uploaded_audio
song_name = sanitize_filename(os.path.splitext(os.path.basename(uploaded_audio))[0])
if not filename or not os.path.exists(filename):
return None, None
audio = AudioSegment.from_file(filename)
start_ms, end_ms = int(start_time * 1000), int(end_time * 1000)
start_ms = max(0, min(start_ms, len(audio)))
end_ms = max(start_ms, min(end_ms, len(audio)))
trimmed_audio = audio[start_ms:end_ms]
mp3_filename = f"downloads/{song_name}.mp3"
trimmed_audio.export(mp3_filename, format="mp3")
m4a_filename = f"downloads/{song_name}.m4a"
result = subprocess.run([
'ffmpeg', '-y', '-i', mp3_filename, '-vn', '-acodec', 'aac', '-b:a', '192k', m4a_filename
], capture_output=True, text=True)
if result.returncode != 0 or not os.path.exists(m4a_filename):
print("FFmpeg Error:", result.stderr)
return mp3_filename, None
m4r_filename = f"downloads/{song_name}.m4r"
os.rename(m4a_filename, m4r_filename)
return mp3_filename, m4r_filename
except Exception as e:
print(f"Error: {e}")
return None, None
# Gradio Interface
with gr.Blocks() as interface:
gr.HTML("""
<h1><i class="fas fa-music"></i> PYTR - Python YouTube Ringtones</h1>
<p>Enter a YouTube URL or upload an audio file to create ringtones.</p>
<p><a href="https://ringtones.jessejesse.xyz">Ringtones</a></p>
<p><a href="https://github.com/sudo-self/pytr">GitHub</a></p>
""")
with gr.Row():
youtube_url = gr.Textbox(placeholder="Enter the URL here...", label="YouTube URL")
uploaded_audio = gr.File(label="Upload Audio File", type="filepath")
with gr.Row():
instructions = gr.Textbox(
value="Android: move the download to the 'Ringtones' folder.\nApple: import download with 'Garage Band' and export to ringtones.",
label="Install Ringtones",
interactive=False
)
gr.HTML("<h3>Trim Audio</h3>")
with gr.Row():
start_time = gr.Slider(0, 20, value=0, label="Start Time (seconds)")
end_time = gr.Slider(1, 20, value=20, label="End Time (seconds)")
process_button = gr.Button("Create Ringtones")
with gr.Row():
mp3_download = gr.File(label="Android Ringtone")
iphone_ringtone = gr.File(label="iPhone Ringtone")
process_button.click(process_youtube_or_audio, inputs=[youtube_url, uploaded_audio, start_time, end_time], outputs=[mp3_download, iphone_ringtone])
interface.launch(share=True)
|