video_processor.py 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588
  1. import configparser
  2. import json
  3. import os
  4. import random
  5. import re
  6. import shutil
  7. import time
  8. from datetime import datetime
  9. from common.redis import get_data, get_first_value_with_prefix, increment_key
  10. from common.tag_video import Tag
  11. from common.tts_help import TTS
  12. from common import Material, Feishu, Common, Oss, AliyunLogger
  13. from common.ffmpeg import FFmpeg
  14. from common.gpt4o_help import GPT4o
  15. from data_channel.douyin import DY
  16. from data_channel.dy_keyword import DyKeyword
  17. from data_channel.dy_ls import DYLS
  18. from data_channel.ks_keyword import KsKeyword
  19. from data_channel.ks_ls import KSLS
  20. from data_channel.kuaishou import KS
  21. from data_channel.kuaishouchuangzuozhe import KsFeedVideo
  22. from data_channel.piaoquan import PQ
  23. from common.sql_help import sqlCollect
  24. from data_channel.shipinhao import SPH
  25. # 读取配置文件
  26. from data_channel.shipinhaodandian import SPHDD
  27. from data_channel.sph_ls import SPHLS
  28. config = configparser.ConfigParser()
  29. config.read('./config.ini')
  30. class VideoProcessor:
  31. """
  32. 视频处理类,包含创建文件夹、生成随机ID、删除文件和处理视频任务等方法。
  33. """
  34. @classmethod
  35. def create_folders(cls, mark):
  36. """
  37. 根据标示和任务标示创建目录
  38. """
  39. id = cls.random_id()
  40. video_path_url = config['PATHS']['VIDEO_PATH'] + mark + "/" + str(id) + "/"
  41. if not os.path.exists(video_path_url):
  42. os.makedirs(video_path_url)
  43. return video_path_url
  44. @classmethod
  45. def random_id(cls):
  46. """
  47. 随机生成ID
  48. """
  49. now = datetime.now()
  50. rand_num = random.randint(10000, 99999)
  51. return f"{now.strftime('%Y%m%d%H%M%S')}{rand_num}"
  52. @classmethod
  53. def remove_files(cls, mark):
  54. """
  55. 删除指定目录下的所有文件和子目录
  56. """
  57. path = config['PATHS']['VIDEO_PATH'] + mark + "/"
  58. # 删除目录下的所有内容
  59. if os.path.exists(path):
  60. # 遍历目录下的所有文件和子目录
  61. for filename in os.listdir(path):
  62. file_path = os.path.join(path, filename)
  63. try:
  64. if os.path.isfile(file_path) or os.path.islink(file_path):
  65. os.unlink(file_path) # 删除文件或符号链接
  66. elif os.path.isdir(file_path):
  67. shutil.rmtree(file_path) # 删除子目录及其所有内容
  68. except Exception as e:
  69. print(f'Failed to delete {file_path}. Reason: {e}')
  70. @classmethod
  71. def process_task(cls, task, mark, name, feishu_id, cookie_sheet):
  72. """
  73. 处理单个任务
  74. """
  75. task_mark = task["task_mark"]
  76. channel_id = str(task["channel_id"])
  77. url = str(task["channel_url"])
  78. piaoquan_id = str(task["piaoquan_id"])
  79. number = task["number"]
  80. title = task["title"]
  81. video_share = task["video_share"]
  82. video_ending = task["video_ending"]
  83. crop_total = task["crop_total"]
  84. gg_duration_total = task["gg_duration_total"]
  85. voice = task['voice']
  86. if voice:
  87. if ',' in voice:
  88. voices = voice.split(',')
  89. else:
  90. voices = [voice]
  91. voice = random.choice(voices)
  92. else:
  93. voice = "zhifeng_emo"
  94. zm = Material.get_pzsrt_data("summary", "500Oe0", video_share)
  95. Common.logger(mark).info(f"{name}的{task_mark}下{channel_id}的用户:{url}开始获取视频")
  96. data_list = cls.get_data_list(channel_id, task_mark, url, number, mark, feishu_id, cookie_sheet, name, task)
  97. if not data_list:
  98. AliyunLogger.logging(channel_id, name, url, "", "无改造视频", "4000")
  99. Common.logger(mark).info(f"{name}的{task_mark}下{channel_id}的视频ID{url} 已经改造过了")
  100. text = (
  101. f"**通知类型**: 没有改造的视频\n"
  102. f"**负责人**: {name}\n"
  103. f"**渠道**: {channel_id}\n"
  104. f"**视频主页ID**: {url}\n"
  105. )
  106. Feishu.finish_bot(text, "https://open.feishu.cn/open-apis/bot/v2/hook/e7697dc6-5254-4411-8b59-3cd0742bf703",
  107. "【 机器改造通知 】")
  108. return
  109. Common.logger(mark).info(f"{name}的{task_mark}下的ID{url} 获取视频完成,共{len(data_list)}条")
  110. for video in data_list:
  111. try:
  112. cls.remove_files(mark)
  113. video_path_url = cls.create_folders(mark)
  114. new_title = cls.generate_title(video, title)
  115. v_id = video["video_id"]
  116. cover = video["cover"]
  117. video_url = video["video_url"]
  118. old_title = video['old_title']
  119. rule = video['rule']
  120. # if channel_id == "单点视频":
  121. # redis_video = get_redis_video_data(v_id)
  122. # if redis_video:
  123. # continue
  124. if not old_title:
  125. old_title = '这个视频,分享给我的老友,祝愿您能幸福安康'
  126. text = (
  127. f"**通知类型**: 标题为空,使用兜底标题生成片尾\n"
  128. f"**负责人**: {name}\n"
  129. f"**渠道**: {channel_id}\n"
  130. f"**视频主页ID**: {url}\n"
  131. f"**视频Video_id**: {v_id}\n"
  132. )
  133. Feishu.finish_bot(text,
  134. "https://open.feishu.cn/open-apis/bot/v2/hook/e7697dc6-5254-4411-8b59-3cd0742bf703",
  135. "【 机器改造通知 】")
  136. Common.logger(mark).info(f"{name}的{task_mark}下的视频{url},标题为空,使用兜底标题生成片尾")
  137. time.sleep(1)
  138. pw_random_id = cls.random_id()
  139. Common.logger(mark).info(f"{name}的{task_mark}下的ID{url} 开始下载视频")
  140. new_video_path = cls.download_and_process_video(channel_id, video_url, video_path_url, v_id,
  141. crop_total, gg_duration_total, pw_random_id, new_title, mark, video)
  142. if not os.path.isfile(new_video_path) or new_video_path == None:
  143. AliyunLogger.logging(channel_id, name, url, v_id, "视频下载失败", "3002", f"video_url:{video_url}")
  144. text = (
  145. f"**通知类型**: 视频下载失败\n"
  146. f"**负责人**: {name}\n"
  147. f"**渠道**: {channel_id}\n"
  148. f"**视频主页ID**: {url}\n"
  149. f"**视频Video_id**: {v_id}\n"
  150. )
  151. Feishu.finish_bot(text,
  152. "https://open.feishu.cn/open-apis/bot/v2/hook/e7697dc6-5254-4411-8b59-3cd0742bf703",
  153. "【 机器改造通知 】")
  154. continue
  155. if new_video_path:
  156. if video_ending and video_ending != 'None':
  157. new_video_path = cls.handle_video_ending(new_video_path, video_ending, old_title, pw_random_id, video_path_url, mark, task_mark, url, name, video_share, zm, voice)
  158. if new_video_path == None:
  159. continue
  160. else:
  161. if video_share and video_share != 'None':
  162. new_video_path = FFmpeg.single_video(new_video_path, video_path_url, zm)
  163. # new_video_path = FFmpeg.single_video(new_video_path, video_path_url, zm)
  164. if not os.path.isfile(new_video_path):
  165. log_data = f"user:{url},,video_id:{v_id},,video_url:{video_url},,ai_title:{new_title}"
  166. AliyunLogger.logging(channel_id, name, url, v_id, "视频改造失败", "3001", log_data)
  167. text = (
  168. f"**通知类型**: 视频改造失败\n"
  169. f"**负责人**: {name}\n"
  170. f"**渠道**: {channel_id}\n"
  171. f"**视频主页ID**: {url}\n"
  172. f"**视频Video_id**: {v_id}\n"
  173. )
  174. Feishu.finish_bot(text,
  175. "https://open.feishu.cn/open-apis/bot/v2/hook/e7697dc6-5254-4411-8b59-3cd0742bf703",
  176. "【 机器改造通知 】")
  177. continue
  178. # 上传视频和封面,并更新数据库
  179. code = cls.upload_video_and_thumbnail(new_video_path, cover, v_id, new_title, task_mark, name, piaoquan_id,
  180. video_path_url, mark, channel_id, url, old_title, title, rule)
  181. # 更新已使用的视频号状态
  182. pq_url = f'https://admin.piaoquantv.com/cms/post-detail/{code}/detail' # 站内视频链接
  183. if name == "单点视频":
  184. sphdd_status = sqlCollect.update_shp_dd_vid(v_id)
  185. if sphdd_status == 1:
  186. Common.logger(mark).info(f"{name}的{task_mark}下的ID{url} 视频修改已使用,状态已修改")
  187. from_user_name = video['from_user_name'] # 来源用户
  188. from_group_name = video['from_group_name'] # 来源群组
  189. source = video['source'] # 渠道
  190. channel_id = source
  191. text = (
  192. f"**站内视频链接**: {pq_url}\n"
  193. f"**渠道**: {source}\n"
  194. f"**来源用户**: {from_user_name}\n"
  195. f"**来源群组**: {from_group_name}\n"
  196. f"**原视频链接**: {video['video_url']}\n"
  197. f"**原视频封面**: {video['cover']}\n"
  198. f"**原视频标题**: {video['old_title']}\n"
  199. )
  200. Feishu.finish_bot(text, "https://open.feishu.cn/open-apis/bot/v2/hook/493b3d4c-5fae-4a9d-980b-1dd86636524e", "【 有一条新的内容改造成功 】")
  201. if channel_id == "快手历史" or channel_id == "抖音历史" or channel_id == "视频号历史":
  202. explain = "历史爆款"
  203. else:
  204. explain = "新供给"
  205. current_time = datetime.now()
  206. formatted_time = current_time.strftime("%Y-%m-%d %H:%M:%S")
  207. if name == "品类关键词搜索":
  208. first_category = task["first_category"]
  209. secondary_category = task["secondary_category"]
  210. keyword_principal = task["keyword_name"]
  211. tag_first = f"一级品类_{first_category}"
  212. tag_keyword = f"关键词_{url}"
  213. if channel_id == "抖音搜索":
  214. tag_channel = "来源_抖音关键词"
  215. elif channel_id == "快手搜索":
  216. tag_channel = "来源_快手关键词"
  217. tag = f"{tag_first},{tag_keyword},{tag_channel}"
  218. tag_status = Tag.video_tag(code, tag)
  219. if tag_status == 0:
  220. Common.logger(mark).info(f"{name}的{task_mark}下的ID{url}下的票圈视频{code},写入标签成功")
  221. log_data = f"user:{url},,video_id:{v_id},,video_url:{video_url},,ai_title:{new_title},,voice:{voice},,first_category:{first_category},,secondary_category:{secondary_category},,keyword_principal:{keyword_principal},,tag:{tag}"
  222. values = [
  223. [
  224. name,
  225. task_mark,
  226. channel_id,
  227. url,
  228. str(v_id),
  229. piaoquan_id,
  230. old_title,
  231. title if title in ["原标题", "AI标题"] else "",
  232. new_title,
  233. str(code),
  234. formatted_time,
  235. str(rule),
  236. explain,
  237. voice,
  238. first_category,
  239. secondary_category,
  240. keyword_principal,
  241. pq_url
  242. ]
  243. ]
  244. else:
  245. log_data = f"user:{url},,video_id:{v_id},,video_url:{video_url},,ai_title:{new_title},,voice:{voice}"
  246. values = [
  247. [
  248. name,
  249. task_mark,
  250. channel_id,
  251. url,
  252. str(v_id),
  253. piaoquan_id,
  254. old_title,
  255. title if title in ["原标题", "AI标题"] else "",
  256. new_title,
  257. str(code),
  258. formatted_time,
  259. str(rule),
  260. explain,
  261. voice
  262. ]
  263. ]
  264. AliyunLogger.logging(channel_id, name, url, v_id, "视频改造成功", "1000", log_data, str(code))
  265. text = (
  266. f"**通知类型**: 视频改造成功\n"
  267. f"**站内视频链接**: {pq_url}\n"
  268. f"**负责人**: {name}\n"
  269. f"**渠道**: {channel_id}\n"
  270. f"**视频主页ID**: {url}\n"
  271. f"**视频Video_id**: {v_id}\n"
  272. f"**使用音频音色**: {voice}\n"
  273. )
  274. Feishu.finish_bot(text,
  275. "https://open.feishu.cn/open-apis/bot/v2/hook/e7697dc6-5254-4411-8b59-3cd0742bf703",
  276. "【 机器改造通知 】")
  277. if values:
  278. if name == "王雪珂":
  279. sheet = "vfhHwj"
  280. elif name == "抖音品类账号-1":
  281. sheet = "61kvW7"
  282. elif name == "鲁涛":
  283. sheet = "FhewlS"
  284. elif name == "范军":
  285. sheet = "B6dCfS"
  286. elif name == "余海涛":
  287. sheet = "mfBrNT"
  288. elif name == "罗情":
  289. sheet = "2J3PwN"
  290. elif name == "王玉婷":
  291. sheet = "bBHFwC"
  292. elif name == "刘诗雨":
  293. sheet = "fBdxIQ"
  294. elif name == "信欣":
  295. sheet = "lPe1eT"
  296. elif name == "快手创作者版品类推荐流":
  297. sheet = "k7l7nQ"
  298. elif name == "抖音品类账号":
  299. sheet = "Bsg5UR"
  300. elif name == "视频号品类账号":
  301. sheet = "b0uLWw"
  302. elif name == "单点视频":
  303. sheet = "ptgCXW"
  304. elif name == "快手品类账号":
  305. sheet = "ibjoMx"
  306. elif name == "品类关键词搜索":
  307. sheet = "Tgpikc"
  308. Feishu.insert_columns("ILb4sa0LahddRktnRipcu2vQnLb", sheet, "ROWS", 1, 2)
  309. time.sleep(0.5)
  310. Feishu.update_values("ILb4sa0LahddRktnRipcu2vQnLb", sheet, "A2:Z2", values)
  311. except Exception as e:
  312. Common.logger(mark).error(f"{name}的{task_mark}任务处理失败:{e}")
  313. continue
  314. @classmethod
  315. def get_data_list(cls, channel_id, task_mark, url, number, mark, feishu_id, cookie_sheet, name, task):
  316. """
  317. 根据渠道ID获取数据列表
  318. """
  319. if channel_id == "抖音":
  320. return DY.get_dy_url(task_mark, url, number, mark, feishu_id, cookie_sheet, channel_id, name)
  321. elif channel_id == "票圈":
  322. return PQ.get_pq_url(task_mark, url, number, mark, channel_id, name)
  323. elif channel_id == "视频号":
  324. return SPH.get_sph_url(task_mark, url, number, mark, channel_id, name)
  325. elif channel_id == "快手":
  326. return KS.get_ks_url(task_mark, url, number, mark, feishu_id, cookie_sheet, channel_id, name)
  327. elif channel_id == "快手创作者版":
  328. return KsFeedVideo.get_data(channel_id, name)
  329. elif channel_id == "单点视频":
  330. return SPHDD.get_sphdd_data(url, channel_id, name)
  331. elif channel_id == "抖音历史":
  332. return DYLS.get_dy_zr_list(task_mark, url, number, mark, channel_id, name)
  333. elif channel_id == "快手历史":
  334. return KSLS.get_ksls_list(task_mark, url, number, mark, channel_id, name)
  335. elif channel_id == "视频号历史":
  336. return SPHLS.get_sphls_data(task_mark, url, number, mark, channel_id, name)
  337. elif channel_id == '抖音搜索':
  338. return DyKeyword.get_key_word(url, task_mark, mark, channel_id, name, task)
  339. elif channel_id == '快手搜索':
  340. return KsKeyword.get_key_word(url, task_mark, mark, channel_id, name, task)
  341. @classmethod
  342. def generate_title(cls, video, title):
  343. """
  344. 生成新标题
  345. """
  346. if video['old_title']:
  347. new_title = video['old_title'].strip().replace("\n", "") \
  348. .replace("/", "").replace("\\", "").replace("\r", "") \
  349. .replace(":", "").replace("*", "").replace("?", "") \
  350. .replace("?", "").replace('"', "").replace("<", "") \
  351. .replace(">", "").replace("|", "").replace(" ", "") \
  352. .replace("&NBSP", "").replace(".", "。").replace(" ", "") \
  353. .replace("'", "").replace("#", "").replace("Merge", "")
  354. else:
  355. return '这个视频,分享给我的老友,祝愿您能幸福安康'
  356. if title == "原标题":
  357. if not new_title:
  358. new_title = '这个视频,分享给我的老友,祝愿您能幸福安康'
  359. elif title == "AI标题":
  360. if not new_title:
  361. new_title = '这个视频,分享给我的老友,祝愿您能幸福安康'
  362. else:
  363. new_title = GPT4o.get_ai_title(new_title)
  364. else:
  365. titles = title.split('/') if '/' in title else [title]
  366. new_title = random.choice(titles)
  367. return new_title
  368. @classmethod
  369. def download_and_process_video(cls, channel_id, video_url, video_path_url, v_id, crop_total, gg_duration_total,
  370. pw_random_id, new_title, mark, video):
  371. """
  372. 下载并处理视频
  373. """
  374. if channel_id == "单点视频":
  375. new_video_path = PQ.dd_sph_download_video(video_url, video_path_url, v_id, video, channel_id)
  376. if new_video_path == None:
  377. return None
  378. Common.logger(mark).info(f"{channel_id}视频下载成功: {new_video_path}")
  379. elif channel_id == "视频号":
  380. new_video_path = PQ.sph_download_video(video_url, video_path_url, v_id, video)
  381. if new_video_path == None:
  382. return None
  383. Common.logger(mark).info(f"{channel_id}视频下载成功: {new_video_path}")
  384. elif channel_id == "票圈" or channel_id == "快手创作者版":
  385. new_video_path = PQ.download_video(video_url, video_path_url, v_id)
  386. if new_video_path == None:
  387. return None
  388. Common.logger(mark).info(f"{channel_id}视频下载成功: {new_video_path}")
  389. elif channel_id == "视频号历史":
  390. new_video_path = Oss.download_sph_ls(video_url, video_path_url, v_id)
  391. Common.logger(mark).info(f"{channel_id}视频下载成功: {new_video_path}")
  392. else:
  393. Common.logger(mark).info(f"视频准备下载")
  394. new_video_path = Oss.download_video_oss(video_url, video_path_url, v_id)
  395. Common.logger(mark).info(f"视频下载成功: {new_video_path}")
  396. if os.path.isfile(new_video_path):
  397. if crop_total and crop_total != 'None': # 判断是否需要裁剪
  398. new_video_path = FFmpeg.video_crop(new_video_path, video_path_url, pw_random_id)
  399. if gg_duration_total and gg_duration_total != 'None': # 判断是否需要指定视频时长
  400. new_video_path = FFmpeg.video_ggduration(new_video_path, video_path_url, pw_random_id,
  401. gg_duration_total)
  402. width, height = FFmpeg.get_w_h_size(new_video_path)
  403. if width < height: # 判断是否需要修改为竖屏
  404. new_video_path = FFmpeg.update_video_h_w(new_video_path, video_path_url, pw_random_id)
  405. new_title_re = re.sub(r'[^\w\s\u4e00-\u9fff,。!?]', '', new_title)
  406. if len(new_title_re) > 12:
  407. new_title_re = '\n'.join(
  408. [new_title_re[i:i + 12] for i in range(0, len(new_title_re), 12)])
  409. new_video_path = FFmpeg.add_video_zm(new_video_path, video_path_url, pw_random_id, new_title_re)
  410. return new_video_path
  411. else:
  412. return None
  413. @classmethod
  414. def handle_video_ending(cls, new_video_path, video_ending, old_title, pw_random_id, video_path_url, mark, task_mark, url, name, video_share, zm, voice):
  415. """
  416. 处理视频片尾
  417. """
  418. if video_ending == "AI片尾引导":
  419. pw_srt_text = GPT4o.get_ai_pw(old_title)
  420. if pw_srt_text:
  421. pw_url = TTS.get_pw_zm(pw_srt_text, voice)
  422. if pw_url:
  423. pw_mp3_path = TTS.download_mp3(pw_url, video_path_url, pw_random_id)
  424. # oss_mp3_key = Oss.mp3_upload_oss(pw_mp3_path, pw_random_id)
  425. # oss_mp3_key = oss_mp3_key.get("oss_object_key")
  426. # new_pw_path = f"http://art-crawler.oss-cn-hangzhou.aliyuncs.com/{oss_mp3_key}"
  427. # print(f"mp3地址:{new_pw_path}")
  428. # pw_url_sec = FFmpeg.get_video_duration(pw_mp3_path)
  429. pw_srt = TTS.getSrt(pw_url)
  430. Common.logger(mark).info(f"{name}的{task_mark}下的视频{url},获取AI片尾srt成功")
  431. else:
  432. # Feishu.bot('zhangyong', 'TTS获取失败提示', f'无法获取到片尾音频,及时更换token', "张勇")
  433. Common.logger(mark).info(f"{name}的{task_mark}下的视频{url},获取AI片尾失败")
  434. return None
  435. else:
  436. Common.logger(mark).info(f"{name}的{task_mark}下的视频{url},获取AI片尾失败")
  437. return None
  438. else:
  439. if ',' in video_ending:
  440. video_ending_list = video_ending.split(',')
  441. else:
  442. video_ending_list = [video_ending]
  443. ending = random.choice(video_ending_list)
  444. pw_list = Material.get_pwsrt_data("summary", "DgX7vC", ending) # 获取srt
  445. if pw_list:
  446. pw_id = pw_list["pw_id"]
  447. pw_srt = pw_list["pw_srt"]
  448. pw_url = PQ.get_pw_url(pw_id)
  449. pw_mp3_path = FFmpeg.get_video_mp3(pw_url, video_path_url, pw_random_id)
  450. else:
  451. Feishu.bot(mark, '机器自动改造消息通知', f'{task_mark}任务下片尾标示错误,请关注!!!!', name)
  452. for attempt in range(3):
  453. jpg_path = FFmpeg.video_png(new_video_path, video_path_url, pw_random_id) # 生成视频最后一帧jpg
  454. if os.path.isfile(jpg_path):
  455. Common.logger(mark).info(f"{name}的{task_mark}下的视频{url},生成视频最后一帧成功")
  456. break
  457. time.sleep(1)
  458. for attempt in range(3):
  459. Common.logger(mark).info(f"{name}的{task_mark}下的视频{url},获取mp3成功")
  460. pw_path = FFmpeg.pw_video(jpg_path, video_path_url, pw_mp3_path, pw_srt, pw_random_id,
  461. pw_mp3_path) # 生成片尾视频
  462. if os.path.isfile(pw_path):
  463. Common.logger(mark).info(f"{task_mark}下的视频{url},生成片尾视频成功")
  464. break
  465. time.sleep(1)
  466. pw_video_list = [new_video_path, pw_path]
  467. Common.logger(mark).info(f"{task_mark}下的视频{url},视频与片尾开始拼接")
  468. video_path = FFmpeg.concatenate_videos(pw_video_list, video_path_url) # 视频与片尾拼接到一起
  469. Common.logger(mark).info(f"{name}的{task_mark}下的视频{url},视频与片尾拼接成功")
  470. time.sleep(1)
  471. if video_share and video_share != 'None':
  472. new_video_path = FFmpeg.single_video(video_path, video_path_url, zm)
  473. else:
  474. new_video_path = video_path
  475. return new_video_path
  476. @classmethod
  477. def upload_video_and_thumbnail(cls, new_video_path: str, cover: str, v_id, new_title: str, task_mark: str, name: str, piaoquan_id,
  478. video_path_url: str, mark: str, channel_id: str, url: str, old_title: str, title, rule: str):
  479. """
  480. 上传视频和封面到OSS,并更新数据库
  481. """
  482. try:
  483. oss_id = cls.random_id()
  484. Common.logger(mark).info(f"{name}的{task_mark},开始发送oss")
  485. oss_object_key = Oss.stitching_sync_upload_oss(new_video_path, oss_id) # 视频发送OSS
  486. Common.logger(mark).info(f"{name}的{task_mark},发送oss成功{oss_object_key}")
  487. status = oss_object_key.get("status")
  488. if status == 200:
  489. oss_object_key = oss_object_key.get("oss_object_key")
  490. time.sleep(1)
  491. if channel_id == "快手历史":
  492. jpg = None
  493. else:
  494. if channel_id == "视频号历史":
  495. jpg_path = Oss.download_sph_ls(cover, video_path_url, v_id)
  496. else:
  497. jpg_path = PQ.download_video_jpg(cover, video_path_url, v_id) # 下载视频封面
  498. if os.path.isfile(jpg_path):
  499. oss_jpg_key = Oss.stitching_fm_upload_oss(jpg_path, oss_id) # 封面发送OSS
  500. status = oss_jpg_key.get("status")
  501. if status == 200:
  502. jpg = oss_jpg_key.get("oss_object_key")
  503. else:
  504. jpg = None
  505. else:
  506. jpg = None
  507. code = PQ.insert_piaoquantv(oss_object_key, new_title, jpg, piaoquan_id)
  508. Common.logger(mark).info(f"{name}的{task_mark}下的视频ID{v_id}发送成功")
  509. sqlCollect.insert_task(task_mark, v_id, mark, channel_id) # 插入数据库
  510. current_time = datetime.now()
  511. formatted_time = current_time.strftime("%Y-%m-%d %H:%M:%S")
  512. if name == "单点视频":
  513. url = str(rule)
  514. sqlCollect.insert_machine_making_data(name, task_mark, channel_id, url, v_id, piaoquan_id, new_title, code,
  515. formatted_time, old_title, oss_object_key)
  516. return code
  517. except Exception as e:
  518. Common.logger(mark).error(f"{name}的{task_mark}上传视频和封面到OSS,并更新数据库失败:{e}\n")
  519. return
  520. @classmethod
  521. def main(cls, data):
  522. """
  523. 主函数,初始化任务并使用线程池处理任务。
  524. """
  525. mark = data["mark"]
  526. name = data["name"]
  527. feishu_id = data["feishu_id"]
  528. feishu_sheet = data["feishu_sheet"]
  529. cookie_sheet = data["cookie_sheet"]
  530. try:
  531. data = get_data(mark, feishu_id, feishu_sheet)
  532. if not data:
  533. Common.logger("redis").error(f"{mark}任务开始新的一轮\n")
  534. return
  535. task = json.loads(data)
  536. if mark == 'dy-pl-gjc' and task['channel_id'] == '抖音搜索':
  537. mark_count = 'dyss-count'
  538. count = get_first_value_with_prefix(mark_count)
  539. increment_key(mark_count)
  540. if int(count) == 300:
  541. Common.logger(mark).log(f"抖音搜索接口今日已经上限")
  542. return "抖音搜索上限"
  543. if mark == 'sph-plzh'and task['channel_id'] == '视频号':
  544. mark_count = 'sph-count'
  545. count = get_first_value_with_prefix(mark_count)
  546. increment_key(mark_count)
  547. if int(count) == 400:
  548. Common.logger(mark).log(f"视频号获取用户主页今日已经上限")
  549. return "视频号获取用户主页视频上限"
  550. VideoProcessor.process_task(task, mark, name, feishu_id, cookie_sheet)
  551. return mark
  552. except Exception as e:
  553. Common.logger(mark).error(f"任务处理失败: {e}")
  554. return mark
  555. # if __name__ == "__main__":
  556. # main()