使用 ffmpeg 按大小分割视频文件 [关闭]

Posted

技术标签:

【中文标题】使用 ffmpeg 按大小分割视频文件 [关闭]【英文标题】:Using ffmpeg to split video files by size [closed] 【发布时间】:2016-11-10 14:28:02 【问题描述】:

我正在尝试使用 ffmpeg 编写一个批处理文件,以自动执行多余的日常任务,即从以 4gb 块(这是大多数 DSLR 相机和 GoPro 的标准)记录的工作中获取素材,并将剪辑分割成 2gb 文件流媒体目的。这个想法是让脚本检查外部驱动器 FOOTAGE 的文件夹 @import 并在 2gb 之后拆分文件(因为最大大小为 4gb,这将减少多次拆分的需要)。

我也在尝试修改拆分文件的文件名,因此 FILE1 为 4gb,它拆分为 FILE1_1 和 FILE1_2,分别为 2gb。我所尝试的一切都只是将原始文件复制到两个新的相同文件中 - 没有拆分或任何东西。

在进行了一些谷歌搜索并阅读了此处的一些答案后,我找到了这篇文章,但它基于持续时间,而不是大小(以不同质量水平录制视频片段使这毫无意义):Split into equal parts and convert many mp4 videos using ffmpeg

有人可以帮我解决这个问题吗?我没有遇到任何可用的解决方案,使用我理解的方法,使用 -fs limit_size,我真的很想了解它是如何工作的。

更新:也发现了这个,但它已经四年没有更新了,我没有看到任何关于拆分的内容会被证明有帮助:

https://github.com/kcm1700/VideoSplitter/blob/master/

【问题讨论】:

【参考方案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

希望,这会有所帮助:)

【讨论】:

我可以知道您提供的此解决方案是否会降低块的视频质量? ffmpeg 菜鸟在这里 这完全取决于您传递的 FFMPEG_ARGS (第三个参数)。如果你什么都不传递,ffmpeg 会根据你的输出容器自动选择设置,这很可能意味着它会重新压缩内容,导致不必要的 CPU 负载和质量损失。因此建议至少将-c copy 作为该脚本的第三个参数传递,因为这将指示ffmpeg 复制视频和音频数据而不复制它。这使得转换速度更快(唯一的限制是硬盘速度),同时保持原始质量。 谢谢。自从发表此评论以来,我对 FFMPEG 有了更多的了解。我当时用过这个脚本,但是遇到了一些麻烦,不记得了,我再看一遍。 你的剧本太棒了!我认为默认行为应该是未修改的副本,并且没有重新编码。 这个脚本只制作了第一部分并且失败了。获取持续时间的ffprobe 命令为源文件和第一部分文件返回相同的持续时间。因为那个while循环只执行一次。【参考方案2】:

您可以使用 mp4box 在一个命令中执行此操作。

mp4box -splits 2000000 filename.mp4

splits 参数的值以千字节为单位。由于存在关键帧,片段不会正好是 2GB。

【讨论】:

我以为是字节?那不是 2MB 吗? 不,它以 kB 为单位。 当我尝试这个工具时,它把视频分成了 3 个部分,而它只需要 2 个部分。最后一段是120kb。前一部分剩余超过 100 MB 的可用空间。 这个命令不起作用。它只创建 1 个文件,其大小在参数上设置 取决于关键帧的位置。【参考方案3】:

一个想法是使用带有选项 -fs 的 ffmpeg。这将限制文件大小。输出文件的大小略大于请求的文件大小。

这只会创建一个文件。但是你可以建立一个循环,直到整个文件被分割。

首先创建文件的一部分,然后检查它的长度:

ffprobe -i input.file -show_format -v quiet | sed -n 's/duration=//p'

然后使用 -ss 启动另一个具有偏移量的文件

之后进行另一轮编码,直到整个文件被分割。您还可以对音频和视频使用流式复制

【讨论】:

你能发布一个使用 -fs 和 -ss 的脚本示例吗?

以上是关于使用 ffmpeg 按大小分割视频文件 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

我想用ffmpeg命令行转换一个视频文件,视、音频编码格式不变,只是将画面旋转90度,请问命令行该如何写?

如何使用 FFMPEG 分割视频,以便每个块都以关键帧开头?

使用ffmpeg从视频文件中提取音频文件视频抽帧和切割视频

利用FFMPEG命令进行文件分割

如何通过静音部分分割视频或音频

ffmpeg_分割一个mp4文件到多个小的mp4文件