|  | @@ -126,39 +126,37 @@ class VideoStitching():
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      # 视频拼接
 | 
	
		
			
				|  |  |      @classmethod
 | 
	
		
			
				|  |  | -    def concatenate_videos(cls, videos, audio, srt):
 | 
	
		
			
				|  |  | +    def concatenate_videos(cls, videos, audio, srt, output_path):
 | 
	
		
			
				|  |  | +        # 设置最大可使用内存限制(单位:字节)
 | 
	
		
			
				|  |  | +        memory_limit = 4 * 1024 * 1024 * 1024  # 4GB
 | 
	
		
			
				|  |  | +        resource.setrlimit(resource.RLIMIT_AS, (memory_limit, memory_limit))
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          clips = []
 | 
	
		
			
				|  |  | -        total_duration = 0
 | 
	
		
			
				|  |  |          included_videos = []
 | 
	
		
			
				|  |  | -        # 设置最大可使用的内存限制(单位:字节)
 | 
	
		
			
				|  |  | -        memory_limit = 2 * 1024 * 1024 * 1024  # 2GB
 | 
	
		
			
				|  |  | -        resource.setrlimit(resource.RLIMIT_AS, (memory_limit, memory_limit))
 | 
	
		
			
				|  |  | +        total_duration = 0
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          # 提取视频的音频
 | 
	
		
			
				|  |  | -        Common.logger().info(f"开始提取视频的音频{audio}")
 | 
	
		
			
				|  |  | -        video1 = VideoFileClip(audio)
 | 
	
		
			
				|  |  | +        video1 = editor.VideoFileClip(audio)
 | 
	
		
			
				|  |  |          mp3 = video1.audio
 | 
	
		
			
				|  |  | -        Common.logger().info(f"提取视频的音频成功")
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          # 获取音频时长(以秒为单位)
 | 
	
		
			
				|  |  |          duration_limit = mp3.duration
 | 
	
		
			
				|  |  | +        Common.logger().info(f"音频时长为:{duration_limit}")
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          # 遍历每个视频并计算总时长
 | 
	
		
			
				|  |  |          for i, video in enumerate(videos):
 | 
	
		
			
				|  |  | -            clip = VideoFileClip(video[3])
 | 
	
		
			
				|  |  | +            clip = editor.VideoFileClip(video[3])
 | 
	
		
			
				|  |  |              clips.append(clip)
 | 
	
		
			
				|  |  |              total_duration += clip.duration
 | 
	
		
			
				|  |  |              if total_duration >= duration_limit:
 | 
	
		
			
				|  |  |                  break
 | 
	
		
			
				|  |  | -            # 处理完毕后释放视频剪辑对象
 | 
	
		
			
				|  |  | -            clip.close()
 | 
	
		
			
				|  |  | -            Common.logger().info(f"处理完毕后释放视频剪辑对象")
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          # 如果总时长小于等于目标时长,则不做视频拼接
 | 
	
		
			
				|  |  |          if total_duration <= duration_limit:
 | 
	
		
			
				|  |  | -            Common.logger().info(f"时长小于等于目标时长,不做视频拼接")
 | 
	
		
			
				|  |  | +            Common.logger().info(f"总时长小于等于目标时长,则不做视频拼接")
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |              return ""
 | 
	
		
			
				|  |  |          else:
 | 
	
		
			
				|  |  | -            Common.logger().info(f"总时长大于目标时长")
 | 
	
		
			
				|  |  |              remaining_time = duration_limit
 | 
	
		
			
				|  |  |              final_clips = []
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -172,64 +170,69 @@ class VideoStitching():
 | 
	
		
			
				|  |  |                      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 = 480
 | 
	
		
			
				|  |  | -        final_height = 720
 | 
	
		
			
				|  |  | -        final_clip = final_clip.resize((final_width, final_height))
 | 
	
		
			
				|  |  | -        # 设置背景色
 | 
	
		
			
				|  |  | -        color_clip = editor.ColorClip(size=(final_width, 120),
 | 
	
		
			
				|  |  | -                                      color=(255, 255, 0)).set_duration(duration_limit)
 | 
	
		
			
				|  |  | -        final_clip = editor.CompositeVideoClip([final_clip, color_clip.set_position(("center", final_height - 100))])
 | 
	
		
			
				|  |  | -        # 处理SRT字幕文件
 | 
	
		
			
				|  |  | -        subtitle_file = f"./video_stitching/video/{srt}.srt"
 | 
	
		
			
				|  |  | -        Common.logger().info(f"处理SRT字幕文件")
 | 
	
		
			
				|  |  | -        if os.path.isfile(subtitle_file):
 | 
	
		
			
				|  |  | -            with open(subtitle_file, 'r') as file:
 | 
	
		
			
				|  |  | -                subtitles = file.read().strip().split('\n\n')
 | 
	
		
			
				|  |  | -            # 从SRT字幕文件中获取字幕
 | 
	
		
			
				|  |  | -            subtitle_clips = []
 | 
	
		
			
				|  |  | -            for subtitle in subtitles:
 | 
	
		
			
				|  |  | -                # 按行分割字幕内容
 | 
	
		
			
				|  |  | -                subtitle_lines = subtitle.strip().split('\n')
 | 
	
		
			
				|  |  | -                # 提取时间轴信息和字幕文本
 | 
	
		
			
				|  |  | -                if len(subtitle_lines) >= 3:
 | 
	
		
			
				|  |  | -                    times, text = subtitle_lines[1], '\n'.join(subtitle_lines[2:])
 | 
	
		
			
				|  |  | -                    start, end = map(cls.srt_to_seconds, times.split(' --> '))
 | 
	
		
			
				|  |  | -                    start = editor.cvsecs(start)
 | 
	
		
			
				|  |  | -                    end = editor.cvsecs(end)
 | 
	
		
			
				|  |  | -                text = cls.split_text(text, 10)
 | 
	
		
			
				|  |  | -                # /System/Library/Fonts/Hiragino Sans GB.ttc 本地字体
 | 
	
		
			
				|  |  | -                Common.logger().info(f"字幕:{text}")
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                sub = editor.TextClip(text, font="/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc",
 | 
	
		
			
				|  |  | -                                      fontsize=30, color="black").set_duration(end - start).set_start(
 | 
	
		
			
				|  |  | -                    start).set_position(
 | 
	
		
			
				|  |  | -                    ("center", final_height - 80)).set_opacity(0.8)
 | 
	
		
			
				|  |  | -                subtitle_clips.append(sub)
 | 
	
		
			
				|  |  | -            Common.logger().info(f"将字幕添加到视频上")
 | 
	
		
			
				|  |  | -            # 将字幕添加到视频上
 | 
	
		
			
				|  |  | -            video_with_subtitles = editor.CompositeVideoClip([final_clip] + subtitle_clips)
 | 
	
		
			
				|  |  | -        else:
 | 
	
		
			
				|  |  | -            text_clip = (
 | 
	
		
			
				|  |  | -                editor.TextClip("分享、转发给群友", font="/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc",
 | 
	
		
			
				|  |  | -                                fontsize=30, color="black").
 | 
	
		
			
				|  |  | -                    set_position(("center", final_height - 80)).
 | 
	
		
			
				|  |  | -                    set_duration(duration_limit).
 | 
	
		
			
				|  |  | -                    set_opacity(0.8)
 | 
	
		
			
				|  |  | -            )
 | 
	
		
			
				|  |  | -            # 把 `文本剪贴板` 贴在视频上
 | 
	
		
			
				|  |  | -            video_with_subtitles = editor.CompositeVideoClip([final_clip, text_clip])
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        # 生成视频
 | 
	
		
			
				|  |  | -        video_with_subtitles.write_videofile(output_path, codec='libx264', fps=24)
 | 
	
		
			
				|  |  | -        if os.path.isfile(output_path):
 | 
	
		
			
				|  |  | -            Common.logger().info("视频生成成功!生成路径为:", output_path)
 | 
	
		
			
				|  |  | -            return included_videos
 | 
	
		
			
				|  |  | -        else:
 | 
	
		
			
				|  |  | -            Common.logger().info("视频生成失败,请检查代码和文件路径。")
 | 
	
		
			
				|  |  | -            return ""
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            final_clip = editor.concatenate_videoclips(final_clips)
 | 
	
		
			
				|  |  | +            final_clip = final_clip.set_audio(mp3)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            # 统一设置视频分辨率
 | 
	
		
			
				|  |  | +            final_width = 480
 | 
	
		
			
				|  |  | +            final_height = 720
 | 
	
		
			
				|  |  | +            final_clip = final_clip.resize((final_width, final_height))
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            # 设置背景色
 | 
	
		
			
				|  |  | +            color_clip = editor.ColorClip(size=(final_width, 120), color=(255, 255, 0)).set_duration(duration_limit)
 | 
	
		
			
				|  |  | +            final_clip = editor.CompositeVideoClip(
 | 
	
		
			
				|  |  | +                [final_clip, color_clip.set_position(("center", final_height - 100))])
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            # 处理SRT字幕文件
 | 
	
		
			
				|  |  | +            Common.logger().info(f"处理SRT字幕文件")
 | 
	
		
			
				|  |  | +            subtitle_file = f"./video_stitching/video/{srt}.srt"
 | 
	
		
			
				|  |  | +            if os.path.isfile(subtitle_file):
 | 
	
		
			
				|  |  | +                with open(subtitle_file, 'r') as file:
 | 
	
		
			
				|  |  | +                    subtitles = file.read().strip().split('\n\n')
 | 
	
		
			
				|  |  | +                # 从SRT字幕文件中获取字幕
 | 
	
		
			
				|  |  | +                subtitle_clips = []
 | 
	
		
			
				|  |  | +                for subtitle in subtitles:
 | 
	
		
			
				|  |  | +                    # 按行分割字幕内容
 | 
	
		
			
				|  |  | +                    subtitle_lines = subtitle.strip().split('\n')
 | 
	
		
			
				|  |  | +                    # 提取时间轴信息和字幕文本
 | 
	
		
			
				|  |  | +                    if len(subtitle_lines) >= 3:
 | 
	
		
			
				|  |  | +                        times, text = subtitle_lines[1], '\n'.join(subtitle_lines[2:])
 | 
	
		
			
				|  |  | +                        start, end = map(cls.srt_to_seconds, times.split(' --> '))
 | 
	
		
			
				|  |  | +                        start = editor.cvsecs(start)
 | 
	
		
			
				|  |  | +                        end = editor.cvsecs(end)
 | 
	
		
			
				|  |  | +                        text = cls.split_text(text, 10)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                        sub = editor.TextClip(text, font="/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc",
 | 
	
		
			
				|  |  | +                                              fontsize=30, color="black").set_duration(end - start).set_start(
 | 
	
		
			
				|  |  | +                            start).set_position(
 | 
	
		
			
				|  |  | +                            ("center", final_height - 80)).set_opacity(0.8)
 | 
	
		
			
				|  |  | +                        subtitle_clips.append(sub)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                # 将字幕添加到视频上
 | 
	
		
			
				|  |  | +                video_with_subtitles = editor.CompositeVideoClip([final_clip] + subtitle_clips)
 | 
	
		
			
				|  |  | +            else:
 | 
	
		
			
				|  |  | +                text_clip = (
 | 
	
		
			
				|  |  | +                    editor.TextClip("分享、转发给群友", font="/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc",
 | 
	
		
			
				|  |  | +                                    fontsize=30, color="black").
 | 
	
		
			
				|  |  | +                        set_position(("center", final_height - 80)).
 | 
	
		
			
				|  |  | +                        set_duration(duration_limit).
 | 
	
		
			
				|  |  | +                        set_opacity(0.8)
 | 
	
		
			
				|  |  | +                )
 | 
	
		
			
				|  |  | +                # 把 `文本剪贴板` 贴在视频上
 | 
	
		
			
				|  |  | +                video_with_subtitles = editor.CompositeVideoClip([final_clip, text_clip])
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            # 生成视频
 | 
	
		
			
				|  |  | +            Common.logger().info(f"开始生成视频")
 | 
	
		
			
				|  |  | +            video_with_subtitles.write_videofile(output_path, codec='libx264', fps=24, temp_audiofile="temp-audio.m4a",
 | 
	
		
			
				|  |  | +                                                 remove_temp=True, audio_codec="aac")
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            if os.path.isfile(output_path):
 | 
	
		
			
				|  |  | +                Common.logger().info("视频生成成功!生成路径为:", output_path)
 | 
	
		
			
				|  |  | +                return included_videos
 | 
	
		
			
				|  |  | +            else:
 | 
	
		
			
				|  |  | +                Common.logger().info("视频生成失败,请检查代码和文件路径。")
 | 
	
		
			
				|  |  | +                return ""
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 |