某些时候,由于上传限制,我们可能想把视频切分成尽量少且满足大小限制的片段,不改变视频原先的格式
实现思路:得到视频的总时长,总文件大小,根据大小限制,确定分割片段个数,
得到每段时长,截取视频片段输出文件
获取视频的总时长(单位秒)
local duration=$(ffprobe -v error -show_entries format=size -of csv=p=0 "$video_path")
获取视频的大小(字节B)
local size=$(ffprobe -v error -show_entries format=duration -of csv=p=0 "$video_path")
输出文件夹使用文件名
local output_dir="$video_dir/$video_base"
代码出现问题,显示语法错误
排查发现
ffprobe -v error -show_entries format=total_time -of csv=p=0 * 这里的参数应该是format=duration
#!/bin/bash
split_video() {
local video_path="$1"
local video_name=$(basename "$video_path")
local video_dir=$(dirname "$video_path")
local video_base="${video_name%.*}"
local output_dir="$video_dir/$video_base"
# 创建输出文件夹
mkdir -p "$output_dir"
# 获取视频时长
local total_time=$(ffprobe -v error -show_entries format=duration -of csv=p=0 "$video_path")
# 计算分割数量
local child_num=$(echo "$(du -BM "$video_path" | cut -f1 | tr -d 'M') / 10" | bc)
((child_num++))
local child_time=$(echo "$total_time / $child_num" | bc -l)
# 分割视频
for ((i=0; i<child_num; i++)); do
start_time=$(echo "$i * $child_time" | bc -l)
output_path="$output_dir/${video_base}($((i + 1))).${video_name##*.}"
ffmpeg -i "$video_path" -ss "$start_time" -t "$child_time" -c copy "$output_path" -y
done
read -p "所有视频片段已创建于 $output_dir. 是否删除原文件 $video_path? (y/n): " confirm_delete
if [[ "$confirm_delete" == "y" ]]; then
rm "$video_path"
echo "已删除 $video_path"
else
echo "未删除 $video_path"
fi
}
# 检查输入参数
if [ "$#" -ne 1 ]; then
echo "用法: $0 <视频文件路径>"
exit 1
fi
# 确保输入的文件存在
video_file="$1"
if [ ! -f "$video_file" ]; then
echo "文件 $video_file 不存在"
exit 1
fi
split_video "$video_file"