如何实现在线同步/更新文件夹并实时对文件进行降尺寸/降采样处理?
如何实现在线同步/更新文件夹并实时对文件进行降尺寸/降采样处理?
我来给你捋捋怎么实现这个需求,刚好这类同步+实时处理的场景我之前也折腾过,给你两个可行的方案,一个是灵活度拉满的Python自定义脚本方案,另一个是用工具组合快速上手的方案,都能覆盖你提出的所有要求:
方案一:Python自定义同步脚本(推荐,完全满足所有要求)
这个方案可以实现边读取源文件边处理写入目标,不需要先全拷贝源文件,完美节省临时空间,而且能精准控制每一步逻辑。
核心思路
遍历源文件夹的所有文件,按规则过滤、判断是否需要更新,对需要处理的文件直接用对应库实时处理后写入目标,其他文件原样同步。
具体实现步骤
1. 准备依赖
先安装需要的Python库:
pip install pillow ffmpeg-python
另外系统需要安装ffmpeg(处理音视频用,各大系统包管理器都能装,比如Ubuntu用apt install ffmpeg,Mac用brew install ffmpeg)。
2. 编写脚本
下面是一个完整的示例脚本,你可以根据自己的需求修改配置:
import os import shutil from PIL import Image import ffmpeg # -------------------------- 配置区 -------------------------- SOURCE_DIR = "/path/to/your/source/folder" # 源文件夹路径 TARGET_DIR = "/path/to/your/target/folder" # 目标文件夹路径 # 需要处理降尺寸/降采样的文件类型 PROCESS_EXTENSIONS = (".jpg", ".jpeg", ".png", ".mp4", ".flac") # 完全忽略的文件类型(不会同步到目标) IGNORE_EXTENSIONS = (".tmp", ".log", ".bak", ".swp") # 源→目标的文件类型转换映射(比如flac转mp3) TYPE_MAPPING = {".flac": ".mp3"} # 给处理过的文件加后缀(不需要就设为空字符串) PROCESSED_SUFFIX = "_compressed" # ----------------------------------------------------------- def process_media(source_path, target_path): """根据文件类型执行对应的降质处理""" ext = os.path.splitext(source_path)[1].lower() # 图片处理:缩放到最长边1920px,优化质量 if ext in (".jpg", ".jpeg", ".png"): with Image.open(source_path) as img: max_side = 1920 width, height = img.size if width > max_side or height > max_side: scale_ratio = min(max_side / width, max_side / height) new_size = (int(width * scale_ratio), int(height * scale_ratio)) img = img.resize(new_size, Image.Resampling.LANCZOS) img.save(target_path, optimize=True, quality=85) # 视频处理:缩放到720p,降低码率 elif ext == ".mp4": ffmpeg.input(source_path).output( target_path, vf="scale=-2:720", # 保持宽高比缩放到720p crf=28, # 视频质量(值越大文件越小,23-30是常用范围) acodec="aac", ab="128k" # 音频转aac,128k码率 ).run(quiet=True) # 音频处理:flac转mp3,降采样到44.1kHz,128k码率 elif ext == ".flac": ffmpeg.input(source_path).output( target_path, acodec="libmp3lame", ab="128k", ar="44100" ).run(quiet=True) def sync_folders(): """核心同步逻辑""" for root, _, files in os.walk(SOURCE_DIR): # 计算当前目录对应的目标目录路径 relative_path = os.path.relpath(root, SOURCE_DIR) target_root = os.path.join(TARGET_DIR, relative_path) # 创建目标目录(不存在则自动创建) os.makedirs(target_root, exist_ok=True) for file in files: source_file = os.path.join(root, file) filename, ext = os.path.splitext(file) ext = ext.lower() # 跳过需要忽略的文件类型 if ext in IGNORE_EXTENSIONS: continue # 确定目标文件的扩展名和文件名 target_ext = TYPE_MAPPING.get(ext, ext) if PROCESSED_SUFFIX and ext in PROCESS_EXTENSIONS: target_filename = f"{filename}{PROCESSED_SUFFIX}{target_ext}" else: target_filename = f"{filename}{target_ext}" target_file = os.path.join(target_root, target_filename) # 判断是否需要处理/同步:目标不存在,或源文件更新时间更晚 need_update = False if not os.path.exists(target_file): need_update = True else: source_mtime = os.path.getmtime(source_file) target_mtime = os.path.getmtime(target_file) if source_mtime > target_mtime: need_update = True if need_update: print(f"正在处理: {source_file} → {target_file}") if ext in PROCESS_EXTENSIONS: # 处理媒体文件并写入目标 process_media(source_file, target_file) else: # 原样同步其他文件(保留元数据) shutil.copy2(source_file, target_file) if __name__ == "__main__": sync_folders()
3. 脚本的优势(对应你的所有要求)
- ✅ 特定文件类型实时处理:
process_media函数专门处理图片/音视频,其他文件直接同步 - ✅ 忽略指定类型:通过
IGNORE_EXTENSIONS配置过滤 - ✅ 避免冗余处理:通过文件修改时间判断是否需要更新
- ✅ 实时处理不占临时空间:直接读取源文件处理后写入目标,不需要中间拷贝
- ✅ 支持文件类型转换:通过
TYPE_MAPPING配置实现(比如flac转mp3) - ✅ 可选添加处理后缀:通过
PROCESSED_SUFFIX配置控制
4. 进阶优化
如果需要实时监控源文件夹变化(一有文件修改/新增就自动处理),可以安装watchdog库监听文件事件:
pip install watchdog
然后修改脚本,用watchdog的事件处理器触发同步逻辑,网上有很多现成的示例,很容易整合。
方案二:rsync + 自定义脚本(快速上手,适合简单场景)
如果你不想写Python脚本,可以用rsync(Linux/macOS自带,Windows可以装cwRsync)配合脚本实现,但这个方案会先把源文件同步到临时目录,再处理后移动到目标,会占用临时空间,适合对临时空间要求不高的场景。
核心步骤
- 用
rsync同步源文件夹到目标的临时子目录,过滤掉需要忽略的文件:
rsync -av --exclude='*.tmp' --exclude='*.log' /path/to/source/ /path/to/target/temp/
- 编写一个脚本遍历临时目录的文件,对需要处理的类型执行降质处理,转换类型并添加后缀后移动到最终目标目录,同时删除临时文件。
- 用cron(Linux/macOS)或任务计划(Windows)定期运行上述命令和脚本,实现定时同步。
这个方案的缺点是需要临时空间存放未处理的文件,但优点是快速上手,不需要写复杂的同步逻辑。
备注:内容来源于stack exchange,提问作者boernsen
相关产品推荐
相关产品推荐

