|
|
import gradio as gr |
|
|
from yt_dlp import YoutubeDL |
|
|
import tempfile |
|
|
import os |
|
|
|
|
|
def download_snippet(url, duration_sec): |
|
|
|
|
|
tmp = tempfile.NamedTemporaryFile(delete=False, suffix=".mp3") |
|
|
output_path = tmp.name |
|
|
tmp.close() |
|
|
|
|
|
ydl_opts = { |
|
|
"format": "bestaudio", |
|
|
"outtmpl": output_path, |
|
|
"external_downloader": "ffmpeg", |
|
|
"external_downloader_args": ["-t", str(int(duration_sec))], |
|
|
"quiet": True, |
|
|
"no_warnings": True, |
|
|
} |
|
|
|
|
|
with YoutubeDL(ydl_opts) as ydl: |
|
|
ydl.download([url]) |
|
|
|
|
|
return output_path |
|
|
|
|
|
with gr.Blocks(title="SoundCloud 30s Stream Snippet") as demo: |
|
|
gr.Markdown("## 🎵 SoundCloud Snippet Generator") |
|
|
gr.Markdown("Downloads only the first *N seconds* using yt-dlp + ffmpeg.") |
|
|
|
|
|
url = gr.Textbox( |
|
|
label="SoundCloud URL", |
|
|
value="https://soundcloud.com/antonio-antetomaso/mutiny-on-the-bounty-closing-titles-cover" |
|
|
) |
|
|
|
|
|
duration = gr.Slider( |
|
|
minimum=1, |
|
|
maximum=300, |
|
|
value=30, |
|
|
step=1, |
|
|
label="Snippet length (seconds)" |
|
|
) |
|
|
|
|
|
btn = gr.Button("Generate snippet") |
|
|
|
|
|
audio = gr.Audio( |
|
|
type="filepath", |
|
|
label="Preview & download" |
|
|
) |
|
|
|
|
|
btn.click(download_snippet, inputs=[url, duration], outputs=audio) |
|
|
|
|
|
demo.launch() |
|
|
|
|
|
|