ffmpegを使用して開始時間と終了時間に基づいてビデオをカットする


511

次のコマンドを使用して、ビデオの開始時間と終了時間を使用してビデオをカットしようとしました

ffmpeg -ss 00:00:03 -t 00:00:08 -i movie.mp4 -acodec copy -vcodec copy -async 1 cut.mp4

上記のコマンドを使用して、から00:00:03にビデオを切り取り00:00:08ます。しかし、それはそれらの間でビデオをカットするのではなく、最初の11秒でビデオをカットすることです。誰でもこれをどのように解決するのを手伝ってくれる?

編集1:

mark4oで提案されている次のコマンドを使用してカットしようとしました

ffmpeg -i movie.mp4 -ss 00:00:03 -t 00:00:08 -async 1 cut.mp4

しかし、次のエラーが表示されました。

エンコーダ「aac」は実験的ですが、実験的コーデックは有効になっていません

なので-strict -2、コマンドにを追加しました。

ffmpeg -i movie.mp4 -ss 00:00:03 -t 00:00:08 -async 1 -strict -2 cut.mp4

現在は正常に動作しています。


3
切り取られていない完全なffmpegコンソール出力がありません。尋ねるときは常にこれを含めてください。ありがとう。
slhck 2013

3
-strict 2はどこから入手しましたか?ドキュメントにないので、興味があるだけです:ffmpeg.org/ffmpeg.html
StackOverflowed

ffmpegをインストールした後の品質のために、ffmpegでこのオプションを見つけることができます
Kalai


1
ここでの問題は、実際には、-i movie.mp4の前と前に配置したという事実だけだったと思います。そのストリームの引数はそれの後に行きますよね?それが、他の方法が機能した理由です。= /
ブレントリッテンハウス

回答:


574

3秒のマークにキーフレームがない可能性があります。非キーフレームは他のフレームとの違いをエンコードするため、前のキーフレームから始まるすべてのデータが必要です。

mp4コンテナを使用すると、編集リストを使用して再エンコードすることなく、非キーフレームでカットできます。つまり、3秒前の最も近いキーフレームが0秒の場合、0秒からビデオをコピーし、編集リストを使用して、3秒で再生を開始するようプレーヤーに指示します。

最新のffmpegを使用している場合 gitのマスターから、それはあなたが提供したコマンドを使用して呼び出されたときに、これは編集リストを使用して行います。これが機能しない場合は、おそらく古いバージョンのffmpegを使用しているか、プレーヤーが編集リストをサポートしていない可能性があります。一部のプレーヤーは編集リストを無視し、常にファイルのすべてのメディアを最初から最後まで再生します。

非キーフレームから正確にカットして、エディットリストをサポートしていないプレーヤーの目的のポイントから再生したい場合、またはカット部分が実際に出力ファイルにないことを確認したい場合(たとえば機密情報が含まれている場合)、再エンコードすることにより、希望の開始時刻にキーフレームが正確に存在するようにできます。を指定しない場合、再エンコードがデフォルトですcopy。例えば:

ffmpeg -i movie.mp4 -ss 00:00:03 -t 00:00:08 -async 1 cut.mp4

再エンコードするときに、品質関連のオプションや特定のAACエンコーダーを追加することもできます。詳細については、ffmpegのビデオ用のx264 エンコーディングガイドとオーディオ用のAACエンコーディングガイドを参照してください。

また、この-tオプションは、終了時間ではなく期間を指定します。上記のコマンドは、3秒から始まる8秒のビデオをエンコードします。3秒で開始し、8秒で終了するには、を使用します-t 5。現在のバージョンのffmpegを使用している場合は、上記のコマンド-t-toで置き換えて、指定した時間に終了することもできます。


4
ビデオの最後まで指定するショートカットはありますか?
Jikku Jose、

20
@JikkuJose:-t/ -toとその引数を省略して、最後まで続行します。
mark4o 2015

41
注:ffmpegはその場所に直接スキップするため-ss、入力ファイルの前(の前-i)を指定する方が高速です。ただし、その場合、時間も「ゼロ」に設定さ-toれ、誤った時間を指すことになります。出典:trac.ffmpeg.org/wiki/Seeking
デニウソンSáマイア

4
これを使用した後、オーディオとビデオの同期の問題ffmpeg -i movie.mp4 -ss 00:00:03 -t 00:00:08 -async 1 cut.mp4が発生しますが、元のファイルにはそのような問題はありません。
user2002522

6
@ user2002522:なしで試してください-async 1
mark4o 2015

431

これを使ってみてください。それは私が理解している中で最速かつ最高のffmpeg-wayです。

 ffmpeg -ss 00:01:00 -i input.mp4 -to 00:02:00 -c copy output.mp4

このコマンドは、ビデオを数秒でトリミングします!

私はここで私のブログそれを説明しまし

-i:入力ファイルを指定します。その場合は(input.mp4)です。
-ss: -iと一緒に使用すると、入力ファイル(input.mp4)内で検索​​して配置します。
00:01:00:これは、トリミングされたビデオが始まる時間です。
-to:これは、開始(00:01:40)から終了(00:02:12)までの期間を指定します。
00:02:00:これは、トリミングされたビデオが終了する時間です。
-c copy:これは、ストリームコピーを介してトリミングするオプションです。(注:非常に速い)

タイミングの形式は次のとおりです:hh:mm:ss

現在非常に支持されている回答は時代遅れであり、トリムが非常に遅くなることに注意してください。詳細については、このffmpegの公式記事をご覧ください。


9
これにより、45秒の720pファイルが3秒で処理されました。これが正解です。
Dheeraj Bhaskar 2017

7
ただし、これでもキーフレームが不足する可能性があります。私はあなたのカット方法を採用し、受け入れられた回答に従って再エンコードし、再エンコードに費やす時間を最小限に抑えました。
ペルソン2017

7
@pelsonが言うように、これはキーフレームを切り取り、最初の数秒を空白のままにします(カット時間がキーフレームの間にある場合)。興味深いことに、パラメーターの順序を変更すると、問題が解決しますffmpeg -ss 00:01:00 -to 00:02:00 -i input.mp4 -ss 00:01:00 -to 00:02:00 -c copy output.mp4。しかし今はスキップが壊れており、終了時刻が正しくありません(私の場合)。
Raphael

6
正確なミリ秒でトリミングする必要がない場合は、この回答を使用する必要があります。これにより、使用可能な最も近いキーフレームが選択されます。これが非常に高速な理由です。最も近いキーフレームを選択し、再エンコードする必要なくスニペットを取り出します。ただし、正確な時間を必要とする場合、最も近いキーフレームを使用するだけでは十分に正確ではありません。利用できる唯一の解決策はビデオを再エンコードすることです、そしてそれがそれがとても遅い理由です。ただし、これが必要な場合の唯一の解決策です。それがOPの問題であったので、他の答えが受け入れられるべきである理由です。
山猫

4
理由は不明ですが、キーフレームの欠落に関する問題が発生するため、これは承認された回答よりも正確であるようには見えません。短いビデオクリップの場合、効果は許容できません。このような場合、遅い再エンコードが唯一の解決策のようです。
icarus74 2018年

91
ffmpeg -i movie.mp4 -ss 00:00:03 -t 00:00:08 -async 1 -c copy cut.mp4 

-c copyを使用して、即座に作成します。その場合、ffmpegはビデオを再エンコードせず、適切なサイズにカットします。


2
of -c copyはうまく機能しますが、私が-async 1を削除した場合のみ
dorien

2
これは、異なる入力コンテナと出力コンテナ(.mkv入力と.mp4出力など)の場合に無効なヘッダーが原因で書き込みに失敗することになります。
Assil Ksiksi 2017年

1
さてさて、あなたは別のコマンドを使用する必要が.MP4にmkvのを変換する:ffmpeg -i movie.mkv -vcodec copy -acodec copy converted_movie.mp4と万力その逆
ヴラドHudnitsky

再エンコードの利点は何ですか?同じ形式の小さなビデオが必要なだけの場合、それは役に立ちますか?
Harsha

29
    ffmpeg -i movie.mp4 -vf trim=3:8 cut.mp4

2番目の3から2番目の8を除くすべてをドロップします。


4
これで最初の8秒が得られ、最初の3秒は最初のフレームでフリーズします。setpts=PTS-STARTPTSトリムフィルターの後にフィルターをチェーンすることで修正されました。
jiggunjer

これは、「エンコーダー 'aac'は実験的ですが、実験的コーデックが有効になっていません。使用する場合は、 '-strict -2'を追加してください。」-strict -2を追加しても効果はありません。結果は長さがゼロのファイルです。
Ivan

4
@Ivan、(コマンドラインの最後ではなく)-strict -2以前に追加してみましたcut.mp4か?
Jan Gondol

ねえ、3秒から8秒なしのビデオだけが欲しいのか教えてくれませんか?
Parth Solanki 2016年

1
これは非常に遅い
Tessaracter

21

ソースビデオの開始時間と終了時間に基づいてカットし、計算を行う必要をなくすには、終了時間を入力オプションとして指定し、開始時間を出力オプションとして指定します。

ffmpeg -t 1:00 -i input.mpg -ss 45 output.mpg

これにより、0:45から1:00まで15秒のカットが生成されます。

これは-ss、出力オプションとして指定された場合、破棄された時間は、入力から読み取られた合計時間に含まれている-tため、停止するタイミングを知るために使用されます。場合一方-ssとして与えられる入力オプション、開始時間がシークされ、カウントされません。このため、混乱が生じます。

省略されたセグメントは破棄される前に処理されるため、シークよりも遅くなりますが、私の知る限り、これが唯一の方法です。大きなファイルの奥からクリッピングしている場合は、計算を-ssして入力に使用する方が賢明です。


4
遅いですが、私にとっては(他の回答からフレームを失うことなく)機能しました
techkuz

8

これが私が使うものです:

ffmpeg -i input.mkv -ss 00:01:00 -to 00:02:00 -c:v copy -c:a copy output.mp4

生成されたmp4ファイルはでも使用できますiMovie

リファレンス:https : //www.arj.no/2018/05/18/trimvideo


複数のカットシーンを連結する場合は、次のスクリプトを使用できます。

#!/usr/bin/env python3

import subprocess

name = "batman.mp4"

times = []
times.append(["01:06:00", "01:07:00"])
times.append(["01:08:00", "01:09:00"])

open('concatenate.txt', 'w').close()
for idx, time in enumerate(times):
    output_filename = f"output{idx}.mp4"
    cmd = ["ffmpeg", "-i", name, "-ss", time[0], "-to", time[1], "-c:v", "copy", "-c:a", "copy", output_filename]
    subprocess.check_output(cmd)
    with open("concatenate.txt", "a") as myfile:
        myfile.write(f"file {output_filename}\n")

cmd = ["ffmpeg", "-f", "concat", "-i", "concatenate.txt", "-c", "copy", "final.mp4"]
output = subprocess.check_output(cmd).decode("utf-8").strip()

これはすでに回答済みです
Tessaracter '26

1
私のアプローチは、受け入れられた答えとは異なります。mp4ファイルの作成に時間がかかるものを試しました。@Tessaracter
alper

1
これは、大きなビデオから小さなクリップを切り取るために私のために働いたここでの唯一の答えです。これは機能し、高速です!!! ありがとう
lacostenycoder

1
どういたしまして。お手伝いできることを嬉しく思います。私は多くのアプローチを試みた後、この答えを見つけることができました。それらのほとんどはかなり遅かった。@lacostenycoder
アルパース

これは、-c:vと-c:aを分割する代わりに、「-c」と「copy」を一​​緒に使用できないのでしょうか。
nstenz


-3

私は6年遅れていますが、上記のすべての回答が@kalaiの質問に適切に対応していないと思います。以下のbashスクリプトは、次の形式のテキストファイルを処理します。

URL | start_time | end_time | filename

例えば

https://www.youtube.com/watch?v=iUDURCrvrMI|00:02:02|00:03:41|1

そして、ファイルをループは、そのファイルダウンロードyoutube-dl間の期間を計算し、サポートをstart_timeし、end_timeそしてそれを渡してffmpegいるので、-t実際にある期間ではなく、本当のend_time

質問があれば私を殴ってください。

    for i in $(<video.txt);
    do
        URL=`echo $i | cut -d "|" -f 1`;
        START=`echo $i | cut -d "|" -f 2`;
        END=`echo $i | cut -d "|" -f 3`;
        FILE=`echo $i | cut -d "|" -f 4`;

        SEC1=`echo $START | sed 's/^/((/; s/:/)*60+/g' | bc`
        SEC2=`echo $END | sed 's/^/((/; s/:/)*60+/g' | bc`

        DIFFSEC=`expr ${SEC2} - ${SEC1}`

        ffmpeg $(youtube-dl -g $URL | sed "s/.*/-ss $START -i &/") -t $DIFFSEC -c copy $FILE".mkv";
        ffmpeg -i $FILE".mkv" -f mp3 -ab 192000 -vn $FILE".mp3";
        rm $FILE".mkv";
    done;

これは、mp3オーディオファイルのみを出力し、ビデオは出力しません。
lacostenycoder

ええ...出力形式を変更するだけです。
rolodex
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.