在Bash中如何为同一目录下不同扩展名的文件赋值变量以完成视频转码任务
Bash 提取指定目录目标格式视频并赋值变量的实现
核心实现思路
要支撑从文件监控、ffmpeg转码、输出迁移、原文件清理到邮件通知的全流程任务,赋值文件变量必须满足两个要求:
- 拿到每个视频的完整绝对路径,避免相对路径找错文件
- 兼容带空格、特殊字符、中文的文件名,不要因为路径拆分出错
注意修正目录路径笔误:你的目录结构描述里将/mnt/volume1/videos简写为/mnt/volum1/videos,脚本中填写路径时要和实际磁盘路径完全一致,否则会触发路径不存在的报错
可直接落地的赋值方案
提前定义公共变量
先把固定路径、配置项抽成独立变量,方便后续调试调整:
# 监控目标目录 WATCH_DIR="/mnt/volume1/videos" # 需要匹配的视频格式后缀 TARGET_EXTS=("mp4" "mov" "mkv") # 转码输出的目标目录 OUTPUT_DIR="/mnt/volume1/hls_output"
批量将匹配文件存入数组(推荐,适配全流程自动化)
用数组存储所有匹配的视频文件,是最稳定的赋值方式,完全兼容特殊字符的文件名,后续循环处理可以直接调用每个文件变量:
# 初始化空数组存储文件路径 video_files=() # 开启bash通配符兼容选项 shopt -s nullglob nocaseglob # 遍历所有目标后缀的文件,追加到数组 for ext in "${TARGET_EXTS[@]}"; do for file in "$WATCH_DIR"/*."$ext"; do # 完整路径作为独立数组元素赋值 video_files+=("$file") done done # 关闭临时开启的通配符选项,避免影响后续脚本逻辑 shopt -u nocaseglob
赋值完成后,video_files数组中的每个元素就是一个独立的文件路径变量,你可以直接在后续流程中循环调用:
# 遍历数组逐个处理,对接全流程任务 for video_path in "${video_files[@]}"; do # 提取视频不带后缀的基名,作为HLS输出的目录名 video_stem=$(basename "${video_path%.*}") # 可直接对接后续业务逻辑: # 1. 调用ffmpeg生成480p/720p/1080p三档HLS输出 # 2. 将生成的HLS文件移动到$OUTPUT_DIR # 3. 删除当前遍历的原始视频文件 # 4. 调用邮件发送命令通知对应用户转码完成 done
容易踩坑的避坑提醒
- 不要直接写
video_files=($WATCH_DIR/*.mp4 $WATCH_DIR/*.mov)这类裸通配符的数组赋值写法,遇到文件名带空格、中文、特殊符号时,会把完整的文件路径拆成多个无效的数组元素,导致ffmpeg找不到源文件 - 必须开启
nullglob通配符选项,不然当目录下没有任何匹配格式的文件时,脚本会把通配符字符串本身当成文件路径去处理,直接触发报错 - 如果用
find命令提取文件做赋值,一定要加-maxdepth 1参数,避免误抓监控目录子文件夹下的视频文件 - 因为是持续监控的目录,赋值文件时可以增加判断逻辑:对比文件10秒前后的修改时间,确认文件传输完成没有在写入时,再把文件加入待处理数组,避免转码不完整的上传中文件
内容的提问来源于stack exchange,提问作者Yacer Azeem
相关产品推荐
相关产品推荐

