Spaces:
Running
Running
File size: 3,816 Bytes
2c19cb5 105e5dd 147c80a 105e5dd 147c80a 105e5dd a6f5db7 147c80a 105e5dd 147c80a 105e5dd ccea871 147c80a 105e5dd 147c80a 105e5dd a6f5db7 147c80a 105e5dd 147c80a 105e5dd a6f5db7 ccea871 a6f5db7 105e5dd a6f5db7 105e5dd a6f5db7 147c80a c79f358 147c80a 419ec35 a6f5db7 105e5dd 419ec35 105e5dd a6f5db7 dd81a22 cab48b5 dd81a22 147c80a 105e5dd 7ce4a76 ccea871 cab48b5 6bc8fde cab48b5 e7c74c6 105e5dd a6f5db7 4383f3c 6bc8fde 0809817 419ec35 a6f5db7 105e5dd a6f5db7 6bc8fde a6f5db7 6bc8fde ccea871 105e5dd 2c19cb5 cab48b5 c25ac20 a6f5db7 |
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 |
import os
import yt_dlp
import gradio as gr
import re
from pydub import AudioSegment
# Ensure downloads directory exists
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': 'm4a/bestaudio',
'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'])
# Ensure correct extension
if not filename.endswith(".m4a"):
possible_file = f"downloads/{song_name}.m4a"
if os.path.exists(possible_file):
filename = possible_file
elif uploaded_audio is not None:
filename = uploaded_audio
song_name = sanitize_filename(os.path.splitext(os.path.basename(uploaded_audio))[0])
# Validate file existence
if not filename or not os.path.exists(filename):
print(f"File {filename} not found!")
return None, None
# Process audio
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]
# Save MP3
mp3_filename = f"downloads/{song_name}.mp3"
trimmed_audio.export(mp3_filename, format="mp3")
# Rename M4A to M4R for iPhone
m4a_filename = filename
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 style="font-size: 2rem; text-align: center;"><i class="fas fa-music"></i> PYTR - Python YouTube Ringtones</h1>
<p style="text-align: center;">Enter a YouTube URL or upload an audio file to create ringtones.</p>
<p style="text-align: center;"><a href="https://ringtones.jessejesse.xyz">Ringtones</a> | <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")
gr.HTML("<h3 style='text-align: center;'>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")
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
)
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)
|