yiyang-8
Initial commit: Integrated video processing, image editing, and AI models
b2c32a9
"""
视频处理模块 - 基于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']}")