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.