""" 视频处理模块 - 基于MoviePy Video Processing Module - Based on MoviePy 本模块提供视频编辑、剪辑、合成等功能 This module provides video editing, clipping, and composition features """ from typing import Optional, List, Tuple import warnings try: from moviepy.editor import ( VideoFileClip, AudioFileClip, ImageClip, TextClip, CompositeVideoClip, concatenate_videoclips, vfx ) MOVIEPY_AVAILABLE = True except ImportError: MOVIEPY_AVAILABLE = False warnings.warn("moviepy库未安装,请运行: pip install moviepy") class VideoEditor: """视频编辑器""" def __init__(self, video_path: Optional[str] = None): """ 初始化视频编辑器 Args: video_path: 视频文件路径 """ if not MOVIEPY_AVAILABLE: raise ImportError("需要安装moviepy库") self.video = None if video_path: self.load_video(video_path) def load_video(self, video_path: str): """ 加载视频文件 Args: video_path: 视频文件路径 """ self.video = VideoFileClip(video_path) return self def cut_video(self, start_time: float, end_time: float) -> 'VideoEditor': """ 剪辑视频 Args: start_time: 开始时间(秒) end_time: 结束时间(秒) Returns: VideoEditor实例 """ if self.video is None: raise ValueError("请先加载视频") self.video = self.video.subclip(start_time, end_time) return self def resize_video(self, width: Optional[int] = None, height: Optional[int] = None) -> 'VideoEditor': """ 调整视频尺寸 Args: width: 目标宽度 height: 目标高度 Returns: VideoEditor实例 """ if self.video is None: raise ValueError("请先加载视频") if width and height: self.video = self.video.resize((width, height)) elif width: self.video = self.video.resize(width=width) elif height: self.video = self.video.resize(height=height) return self def add_audio(self, audio_path: str) -> 'VideoEditor': """ 添加音频 Args: audio_path: 音频文件路径 Returns: VideoEditor实例 """ if self.video is None: raise ValueError("请先加载视频") audio = AudioFileClip(audio_path) self.video = self.video.set_audio(audio) return self def add_text(self, text: str, position: Tuple[int, int] = ('center', 'center'), duration: Optional[float] = None, fontsize: int = 50, color: str = 'white') -> 'VideoEditor': """ 添加文字 Args: text: 文字内容 position: 文字位置 duration: 显示时长(秒),None表示整个视频时长 fontsize: 字体大小 color: 字体颜色 Returns: VideoEditor实例 """ if self.video is None: raise ValueError("请先加载视频") if duration is None: duration = self.video.duration txt_clip = TextClip(text, fontsize=fontsize, color=color) txt_clip = txt_clip.set_position(position).set_duration(duration) self.video = CompositeVideoClip([self.video, txt_clip]) return self def speed_up(self, factor: float = 2.0) -> 'VideoEditor': """ 加速视频 Args: factor: 加速倍数 Returns: VideoEditor实例 """ if self.video is None: raise ValueError("请先加载视频") self.video = self.video.fx(vfx.speedx, factor) return self def fade_in(self, duration: float = 1.0) -> 'VideoEditor': """ 添加淡入效果 Args: duration: 淡入时长(秒) Returns: VideoEditor实例 """ if self.video is None: raise ValueError("请先加载视频") self.video = self.video.fx(vfx.fadein, duration) return self def fade_out(self, duration: float = 1.0) -> 'VideoEditor': """ 添加淡出效果 Args: duration: 淡出时长(秒) Returns: VideoEditor实例 """ if self.video is None: raise ValueError("请先加载视频") self.video = self.video.fx(vfx.fadeout, duration) return self def save(self, output_path: str, fps: int = 24, codec: str = 'libx264'): """ 保存视频 Args: output_path: 输出文件路径 fps: 帧率 codec: 视频编码器 """ if self.video is None: raise ValueError("请先加载视频") self.video.write_videofile(output_path, fps=fps, codec=codec) def get_info(self) -> dict: """ 获取视频信息 Returns: 包含视频信息的字典 """ if self.video is None: raise ValueError("请先加载视频") return { 'duration': self.video.duration, 'fps': self.video.fps, 'size': self.video.size, 'width': self.video.w, 'height': self.video.h } class VideoMerger: """视频合并器""" @staticmethod def merge_videos(video_paths: List[str], output_path: str, method: str = 'concatenate'): """ 合并多个视频 Args: video_paths: 视频文件路径列表 output_path: 输出文件路径 method: 合并方法,'concatenate'表示顺序连接 """ if not MOVIEPY_AVAILABLE: raise ImportError("需要安装moviepy库") clips = [VideoFileClip(path) for path in video_paths] if method == 'concatenate': final_clip = concatenate_videoclips(clips) else: raise ValueError(f"不支持的合并方法: {method}") final_clip.write_videofile(output_path) # 清理资源 for clip in clips: clip.close() final_clip.close() # 使用示例 if __name__ == "__main__": # 创建视频编辑器 editor = VideoEditor("input_video.mp4") # 剪辑视频(0-10秒) editor.cut_video(0, 10) # 调整尺寸为720p editor.resize_video(width=1280, height=720) # 添加淡入淡出效果 editor.fade_in(1.0).fade_out(1.0) # 保存视频 editor.save("output_video.mp4") # 获取视频信息 info = editor.get_info() print(f"视频时长: {info['duration']}秒") print(f"视频尺寸: {info['width']}x{info['height']}")