generativeai_video.py 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. import asyncio
  2. import os
  3. import cv2
  4. import aiohttp
  5. import requests
  6. import google.generativeai as genai
  7. import uuid
  8. from common.feishu_data import Material
  9. class VideoAnalyzer:
  10. def __init__(self, api_key):
  11. """初始化类,配置 API 密钥和视频路径"""
  12. genai.configure(api_key=api_key)
  13. self.video_file = None
  14. async def process_and_delete_file(self, file_path):
  15. """删除文件"""
  16. try:
  17. print(f"正在处理文件: {file_path}" )
  18. os.remove( file_path )
  19. print( f"文件已删除: {file_path}" )
  20. except Exception as e:
  21. print( f"处理或删除文件时发生错误: {str( e )}" )
  22. async def download_video(self, video_url, save_directory='/root/google_ai_studio/path'):
  23. # async def download_video(self, video_url, save_directory='/Users/tzld/Desktop/google_ai_studio/path'):
  24. """从给定的视频链接下载视频并保存到指定路径"""
  25. try:
  26. # 发送 GET 请求获取视频内容
  27. random_filename = f"{uuid.uuid4()}.mp4"
  28. save_path = os.path.join(save_directory, random_filename)
  29. async with aiohttp.ClientSession() as session:
  30. async with session.get( video_url ) as response:
  31. response.raise_for_status() # 检查请求是否成功
  32. with open( save_path, 'wb' ) as video_file:
  33. while True:
  34. chunk = await response.content.read( 1024 * 1024 ) # 每次读取 1MB
  35. if not chunk:
  36. break
  37. video_file.write( chunk )
  38. print( f"视频已成功下载并保存到: {save_path}" )
  39. return save_path
  40. except requests.exceptions.RequestException as e:
  41. print( f"下载视频时出现错误: {e}" )
  42. return None
  43. async def upload_video(self, save_path, mime_type = None):
  44. """上传视频文件并获取视频文件对象"""
  45. self.video_file = genai.upload_file(save_path, mime_type=mime_type)
  46. await self._wait_for_processing()
  47. async def _wait_for_processing(self):
  48. """等待视频文件处理完成"""
  49. while self.video_file.state.name == 'PROCESSING':
  50. print( '等待视频处理完成...' )
  51. await asyncio.sleep(2) # 使用异步睡眠代替阻塞睡眠
  52. self.video_file = genai.get_file( self.video_file.name )
  53. print( f'视频处理完成: {self.video_file.uri}' )
  54. async def create_cache(self):
  55. generation_config = {
  56. "temperature": 1,
  57. "top_p": 0.95,
  58. "top_k": 64,
  59. "max_output_tokens": 8192,
  60. "response_mime_type": "application/json"
  61. }
  62. """创建缓存内容,并返回生成模型"""
  63. # 创建生成模型,使用 gemini-1.5-flash 模型
  64. model = genai.GenerativeModel(
  65. model_name="gemini-1.5-flash",
  66. generation_config=generation_config,
  67. )
  68. return model
  69. async def analyze_video(self, model, questions, sample_data):
  70. chat_session = model.start_chat(history=[])
  71. message_content = {
  72. "parts": [
  73. self.video_file,
  74. str(questions) +
  75. "输出返回格式样例:\n" + str(sample_data)
  76. ]
  77. }
  78. response = chat_session.send_message( message_content )
  79. self.video_file.delete()
  80. return response
  81. def video_duration(self, filename):
  82. cap = cv2.VideoCapture( filename )
  83. if cap.isOpened():
  84. rate = cap.get( 5 )
  85. frame_num = cap.get( 7 )
  86. duration = frame_num / rate
  87. return int(duration)
  88. return 0
  89. async def main(video_path, api_key, prompt, mark):
  90. """主函数,执行视频上传、缓存创建、问题生成"""
  91. attempt = 0
  92. max_attempts = 1
  93. while attempt < max_attempts:
  94. try:
  95. # 初始化视频分析类
  96. analyzer = VideoAnalyzer(api_key )
  97. for file in genai.list_files():
  98. # file.delete()
  99. print( " ", file.name )
  100. duration = analyzer.video_duration( video_path )
  101. print( f"视频时长为{duration}秒" )
  102. if int( duration ) >= 600 or int( duration ) == 0:
  103. return f"视频时长过长/视频时长为:{duration}秒"
  104. save_path = await analyzer.download_video(video_path)
  105. if not save_path:
  106. if os.path.exists( save_path ):
  107. os.remove( save_path )
  108. print( f"文件已删除: {save_path}" )
  109. print("视频下载失败")
  110. return "视频下载失败"
  111. # 上传并处理视频
  112. await analyzer.upload_video(save_path)
  113. # 创建缓存模型
  114. model =await analyzer.create_cache()
  115. sample_data = {
  116. "一、基础信息": {
  117. "视觉/音乐/文字": "",
  118. "内容选题": "",
  119. "视频主题": ""
  120. },
  121. "二、主体和场景": {
  122. "视频主体": "",
  123. "视频场景": []
  124. },
  125. "三、情感与风格": {},
  126. "四、视频传播性与观众": {
  127. "片尾引导": {},
  128. "传播性判断": "",
  129. "观众画像": {}
  130. },
  131. "五、音画细节": {
  132. "音频细节": {},
  133. "视频水印": {},
  134. "视频字幕": {},
  135. "视频口播": ""
  136. },
  137. "六、人物与场景": {
  138. "知名人物": {},
  139. "人物年龄段": "",
  140. "场景描述": []
  141. },
  142. "七、时效性与分类": {
  143. "时效性": {},
  144. "视频一级分类": "",
  145. "二级分类": ["品类- 、分数-", "品类- 、分数-", "品类- 、分数-"]
  146. }
  147. }
  148. response =await analyzer.analyze_video( model, prompt, sample_data )
  149. print( response.usage_metadata )
  150. print(response.text)
  151. if os.path.exists( save_path ):
  152. os.remove( save_path )
  153. print( f"文件已删除: {save_path}" )
  154. return response.text, mark
  155. except Exception as e:
  156. attempt += 1 # 增加尝试次数
  157. if attempt < max_attempts:
  158. print(f"重试第 {attempt} 次...")
  159. else:
  160. print( "达到最大重试次数,处理失败" )
  161. return f"视频分析处理失败:{e}"
  162. if __name__ == "__main__":
  163. proxy_url = 'http://127.0.0.1:1081'
  164. os.environ["http_proxy"] = proxy_url
  165. os.environ["https_proxy"] = proxy_url
  166. # video_path = 'http://temp.yishihui.com/longvideo/transcode/video/vpc/20240926/66510681PACx7zsp2wDBHJlicE.mp4'
  167. video_path = 'http://temp.yishihui.com/longvideo/transcode/video/vpc/20240605/68754804SJz5E9JNe5hAdSkRwF.mp4'
  168. api_key = "AIzaSyCor0q5w37Dy6fGxloLlCT7KqyEFU3PWP8"
  169. asyncio.run(main(video_path,api_key))