Created
May 11, 2025 12:35
-
-
Save izfsk-ium/395feae4dae7bcce64d4997ac1c3ed7e to your computer and use it in GitHub Desktop.
减少视频文件的大小
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# ====== 彩色定义 ====== | |
RED='\033[1;31m' | |
GREEN='\033[1;32m' | |
YELLOW='\033[1;33m' | |
CYAN='\033[1;36m' | |
BLUE='\033[1;34m' | |
BOLD='\033[1m' | |
NC='\033[0m' # 重置 | |
# ====== 函数:打印分隔线 ====== | |
print_section() { | |
echo -e "${BLUE}${BOLD}\n========== $1 ==========${NC}" | |
} | |
# ====== 参数解析 ====== | |
force_delete=false | |
for arg in "$@"; do | |
case "$arg" in | |
--force-delete) | |
force_delete=true | |
shift | |
;; | |
*) | |
if [[ -z "$input_file" ]]; then | |
input_file="$arg" | |
fi | |
;; | |
esac | |
done | |
# ====== 检查输入文件 ====== | |
if [[ -z "$input_file" ]]; then | |
echo -e "${YELLOW}用法: $0 [--force-delete] <输入视频文件>${NC}" | |
exit 1 | |
fi | |
if [[ ! -f "$input_file" ]]; then | |
echo -e "${RED}错误: 文件 '$input_file' 未找到!${NC}" | |
exit 1 | |
fi | |
# ====== 显示原视频信息 ====== | |
print_section "原视频信息" | |
ffprobe_output=$(ffprobe -hide_banner -v error -select_streams v:0 \ | |
-show_entries stream=codec_name,width,height,bit_rate,r_frame_rate,avg_frame_rate \ | |
-of default=noprint_wrappers=1 "$input_file") | |
echo -e "${CYAN}$ffprobe_output${NC}" | |
# ====== 提取文件名信息 ====== | |
original_size=$(stat -c%s "$input_file") | |
base_name=$(basename "$input_file") | |
extension="${base_name##*.}" | |
file_name_without_extension="${base_name%.*}" | |
tmp_output_file="/tmp/${file_name_without_extension}_$(date +%s).mkv" | |
target_dir=$(dirname "$input_file") | |
print_section "文件准备" | |
echo -e "${CYAN}输入文件 : $input_file" | |
echo -e "中间输出文件 : $tmp_output_file" | |
echo -e "原始文件大小 : $(numfmt --to=iec-i --suffix=B $original_size)${NC}" | |
# ====== 构建 FFmpeg 命令 ====== | |
ffmpeg_command=( | |
ffmpeg | |
-hide_banner | |
-loglevel error | |
-stats | |
-i "$input_file" | |
-c:v hevc_nvenc | |
-rc vbr_hq | |
-cq 24 | |
-c:a libopus | |
-b:a 128k | |
-map 0 | |
-map_metadata 0 | |
-y | |
"$tmp_output_file" | |
) | |
print_section "将执行的 FFmpeg 命令" | |
echo -e "${YELLOW}${BOLD}${ffmpeg_command[*]}${NC}" | |
# ====== 执行 FFmpeg ====== | |
print_section "开始编码" | |
"${ffmpeg_command[@]}" | |
ffmpeg_exit_status=$? | |
if [[ $ffmpeg_exit_status -ne 0 ]]; then | |
echo -e "${RED}错误: FFmpeg 编码失败 (退出状态码: $ffmpeg_exit_status)。${NC}" | |
[[ -f "$tmp_output_file" ]] && rm "$tmp_output_file" | |
exit 1 | |
fi | |
echo -e "${GREEN}FFmpeg 编码成功!${NC}" | |
# ====== 输出结果和压缩比 ====== | |
output_size=$(stat -c%s "$tmp_output_file") | |
size_diff=$((original_size - output_size)) | |
print_section "压缩结果" | |
echo -e "${CYAN}输出文件大小 : $(numfmt --to=iec-i --suffix=B $output_size)${NC}" | |
if [[ $size_diff -ge 0 ]]; then | |
echo -e "${GREEN}文件体积减少了: $(numfmt --to=iec-i --suffix=B $size_diff)${NC}" | |
else | |
echo -e "${YELLOW}文件体积增加了: $(numfmt --to=iec-i --suffix=B $((-size_diff)))${NC}" | |
fi | |
# ====== 文件移动和删除 ====== | |
print_section "处理输出文件" | |
if $force_delete; then | |
final_output="${target_dir}/${file_name_without_extension}.mkv" | |
echo -e "${CYAN}复制到: $final_output 并删除原始文件...${NC}" | |
rm "$input_file" | |
cp "$tmp_output_file" "$final_output" | |
echo -e "${GREEN}已删除原始文件: $input_file${NC}" | |
else | |
if [[ "${extension,,}" == "mkv" ]]; then | |
final_output="${target_dir}/new_${file_name_without_extension}.mkv" | |
else | |
final_output="${target_dir}/${file_name_without_extension}.mkv" | |
fi | |
echo -e "${CYAN}复制到: $final_output${NC}" | |
cp "$tmp_output_file" "$final_output" | |
read -p "$(echo -e "${YELLOW}是否删除原始文件 '$input_file'? [y/N]: ${NC}")" confirm_delete | |
if [[ "$confirm_delete" =~ ^[Yy]$ ]]; then | |
rm "$input_file" | |
echo -e "${GREEN}已删除原始文件: $input_file 并重命名。${NC}" | |
else | |
echo -e "${CYAN}保留原始文件: $input_file${NC}" | |
fi | |
fi | |
# ====== 清理临时文件 ====== | |
rm "$tmp_output_file" | |
print_section "完成" | |
echo -e "${GREEN}文件处理完成!${NC}" | |
exit 0 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment