Skip to content

Instantly share code, notes, and snippets.

@yumin9822
Last active March 28, 2025 02:16
Show Gist options
  • Save yumin9822/e94ce90b1812a4cbe60633ec83435894 to your computer and use it in GitHub Desktop.
Save yumin9822/e94ce90b1812a4cbe60633ec83435894 to your computer and use it in GitHub Desktop.
video screenshoot and upload to imgbox, enable comppression by Tinypng while bigger than 10MB
#!/bin/bash
ScriptName=${0##*/}
function print_usage() {
echo "请使用: $ScriptName <文件序号> <视频文件夹>"
echo "截图将保存到 /root/screenshots 文件夹中。"
echo "示例: $ScriptName 2 /path/to/video_folder"
echo "说明:"
echo " - 文件序号:选择文件夹中的第几个视频文件(从 1 开始)。"
echo " - 视频文件夹:支持 ISO 文件、普通视频文件和多级目录。"
echo " - 忽略小于 ${FILES_MIN_SIZE_MB}MB 的视频文件。"
echo " - 支持常见视频文件后缀:.mp4, .mkv, .avi, .ts, .VOB, .m2ts, .iso 等。"
}
# 多个 TinyPNG API KEY
TINYPNG_API_KEYS=(
"aaaaaaaa"
"bbbbbbbbb"
"cccccccc"
)
CURRENT_API_KEY_INDEX=0 # 当前使用的 API KEY 索引
QUOTA_LIMIT=480 # API KEY 使用次数上限
FILES_MIN_SIZE_MB="500"
NUMBERS_PNG="6"
STARTING_TIME="00:03:30"
FILE_INDEX=$1
FILE_DIR=$2
ENABLE_COMPRESSION=true # 默认开启图片压缩功能
# 文件大小限制
FILES_MIN_SIZE=$((${FILES_MIN_SIZE_MB} * 1024 * 1024)) # 500MB in bytes
PNG_MAX_SIZE=$((10 * 1024 * 1024)) # 10MB in bytes
# 支持的视频文件后缀
VIDEO_EXTS=("mp4" "mkv" "avi" "ts" "VOB" "m2ts" "mov" "flv" "wmv" "mpeg" "mpg" "iso" "ISO")
## 检查参数数量
if [ $# -lt 2 ]; then
print_usage
exit 1
fi
## 检查视频文件夹是否存在
if [ ! -d "${FILE_DIR}" ]; then
echo "错误:文件夹 '${FILE_DIR}' 不存在。"
exit 1
fi
## 检查 ffmpeg 是否安装
if ! command -v ffmpeg &> /dev/null; then
echo "错误:未找到 'ffmpeg' 工具,请先安装。"
exit 1
fi
## 检查 tinifier 是否安装
if ! command -v tinifier &> /dev/null; then
echo "错误:未找到 'tinifier' 工具,请先安装。"
echo "Check Here: https://github.com/tarampampam/tinifier/"
exit 1
fi
## 检查 imgbox 是否安装
if ! command -v imgbox &> /dev/null; then
echo "错误:未找到 'imgbox' 工具,请先安装。"
echo "Check here: https://codeberg.org/plotski/imgbox-cli"
exit 1
fi
## 创建截图保存目录
OUTPUT_DIR="/root/screenshots"
mkdir -p "${OUTPUT_DIR}"
## 获取视频文件列表
VIDEO_FILES=()
# 优先查找一级目录
for ext in "${VIDEO_EXTS[@]}"; do
while IFS= read -r -d '' video_file; do
file_size=$(stat -c%s "${video_file}" 2>/dev/null)
if [[ -z "${file_size}" ]] || ! [[ "${file_size}" =~ ^[0-9]+$ ]]; then
echo "错误:无法获取文件大小,跳过文件:${video_file}"
continue
fi
if [ "${file_size}" -ge "${FILES_MIN_SIZE}" ]; then
VIDEO_FILES+=("${video_file}")
else
echo "忽略文件:${video_file}(小于 ${FILES_MIN_SIZE_MB}MB)"
fi
done < <(find "${FILE_DIR}" -maxdepth 1 -type f -iname "*.${ext}" -print0)
done
# 如果一级目录没有视频文件,则递归查找多级目录
if [ ${#VIDEO_FILES[@]} -eq 0 ]; then
echo "一级目录未找到视频文件,开始递归查找多级目录..."
for ext in "${VIDEO_EXTS[@]}"; do
while IFS= read -r -d '' video_file; do
file_size=$(stat -c%s "${video_file}" 2>/dev/null)
if [[ -z "${file_size}" ]] || ! [[ "${file_size}" =~ ^[0-9]+$ ]]; then
echo "错误:无法获取文件大小,跳过文件:${video_file}"
continue
fi
if [ "${file_size}" -ge "${FILES_MIN_SIZE}" ]; then
VIDEO_FILES+=("${video_file}")
else
echo "忽略文件:${video_file}(小于 ${FILES_MIN_SIZE_MB}MB)"
fi
done < <(find "${FILE_DIR}" -type f -iname "*.${ext}" -print0)
done
fi
# 检查是否找到视频文件
if [ ${#VIDEO_FILES[@]} -eq 0 ]; then
echo "错误:文件夹 '${FILE_DIR}' 中没有找到支持的视频文件(或文件均小于 ${FILES_MIN_SIZE_MB}MB)。"
exit 1
fi
# 检查文件序号是否有效
if [ "${FILE_INDEX}" -lt 1 ] || [ "${FILE_INDEX}" -gt ${#VIDEO_FILES[@]} ]; then
echo "错误:文件序号 ${FILE_INDEX} 无效,有效范围是 1 到 ${#VIDEO_FILES[@]}。"
exit 1
fi
# 获取指定序号的视频文件
NAME="${VIDEO_FILES[$((FILE_INDEX - 1))]}"
echo "选择的视频文件:${NAME}"
## 处理 ISO 文件
#if [[ "${NAME}" == *.iso ]]; then
if [[ "${NAME}" == *.iso || "${NAME}" == *.ISO ]]; then
echo "检测到 ISO 文件,正在挂载并查找视频文件..."
MOUNT_POINT="/mnt/iso"
sudo mkdir -p "${MOUNT_POINT}"
sudo umount "${MOUNT_POINT}" 2>/dev/null # 确保挂载点未被占用
sudo mount -o loop "${NAME}" "${MOUNT_POINT}"
# 查找 DVD 或蓝光视频文件
ISO_VIDEO_FILES=()
while IFS= read -r -d '' video_file; do
file_size=$(stat -c%s "${video_file}" 2>/dev/null)
if [[ -z "${file_size}" ]] || ! [[ "${file_size}" =~ ^[0-9]+$ ]]; then
echo "错误:无法获取文件大小,跳过文件:${video_file}"
continue
fi
if [ "${file_size}" -ge "${FILES_MIN_SIZE}" ]; then
ISO_VIDEO_FILES+=("${video_file}")
else
echo "忽略文件:${video_file}(小于 ${FILES_MIN_SIZE_MB}MB)"
fi
done < <(find "${MOUNT_POINT}/VIDEO_TS" -type f -iname "*.VOB" -print0)
if [ ${#ISO_VIDEO_FILES[@]} -eq 0 ]; then
echo "未找到 DVD 视频文件,开始查找蓝光视频文件..."
while IFS= read -r -d '' video_file; do
file_size=$(stat -c%s "${video_file}" 2>/dev/null)
if [[ -z "${file_size}" ]] || ! [[ "${file_size}" =~ ^[0-9]+$ ]]; then
echo "错误:无法获取文件大小,跳过文件:${video_file}"
continue
fi
if [ "${file_size}" -ge "${FILES_MIN_SIZE}" ]; then
ISO_VIDEO_FILES+=("${video_file}")
else
echo "忽略文件:${video_file}(小于 ${FILES_MIN_SIZE_MB}MB)"
fi
done < <(find "${MOUNT_POINT}/BDMV/STREAM" -type f -iname "*.m2ts" -print0)
fi
if [ ${#ISO_VIDEO_FILES[@]} -eq 0 ]; then
echo "错误:未找到支持的视频文件。"
sudo umount "${MOUNT_POINT}"
exit 1
fi
# 使用第一个视频文件
NAME="${ISO_VIDEO_FILES[0]}"
echo "选择的视频文件:${NAME}"
fi
## 提取截图
ffmpeg -ss "${STARTING_TIME}" -i "${NAME}" -vf fps=1/20 -vframes "${NUMBERS_PNG}" "${OUTPUT_DIR}/${FILE_DIR}"-%02d.png
# 确保挂载点的挂载取消
mountpoint -q "${MOUNT_POINT}" && sudo umount "${MOUNT_POINT}" 2>/dev/null
## 记录日志
LOG_FILE="/root/snapshots.txt"
echo "########################################" >> "${LOG_FILE}"
echo "$(date)" >> "${LOG_FILE}"
## 处理截图文件
UPLOAD_FILES=() # 用于存储需要上传的文件
for screenshot in "${OUTPUT_DIR}/${FILE_DIR}"-*.png; do
file_size=$(stat -c%s "${screenshot}")
# 如果文件大于 10MB 且启用了压缩功能,尝试压缩
if [ "${file_size}" -gt "${PNG_MAX_SIZE}" ] && ${ENABLE_COMPRESSION}; then
echo "文件 ${screenshot} 大小 ${file_size} 字节,大于 10MB,正在压缩..."
# 检查当前 API KEY 的使用次数
while true; do
CURRENT_API_KEY="${TINYPNG_API_KEYS[$CURRENT_API_KEY_INDEX]}"
USED_QUOTA=$(tinifier quota -k "${CURRENT_API_KEY}" | awk '{print $NF}'|sed 's/\x1b\[[0-9;]*m//g')
echo "当前 API KEY 使用次数:${USED_QUOTA}"
if [ "${USED_QUOTA}" -ge "${QUOTA_LIMIT}" ]; then
echo "API KEY ${CURRENT_API_KEY} 使用次数已达上限,切换到下一个 API KEY。"
CURRENT_API_KEY_INDEX=$((CURRENT_API_KEY_INDEX + 1))
if [ "${CURRENT_API_KEY_INDEX}" -ge ${#TINYPNG_API_KEYS[@]} ]; then
echo "错误:所有 API KEY 使用次数均已达到上限。"
if [[ "${NAME}" == *.iso ]]; then
sudo umount "${MOUNT_POINT}"
fi
exit 1
fi
else
break
fi
done
# 使用当前 API KEY 压缩文件
tinifier compress -k "${CURRENT_API_KEY}" "${screenshot}"
fi
# 将文件添加到上传列表
UPLOAD_FILES+=("${screenshot}")
done
# 批量上传文件
if [ ${#UPLOAD_FILES[@]} -gt 0 ]; then
echo "正在上传以下文件:"
printf '%s\n' "${UPLOAD_FILES[@]}"
imgbox --thumb-width 350 -t "${FILE_DIR}" "${UPLOAD_FILES[@]}" | tee -a "${LOG_FILE}"
else
echo "没有文件需要上传。"
fi
# 卸载 ISO 文件(如果存在)
if [[ "${NAME}" == *.iso ]]; then
sudo umount "${MOUNT_POINT}"
fi
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment