فهرست منبع

增加口播视频拼接 功能

zhangyong 1 سال پیش
والد
کامیت
042d70c147
2فایلهای تغییر یافته به همراه146 افزوده شده و 50 حذف شده
  1. 42 0
      common/material.py
  2. 104 50
      video_stitching/video_stitching.py

+ 42 - 0
common/material.py

@@ -70,6 +70,48 @@ class Material():
             if item[0] == '管理后台':
                 return item[1]
 
+    # 获取音频类型
+    @classmethod
+    def get_audio_type(cls):
+        audio_type = [{"audio": "音画美文--美文类", "type": "6VXm7q"}, {"audio": "音画美文--通用类", "type": "aSNFl8"},
+                      {"audio": "口播--美文类", "type": "Sed8gy"}]
+        audio_type = random.choice(audio_type)
+
+        type_audio = audio_type['audio']
+        type = audio_type['type']
+        audio_type = Feishu.get_values_batch("prod", "succinct", type)
+        list = []
+        title_list = []
+        if type_audio == "口播--美文类":
+            for row in audio_type[1:]:
+                audio_id = row[2]
+                text = row[3]
+                title = row[4]
+                number = {"audio_id": audio_id, "text": text}
+                list.append(number)
+                title_list.append(title)
+
+            list = random.choice(list)
+            audio_id = list['audio_id']
+            srt = list['text']
+            return audio_id, srt, title_list, type_audio
+        else:
+            for row in audio_type[1:]:
+                audio_id = row[0]
+                text = row[1]
+                title = row[2]
+                number = {"audio_id": audio_id, "text": text}
+                list.append(number)
+                title_list.append(title)
+            list = random.choice(list)
+            audio_id = list['audio_id']
+            srt = list['text']
+            return audio_id, srt, title_list, type_audio
+
+
+
+
+
 
 
 

+ 104 - 50
video_stitching/video_stitching.py

@@ -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"视频添加到对应用户成功")
                     # 关闭视频文件