Edmond7 commited on
Commit
ae3f337
·
verified ·
1 Parent(s): 05d64bd

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +67 -60
app.py CHANGED
@@ -24,7 +24,11 @@ API_KEY_NAME = "X-API-Key"
24
  api_key_header = APIKeyHeader(name=API_KEY_NAME, auto_error=False)
25
 
26
  # Constants
27
- INVIDIOUS_INSTANCE = "https://iv.melmac.space"
 
 
 
 
28
  API_KEY = os.environ.get("API_KEY")
29
 
30
  # S3 Configuration
@@ -45,72 +49,75 @@ def get_random_user_agent() -> str:
45
  return random.choice(user_agents)
46
 
47
  async def search_and_get_videos(query: str) -> List[Dict]:
48
- url = f"{INVIDIOUS_INSTANCE}/api/v1/search?q={query}&type=video"
49
- try:
50
- async with aiohttp.ClientSession() as session:
51
- async with session.get(url, headers={"User-Agent": get_random_user_agent()}) as response:
52
- response.raise_for_status()
53
- search_results = await response.json()
54
- videos = [
55
- {
56
- "id": video.get("videoId"),
57
- "title": video.get("title"),
58
- "thumbnail": video["videoThumbnails"][0]["url"]
59
- if video.get("videoThumbnails")
60
- else "",
61
- }
62
- for video in search_results
63
- ][:2]
64
- return videos
65
- except aiohttp.ClientError as e:
66
- logger.error(f"Error performing video search: {e}")
67
- return []
68
-
69
- async def get_youtube_audio(video_id: str, max_retries: int = 3) -> Dict:
70
- for attempt in range(max_retries):
71
  try:
72
- url = f"{INVIDIOUS_INSTANCE}/api/v1/videos/{video_id}"
73
-
74
  async with aiohttp.ClientSession() as session:
75
- async with session.get(url) as response:
76
  response.raise_for_status()
77
- video_data = await response.json()
78
-
79
- audio_format = next((format for format in video_data.get('adaptiveFormats', [])
80
- if format.get('type', '').startswith('audio/mp4')), None)
81
-
82
- if audio_format:
83
- audio_url = audio_format.get('url')
84
- if audio_url:
85
- try:
86
- async with session.get(audio_url) as audio_response:
87
- audio_content = await audio_response.read()
88
-
89
- with tempfile.NamedTemporaryFile(delete=False, suffix='.m4a') as temp_file:
90
- temp_file.write(audio_content)
91
- temp_file_path = temp_file.name
92
-
93
- return {'success': True, 'temp_file_path': temp_file_path}
94
- except aiohttp.ServerDisconnectedError:
95
- if attempt == max_retries - 1:
96
- logger.error(f"Max retries reached for video ID {video_id}")
97
- return {'success': False, 'error': "Max retries reached"}
98
- await asyncio.sleep(1 * (attempt + 1))
99
- continue
100
-
101
- logger.warning(f"No suitable audio format found for video ID {video_id}")
102
- return {'success': False, 'error': "No suitable audio format found"}
103
  except aiohttp.ClientError as e:
104
- logger.error(f"Network error fetching YouTube audio for video ID {video_id}: {e}")
105
- except json.JSONDecodeError:
106
- logger.error(f"Error decoding JSON response for video ID {video_id}")
107
- except Exception as e:
108
- logger.error(f"Unexpected error fetching YouTube audio for video ID {video_id}: {e}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
  if attempt == max_retries - 1:
110
- return {'success': False, 'error': str(e)}
111
  await asyncio.sleep(1 * (attempt + 1))
112
 
113
- return {'success': False, 'error': "Failed to fetch audio after multiple attempts"}
114
 
115
  def extract_text_from_document(file: UploadFile) -> dict:
116
  try:
 
24
  api_key_header = APIKeyHeader(name=API_KEY_NAME, auto_error=False)
25
 
26
  # Constants
27
+ INVIDIOUS_INSTANCES = [
28
+ "https://invidious.privacydev.net",
29
+ "https://invidious.reallyaweso.me",
30
+ "https://invidious.adminforge.de"
31
+ ]
32
  API_KEY = os.environ.get("API_KEY")
33
 
34
  # S3 Configuration
 
49
  return random.choice(user_agents)
50
 
51
  async def search_and_get_videos(query: str) -> List[Dict]:
52
+ for instance in INVIDIOUS_INSTANCES:
53
+ url = f"{instance}/api/v1/search?q={query}&type=video"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
  try:
 
 
55
  async with aiohttp.ClientSession() as session:
56
+ async with session.get(url, headers={"User-Agent": get_random_user_agent()}) as response:
57
  response.raise_for_status()
58
+ search_results = await response.json()
59
+ videos = [
60
+ {
61
+ "id": video.get("videoId"),
62
+ "title": video.get("title"),
63
+ "thumbnail": video["videoThumbnails"][0]["url"]
64
+ if video.get("videoThumbnails")
65
+ else "",
66
+ }
67
+ for video in search_results
68
+ ][:2]
69
+ return videos
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
  except aiohttp.ClientError as e:
71
+ logger.error(f"Error performing video search on {instance}: {e}")
72
+ logger.error("All Invidious instances failed")
73
+ return []
74
+
75
+ async def get_youtube_audio(video_id: str, max_retries: int = 3) -> Dict:
76
+ for instance in INVIDIOUS_INSTANCES:
77
+ for attempt in range(max_retries):
78
+ try:
79
+ url = f"{instance}/api/v1/videos/{video_id}"
80
+
81
+ async with aiohttp.ClientSession() as session:
82
+ async with session.get(url) as response:
83
+ response.raise_for_status()
84
+ video_data = await response.json()
85
+
86
+ audio_format = next((format for format in video_data.get('adaptiveFormats', [])
87
+ if format.get('type', '').startswith('audio/mp4')), None)
88
+
89
+ if audio_format:
90
+ audio_url = audio_format.get('url')
91
+ if audio_url:
92
+ try:
93
+ async with session.get(audio_url) as audio_response:
94
+ audio_content = await audio_response.read()
95
+
96
+ with tempfile.NamedTemporaryFile(delete=False, suffix='.m4a') as temp_file:
97
+ temp_file.write(audio_content)
98
+ temp_file_path = temp_file.name
99
+
100
+ return {'success': True, 'temp_file_path': temp_file_path}
101
+ except aiohttp.ServerDisconnectedError:
102
+ if attempt == max_retries - 1:
103
+ logger.error(f"Max retries reached for video ID {video_id} on {instance}")
104
+ break
105
+ await asyncio.sleep(1 * (attempt + 1))
106
+ continue
107
+
108
+ logger.warning(f"No suitable audio format found for video ID {video_id} on {instance}")
109
+ break
110
+ except aiohttp.ClientError as e:
111
+ logger.error(f"Network error fetching YouTube audio for video ID {video_id} on {instance}: {e}")
112
+ except json.JSONDecodeError:
113
+ logger.error(f"Error decoding JSON response for video ID {video_id} on {instance}")
114
+ except Exception as e:
115
+ logger.error(f"Unexpected error fetching YouTube audio for video ID {video_id} on {instance}: {e}")
116
  if attempt == max_retries - 1:
117
+ break
118
  await asyncio.sleep(1 * (attempt + 1))
119
 
120
+ return {'success': False, 'error': "Failed to fetch audio after multiple attempts on all instances"}
121
 
122
  def extract_text_from_document(file: UploadFile) -> dict:
123
  try: