리눅스에서 mp4 파일 가입


31

하나의 파일을 만들기 위해 두 개의 mp4 파일을 결합하고 싶습니다. 비디오 스트림은 h264로 인코딩되고 오디오는 aac로 인코딩됩니다. 계산상의 이유로 비디오를 다른 형식으로 다시 인코딩 할 수 없습니다. 또한 GUI 프로그램을 사용할 수 없으며 모든 처리는 Linux 명령 행 유틸리티를 사용하여 수행해야합니다. FFmpeg는 mpeg4 파일에 대해이 작업을 수행 할 수 없으므로 대신 MP4Box를 사용했습니다.

MP4Box -add video1.mp4 -cat video2.mp4 newvideo.mp4

불행히도 오디오는 모두 섞입니다. 문제는 오디오가 aac에 있다고 생각하여 mp3로 코드를 트랜스 코딩하고 MP4Box를 다시 사용했습니다. 이 경우 전반에 newvideo.mp4()에 해당하는 오디오는 괜찮지 video1.mp4만 오디오가 아니므로 비디오를 탐색 할 수 없습니다.

나의 다음 생각은 오디오 및 비디오 스트림이 내가 고쳐야 할 길이에 약간의 불일치가 있다는 것이었다. 따라서 각 입력 비디오에 대해 비디오 및 오디오 스트림을 분할 한 다음 FFmpeg의 -shortest 옵션으로 결합했습니다.

따라서 첫 번째 비디오에서 다음을 실행했습니다.

 avconv -y -i video1.mp4 -c copy -map 0:0 videostream1.mp4
 avconv -y -i video1.mp4 -c copy -map 0:1 audiostream1.m4a
 avconv -y -i videostream1.mp4 -i audiostream1.m4a  -c copy -shortest  video1_aligned.mp4

두 번째 비디오와 마찬가지로 이전과 같이 MP4Box를 사용했습니다. 불행히도 이것은 작동하지 않았습니다. 내가 유일하게 성공한 것은 비디오 스트림 (예 : videostream1.mp4 및 videostream2.mp4)과 오디오 스트림 (예 : audiostream1.m4a 및 audiostream2.m4a)을 개별적으로 결합한 다음 비디오 및 오디오를 최종 파일로 결합했을 때였습니다. 그러나 비디오의 후반에 대한 동기화가 손실됩니다. 구체적으로, 1 초의 오디오 및 비디오 지연이 있습니다. 어떤 제안이라도 환영합니다.


"FFmpeg는 mpeg4 파일에 대해이 작업을 수행 할 수 없으므로 대신 MP4Box를 사용했습니다."MP4 파일을 의미합니까? 두 오디오-비디오 스트림 모두 동일한 인코딩 매개 변수 (너비, 높이, SPS, PPS, 프레임 속도, 샘플링 속도, 채널 수)를 사용합니까?

ffprobe를 사용하면 오디오 스트림의 속성이 동일하다는 것을 알았습니다. 비디오 스트림의 크기는 같지만 속도는 다릅니다. 첫 번째 비디오 비디오 : h264, 720x592, 277 kb / s, PAR 18944 : 12915 DAR 512 : 287, 24.97 fps, 45k tbr, 90k tbn, 90k tbc, 두 번째 비디오 : h264, 720x592, 226 kb / s, PAR 481 : 330 DAR 39:22, 24.91 fps, 45k tbr, 90k tbn, 90k tbc. 이것이 내 문제의 원인이라고 생각하십니까?

MP4는 다른 비디오에 대해 다른 트랙을 사용하여 다른 특성을 가진 비디오 / 오디오 참여를 지원하지만 플레이어는 그렇게 똑똑하지 않습니다.
rajneesh


귀하의 질문은 ffmpeg FAQ에서 이미 답변되었습니다 : ffmpeg.org/faq.html#How-can-I-join-video-files_003f
Palec

답변:


31

이 작업을 수행하는 가장 좋은 방법은 concat demuxer를 사용하는 것 입니다. 먼저 inputs.txt다음과 같은 형식 의 파일을 작성하십시오 .

file '/path/to/input1.mp4'
file '/path/to/input2.mp4'
file '/path/to/input3.mp4'

그런 다음이 ffmpeg 명령을 실행하십시오.

ffmpeg -f concat -i inputs.txt -c copy output.mp4

FAQ의 연결을ffmpeg 참조하십시오 .


이전 버전의 ffmpeg를 사용하는 사람의 이익을 위해 다음을 유지합니다.

ffmpeg의 최신 버전이이를 수행 할 수 있습니다. 먼저 파일을 mpeg 전송 스트림으로 리 먹싱해야합니다 (컨테이너 형식 만 변경하므로 프로세서가 약간 가벼움).

ffmpeg -i input.mp4 -map 0 -c copy -f mpegts -bsf h264_mp4toannexb middle.ts

h264에 대한 오류가 발생하면 다음을 사용해야합니다.

ffmpeg -i input.mp4 -map 0 -c copy -f mpegts -bsf h264_mp4toannexb middle.ts

각 입력 파일과 별도로이 작업을 수행해야합니다. 파일을 함께 연결하려면 다음을 사용하십시오.

ffmpeg -i "concat:middle1.ts|middle2.ts|middle3.ts" -c copy output.mp4

aac에 대한 오류가 발생하면 사용해야 할 수도 있습니다.

ffmpeg -i "concat:middle1.ts|middle2.ts|middle3.ts" -c copy -absf aac_adtstoasc output.mp4

시스템이 명명 된 파이프를 지원하는 경우 중간 파일을 만들지 않고도이 작업을 수행 할 수 있습니다.

mkfifo temp0 temp1

세 개의 별도 가상 터미널에서 다음을 수행해야합니다.

ffmpeg -i input0.mp4 -map 0 -c copy -f mpegts -bsf h264_mp4toannexb -y temp0
ffmpeg -i input1.mp4 -map 0 -c copy -f mpegts -bsf h264_mp4toannexb -y temp1
ffmpeg -f mpegts -i "concat:temp0|temp1" -c copy -absf aac_adtstoasc output.mp4

output.mp4가 이미 존재하는 경우 세 번째 ffmpeg는 덮어 쓸지 묻지 만 FIFO에 액세스 한 후에이를 수행 하며 첫 번째 ffmpeg를 닫습니다. 따라서 출력 파일에 사용되지 않는 이름을 선택하십시오.

입력 파일이 다른 경우에는 작동하지 않을 수 있습니다. 비트 전송률의 차이는 정상이지만 프레임 크기, 프레임 속도 등은 일치해야합니다.


많은 thx 메이트, 매력처럼 일했다
Jose Armando

2
@DaveJarvis 그렇지 않다; 이것은 libav 팀에 의해 고의적으로 악의적으로 퍼진 메시지입니다.이 팀은 ffmpeg 프로젝트와 분리되어 avconv를 개발하고 (ffmpeg 이름에 대한 저작권을 확보 할 수 없어 이름을 변경 한) 많은 개발자입니다. 참조 누가 내게는 FFmpeg, libav 및 avconv의 차이와 관계를 알 수 있습니까? 좀 더 자세한 정보가 필요합니다.
evilsoup

2
*** THIS PROGRAM IS DEPRECATED *** This program is only provided for compatibility and will be removed in a future release. Please use avconv instead.달리기에 지금 볼 수있는 메시지입니다ffmpeg
로드 님.

@LordLoh. 이전 의견의 링크를 참조하십시오.
evilsoup

1
그 대답은 대답하지 않습니다-mp4와 어떻게 연결 하는가avconv
Lord Loh.

7

mp4의 경우 내가 찾은 유일한 해결책은 gpac 패키지의 MP4Box입니다.

#!/bin/bash
filesList=""
for file in $(ls *.mp4|sort -n);do
    filesList="$filesList -cat $file"
done
MP4Box $filesList -new merged_files_$(date +%Y%m%d_%H%M%S).mp4

또는 명령은

MP4Box -cat file1.mp4 -cat file2.mp4 -new mergedFile.mp4

mencoder와 avconv로 나는 그것을 작동시킬 수 없었다 :-(


2

스크립트 dvo에 감사드립니다. 저에게는 훌륭한 출발점이되었습니다. 명명 된 파이프를 사용하는 데 아무런 문제가 없었으므로 대신 스크립트를 사용하도록 스크립트를 조정했습니다. 또한 공백이있는 파일 이름으로 작동하도록 수정했습니다. 명명 된 파이프에 대한 출력은 사용자가 읽을 때까지 "이동"하지 않으므로 avconv를 마지막으로 호출하기 전에 &로 초기 remux 태스크를 백그라운드로 지정해야합니다. 또한 -c copy를 사용하거나 전체 로트를 다시 인코딩해야합니다.

#!/bin/bash
for FILE in "$@"; do
   TAG=$(echo "$FILE" | sed -e s/[^A-Za-z0-9.]/_/g)
   mkfifo $TAG.mp4concatpipe
   avconv -loglevel "quiet" -i "$FILE"  -f mpegts -c copy -bsf h264_mp4toannexb -y $TAG.mp4concatpipe &
   IN=$IN\|$TAG.fifo
done

IN=${IN#\|}
avconv -i concat:$IN -c copy out.mp4
rm *.mp4concatpipe

어떤 이유로 이것은 "concat : first.m4v.fifo | second.m4v.fifo : 해당 파일이나 디렉토리가 없습니다"라는 오류가 발생합니다. 따옴표 (-i concat : "$ IN"또는 -i "concat : $ IN "). 아래의 다른 답변에서 제안 된 MP4Box는 훌륭하게 작동합니다!
vorburger

2

Mac (macOS 10.13 High Sierra)에서는 다음을 성공적으로 사용했습니다.

for f in *.m4a; do echo "file '$f'" >> mylist.txt; done

필요한 경우 위와 같이 위와 같이 순서를 변경하십시오 (./가 제거됨-경로로 인해 ffmpeg가 안전하지 않은 파일 이름 오류를 발생 시켰습니다).

그런 다음 기본 MacPorts ffmpeg에 지정된 코덱과 비트 전송률을 제거해야했습니다.

ffmpeg -f concat -i mylist.txt  output.m4a

수퍼 유저에 오신 것을 환영합니다! 질문을주의 깊게 다시 읽으십시오. 당신의 대답은 리눅스에 관한 원래의 질문에 대답하지 않습니다. 리눅스에서 작동한다고 생각한다면 앞으로 독자가 수퍼 유저를 환영하고 의견을 보내 주셔서 감사합니다. 몇 분 동안 읽고 superuser.com/help를 읽어보십시오. 답변 : superuser.com/help/how-to-answer .
mic84

2

여기에 훨씬 더 쉬운 하나의 라이너가 있습니다. 하나의 결과 비디오 파일을 제공하기 위해 수행해야 할 모든 작업을 수행합니다. 건배!

find *.mp4 | sed 's:\ :\\\ :g'| sed 's/^/file /' > list.txt; ffmpeg -f concat -i list.txt -c copy output.mp4; rm list.txts

1

고마워 evilsoup; 여기에 최신을 사용하여 프로세스를 자동화하는 작은 스크립트가 avconv있습니다.
BTW, 명명 된 파이프가 나를 위해 작동하지 않았습니다 (출력이 막혔습니다).

   #!/bin/bash

    for FILE in $@; do
      avconv -i $FILE -map 0 -f mpegts -bsf h264_mp4toannexb -c:v copy -y $FILE.tmp
      IN=$IN\|$FILE.tmp
    done

    IN=${IN#\|}
    avconv -i concat:"$IN" out.mp4

    for FILE in $@; do
      rm $FILE.tmp
    done

0

와 함께 큰 성공을 즐겼다

for f in ./*.m4a; do echo "file '$f'" >> mylist.txt; done

mylist.txt를 약간 재정렬해야 할 수도 있습니다.

ffmpeg -f concat -i mylist.txt -c:a libfdk_aac -b:a 128k output.m4a

ffmpeg 버전 2.2.3

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.