generativeai_video.py 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. import asyncio
  2. import os
  3. import aiohttp
  4. import requests
  5. import google.generativeai as genai
  6. import uuid
  7. class VideoAnalyzer:
  8. def __init__(self, api_key):
  9. """初始化类,配置 API 密钥和视频路径"""
  10. genai.configure(api_key=api_key)
  11. self.video_file = None
  12. async def process_and_delete_file(self, file_path):
  13. """删除文件"""
  14. try:
  15. print(f"正在处理文件: {file_path}" )
  16. os.remove( file_path )
  17. print( f"文件已删除: {file_path}" )
  18. except Exception as e:
  19. print( f"处理或删除文件时发生错误: {str( e )}" )
  20. async def download_video(self, video_url, save_directory='/root/google_ai_studio/path'):
  21. # async def download_video(self, video_url, save_directory='/Users/tzld/Desktop/google_ai_studio/path'):
  22. """从给定的视频链接下载视频并保存到指定路径"""
  23. try:
  24. # 发送 GET 请求获取视频内容
  25. random_filename = f"{uuid.uuid4()}.mp4"
  26. save_path = os.path.join(save_directory, random_filename)
  27. async with aiohttp.ClientSession() as session:
  28. async with session.get( video_url ) as response:
  29. response.raise_for_status() # 检查请求是否成功
  30. with open( save_path, 'wb' ) as video_file:
  31. while True:
  32. chunk = await response.content.read( 1024 * 1024 ) # 每次读取 1MB
  33. if not chunk:
  34. break
  35. video_file.write( chunk )
  36. print( f"视频已成功下载并保存到: {save_path}" )
  37. return save_path
  38. except requests.exceptions.RequestException as e:
  39. print( f"下载视频时出现错误: {e}" )
  40. return None
  41. async def upload_video(self, save_path, mime_type = None):
  42. """上传视频文件并获取视频文件对象"""
  43. self.video_file = genai.upload_file(save_path, mime_type=mime_type)
  44. await self._wait_for_processing()
  45. async def _wait_for_processing(self):
  46. """等待视频文件处理完成"""
  47. while self.video_file.state.name == 'PROCESSING':
  48. print( '等待视频处理完成...' )
  49. await asyncio.sleep(2) # 使用异步睡眠代替阻塞睡眠
  50. self.video_file = genai.get_file( self.video_file.name )
  51. print( f'视频处理完成: {self.video_file.uri}' )
  52. async def create_cache(self):
  53. generation_config = {
  54. "temperature": 1,
  55. "top_p": 0.95,
  56. "top_k": 64,
  57. "max_output_tokens": 8192,
  58. "response_mime_type": "application/json"
  59. }
  60. """创建缓存内容,并返回生成模型"""
  61. # 创建生成模型,使用 gemini-1.5-flash 模型
  62. model = genai.GenerativeModel(
  63. model_name="gemini-1.5-flash",
  64. generation_config=generation_config,
  65. )
  66. return model
  67. async def analyze_video(self, model, questions, sample_data):
  68. chat_session = model.start_chat(
  69. history=[
  70. ]
  71. )
  72. message_content = {
  73. "parts": [
  74. self.video_file,
  75. "你是一个专业的视频分析师,负责根据访问的视频文件回答用户的所有问题\\n"+questions +
  76. "输出返回格式样例:\n"+ str(sample_data)
  77. ]
  78. }
  79. response = chat_session.send_message( message_content )
  80. return response
  81. async def main(video_path):
  82. """主函数,执行视频上传、缓存创建、问题生成"""
  83. # video_path = '/root/3333.mp4'
  84. api_key = 'AIzaSyDs4FWRuwrEnQzu1M_Skio6NII6Mp4whAw'
  85. # 初始化视频分析类
  86. analyzer = VideoAnalyzer(api_key )
  87. save_path = await analyzer.download_video(video_path)
  88. if not save_path:
  89. if os.path.exists( save_path ):
  90. os.remove( save_path )
  91. print( f"文件已删除: {save_path}" )
  92. print("视频下载失败")
  93. # 上传并处理视频
  94. await analyzer.upload_video(save_path)
  95. # 创建缓存模型
  96. model =await analyzer.create_cache()
  97. sample_data = {
  98. "基础信息": {
  99. "视觉/音乐/文字": "",
  100. "内容选题": "",
  101. "视频主题": ""
  102. },
  103. "主体和场景": {
  104. "视频主体": "",
  105. "视频场景": []
  106. },
  107. "情感与风格": {},
  108. "视频传播性与观众": {
  109. "片尾引导": {},
  110. "传播性判断": "",
  111. "观众画像": {}
  112. },
  113. "音画细节": {
  114. "音频细节": {},
  115. "视频水印": {},
  116. "视频字幕": {},
  117. "视频口播": ""
  118. },
  119. "人物与场景": {
  120. "知名人物": {},
  121. "人物年龄段": "",
  122. "场景描述": []
  123. },
  124. "时效性与分类": {
  125. "时效性": {},
  126. "视频一级分类": "",
  127. "二级分类": ""
  128. }
  129. }
  130. # 视频分析问题
  131. video_analysis_questions = "一、基础信息:\n" \
  132. "1.视觉/音乐/文字: 请从视频中的视觉、音乐、文字这三个维度信息做分析比较,哪个维度的信息是该视频中最重要的,可能成为该视频的要点驱动力?你只要回答 视觉/音乐/文字 三者其一即可。\n" \
  133. "2.内容选题: 如果需要从视频中提取一个内容选题,你觉得应该是什么?请注意:选题应该体现视频的关键点,亮点,爆点,选题不能超过8个字。\n" \
  134. "3.视频主题:描述视频的整体主题。\n " \
  135. "二、主体和场景:\n" \
  136. "1.视频主体:视频中的核心人物或物体,有几个?分别是什么?\n" \
  137. "2.视频场景:视频属于什么场景?场景可以有多个,每个不超过6个字\n" \
  138. "三、情感与风格:\n" \
  139. "1.情感倾向:视频传递的情感是积极、消极还是中立或其他?\n" \
  140. "2.视频风格:判断视频的风格类型(如严肃、轻松、幽默等)。\n四、视频传播性与观众:\n" \
  141. "1.片尾引导\n" \
  142. "视频片尾是否有引导观众分享?\n" \
  143. "引导时长?\n" \
  144. "引导强度如何?\n" \
  145. "2.传播性判断:基于中国中老年微信用户,判断该视频的传播性并说明依据。\n" \
  146. "3.观众画像:\n" \
  147. "推测观众的年龄\n" \
  148. "推测观众的性别\n" \
  149. "推测观众的地域\n" \
  150. "五、音画细节:\n" \
  151. "1.音频细节\n" \
  152. "视频中的音频信息,是否有歌曲?\n" \
  153. "视频中的音频信息,歌曲名是什么?\n" \
  154. "视频中的音色音色是怎样的?\n" \
  155. "2.视频水印\n" \
  156. "是否有产品名的水印?\n" \
  157. "水印是否涉及产品名称是什么?\n" \
  158. "3.视频字幕\n" \
  159. "是否有字幕?\n" \
  160. "字幕的颜色?\n" \
  161. "字幕的字号?\n" \
  162. "字幕的位置如何?\n" \
  163. "4. 视频口播:提供视频中出现的准确且完整的口播内容。\n" \
  164. "六、人物与场景:\n" \
  165. "1.知名人物\n" \
  166. "视频或音频中是否出现知名人物?\n" \
  167. "视频或音频中是否出现知名人物是谁?\n" \
  168. "2.人物年龄段:视频中人物的年龄段(如中青年男、中青年女等)。\n" \
  169. "3.场景描述:视频和声音中涉及的场景描述。\n" \
  170. "七、时效性与分类:\n" \
  171. "1.时效性:\n" \
  172. "适用时效日\n" \
  173. "适用时效早中晚\n" \
  174. "2.视频一级分类:判断视频分别属于下面的哪种一级分类,并输出准确完整的一级品类_分类名称:\n" \
  175. "一级分类范围为:\n" \
  176. "一级品类_音乐\n" \
  177. "一级品类_剧情 / 剧情演绎\n" \
  178. "一级品类_二次元\n" \
  179. "一级品类_游戏\n" \
  180. "一级品类_公益\n" \
  181. "一级品类_随拍 / 颜值\n" \
  182. "一级品类_舞蹈\n" \
  183. "一级品类_动物 / 萌宠\n" \
  184. "一级品类_三农\n" \
  185. "一级品类_科技 / 科技数码\n" \
  186. "一级品类_财经\n" \
  187. "一级品类_母婴 / 母婴亲子\n" \
  188. "一级品类_法律 / 人文社科\n" \
  189. "一级品类_科普 / 人文社科\n" \
  190. "一级品类_情感 / 情感心理\n" \
  191. "一级品类_职场 / 人文社科\n" \
  192. "一级品类_教育 / 教育培训\n" \
  193. "一级品类_摄影摄像\n" \
  194. "一级品类_艺术 / 才艺技能\n" \
  195. "一级品类_美食\n" \
  196. "一级品类_旅行 / 旅游\n" \
  197. "一级品类_地域本地\n" \
  198. "一级品类_时尚 / 时尚 / 美妆\n" \
  199. "一级品类_文化 / 人文社科\n" \
  200. "一级品类_搞笑 / 休闲娱乐\n" \
  201. "一级品类_明星 / 名人\n" \
  202. "一级品类_综艺\n" \
  203. "一级品类_影视综艺\n" \
  204. "一级品类_电影\n" \
  205. "一级品类_影视综艺\n" \
  206. "一级品类_电视剧\n" \
  207. "一级品类_影视综艺\n" \
  208. "一级品类_汽车\n" \
  209. "一级品类_体育 / 运动\n" \
  210. "一级品类_医疗健康 / 长寿 / 健身\n" \
  211. "一级品类_生活记录 / 生活\n" \
  212. "一级品类_生活家居 / 家居家装\n" \
  213. "一级品类_时政社会\n" \
  214. "一级品类_奇人异象\n" \
  215. "一级品类_历史\n" \
  216. "一级品类_军事\n" \
  217. "一级品类_宗教\n" \
  218. "一级品类_短剧\n" \
  219. "一级品类_收藏品\n" \
  220. "3.二级分类: 判断视频分别属于下面的哪种二级分类,并输出准确完整的品类-分类名称\n" \
  221. "二级分类范围为:\n" \
  222. "品类-祝福音乐\n" \
  223. "品类-人生感悟音乐\n" \
  224. "品类-民族异域音乐\n" \
  225. "品类-亲情音乐\n" \
  226. "品类-红歌老歌\n" \
  227. "品类-音乐知识\n" \
  228. "品类-正能量剧情\n" \
  229. "品类-对口型表演\n" \
  230. "品类-快闪\n" \
  231. "品类-拟真游戏\n" \
  232. "品类-麻将\n" \
  233. "品类-棋牌\n" \
  234. "品类-老年审美美女\n" \
  235. "品类-老年审美帅哥\n" \
  236. "品类-红歌老歌舞蹈\n" \
  237. "品类-广场舞\n" \
  238. "品类-舞蹈教程\n" \
  239. "品类-宠物日常\n" \
  240. "品类-动物表演\n" \
  241. "品类-生动物\n" \
  242. "品类-农村生活\n" \
  243. "品类-农业技术\n" \
  244. "品类-老年相关科技\n" \
  245. "品类-未来科幻\n" \
  246. "品类-国家科技力量\n" \
  247. "品类-保险\n" \
  248. "品类-理财\n" \
  249. "品类-亲子日常\n" \
  250. "品类-K12教育\n" \
  251. "品类-老年相关法律科普\n" \
  252. "品类-知识科普\n" \
  253. "品类-生活技巧科普\n" \
  254. "品类-怀念时光\n" \
  255. "品类-人生忠告\n" \
  256. "品类-迷信祝福\n" \
  257. "品类-节日祝福\n" \
  258. "品类-早中晚好\n" \
  259. "品类-退休前\n" \
  260. "品类-退休后\n" \
  261. "品类-益智解密\n" \
  262. "品类-老年教育\n" \
  263. "品类-风景实拍\n" \
  264. "品类-动植物实拍\n" \
  265. "品类-人像模特实拍\n" \
  266. "品类-摄影教学\n" \
  267. "品类-名画赏析\n" \
  268. "品类-杂技柔术\n" \
  269. "品类-魔术\n" \
  270. "品类-魔术特效\n" \
  271. "品类-书法\n" \
  272. "品类-绘画\n" \
  273. "品类-木工\n" \
  274. "品类-口技\n" \
  275. "品类-大型集体艺术\n" \
  276. "品类-戏曲戏剧\n" \
  277. "品类-二人转\n" \
  278. "品类-其他才艺\n" \
  279. "品类-美食测评\n" \
  280. "品类-美食教程\n" \
  281. "品类-吃播探店\n" \
  282. "品类-旅行记录\n" \
  283. "品类-旅行攻略\n" \
  284. "品类-省份城市亮点\n" \
  285. "品类-本地新闻\n" \
  286. "品类-本地生活\n" \
  287. "品类-老年时尚\n" \
  288. "品类-美妆护肤穿搭\n" \
  289. "品类-传统文化\n" \
  290. "品类-国际文化\n" \
  291. "品类-搞笑瞬间合集\n" \
  292. "品类-搞笑段子\n" \
  293. "品类-历史名人\n" \
  294. "品类-当代正能量人物\n" \
  295. "品类-老明星\n" \
  296. "品类-老年人上综艺\n" \
  297. "品类-老年关心纪录片\n" \
  298. "品类-老综艺影像\n" \
  299. "品类-电影切片\n" \
  300. "品类-电影解说\n" \
  301. "品类-电视剧切片\n" \
  302. "品类-电视剧解说\n" \
  303. "品类-中国队比赛\n" \
  304. "品类-老年运动\n" \
  305. "品类-健康知识\n" \
  306. "品类-长寿知识\n" \
  307. "品类-饮食健康\n" \
  308. "品类-健身操\n" \
  309. "品类-老年生活\n" \
  310. "品类-生活小妙招\n" \
  311. "品类-园艺花艺\n" \
  312. "品类-民生政策\n" \
  313. "品类-流行病疫情\n" \
  314. "品类-社会风气\n" \
  315. "品类-食品安全\n" \
  316. "品类-贪污腐败\n" \
  317. "品类-人财诈骗\n" \
  318. "品类-核污染\n" \
  319. "品类-惠民新闻\n" \
  320. "品类-天气变化\n" \
  321. "品类-国家力量\n" \
  322. "品类-国际时政\n" \
  323. "品类-他国政策\n" \
  324. "品类-惊奇事件\n" \
  325. "品类-罕见画面\n" \
  326. "品类-中国战争史\n" \
  327. "品类-中国党史\n" \
  328. "品类-中国历史影像\n" \
  329. "品类-国际军事\n" \
  330. "品类-国内军事\n" \
  331. "品类-国家统一\n" \
  332. # 分析视频并打印结果
  333. response =await analyzer.analyze_video( model, video_analysis_questions, sample_data )
  334. print( response.usage_metadata )
  335. print(response.text)
  336. if os.path.exists( save_path ):
  337. os.remove( save_path )
  338. print( f"文件已删除: {save_path}" )
  339. return response.text
  340. if __name__ == "__main__":
  341. proxy_url = 'http://127.0.0.1:1081'
  342. os.environ["http_proxy"] = proxy_url
  343. os.environ["https_proxy"] = proxy_url
  344. # video_path = 'http://temp.yishihui.com/longvideo/transcode/video/vpc/20240926/66510681PACx7zsp2wDBHJlicE.mp4'
  345. video_path = 'http://temp.yishihui.com/jq_oss/video/2024092618393680952.mp4'
  346. asyncio.run(main(video_path))