如何使用 ffmpeg 按大小分割视频文件?

如何使用 ffmpeg 按大小分割视频文件?

我想使用 ffmpeg 按大小分割视频文件。

你知道怎么做吗 ?

我是否必须计算与每个尺寸相对应的持续时间?

谢谢。

答案1

我刚刚遇到了同样的问题,在没有找到解决方案之后,我为这项工作编写了一个快速 bash 脚本。

特征:

  • 使用 ffmpeg 的-fs-flag 来限制文件大小
  • 检查结果视频部分的长度并计算下一部分的开始位置
  • 枚举视频部分
  • 继续处理尽可能多的部分以包含整个源文件。
  • 允许自定义 ffmpeg 参数一次性降低分辨率和质量。

它只需要三个参数:源文件名、每个部分的所需文件大小和 ffmpeg 所需的参数。

将文件分割成 64MB 部分的示例调用:

./split-video.sh huge-video.mov 64000000 "-c:v libx264 -crf 23 -c:a copy -vf scale=960:-1"

最后,脚本的源代码:

#!/bin/bash
# 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 of the source video
DURATION=$(ffprobe -i "$FILE" -show_entries format=duration -v quiet -of default=noprint_wrappers=1:nokey=1|cut -d. -f1)

# Duration that has been encoded so far
CUR_DURATION=0

# Filename of the source video (without extension)
BASENAME="${FILE%.*}"

# Extension for the video parts
#EXTENSION="${FILE##*.}"
EXTENSION="mp4"

# Number of the current video part
i=1

# Filename of the next video part
NEXTFILENAME="$BASENAME-$i.$EXTENSION"

echo "Duration of source video: $DURATION"

# Until the duration of all partial videos has reached the duration of the source video
while [[ $CUR_DURATION -lt $DURATION ]]; do
    # Encode next part
    echo ffmpeg -i "$FILE" -ss "$CUR_DURATION" -fs "$SIZELIMIT" $FFMPEG_ARGS "$NEXTFILENAME"
    ffmpeg -ss "$CUR_DURATION" -i "$FILE" -fs "$SIZELIMIT" $FFMPEG_ARGS "$NEXTFILENAME"

    # Duration of the new part
    NEW_DURATION=$(ffprobe -i "$NEXTFILENAME" -show_entries format=duration -v quiet -of default=noprint_wrappers=1:nokey=1|cut -d. -f1)

    # Total duration encoded so far
    CUR_DURATION=$((CUR_DURATION + NEW_DURATION))

    i=$((i + 1))

    echo "Duration of $NEXTFILENAME: $NEW_DURATION"
    echo "Part No. $i starts at $CUR_DURATION"

    NEXTFILENAME="$BASENAME-$i.$EXTENSION"
done

希望有帮助:)

答案2

-fs选项限制文件大小。数字以字节为单位提供。如果您不想重新编码,请使用该-copy选项。

不幸的是,我不知道如何查找开始下一个视频的字节位置。但您可以检查结果持续时间,并使用-ss从那里开始编码的选项开始下一个编码。

答案3

我发现视频分割器在 GitHub 上非常有用。下面是我成功根据文件大小分割视频的方法:

find . -type f -size +3900M -exec python ffmpeg-split.py -f '{}' -S 3900000000 -e '-threads 4' \;

此命令的目的是找到大于 3.9G 的文件,并将它们分成每个大小为 3900000000 字节(3.6G)的小部分。这样做是为了确保文件可以复制到 FAT32 磁盘。

相关内容