开启左侧

如何用 Multi-Agent 自动运营抖音账号:从脚本到内容闭环

[复制链接]
在线会员 aZgrMu 发表于 前天 07:40 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题
现在,让咱们一一完毕那些智能体战组件。
情况拆修战依靠装置

起首,让咱们树立开辟情况并装置须要的依靠:
  1. # 起首,创立一个假造情况(举荐)# python -m venv douyin_agent_env# source douyin_agent_env/bin/activate  # Linux/Mac# .\douyin_agent_env\Scripts\activate  # Windows#装置 须要的包
  2. !pip install langchain openai python-dotenv moviepy pillow pandas matplotlib sqlite3 requests schedule
复造代码
交下来,创立一个 .env 文献去保存咱们的API稀钥战设置:
  1. OPENAI_API_KEY=your_openai_api_key_here
  2. DOUYIN_CLIENT_KEY=your_douyin_client_key_here
  3. DOUYIN_CLIENT_SECRET=your_douyin_client_secret_here
复造代码
根底组件完毕

起首,让咱们完毕一点儿根底组件,那些将被统统智能体使用。
影象体系(Memory System)

影象体系许可智能体记着已往的接互、决议计划战成果,那关于连结不合性战连续进修相当主要。
  1. from langchain.memory import ConversationBufferMemory, ConversationSu妹妹aryMemory
  2. from langchain.schema import BaseMessage
  3. import sqlite3
  4. from datetime import datetime
  5. import json
  6. from typing import List, Dict, Any
  7. classMemorySystem:def__init__(self, db_path:str="douyin_agent_memory.db"):
  8.         self.db_path = db_path
  9.         self._init_db()
  10.         self.conversation_memory = ConversationBufferMemory(return_messages=True)
  11.         self.su妹妹ary_memory = ConversationSu妹妹aryMemory(llm=None)# 咱们会正在使用时树立LLMdef_init_db(self):"""初初化数据库表"""
  12.         conn = sqlite3.connect(self.db_path)
  13.         cursor = conn.cursor()#创立 实质汗青表
  14.         cursor.execute('''
  15.         CREATE TABLE IF NOT EXISTS content_history (
  16.             id INTEGER PRIMARY KEY AUTOINCREMENT,
  17.             content_id TEXT UNIQUE,
  18.             content_type TEXT,
  19.             title TEXT,
  20.             description TEXT,
  21.             publish_date TIMESTAMP,
  22.             performance_data TEXT,
  23.             created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
  24.         )
  25.         ''')#创立 决议计划记载表
  26.         cursor.execute('''
  27.         CREATE TABLE IF NOT EXISTS decision_history (
  28.             id INTEGER PRIMARY KEY AUTOINCREMENT,
  29.             agent_name TEXT,
  30.             decision_type TEXT,
  31.             decision_content TEXT,
  32.             context TEXT,
  33.             outcome TEXT,
  34.             timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
  35.         )
  36.         ''')#创立 用户互动表
  37.         cursor.execute('''
  38.         CREATE TABLE IF NOT EXISTS user_interactions (
  39.             id INTEGER PRIMARY KEY AUTOINCREMENT,
  40.             interaction_type TEXT,
  41.             user_id TEXT,
  42.             content_id TEXT,
  43.             interaction_content TEXT,
  44.             response TEXT,
  45.             timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
  46.         )
  47.         ''')
  48.         
  49.         conn.co妹妹it()
  50.         conn.close()defadd_conversation_message(self, message: BaseMessage):"""增加对于话消息到影象"""
  51.         self.conversation_memory.chat_memory.add_message(message)defget_conversation_history(self)-> List[BaseMessage]:"""获得对于话汗青"""return self.conversation_memory.chat_memory.messages
  52.    
  53.     defrecord_content(self, content_id:str, content_type:str, title:str,
  54.                       description:str, publish_date: datetime =None,
  55.                       performance_data: Dict =None):"""记载实质公布疑息"""
  56.         conn = sqlite3.connect(self.db_path)
  57.         cursor = conn.cursor()try:
  58.             cursor.execute('''
  59.             INSERT OR REPLACE INTO content_history
  60.             (content_id, content_type, title, description, publish_date, performance_data)
  61.             VALUES (?, ?, ?, ?, ?, ?)
  62.             ''',(
  63.                 content_id,
  64.                 content_type,
  65.                 title,
  66.                 description,
  67.                 publish_date.isoformat()if publish_date elseNone,
  68.                 json.dumps(performance_data)if performance_data elseNone))
  69.             conn.co妹妹it()except Exception as e:print(f"Error recording content: {e}")finally:
  70.             conn.close()defrecord_decision(self, agent_name:str, decision_type:str,
  71.                        decision_content:str, context: Dict =None,
  72.                        outcome:str=None):"""记载智能体决议计划"""
  73.         conn = sqlite3.connect(self.db_path)
  74.         cursor = conn.cursor()try:
  75.             cursor.execute('''
  76.             INSERT INTO decision_history
  77.             (agent_name, decision_type, decision_content, context, outcome)
  78.             VALUES (?, ?, ?, ?, ?)
  79.             ''',(
  80.                 agent_name,
  81.                 decision_type,
  82.                 decision_content,
  83.                 json.dumps(context)if context elseNone,
  84.                 outcome
  85.             ))
  86.             conn.co妹妹it()except Exception as e:print(f"Error recording decision: {e}")finally:
  87.             conn.close()defrecord_user_interaction(self, interaction_type:str, user_id:str,
  88.                                content_id:str, interaction_content:str,
  89.                                response:str=None):"""记载用户互动"""
  90.         conn = sqlite3.connect(self.db_path)
  91.         cursor = conn.cursor()try:
  92.             cursor.execute('''
  93.             INSERT INTO user_interactions
  94.             (interaction_type, user_id, content_id, interaction_content, response)
  95.             VALUES (?, ?, ?, ?, ?)
  96.             ''',(
  97.                 interaction_type,
  98.                 user_id,
  99.                 content_id,
  100.                 interaction_content,
  101.                 response
  102.             ))
  103.             conn.co妹妹it()except Exception as e:print(f"Error recording user interaction: {e}")finally:
  104.             conn.close()defget_content_history(self, limit:int=10)-> List[Dict]:"""获得实质汗青"""
  105.         conn = sqlite3.connect(self.db_path)
  106.         cursor = conn.cursor()
  107.         
  108.         cursor.execute('''
  109.         SELECT content_id, content_type, title, description, publish_date, performance_data
  110.         FROM content_history
  111.         ORDER BY publish_date DESC
  112.         LIMIT ?
  113.         ''',(limit,))
  114.         
  115.         results = cursor.fetchall()
  116.         conn.close()
  117.         
  118.         content_list =[]for row in results:
  119.             content_list.append({'content_id': row[0],'content_type': row[1],'title': row[2],'description': row[3],'publish_date': row[4],'performance_data': json.loads(row[5])if row[5]elseNone})return content_list
  120.    
  121.     defget_top_performing_content(self, metric:str='view_count', limit:int=5)-> List[Dict]:"""获得表示最佳的实质"""
  122.         conn = sqlite3.connect(self.db_path)
  123.         cursor = conn.cursor()
  124.         
  125.         cursor.execute('''
  126.         SELECT content_id, content_type, title, description, publish_date, performance_data
  127.         FROM content_history
  128.         WHERE performance_data IS NOT NULL
  129.         ORDER BY publish_date DESC
  130.         LIMIT 100
  131.         ''')
  132.         
  133.         results = cursor.fetchall()
  134.         conn.close()# 剖析功用数据并排序
  135.         content_list =[]for row in results:
  136.             perf_data = json.loads(row[5])if row[5]else{}if metric in perf_data:
  137.                 content_list.append({'content_id': row[0],'content_type': row[1],'title': row[2],'description': row[3],'publish_date': row[4],'performance_data': perf_data,'metric_value': perf_data[metric]})# 按目标值排序
  138.         content_list.sort(key=lambda x: x['metric_value'], reverse=True)return content_list[:limit]
复造代码
东西库(Tool Library)

交下来,让咱们创立一个东西库,包罗各类智能体可以需要使用的东西:
  1. import requests
  2. import json
  3. from datetime import datetime, timedelta
  4. from typing import List, Dict, Any, Optional
  5. import os
  6. from dotenv import load_dotenv
  7. # 减载情况变质
  8. load_dotenv()classToolLibrary:def__init__(self):
  9.         self.douyin_api_base ="https://open.douyin.com"
  10.         self.douyin_client_key = os.getenv("DOUYIN_CLIENT_KEY")
  11.         self.douyin_client_secret = os.getenv("DOUYIN_CLIENT_SECRET")
  12.         self.access_token =None
  13.         self._refresh_access_token()def_refresh_access_token(self):"""革新抖音API会见令牌"""
  14.         url =f"{self.douyin_api_base}/oauth/client_token/"
  15.         params ={"client_key": self.douyin_client_key,"client_secret": self.douyin_client_secret,"grant_type":"client_credential"}try:
  16.             response = requests.get(url, params=params)
  17.             response.raise_for_status()
  18.             data = response.json()if data.get("data"):
  19.                 self.access_token = data["data"].get("access_token")print("Access token refreshed successfully")else:print(f"Failed to refresh access token: {data}")except Exception as e:print(f"Error refreshing access token: {e}")defget_trending_topics(self, category:str="general")-> List[Dict]:"""获得目前热门话题"""# 正在理论使用中,那里能够跟尾到抖音的热门API或者第三圆热门效劳# 那里咱们使用模仿数据动作示例
  20.         mock_trending_topics =[{"id":"1","title":"野生智能新突破","hot_value":9800000,"category":"科技"},{"id":"2","title":"安康饮食小揭士","hot_value":7500000,"category":"糊口"},{"id":"3","title":"旅游举荐天","hot_value":6200000,"category":"旅游"},{"id":"4","title":"职场妙技提拔","hot_value":5800000,"category":"教诲"},{"id":"5","title":"弄笑一样平常","hot_value":8900000,"category":"娱乐"}]if category !="general":return[topic for topic in mock_trending_topics if topic["category"]== category]return mock_trending_topics
  21.    
  22.     defsearch_content_ideas(self, keyword:str, limit:int=10)-> List[Dict]:"""搜刮实质创意"""# 正在理论使用中,那里能够跟尾到抖音的搜刮API或者第三圆实质阐发效劳# 那里咱们使用模仿数据动作示例
  23.         mock_ideas =[{"title":f"{keyword}的5个本领","type":"学程","potential":"下"},{"title":f"{keyword}罕见毛病","type":"纠错","potential":"中"},{"title":f"{keyword}VS 其余办法","type":"比照","potential":"下"},{"title":f"尔是怎样进修{keyword}的","type":"小我私家经历","potential":"中"},{"title":f"{keyword}的未来开展","type":"趋势阐发","potential":"中下"}]return mock_ideas[:limit]defget_account_data(self)-> Dict:"""获得账号数据"""# 正在理论使用中,那里该当挪用抖音API# 那里咱们使用模仿数据return{"fans_count":52000,"following_count":320,"total_likes":1200000,"total_views":45000000,"avg_views_per_video":150000,"avg_likes_per_video":4000,"avg_co妹妹ents_per_video":150,"avg_shares_per_video":80}defget_video_performance(self, video_id:str)-> Dict:"""获得望频表示数据"""# 正在理论使用中,那里该当挪用抖音API# 那里咱们使用模仿数据return{"video_id": video_id,"view_count":125000,"like_count":3200,"co妹妹ent_count":180,"share_count":95,"completion_rate":0.68,# 完播率"average_watch_time":12.5,#均匀 寓目时少(秒)"publish_time":(datetime.now()- timedelta(days=3)).isoformat(),"performance_trend":"increasing"# 表示趋势}defget_co妹妹ents(self, video_id:str, limit:int=50)-> List[Dict]:"""获得望频批评"""# 正在理论使用中,那里该当挪用抖音API# 那里咱们使用模仿数据
  24.         mock_co妹妹ents =[{"co妹妹ent_id":"1","user_id":"user1","content":"那个望频太有效了!","like_count":45,"timestamp":"2023-10-01T10:30:00"},{"co妹妹ent_id":"2","user_id":"user2","content":"叨教第两步如何干?","like_count":12,"timestamp":"2023-10-01T11:15:00"},{"co妹妹ent_id":"3","user_id":"user3","content":"已经珍藏,目前垂垂瞅","like_count":8,"timestamp":"2023-10-01T12:45:00"},{"co妹妹ent_id":"4","user_id":"user4","content":"没有附和您的概念,尔觉得...","like_count":23,"timestamp":"2023-10-01T14:20:00"},{"co妹妹ent_id":"5","user_id":"user5","content":"能不克不及出一期更具体的?","like_count":31,"timestamp":"2023-10-01T16:05:00"}]return mock_co妹妹ents[:limit]defreply_to_co妹妹ent(self, co妹妹ent_id:str, reply_content:str)->bool:"""复兴批评"""# 正在理论使用中,那里该当挪用抖音APIprint(f"Replying to co妹妹ent {co妹妹ent_id}: {reply_content}")returnTrue#假定 复兴胜利defupload_video(self, video_path:str, title:str, description:str,
  25.                    tags: List[str]=None, publish_time: datetime =None)-> Optional[str]:"""上传望频(并可选天按时公布)"""# 正在理论使用中,那里该当挪用抖音API上传望频print(f"Uploading video: {title}")print(f"Description: {description}")print(f"Tags: {tags}")#模仿 天生一个望频ID
  26.         video_id =f"video_{datetime.now().strftime('%Y%m%d%H%M%S')}"return video_id
  27.    
  28.     defschedule_video_publish(self, video_id:str, publish_time: datetime)->bool:"""摆设望频公布时间"""# 正在理论使用中,那里该当挪用抖音APIprint(f"Scheduling video {video_id} to be published at {publish_time}")returnTrue#假定 操纵胜利
复造代码
智能体完毕

现在,让咱们开端完毕各个智能体。咱们将使用LangChain框架去建立那些智能体。
创意总监Agent(Creative Director Agent)

创意总监Agent担当天生实质创意战选题标的目的。它会阐发热门话题、账号汗青表示战粉丝兴致,提出有后劲的实质创意。
  1. from langchain.llms import OpenAI
  2. from langchain.prompts import PromptTemplate
  3. from langchain.chains import LLMChain
  4. from langchain.agents import AgentType, initialize_agent, Tool
  5. from typing import List, Dict, Any
  6. import json
  7. from datetime import datetime
  8. classCreativeDirectorAgent:def__init__(self, memory_system: MemorySystem, tool_library: ToolLibrary):
  9.         self.memory = memory_system
  10.         self.tools = tool_library
  11.         self.llm = OpenAI(temperature=0.7, max_tokens=2000)# 较下的温度以得到更多创意# 界说创意总监使用的东西
  12.         self.agent_tools =[
  13.             Tool(
  14.                 name="获得热门话题",
  15.                 func=self.tools.get_trending_topics,
  16.                 description="获得目前抖音上的热门话题,可用于实质创意"),
  17.             Tool(
  18.                 name="搜刮实质创意",
  19.                 func=lambda keyword: json.dumps(self.tools.search_content_ideas(keyword), ensure_ascii=False),
  20.                 description="鉴于枢纽词汇搜刮相干的实质创意"),
  21.             Tool(
  22.                 name="获得账号汗青实质",
  23.                 func=lambda limit=10: json.dumps(self.memory.get_content_history(limit), ensure_ascii=False),
  24.                 description="获得账号汗青公布的实质,用于参照战制止重复"),
  25.             Tool(
  26.                 name="获得下表示实质",
  27.                 func=lambda metric='view_count', limit=5: json.dumps(self.memory.get_top_performing_content(metric, limit), ensure_ascii=False),
  28.                 description="获得账号汗青上表示最佳的实质,阐发胜利因素")]#创立 创意总监Agent
  29.         self.agent = initialize_agent(
  30.             self.agent_tools,
  31.             self.llm,
  32.             agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
  33.             verbose=True)# 创意天生提醒模板
  34.         self.creative_prompt = PromptTemplate(
  35.             input_variables=["account_data","content_objectives","constraints"],
  36.             template="""您是一名专科的抖音实质创意总监,担当为账号订定实质战略战天生创意选题。
  37.             
  38.             账号数据:
  39.             {account_data}
  40.             
  41.             实质目标:
  42.             {content_objectives}
  43.             
  44.             束缚前提:
  45.             {constraints}
  46.             
  47.             请根据如下步调截至思考战事情:
  48.             1. 起首,理解目前的热门话题战趋势
  49.             2.检查 账号汗青表示最佳的实质,阐发胜利因素
  50.             3. 保证新创意取账号定位不合,共时制止取汗青实质重复
  51.             4. 天生5-7个有后劲的实质创意,每一个创意包罗:题目、范例、扼要描绘、预期结果、预估易度
  52.             
  53.             请以JSON格局前去您的创意倡议。
  54.             """)defgenerate_content_ideas(self, content_objectives:str="增加粉丝互动战账号暴光",
  55.                               constraints:str="连结账号笔直范围定位,每一望频时少掌握正在15-60秒")-> List[Dict]:"""天生实质创意"""
  56.         account_data = self.tools.get_account_data()
  57.         account_data_str = json.dumps(account_data, ensure_ascii=False)
  58.         
  59.         prompt = self.creative_prompt.format(
  60.             account_data=account_data_str,
  61.             content_objectives=content_objectives,
  62.             constraints=constraints
  63.         )try:
  64.             result = self.agent.run(prompt)#记载 决议计划
  65.             self.memory.record_decision(
  66.                 agent_name="CreativeDirectorAgent",
  67.                 decision_type="content_ideas_generation",
  68.                 decision_content=result,
  69.                 context={"content_objectives": content_objectives,"constraints": constraints,"timestamp": datetime.now().isoformat()})# 测验考试剖析JSON成果try:
  70.                 ideas = json.loads(result)return ideas ifisinstance(ideas,list)else[ideas]except json.JSONDecodeError:#假设 没有是有用的JSON,前去本初成果return[{"raw_result": result}]except Exception as e:print(f"Error generating content ideas: {e}")return[]defrefine_content_idea(self, idea: Dict, feedback:str)-> Dict:"""按照反应劣化实质创意"""
  71.         refine_prompt =f"""
  72.         本初创意:
  73.         {json.dumps(idea, ensure_ascii=False)}
  74.         
  75.         反应定见:
  76.         {feedback}
  77.         
  78.         请按照反应定见劣化那个实质创意,保存其中心代价的共时,处置反应中提到的成就。
  79.         请以JSON格局前去劣化后的创意。
  80.         """try:
  81.             result = self.agent.run(refine_prompt)#记载 决议计划
  82.             self.memory.record_decision(
  83.                 agent_name="CreativeDirectorAgent",
  84.                 decision_type="content_idea_refinement",
  85.                 decision_content=result,
  86.                 context={"original_idea": idea,"feedback": feedback,"timestamp": datetime.now().isoformat()})try:
  87.                 refined_idea = json.loads(result)return refined_idea
  88.             except json.JSONDecodeError:return{"raw_result": result,"original_idea": idea}except Exception as e:print(f"Error refining content idea: {e}")return idea
复造代码
脚本作者Agent(Script Writer Agent)

脚本作者Agent担当将创意转移为可拍摄的具体剧本,包罗场景描绘、台词汇、镜头倡议等。
  1. from langchain.llms import OpenAI
  2. from langchain.prompts import PromptTemplate
  3. from langchain.chains import LLMChain
  4. from langchain.agents import AgentType, initialize_agent, Tool
  5. from typing import List, Dict, Any
  6. import json
  7. from datetime import datetime
  8. classScriptWriterAgent:def__init__(self, memory_system: MemorySystem, tool_library: ToolLibrary):
  9.         self.memory = memory_system
  10.         self.tools = tool_library
  11.         self.llm = OpenAI(temperature=0.8, max_tokens=3000)# 较下的温度以得到更有创意的剧本# 界说脚本作者使用的东西
  12.         self.agent_tools =[
  13.             Tool(
  14.                 name="获得下表示实质",
  15.                 func=lambda metric='view_count', limit=5: json.dumps(self.memory.get_top_performing_content(metric, limit), ensure_ascii=False),
  16.                 description="获得账号汗青上表示最佳的实质,阐发其剧本构造微风格"),
  17.             Tool(
  18.                 name="搜刮实质创意",
  19.                 func=lambda keyword: json.dumps(self.tools.search_content_ideas(keyword), ensure_ascii=False),
  20.                 description="鉴于枢纽词汇搜刮相干的实质创意,为剧本供给更多灵感")]#创立 脚本作者Agent
  21.         self.agent = initialize_agent(
  22.             self.agent_tools,
  23.             self.llm,
  24.             agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
  25.             verbose=True)# 剧本写做提醒模板
  26.         self.script_prompt = PromptTemplate(
  27.             input_variables=["content_idea","account_style","duration_constraint"],
  28.             template="""您是一名专科的抖音短望频编剧,善于创做令人着迷、适宜仄台算法的短望频剧本。
  29.             
  30.             实质创意:
  31.             {content_idea}
  32.             
  33.             账号气势派头定位:
  34.             {account_style}
  35.             
  36.             时少束缚:
  37.             {duration_constraint}
  38.             
  39.             请根据如下步调截至思考战事情:
  40.             1. 起首,阐发那个实质创意的中心代价战吸收面
  41.             2.检查 账号汗青上表示最佳的实质,阐发其胜利的剧本构造
  42.             3. 创做一个残破的短望频剧本,包罗如下元艳:
  43.                - 望频概括:扼要描绘望频实质战目标
  44.                - 钩子设想:前3秒怎样吸收不雅寡留神力
  45.                - 具体剧本:按时间线合成,包罗场景、绘里描绘、台词汇/旁利剑、音乐/音效倡议
  46.                - 互动设想:怎样指导用户面赞、批评、分享
  47.                - 话题标签倡议:相干的热门话题战笔直范围标签
  48.             
  49.             请以JSON格局前去您的剧本。
  50.             """)defwrite_script(self, content_idea: Dict,
  51.                     account_style:str="常识科普类,专科但是没有得爱好,语速适中,绘里明了",
  52.                     duration_constraint:str="15-30秒")-> Dict:"""编辑剧本"""
  53.         content_idea_str = json.dumps(content_idea, ensure_ascii=False)
  54.         
  55.         prompt = self.script_prompt.format(
  56.             content_idea=content_idea_str,
  57.             account_style=account_style,
  58.             duration_constraint=duration_constraint
  59.         )try:
  60.             result = self.agent.run(prompt)#记载 决议计划
  61.             self.memory.record_decision(
  62.                 agent_name="ScriptWriterAgent",
  63.                 decision_type="script_writing",
  64.                 decision_content=result,
  65.                 context={"content_idea": content_idea,"account_style": account_style,"duration_constraint": duration_constraint,"timestamp": datetime.now().isoformat()})# 测验考试剖析JSON成果try:
  66.                 script = json.loads(result)return script
  67.             except json.JSONDecodeError:#假设 没有是有用的JSON,前去本初成果return{"raw_result": result}except Exception as e:print(f"Error writing script: {e}")return{}defrefine_script(self, script: Dict, feedback:str)-> Dict:"""按照反应劣化剧本"""
  68.         refine_prompt =f"""
  69.         本初剧本:
  70.         {json.dumps(script, ensure_ascii=False)}
  71.         
  72.         反应定见:
  73.         {feedback}
  74.         
  75.         请按照反应定见劣化那个剧本,保存其中心代价的共时,处置反应中提到的成就。
  76.         请以JSON格局前去劣化后的剧本。
  77.         """try:
  78.             result = self.agent.run(refine_prompt)#记载 决议计划
  79.             self.memory.record_decision(
  80.                 agent_name="ScriptWriterAgent",
  81.                 decision_type="script_refinement",
  82.                 decision_content=result,
  83.                 context={"original_script": script,"feedback": feedback,"timestamp": datetime.now().isoformat()})try:
  84.                 refined_script = json.loads(result)return refined_script
  85.             except json.JSONDecodeError:return{"raw_result": result,"original_script": script}except Exception as e:print(f"Error refining script: {e}")return script
复造代码
实质制作Agent(Content Producer Agent)

实质制作Agent担当按照剧本制作望频。它能够使用模板、艳材库、文原转语音等东西去主动化天生望频。
  1. from langchain.llms import OpenAI
  2. from langchain.prompts import PromptTemplate
  3. from langchain.chains import LLMChain
  4. from langchain.agents import AgentType, initialize_agent, Tool
  5. from typing import List, Dict, Any, Optional
  6. import json
  7. from datetime import datetime
  8. import os
  9. from moviepy.editor import*from gtts import gTTS
  10. import requests
  11. from PIL import Image, ImageDraw, ImageFont
  12. classContentProducerAgent:def__init__(self, memory_system: MemorySystem, tool_library: ToolLibrary):
  13.         self.memory = memory_system
  14.         self.tools = tool_library
  15.         self.llm = OpenAI(temperature=0.3, max_tokens=1500)# 较高的温度以得到更精确的施行# 艳材库路子
  16.         self.background_videos_path ="assets/background_videos"
  17.         self.music_path ="assets/music"
  18.         self.images_path ="assets/images"
  19.         self.output_path ="output/videos"# 保证目次存留for path in[self.background_videos_path, self.music_path, self.images_path, self.output_path]:
  20.             os.makedirs(path, exist_ok=True)# 界说实质制作使用的东西
  21.         self.agent_tools =[
  22.             Tool(
  23.                 name="文原转语音",
  24.                 func=self._text_to_speech,
  25.                 description="将文原变换为语音,参数为文原实质战可选的语言代码"),
  26.             Tool(
  27.                 name="搜刮艳材",
  28.                 func=self._search_materials,
  29.                 description="按照枢纽词汇搜刮相干的艳材(图片、望频、音乐)")]#创立 实质制作Agent
  30.         self.agent = initialize_agent(
  31.             self.agent_tools,
  32.             self.llm,
  33.             agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
  34.             verbose=True)# 望频制作方案提醒模板
  35.         self.production_plan_prompt = PromptTemplate(
  36.             input_variables=["script","production_constraints"],
  37.             template="""您是一名专科的望频制作大师,担当按照剧本订定具体的望频制作方案。
  38.             
  39.             剧本实质:
  40.             {script}
  41.             
  42.             制作束缚:
  43.             {production_constraints}
  44.             
  45.             请订定一个具体的望频制作方案,包罗如下实质:
  46.             1. 艳材需要浑单:需要哪些图片、望频、音频艳材
  47.             2. 望频构造:场景挨次、转场结果
  48.             3. 文原元艳:需要增加的文原、字幕、题目,及其款式战职位
  49.             4. 音频方案:布景音乐、音效、旁利剑的摆设
  50.             5. 制作步调:具体的制作过程
  51.             
  52.             请以JSON格局前去您的制作方案。
  53.             """)def_text_to_speech(self, text:str, lang:str='zh')->str:"""将文原变换为语音"""try:
  54.             tts = gTTS(text=text, lang=lang, slow=False)
  55.             filename =f"temp_audio_{datetime.now().strftime('%Y%m%d%H%M%S')}.mp3"
  56.             filepath = os.path.join(self.output_path, filename)
  57.             tts.save(filepath)return filepath
  58.         except Exception as e:print(f"Error in text-to-speech: {e}")return""def_search_materials(self, keyword:str, material_type:str="all")-> List[str]:"""搜刮艳材(模仿函数)"""# 正在理论使用中,那里能够跟尾到艳材库API或者当地艳材库# 那里咱们前去模仿数据
  59.         mock_materials ={"background":["assets/background_videos/bg1.mp4","assets/background_videos/bg2.mp4"],"music":["assets/music/music1.mp3","assets/music/music2.mp3"],"image":["assets/images/img1.jpg","assets/images/img2.jpg"]}if material_type =="all":
  60.             results =[]for materials in mock_materials.values():
  61.                 results.extend(materials)return results
  62.         
  63.         return mock_materials.get(material_type,[])def_create_text_image(self, text:str, size:tuple=(1080,1920),
  64.                           font_size:int=80, text_color:tuple=(255,255,255),
  65.                           bg_color:tuple=(0,0,0,180))->str:"""创立包罗文原的图片"""try:#创立 通明布景
  66.             img = Image.new('RGBA', size, bg_color)
  67.             draw = ImageDraw.Draw(img)# 减载字体(那里使用体系默认字体,理论使用中能够指定字体文献)try:
  68.                 font = ImageFont.truetype("arial.ttf", font_size)except:
  69.                 font = ImageFont.load_default()# 计较文当地位(居中)
  70.             text_bbox = draw.textbbox((0,0), text, font=font)
  71.             text_width = text_bbox[2]- text_bbox[0]
  72.             text_height = text_bbox[3]- text_bbox[1]
  73.             x =(size[0]- text_width)//2
  74.             y =(size[1]- text_height)//2# 画造文原
  75.             draw.text((x, y), text, font=font, fill=text_color)#保管 图片
  76.             filename =f"text_image_{datetime.now().strftime('%Y%m%d%H%M%S')}.png"
  77.             filepath = os.path.join(self.output_path, filename)
  78.             img.save(filepath)return filepath
  79.         except Exception as e:print(f"Error creating text image: {e}")return""defcreate_production_plan(self, script: Dict,
  80.                               production_constraints:str="使用现有的艳材库,连结横屏9:16格局,望频明了流畅")-> Dict:"""创立望频制作方案"""
  81.         script_str = json.dumps(script, ensure_ascii=False)
  82.         
  83.         prompt = self.production_plan_prompt.format(
  84.             script=script_str,
  85.             production_constraints=production_constraints
  86.         )try:
  87.             result = self.agent.run(prompt)#记载 决议计划
  88.             self.memory.record_decision(
  89.                 agent_name="ContentProducerAgent",
  90.                 decision_type="production_plan_creation",
  91.                 decision_content=result,
  92.                 context={"script": script,"production_constraints": production_constraints,"timestamp": datetime.now().isoformat()})# 测验考试剖析JSON成果try:
  93.                 plan = json.loads(result)return plan
  94.             except json.JSONDecodeError:#假设 没有是有用的JSON,前去本初成果return{"raw_result": result}except Exception as e:print(f"Error creating production plan: {e}")return{}defproduce_video(self, script: Dict, production_plan: Dict =None)-> Optional[str]:"""按照剧本战制作方案制作望频"""#假设 不供给制作方案,先创立一个ifnot production_plan:
  95.             production_plan = self.create_production_plan(script)try:# 那是一个简化的望频制作过程# 正在理论使用中,您可以需要按照剧本战制作方案的具体构造去完毕# 1. 准备艳材# 那里咱们使用一点儿简朴的艳材动作示例
  96.             bg_video_path = os.path.join(self.background_videos_path,"sample_bg.mp4")#假设 不示例布景望频,创立一个简朴的杂色布景ifnot os.path.exists(bg_video_path):#创立 一个5秒的玄色布景望频
  97.                 bg_clip = ColorClip(size=(1080,1920), color=(0,0,0
复造代码
您需要登录后才可以回帖 登录 | 立即注册 qq_login

本版积分规则

发布主题
阅读排行更多+
用专业创造成效
400-778-7781
周一至周五 9:00-18:00
意见反馈:server@mailiao.group
紧急联系:181-67184787
ftqrcode

扫一扫关注我们

Powered by 职贝云数A新零售门户 X3.5© 2004-2025 职贝云数 Inc.( 蜀ICP备2024104722号 )