FFmpeg:如何有效地分割video?

我希望将一个大的AVIvideo分成两个更小的连续video。 我正在使用ffmpeg。

一种方法是运行两次ffmpeg:

ffmpeg -i input.avi -vcodec copy -acodec copy -ss 00:00:00 -t 00:30:00 output1.avi ffmpeg -i input.avi -vcodec copy -acodec copy -ss 00:30:00 -t 00:30:00 output2.avi 

但是根据ffmpeg的手册,我只用一行就可以从一个input文件创build多个输出文件:

 ffmpeg -i input.avi -vcodec copy -acodec copy -ss 00:00:00 -t 00:30:00 output1.avi \ -vcodec copy -acodec copy -ss 00:30:00 -t 00:30:00 output2.avi 

我的问题是,后面的方法是否节省了计算时间和内存?

ffmpeg维基链接参考“如何高效地分割video”链接回到这个页面。 我不相信这个网页回答这个问题,所以我做了@AlcubierreDrivebuild议…

 echo "Two commands" time ffmpeg -v quiet -y -i input.ts -vcodec copy -acodec copy -ss 00:00:00 -t 00:30:00 -sn test1.mkv time ffmpeg -v quiet -y -i input.ts -vcodec copy -acodec copy -ss 00:30:00 -t 01:00:00 -sn test2.mkv echo "One command" time ffmpeg -v quiet -y -i input.ts -vcodec copy -acodec copy -ss 00:00:00 -t 00:30:00 \ -sn test3.mkv -vcodec copy -acodec copy -ss 00:30:00 -t 01:00:00 -sn test4.mkv 

哪个输出…

 Two commands real 0m16.201s user 0m1.830s sys 0m1.301s real 0m43.621s user 0m4.943s sys 0m2.908s One command real 0m59.410s user 0m5.577s sys 0m3.939s 

经过几次运算和一些小math运算,我testing了SD&HD文件。

 Two commands SD 0m53.94 #2 wins One command SD 0m49.63 Two commands SD 0m55.00 One command SD 0m52.26 #1 wins Two commands SD 0m58.60 #2 wins One command SD 0m58.61 Two commands SD 0m54.60 One command SD 0m50.51 #1 wins Two commands SD 0m53.94 One command SD 0m49.63 #1 wins Two commands SD 0m55.00 One command SD 0m52.26 #1 wins Two commands SD 0m58.71 One command SD 0m58.61 #1 wins Two commands SD 0m54.63 One command SD 0m50.51 #1 wins Two commands SD 1m6.67s #2 wins One command SD 1m20.18 Two commands SD 1m7.67 One command SD 1m6.72 #1 wins Two commands SD 1m4.92 One command SD 1m2.24 #1 wins Two commands SD 1m1.73 One command SD 0m59.72 #1 wins Two commands HD 4m23.20 One command HD 3m40.02 #1 wins Two commands SD 1m1.30 One command SD 0m59.59 #1 wins Two commands HD 3m47.89 One command HD 3m29.59 #1 wins Two commands SD 0m59.82 One command SD 0m59.41 #1 wins Two commands HD 3m51.18 One command HD 3m30.79 #1 wins 

SD文件 = 1.35GB DVB传输stream
高清文件 = 3.14GB DVB传输stream

结论

如果你正在处理HD,那么单一的命令会更好,它同意使用-ss在input文件之后执行“慢速寻找”的手册注释。 SD文件有一个微不足道的差异。

两个命令版本应该更快一些,在快速search的input文件之前添加另一个-ss,然后进行更准确的慢search。

这里有一个有用的脚本,它可以帮助你自动分割: 使用ffmpeg分割video的脚本

 #!/bin/bash # Written by Alexis Bezverkhyy <alexis@grapsus.net> in 2011 # This is free and unencumbered software released into the public domain. # For more information, please refer to <http://unlicense.org/> function usage {    echo "Usage : ffsplit.sh input.file chunk-duration [output-filename-format]"    echo -e "\t - input file may be any kind of file reconginzed by ffmpeg"    echo -e "\t - chunk duration must be in seconds"    echo -e "\t - output filename format must be printf-like, for example myvideo-part-%04d.avi"    echo -e "\t - if no output filename format is given, it will be computed\ automatically from input filename" } IN_FILE="$1" OUT_FILE_FORMAT="$3" typeset -i CHUNK_LEN CHUNK_LEN="$2" DURATION_HMS=$(ffmpeg -i "$IN_FILE" 2>&1 | grep Duration | cut -f 4 -d ' ') DURATION_H=$(echo "$DURATION_HMS" | cut -d ':' -f 1) DURATION_M=$(echo "$DURATION_HMS" | cut -d ':' -f 2) DURATION_S=$(echo "$DURATION_HMS" | cut -d ':' -f 3 | cut -d '.' -f 1) let "DURATION = ( DURATION_H * 60 + DURATION_M ) * 60 + DURATION_S" if [ "$DURATION" = '0' ] ; then    echo "Invalid input video"    usage    exit 1 fi if [ "$CHUNK_LEN" = "0" ] ; then    echo "Invalid chunk size"    usage    exit 2 fi if [ -z "$OUT_FILE_FORMAT" ] ; then    FILE_EXT=$(echo "$IN_FILE" | sed 's/^.*\.\([a-zA-Z0-9]\+\)$/\1/')    FILE_NAME=$(echo "$IN_FILE" | sed 's/^\(.*\)\.[a-zA-Z0-9]\+$/\1/')    OUT_FILE_FORMAT="${FILE_NAME}-%03d.${FILE_EXT}"    echo "Using default output file format : $OUT_FILE_FORMAT" fi N='1' OFFSET='0' let 'N_FILES = DURATION / CHUNK_LEN + 1' while [ "$OFFSET" -lt "$DURATION" ] ; do    OUT_FILE=$(printf "$OUT_FILE_FORMAT" "$N")    echo "writing $OUT_FILE ($N/$N_FILES)..."    ffmpeg -i "$IN_FILE" -vcodec copy -acodec copy -ss "$OFFSET" -t "$CHUNK_LEN" "$OUT_FILE"    let "N = N + 1"    let "OFFSET = OFFSET + CHUNK_LEN" done 

http://ffmpeg.org/trac/ffmpeg/wiki/Seeking%20with%20FFmpeg也可能对你有用。; 此外ffmpeg有一个分段复用器可能工作。

无论如何,我的猜测是把他们合并成一个命令会节省时间。

根据我的经验,不要使用ffmpeg进行分割/连接。 MP4Box,比ffmpeg更快更轻。 请尝试。 例如,如果要将1400MB的MP4文件分成700MB的两部分,可以使用以下cmdl: MP4Box -splits 716800 input.mp4例如用于连接两个文件,您可以使用:

 MP4Box -cat file1.mp4 -cat file2.mp4 output.mp4 

这是一个简单的Windows bat文件,将传入的文件分成50个部分。 每部分有1分钟的长度。 对不起,这样的愚蠢的脚本。 我希望有一个愚蠢的Windows脚本,而不是根本没有它更好。 也许它有助于某人。 (基于本站的“bat for loop”)。

 set var=0 @echo off :start set lz= if %var% EQU 50 goto end if %var% LEQ 9 set lz=0 echo part %lz%%var% ffmpeg -ss 00:%lz%%var%:00 -t 00:01:00 -i %1 -acodec copy -vcodec copy %2_%lz%%var%.mp4 set /a var+=1 goto start :end echo var has reached %var%. exit 

后面的方法是否节省了计算时间和内存?

你提供的这两个例子没有太大的区别。 第一个示例按2个步骤顺序剪切video,而第二个示例同时剪切video(使用线程)。 没有特别的加速将是显而易见的。 您可以阅读更多关于使用FFmpeg创build多个输出的信息

此外,你可以使用什么(在最近FFmpeg)是stream分割复用器 ,它可以:

输出stream到几乎固定持续时间的单独文件。 输出文件名模式可以按照类似于image2的方式设置。

没有testingist,但是这看起来很有希望:

基本的stream分割器

显然,将AVI分成相同大小的片段,这意味着这些块不会丢失质量或增加内存,或者必须重新计算。

它也使用编解码器副本 – 这是否意味着它可以处理非常大的stream? 因为这是我的问题,我想分解我的AVI,所以我可以使用一个filter来摆脱扭曲。 但是整个avi运行了好几个小时。

事实certificate,在以后的情况下,文件大小将与时间片成比例地等效。