|
@@ -10,6 +10,7 @@ import resource
|
|
|
import requests
|
|
|
import urllib.parse
|
|
|
|
|
|
+from moviepy.video.compositing.concatenate import concatenate
|
|
|
|
|
|
sys.path.append(os.getcwd())
|
|
|
from datetime import datetime
|
|
@@ -61,6 +62,19 @@ class VideoStitching():
|
|
|
machine="",
|
|
|
)
|
|
|
|
|
|
+
|
|
|
+
|
|
|
+ @classmethod
|
|
|
+ def insert_video_typeAudio(cls, video, audio_id):
|
|
|
+ current_time = datetime.now()
|
|
|
+ formatted_time = current_time.strftime("%Y-%m-%d")
|
|
|
+ insert_sql = f"""INSERT INTO video_audio (audio, account_id, oss_object_key, time) values ('{audio_id}', '{video}', '{video}', '{formatted_time}')"""
|
|
|
+ MysqlHelper.update_values(
|
|
|
+ sql=insert_sql,
|
|
|
+ env="prod",
|
|
|
+ machine="",
|
|
|
+ )
|
|
|
+
|
|
|
# 随机生成id
|
|
|
@classmethod
|
|
|
def random_id(cls):
|
|
@@ -76,6 +90,12 @@ class VideoStitching():
|
|
|
account_id = MysqlHelper.get_values(account_id, "prod")
|
|
|
return account_id
|
|
|
|
|
|
+ @classmethod
|
|
|
+ def get_audio_list(cls):
|
|
|
+ audio_list = f"""select oss_object_key from video_koubo_url;"""
|
|
|
+ audio_list = MysqlHelper.get_values(audio_list, "prod")
|
|
|
+ return audio_list
|
|
|
+
|
|
|
|
|
|
@classmethod
|
|
|
def get_url_list(cls, audio_id, account):
|
|
@@ -87,14 +107,22 @@ class VideoStitching():
|
|
|
url_list = MysqlHelper.get_values(url_list, "prod")
|
|
|
return url_list
|
|
|
|
|
|
+ @classmethod
|
|
|
+ def get_audio_url_list(cls, choice_audio, audio_id):
|
|
|
+ url_list = f"""SELECT audio FROM video_audio where audio = '{audio_id}' and oss_object_key = '{choice_audio}';"""
|
|
|
+ url_list = MysqlHelper.get_values(url_list, "prod")
|
|
|
+ return url_list
|
|
|
+
|
|
|
# 新生成视频上传到对应账号下
|
|
|
@classmethod
|
|
|
- def insert_piaoquantv(cls, oss_object_key):
|
|
|
+ def insert_piaoquantv(cls, oss_object_key, title_list):
|
|
|
code = 1
|
|
|
list = ["66481136", "66481137", "66481140", "66481141", "66481142"]
|
|
|
for i in range(2):
|
|
|
item = random.choice(list)
|
|
|
- title = Material.get_title()
|
|
|
+ title_list = [item for item in title_list if item is not None]
|
|
|
+ title = random.choice(title_list)
|
|
|
+ # title = title[0].strip("[]'")
|
|
|
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=title, careModelStatus='1',
|
|
@@ -130,7 +158,7 @@ class VideoStitching():
|
|
|
|
|
|
# 视频拼接
|
|
|
@classmethod
|
|
|
- def concatenate_videos(cls, videos, audio, srt):
|
|
|
+ def concatenate_videos(cls, videos, audio, srt, type_audio):
|
|
|
clips = []
|
|
|
total_duration = 0
|
|
|
included_videos = []
|
|
@@ -145,38 +173,51 @@ class VideoStitching():
|
|
|
|
|
|
# 获取音频时长(以秒为单位)
|
|
|
duration_limit = mp3.duration
|
|
|
-
|
|
|
- # 遍历每个视频并计算总时长
|
|
|
- for i, video in enumerate(videos):
|
|
|
- clip = VideoFileClip(f"https://art-crawler.oss-cn-hangzhou.aliyuncs.com/{video[2]}")
|
|
|
- clips.append(clip)
|
|
|
- total_duration += clip.duration
|
|
|
- if total_duration >= duration_limit:
|
|
|
- break
|
|
|
-
|
|
|
- # 如果总时长小于等于目标时长,则不做视频拼接
|
|
|
- if total_duration <= duration_limit:
|
|
|
- Common.logger().info(f"时长小于等于目标时长,不做视频拼接")
|
|
|
- # 关闭视频文件
|
|
|
- for clip in clips:
|
|
|
- clip.close()
|
|
|
- return ""
|
|
|
+ if type_audio == "口播--美文类":
|
|
|
+ # 读取视频文件,获取视频时长
|
|
|
+ clip = f"https://art-crawler.oss-cn-hangzhou.aliyuncs.com/{videos[0]}"
|
|
|
+ clip = VideoFileClip(clip)
|
|
|
+ video_duration = clip.duration
|
|
|
+ # 计算需要循环播放的视频个数
|
|
|
+ n_videos = int(duration_limit / video_duration) + 1
|
|
|
+ # 循环生成视频剪辑
|
|
|
+ video_clips = [clip] * n_videos
|
|
|
+ # 连接视频剪辑
|
|
|
+ final_clip = concatenate(video_clips, method="compose")
|
|
|
+ # 设置最终剪辑的时长与音频时长一致
|
|
|
+ final_clip = final_clip.set_duration(duration_limit)
|
|
|
else:
|
|
|
- Common.logger().info(f"总时长大于目标时长")
|
|
|
- remaining_time = duration_limit
|
|
|
- final_clips = []
|
|
|
-
|
|
|
- for clip, video in zip(clips, videos):
|
|
|
- if remaining_time - clip.duration >= 0:
|
|
|
- final_clips.append(clip)
|
|
|
- included_videos.append(video)
|
|
|
- remaining_time -= clip.duration
|
|
|
- else:
|
|
|
- # 如果剩余时间不足以加入下一个视频,则截断当前视频并返回已包含的URL
|
|
|
- final_clips.append(clip.subclip(0, remaining_time))
|
|
|
- included_videos.append(video)
|
|
|
+ # 遍历每个视频并计算总时长
|
|
|
+ for i, video in enumerate(videos):
|
|
|
+ clip = VideoFileClip(f"https://art-crawler.oss-cn-hangzhou.aliyuncs.com/{video[2]}")
|
|
|
+ clips.append(clip)
|
|
|
+ total_duration += clip.duration
|
|
|
+ if total_duration >= duration_limit:
|
|
|
break
|
|
|
- final_clip = concatenate_videoclips(final_clips)
|
|
|
+
|
|
|
+ # 如果总时长小于等于目标时长,则不做视频拼接
|
|
|
+ if total_duration <= duration_limit:
|
|
|
+ Common.logger().info(f"时长小于等于目标时长,不做视频拼接")
|
|
|
+ # 关闭视频文件
|
|
|
+ for clip in clips:
|
|
|
+ clip.close()
|
|
|
+ return ""
|
|
|
+ else:
|
|
|
+ Common.logger().info(f"总时长大于目标时长")
|
|
|
+ remaining_time = duration_limit
|
|
|
+ final_clips = []
|
|
|
+
|
|
|
+ for clip, video in zip(clips, videos):
|
|
|
+ if remaining_time - clip.duration >= 0:
|
|
|
+ final_clips.append(clip)
|
|
|
+ included_videos.append(video)
|
|
|
+ remaining_time -= clip.duration
|
|
|
+ else:
|
|
|
+ # 如果剩余时间不足以加入下一个视频,则截断当前视频并返回已包含的URL
|
|
|
+ final_clips.append(clip.subclip(0, remaining_time))
|
|
|
+ included_videos.append(video)
|
|
|
+ break
|
|
|
+ final_clip = concatenate_videoclips(final_clips)
|
|
|
final_clip = final_clip.set_audio(mp3)
|
|
|
# 统一设置视频分辨率
|
|
|
final_width = 320
|
|
@@ -196,10 +237,8 @@ class VideoStitching():
|
|
|
# 获取字幕
|
|
|
subtitle_clips = []
|
|
|
for match in matches:
|
|
|
- start = cls.srt_to_seconds(match[0])
|
|
|
- start = editor.cvsecs(start)
|
|
|
- end = cls.srt_to_seconds(match[1])
|
|
|
- end = editor.cvsecs(end)
|
|
|
+ start = editor.cvsecs(cls.srt_to_seconds(match[0]))
|
|
|
+ end = editor.cvsecs(cls.srt_to_seconds(match[1]))
|
|
|
text = match[2].strip()
|
|
|
text = cls.split_text(text, 10)
|
|
|
# /System/Library/Fonts/Hiragino Sans GB.ttc 本地字体
|
|
@@ -275,26 +314,38 @@ class VideoStitching():
|
|
|
@classmethod
|
|
|
def video_stitching(cls):
|
|
|
cookie = Material.get_houtai_cookie()
|
|
|
- # 获取音频
|
|
|
- audio_id, srt = Material.get_audio()
|
|
|
- # 获取已入库的用户id
|
|
|
- account_id = cls.get_account_id()
|
|
|
- account = random.choice(account_id)
|
|
|
- account = str(account).replace('(', '').replace(')', '').replace(',', '')
|
|
|
- Common.logger().info(f"获取用户ID:{account}")
|
|
|
- # 获取 未使用的视频链接
|
|
|
- url_list = cls.get_url_list(audio_id, account)
|
|
|
+ # 获取音频类型+字幕
|
|
|
+ audio_id, srt, title_list, type_audio = Material.get_audio_type()
|
|
|
+ if type_audio == "口播--美文类":
|
|
|
+ # 获取已入库的口播视频
|
|
|
+ audio_list = cls.get_audio_list()
|
|
|
+ videos = [list(item) for item in audio_list]
|
|
|
+ videos = random.choice(videos) #随机选择视频
|
|
|
+ # 判断该视频+音频是否生成过视频
|
|
|
+ video = VideoStitching.get_audio_url_list(videos, audio_id)
|
|
|
+ if video:
|
|
|
+ Common.logger().info(f"该该视频+音频已经生成过视频,不做视频拼接")
|
|
|
+ return
|
|
|
+ else:
|
|
|
+ # 获取已入库的用户id
|
|
|
+ account_id = cls.get_account_id()
|
|
|
+ account = random.choice(account_id)
|
|
|
+ account = str(account).replace('(', '').replace(')', '').replace(',', '')
|
|
|
+ Common.logger().info(f"获取用户ID:{account}")
|
|
|
+ # 获取 未使用的视频链接
|
|
|
+ url_list = cls.get_url_list(audio_id, account)
|
|
|
+ videos = [list(item) for item in url_list]
|
|
|
# 获取音频url
|
|
|
audio = cls.get_audio_url(audio_id, cookie)
|
|
|
if audio == "":
|
|
|
Common.logger().info(f"获取音频地址为空")
|
|
|
return
|
|
|
Common.logger().info(f"获取音频地址:{audio},获取用户id:{audio_id}")
|
|
|
- videos = [list(item) for item in url_list]
|
|
|
+
|
|
|
# videos = Oss.get_oss_url(videos)
|
|
|
# 视频截取
|
|
|
try:
|
|
|
- audio_url, video_with_subtitles, clips = cls.concatenate_videos(videos, str(audio), srt)
|
|
|
+ audio_url, video_with_subtitles, clips = cls.concatenate_videos(videos, str(audio), srt, type_audio)
|
|
|
if len(audio_url) == 0:
|
|
|
Common.logger().info(f"视频生成失败")
|
|
|
# 随机生成视频id
|
|
@@ -309,14 +360,17 @@ class VideoStitching():
|
|
|
if status == 200:
|
|
|
time.sleep(10)
|
|
|
# 发送成功 已使用视频存入数据库
|
|
|
- cls.insert_videoAudio(audio_url, audio_id)
|
|
|
+ if type_audio == "口播--美文类":
|
|
|
+ cls.insert_video_typeAudio(videos[0], audio_id)
|
|
|
+ else:
|
|
|
+ cls.insert_videoAudio(audio_url, audio_id)
|
|
|
Common.logger().info(f"发送成功 已使用视频存入数据库完成")
|
|
|
if os.path.isfile(output_path):
|
|
|
os.remove(output_path)
|
|
|
Common.logger().info(f"文件删除成功{output_path}")
|
|
|
else:
|
|
|
Common.logger().info(f"文件不存在{output_path}")
|
|
|
- piaoquantv = cls.insert_piaoquantv(oss_object_key)
|
|
|
+ piaoquantv = cls.insert_piaoquantv(oss_object_key, title_list)
|
|
|
if piaoquantv:
|
|
|
Common.logger().info(f"视频添加到对应用户成功")
|
|
|
# 关闭视频文件
|