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>&nbsp;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)