bash 使用 ffmpeg 按大小分割视频文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/38259544/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using ffmpeg to split video files by size
提问by user2548469
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).
我正在尝试使用 ffmpeg 编写一个批处理文件来自动化从工作中获取素材的冗余日常任务,这些素材记录在 4gb 块中(这是大多数 DSLR 相机和 GoPro 的标准),并将剪辑分成 2gb 文件以进行流式传输。这个想法是让脚本检查外部驱动器 FOOTAGE 的文件夹@import 并在 2gb 后拆分文件(因为最大大小为 4gb,这将减少对多个拆分的需要)。
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.
我也在尝试修改拆分文件的文件名,因此 FILE1 为 4gb,它拆分为 FILE1_1 和 FILE1_2,分别为 2gb。我尝试过的一切只是将原始文件复制到两个新的相同文件中 - 没有拆分或任何东西。
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
在做了一些谷歌搜索并在这里阅读了一些答案之后,我找到了这篇文章,但它基于持续时间,而不是大小(以不同质量级别录制视频片段使得这毫无意义):拆分成相等的部分并使用 ffmpeg 转换许多 mp4 视频
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.
有人可以帮我弄这个吗?我还没有遇到任何可用的解决方案,使用我理解的方法,使用 -fs limit_size,我真的很想了解它是如何工作的。
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:
更新:也发现了这个,但它已经四年没有更新了,我在那里看不到任何关于拆分的内容,这将被证明是有帮助的:
回答by LukeLR
I just had the same problem, and after I didn't find a solution here, I wrote a quick bash script for that job.
我刚刚遇到了同样的问题,在这里找不到解决方案后,我为该工作编写了一个快速的 bash 脚本。
Features:
特征:
- 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 的
-fs
-flag 来限制文件大小 - 检查生成的视频部分的长度并计算下一部分的开始位置
- 枚举视频部分
- 根据需要处理尽可能多的部分以包含整个源文件。
- 允许自定义 ffmpeg 参数也可以一次性降低分辨率和质量。
It takes only three arguments: The source filename, the desired filesize of each part and the desired arguments for ffmpeg.
它只需要三个参数:源文件名、每个部分所需的文件大小和 ffmpeg 所需的参数。
Example call to split a file into 64MB parts:
将文件拆分为 64MB 部分的示例调用:
./split-video.sh huge-video.mov 64000000 "-c:v libx264 -crf 23 -c:a copy -vf scale=960:-1"
Finally, the source code of the script:
最后,脚本的源代码:
#!/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=""
SIZELIMIT=""
FFMPEG_ARGS=""
# 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
Hope, that helps :)
希望,这有帮助:)
回答by Gyan
回答by mm2knet
One idea would be to use ffmpeg with the option -fs. This wil limit the file size. The size of the output file is slightly more than the requested file size.
一种想法是将 ffmpeg 与选项 -fs 一起使用。这将限制文件大小。输出文件的大小略大于请求的文件大小。
This will only create one file. But you can build a loop until the whole file is split.
这只会创建一个文件。但是您可以构建一个循环,直到整个文件被拆分。
First create a part of the file, then check how long it is with:
首先创建文件的一部分,然后检查它的长度:
ffprobe -i input.file -show_format -v quiet | sed -n 's/duration=//p'
Then start another file with the offset by using -ss
然后使用 -ss 以偏移量启动另一个文件
After that do another round of encoding until the whole file is split. You can also use a stream copy for audio and video
之后进行另一轮编码,直到整个文件被拆分。您还可以将流副本用于音频和视频