You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用FFmpeg将MP4文件分割为大小均等的多个小文件

如何用FFmpeg将MP4文件分割为大小均等的多个小文件

我完全懂你遇到的糟心事——用segment按固定时间分割MP4时,要么因为录制时帧率波动大,要么因为视频内容复杂度忽高忽低,导致每个片段的体积差得离谱,有的甚至能差25倍。这时候按文件大小分割才是更靠谱的方案,你尝试的脚本思路找对了,我来帮你梳理完整的实现和使用细节:

一、按文件大小分割的Shell脚本

这个脚本会先计算原视频的比特率,再根据你设定的单片段大小反推近似分割时长,最后循环调用FFmpeg完成分割,能最大程度保证每个片段的体积接近你设定的上限:

#!/bin/sh
# Short script to split videos by filesize using ffmpeg by LukeLR

if [ $# -ne 3 ]; then
    echo 'Illegal number of parameters. Needs 3 parameters:'
    echo 'Usage:'
    echo './split-video.sh FILE SIZELIMIT "FFMPEG_ARGS"'
    echo 
    echo 'Parameters:'
    echo '    - FILE:        Name of the video file to split'
    echo '    - SIZELIMIT:   Maximum file size of each part (in bytes)'
    echo '    - FFMPEG_ARGS: Additional arguments to pass to each ffmpeg-call'
    echo '                   (video format and quality options etc.)'
    exit 1
fi

FILE="$1"
SIZELIMIT="$2"
FFMPEG_ARGS="$3"

# 获取原视频总时长
DURATION=$(ffmpeg -i "$FILE" 2>&1 | grep -oE 'Duration: [0-9:.]+' | cut -d ' ' -f 2 | tr -d ,)

# 将时长转换为总秒数
HOURS=$(echo "$DURATION" | cut -d ':' -f 1)
MINUTES=$(echo "$DURATION" | cut -d ':' -f 2)
SECONDS=$(echo "$DURATION" | cut -d ':' -f 3)
TOTAL_SECONDS=$(echo "$HOURS*3600 + $MINUTES*60 + $SECONDS" | bc)

# 计算原视频的近似比特率
FILESIZE=$(stat -c%s "$FILE")
BITRATE=$(echo "$FILESIZE * 8 / $TOTAL_SECONDS" | bc)

# 反推每个片段的近似时长
SEGMENT_DURATION=$(echo "$SIZELIMIT * 8 / $BITRATE" | bc)

# 循环分割视频
START_TIME=0
PART=1

while [ $START_TIME -lt $TOTAL_SECONDS ]; do
    ffmpeg -ss "$START_TIME" -t "$SEGMENT_DURATION" -i "$FILE" $FFMPEG_ARGS "part_$(printf "%03d" $PART).mp4"
    START_TIME=$(echo "$START_TIME + $SEGMENT_DURATION" | bc)
    PART=$((PART + 1))
done

二、脚本使用步骤

  1. 保存并授权:把上面的代码存为split-video.sh,然后给脚本加上执行权限:
    chmod +x split-video.sh
    
  2. 参数说明:
    • FILE:要分割的源MP4文件路径,比如你的../data/2024-06-02_12-34-51.mp4
    • SIZELIMIT:每个片段的最大字节数,比如要每个片段约50MB,就换算成50*1024*1024=52428800
    • FFMPEG_ARGS:FFmpeg的编码/封装参数,如果你想跳过重新编码(节省时间),直接用-c copy -map 0就行
  3. 示例命令:
    比如把你的源视频分割成每个50MB的片段,且保留原编码格式:
    ./split-video.sh ../data/2024-06-02_12-34-51.mp4 52428800 "-c copy -map 0"
    

三、小提醒

  • 因为视频关键帧的限制,实际分割后的片段大小可能会有小幅误差(不会差太多),如果追求极致精准,需要先给视频重新编码并插入均匀的关键帧,但会增加耗时。
  • 如果你用的是macOS,脚本里的stat -c%s "$FILE"要改成stat -f%z "$FILE",不然获取不到文件大小。
  • 如果设定的SIZELIMIT超过原视频总大小,脚本只会生成一个完整的片段。

备注:内容来源于stack exchange,提问作者GBPU

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.16 12:23:11