rm-dev-null commited on
Commit
1c9e038
·
verified ·
1 Parent(s): 6c00184

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +105 -36
app.py CHANGED
@@ -4,41 +4,99 @@ from pydub import AudioSegment
4
  import shazamio
5
  import os
6
  import time
7
- token = os.environ.get('TOKEN')
 
 
 
8
  # Replace with your actual client ID and client secret
9
  client_id = os.environ.get('SOUNDCLOUD_CLIENT_ID')
10
  client_secret = os.environ.get('SOUNDCLOUD_CLIENT_SECRET')
 
11
 
12
- def download_audio(streaming_url, output_path, headers):
13
- response = requests.get(streaming_url, headers=headers, stream=True)
14
- with open(output_path, 'wb') as f:
15
- for chunk in response.iter_content(chunk_size=8192):
16
- f.write(chunk)
17
-
18
- async def identify_track(shazam, audio_chunk):
19
- temp_file = 'temp_chunk.wav'
20
- audio_chunk.export(temp_file, format='wav')
21
- result = await shazam.recognize_file(temp_file)
22
- if result and 'track' in result:
23
- track_data = result['track']
24
- return {
25
- 'title': track_data['title'],
26
- 'subtitle': track_data['subtitle']
27
  }
28
- else:
29
- return None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
 
31
  async def process_dj_set(track_url, progress=gr.Progress()):
 
 
 
 
 
 
 
 
 
 
32
  headers = {
33
- 'Authorization': 'Bearer ' + f'{token}'
34
  }
35
- resolve_response = requests.get(f'https://api.soundcloud.com/resolve.json?url={track_url}', headers=headers)
36
- if resolve_response.status_code != 200:
37
- return "Failed to resolve track URL.", ""
38
- track_data = resolve_response.json()
39
- streaming_url = track_data['stream_url']
40
- download_audio(streaming_url, 'track.wav', headers)
41
- audio = AudioSegment.from_wav('track.wav')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  chunk_duration = 30000 # 30 seconds
43
  overlap = 10000 # 10 seconds
44
  chunks = []
@@ -48,17 +106,32 @@ async def process_dj_set(track_url, progress=gr.Progress()):
48
  chunk = audio[start:end]
49
  chunks.append((start, chunk))
50
  start += chunk_duration - overlap
 
 
51
  shazam = shazamio.Shazam()
 
 
52
  tracklist = []
53
  for start_time, chunk in chunks:
54
  progress(0.1)
55
- track_info = await identify_track(shazam, chunk)
56
- if track_info:
57
  timestamp = time.strftime("%M:%S", time.gmtime(start_time / 1000))
58
  tracklist.append(f"{timestamp} - {track_info['title']} by {track_info['subtitle']}")
 
 
 
 
59
  tracklist_output = "\n".join(tracklist)
60
- download_content = tracklist_output
61
- return tracklist_output, download_content
 
 
 
 
 
 
 
62
 
63
  css = """
64
  #col-container {
@@ -70,7 +143,7 @@ css = """
70
  with gr.Blocks(css=css) as demo:
71
  with gr.Column(elem_id="col-container"):
72
  gr.Markdown("# SoundCloud DJ Set Track Identifier")
73
-
74
  with gr.Row():
75
  track_url = gr.Text(
76
  label="SoundCloud DJ Set URL",
@@ -79,17 +152,13 @@ with gr.Blocks(css=css) as demo:
79
  placeholder="Enter SoundCloud DJ set URL",
80
  container=False,
81
  )
82
-
83
  run_button = gr.Button("Process", scale=0, variant="primary")
84
-
85
  result = gr.Textbox(label="Tracklist", show_label=False)
86
-
87
  with gr.Accordion("Download Tracklist", open=False):
88
  download_button = gr.File(label="Download")
89
-
90
  gr.Examples(examples=["https://soundcloud.com/your-track-url"], inputs=[track_url])
91
 
92
- run_button.click(process_dj_set, inputs=track_url, outputs=[result, download_button])
93
 
94
  if __name__ == "__main__":
95
  demo.launch()
 
4
  import shazamio
5
  import os
6
  import time
7
+ import tempfile
8
+ from pathlib import Path
9
+ import sys
10
+
11
  # Replace with your actual client ID and client secret
12
  client_id = os.environ.get('SOUNDCLOUD_CLIENT_ID')
13
  client_secret = os.environ.get('SOUNDCLOUD_CLIENT_SECRET')
14
+ token = os.environ.get('TOKEN')
15
 
16
+ def get_soundcloud_access_token(client_id, client_secret):
17
+ try:
18
+ auth_string = f'{client_id}:{client_secret}'
19
+ auth_headers = {
20
+ 'Authorization': 'Basic ' + base64.b64encode(auth_string.encode()).decode()
21
+ }
22
+ data = {
23
+ 'grant_type': 'client_credentials'
 
 
 
 
 
 
 
24
  }
25
+ response = requests.post('https://api.soundcloud.com/oauth2/token', headers=auth_headers, data=data)
26
+ if response.status_code == 200:
27
+ token_data = response.json()
28
+ return token_data['access_token']
29
+ else:
30
+ raise Exception(f"Failed to obtain access token: {response.text}")
31
+ except Exception as e:
32
+ return f"Error obtaining access token: {str(e)}"
33
+
34
+ def download_audio(streaming_url, output_path, headers):
35
+ try:
36
+ response = requests.get(streaming_url, headers=headers, stream=True)
37
+ with open(output_path, 'wb') as f:
38
+ for chunk in response.iter_content(chunk_size=8192):
39
+ f.write(chunk)
40
+ except Exception as e:
41
+ raise Exception(f"Error downloading audio: {str(e)}")
42
+
43
+ async def identify_track(shazam, audio_chunk, temp_dir):
44
+ try:
45
+ temp_file = os.path.join(temp_dir, 'temp_chunk.wav')
46
+ audio_chunk.export(temp_file, format='wav')
47
+ result = await shazam.recognize_file(temp_file)
48
+ if result and 'track' in result:
49
+ track_data = result['track']
50
+ return {
51
+ 'title': track_data['title'],
52
+ 'subtitle': track_data['subtitle']
53
+ }
54
+ else:
55
+ return None
56
+ except Exception as e:
57
+ return f"Error identifying track: {str(e)}"
58
 
59
  async def process_dj_set(track_url, progress=gr.Progress()):
60
+ temp_dir = tempfile.mkdtemp()
61
+ output_path = os.path.join(temp_dir, 'track.wav')
62
+ tracklist_path = os.path.join(temp_dir, 'tracklist.txt')
63
+ status_messages = []
64
+
65
+ # Get access token
66
+ access_token = get_soundcloud_access_token(client_id, client_secret)
67
+ if isinstance(access_token, str) and access_token.startswith("Error"):
68
+ return "", "", access_token
69
+
70
  headers = {
71
+ 'Authorization': f'Bearer {access_token}'
72
  }
73
+
74
+ # Resolve track URL
75
+ try:
76
+ resolve_response = requests.get(f'https://api.soundcloud.com/resolve.json?url={track_url}', headers=headers)
77
+ if resolve_response.status_code != 200:
78
+ return "", "", f"Failed to resolve track URL: {resolve_response.text}"
79
+ track_data = resolve_response.json()
80
+ streaming_url = track_data['stream_url']
81
+ status_messages.append("Track URL resolved successfully.")
82
+ except Exception as e:
83
+ return "", "", f"Error resolving track URL: {str(e)}"
84
+
85
+ # Download audio
86
+ try:
87
+ download_audio(streaming_url, output_path, headers)
88
+ status_messages.append("Audio downloaded successfully.")
89
+ except Exception as e:
90
+ return "", "", f"Error downloading audio: {str(e)}"
91
+
92
+ # Load audio
93
+ try:
94
+ audio = AudioSegment.from_wav(output_path)
95
+ status_messages.append("Audio loaded successfully.")
96
+ except Exception as e:
97
+ return "", "", f"Error loading audio: {str(e)}"
98
+
99
+ # Split audio into chunks
100
  chunk_duration = 30000 # 30 seconds
101
  overlap = 10000 # 10 seconds
102
  chunks = []
 
106
  chunk = audio[start:end]
107
  chunks.append((start, chunk))
108
  start += chunk_duration - overlap
109
+
110
+ # Initialize Shazam
111
  shazam = shazamio.Shazam()
112
+
113
+ # Identify tracks
114
  tracklist = []
115
  for start_time, chunk in chunks:
116
  progress(0.1)
117
+ track_info = await identify_track(shazam, chunk, temp_dir)
118
+ if isinstance(track_info, dict):
119
  timestamp = time.strftime("%M:%S", time.gmtime(start_time / 1000))
120
  tracklist.append(f"{timestamp} - {track_info['title']} by {track_info['subtitle']}")
121
+ elif isinstance(track_info, str):
122
+ status_messages.append(track_info)
123
+
124
+ # Prepare tracklist output
125
  tracklist_output = "\n".join(tracklist)
126
+ with open(tracklist_path, 'w') as f:
127
+ f.write(tracklist_output)
128
+
129
+ # Prepare status message
130
+ status_message = "\n".join(status_messages)
131
+ if not tracklist:
132
+ status_message += "\nNo tracks identified."
133
+
134
+ return tracklist_output, tracklist_path, status_message
135
 
136
  css = """
137
  #col-container {
 
143
  with gr.Blocks(css=css) as demo:
144
  with gr.Column(elem_id="col-container"):
145
  gr.Markdown("# SoundCloud DJ Set Track Identifier")
146
+ status_text = gr.Markdown(elem_id="status_text")
147
  with gr.Row():
148
  track_url = gr.Text(
149
  label="SoundCloud DJ Set URL",
 
152
  placeholder="Enter SoundCloud DJ set URL",
153
  container=False,
154
  )
 
155
  run_button = gr.Button("Process", scale=0, variant="primary")
 
156
  result = gr.Textbox(label="Tracklist", show_label=False)
 
157
  with gr.Accordion("Download Tracklist", open=False):
158
  download_button = gr.File(label="Download")
 
159
  gr.Examples(examples=["https://soundcloud.com/your-track-url"], inputs=[track_url])
160
 
161
+ run_button.click(process_dj_set, inputs=track_url, outputs=[result, download_button, status_text])
162
 
163
  if __name__ == "__main__":
164
  demo.launch()