Spaces:
Running
Running
File size: 4,435 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 7ce4a76 ccea871 cab48b5 6bc8fde 7ce4a76 182b08d 7ce4a76 cab48b5 e7c74c6 105e5dd 7ce4a76 4383f3c 6bc8fde 0809817 419ec35 182b08d ccea871 182b08d 7ce4a76 ccea871 105e5dd 7ce4a76 ccea871 6bc8fde 7ce4a76 6bc8fde ccea871 105e5dd 2c19cb5 cab48b5 c25ac20 |
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 |
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 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>
<style>
#youtube-url, #uploaded-audio { width: 45%; }
#process-button { width: 100%; margin-top: 10px; background-color: #6a4cfc; color: white; border: none; border-radius: 5px; }
#mp3-download, #iphone-ringtone { width: 45%; }
#instructions { width: 100%; margin-top: 20px; }
#start-time-slider, #end-time-slider { width: 45%; }
</style>
""")
with gr.Row():
youtube_url = gr.Textbox(placeholder="Enter the URL here...", label="YouTube URL", elem_id="youtube-url")
uploaded_audio = gr.File(label="Upload Audio File", type="filepath", elem_id="uploaded-audio")
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)", elem_id="start-time-slider")
end_time = gr.Slider(1, 20, value=20, label="End Time (seconds)", elem_id="end-time-slider")
# Add a class for custom button color
process_button = gr.Button("Create Ringtones", elem_id="process-button")
with gr.Row():
mp3_download = gr.File(label="Android Ringtone", elem_id="mp3-download")
iphone_ringtone = gr.File(label="iPhone Ringtone", elem_id="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,
elem_id="instructions"
)
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)
|