Spaces:
Sleeping
Sleeping
import gradio as gr | |
import requests | |
from pydub import AudioSegment | |
import shazamio | |
import os | |
import time | |
# Environment variables | |
token = os.environ.get('TOKEN') | |
client_id = os.environ.get('SOUNDCLOUD_CLIENT_ID') | |
client_secret = os.environ.get('SOUNDCLOUD_CLIENT_SECRET') | |
# Function to download audio | |
def download_audio(streaming_url, output_path, headers): | |
try: | |
response = requests.get(streaming_url, headers=headers, stream=True) | |
response.raise_for_status() | |
with open(output_path, 'wb') as f: | |
for chunk in response.iter_content(chunk_size=8192): | |
f.write(chunk) | |
return "Audio downloaded successfully." | |
except Exception as e: | |
return f"Error downloading audio: {e}" | |
# Function to identify track using Shazam | |
async def identify_track(shazam, audio_chunk): | |
try: | |
temp_file = 'temp_chunk.wav' | |
audio_chunk.export(temp_file, format='wav') | |
# Ensure temp_file exists and is not a directory | |
if not os.path.isfile(temp_file): | |
raise FileNotFoundError(f"Temporary file '{temp_file}' does not exist or is not a valid file.") | |
result = await shazam.recognize_file(temp_file) | |
os.remove(temp_file) # Clean up temporary file | |
if result and 'track' in result: | |
track_data = result['track'] | |
return { | |
'title': track_data['title'], | |
'subtitle': track_data['subtitle'] | |
} | |
else: | |
return None | |
except Exception as e: | |
return f"Error identifying track: {e}" | |
# Main processing function | |
async def process_dj_set(track_url, progress=gr.Progress()): | |
try: | |
status = "Resolving SoundCloud URL..." | |
headers = {'Authorization': f'Bearer {token}'} | |
resolve_response = requests.get(f'https://api.soundcloud.com/resolve.json?url={track_url}', headers=headers) | |
if resolve_response.status_code != 200: | |
return "Failed to resolve track URL.", "" | |
track_data = resolve_response.json() | |
streaming_url = track_data.get('stream_url') | |
if not streaming_url: | |
return "Streaming URL not found.", "" | |
status = "Downloading audio..." | |
download_status = download_audio(streaming_url, 'track.wav', headers) | |
if "Error" in download_status: | |
return download_status, "" | |
status = "Processing audio..." | |
# Ensure 'track.wav' exists and is not a directory | |
if not os.path.isfile('track.wav'): | |
raise FileNotFoundError("Downloaded audio file 'track.wav' does not exist or is not valid.") | |
audio = AudioSegment.from_wav('track.wav') | |
chunk_duration = 30000 # 30 seconds | |
overlap = 10000 # 10 seconds | |
chunks = [] | |
start = 0 | |
while start + chunk_duration < len(audio): | |
end = start + chunk_duration | |
chunk = audio[start:end] | |
chunks.append((start, chunk)) | |
start += chunk_duration - overlap | |
shazam = shazamio.Shazam() | |
tracklist = [] | |
for start_time, chunk in chunks: | |
progress(0.1) | |
track_info = await identify_track(shazam, chunk) | |
if isinstance(track_info, str) and "Error" in track_info: # Check for errors in identification | |
return track_info, "" | |
if track_info: | |
timestamp = time.strftime("%M:%S", time.gmtime(start_time / 1000)) | |
tracklist.append(f"{timestamp} - {track_info['title']} by {track_info['subtitle']}") | |
status = "Generating output..." | |
tracklist_output = "\n".join(tracklist) | |
return tracklist_output, tracklist_output | |
except Exception as e: | |
return f"An error occurred during processing: {e}", "" | |
css = """ | |
#col-container { | |
margin: 0 auto; | |
max-width: 640px; | |
} | |
""" | |
with gr.Blocks(css=css) as demo: | |
with gr.Column(elem_id="col-container"): | |
gr.Markdown("# SoundCloud DJ Set Track Identifier") | |
with gr.Row(): | |
track_url_input = gr.Text( | |
label="SoundCloud DJ Set URL", | |
show_label=False, | |
max_lines=1, | |
placeholder="Enter SoundCloud DJ set URL", | |
container=False, | |
) | |
run_button = gr.Button("Process", scale=0, variant="primary") | |
result_output = gr.Textbox(label="Tracklist", show_label=False) | |
with gr.Accordion("Download Tracklist", open=False): | |
download_button = gr.File(label="Download") | |
gr.Examples(examples=["https://soundcloud.com/your-track-url"], inputs=[track_url_input]) | |
run_button.click(process_dj_set, inputs=track_url_input, outputs=[result_output, download_button]) | |
if __name__ == "__main__": | |
demo.launch(share=False) |