使用 ffmpeg 按大小分割视频文件 [英] Using ffmpeg to split video files by size

查看:61
本文介绍了使用 ffmpeg 按大小分割视频文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to write a batch file using ffmpeg to automate the redundant daily task of taking footage from work that's recorded in 4gb blocks (which is standard in most DSLR cameras & GoPro's), and split the clips into 2gb files for streaming purposes. The idea is to have the script check external drive FOOTAGE's folder @import and split files after 2gb (since the max size is 4gb, this will alleviate the need for more than one split).

我也在尝试修改拆分文件的文件名,因此 FILE1 为 4gb,它拆分为 FILE1_1 和 FILE1_2,分别为 2gb.我尝试过的所有操作都只是将原始文件复制到两个相同的新文件中 - 没有拆分或任何其他内容.

I'm also trying to amend the filenames of the split files, so FILE1 is 4gb, it splits into FILE1_1 and FILE1_2 which are 2gb each, respectively. Everything I've tried has just copied the original file into two new, identical files - no split or anything.

在进行了一些谷歌搜索并阅读了此处的一些答案后,我找到了这篇文章,但它基于持续时间,而不是大小(以不同质量级别录制视频片段使这毫无意义):分割成相等的部分并使用 ffmpeg 转换许多 mp4 视频

After doing some Googling and reading some of the answers here, I found this post, but it's based on duration, not size (recording video footage at varying levels of quality makes this pointless): Split into equal parts and convert many mp4 videos using ffmpeg

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

Can someone help me with this? I haven't come across any usable solutions utilizing what I understand to be the method, using -fs limit_size, and I really want to understand how this works.

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

UPDATE: Also found this, but it hasn't been updated in four years and I don't see anything in there regarding splitting that will prove helpful:

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

推荐答案

我刚刚遇到了同样的问题,在这里找不到解决方案后,我为该工作编写了一个快速的 bash 脚本.

I just had the same problem, and after I didn't find a solution here, I wrote a quick bash script for that job.

特点:

  • 使用 ffmpeg 的 -fs-flag 来限制文件大小
  • 检查生成的视频部分的长度并计算从哪里开始下一部分
  • 枚举视频部分
  • 根据需要处理尽可能多的部分以包含整个源文件.
  • 允许自定义 ffmpeg 参数同时降低分辨率和质量.
  • Use ffmpeg's -fs-flag to limit filesize
  • Check length of resulting video part and calculate where to start next part
  • Enumerate video parts
  • proceed with as many parts as needed to contain the whole source file.
  • Allow for custom ffmpeg arguments to also reduce resolution and quality in one pass.

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

It takes only three arguments: The source filename, the desired filesize of each part and the desired arguments for ffmpeg.

将文件拆分为 64MB 部分的示例调用:

Example call to split a file into 64MB parts:

./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 按大小分割视频文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆