瀏覽代碼

报警调整

zhangyong 11 月之前
父節點
當前提交
74d82e5b20
共有 3 個文件被更改,包括 117 次插入4 次删除
  1. 1 1
      common/feishu_utils.py
  2. 115 1
      common/ffmpeg.py
  3. 1 2
      video_rewriting/video_data.py

+ 1 - 1
common/feishu_utils.py

@@ -174,7 +174,7 @@ class Feishu:
 
     # 合并单元格
     @classmethod
-    def merge_cells(cls, log_type, crawler, sheetid, ranges):
+    def merge_cells(cls, crawler, sheetid, ranges):
         """
         合并单元格
         :param log_type: 日志路径

+ 115 - 1
common/ffmpeg.py

@@ -108,7 +108,121 @@ class FFmpeg():
                       str(pw_duration), '-pix_fmt', 'yuv420p', '-c:a', 'aac', '-strict', 'experimental', '-shortest',
                       '-vf', f"scale=320x480,{background_cmd},{subtitle_cmd}", pw_path]
         subprocess.run(ffmpeg_cmd)
-        return  pw_path
+        return pw_path
+
+
+    """
+    设置统一格式拼接视频
+    """
+    @classmethod
+    def concatenate_videos(cls, video_files, concatenated_video_path):
+        # 拼接视频
+        VIDEO_COUNTER = 0
+        FF_INPUT = ""
+        FF_SCALE = ""
+        FF_FILTER = ""
+        ffmpeg_cmd = ["ffmpeg"]
+        for videos in video_files:
+            # 添加输入文件
+            FF_INPUT += f" -i {videos}"
+            # 为每个视频文件统一长宽,并设置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]", concatenated_video_path])
+        subprocess.run(ffmpeg_cmd)
+
+        return concatenated_video_path
+
+
+    """
+    单个视频拼接
+    """
+    @classmethod
+    def single_video(cls):
+        text_ptah = cls.bk_text_folders(mark)
+        video_files = cls.concat_videos_with_subtitles(videos, audio_duration, platform, mark)
+        with open(text_ptah, 'w') as f:
+            for file in video_files:
+                f.write(f"file '{file}'\n")
+        if video_files == "":
+            return ""
+        if os.path.exists(s_path):
+            # subtitle_cmd = f"subtitles={s_path}:force_style='Fontsize=11,Fontname=Hiragino Sans GB,Outline=0,PrimaryColour=&H000000,SecondaryColour=&H000000'"
+            subtitle_cmd = f"subtitles={s_path}:force_style='Fontsize=12,Fontname=wqy-zenhei,Bold=1,Outline=0,PrimaryColour=&H000000,SecondaryColour=&H000000'"
+        else:
+            # subtitle_cmd = "drawtext=text='分享、转发给群友':fontsize=28:fontcolor=black:x=(w-text_w)/2:y=h-text_h-15"
+            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"
+        # 多线程数
+        num_threads = 4
+        # 构建 FFmpeg 命令,生成视频
+        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("视频处理完成!")
+            if os.path.isfile(text_ptah):
+                os.remove(text_ptah)
+        except subprocess.CalledProcessError as e:
+            print(f"视频处理失败:{e}")
+        print(f"{mark}:视频拼接成功啦~~~")
+        return video_files
+
+    # 计算需要拼接的视频
+    @classmethod
+    def concat_videos_with_subtitles(cls, videos, audio_duration, platform, mark):
+        # 计算视频文件列表总时长
+        if platform == "baokuai":
+            total_video_duration = sum(cls.get_video_duration(video_file) for video_file in videos)
+        else:
+            total_video_duration = sum(cls.get_video_duration(video_file[3]) for video_file in videos)
+        if platform == "koubo" or platform == "zhannei" or platform == "baokuai":
+            # 视频时长大于音频时长
+            if total_video_duration > audio_duration:
+                return videos
+            # 计算音频秒数与视频秒数的比率,然后加一得到需要的视频数量
+            video_audio_ratio = audio_duration / total_video_duration
+            videos_needed = int(video_audio_ratio) + 2
+            trimmed_video_list = videos * videos_needed
+            return trimmed_video_list
+        else:
+            # 如果视频总时长小于音频时长,则不做拼接
+            if total_video_duration < audio_duration:
+                return ""
+            # 如果视频总时长大于音频时长,则截断视频
+            trimmed_video_list = []
+            remaining_duration = audio_duration
+            for video_file in videos:
+                video_duration = cls.get_video_duration(video_file[3])
+                if video_duration <= remaining_duration:
+                    # 如果视频时长小于或等于剩余时长,则将整个视频添加到列表中
+                    trimmed_video_list.append(video_file)
+                    remaining_duration -= video_duration
+                else:
+                    trimmed_video_list.append(video_file)
+                    break
+            return trimmed_video_list
 
 
 

+ 1 - 2
video_rewriting/video_data.py

@@ -97,7 +97,7 @@ class getVideo():
                             Common.logger("log").info(f"{task_mark}下的视频ID{id},{new_video_path}视频下载失败")
                             continue
                         oss_id = cls.random_id()
-                        oss_object_key = Oss.stitching_sync_upload_oss(new_video_path, oss_id)
+                        oss_object_key = Oss.stitching_sync_upload_oss(new_video_path, oss_id)  # 视频发送OSS
                         status = oss_object_key.get("status")
                         if status == 200:
                             # 获取 oss 视频地址
@@ -123,7 +123,6 @@ class getVideo():
                         Feishu.bot(mark, '机器自动改造消息通知', f'{task_mark}任务改造完成,请关注', name)
                 if video_id != 'None' and video_id != '' and video_id != None:
                     Feishu.bot(mark, '机器自动改造消息通知', f'{task_mark}任务改造完成,请关注', name)
-
             except Exception as e:
                 Common.logger("warning").warning(f"{name}的{task_mark}任务处理失败:{e}\n")
         return mark