tecuts commited on
Commit
229ee72
·
verified ·
1 Parent(s): 457238a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +115 -13
app.py CHANGED
@@ -7,6 +7,8 @@ from datetime import datetime, timedelta
7
  import time
8
  import asyncio
9
  import cloudscraper
 
 
10
 
11
  app = Flask(__name__)
12
  ytmusic = YTMusic()
@@ -29,11 +31,106 @@ def search():
29
  @app.route('/searcht', methods=['POST'])
30
  def searcht():
31
  query = request.json.get('query', '')
 
32
  search_results = ytmusic.search(query, filter="songs")
33
  first_song = next((song for song in search_results if 'videoId' in song and song['videoId']), {}) if search_results else {}
34
  return jsonify(first_song)
35
 
36
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  class ApiRotator:
38
  def __init__(self, apis):
39
  self.apis = apis
@@ -56,16 +153,16 @@ class ApiRotator:
56
  # In your function:
57
  api_rotator = ApiRotator([
58
  "https://cobalt-api.ayo.tf",
 
59
  "http://34.107.254.11",
60
  "https://dwnld.nichind.dev",
61
- "https://cobalt-api.kwiatekmiki.com",
62
  "https://yt.edd1e.xyz/"
63
 
64
  ])
65
 
66
 
67
 
68
- async def get_track_download_url(track_id: str) -> str:
69
  apis = api_rotator.get_prioritized_apis()
70
  session = cloudscraper.create_scraper() # Requires cloudscraper package
71
  headers = {
@@ -81,7 +178,7 @@ async def get_track_download_url(track_id: str) -> str:
81
  response = session.post(
82
  api_url,
83
  timeout=20,
84
- json={"url": y_url, "audioFormat": "mp3", "downloadMode": "audio"},
85
  headers=headers
86
  )
87
  logger.info(f"Response status: {response.status_code}")
@@ -110,16 +207,21 @@ async def get_track_download_url(track_id: str) -> str:
110
 
111
 
112
  @app.route('/track_dl', methods=['POST'])
113
- async def track_dl():
114
- track_id = request.json.get('track_id')
115
- dl_url = await get_track_download_url(track_id)
116
- if dl_url and "http" in dl_url:
117
- result = {"url": dl_url}
118
- return jsonify(result)
119
- else:
120
- return {
121
- "error": "Failed to Fetch the Track."
122
- }
 
 
 
 
 
123
 
124
 
125
 
 
7
  import time
8
  import asyncio
9
  import cloudscraper
10
+ from pydantic import BaseModel
11
+ from urllib.parse import urlparse, parse_qs
12
 
13
  app = Flask(__name__)
14
  ytmusic = YTMusic()
 
31
  @app.route('/searcht', methods=['POST'])
32
  def searcht():
33
  query = request.json.get('query', '')
34
+ logger.info(f"serch query: {query}")
35
  search_results = ytmusic.search(query, filter="songs")
36
  first_song = next((song for song in search_results if 'videoId' in song and song['videoId']), {}) if search_results else {}
37
  return jsonify(first_song)
38
 
39
 
40
+ # Function to extract track ID from Amazon Music URL
41
+ def extract_amazon_track_id(url: str):
42
+ if "music.amazon.com" in url:
43
+ # Case 1: URL contains trackAsin (e.g., https://music.amazon.com/albums/B01N48U32A?trackAsin=B01NAE38YO&do=play)
44
+ parsed_url = urlparse(url)
45
+ query_params = parse_qs(parsed_url.query)
46
+ if "trackAsin" in query_params:
47
+ return query_params["trackAsin"][0]
48
+
49
+ # Case 2: URL is a direct track link (e.g., https://music.amazon.com/tracks/B0DNTPYT5S)
50
+ if "/tracks/" in url:
51
+ return url.split("/tracks/")[-1].split("?")[0]
52
+
53
+ return None
54
+
55
+
56
+ # Function to get track info from Song.link API
57
+ def get_song_link_info(url: str):
58
+ # Check if the URL is from Amazon Music
59
+ if "music.amazon.com" in url:
60
+ track_id = extract_amazon_track_id(url)
61
+ if track_id:
62
+ # Use the working format for Amazon Music tracks
63
+ api_url = f"https://api.song.link/v1-alpha.1/links?type=song&platform=amazonMusic&id={track_id}&userCountry=US"
64
+ else:
65
+ # If no track ID is found, use the original URL
66
+ api_url = f"https://api.song.link/v1-alpha.1/links?url={url}&userCountry=US"
67
+ else:
68
+ # For non-Amazon Music URLs, use the standard format
69
+ api_url = f"https://api.song.link/v1-alpha.1/links?url={url}&userCountry=US"
70
+
71
+ # Make the API call
72
+ response = requests.get(api_url)
73
+ if response.status_code == 200:
74
+ return response.json()
75
+ else:
76
+ return None
77
+
78
+ # Function to extract Tidal or YouTube URL
79
+ def extract_url(links_by_platform: dict, platform: str):
80
+ if platform in links_by_platform:
81
+ return links_by_platform[platform]["url"]
82
+ return None
83
+
84
+
85
+ # Function to extract track title and artist from entities
86
+ def extract_track_info(entities_by_unique_id: dict, platform: str):
87
+ for entity in entities_by_unique_id.values():
88
+ if entity["apiProvider"] == platform:
89
+ return entity["title"], entity["artistName"]
90
+ return None, None
91
+
92
+
93
+
94
+ @app.route('/match', methods=['POST'])
95
+ async def match():
96
+ data = request.json
97
+ track_url = data.get('url')
98
+
99
+ if not track_url:
100
+ raise HTTPException(status_code=400, detail="No URL provided")
101
+
102
+ track_info = get_song_link_info(track_url)
103
+ if not track_info:
104
+ raise HTTPException(status_code=404, detail="Could not fetch track info")
105
+
106
+ youtube_url = extract_url(track_info["linksByPlatform"], "youtube")
107
+ if youtube_url:
108
+ title, artist = extract_track_info(track_info["entitiesByUniqueId"], "youtube")
109
+ if title and artist:
110
+ filename = f"{title} - {artist}"
111
+ return {"url": youtube_url, "filename": filename}
112
+ else:
113
+ return {"url": youtube_url, "filename": "Unknown Track - Unknown Artist"}
114
+ else:
115
+ entityUniqueId = track_info["entityUniqueId"]
116
+ logger.info(f"songlink info: {entityUniqueId}")
117
+ title = track_info["entitiesByUniqueId"][entityUniqueId]["title"]
118
+ artist = track_info["entitiesByUniqueId"][entityUniqueId]["artistName"]
119
+ search_query = f'{title}+{artist}'
120
+ search_results = ytmusic.search(search_query, filter="songs")
121
+ first_song = next((song for song in search_results if 'videoId' in song and song['videoId']), {}) if search_results else {}
122
+ if 'videoId' in first_song:
123
+ videoId = first_song["videoId"]
124
+ ym_url = f'https://www.youtube.com/watch?v={videoId}'
125
+ return {"filename": title, "url": ym_url}
126
+ else:
127
+ raise HTTPException(status_code=404, detail="Video ID not found")
128
+
129
+ # If no URLs found, return an error
130
+ raise HTTPException(status_code=404, detail="No matching URL found")
131
+
132
+
133
+
134
  class ApiRotator:
135
  def __init__(self, apis):
136
  self.apis = apis
 
153
  # In your function:
154
  api_rotator = ApiRotator([
155
  "https://cobalt-api.ayo.tf",
156
+ "https://cobalt-api.kwiatekmiki.com",
157
  "http://34.107.254.11",
158
  "https://dwnld.nichind.dev",
 
159
  "https://yt.edd1e.xyz/"
160
 
161
  ])
162
 
163
 
164
 
165
+ async def get_track_download_url(track_id: str, quality: str) -> str:
166
  apis = api_rotator.get_prioritized_apis()
167
  session = cloudscraper.create_scraper() # Requires cloudscraper package
168
  headers = {
 
178
  response = session.post(
179
  api_url,
180
  timeout=20,
181
+ json={"url": y_url, "audioFormat": "mp3", "downloadMode": "audio", "audioBitrate": quality},
182
  headers=headers
183
  )
184
  logger.info(f"Response status: {response.status_code}")
 
207
 
208
 
209
  @app.route('/track_dl', methods=['POST'])
210
+ async def track_dl(request: Request):
211
+ data = await request.json()
212
+ track_id = data.get('track_id')
213
+ quality = data.get('quality', '128')
214
+ try:
215
+ quality_num = int(quality)
216
+ if quality_num > 128 or quality.upper() == 'FLAC':
217
+ return {"error": "Quality above 128 or FLAC is for Premium Users Only."}
218
+ dl_url = await get_track_download_url(track_id, quality)
219
+ if dl_url and "http" in dl_url:
220
+ return {"url": dl_url}
221
+ else:
222
+ return {"error": "Failed to Fetch the Track."}
223
+ except ValueError:
224
+ return {"error": "Invalid quality value provided. It should be a valid integer or FLAC."}
225
 
226
 
227