1. 从“artcraft”这个名字说起:一个被低估的创作工具链思路
第一次看到“artcraft”这个标题,我脑子里蹦出来的不是某个具体软件,而是一种工作方式——把“art”(艺术创作)和“craft”(手艺、工艺、精雕细琢)捏在一起。这恰恰是很多创作者最缺的东西:有想法,但落不了地;有工具,但串不成线。artcraft 这个项目,本质上就是一套面向个人创作者的轻量级创作流水线,它不追求大而全,而是把“从灵感捕捉到成品输出”这条路上最硌脚的几个环节,用一套统一的思路给磨平了。
我之所以对这个标题感兴趣,是因为过去几年我接触过大量独立创作者、小型工作室和业余爱好者,他们面临的痛点出奇地一致:素材散落在各个文件夹、版本管理靠“最终版2.0”、输出格式每次都要手动调、想批量处理又不会写脚本。artcraft 要解决的,就是这种“创作过程中的摩擦力”。它适合谁?适合那些不想被复杂工程化工具绑架、但又需要一定自动化能力的创作者,比如做图文排版、短视频素材整理、手绘扫描件后期、播客音频粗剪的人。哪怕你只会点鼠标,也能通过它把重复劳动压缩掉一大半。
这篇文章我会从设计思路、核心模块、实操流程、踩坑记录四个维度,把 artcraft 这类项目拆开揉碎讲清楚。所有细节都是基于我实际搭建类似工作流时的经验补全的,你可以直接抄作业,也可以按自己的需求改。
2. 整体设计思路:为什么是“流水线”而不是“工具箱”
2.1 创作流程的四个断点
大部分创作者的日常是这样的:手机拍了一堆素材,导到电脑上,挑出能用的,修一修,排版或剪辑,导出,发布。听起来简单,但每个环节都在漏时间。我观察下来,断点集中在四个地方:
- 采集断点:素材来源太多,相机、手机、扫描仪、录屏、网页下载,命名规则全不一样,混在一起就乱。
- 筛选断点:拍了一百张,能用的可能就五张,但你要一张张点开看,眼睛都花了。
- 处理断点:调色、裁剪、加水印、转格式,每个操作单独做都不难,但重复一百次就是折磨。
- 输出断点:不同平台要求不同尺寸、不同码率、不同命名,每次都要重新导一遍。
artcraft 的设计思路,就是用一条可配置的流水线把这四个断点串起来。它不是让你学一个新软件,而是让你把已有的工具(比如系统自带的图片查看器、免费的音频编辑器、命令行工具)通过一套规则连接起来。核心思想是:一次定义,批量执行,随时回滚。
2.2 为什么选择“配置驱动”而不是“全自动”
很多人一听到自动化,就想着“一键完成所有事”。但实际创作中,完全自动往往意味着失控。比如自动裁剪可能把主体切掉,自动调色可能把氛围毁掉。artcraft 这类项目通常采用“配置驱动”的方式:你定义好规则,它按规则执行,但每一步都可以人工干预或跳过。
我试过纯脚本全自动处理一批活动照片,结果因为光线差异太大,自动白平衡把一些暖色调的温馨场景调成了冷冰冰的蓝调。后来改成“配置驱动+人工确认关键节点”,效率虽然略低一点,但成品可用率从六成提到了九成以上。这个取舍很关键:自动化处理的是“确定性劳动”,人工保留的是“审美判断”。
2.3 模块拆解:一个典型的 artcraft 式架构
基于常见实践,这类项目通常包含以下模块,我用一个表格来对照说明:
| 模块名称 | 核心职责 | 常见实现方式 | 关键配置项 |
|---|---|---|---|
| 采集器 | 统一导入素材 | 监听文件夹、命令行导入、API拉取 | 源路径、命名模板、去重规则 |
| 预处理器 | 初步筛选与标准化 | 缩略图生成、元数据读取、格式转换 | 尺寸阈值、格式白名单、EXIF保留策略 |
| 处理器 | 核心编辑操作 | 图像处理库、音频处理库、视频转码工具 | 操作链、参数集、条件分支 |
| 输出器 | 按目标平台导出 | 模板引擎、批量重命名、格式封装 | 输出路径、命名规则、质量参数 |
| 日志与回滚 | 记录与恢复 | 操作日志、版本快照 | 日志级别、快照频率、保留数量 |
这个架构的好处是每个模块可以独立替换。比如你不想用命令行工具做图像处理,换成图形界面的批处理软件也行,只要输出格式对得上。artcraft 的“craft”就体现在这里:它不是造一个万能工具,而是造一套连接件。
3. 核心细节解析:从素材到成品的每个关键点
3.1 素材采集:命名规范比工具更重要
我见过太多人把时间浪费在“找文件”上。artcraft 的第一个核心细节,就是强制统一的命名规范。常见做法是采用“日期_项目_序号_描述”的格式,比如20250412_手绘扫描_003_线稿.png。为什么这么设计?
- 日期在前:按时间排序时天然有序,不用额外排序。
- 项目名居中:方便用通配符批量筛选,比如
*手绘扫描*。 - 序号补零:
003而不是3,保证文件管理器里顺序正确。 - 描述可选:给未来的自己留线索,但不要过长。
注意:命名规范一旦定下,就不要中途改。我试过中途把日期格式从
20250412改成2025-04-12,结果旧文件和新文件混在一起,排序全乱了,最后花了一个小时手动重命名。
采集环节还有一个容易被忽略的点:去重。同一张图可能被导入两次,或者手机自动备份和手动拷贝重复了。artcraft 通常会计算文件哈希值(比如 MD5),只保留第一次出现的。这个操作在命令行里一行就能搞定,但手动做几乎不可能。
3.2 预处理器:缩略图与元数据的妙用
预处理器阶段最值得投入的是缩略图生成和元数据提取。缩略图让你快速浏览,元数据让你快速筛选。比如你拍了一组照片,想挑出所有用某款镜头拍的,或者所有在某个时间段拍的,直接读 EXIF 信息就能过滤。
我自己的习惯是:导入后先生成 200px 宽的缩略图,放在一个单独的_thumbs文件夹里。然后用图片查看器快速翻一遍,把不要的缩略图删掉,再写个脚本把对应的原图也删掉。这个“缩略图筛选法”比直接看原图快至少三倍,因为加载速度快,而且不会误删——你删的是缩略图,原图还在,确认无误后再批量清理。
元数据还有一个用途:自动分类。比如根据图片的宽高比,自动分成横版、竖版、方版三个文件夹。根据音频的时长,自动分成短音频(<1分钟)、中音频(1-5分钟)、长音频(>5分钟)。这些规则写一次,以后每次导入都自动执行。
3.3 处理器:操作链的设计哲学
处理器是 artcraft 最核心的部分,也是最容易设计得过于复杂的地方。我的经验是:操作链不要超过五步。超过五步,调试成本急剧上升,而且中间任何一步出错,后面全废。
一个典型的图像处理操作链可能是这样的:
- 自动旋转(根据 EXIF 方向)
- 裁剪到目标比例
- 调整大小到目标分辨率
- 应用轻度锐化
- 添加水印
每一步都有参数,比如裁剪比例是 16:9 还是 4:3,锐化强度是 0.5 还是 1.0。这些参数不要写死在代码里,而是放在一个配置文件里,比如 JSON 或 YAML。这样你换一个项目,只改配置,不改逻辑。
# 示例配置:图像处理链 steps: - action: auto_rotate - action: crop ratio: "16:9" anchor: "center" - action: resize width: 1920 height: 1080 fit: "cover" - action: sharpen amount: 0.8 - action: watermark image: "logo.png" position: "bottom-right" opacity: 0.6这个配置文件的好处是可读、可版本管理、可复用。你可以在 Git 里跟踪它的变化,知道什么时候改了哪个参数。我试过把参数直接写在脚本里,结果三个月后想改一个水印位置,找了半天才找到那行代码。
3.4 输出器:一次处理,多端适配
输出环节最烦人的是不同平台要求不同。同一个视频,发到 A 平台要 1080p 横版,发到 B 平台要 720p 竖版,发到 C 平台要 1:1 方版。手动导三遍,每次都要重新设置参数。
artcraft 的输出器通常采用模板化导出。你定义几个输出模板,每个模板对应一个平台,然后一次性生成所有版本。比如:
| 模板名称 | 分辨率 | 比例 | 格式 | 码率 | 命名后缀 |
|---|---|---|---|---|---|
| 横版高清 | 1920x1080 | 16:9 | MP4 | 8Mbps | _hd |
| 竖版短视频 | 1080x1920 | 9:16 | MP4 | 6Mbps | _vertical |
| 方版社交 | 1080x1080 | 1:1 | MP4 | 5Mbps | _square |
| 预览低码 | 640x360 | 16:9 | MP4 | 1Mbps | _preview |
这样你只需要点一次“导出”,所有版本自动生成,命名也统一。后续上传时,按后缀找文件就行,不用再打开编辑软件。
提示:输出路径最好按“项目名/日期/平台”三层结构组织,比如
输出/手绘项目/20250412/横版高清/。这样时间久了也不会乱,找文件时按时间或平台都能快速定位。
4. 实操过程:从零搭建一条 artcraft 流水线
4.1 环境准备与工具选型
搭建 artcraft 式流水线,不需要昂贵的软件。基于常见实践,我推荐以下组合:
- 图像处理:ImageMagick(命令行)或 Pillow(Python 库)。ImageMagick 胜在命令简单,Pillow 胜在灵活可编程。
- 音频处理:FFmpeg(命令行)或 pydub(Python 库)。FFmpeg 几乎支持所有格式,pydub 更适合做精细剪辑。
- 视频处理:FFmpeg 是首选,没有之一。转码、裁剪、加水印、调码率,一条命令搞定。
- 批量重命名:Advanced Renamer(图形界面)或 Python 脚本。图形界面适合新手,脚本适合复杂规则。
- 版本管理:Git(本地仓库即可)。不要用“最终版”“最终版2”“最终版真的最终”这种命名,用 Git 管理配置文件和脚本。
安装 ImageMagick 和 FFmpeg 在各大操作系统上都很简单,Windows 可以用包管理器(如 Chocolatey),macOS 用 Homebrew,Linux 用 apt 或 yum。Python 库直接用 pip 安装。
# 示例:安装常用工具(以 macOS 为例) brew install imagemagick brew install ffmpeg pip install pillow pydub4.2 第一步:建立项目目录结构
目录结构决定了你找文件的速度。我习惯用这样的结构:
artcraft_project/ ├── config/ # 配置文件 │ ├── image_pipeline.yaml │ ├── audio_pipeline.yaml │ └── output_templates.yaml ├── input/ # 原始素材(只读,不修改) │ ├── 20250412_手绘扫描/ │ └── 20250413_录音素材/ ├── workspace/ # 中间处理文件 │ ├── thumbs/ │ └── temp/ ├── output/ # 最终成品 │ ├── 20250412_手绘扫描/ │ │ ├── 横版高清/ │ │ └── 方版社交/ │ └── 20250413_录音素材/ └── scripts/ # 处理脚本 ├── process_images.py └── process_audio.py关键原则:input 目录永远不修改。所有操作都在 workspace 或 output 里进行。这样万一处理错了,原始素材还在,重新跑一遍就行。
4.3 第二步:编写图像处理脚本
下面是一个基于 Python 和 Pillow 的简化脚本,实现了自动旋转、裁剪、缩放、锐化、加水印的完整链条。你可以直接复制修改。
import os import yaml from PIL import Image, ImageEnhance, ImageOps def load_config(path): with open(path, 'r', encoding='utf-8') as f: return yaml.safe_load(f) def process_image(input_path, output_path, config): img = Image.open(input_path) # 1. 自动旋转 img = ImageOps.exif_transpose(img) # 2. 裁剪到目标比例 target_ratio = config['crop']['ratio'] w, h = img.size target_w, target_h = map(int, target_ratio.split(':')) target_ratio_val = target_w / target_h current_ratio = w / h if current_ratio > target_ratio_val: new_w = int(h * target_ratio_val) left = (w - new_w) // 2 img = img.crop((left, 0, left + new_w, h)) else: new_h = int(w / target_ratio_val) top = (h - new_h) // 2 img = img.crop((0, top, w, top + new_h)) # 3. 缩放到目标尺寸 img = img.resize((config['resize']['width'], config['resize']['height']), Image.LANCZOS) # 4. 锐化 enhancer = ImageEnhance.Sharpness(img) img = enhancer.enhance(config['sharpen']['amount']) # 5. 加水印 if config.get('watermark'): watermark = Image.open(config['watermark']['image']).convert('RGBA') watermark = watermark.resize((int(img.width * 0.15), int(img.width * 0.15 * watermark.height / watermark.width))) # 调整透明度 alpha = watermark.split()[3] alpha = alpha.point(lambda p: p * config['watermark']['opacity']) watermark.putalpha(alpha) # 粘贴到右下角 pos = (img.width - watermark.width - 20, img.height - watermark.height - 20) img.paste(watermark, pos, watermark) # 保存 img.save(output_path, quality=config.get('quality', 90)) if __name__ == '__main__': config = load_config('config/image_pipeline.yaml') input_dir = 'input/20250412_手绘扫描' output_dir = 'output/20250412_手绘扫描/横版高清' os.makedirs(output_dir, exist_ok=True) for filename in os.listdir(input_dir): if filename.lower().endswith(('.png', '.jpg', '.jpeg', '.tiff')): input_path = os.path.join(input_dir, filename) output_path = os.path.join(output_dir, filename) process_image(input_path, output_path, config) print(f'处理完成: {filename}')这个脚本的核心逻辑是读配置、按步骤执行、输出到指定目录。你可以把image_pipeline.yaml里的参数改一改,就能适配不同的项目需求。
4.4 第三步:音频批量处理实操
音频处理的需求通常集中在:统一音量、去除首尾静音、转成统一格式、按长度分割。下面是一个基于 pydub 的示例:
from pydub import AudioSegment from pydub.silence import detect_leading_silence import os def process_audio(input_path, output_path, target_loudness=-20.0): audio = AudioSegment.from_file(input_path) # 去除首尾静音 start_trim = detect_leading_silence(audio, silence_threshold=-50.0, chunk_size=10) end_trim = detect_leading_silence(audio.reverse(), silence_threshold=-50.0, chunk_size=10) audio = audio[start_trim:len(audio)-end_trim] # 统一音量(简单增益调整) change_in_dBFS = target_loudness - audio.dBFS audio = audio.apply_gain(change_in_dBFS) # 导出为统一格式 audio.export(output_path, format='mp3', bitrate='192k') if __name__ == '__main__': input_dir = 'input/20250413_录音素材' output_dir = 'output/20250413_录音素材/统一格式' os.makedirs(output_dir, exist_ok=True) for filename in os.listdir(input_dir): if filename.lower().endswith(('.wav', '.m4a', '.flac', '.mp3')): input_path = os.path.join(input_dir, filename) output_path = os.path.join(output_dir, os.path.splitext(filename)[0] + '.mp3') process_audio(input_path, output_path) print(f'处理完成: {filename}')这里的关键参数是target_loudness,我一般设 -20 dBFS,适合播客和视频配音。如果你做的是音乐,可能需要 -14 dBFS 左右。这个值没有绝对标准,根据你的发布平台调整。
4.5 第四步:输出模板配置与批量导出
输出模板的配置我建议用 YAML,因为可读性好,而且支持注释。下面是一个视频输出模板的示例:
templates: - name: "横版高清" width: 1920 height: 1080 format: "mp4" video_bitrate: "8M" audio_bitrate: "192k" suffix: "_hd" - name: "竖版短视频" width: 1080 height: 1920 format: "mp4" video_bitrate: "6M" audio_bitrate: "128k" suffix: "_vertical" - name: "方版社交" width: 1080 height: 1080 format: "mp4" video_bitrate: "5M" audio_bitrate: "128k" suffix: "_square"然后用 FFmpeg 批量执行:
#!/bin/bash # 批量导出脚本示例 INPUT_FILE="workspace/temp/final_cut.mp4" OUTPUT_DIR="output/20250412_视频项目" while IFS= read -r line; do # 解析 YAML 行(简化处理,实际可用 yq 工具) name=$(echo "$line" | grep -oP '(?<=name: ").*(?=")') width=$(echo "$line" | grep -oP '(?<=width: ).*') height=$(echo "$line" | grep -oP '(?<=height: ).*') bitrate=$(echo "$line" | grep -oP '(?<=video_bitrate: ").*(?=")') suffix=$(echo "$line" | grep -oP '(?<=suffix: ").*(?=")') mkdir -p "$OUTPUT_DIR/$name" ffmpeg -i "$INPUT_FILE" \ -vf "scale=$width:$height:force_original_aspect_ratio=decrease,pad=$width:$height:(ow-iw)/2:(oh-ih)/2" \ -c:v libx264 -b:v "$bitrate" \ -c:a aac -b:a 128k \ "$OUTPUT_DIR/$name/output${suffix}.mp4" done < <(grep -A6 'name:' config/output_templates.yaml)这个脚本的核心是 FFmpeg 的scale和pad滤镜组合,保证视频按比例缩放后居中填充,不会变形。force_original_aspect_ratio=decrease确保画面完整,pad补黑边。
5. 常见问题与排查技巧实录
5.1 图像处理中的典型坑
问题一:EXIF 方向导致图片旋转错误。很多手机拍的照片在文件里存的是横向数据,但 EXIF 里标记了“需要旋转 90 度”。如果你直接读图不处理 EXIF,图片就是歪的。解决方法是用ImageOps.exif_transpose()自动处理,或者用 ImageMagick 的-auto-orient参数。
问题二:PNG 透明背景在 JPEG 输出时变黑。因为 JPEG 不支持透明通道,转换时透明区域默认填黑。解决方法是在转换前先把透明背景合成到白色底上:
if img.mode in ('RGBA', 'LA'): background = Image.new('RGB', img.size, (255, 255, 255)) background.paste(img, mask=img.split()[-1]) img = background问题三:批量锐化过度导致噪点明显。锐化参数不要超过 1.5,一般 0.5 到 1.0 就够了。而且锐化应该在缩放之后做,顺序反了效果很差。
5.2 音频处理中的常见故障
问题一:音量标准化后忽大忽小。简单的增益调整(apply_gain)只能统一整体音量,不能做动态压缩。如果素材本身音量波动大,需要先用压缩器(compressor)处理。pydub 可以用audio.compress_dynamic_range(),但效果一般。更专业的做法是用 FFmpeg 的loudnorm滤镜:
ffmpeg -i input.wav -af loudnorm=I=-20:TP=-1.5:LRA=11 -ar 44100 output.wav这个滤镜会做两遍分析,第一遍测量,第二遍应用,效果比简单增益好很多。
问题二:去除静音把有用部分也切了。detect_leading_silence的阈值设得太高,会把轻声细语也当成静音。我一般设 -50 dBFS,如果素材底噪大,可以调到 -40 dBFS。另外,去除首尾静音后最好留 0.1 秒的缓冲,不然听起来很突兀。
5.3 批量处理时的性能与稳定性
问题一:处理大量文件时内存爆了。如果你一次性把所有图片读进内存,几百张高清图就能吃掉几个 G。解决方法是用生成器逐张处理,处理完一张释放一张。Python 里用for循环配合del或者直接用函数作用域自动回收。
问题二:某个文件损坏导致整个批处理中断。一定要加异常捕获,跳过坏文件并记录日志:
import logging logging.basicConfig(filename='process.log', level=logging.ERROR) for filename in os.listdir(input_dir): try: process_image(...) except Exception as e: logging.error(f'处理失败: {filename}, 错误: {str(e)}') continue这样即使有几个文件有问题,其他文件照样处理,最后看日志补处理就行。
问题三:输出文件覆盖了之前的版本。输出目录最好带时间戳,比如output/20250412_143022/。或者用 Git 管理输出目录(虽然大文件不太适合 Git,但可以用 Git LFS)。我自己的习惯是每次批量处理前,先把输出目录重命名加个日期后缀,再新建一个空的输出目录。
5.4 常见问题速查表
| 现象 | 可能原因 | 排查方法 | 解决方案 |
|---|---|---|---|
| 图片方向不对 | EXIF 未处理 | 用exiftool查看 Orientation 标签 | 加exif_transpose或-auto-orient |
| 透明背景变黑 | JPEG 不支持透明 | 检查原图模式是否为 RGBA | 合成白色背景后再转 |
| 音频音量忽大忽小 | 未做动态压缩 | 用 Audacity 查看波形 | 用loudnorm滤镜处理 |
| 批处理中途停止 | 某个文件损坏 | 查看日志最后一条记录 | 加异常捕获,跳过坏文件 |
| 输出文件被覆盖 | 输出路径固定 | 检查输出目录命名 | 加时间戳或版本号 |
| 处理速度太慢 | 单线程处理 | 查看 CPU 占用 | 用多进程或 GNU Parallel |
| 水印位置不对 | 坐标计算错误 | 打印图片和水印尺寸 | 用相对位置而非绝对坐标 |
| 视频比例变形 | 缩放未保持比例 | 检查 FFmpeg 滤镜参数 | 用force_original_aspect_ratio |
6. 进阶技巧:让 artcraft 流水线更“聪明”
6.1 条件分支:不同素材走不同路径
不是所有素材都需要同样的处理。比如横版图和竖版图应该走不同的裁剪逻辑,短音频和长音频应该用不同的压缩参数。artcraft 式流水线可以通过条件判断来实现:
def get_pipeline_config(img): w, h = img.size if w > h: return load_config('config/landscape_pipeline.yaml') else: return load_config('config/portrait_pipeline.yaml')这样你只需要维护两套配置,脚本自动根据素材特征选择。我试过用这套逻辑处理混合了横竖版的活动照片,效率比手动分类高太多了。
6.2 增量处理:只处理新增文件
每次全量处理很浪费时间。可以记录已处理文件的哈希值,只处理新增的:
import hashlib import json def get_file_hash(path): with open(path, 'rb') as f: return hashlib.md5(f.read()).hexdigest() def load_processed_set(log_path='processed.json'): if os.path.exists(log_path): with open(log_path, 'r') as f: return set(json.load(f)) return set() def save_processed_set(processed_set, log_path='processed.json'): with open(log_path, 'w') as f: json.dump(list(processed_set), f)每次处理前检查哈希是否在已处理集合里,不在才处理。处理完把新哈希加进去。这个技巧在处理持续更新的素材库时特别有用,比如你每天拍几张照片,不用每次都把整个库重跑一遍。
6.3 日志与回滚:出了事能查、能恢复
日志要记录三件事:什么时候、处理了哪个文件、结果如何。格式建议用 JSON Lines,每行一个 JSON 对象,方便后续用脚本分析:
{"time": "2025-04-12T14:30:22", "file": "input/001.jpg", "status": "success", "output": "output/001_hd.jpg"} {"time": "2025-04-12T14:30:23", "file": "input/002.jpg", "status": "failed", "error": "UnidentifiedImageError"}回滚的话,最简单的做法是输出目录按批次隔离。每次批量处理生成一个带时间戳的目录,如果发现处理错了,直接删掉那个目录重跑就行。不要覆盖之前的输出,除非你确定新结果更好。
6.4 性能优化:多进程与并行处理
Python 的multiprocessing可以轻松把处理速度提升数倍:
from multiprocessing import Pool def process_wrapper(args): input_path, output_path, config = args try: process_image(input_path, output_path, config) return (input_path, 'success') except Exception as e: return (input_path, f'failed: {str(e)}') if __name__ == '__main__': tasks = [(os.path.join(input_dir, f), os.path.join(output_dir, f), config) for f in os.listdir(input_dir)] with Pool(processes=4) as pool: results = pool.map(process_wrapper, tasks)processes=4表示用四个进程,一般设成 CPU 核心数就行。注意:多进程处理时,日志写入要加锁,不然会乱。或者每个进程写自己的日志文件,最后合并。
7. 我踩过的坑与最后分享几个小技巧
第一个坑是配置文件格式选错。我一开始用 INI,后来发现嵌套结构写起来很别扭,换成 JSON 又没法写注释,最后锁定 YAML。YAML 的缩进虽然容易出错,但可读性确实好,而且支持注释,对需要频繁调整参数的项目来说很合适。
第二个坑是过度依赖图形界面工具。早期我用某款批量处理软件,点几下就能完成,但后来需求变复杂了,软件不支持条件分支,只能推倒重来。所以如果你的需求可能会变,一开始就用脚本+配置的方式,虽然上手慢一点,但扩展性强太多。
第三个坑是忘记处理文件名中的特殊字符。有些素材文件名带空格、中文、括号,脚本处理时容易出错。统一重命名成英文+数字+下划线是最稳妥的,比如20250412_project_001.jpg。如果必须保留中文,确保脚本用 UTF-8 编码读写。
最后分享一个小技巧:用 Makefile 管理整个流水线。把每个步骤写成一个 Make 目标,比如make import、make process、make export,这样你不需要记住每个脚本的路径和参数,敲一个命令就行。而且 Makefile 天然支持依赖关系,比如export依赖process,process依赖import,没处理完就不会导出。
import: python scripts/import.py process: import python scripts/process_images.py python scripts/process_audio.py export: process bash scripts/export.sh clean: rm -rf workspace/temp/*这个 Makefile 虽然简单,但把整个流程串起来了。你只需要记住make export,它自动按顺序执行所有步骤。如果中间某步失败,Make 会停下来并报错,不会继续往下跑。这个特性在批量处理时特别有用,避免用错误的数据生成成品。
另外,如果你处理的是视频,FFmpeg 的-threads参数可以指定线程数,一般设成 CPU 核心数的一半到全部。但注意,如果同时处理多个视频,每个都开满线程反而会互相抢资源,这时候用-threads 2配合多进程更合理。这个参数没有绝对最优值,根据你的机器配置实测调整。