|
@@ -7,6 +7,7 @@ import subprocess
|
|
|
import sys
|
|
|
import time
|
|
|
import urllib.parse
|
|
|
+import json
|
|
|
|
|
|
import requests
|
|
|
from datetime import datetime, timedelta
|
|
@@ -186,24 +187,77 @@ class AgcVidoe():
|
|
|
# 使用 FFmpeg 将 SRT 转换为 ASS
|
|
|
subprocess.run(["ffmpeg", "-i", s_path, a_path])
|
|
|
|
|
|
+
|
|
|
+ @classmethod
|
|
|
+ def get_cover(cls, uid):
|
|
|
+ time.sleep(1)
|
|
|
+ url = "https://admin.piaoquantv.com/manager/video/multiCover/listV2"
|
|
|
+
|
|
|
+ payload = json.dumps({
|
|
|
+ "videoId": uid,
|
|
|
+ "range": "2h"
|
|
|
+ })
|
|
|
+ headers = {
|
|
|
+ 'accept': 'application/json',
|
|
|
+ 'accept-language': 'zh-CN,zh;q=0.9',
|
|
|
+ 'cache-control': 'no-cache',
|
|
|
+ 'content-type': 'application/json',
|
|
|
+ 'cookie': 'SESSION=YjU3MzgwNTMtM2QyYi00YjljLWI3YWUtZTBjNWYwMGQzYWNl',
|
|
|
+ 'origin': 'https://admin.piaoquantv.com',
|
|
|
+ 'pragma': 'no-cache',
|
|
|
+ 'priority': 'u=1, i',
|
|
|
+ 'sec-ch-ua': '"Chromium";v="124", "Google Chrome";v="124", "Not-A.Brand";v="99"',
|
|
|
+ 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36'
|
|
|
+ }
|
|
|
+
|
|
|
+ response = requests.request("POST", url, headers=headers, data=payload)
|
|
|
+ data = response.json()
|
|
|
+ content = data["content"]
|
|
|
+ if len(content) == 1:
|
|
|
+ return content[0]["coverUrl"]
|
|
|
+ max_share_count = 0
|
|
|
+ selected_cover_url = ""
|
|
|
+ for item in content:
|
|
|
+ share_count = item.get("shareWeight")
|
|
|
+ if share_count is not None and share_count > max_share_count:
|
|
|
+ max_share_count = share_count
|
|
|
+ selected_cover_url = item["coverUrl"]
|
|
|
+ elif share_count == max_share_count and item["createUser"] == "用户":
|
|
|
+ selected_cover_url = item["coverUrl"]
|
|
|
+ return selected_cover_url
|
|
|
+
|
|
|
+
|
|
|
# 新生成视频上传到对应账号下
|
|
|
@classmethod
|
|
|
- def insert_piaoquantv(cls, oss_object_key, audio_title, pq_ids_list):
|
|
|
+ def insert_piaoquantv(cls, oss_object_key, audio_title, pq_ids_list, cover, uid):
|
|
|
for i in range(2):
|
|
|
-
|
|
|
url = "https://vlogapi.piaoquantv.com/longvideoapi/crawler/video/send"
|
|
|
- payload = dict(pageSource='vlog-pages/post/post-video-post', videoPath=oss_object_key, width='720',
|
|
|
- height='1280', fileExtensions='mp4', viewStatus='1', title=audio_title,
|
|
|
- careModelStatus='1',
|
|
|
- token='f04f58d6e664cbc9902660a1e8d20ce6cd7fdb0f', loginUid=pq_ids_list[i],
|
|
|
- versionCode='719',
|
|
|
- machineCode='weixin_openid_o0w175aZ4FJtqVsA1tcozJDJHdDU', appId='wx89e7eb06478361d7',
|
|
|
- clientTimestamp='1703337579331',
|
|
|
- machineInfo='{"sdkVersion":"3.2.5","brand":"iPhone","language":"zh_CN","model":"iPhone 12 Pro<iPhone13,3>","platform":"ios","system":"iOS 15.6.1","weChatVersion":"8.0.44","screenHeight":844,"screenWidth":390,"pixelRatio":3,"windowHeight":762,"windowWidth":390,"softVersion":"4.1.719"}',
|
|
|
- sessionId='1703337560040-27bfe208-a389-f476-db1d-840681e04b32',
|
|
|
- subSessionId='1703337569952-8f56d53c-b36d-760e-8abe-0b4a027cd5bd', senceType='1089',
|
|
|
- hotSenceType='1089', id='1050', channel='pq')
|
|
|
-
|
|
|
+ if cover:
|
|
|
+ payload = dict(pageSource='vlog-pages/post/post-video-post', videoPath=oss_object_key, width='720',
|
|
|
+ height='1280', fileExtensions='mp4', viewStatus='1', title=audio_title,
|
|
|
+ careModelStatus='1',
|
|
|
+ token='f04f58d6e664cbc9902660a1e8d20ce6cd7fdb0f', loginUid=pq_ids_list[i],
|
|
|
+ versionCode='719',
|
|
|
+ machineCode='weixin_openid_o0w175aZ4FJtqVsA1tcozJDJHdDU', appId='wx89e7eb06478361d7',
|
|
|
+ clientTimestamp='1703337579331',
|
|
|
+ machineInfo='{"sdkVersion":"3.2.5","brand":"iPhone","language":"zh_CN","model":"iPhone 12 Pro<iPhone13,3>","platform":"ios","system":"iOS 15.6.1","weChatVersion":"8.0.44","screenHeight":844,"screenWidth":390,"pixelRatio":3,"windowHeight":762,"windowWidth":390,"softVersion":"4.1.719"}',
|
|
|
+ sessionId='1703337560040-27bfe208-a389-f476-db1d-840681e04b32',
|
|
|
+ subSessionId='1703337569952-8f56d53c-b36d-760e-8abe-0b4a027cd5bd', senceType='1089',
|
|
|
+ hotSenceType='1089', id='1050', channel='pq')
|
|
|
+ else:
|
|
|
+ cover = cls.get_cover(uid)
|
|
|
+ payload = dict(pageSource='vlog-pages/post/post-video-post', videoPath=oss_object_key, width='720',
|
|
|
+ height='1280', fileExtensions='mp4', viewStatus='1', title=audio_title,
|
|
|
+ coverImgPath=cover,
|
|
|
+ careModelStatus='1',
|
|
|
+ token='f04f58d6e664cbc9902660a1e8d20ce6cd7fdb0f', loginUid=pq_ids_list[i],
|
|
|
+ versionCode='719',
|
|
|
+ machineCode='weixin_openid_o0w175aZ4FJtqVsA1tcozJDJHdDU', appId='wx89e7eb06478361d7',
|
|
|
+ clientTimestamp='1703337579331',
|
|
|
+ machineInfo='{"sdkVersion":"3.2.5","brand":"iPhone","language":"zh_CN","model":"iPhone 12 Pro<iPhone13,3>","platform":"ios","system":"iOS 15.6.1","weChatVersion":"8.0.44","screenHeight":844,"screenWidth":390,"pixelRatio":3,"windowHeight":762,"windowWidth":390,"softVersion":"4.1.719"}',
|
|
|
+ sessionId='1703337560040-27bfe208-a389-f476-db1d-840681e04b32',
|
|
|
+ subSessionId='1703337569952-8f56d53c-b36d-760e-8abe-0b4a027cd5bd', senceType='1089',
|
|
|
+ hotSenceType='1089', id='1050', channel='pq')
|
|
|
payload['videoPath'] = oss_object_key
|
|
|
payload['title'] = audio_title
|
|
|
data = urllib.parse.urlencode(payload)
|
|
@@ -388,50 +442,81 @@ class AgcVidoe():
|
|
|
subtitle_cmd = "drawtext=text='分享、转发给群友':x=(w-text_w)/2:y=h-text_h-15:fontsize=28:fontcolor=black:fontfile=/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc"
|
|
|
# 背景色参数
|
|
|
background_cmd = "drawbox=y=ih-65:color=yellow@1.0:width=iw:height=0:t=fill"
|
|
|
- VIDEO_COUNTER = 0
|
|
|
- FF_INPUT = ""
|
|
|
- FF_SCALE = ""
|
|
|
- FF_FILTER = ""
|
|
|
- ffmpeg_cmd = ["ffmpeg"]
|
|
|
- for videos in video_files:
|
|
|
- Common.logger("video").info(f"{mark}的{platform}视频:{videos[3]}")
|
|
|
- # 添加输入文件
|
|
|
- FF_INPUT += f" -i {videos[3]}"
|
|
|
- # 为每个视频文件统一长宽,并设置SAR(采样宽高比)
|
|
|
- FF_SCALE += f"[{VIDEO_COUNTER}:v]scale=320x480,setsar=1[v{VIDEO_COUNTER}];"
|
|
|
- # 为每个视频文件创建一个输入流,并添加到-filter_complex参数中
|
|
|
- FF_FILTER += f"[v{VIDEO_COUNTER}][{VIDEO_COUNTER}:a]"
|
|
|
- # 增加视频计数器
|
|
|
- VIDEO_COUNTER += 1
|
|
|
- # 构建最终的FFmpeg命令
|
|
|
- ffmpeg_cmd.extend(FF_INPUT.split())
|
|
|
- ffmpeg_cmd.extend(["-filter_complex", f"{FF_SCALE}{FF_FILTER}concat=n={VIDEO_COUNTER}:v=1:a=1[v][a]",
|
|
|
- "-map", "[v]", "-map", "[a]", v_path])
|
|
|
-
|
|
|
- # 多线程数
|
|
|
- num_threads = 4
|
|
|
- # 构建 FFmpeg 命令,生成视频
|
|
|
- ffmpeg_cmd_oss = [
|
|
|
- "ffmpeg",
|
|
|
- "-i", v_path, # 视频文件列表
|
|
|
- "-i", audio_video, # 音频文件
|
|
|
- "-c:v", "libx264", # 复制视频流
|
|
|
- "-c:a", "aac", # 编码音频流为AAC
|
|
|
- "-threads", str(num_threads),
|
|
|
- "-vf", f"{background_cmd},{subtitle_cmd}", # 添加背景色和字幕
|
|
|
- "-t", str(int(audio_duration)), # 保持与音频时长一致
|
|
|
- "-map", "0:v:0", # 映射第一个输入的视频流
|
|
|
- "-map", "1:a:0", # 映射第二个输入的音频流
|
|
|
- "-y", # 覆盖输出文件
|
|
|
- v_oss_path
|
|
|
- ]
|
|
|
- try:
|
|
|
- subprocess.run(ffmpeg_cmd)
|
|
|
- if os.path.isfile(v_path):
|
|
|
+ if platform == "koubo" or platform == "zhannei":
|
|
|
+ text_ptah = cls.bk_text_folders(mark)
|
|
|
+ with open(text_ptah, 'w') as f:
|
|
|
+ for file in video_files:
|
|
|
+ f.write(f"file '{file[3]}'\n")
|
|
|
+ # 多线程数
|
|
|
+ num_threads = 4
|
|
|
+ ffmpeg_cmd_oss = [
|
|
|
+ "ffmpeg",
|
|
|
+ "-f", "concat",
|
|
|
+ "-safe", "0",
|
|
|
+ "-i", f"{text_ptah}", # 视频文件列表
|
|
|
+ "-i", audio_video, # 音频文件
|
|
|
+ "-c:v", "libx264",
|
|
|
+ "-c:a", "aac",
|
|
|
+ "-threads", str(num_threads),
|
|
|
+ "-vf", f"scale=320x480,{background_cmd},{subtitle_cmd}", # 添加背景色和字幕
|
|
|
+ "-t", str(int(audio_duration)), # 保持与音频时长一致
|
|
|
+ "-map", "0:v:0", # 映射第一个输入的视频流
|
|
|
+ "-map", "1:a:0", # 映射第二个输入的音频流
|
|
|
+ "-y", # 覆盖输出文件
|
|
|
+ v_oss_path
|
|
|
+ ]
|
|
|
+ try:
|
|
|
subprocess.run(ffmpeg_cmd_oss)
|
|
|
- print("视频处理完成!")
|
|
|
- except subprocess.CalledProcessError as e:
|
|
|
- print(f"视频处理失败:{e}")
|
|
|
+ print("视频处理完成!")
|
|
|
+ if os.path.isfile(text_ptah):
|
|
|
+ os.remove(text_ptah)
|
|
|
+ except subprocess.CalledProcessError as e:
|
|
|
+ print(f"视频处理失败:{e}")
|
|
|
+ else:
|
|
|
+ VIDEO_COUNTER = 0
|
|
|
+ FF_INPUT = ""
|
|
|
+ FF_SCALE = ""
|
|
|
+ FF_FILTER = ""
|
|
|
+ ffmpeg_cmd = ["ffmpeg"]
|
|
|
+ for videos in video_files:
|
|
|
+ Common.logger("video").info(f"{mark}的{platform}视频:{videos[3]}")
|
|
|
+ # 添加输入文件
|
|
|
+ FF_INPUT += f" -i {videos[3]}"
|
|
|
+ # 为每个视频文件统一长宽,并设置SAR(采样宽高比)
|
|
|
+ FF_SCALE += f"[{VIDEO_COUNTER}:v]scale=320x480,setsar=1[v{VIDEO_COUNTER}];"
|
|
|
+ # 为每个视频文件创建一个输入流,并添加到-filter_complex参数中
|
|
|
+ FF_FILTER += f"[v{VIDEO_COUNTER}][{VIDEO_COUNTER}:a]"
|
|
|
+ # 增加视频计数器
|
|
|
+ VIDEO_COUNTER += 1
|
|
|
+ # 构建最终的FFmpeg命令
|
|
|
+ ffmpeg_cmd.extend(FF_INPUT.split())
|
|
|
+ ffmpeg_cmd.extend(["-filter_complex", f"{FF_SCALE}{FF_FILTER}concat=n={VIDEO_COUNTER}:v=1:a=1[v][a]",
|
|
|
+ "-map", "[v]", "-map", "[a]", v_path])
|
|
|
+
|
|
|
+ # 多线程数
|
|
|
+ num_threads = 4
|
|
|
+ # 构建 FFmpeg 命令,生成视频
|
|
|
+ ffmpeg_cmd_oss = [
|
|
|
+ "ffmpeg",
|
|
|
+ "-i", v_path, # 视频文件列表
|
|
|
+ "-i", audio_video, # 音频文件
|
|
|
+ "-c:v", "libx264", # 复制视频流
|
|
|
+ "-c:a", "aac", # 编码音频流为AAC
|
|
|
+ "-threads", str(num_threads),
|
|
|
+ "-vf", f"{background_cmd},{subtitle_cmd}", # 添加背景色和字幕
|
|
|
+ "-t", str(int(audio_duration)), # 保持与音频时长一致
|
|
|
+ "-map", "0:v:0", # 映射第一个输入的视频流
|
|
|
+ "-map", "1:a:0", # 映射第二个输入的音频流
|
|
|
+ "-y", # 覆盖输出文件
|
|
|
+ v_oss_path
|
|
|
+ ]
|
|
|
+ try:
|
|
|
+ subprocess.run(ffmpeg_cmd)
|
|
|
+ if os.path.isfile(v_path):
|
|
|
+ subprocess.run(ffmpeg_cmd_oss)
|
|
|
+ print("视频处理完成!")
|
|
|
+ except subprocess.CalledProcessError as e:
|
|
|
+ print(f"视频处理失败:{e}")
|
|
|
print(f"{mark}的{platform}:视频拼接成功啦~~~")
|
|
|
Common.logger("video").info(f"{mark}的{platform}:视频拼接成功啦~~~")
|
|
|
return video_files
|
|
@@ -459,8 +544,6 @@ class AgcVidoe():
|
|
|
yhmw_count = 0
|
|
|
else:
|
|
|
yhmw_count = int(int(yhmw_all_count)/2)
|
|
|
-
|
|
|
-
|
|
|
# 如果没有该文件目录则创建,有文件目录的话 则删除文件
|
|
|
s_path, v_path, video_path_url, v_oss_path = cls.create_folders(mark)
|
|
|
|
|
@@ -481,7 +564,7 @@ class AgcVidoe():
|
|
|
Feishu.bot('recommend', 'AGC完成通知', '今日常规自制视频拼接任务完成啦~', mark, mark_name)
|
|
|
return mark
|
|
|
# 获取音频类型+字幕+标题
|
|
|
- uid, srt, video_list = Material.get_all_data(feishu_id, link, mark)
|
|
|
+ uid, srt, video_list, cover_status = Material.get_all_data(feishu_id, link, mark)
|
|
|
# 获取已入库的用户id
|
|
|
user_id = cls.get_user_id(platform, mark)
|
|
|
# 获取 未使用的视频链接
|
|
@@ -534,7 +617,7 @@ class AgcVidoe():
|
|
|
cls.insert_videoAudio(video_files, uid, platform, mark)
|
|
|
Common.logger("video").info(f"{mark}的{platform}渠道完成已使用视频存入数据库")
|
|
|
Common.logger("video").info(f"{mark}的{platform}渠道开始视频添加到对应用户")
|
|
|
- piaoquantv = cls.insert_piaoquantv(oss_object_key, audio_title, pq_ids_list)
|
|
|
+ piaoquantv = cls.insert_piaoquantv(oss_object_key, audio_title, pq_ids_list, cover_status, uid)
|
|
|
if piaoquantv:
|
|
|
Common.logger("video").info(f"{mark}的{platform}渠道视频添加到对应用户成功")
|
|
|
if os.path.isfile(v_oss_path):
|
|
@@ -576,7 +659,7 @@ class AgcVidoe():
|
|
|
# Feishu.bot('recommend', 'AGC完成通知', '今日脚本跟随视频拼接任务完成啦~', mark.split("-")[0], mark_name)
|
|
|
# return mark
|
|
|
# 获取音频类型+字幕+标题
|
|
|
- uid, srt, video_list = Material.get_all_data(feishu_id, link, mark)
|
|
|
+ uid, srt, video_list, cover = Material.get_all_data(feishu_id, link, mark)
|
|
|
platform_list = ex_list["platform_list"] # 渠道
|
|
|
# 如果没有该文件目录则创建,有文件目录的话 则删除文件
|
|
|
s_path, v_path, video_path_url, v_oss_path = cls.create_folders(mark)
|
|
@@ -651,7 +734,7 @@ class AgcVidoe():
|
|
|
cls.insert_videoAudio(video_files, uid, platform, mark)
|
|
|
Common.logger("gs_video").info(f"{mark}的{platform}渠道完成已使用视频存入数据库")
|
|
|
Common.logger("gs_video").info(f"{mark}的{platform}渠道开始视频添加到对应用户")
|
|
|
- piaoquantv = cls.insert_piaoquantv(oss_object_key, audio_title, pq_ids_list)
|
|
|
+ piaoquantv = cls.insert_piaoquantv(oss_object_key, audio_title, pq_ids_list, cover, uid)
|
|
|
if piaoquantv:
|
|
|
Common.logger("gs_video").info(f"{mark}的{platform}渠道视频添加到对应用户成功")
|
|
|
if os.path.isfile(v_oss_path):
|
|
@@ -690,6 +773,7 @@ class AgcVidoe():
|
|
|
uid = data['uid'] # 音频id
|
|
|
srt = data['text'] # srt
|
|
|
videos = data['video']
|
|
|
+ cover = data['cover']
|
|
|
if ',' in videos:
|
|
|
videos = videos.split(',')
|
|
|
else:
|
|
@@ -735,7 +819,7 @@ class AgcVidoe():
|
|
|
Common.logger("bk_video").info(f"{mark}拼接视频发送成功,OSS 地址:{oss_object_key}")
|
|
|
time.sleep(10)
|
|
|
Common.logger("bk_video").info(f"{mark}开始视频添加到对应用户")
|
|
|
- piaoquantv = cls.insert_piaoquantv(oss_object_key, audio_title, pq_ids_list)
|
|
|
+ piaoquantv = cls.insert_piaoquantv(oss_object_key, audio_title, pq_ids_list, cover, uid)
|
|
|
if piaoquantv:
|
|
|
Common.logger("bk_video").info(f"{mark}视频添加到对应用户成功")
|
|
|
if os.path.isfile(v_oss_path):
|