FFmpegを使用して2つのMP4ファイルを連結する方法


442

私はffmpegを使用して2つのmp4ファイルを連結しようとしています。これは自動プロセスである必要があるため、なぜffmpegを選択したのですか。2つのファイルを.tsファイルに変換してから連結し、連結された.tsファイルをエンコードしようとしています。ファイルはh264とaacでエンコードされており、品質を元の品質と同じか可能な限り近いものに保つことを望んでいます。

ffmpeg -i part1.mp4 -vcodec copy -vbsf h264_mp4toannexb -acodec copy part1.ts
ffmpeg -i part2.mp4 -vcodec copy -vbsf h264_mp4toannexb -acodec copy part2.ts
cat part1.ts part2.ts > parts.ts
ffmpeg -y -i parts.ts -acodec copy -ar 44100 -ab 96k -coder ac -vbsf h264_mp4toannexb parts.mp4

残念ながら、エンコード中にffmpegから次のエラーメッセージが返されます。

[h264 @ 0x1012600]sps_id out of range
[h264 @ 0x1012600]non-existing SPS 0 referenced in buffering period
[h264 @ 0x1012600]sps_id out of range
[h264 @ 0x1012600]non-existing SPS 0 referenced in buffering period
[NULL @ 0x101d600]error, non monotone timestamps 13779431 >= 13779431kbits/s    
av_interleaved_write_frame(): Error while opening file

これはエンコーディングの半分ほどのところで発生するため、2つの.tsファイルを連結して機能させることはできないと思います。

回答:


785

FFmpegには3つの連結メソッドがあります。

1. 連結ビデオフィルター

入力に同じパラメーター(幅、高さなど)がない場合、または形式/コーデックが同じでない場合、またはフィルタリングを実行する場合は、このメソッドを使用します。(一致しない入力だけを再エンコードして、同じコーデックと他のパラメーターを共有し、concat demuxerを使用して他の入力の再エンコードを回避できます)。

ffmpeg -i opening.mkv -i episode.mkv -i ending.mkv \
       -filter_complex "[0:v] [0:a] [1:v] [1:a] [2:v] [2:a] 
                        concat=n=3:v=1:a=1 [v] [a]" \
       -map "[v]" -map "[a]" output.mkv

このメソッドは再エンコードを実行することに注意してください。

2. 連結デマルチプレクサ

この方法は、再エンコードを回避する必要があり、フォーマットがファイルレベルの連結をサポートしていない場合に使用します(一般ユーザーが使用するほとんどのファイルは、ファイルレベルの連結をサポートしていません)。

$ cat mylist.txt
file '/path/to/file1'
file '/path/to/file2'
file '/path/to/file3'

$ ffmpeg -f concat -safe 0 -i mylist.txt -c copy output.mp4

Windowsの場合

(echo file 'first file.mp4' & echo file 'second file.mp4' )>list.txt
ffmpeg -safe 0 -f concat -i list.txt -c copy output.mp4

3. concatプロトコル

この方法は、ファイルレベルの連結をサポートする形式(MPEG-1、MPEG-2 PS、DV)で使用します。MP4 では使用しないでください。

ffmpeg -i "concat:input1|input2" -codec copy output.mkv

これらのフォーマットの性質とこのメソッドによって実行される単純化された連結のため、このメソッドはMP4を含む多くのフォーマットでは機能しません。


使用する方法がわからない場合は、連結デマルチプレクサを試してください。

また見なさい


3
Windowsコマンドプロンプトのエスケープ文字は^;です。また、引用符の問題が発生したため、次のようになりました:ffmpeg -i concat:input1 ^ | input2 -codec copy output
user423430

1
役立つ答え。そして、このバリエーションを読んだとき、私にはさらに理にかなっています
Ryan

3
concatはデマルチプレクサは、ビデオのために動作しますが、私は、オーディオ負けてる
ロイック・

23
ワンライナーの場合:ffmpeg -safe 0 -f concat -i <(find . -type f -name '*' -printf "file '$PWD/%p'\n" | sort) -c copy output.mkv(mkvはmp4よりも多くのコーデックを受け入れますが、mp4で試すこともできます)。-safe 0不満最近のffmpegのバージョンのある安全でないファイル名、および-type fファイルのみをリストするためです。| sortファイルをアルファベット順にソートするために追加しました。理由は、findファイルシステム上に保存されたとして、それらを順番に読み込みます。空白を含むファイルでも機能します。
erik

1
私にとって、Windowsでは、二重引用符は(例の単一引用符ではなく)機能しましたffmpeg -i "concat:input1|input2" -codec copy output。パイプ文字をエスケープする必要はありません。
Shovalt 16

82

MP4ファイルの場合

以下のためのMP4ファイル:以下はのための効果的なソリューションでした(私はDailyMotion.comから入手した50分間のテレビエピソード、唯一の三つの部分にように3つのMP4ビデオファイルをダウンロード可能)のWindows 7、および行いませ再符号化を伴いますファイル。

ファイルの名前を変更しました( テレビエピソード全体を表示するためにパーツが正しい順序になるように file1.mp4file2.mp4file3.mp4

次に、次の内容の簡単なバッチファイル(concat.bat)を作成しました。

:: Create File List
echo file file1.mp4 >  mylist.txt 
echo file file2.mp4 >> mylist.txt
echo file file3.mp4 >> mylist.txt

:: Concatenate Files
ffmpeg -f concat -i mylist.txt -c copy output.mp4

バッチファイル、および ffmpeg.exe、必見の両方と同じフォルダに置くことのMP4ファイルを接合します。次に、バッチファイルを実行します。通常、実行にかかる時間は10秒未満です。

補遺(2018/10/21)-

あなたが探していたものが多くの再入力なしで現在のフォルダー内のすべてのmp4ファイルを指定する方法である場合は、代わりにWindows バッチファイルでこれを試してください(オプションを含める必要があります) -safe 0を):

:: Create File List
for %%i in (*.mp4) do echo file '%%i'>> mylist.txt

:: Concatenate Files
ffmpeg -f concat -safe 0 -i mylist.txt -c copy output.mp4

これは、Windows 7ではバッチファイルで機能します。バッチファイルでのみ機能するため、コマンドラインで使用しないでください。


5
はるかに簡単なソリューションです。
1934286

これが最善かつ最も簡単な答えです。よくできました、私の仲間。あなたは私の日を救った。
DysaniazzZ 2018

これは良い解決策ですが、バッチファイルについて話すと、このサウンドはプリミティブになり(バッチで行われたように)、それよりも複雑になります(バッチファイルは完全に不要であるため)。単純に表示するとC:\blah>type mylist.txt<ENTER>(ファイルの内容が表示されるので)はるかに明確です。次にffmpeg -f concat -i mylist.txt -c copy output.mp4<ENTER> 、参照trac.ffmpeg.org/wiki/Concatenate (その参照は同じファイル名mylist.txtも使用する) を含める必要があります
barlop

これは、-iパラメーターのファイルの長いリストを入力する手間を省く、非常に優れたソリューションです。Linuxではこれを行いました。ls -1 P1041*.mp4 | sed s/"P"/" file P"/g > mylist.txtこれは、バッチスクリプトをコーディングするよりもさらにクールです。とにかく、-c copy(私が知らなかった)非常に速く実行し、これがこの答えの本当の魔法です。
Würgspaß

1
私のmp4ファイルでは、ffmpeg v3.2.2を使用してMacで連結コードを実行した後、出力ファイルにオーディオがまったくありません。
kakyo

59

これは、中間ファイルを必要とせずにこれを行うための高速(1分未満かかる)でロスレスな方法です。

ls Movie_Part_1.mp4 Movie_Part_2.mp4 | \
perl -ne 'print "file $_"' | \
ffmpeg -f concat -i - -c copy Movie_Joined.mp4

"ls"には結合するファイルが含まれます "perl"は連結ファイルをオンザフライでパイプに作成します "-i-"部分はffmpegにパイプから読み取るように指示します

(注-私のファイルにはスペースも奇妙なものもありませんでした。「ハード」ファイルでこのアイデアを実行したい場合は、適切なシェルエスケープが必要になります)。


2
OSXでこれを実行したところ、うまくいきました!要件がほとんどない、素晴らしく高速なロスレスソリューション。
GM Lucid 2014年

1
空白を含むファイルのための適切なエスケープ付き:ls Movie_Part_1.mp4 Movie_Part_2.mp4 | perl -ne '$_ =~ s/\n$//; print "file '"'"'$_'"'"'\n"' | ffmpeg -f concat -i - -c copy Movie_Joined.mp4
トーマスバッケム

4
ls * | perl -ne 'print "file $_"' | ffmpeg -f concat -i - -c copy Movie_Joined.mp4ファイルに適切な名前が付けられていて、順序どおりになっている場合も、同様に実行できます。OS X上で、私が望んでいたとおりにうまく機能しました。
natebeaty

3
Linuxでは、次のワンライナーを使用しましたffmpeg -safe 0 -f concat -i <(find . -type f -name '*' -printf "file '$PWD/%p'\n" | sort) -c copy output.mkv(mkvはmp4よりも多くのコーデックを受け入れますが、mp4で試すこともできます)。-safe 0不満最近のffmpegのバージョンのある安全でないファイル名、および-type fファイルのみをリストするためです。| sortファイルをアルファベット順にソートするために追加しました。理由は、findファイルシステム上に保存されたとして、それらを順番に読み込みます。空白を含むファイルでも機能します。
erik

12
私は、このパラメータを追加する必要がありましたffmpegそれを動作させるために:-protocol_whitelist file,tcp,http,pipe
Bensge

44

MP4ファイルの場合:

それらがまったく同じでない(100%同じコーデック、同じ解像度、同じタイプ)MP4ファイルの場合、最初にそれらを中間ストリームにトランスコードする必要があります。

ffmpeg -i myfile1.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts temp1.ts
ffmpeg -i myfile2.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts temp2.ts
// now join
ffmpeg -i "concat:temp1.ts|temp2.ts" -c copy -bsf:a aac_adtstoasc output.mp4

注意!:出力は最初のファイルのようになります(2番目のファイルではありません)


2
以下の私の回答に示されているように、ファイルをトランスコードする必要はありません。FFmpegは、複数のmp4ファイルを単一のmp4ファイルに連結できます。中間ステップや再エンコードは必要ありません。再エンコードが必要になる唯一のケースは、元のファイルがmp4ファイルではない場合で、出力ファイルとしてmp4ファイルを作成することです。
Ed999、2017年

@T。Todua:2つのmp4ソースファイルの違いを正確に知りたいと思います。異なるサンプルレートを使用していますか(例:44,100 Hzと48,000 Hz)?または、異なるビットレート(128 kbpsと64 kbpsなど)を使用していますか?どちらの場合でも、コマンド-c copy(ストリームコピー命令)がソースファイルを変更して互換性を持たせる方法がよくわかりません。
Ed999 2017

4
@ T.Toduaこんにちは。ビデオにオーディオトラックがない場合、コマンドは適切に機能します。ただし、myfile1.mp4にオーディオがなく、myfile2.mp4にオーディオがある場合、結果のoutput.mp4にはオーディオがありません。予想されるoutput.mp4にはオーディオが含まれている必要があります。どうすれば解決できますか?
AnswerZhao 2017年

2
@ T.Todua er ....それはあまりにも悪いです。file1 | file2は、file2 | file1を使用して別のビデオを生成します。順序は重要です。
AnswerZhao、

1
concat 2 mp4ファイルでコマンドを試しました。できます。ただし、2番目のファイルのオーディオは、生成された新しい連結のAh-oh-Eeの音声のように途切れ途切れになります。これに対する修正はありますか?
superlinux '17

35

3つの.mp3オーディオファイルを1つの.m4aファイルに連結しようとしていましたが、このffmpegコマンドは機能します。

入力コマンド:

ffmpeg -i input1.mp3 -i input2.mp3 -i input3.mp3 -filter_complex concat=n=3:v=0:a=1 -f MOV -vn -y input.m4a

の意味: "-filter_complex concat = n = 3:v = 0:a = 1"

concatは、メディア連結(結合)関数を使用することを意味します。
nは、入力ファイルの総数を確認することを意味します。
v はビデオがあるという意味ですか?0 =ビデオなし、1 =ビデオあり。手段は、オーディオを持っていますか?0 =音声なし、1 =音声あり。-f手段は(、すべてのサポートされている形式を確認するために使用を設定したファイル形式を強制する)-vn手段に無効ビデオ(とも望まない場合は、オーディオ無効になります)-y手段上書き出力ファイルを(出力ファイルがすでに存在する場合)。

ffmpeg -formats
-an

詳細:ffmpeg -h full すべてのオプションを印刷する(すべてのフォーマットとコーデック固有のオプションを含む、非常に長い)


1
fiを使用-f concat -safe 0 -i "file.txt" -c copy -y "OutPut.mp4"すると連結されますが、一部のビデオにオーディオが含まれ、一部にオーディオが含まれていない場合、機能しません。これを整理するにはどうすればよいですか。ありがとう–
Ahmad

1
これは機能します。回答の詳細な説明に感謝します。とても助かります。
ジョーT.ボカ2018

31

中間形式としてmpgを使用することになり、動作しました(これは危険な例です。-qscale0はビデオを再エンコードします...)

ffmpeg -i 1.mp4 -qscale 0 1.mpg
ffmpeg -i 2.mp4 -qscale 0 2.mpg
cat 1.mpg 2.mpg | ffmpeg -f mpeg -i - -qscale 0 -vcodec mpeg4 output.mp4

8
このコメントの時点で、-sameqは削除されました。-qscale 0代わりに使用してください。
Xavier Ho

6
-sameq「同じ品質」という意味ではなく、@ XavierHoによって言及されているようにffmpegから削除されました。
llogan 2013

3
2つのファイルを連結するためだけに中間形式でビデオをトランスコードする必要があるのは残念です。あなたは世代損失を得るでしょう。コンテナ形式より深く進まないで、concat上記の@rogerdpackのようにで、ffmpegでコマンドをお勧めします。
Randall Cook

8
これはなぜ受け入れられた答えなのですか?これは非常に悪い方法です。
表示名

4
@SargeBorsch動作するため。ページの他のすべてを試しましたが、どれも機能しません。

14

ffmpegでのさまざまな連結方法に関する詳細なドキュメントは、こちらにあります

「連結フィルター」を使用すると、すばやく連結できます。

再エンコードを実行します。このオプションは、入力のビデオ/オーディオ形式が異なる場合に最適です。

2つのファイルを連結する場合:

ffmpeg -i input1.mp4 -i input2.webm \
-filter_complex "[0:v:0] [0:a:0] [1:v:0] [1:a:0] concat=n=2:v=1:a=1 [v] [a]" \
-map "[v]" -map "[a]" output.mp4

3つのファイルを連結する場合:

ffmpeg -i input1.mp4 -i input2.webm -i input3.mp4 \
-filter_complex "[0:v:0] [0:a:0] [1:v:0] [1:a:0] [2:v:0] [2:a:0] concat=n=3:v=1:a=1 [v] [a]" \
-map "[v]" -map "[a]" output.mp4

これは、同じだけでなく複数の入力ファイルタイプでも機能します。


この例にあるオプションの詳細を指定できますか?
開発者

@開発者:オプションの説明-> Concatフィルターwiki
SJ00

4
3つのファイルを連結する場合、n = 2ではなくconcat = n = 3:v = 1:a = 1を使用する必要があります
Cynapsis

1
ロスレスの連結が得られません。ouput.mp4ビデオビットレートが入力ビデオのビデオビットレートより大幅に低くなっています
jasan

指摘してくれたCynapsisとコマンドを更新してくれたgeorgiecasey
SJ00

10

オプション3を使用してMacでいくつかのMP4を連結すると、受け入れられた回答でパイプオペレーターが機能しないことがわかりました。

次のワンライナーは、Mac(High Sierra)で動作し、中間ファイルの作成を必要とせずにmp4を連結します。

ffmpeg -f concat -safe 0 -i <(for f in ./*.mp4; do echo "file '$PWD/$f'"; done) -c copy output.mp4


2
この単純な答えは、実際に私のために働いた唯一のものです。このシンプルなワンライナーが必要なすべてである一方で、ここや他の場所にあるドキュメントのページに何ページもあり、実際に機能します。ありがとうございました。
ブルジェイ

10

ここではffmpeg、使用しているだけで使用していない2つの純粋なbashソリューション

  • 中間ファイル
  • perl、python、javascript

を使用したワンライナーソリューション ls

ls video1.mp4 video2.mp4 | while read line; do echo file \'$line\'; done | ffmpeg -protocol_whitelist file,pipe -f concat -i - -c copy output.mp4

0または2+の引数を取る関数

#######################################
# Merge mp4 files into one output mp4 file
# usage:
#   mergemp4 #merges all mp4 in current directory
#   mergemp4 video1.mp4 video2.mp4
#   mergemp4 video1.mp4 video2.mp4 [ video3.mp4 ...] output.mp4 
#######################################
function mergemp4() {
  if [ $# = 1 ]; then return; fi

  outputfile="output.mp4"

  #if no arguments we take all mp4 in current directory as array
  if [ $# = 0 ]; then inputfiles=($(ls -1v *.mp4)); fi
  if [ $# = 2 ]; then inputfiles=($1 $2); fi  
  if [ $# -ge 3 ]; then
    outputfile=${@: -1} # Get the last argument
    inputfiles=(${@:1:$# - 1}) # Get all arguments besides last one as array
  fi

  # -y: automatically overwrite output file if exists
  # -loglevel quiet: disable ffmpeg logs
  ffmpeg -y \
  -loglevel quiet \
  -f concat \
  -safe 0 \
  -i <(for f in $inputfiles; do echo "file '$PWD/$f'"; done) \
  -c copy $outputfile

  if test -f "$outputfile"; then echo "$outputfile created"; fi
}

注:このスレッドでいくつかの解決策を試しましたが、誰も私を満足させませんでした


9

rogerdpackとEd999の応答に基づいて、.shバージョンを作成しました

#!/bin/bash

[ -e list.txt ] && rm list.txt
for f in *.mp4
do
   echo "file $f" >> list.txt
done

ffmpeg -f concat -i list.txt -c copy joined-out.mp4 && rm list.txt

*.mp4現在のフォルダ内のすべてのファイルを結合しますjoined-out.mp4

Macでテスト済み。

結果のファイルサイズは、テストした60個のファイルの正確な合計です。損失は​​ないはずです。ちょうど私が必要としたもの


9

これは私のために働いた(Windows上で)

ffmpeg -i "concat:input1|input2" -codec copy output

例...

ffmpeg -i "concat:01.mp4|02.mp4" -codec copy output.mp4

パイソン

いくつかのpythonコードを使用して、フォルダー内にある多くのmp4でそれを実行します(python.orgからpythonをインストールし、このコードをコピーしてmp4.pyというファイルに貼り付けて保存し、pythonでフォルダーに開いているcmdから実行しますmp4.pyとフォルダー内のすべてのmp4が連結されます)

import glob
import os

stringa = ""
for f in glob.glob("*.mp4"):
    stringa += f + "|"
os.system("ffmpeg -i \"concat:" + stringa + "\" -codec copy output.mp4")

Pythonを使用したバージョン2

私のブログへの私の投稿から、これは私がそれをPythonでどのように行うかです:

import os
import glob

def concatenate():
    stringa = "ffmpeg -i \"concat:"
    elenco_video = glob.glob("*.mp4")
    elenco_file_temp = []
    for f in elenco_video:
        file = "temp" + str(elenco_video.index(f) + 1) + ".ts"
        os.system("ffmpeg -i " + f + " -c copy -bsf:v h264_mp4toannexb -f mpegts " + file)
        elenco_file_temp.append(file)
    print(elenco_file_temp)
    for f in elenco_file_temp:
        stringa += f
        if elenco_file_temp.index(f) != len(elenco_file_temp)-1:
            stringa += "|"
        else:
            stringa += "\" -c copy  -bsf:a aac_adtstoasc output.mp4"
    print(stringa)
    os.system(stringa)

concatenate()

1
連結プロトコルはMP4では使用しないでください。承認された回答に記載されているように機能しません。
llogan

@LordNeckbeard出力ビットレートを指定しながら2つのMP4ビデオを連結することについて、このffmpegの質問への回答を知っているのでしょうか。video.stackexchange.com/q/24569/5657ありがとう。
ライアン

@LordNeckbeard私の推測では、もしあなたがそれに答えるなら、あなたの答えは最高です。私は特に自分自身に満足していません。
ライアン

(Neckbeard卿が指摘するように)連結を成功させるために.mp4ファイルを中間の.TSフォーマットに変換する必要があるだけでなく、おそらくさらに悪いことに、この答えは入力の必要性に対処しさえしません一致するビットレート、フレームレート、サンプルレート、タイムベース、および継続時間を持つビデオファイル。これらの5つの要素がすべて共通していないと、ファイル連結する(つまり、ストリームコピーを使用して結合する)ことはできませんが、代わりに再エンコードする必要があります。
Ed999 2018年

7

.mp4ファイルについては、オープンソースのコマンドラインツールを使用する方がより速く、より速く機能することがわかりましたmp4box。次に、次のように使用できます。

mp4box.exe -add video1.mp4 -cat video2.mp4 destvideo.mp4

ほとんどのプラットフォームでは、こちらからダウンロードしてくださいhttps : //gpac.wp.imt.fr/mp4box/


2
これは誰かにとって役立つかもしれませんが、要件は次のとおりです。「ffmpegを使用して2つのmp4ファイルを連結しようとしています。これは自動プロセスにする必要があります」質問全体を読んで、正しい答えを出してみてください。
thvs86

5
この答えは完全に適切です。それは同じ仕事をするFOSSツールです。FFmpegと同じようにスクリプトで使用できます。それはFFmpegの答えのどれよりも簡単に仕事をします。それらがどれほど複雑か見てください!それらの1つは、Node.jsを使用してFFmpegを呼び出します!狂気。不思議に立ち止まって、もう一度StackOverflowを役立ててみてください。このサイトは、あなたのようなワンクのおかげで、以前の自分の影になっています。また、この質問は「XY問題」の一例です。
ブルジェイ

mp4boxがFOSSツールであることは重要ではありません。質問では、mp4boxではなくffmpegを使用して回答を求めました。
jramos775

@ thvs86私はその一例です。私はそれがメディアのための本当のスイスナイフであるので、ffmpegを使用します。議論の構造は非常に複雑になる可能性があるため、特定の使用例についてのヘルプも検索します(これは、ここでのさまざまな回答によって示されています)。私がmp4boxについて聞いたのはこれが初めてであり、この答えがなければ私はそれを見つけられなかったでしょう。だから私から+1してください、どうぞ、無意味なインターネットポイントや厳格なルールについてよりも、答えを求める人々について考えてください。
Pavel

4

これは、いくつかのGoPro mp4を720p mp4に連結するために作成したスクリプトです。お役に立てば幸いです。

#!/bin/sh
cmd="( "
for i; do
    cmd="${cmd}ffmpeg -i $i -ab 256000 -vb 10000000 -mbd rd -trellis 2 -cmp 2 -subcmp 2 -g 100 -f mpeg -; "
done
cmd="${cmd} ) | ffmpeg -i - -vb 10000000 -ab 256000 -s 1280x720 -y out-`date +%F-%H%M.%S`.mp4"
echo "${cmd}"
eval ${cmd}

これは連結していません。このコードは入力を連結せず、再エンコードします。これは、任意のビデオファイルを受け取り、それらを共通のオーディオおよびビデオのビットレートに変更します(ソースファイルの元のビットレートまたは元のフレームサイズに関係なく)。o / pは、ストリームコピーを使用して2つのファイルを結合し、再エンコードしないことを望んでいたため、これは尋ねられた質問に対応していません。
Ed999 2018年

4

ここのドキュメントから:https : //trac.ffmpeg.org/wiki/Concatenate

MP4ファイルがある場合、最初にそれらをMPEG-2トランスポートストリームにトランスコードすることにより、これらを無損失で連結できます。H.264ビデオとAACオーディオでは、以下を使用できます。

ffmpeg -i input1.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts intermediate1.ts
ffmpeg -i input2.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts intermediate2.ts
ffmpeg -i "concat:intermediate1.ts|intermediate2.ts" -c copy -bsf:a aac_adtstoasc output.mp4

このアプローチはすべてのプラットフォームで機能します。

これをクロスプラットフォームスクリプトにカプセル化する機能が必要だったのでfluent-ffmpeg、次のソリューションを使用して思いつきました。

const unlink = path =>
  new Promise((resolve, reject) =>
    fs.unlink(path, err => (err ? reject(err) : resolve()))
  )

const createIntermediate = file =>
  new Promise((resolve, reject) => {
    const out = `${Math.random()
      .toString(13)
      .slice(2)}.ts`

    ffmpeg(file)
      .outputOptions('-c', 'copy', '-bsf:v', 'h264_mp4toannexb', '-f', 'mpegts')
      .output(out)
      .on('end', () => resolve(out))
      .on('error', reject)
      .run()
  })

const concat = async (files, output) => {
  const names = await Promise.all(files.map(createIntermediate))
  const namesString = names.join('|')

  await new Promise((resolve, reject) =>
    ffmpeg(`concat:${namesString}`)
      .outputOptions('-c', 'copy', '-bsf:a', 'aac_adtstoasc')
      .output(output)
      .on('end', resolve)
      .on('error', reject)
      .run()
  )

  names.map(unlink)
}

concat(['file1.mp4', 'file2.mp4', 'file3.mp4'], 'output.mp4').then(() =>
  console.log('done!')
)

1
ffmpeg \
  -i input_1.mp4 \
  -i input_2.mp4 \
  -filter_complex '[0:v]pad=iw*2:ih[int];[int][1:v]overlay=W/2:0[vid]' \
  -map [vid] \
  -c:v libx264 \
  -crf 23 \
  -preset veryfast \
  output.mp4

1
回答を投稿するだけでなく、OPや将来の読者にとってもソリューションをよりよく理解するための小さな説明を追加することもできます。
Balagurunathan Marimuthu 2017

1
これにより、両方の入力が同時に隣り合って再生される新しいサイレントビデオが作成されました。連結すると、input_1.mp4が再生され、次にinput_2.mp4が再生されるビデオが作成されると予想していました
Alexx Roche

3
これは完全に間違った答えでした。これはビデオを連結するものではなく、@ AlexxRocheが言及したように、サイレントに並べて再生するだけです。
Kalob Taulien、2018

1

現在のディレクトリからすべてのmp4ファイルをマージする

私は個人的に、後で削除する必要がある外部ファイルを作成しないのが好きなので、リストに番号が付けられたファイル(などfile_1_name, file_2_name, file_10_name, file_20_name, file_100_name)を含む私の解決策が続いていました

#!/bin/bash
filesList=""
for file in $(ls -1v *.mp4);do #lists even numbered file
    filesList="${filesList}${file}|"
done
filesList=${filesList%?} # removes trailing pipe
ffmpeg -i "concat:$filesList" -c copy $(date +%Y%m%d_%H%M%S)_merged.mp4

このコードをメモ帳にコピーしても何も起こりませんでした。
7vujy0f0hy

1
@ 7vujy0f0hyこれは、bashシェルを備えたLinuxで動作します。cygwinでも動作する可能性があります
Pipo

1

以下のさまざまな試行の後、スクリプトはWindows 10 PowerShellで動作しました。

    $files=Get-ChildItem -path e:\ -Filter *.mp4


    $files| ForEach-Object  {"file '$($_.FullName)'"}| Out-File -FilePath e:\temp.txt -Encoding ASCII


    if (-not (test-path "e:\ffmpeg\bin\ffmpeg.exe")) {throw "e:\ffmpeg\bin\ffmpeg.exe needed"}

    E:\ffmpeg\bin\ffmpeg.exe -safe 0 -f concat -i "e:\temp.txt" -c copy -bsf:v hevc_mp4toannexb -an e:\joined.mp4

    # Conversion Cleanup
    Remove-Item e:\temp.txt

ここで最初の2行は、次の内容のテキストファイルtemp.txtを作成します

file 'e:\first.mp4'
file 'e:\second.mp4'

3、4行目は、ffmpegがパスで利用可能かどうかをチェックし、「joined.mp4」を作成します

他の回答との主な違いは次のとおりです

usage  of -bsf:v hevc_mp4toannexb -an

上記の私のmp4ファイルが機能するため、ビデオのエンコーディングによっては、以下のような他の代替手段を使用する必要がある場合があります。

h264_mp4toannexb

このようなすべてのビットストリームフィルターは、https://ffmpeg.org/ffmpeg-bitstream-filters.htmlにあります。


私のものはCCTVカメラから来たMP4でした。そのコマンドがないと、会話は出力ファイルの生成に失敗します。そのWebサイトからの最新のffmpegを使用しています。
rahul maindargi

0

これは、コマンド置換と連結ビデオフィルターを使用してMP4ファイルでいっぱいのディレクトリに参加するための私の方法です(これは再エンコードされます)-特に多くのファイルがある場合、他の誰かがこのワンライナーを使用するだろうと考えました(私はちょうど17ファイルを一挙に結合しました):

ffmpeg $(for f in *.mp4 ; do echo -n "-i $f "; done) -filter_complex \
"$(i=0 ; for f in *.mp4 ; do echo -n "[$i:v] [$i:a] " ; i=$((i+1)) ; done \
&& echo "concat=n=$i:v=1:a=1 [v] [a]")" -map "[v]" -map "[a]" output.mp4

注:このコマンドは、ファイルに名前が付けられた順序(つまり、を実行した場合に表示される順序と同じ)でファイルを結合します。ls *.mp4私の場合、それぞれにトラック番号が付いているため、うまくいきました。


0

ここで説明する連結プロトコル。 https://trac.ffmpeg.org/wiki/Concatenate#protocol

中間ファイルを回避するために名前付きパイプを使用して実装する場合

非常に高速で(読み取り:インスタント)、フレームがドロップされず、適切に機能します。

名前付きパイプファイルを削除し、ビデオがH264およびAACであるかどうかを確認することを忘れないでください(H264とAACのffmpeg -i filename.mp4言及を確認してください)。


-1

再利用可能なPowerShellスクリプトの形式で受け入れられた回答

Param(
[string]$WildcardFilePath,
[string]$OutFilePath
)
try
{
    $tempFile = [System.IO.Path]::GetTempFileName()
    Get-ChildItem -path $wildcardFilePath | foreach  { "file '$_'" } | Out-File -FilePath $tempFile -Encoding ascii
    ffmpeg.exe -safe 0 -f concat -i $tempFile -c copy $outFilePath
}
finally
{
    Remove-Item $tempFile
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.