zhangyong 6 meses atrás
pai
commit
8af2ba5e63
2 arquivos alterados com 51 adições e 106 exclusões
  1. 30 103
      analyze_video.py
  2. 21 3
      google_ai/generativeai_video.py

+ 30 - 103
analyze_video.py

@@ -1,70 +1,48 @@
 import asyncio
 import uvicorn
-from datetime import datetime, timedelta
 from fastapi import FastAPI
 from pydantic import BaseModel
-import random
-
 from google_ai.generativeai_video import main
 
 app = FastAPI()
-
-# 初始化 API key 列表,每个 key 包含 '错误计数' 和 '锁定直到' 时间
 api_keys = [
-    {'key': 'AIzaSyDs4FWRuwrEnQzu1M_Skio6NII6Mp4whAw', 'locked': False, 'locked_until': None, 'error_count': 0},
-    {'key': 'AIzaSyC-IxUvJhbiKWA7uN1RTtVbOjt3pj_-Apc', 'locked': False, 'locked_until': None, 'error_count': 0},
-    {'key': 'AIzaSyB43Pvugb-CMkEXJUSubXEAxKxYflCPPNU', 'locked': False, 'locked_until': None, 'error_count': 0},
-    {'key': 'AIzaSyAYgOeHS2NUlVuVe14rgNDaxXRNRt4smuY', 'locked': False, 'locked_until': None, 'error_count': 0},
-    {'key': 'AIzaSyAa4H7YzIOiqA0QIDuO6kNErFBoWT-BEtc', 'locked': False, 'locked_until': None, 'error_count': 0},
-    {'key': 'AIzaSyAUvBSpjFcm7b8FsgRUTG6anzoalDp9gYg', 'locked': False, 'locked_until': None, 'error_count': 0},
-    {'key': 'AIzaSyB43Pvugb-CMkEXJUSubXEAxKxYflCPPNU', 'locked': False, 'locked_until': None, 'error_count': 0}
+    {'key': 'AIzaSyDs4FWRuwrEnQzu1M_Skio6NII6Mp4whAw', 'locked': False},
+    {'key': 'AIzaSyC-IxUvJhbiKWA7uN1RTtVbOjt3pj_-Apc', 'locked': False},
+    {'key': 'AIzaSyB43Pvugb-CMkEXJUSubXEAxKxYflCPPNU', 'locked': False},
+    {'key': 'AIzaSyAYgOeHS2NUlVuVe14rgNDaxXRNRt4smuY', 'locked': False},
+    {'key': 'AIzaSyAa4H7YzIOiqA0QIDuO6kNErFBoWT-BEtc', 'locked': False},
+    {'key': 'AIzaSyAUvBSpjFcm7b8FsgRUTG6anzoalDp9gYg', 'locked': False},
+    {'key': 'AIzaSyB43Pvugb-CMkEXJUSubXEAxKxYflCPPNU', 'locked': False}
 ]
-
 lock = asyncio.Lock()
 
+
 class VideoRequest(BaseModel):
     video_path: str
 
+
 async def get_available_api_key():
-    """获取一个未锁定且没有过期的 API key,如果没有可用的则随机解锁一个"""
+    """获取一个未锁定的 API key,如果没有可用的则等待 60 秒后重试"""
     while True:
         async with lock:
-            now = datetime.now()
-            available_key = None
             for key_data in api_keys:
-                if not key_data['locked'] and (key_data['locked_until'] is None or key_data['locked_until'] <= now):
-                    available_key = key_data['key']
-                    key_data['locked'] = True
-                    break
+                if not key_data['locked']:
+                    key_data['locked'] = True  # 锁定该 key
+                    return key_data['key']
+        print("没有可用的 API key,等待 60 秒后重试...")
+        await asyncio.sleep(60)
 
-            if available_key:
-                return available_key
-            else:
-                # 所有 key 都被锁定,随机解锁一个,并重置错误计数
-                print("所有 API key 都被锁定,随机解锁一个并重置错误计数...")
-                random_key_data = random.choice(api_keys)
-                random_key_data['locked'] = False
-                random_key_data['locked_until'] = None  # 解除时间锁定
-                random_key_data['error_count'] = 0  # 清空错误计数
-                random_key_data['locked'] = True
-                return random_key_data['key']
 
-async def release_api_key(api_key, lock_until=None, reset_error_count=False):
-    """释放已锁定的 API key,支持设置锁定时间并重置错误计数"""
+async def release_api_key(api_key):
+    """释放已锁定的 API key,并将其放到列表末尾"""
     async with lock:
-        for key_data in api_keys:
+        for i, key_data in enumerate(api_keys):
             if key_data['key'] == api_key:
-                key_data['locked'] = False
-                key_data['locked_until'] = lock_until  # 设置锁定时间
-                if reset_error_count:
-                    key_data['error_count'] = 0  # 重置错误计数
+                key_data['locked'] = False  # 释放该 key
+                # 将释放的 key 移动到列表末尾
+                api_keys.append(api_keys.pop(i))
                 break
 
-def get_next_midnight():
-    """计算下一天的 0 点"""
-    now = datetime.now()
-    next_midnight = (now + timedelta(days=1)).replace(hour=1, minute=0, second=0, microsecond=0)
-    return next_midnight
 
 @app.post("/process_video/")
 async def process_video(request: VideoRequest):
@@ -72,72 +50,19 @@ async def process_video(request: VideoRequest):
     video_path = request.video_path
 
     # 获取一个可用的 API key
-    api_key = await get_available_api_key()
-
+    # api_key = await get_available_api_key()
+    api_key = "AIzaSyCor0q5w37Dy6fGxloLlCT7KqyEFU3PWP8"
     try:
-        print(f"来一个请求,使用 API key: {api_key}")
+        print("来一个请求,使用 API key:", api_key)
         result, mark = await main(video_path, api_key)
-        if "too many values to unpack" in result:
-            async with lock:
-                for key_data in api_keys:
-                    if key_data['key'] == api_key:
-                        key_data['error_count'] += 1
-                        print( f"API key {api_key} 的错误计数增加到 {key_data['error_count']}" )
-
-                        # 如果错误计数达到 5 次,锁定该 key 到第二天 00:00
-                        if key_data['error_count'] >= 5:
-                            lock_until = get_next_midnight()
-                            print( f"API key {api_key} 连续返回错误 5 次,锁定至 {lock_until}" )
-                            await release_api_key( api_key, lock_until )
-                        else:
-                            await release_api_key( api_key )
-                        break
-
-            return {
-                "code": 0,
-                "message": "视频处理失败: too many values to unpack",
-                "result": result,
-                "mark": mark
-            }
-        else:
-            # 视频处理成功,重置错误计数
-            await release_api_key( api_key, reset_error_count=True )
-            return {
-                "code": 0,
-                "message": "视频处理成功",
-                "result": result,
-                "mark": mark
-            }
-
-    except ValueError as e:
-        error_message = str(e)
-        if "too many values to unpack" in error_message:
-            # 增加该 key 的错误计数
-            async with lock:
-                for key_data in api_keys:
-                    if key_data['key'] == api_key:
-                        key_data['error_count'] += 1
-                        print(f"API key {api_key} 的错误计数增加到 {key_data['error_count']}")
-
-                        # 如果错误计数达到 10 次,锁定该 key 到第二天 0 点
-                        if key_data['error_count'] >= 10:
-                            lock_until = get_next_midnight()
-                            print(f"API key {api_key} 连续返回错误 5 次,锁定至 {lock_until}")
-                            await release_api_key(api_key, lock_until)
-                        else:
-                            await release_api_key(api_key)
-                        break
-        else:
-            await release_api_key(api_key)
         return {
-            "code": 1,
-            "message": f"视频处理失败: {e}",
-            "result": f"视频处理失败: {e}",
-            "mark": f"视频处理失败: {e}"
+            "code": 0,
+            "message": "视频处理成功",
+            "result": result,
+            "mark": mark
         }
     except Exception as e:
         print(f"视频处理失败: {str(e)}")
-        await release_api_key(api_key)
         return {
             "code": 1,
             "message": f"视频处理失败: {e}",
@@ -145,7 +70,9 @@ async def process_video(request: VideoRequest):
             "mark": f"视频处理失败: {e}"
         }
     finally:
+        # 释放 API key,确保后续请求可以使用
         await release_api_key(api_key)
 
+
 if __name__ == "__main__":
     uvicorn.run(app, host="0.0.0.0", port=8080)

+ 21 - 3
google_ai/generativeai_video.py

@@ -1,6 +1,6 @@
 import asyncio
 import os
-
+import cv2
 import aiohttp
 import requests
 import google.generativeai as genai
@@ -92,17 +92,30 @@ class VideoAnalyzer:
             response = chat_session.send_message( message_content )
             return response
 
+    def video_duration(self, filename):
+        cap = cv2.VideoCapture( filename )
+        if cap.isOpened():
+            rate = cap.get( 5 )
+            frame_num = cap.get( 7 )
+            duration = frame_num / rate
+            return int(duration)
+        return 0
+
 async def main(video_path, api_key):
     """主函数,执行视频上传、缓存创建、问题生成"""
     # api_key = 'AIzaSyAa4H7YzIOiqA0QIDuO6kNErFBoWT-BEtc'
+
     mark, prompt = Material.feishu_list()
     attempt = 0
     max_attempts = 1
     while attempt < max_attempts:
-
         try:
             # 初始化视频分析类
             analyzer = VideoAnalyzer(api_key )
+            duration = analyzer.video_duration( video_path )
+            print( f"视频时长为{duration}秒" )
+            if int( duration ) >= 600 or int( duration ) == 0:
+                return f"视频时长过长为/视频数为:{duration}秒"
             save_path = await analyzer.download_video(video_path)
             if not save_path:
                 if os.path.exists( save_path ):
@@ -172,4 +185,9 @@ if __name__ == "__main__":
     os.environ["https_proxy"] = proxy_url
     # video_path = 'http://temp.yishihui.com/longvideo/transcode/video/vpc/20240926/66510681PACx7zsp2wDBHJlicE.mp4'
     video_path = 'http://temp.yishihui.com/longvideo/transcode/video/vpc/20240605/68754804SJz5E9JNe5hAdSkRwF.mp4'
-    asyncio.run(main(video_path))
+    api_key = "AIzaSyCor0q5w37Dy6fGxloLlCT7KqyEFU3PWP8"
+
+    asyncio.run(main(video_path,api_key))
+
+
+