NeoPy commited on
Commit
6e9813d
·
verified ·
1 Parent(s): 8b0f313

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +62 -159
app.py CHANGED
@@ -1,202 +1,105 @@
1
  import gradio as gr
2
  import requests
3
  from bs4 import BeautifulSoup
4
- import re
5
  import os
 
6
  import tempfile
7
- from urllib.parse import urlparse
 
 
 
 
8
 
9
- def get_audio_url(url):
10
- """Extract audio URL from soundgasm.net page"""
11
  try:
12
  response = requests.get(url)
13
- response.raise_for_status()
 
 
 
 
 
 
 
 
 
 
 
14
  soup = BeautifulSoup(response.text, 'html.parser')
15
-
16
- # Try to find the audio source from the <audio> tag directly
17
- audio_tag = soup.find('audio', {'id': 'jp_audio_0'})
18
  if audio_tag and 'src' in audio_tag.attrs:
19
- return audio_tag['src']
 
 
20
 
21
- # If not found, try to extract from the JavaScript part
22
- script_tags = soup.find_all('script')
23
- for script in script_tags:
24
- if script.string:
25
- match = re.search(r'm4a: "(https://media.soundgasm.net/sounds/[a-f0-9]+\.m4a)"', script.string)
26
- if match:
27
- return match.group(1)
28
- return None
29
- except Exception as e:
30
- print(f"Error extracting audio URL: {e}")
31
- return None
32
 
33
- def get_audio_title(url):
34
- """Extract audio title from soundgasm.net page"""
35
- try:
36
- response = requests.get(url)
37
- response.raise_for_status()
38
- soup = BeautifulSoup(response.text, 'html.parser')
39
-
40
- title_element = soup.find('div', class_='jp-title')
41
- if title_element:
42
- return title_element.get_text(strip=True)
43
- return "Unknown Title"
44
- except Exception as e:
45
- print(f"Error extracting title: {e}")
46
- return "Unknown Title"
47
 
48
- def download_audio(url, progress=gr.Progress()):
49
- """Download audio from soundgasm.net URL"""
50
  if not url:
51
- return None, "Please enter a valid soundgasm.net URL"
52
 
53
  if "soundgasm.net" not in url:
54
  return None, "Please enter a valid soundgasm.net URL"
55
 
56
- progress(0.1, desc="Extracting audio URL...")
57
-
58
- # Get audio URL
59
- audio_url = get_audio_url(url)
60
- if not audio_url:
61
- return None, "Could not find audio URL on the page. Please check if the URL is correct."
62
-
63
- progress(0.3, desc="Getting audio title...")
64
-
65
- # Get audio title for filename
66
- title = get_audio_title(url)
67
- safe_title = re.sub(r'[^\w\s-]', '', title).strip()
68
- safe_title = re.sub(r'[-\s]+', '-', safe_title)
69
-
70
- progress(0.5, desc="Downloading audio...")
71
-
72
- try:
73
- # Download the audio file
74
- response = requests.get(audio_url, stream=True)
75
- response.raise_for_status()
76
-
77
- # Create temporary file
78
- temp_dir = tempfile.gettempdir()
79
- filename = f"{safe_title}.m4a"
80
- filepath = os.path.join(temp_dir, filename)
81
-
82
- total_size = int(response.headers.get('content-length', 0))
83
- downloaded = 0
84
-
85
- with open(filepath, 'wb') as f:
86
- for chunk in response.iter_content(chunk_size=8192):
87
- if chunk:
88
- f.write(chunk)
89
- downloaded += len(chunk)
90
- if total_size > 0:
91
- progress_val = 0.5 + (downloaded / total_size) * 0.4
92
- progress(progress_val, desc=f"Downloading... {downloaded}/{total_size} bytes")
93
-
94
- progress(1.0, desc="Download complete!")
95
-
96
- return filepath, f"Successfully downloaded: {title}"
97
-
98
- except Exception as e:
99
- return None, f"Error downloading audio: {str(e)}"
100
-
101
- def validate_url(url):
102
- """Validate if the URL is a valid soundgasm.net URL"""
103
- if not url:
104
- return "Please enter a URL"
105
-
106
- if "soundgasm.net" not in url:
107
- return "Please enter a valid soundgasm.net URL"
108
-
109
- try:
110
- parsed = urlparse(url)
111
- if not parsed.scheme or not parsed.netloc:
112
- return "Please enter a valid URL with http:// or https://"
113
- except:
114
- return "Invalid URL format"
115
 
116
- return ""
 
 
 
117
 
118
- # Create Gradio interface
119
  with gr.Blocks(title="Soundgasm Audio Downloader", theme=gr.themes.Soft()) as demo:
120
- gr.Markdown(
121
- """
122
- # 🎵 Soundgasm Audio Downloader
123
-
124
- Download audio files from soundgasm.net links using only requests and BeautifulSoup4.
125
-
126
- **Instructions:**
127
- 1. Paste a soundgasm.net audio URL in the input field
128
- 2. Click "Download Audio" to start the download
129
- 3. The audio file will be available for download once processing is complete
130
-
131
- **Supported URLs:** `https://soundgasm.net/u/username/audio-title`
132
- """
133
- )
134
 
135
  with gr.Row():
136
- with gr.Column(scale=3):
137
  url_input = gr.Textbox(
138
  label="Soundgasm URL",
139
  placeholder="https://soundgasm.net/u/username/audio-title",
140
  lines=1
141
  )
 
142
 
143
- url_validation = gr.Textbox(
144
- label="URL Validation",
 
145
  interactive=False,
146
- visible=False
147
  )
148
-
149
- with gr.Column(scale=1):
150
- download_btn = gr.Button("Download Audio", variant="primary", size="lg")
151
-
152
- with gr.Row():
153
- status_output = gr.Textbox(
154
- label="Status",
155
- interactive=False,
156
- lines=2
157
- )
158
 
159
  with gr.Row():
160
- file_output = gr.File(
161
- label="Downloaded Audio File",
162
- file_count="single",
163
- file_types=[".m4a", ".mp3", ".wav"]
164
  )
165
 
166
  # Event handlers
167
- url_input.change(
168
- fn=validate_url,
169
- inputs=[url_input],
170
- outputs=[url_validation]
171
- )
172
-
173
  download_btn.click(
174
- fn=download_audio,
175
  inputs=[url_input],
176
- outputs=[file_output, status_output],
177
- show_progress=True
178
  )
179
 
180
- # Example URLs
181
- gr.Markdown(
182
- """
183
- ### Example URLs:
184
- - `https://soundgasm.net/u/aasimaraudio/Let-Me-Help-You-Relieve-Your-Work-Related-Stress-Will-Ya`
185
- - `https://soundgasm.net/u/username/audio-title`
186
-
187
- ### Features:
188
- - ✅ Extract audio URLs using requests and BeautifulSoup4
189
- - ✅ Download audio files in original quality
190
- - ✅ Automatic filename generation from audio title
191
- - ✅ Progress tracking during download
192
- - ✅ Error handling and validation
193
-
194
- ### Technical Details:
195
- - Uses only `requests` and `bs4` libraries as requested
196
- - Extracts audio URLs from HTML and JavaScript content
197
- - Supports m4a audio format (soundgasm's default format)
198
- - No external dependencies beyond the specified libraries
199
- """
200
  )
201
 
202
  if __name__ == "__main__":
 
1
  import gradio as gr
2
  import requests
3
  from bs4 import BeautifulSoup
 
4
  import os
5
+ import re
6
  import tempfile
7
+ import shutil
8
+
9
+ def download_soundgasm_audio(url, output_dir='downloaded_audio'):
10
+ if not os.path.exists(output_dir):
11
+ os.makedirs(output_dir)
12
 
 
 
13
  try:
14
  response = requests.get(url)
15
+ response.raise_for_status() # Raise an exception for HTTP errors
16
+ except requests.exceptions.RequestException as e:
17
+ return None, f'Error fetching URL: {e}'
18
+
19
+ # Try to find the audio source directly in the HTML using regex
20
+ match = re.search(r'(https?://media\.soundgasm\.net/sounds/[^\"]+\.m4a)', response.text)
21
+ audio_url = None
22
+ if match:
23
+ audio_url = match.group(1)
24
+
25
+ if not audio_url:
26
+ # Fallback to BeautifulSoup if regex fails
27
  soup = BeautifulSoup(response.text, 'html.parser')
28
+ audio_tag = soup.find('audio')
 
 
29
  if audio_tag and 'src' in audio_tag.attrs:
30
+ audio_url = audio_tag['src']
31
+ if not audio_url.startswith('http'):
32
+ audio_url = f"https://soundgasm.net{audio_url}"
33
 
34
+ if audio_url:
35
+ try:
36
+ audio_response = requests.get(audio_url, stream=True)
37
+ audio_response.raise_for_status()
38
+ except requests.exceptions.RequestException as e:
39
+ return None, f'Error fetching audio file: {e}'
 
 
 
 
 
40
 
41
+ file_name = os.path.join(output_dir, os.path.basename(audio_url).split('?')[0])
42
+ with open(file_name, 'wb') as f:
43
+ for chunk in audio_response.iter_content(chunk_size=8192):
44
+ f.write(chunk)
45
+ return file_name, f'Audio downloaded successfully!'
46
+ else:
47
+ return None, 'No audio source found on the page.'
 
 
 
 
 
 
 
48
 
49
+ def process_soundgasm_url(url):
 
50
  if not url:
51
+ return None, "Please enter a soundgasm.net URL"
52
 
53
  if "soundgasm.net" not in url:
54
  return None, "Please enter a valid soundgasm.net URL"
55
 
56
+ audio_file, message = download_soundgasm_audio(url)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
 
58
+ if audio_file:
59
+ return audio_file, message
60
+ else:
61
+ return None, message
62
 
63
+ # Create Gradio interface using Blocks
64
  with gr.Blocks(title="Soundgasm Audio Downloader", theme=gr.themes.Soft()) as demo:
65
+ gr.Markdown("# Soundgasm Audio Downloader")
66
+ gr.Markdown("Enter a soundgasm.net link to download and play the audio file.")
 
 
 
 
 
 
 
 
 
 
 
 
67
 
68
  with gr.Row():
69
+ with gr.Column():
70
  url_input = gr.Textbox(
71
  label="Soundgasm URL",
72
  placeholder="https://soundgasm.net/u/username/audio-title",
73
  lines=1
74
  )
75
+ download_btn = gr.Button("Download Audio", variant="primary")
76
 
77
+ with gr.Column():
78
+ status_output = gr.Textbox(
79
+ label="Status",
80
  interactive=False,
81
+ lines=2
82
  )
 
 
 
 
 
 
 
 
 
 
83
 
84
  with gr.Row():
85
+ audio_output = gr.Audio(
86
+ label="Downloaded Audio",
87
+ type="filepath",
88
+ interactive=False
89
  )
90
 
91
  # Event handlers
 
 
 
 
 
 
92
  download_btn.click(
93
+ fn=process_soundgasm_url,
94
  inputs=[url_input],
95
+ outputs=[audio_output, status_output]
 
96
  )
97
 
98
+ # Also allow Enter key to trigger download
99
+ url_input.submit(
100
+ fn=process_soundgasm_url,
101
+ inputs=[url_input],
102
+ outputs=[audio_output, status_output]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103
  )
104
 
105
  if __name__ == "__main__":