FFmpeg:ビデオを効率的に分割する方法は?


103

大きな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のマンページによれば、1行だけを使用して、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

私の質問は、後者のアプローチは計算時間とメモリを節約することですか?


3
「-vcodec copy -acodec copy」を使用すると、非常に高速になります:))
Savas Adar

@Antony、両方のバージョンの時間を計って(そしてのようなメモリモニターを見てhtop)、答えを教えてください。
AlcubierreDrive 2013

最初の例では順次実行しますが、2番目の例ではスレッドを使用します。どちらも同じことを行い、目立ったスピードアップは起こりません。しかし、物事を単純化するために、ffmpegストリームセグメンターmuxerを
Mladen B.

1
この例はひどく間違っているようです!ffmpegのドキュメントでは、-ssオプションについて次のように説明しています。タイムスタンプが位置に到達しました。」出力位置で使用しているので、2行目は、最初の30分をデコードして破棄する労力を浪費します。
Lucian Wischik 2015

1
@LucianWischikですが-ss、2番目の分割で入力オプションとして使用すると正確でない場合があるため、完全な分割が得られない場合があります。OPによるIMOの例はより正確です。
jiggunjer

回答:


82

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を処理する場合に適しています。入力ファイルの後に「slow seek」を実行するために-ssを使用することに関するマニュアルのコメントに同意します。SDファイルの違いはごくわずかです。

2つのコマンドバージョンは、「高速シーク」の入力ファイルの前に別の-ssを追加し、その後に、より正確な低速シークを行うことで、より高速になるはずです。


TSに複数の番組(DVB-Tでキャプチャされたテレビ番組)が含まれている場合、どのように分割できますか?たとえば、フットボール+料理+漫画を含むTSファイルがあります。このTSファイルを3つのmpgファイルに分割するにはどうすればよいですか?
Dr.jacky、2015

ここでの質問であなたの答えを使用しました(stackoverflow.com/questions/41983940/…)が機能しませんでした。何が間違っていると思いますか?
utdev 2017

1
私の場合、結果ファイルはビデオなし(オーディオのみ)でした。いくつかの実験の後、私は魂を見つけました。このような「品質を変更しない」ためのキーを指定する必要があります-q:v 0
オクラ

19

ここで便利なスクリプトがあります、それはあなたが自動的に分割できます:分割動画のスクリプトはffmpegのを使用して

#!/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

2
同じコメントがSEARASと同じです。バッチファイルは、移植性がないため、どうしても必要な場合や他に利用できるオプションがない場合に便利です。たとえば、Windowsで同じスクリプトを実行することはできません。より汎用的で移植可能な方法がある場合、それらを移植するために必要な時間を節約するために、バッチスクリプトは避ける必要があります。ffmpegにはこの問題を解決する複数の方法があるため、スクリプトを使用せずにffmpegを単独で使用するのが適切な方法です。
Mladen B.

素晴らしいスクリプトです。あなたはそれを書きましたか?GitHubにありますか?私はいくつかの提案をしたいと思います:)

mp4の場合、シーンが破損しています。-vcodec libx264 -acodec aac
紀州

8

私の経験では、分割/結合に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


これはまさに私が必要としたものでした!私がffmpegでカットしているとき、クリップはキーフレームで開始せず、最後に奇妙なフリーズがありました。MP4Box -splitzを使用するとうまくいきました!
マット

1
複数の番号を持つMp4Boxを使用してビデオをトリミングするにはどうすればよいですか?たとえば、秒単位のサブクリップが必要な場合は、5〜8、21〜30、12〜18なので、3つの出力ビデオファイルが必要です。
mhndev 2018

そしてEndTime、よりもはるかに使いやすいです-t
vmassuchetto 2018


2

後者のアプローチは計算時間とメモリを節約しますか?

あなたが提供した2つの例の間に大きな違いはありません。最初の例は2ステップでビデオを連続してカットしますが、2番目の例は同時に(スレッドを使用して)カットします。特にスピードアップは目立ちません。あなたはFFmpegで複数の出力を作成することについてもっと読むことができます

さらに、(最近のFFmpegで)使用できるのは、次のことができるストリームセグメンターマルチプレクサです。

ほぼ固定された期間の複数の個別ファイルへの出力ストリーム。出力ファイル名パターンは、image2と同様の方法で設定できます。


2

これは、着信ファイルを50の部分に分割する単純なWindows batファイルです。各部分の長さは1分です。そのようなばかげたスクリプトでごめんなさい。私はそれがまったくないのではなく、ダムウィンドウスクリプトを持っている方がいいと思います。多分それは誰かを助ける。(このサイトの「bat file 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

これは基本的に、ffmpegループとして書き直された質問(連続するコマンド)の最初のコードスニペットです。これは、そのアプローチまたは単一のコマンドが「計算時間とメモリを節約する」かどうかの質問には答えません。
BACON、2018

1

istをテストしませんでしたが、これは有望に見えます:

基本的なストリームセグメンター

これは明らかにAVIを同じサイズのセグメントに分割しています。これは、これらのチャンクが品質を落としたりメモリを増やしたりしないか、再計算する必要があることを意味します。

コーデックコピーも使用します。つまり、非常に大きなストリームを処理できるということですか。これが私の問題なので、aviを分解して、フィルターを使用して歪みを取り除くことができます。しかし、avi全体が何時間も実行されます。


-1

これがビデオを分割する完璧な方法です。私は以前にそれをやったことがあり、それは私にとってうまくいきます。

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)。

これに従ってください、私はそれが完全に動作すると確信しています。


なぜこれがビデオを分割する「完璧な方法」なのですか?問題のコマンドラインと同じように、あなたは渡している-iが続く-ss-t。問題は、同じ入力ファイルから複数のセグメントを効率的に抽出する方法についてですが、抽出するのは単一のセグメントのみです。これが質問にどのように答えるかはわかりません。
BACON、2018

-2

簡単な方法の1つは、publitio url-based apiで trimオプションを使用することです。

動画をアップロードしたら、次のように開始オフセットと終了オフセットをurl(so_2、eo_2)に設定します。

    https://media.publit.io/file/so_2,eo_2/tummy.mp4

これにより、2秒と2秒から始まる新しい動画がすぐに作成されます。この方法でビデオを好きなように分割できます。


問題は、を使用して入力ファイルから複数のセグメントを抽出する2つのアプローチのうち、どちらがより効率的かを尋ねることですffmpeg。本当に高速なインターネット接続がなければ、動画全体をクラウドサービスにアップロードしてから結果をダウンロードする必要があるため、処理時間が大幅に増えると思います。そうであっても、これはまだそのアプローチの質問に答えていないffmpeg、より効率的であるが。
BACON、2018
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.