Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -1,46 +1,77 @@
|
|
1 |
import gradio as gr
|
2 |
-
import
|
3 |
-
import
|
4 |
-
import
|
5 |
-
import soundfile as sf
|
6 |
-
import io
|
7 |
|
8 |
-
def
|
9 |
-
"""
|
10 |
-
|
11 |
-
# Load audio from URL
|
12 |
-
y, sr = librosa.load(audio_url)
|
13 |
-
|
14 |
-
# Check for valid start and end times
|
15 |
-
if start_time < 0 or end_time > len(y) / sr or start_time >= end_time:
|
16 |
-
return "Invalid start or end time. Please check your input."
|
17 |
-
|
18 |
-
|
19 |
-
start_sample = int(start_time * sr)
|
20 |
-
end_sample = int(end_time * sr)
|
21 |
-
trimmed_audio = y[start_sample:end_sample]
|
22 |
-
|
23 |
-
# Save the trimmed audio to a BytesIO object
|
24 |
-
output_audio = io.BytesIO()
|
25 |
-
sf.write(output_audio, trimmed_audio, sr, format='wav')
|
26 |
-
output_audio.seek(0) # Reset the file pointer to the beginning
|
27 |
-
|
28 |
-
return gr.Audio(output_audio, label="Trimmed Audio")
|
29 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
30 |
except Exception as e:
|
31 |
-
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
32 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
33 |
|
|
|
34 |
iface = gr.Interface(
|
35 |
-
fn=
|
36 |
-
inputs=
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
],
|
41 |
-
|
42 |
-
title="Audio Trimmer",
|
43 |
-
description="Enter the URL of an audio file and specify the start and end times to trim it.",
|
44 |
)
|
45 |
|
46 |
-
|
|
|
|
1 |
import gradio as gr
|
2 |
+
from pytube import YouTube
|
3 |
+
import os
|
4 |
+
import re
|
|
|
|
|
5 |
|
6 |
+
def sanitize_filename(title):
|
7 |
+
"""Remove invalid characters from filename"""
|
8 |
+
return re.sub(r'[<>:"/\\|?*]', '', title)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
|
10 |
+
def download_audio(url, output_dir="downloads"):
|
11 |
+
try:
|
12 |
+
# Create output directory if it doesn't exist
|
13 |
+
if not os.path.exists(output_dir):
|
14 |
+
os.makedirs(output_dir)
|
15 |
+
|
16 |
+
# Create YouTube object
|
17 |
+
yt = YouTube(url)
|
18 |
+
|
19 |
+
# Get audio stream
|
20 |
+
audio_stream = yt.streams.filter(only_audio=True).first()
|
21 |
+
|
22 |
+
# Sanitize the title for filename
|
23 |
+
safe_title = sanitize_filename(yt.title)
|
24 |
+
|
25 |
+
# Download the audio
|
26 |
+
output_file = audio_stream.download(
|
27 |
+
output_path=output_dir,
|
28 |
+
filename=f"{safe_title}.mp3"
|
29 |
+
)
|
30 |
+
|
31 |
+
return {
|
32 |
+
"status": "success",
|
33 |
+
"message": f"Successfully downloaded: {safe_title}",
|
34 |
+
"title": yt.title,
|
35 |
+
"author": yt.author,
|
36 |
+
"duration": f"{yt.length // 60}:{yt.length % 60:02d}",
|
37 |
+
"file_path": output_file
|
38 |
+
}
|
39 |
+
|
40 |
except Exception as e:
|
41 |
+
return {
|
42 |
+
"status": "error",
|
43 |
+
"message": f"Error: {str(e)}",
|
44 |
+
"title": "",
|
45 |
+
"author": "",
|
46 |
+
"duration": "",
|
47 |
+
"file_path": ""
|
48 |
+
}
|
49 |
|
50 |
+
def process_url(url):
|
51 |
+
if not url.strip():
|
52 |
+
return "Please enter a YouTube URL"
|
53 |
+
|
54 |
+
result = download_audio(url)
|
55 |
+
|
56 |
+
if result["status"] == "error":
|
57 |
+
return result["message"]
|
58 |
+
|
59 |
+
return f"""Download successful!
|
60 |
+
Title: {result['title']}
|
61 |
+
Author: {result['author']}
|
62 |
+
Duration: {result['duration']}
|
63 |
+
Saved to: {result['file_path']}"""
|
64 |
|
65 |
+
# Create Gradio interface
|
66 |
iface = gr.Interface(
|
67 |
+
fn=process_url,
|
68 |
+
inputs=gr.Textbox(label="YouTube URL", placeholder="Enter YouTube video URL here..."),
|
69 |
+
outputs=gr.Textbox(label="Status"),
|
70 |
+
title="YouTube to MP3 Downloader",
|
71 |
+
description="Enter a YouTube URL to download the audio as MP3",
|
72 |
+
examples=[["https://www.youtube.com/watch?v=dQw4w9WgXcQ"]],
|
73 |
+
theme=gr.themes.Base()
|
|
|
|
|
74 |
)
|
75 |
|
76 |
+
if __name__ == "__main__":
|
77 |
+
iface.launch()
|