tecuts commited on
Commit
8d69ef7
·
verified ·
1 Parent(s): f11df80

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +68 -27
app.py CHANGED
@@ -117,56 +117,97 @@ def main():
117
  async def get_info(
118
  request: Request,
119
  url: str,
120
- quality: Union[str, None] = None,
121
- playlist: bool = True
122
  ):
123
- # Get client IP
 
 
 
124
  client_ip = get_client_ip(request)
125
-
126
- # Check rate limit
127
  is_allowed, remaining = check_rate_limit(client_ip)
128
 
129
  if not is_allowed:
130
  raise HTTPException(
131
  status_code=status.HTTP_429_TOO_MANY_REQUESTS,
132
  detail=f"Daily limit of {DAILY_LIMIT} requests exceeded. Try again tomorrow.",
133
- headers={
134
- "X-RateLimit-Limit": str(DAILY_LIMIT),
135
- "X-RateLimit-Remaining": "0",
136
- "X-RateLimit-Reset": str(int(time.time()) + 86400),
137
- "Cache-Control": "no-store, max-age=0"
138
- }
139
  )
140
 
 
 
 
 
 
 
 
 
141
  ydl_options = {
142
- "retries": 3,
143
- "encoding": "utf8",
144
- "noplaylist": not playlist,
145
- "dump_single_json": True,
146
- "format": "bestvideo+bestaudio/best",
147
- "ignoreerrors": True,
148
- "extract_flat": playlist,
149
- "cachedir": "/tmp/yt-dlp-cache"
150
  }
151
 
152
- with YoutubeDL(ydl_options) as ytdl:
153
  try:
154
- response = ytdl.extract_info(url, download=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155
  return JSONResponse(
156
- response,
157
  headers={
158
  "Cache-Control": "s-maxage=2592000, stale-while-revalidate",
159
  "X-RateLimit-Limit": str(DAILY_LIMIT),
160
- "X-RateLimit-Remaining": str(remaining),
161
- "X-RateLimit-Reset": str(int(time.time()) + 86400)
162
  }
163
  )
 
164
  except Exception as e:
165
- print(e)
 
 
 
166
  raise HTTPException(
167
  status_code=status.HTTP_400_BAD_REQUEST,
168
- detail=repr(e),
169
- headers={"Cache-Control": "no-store, max-age=0"},
170
  )
171
 
172
  @app.get("/api/playlist")
 
117
  async def get_info(
118
  request: Request,
119
  url: str,
120
+ quality: str = "1080",
121
+ audio_only: bool = False # <-- Added audio toggle
122
  ):
123
+ """
124
+ Resolves a video or audio URL and returns a simplified JSON payload.
125
+ Auto-detects SoundCloud to prevent video-filter errors.
126
+ """
127
  client_ip = get_client_ip(request)
 
 
128
  is_allowed, remaining = check_rate_limit(client_ip)
129
 
130
  if not is_allowed:
131
  raise HTTPException(
132
  status_code=status.HTTP_429_TOO_MANY_REQUESTS,
133
  detail=f"Daily limit of {DAILY_LIMIT} requests exceeded. Try again tomorrow.",
134
+ headers={"X-RateLimit-Reset": str(int(time.time()) + 86400)}
 
 
 
 
 
135
  )
136
 
137
+ # --- SMART FORMAT SELECTION ---
138
+ # Auto-detect SoundCloud, or check if the client explicitly wants audio
139
+ if "soundcloud.com" in url or audio_only:
140
+ format_selector = "bestaudio/best"
141
+ else:
142
+ # Your custom H.264 first, AV1 second video logic
143
+ format_selector = f"best[height<={quality}][vcodec^=avc][ext=mp4]/best[height<={quality}][vcodec^=av01][ext=mp4]/best[height<={quality}][ext=mp4]/bestvideo[height<={quality}]+bestaudio/best"
144
+
145
  ydl_options = {
146
+ "format": format_selector,
147
+ "quiet": True,
148
+ "no_warnings": True,
149
+ "skip_download": True,
150
+ "noplaylist": True,
151
+ "cachedir": "/tmp/yt-dlp-cache",
152
+ "js-runtimes": "node"
 
153
  }
154
 
155
+ with YoutubeDL(ydl_options) as ydl:
156
  try:
157
+ info = ydl.extract_info(url, download=False)
158
+
159
+ download_url = info.get("url")
160
+ http_headers = info.get("http_headers", {})
161
+
162
+ # Fallback for split formats (bestvideo+bestaudio)
163
+ if not download_url and info.get("requested_formats"):
164
+ # If audio_only is True, requested_formats[0] might be audio.
165
+ # If video, requested_formats[0] is video, [1] is audio.
166
+ # We grab the first one to ensure we get a valid URL.
167
+ fmt = info["requested_formats"][0]
168
+ download_url = fmt.get("url")
169
+ http_headers = fmt.get("http_headers", http_headers)
170
+
171
+ if not download_url:
172
+ raise HTTPException(
173
+ status_code=400,
174
+ detail="ダウンロードURLを取得できませんでした",
175
+ headers={"Cache-Control": "no-store, max-age=0"}
176
+ )
177
+
178
+ title = info.get("title", "audio" if audio_only else "video")
179
+ ext = info.get("ext", "mp3" if audio_only else "mp4")
180
+ filename = f"{title}.{ext}"
181
+ filesize = info.get("filesize") or info.get("filesize_approx")
182
+
183
+ response_data = {
184
+ "status": "ok",
185
+ "url": download_url,
186
+ "title": title,
187
+ "filename": filename,
188
+ "ext": ext,
189
+ "filesize": filesize,
190
+ "headers": http_headers,
191
+ }
192
+
193
  return JSONResponse(
194
+ response_data,
195
  headers={
196
  "Cache-Control": "s-maxage=2592000, stale-while-revalidate",
197
  "X-RateLimit-Limit": str(DAILY_LIMIT),
198
+ "X-RateLimit-Remaining": str(remaining)
 
199
  }
200
  )
201
+
202
  except Exception as e:
203
+ error_msg = str(e)
204
+ if "DownloadError" in str(type(e)):
205
+ error_msg = f"メディアの取得に失敗: {error_msg}" # Changed 'video' to 'media' in JP
206
+
207
  raise HTTPException(
208
  status_code=status.HTTP_400_BAD_REQUEST,
209
+ detail=error_msg,
210
+ headers={"Cache-Control": "no-store, max-age=0"}
211
  )
212
 
213
  @app.get("/api/playlist")