zhangyong 2 månader sedan
förälder
incheckning
96d3e6d30b
2 ändrade filer med 74 tillägg och 39 borttagningar
  1. 1 1
      carry_video/nrfx_carry_video.py
  2. 73 38
      common/ffmpeg.py

+ 1 - 1
carry_video/nrfx_carry_video.py

@@ -321,7 +321,7 @@ class NrfxCarryViode:
             logger.info(f"[+] 内容分析-片尾音频下载成功")
             logger.info(f"[+] 内容分析-片尾获取最后一帧成功")
             jpg_path = FFmpeg.video_png(video_path, file_path)  # 生成视频最后一帧jpg
-            pw_path = FFmpeg.pw_video(jpg_path, file_path, pw_mp3_path, pw_srt)  # 生成片尾视频
+            pw_path = FFmpeg.nrfx_pw_video(jpg_path, file_path, pw_mp3_path, pw_srt)  # 生成片尾视频
             if not os.path.exists(pw_path) or os.path.getsize(pw_path) == 0:
                 logger.error(f"[+] 内容分析-片尾拼接失败")
                 AliyunLogger.logging(data["name"], "内容分析", "", data["video_url"],

+ 73 - 38
common/ffmpeg.py

@@ -244,10 +244,61 @@ class FFmpeg():
         return 0
 
     """
-     生成片尾视频
+    生成片尾视频
     """
     @classmethod
     def pw_video(cls, jpg_path, file_path, pw_mp3_path, pw_srt):
+        # 添加音频到图片
+        """
+        jpg_url 图片地址
+        pw_video 提供的片尾视频
+        pw_duration  提供的片尾视频时长
+        new_video_path 视频位置
+        subtitle_cmd 字幕
+        pw_url 生成视频地址
+        :return:
+        """
+        pw_srt_path = file_path + 'pw_video.srt'
+        with open(pw_srt_path, 'w') as f:
+            f.write(pw_srt)
+        pw_url_path = file_path + 'pw_video.mp4'
+        try:
+            pw_duration = cls.get_mp3_duration(pw_mp3_path)
+            if pw_duration == 0:
+                return pw_url_path
+            time.sleep(2)
+            # 添加字幕 wqy-zenhei  Hiragino Sans GB
+            height = 1080
+            margin_v = int(height) // 8  # 可根据需要调整字幕和背景之间的距离
+            subtitle_cmd = f"subtitles={pw_srt_path}:force_style='Fontsize=13,Fontname=wqy-zenhei,Outline=0,PrimaryColour=&H000000,SecondaryColour=&H000000,Bold=1,MarginV={margin_v}'"
+            bg_position_offset = (int(360) - 360 // 8) / 1.75
+            background_cmd = f"drawbox=y=(ih-{int(360)}/2-{bg_position_offset}):color=yellow@1.0:width=iw:height={int(360)}/4:t=fill"
+
+            cls.asyncio_run_subprocess([
+                'ffmpeg',
+                '-loop', '1',
+                '-i', jpg_path,  # 输入的图片文件
+                '-i', pw_mp3_path,  # 输入的音频文件
+                '-c:v', 'libx264',  # 视频编码格式
+                '-t', str(pw_duration),  # 输出视频的持续时间,与音频持续时间相同
+                '-pix_fmt', 'yuv420p',  # 像素格式
+                '-c:a', 'aac',  # 音频编码格式
+                '-strict', 'experimental',  # 使用实验性编码器
+                '-shortest',  # 确保输出视频的长度与音频一致
+                '-vf', f"{background_cmd},{subtitle_cmd}",  # 视频过滤器,设置分辨率和其他过滤器
+                pw_url_path  # 输出的视频文件路径
+            ], timeout=500)
+            if os.path.exists(pw_srt_path):
+                os.remove(pw_srt_path)
+            return pw_url_path
+        except Exception as e:
+            return pw_url_path
+
+    """
+     生成片尾视频
+    """
+    @classmethod
+    def nrfx_pw_video(cls, jpg_path, file_path, pw_mp3_path, pw_srt):
         # 添加音频到图片
         """
         jpg_url 图片地址
@@ -273,43 +324,27 @@ class FFmpeg():
             subtitle_cmd = f"subtitles={pw_srt_path}:force_style='Fontsize=13,Fontname=wqy-zenhei,Outline=0,PrimaryColour=&H000000,SecondaryColour=&H000000,Bold=1,MarginV={margin_v}'"
             bg_position_offset = (int(360) - 360//8) / 1.75
             background_cmd = f"drawbox=y=(ih-{int(360)}/2-{bg_position_offset}):color=yellow@1.0:width=iw:height={int(360)}/4:t=fill"
-            if "mp4" in jpg_path:
-                pw_path_txt = file_path + 'pw_path_video.txt'
-                with open(pw_path_txt, 'w') as f:
-                    f.write(f"file '{jpg_path}'\n")
-                cls.asyncio_run_subprocess([
-                    "ffmpeg",
-                    "-f", "concat",
-                    "-safe", "0",
-                    "-i", f"{pw_path_txt}",  # 视频序列输入的文本文件
-                    "-i", pw_mp3_path,  # 音频文件
-                    "-c:v", "libx264",  # 视频编码格式
-                    "-t", str(pw_duration),  # 输出视频的持续时间
-                    "-c:a", "aac",  # 音频编码格式
-                    "-b:v", "260k",  # 视频比特率
-                    "-b:a", "96k",  # 音频比特率
-                    "-threads", "2",  # 线程数
-                    "-vf", f"{background_cmd},{subtitle_cmd}",  # 视频过滤器(背景和字幕)
-                    "-map", "0:v:0",  # 映射视频流来自第一个输入文件(视频)
-                    "-map", "1:a:0",  # 映射音频流来自第二个输入文件(音频)
-                    "-y",  # 强制覆盖输出文件
-                    pw_url_path  # 输出文件路径
-                ], timeout=500)
-            else:
-                cls.asyncio_run_subprocess([
-                    'ffmpeg',
-                    '-loop', '1',
-                    '-i', jpg_path,  # 输入的图片文件
-                    '-i', pw_mp3_path,  # 输入的音频文件
-                    '-c:v', 'libx264',  # 视频编码格式
-                    '-t', str(pw_duration),  # 输出视频的持续时间,与音频持续时间相同
-                    '-pix_fmt', 'yuv420p',  # 像素格式
-                    '-c:a', 'aac',  # 音频编码格式
-                    '-strict', 'experimental',  # 使用实验性编码器
-                    '-shortest',  # 确保输出视频的长度与音频一致
-                    '-vf', f"{background_cmd},{subtitle_cmd}",  # 视频过滤器,设置分辨率和其他过滤器
-                    pw_url_path  # 输出的视频文件路径
-                ], timeout=500)
+            pw_path_txt = file_path + 'pw_path_video.txt'
+            with open(pw_path_txt, 'w') as f:
+                f.write(f"file '{jpg_path}'\n")
+            cls.asyncio_run_subprocess([
+                "ffmpeg",
+                "-f", "concat",
+                "-safe", "0",
+                "-i", f"{pw_path_txt}",  # 视频序列输入的文本文件
+                "-i", pw_mp3_path,  # 音频文件
+                "-c:v", "libx264",  # 视频编码格式
+                "-t", str(pw_duration),  # 输出视频的持续时间
+                "-c:a", "aac",  # 音频编码格式
+                "-b:v", "260k",  # 视频比特率
+                "-b:a", "96k",  # 音频比特率
+                "-threads", "2",  # 线程数
+                "-vf", f"{background_cmd},{subtitle_cmd}",  # 视频过滤器(背景和字幕)
+                "-map", "0:v:0",  # 映射视频流来自第一个输入文件(视频)
+                "-map", "1:a:0",  # 映射音频流来自第二个输入文件(音频)
+                "-y",  # 强制覆盖输出文件
+                pw_url_path  # 输出文件路径
+            ], timeout=500)
             if os.path.exists(pw_srt_path):
                 os.remove(pw_srt_path)
             return pw_url_path