大きなaviビデオを2つの小さな連続ビデオに分割したいと思います。私はffmpegを使用しています。
1つの方法は、ffmpegを2回実行することです。
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のマンページによると、one行だけを使用して、1つの入力ファイルから複数の出力ファイルを作成できます。
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 wikiは、「ビデオを効率的に分割する方法」を参照してこのページにリンクしています。私はこのページがその質問に答えると確信していないので、@ AlcubierreDriveが示唆したように…
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
数回の実行と少しの数学の後、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トランスポートストリーム
HDファイル = 3.14GB DVBトランスポートストリーム
HDを処理している場合は、単一のコマンドの方が優れています。入力ファイルの後に-ssを使用して「スローシーク」を行うことに関するマニュアルのコメントに同意します。 SDファイルの違いはごくわずかです。
2つのコマンドバージョンは、「高速シーク」の入力ファイルの前に別の-ssを追加し、その後により正確な低速シークを追加することで、より高速になります。
以下は便利なスクリプトです。自動的に分割するのに役立ちます。 ffmpegを使用してビデオを分割するためのスクリプト
#!/bin/bash
# Written by Alexis Bezverkhyy <[email protected]> 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には、動作する可能性のあるセグメントマルチプレクサがあります。
とにかく、それらを1つのコマンドに結合すると時間を節約できると思います。
私の経験では、ffmpegを分割/結合に使用しないでください。 MP4Boxは、ffmpegよりも高速で軽量です。やってみてください。たとえば、1400mbのMP4ファイルを700mbの2つの部分に分割する場合、次のcmdlを使用できます。MP4Box -splits 716800 input.mp4
たとえば、使用できる2つのファイルを連結する場合:
MP4Box -cat file1.mp4 -cat file2.mp4 output.mp4
または、時間で分割する必要がある場合は、-splitx StartTime:EndTime
を使用します。
MP4Box -add input.mp4 -splitx 0:15 -new split.mp4
後者のアプローチは計算時間とメモリを節約しますか?
提供した2つの例の間に大きな違いはありません。最初の例では、ビデオを2ステップで連続的にカットしますが、2番目の例では、同時に(スレッドを使用して)カットします。特定の高速化は目立ちません。 FFmpegで複数の出力を作成する について詳しく読むことができます。
さらに、(最近のFFmpegで)使用できるのは stream segmenter muxer です。
出力ストリームは、ほぼ固定された期間のいくつかの個別のファイルにストリーミングされます。出力ファイル名パターンは、 image2 と同様の方法で設定できます。
着信ファイルを50の部分に分割する単純なWindows batファイルを次に示します。各部分の長さは1分です。そのような愚かなスクリプトでごめんね。まったく持たないのではなく、ダムのWindowsスクリプトを用意する方が良いと思います。おそらくそれは誰かを助ける。 (このサイトの「ループ用のbatファイル」に基づいています。)
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
ビデオを分割する完璧な方法は次のとおりです。私は以前にそれをやったことがあり、それは私のためにうまく機能しています。
ffmpeg -i C:\xampp\htdocs\videoCutting\movie.mp4 -ss 00:00:00 -t 00:00:05 -async 1 C:\xampp\htdocs\videoCutting\SampleVideoNew.mp4
(cmdの場合)。 Shell_exec('ffmpeg -i C:\xampp\htdocs\videoCutting\movie.mp4 -ss 00:00:00 -t 00:00:05 -async 1 C:\xampp\htdocs\videoCutting\SampleVideoNew.mp4')
(PHPの場合)。
これに従ってください、それは完全に動作すると確信しています。
Istをテストしませんでしたが、これは有望に見えます:
明らかにAVIを同じサイズのセグメントに分割しています。これは、これらのチャンクが品質を低下させたり、メモリを増やしたり、再計算する必要がないことを意味します。
また、コーデックコピーを使用します。つまり、非常に大きなストリームを処理できるということですか。これが私の問題であるため、フィルターを使用して歪みを取り除くことができるように、aviを分解します。しかし、avi全体は何時間も実行されます。