使用 ffmpeg 按大小分割视频文件 [英] Using ffmpeg to split video files by size
问题描述
我正在尝试使用 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屋!