FFmpeg를 사용하여 두 개의 MP4 파일을 연결하는 방법은 무엇입니까?


443

ffmpeg를 사용하여 두 개의 mp4 파일을 연결하려고합니다. 나는 이것이 자동 프로세스이기 때문에 ffmpeg를 선택한 이유입니다. 두 파일을 .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

이것은 인코딩의 절반 정도 발생하여 두 개의 .ts 파일을 함께 연결할 수 없으며 작동한다고 생각합니다.

답변:


786

FFmpeg에는 세 가지 연결 방법이 있습니다.

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. concat demuxer

재 인코딩을 피하고 형식이 파일 레벨 연결을 지원하지 않는 경우 (일반 사용자가 사용하는 대부분의 파일은 파일 레벨 연결을 지원하지 않는 경우)이 방법을 사용하십시오.

$ 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. 연결 프로토콜

파일 수준 연결을 지원하는 형식 (MPEG-1, MPEG-2 PS, DV)과 함께이 방법을 사용하십시오. 마십시오 하지 MP4로 사용합니다.

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

이 방법은 이러한 형식의 특성과이 방법으로 수행되는 단순한 연결로 인해 MP4를 포함한 많은 형식에서 작동하지 않습니다.


어떤 방법을 사용해야하는지 확실치 않은 경우 concat demuxer를 사용해보십시오.

참조


3
Windows 명령 프롬프트 이스케이프 문자는 ^입니다. 나는 또한 따옴표에 문제가있어서 다음과 같이되었다 : ffmpeg -i concat : input1 ^ | input2 -codec copy output
— user423430

1
유용한 답변. 나는이 변화를 읽을 때 그리고 그것은 나에게 더욱 의미가 만든 : superuser.com/a/607384/74576
— 라이언에게

3
concat demuxer는 비디오에서 작동하지만 오디오가 손실됩니다
— Loïc

24
oneliner 사용의 경우 : 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

84

MP4 파일

들어 .MP4 파일 : 다음에 대한 효과적인 솔루션이었다 (나는 DailyMotion.com에서 얻은 50 분 TV 에피소드, 만 세 부분으로 세 .MP4 비디오 파일을 다운로드 할) 윈도우 7 및 않습니다 NOT 재 인코딩을 포함 파일.

전체 TV 에피소드를 볼 수 있도록 올바른 순서 로 파일의 이름을 바꿨습니다 ( file1.mp4 , file2.mp4 , file3.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 는 AS, 반드시 모두가 같은 폴더에 넣어 .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

이것은 좋은 해결책이지만 배치 파일에 대해 이야기하면이 배치가 완료 된 것처럼 소리가 원시적이며 배치 파일이 완전히 불필요하기 때문에보다 복잡합니다. 간단히 보여 주면 훨씬 더 명확합니다. 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매개 변수에 대한 긴 파일 목록을 입력하지 않아도되는 매우 좋은 솔루션 입니다. 리눅스에서 나는 이것을했다 : ls -1 P1041*.mp4 | sed s/"P"/" file P"/g > mylist.txt배치 스크립트를 코딩하는 것보다 훨씬 멋지다. 어쨌든, -c copy매우 빨리 수행합니다 (내가 알지 못했던). 이것은이 답변의 진정한 마술입니다.
— Würgspaß

1
내 mp4 파일의 경우 ffmpeg v3.2.2를 사용하여 Mac에서 concat 코드를 실행 한 후 출력 파일에 오디오가 전혀 없습니다.
— kakyo

60

다음은 중간 파일이 필요없이 빠르고 (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

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
— 토마스 Bachem는

4
ls * | perl -ne 'print "file $_"' | ffmpeg -f concat -i - -c copy Movie_Joined.mp4파일 이름과 순서가 올바른 경우 에도 할 수 있습니다 . 정확히 내가 원했던 OS X에서 나를 위해 훌륭하게 일했습니다.
— natebeaty

3
리눅스에서는이 oneliner를 사용했습니다 : 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 December

13
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
아래 답변에 표시된 것처럼 파일을 트랜스 코딩 할 필요는 없습니다. FFmpeg는 여러 mp4 파일을 하나의 mp4 파일로 연결할 수 있습니다. 중간 단계없이 다시 인코딩하지 않아도됩니다. 다시 인코딩해야하는 유일한 경우는 원본 파일이 mp4 파일이 아닌 경우 mp4 파일을 출력 파일로 만드는 것입니다.
— Ed999

@티. Todua : 두 mp4 소스 파일의 차이점이 정확히 무엇인지 배우고 싶습니다. 다른 샘플링 속도 (예 : 44,100 Hz 및 48,000 Hz)를 사용하고 있습니까? 아니면 다른 비트 전송률 (예 : 128kbps 및 64kbps)을 사용하고 있습니까? 어느 경우이든, -c copy 명령 (스트림 복사 명령)이 소스 파일을 호환 가능하게 수정하는 방법을 이해하지 못합니다.
— Ed999

4
@ T.Todua 안녕하세요, 비디오가 오디오 트랙이 없을 때 명령이 잘 작동합니다. 그러나 myfile1.mp4에 오디오가없고 myfile2.mp4에 오디오가 있으면 결과 output.mp4에 오디오가 없습니다. 예상 출력 .mp4에는 오디오가 포함되어야합니다. 어떻게 해결할 수 있습니까?
— AnswerZhao

2
@ T.Todua er .... 너무 나쁘다. file1 | file2는 file2 | file1과 다른 비디오를 생성합니다. 순서가 중요합니다.
— AnswerZhao

1
concat 2 mp4 파일에서 명령을 시도했습니다. 효과가있다. 그러나 두 번째 파일의 오디오는 생성 된 새 연결에서 Ah-oh-Ee 음성처럼 고르지 않습니다. 이 문제를 해결 했습니까?
— superlinux

35

세 개의 .mp3오디오 파일을 하나의 .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
작동합니다. 답변에 자세한 설명을 주셔서 감사합니다. 매우 도움이됩니다.
— Joe T. Boka

31

나는 mpg를 중간 형식으로 사용하여 효과가있었습니다. (이것은 위험한 예입니다. -qscale 0은 비디오를 다시 인코딩합니다 ...)

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

3
두 파일을 연결하기 위해 비디오를 중간 형식으로 트랜스 코딩해야하는 것은 부끄러운 일입니다. 당신은 세대 손실을 얻을 것이다. concat@rogerdpack이 위와 같이 컨테이너 형식보다 더 깊이 들어 가지 않고 ffmpeg 의 명령을 사용하는 것이 좋습니다.
— 랜달 쿡

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 filter wiki
— SJ00

4
3 개의 파일을 연결할 때 concat = n = 3 : v = 1 : a = 1이 아닌 n = 2를
— 사용해야합니다.

1
무손실 연결이되지 않습니다. ouput.mp4비디오 비트 전송률이 입력 비디오 비디오 전송률보다 상당히 낮습니다
— jasan

그것을 지적 해 주셔서 감사합니다 Cynapsis 및 명령 업데이트를위한
— georgiecasey

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
이 간단한 대답은 실제로 나를 위해 일한 유일한 대답입니다. 여기와 다른 곳에서 문서 페이지를 볼 수 있지만이 간단한 원 라이너는 필요한 모든 것입니다. 실제로 작동합니다. 감사합니다.
— blujay

10

여기에만 사용 ffmpeg하고 사용하지 않는 2 개의 순수한 bash 솔루션

  • 중개 파일
  • 펄, 파이썬 또는 자바 스크립트

사용하는 원 라이너 솔루션 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

이것은 나를 위해 일했다 (창문에서)

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

예를 들면 ...

ffmpeg -i "concat:01.mp4|02.mp4" -codec copy output.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")

파이썬 버전 2

내 블로그의 게시물에서 가져온 것은 다음과 같이 파이썬에서 수행하는 방법입니다.

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
concat 프로토콜은 MP4와 함께 사용하지 않아야하며 허용 된 답변에 언급 된대로 작동하지 않습니다 .
— llogan

@LordNeckbeard 출력 비트 레이트를 지정하면서 2 개의 MP4 비디오를 연결하는 것에 대한이 ffmpeg 질문에 대한 답변을 알고 있는지 궁금합니다. video.stackexchange.com/q/24569/5657 감사합니다.
— Ryan

@LordNeckbeard 내 추측은 당신이 그것을 위해 있다면, 당신의 대답은 여전히 ​​가장 좋은 것입니다! 나는 내 자신에 특히 만족하지 않습니다.
— Ryan

연결이 성공하기 위해서는 Lord Neckbeard가 지적한 것처럼 .mp4 파일을 중간 .TS 형식으로 변환해야 할뿐만 아니라이 답변이 입력의 필요성을 해결하기 시작하지도 않습니다. 비트 레이트, 프레임 속도, 샘플 속도, 타임베이스 및 지속 시간이 일치하는 비디오 파일. 이러한 5 가지 요소가 공통적으로 존재 하지 않으면 파일 을 연결할 수 없으며 (즉 , 스트림 복사를 사용하여 결합 ) 대신에 다시 인코딩해야합니다.
— Ed999

7

를 들어 .mp4파일, 나는 그것이 오픈 소스 명령 줄 도구를 사용하는 것이 더 빠르게 작동 발견 mp4box. 그런 다음 다음과 같이 사용할 수 있습니다.

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

대부분의 플랫폼에서 여기에서 다운로드하십시오 : https://gpac.wp.imt.fr/mp4box/


2
이것은 누군가에게 유용 할 수 있지만 요구 사항은 다음과 같습니다. " ffmpeg를 사용하여 두 개의 mp4 파일을 연결하려고합니다. 자동 프로세스가되어야합니다 ." 전체 질문을 읽고 적절한 답변을 제공하십시오.
— thvs86

5
이 답변은 전적으로 정답입니다. 동일한 작업을 수행하는 FOSS 도구입니다. FFmpeg와 같은 스크립트에서 사용할 수 있습니다. FFmpeg 답변보다 더 간단하게 작업을 수행합니다. 그들이 얼마나 복잡한 지보세요! 그들 중 하나는 Node.js를 사용하여 FFmpeg를 호출합니다! 광기. 원크 리즘으로 멈추고 StackOverflow를 다시 유용하게 만드십시오. 이 사이트는 당신과 같은 윙크 덕분에 이전의 자아의 그림자입니다. 게다가,이 질문은 "XY 문제"의 예입니다.
— blujay

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는 스트림 복사를 사용하여 두 파일을 결합하고 다시 인코딩하지 않기를 원했기 때문에 질문 한 내용을 해결하지 못했습니다.
— Ed999

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

1
이로써 두 입력이 서로 동시에 재생되는 새로운 무음 비디오가 만들어졌습니다. 연결이 input_1.mp4가 재생 된 다음 input_2.mp4가 재생되는 비디오를 생성 할 것으로 예상했습니다.
— Alexx Roche

3
이것은 완전히 틀린 대답이었습니다. 이것은 비디오를 연결하는 것이 아니라 @AlexxRoche가 언급 한 것처럼 자동으로 나란히 재생합니다.
— Kalob Taulien

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 쉘이있는 리눅스에서 작동합니다. 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

여기서 첫 두 줄은 다음 내용을 가진 텍스트 파일 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입니다. 그 명령이 없으면 대화가 출력 파일을 생성하지 못합니다. 웹 사이트에서 최신 ffmpeg를 사용하고 있습니다.
— rahul maindargi 2014 년

0

다음은 명령 대체 및 concat 비디오 필터를 사용하여 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

NB이 명령은 파일의 이름이 지정된 순서대로 (즉, 실행시 표시되는 순서와 동일) 파일을 결합합니다 ls *.mp4. 제 경우에는 각각 트랙 번호가 있으므로 훌륭하게 작동했습니다.


0

여기에 설명 된 concat 프로토콜; https://trac.ffmpeg.org/wiki/Concatenate#protocol

중간 파일을 피하기 위해 명명 된 파이프를 사용하여 구현할 때

매우 빠르며 (읽기 : 즉시), 프레임이 떨어지지 않으며 잘 작동합니다.

명명 된 파이프 파일을 삭제하고 비디오로 H264 및 AAC인지 확인해야합니다 ffmpeg -i filename.mp4(h264 및 aac 언급 확인).


-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.