명령 줄에서 비디오 파일을 정확하게 잘라 내기


22

비디오 파일 (avi, mkv 및 mp4가 바람직)을 가져 와서 정확한 시간 정확도로 매우 짧은 클립 (2-6 초)을자를 수있는 cli 응용 프로그램을 찾는 데 문제가 있습니다. 나는 해봤 는 FFmpeg , mencoder , avidemuxmp4box 하지만 6+ 두 번째 클립을 생성 키 프레임에 그들은 모두 상처를. 입력 파일을 다시 인코딩하고 정확한 시간을 줄이거 나 부정확하게 잘라 내고 다시 인코딩 한 다음 정확하게 잘라내는 도구가 있습니까?


제대로 자르기 전에 재 인코딩해야 할 수도 있습니다. 주변 키 프레임을 먼저 잘라 내고 스 니펫 만 다시 코딩하여 작업 속도를 높일 수 있습니다.
Nifle

4
정확히 어떤 FFmpeg 명령을 사용해 보셨습니까? 나는 비디오를 이전에 디코딩하면 (즉 , 뒤에-ss 매개 변수를 배치하면 )보다 정확해야한다고 생각합니다. -i
slhck

1
FFmpeg 트릭이 작동했습니다! 나는 명령이 그렇게 중요하다는 것을 몰랐다. 다른 도구와 동일합니까?
curmil

답변:


23

로 비디오 자르기 ffmpeg

FFmpeg로 비디오를 정확하게자를 수 있습니다 . 버전 2.5부터는 매우 쉽습니다. 예를 들어 0 분, 3 초 및 123 밀리 초에서 시작하여 10 초가 줄어 듭니다.

ffmpeg -ss 00:00:03.123 -i input.mp4 -t 10 -c:v libx264 -c:a copy out.mp4

위치와 시간은 초 또는 hh:mm:ss[.xxx]형식 일 수 있습니다.

이 예에서 비디오는 x264 인코더를 사용하여 다시 인코딩됩니다 . 오디오가 복사됩니다.

지속 시간 대신 끝점을 지정하는 -to대신 대신 사용할 수도 있습니다 -t. 그러나 ffmpeg 를 앞에 두면 ffmpeg가 먼저 해당 지점을 찾은 다음 출력을 시작하기 때문에이 경우 -to와 같습니다 .-t-ss-i

찾기 위키 항목 도 참조하십시오 .


이전 ffmpeg버전의 정확한 절단

이전 버전의 ffmpeg가있는 경우 정확한 검색을 위해서는 -ssafter 를 배치해야합니다. -i그러면 전체 비디오를 먼저 디코딩해야하기 때문에 인코딩 프로세스가 약간 느려집니다.

ffmpeg -i input.mp4 -ss 00:00:03.123 -t 10 -c:v libx264 -c:a copy out.mp4

여기 -to-t다르게 동작합니다. -t 1010 초 길이의 클립 -to 10을 만드는 반면 7 초 길이의 클립을 만듭니다.


대신 -c:v libx264 -c:a libfaac우리 -acodec copy -vcodec copy는 ffmpeg에게 원본 파일과 동일한 코덱을 감지하고 사용하도록 지시하는 것을 사용할 수 있다고 생각 합니다. 누구든지 확인할 수 있습니까?
Baodad

2
@Baodad 당신은 할 수 있지만 이것은 정확하게 자르지 않을 것 입니다. 비디오 / 오디오 비트 스트림을 복사 할 때 ffmpeg는 키 프레임에서 시작해야합니다. 키 프레임은 매 초마다 또는 더 멀리 떨어져있을 수 있습니다.
slhck

"알 수없는 인코더 'libfaac'"오류를 어떻게 극복합니까?
Doug

@Doug 다른 인코더를 선택하십시오 (예 :) -c:a aac -strict experimental. 이것이 가장 간단한 해결책입니다.
slhck

1

지금까지 내가 찾은 유일한 Linux 명령 줄 도구는 정확한 프레임에서 (또는 프레임 정확도로)자를 수있는 도구는 melt( sudo apt-get install melt)입니다.

say inputvid.mp4로 인코딩 설정을 먼저 확인 ffmpeg하십시오. (여기서 다시 인코딩하고 싶다고 말하지만 -f mp4파일로 /dev/null출력을 버립니다. 나는 stderr을 리디렉션하여 grep 할 수 있습니다. , 명령 프롬프트가 표시 y되고 ENTER로 응답해야 하므로 프로세스가 진행되고 유용한 정보를 덤프합니다. 이것은 Ubuntu 14의 ffmpeg 3.3.3입니다).

ffmpeg -i inputvid.mp4 -f mp4 /dev/null 2>&1 | grep 'Stream\|encoder'
    Stream #0:0(und): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p(tv, bt709), 640x360 [SAR 1:1 DAR 16:9], 389 kb/s, 23.98 fps, 23.98 tbr, 24k tbn, 47.95 tbc (default)
    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 95 kb/s (default)
y
File '/dev/null' already exists. Overwrite ? [y/N] Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
  Stream #0:1 -> #0:1 (aac (native) -> aac (native))
    encoder         : Lavf57.71.100
    Stream #0:0(und): Video: h264 (libx264) ([33][0][0][0] / 0x0021), yuv420p(progressive), 640x360 [SAR 1:1 DAR 16:9], q=-1--1, 23.98 fps, 24k tbn, 23.98 tbc (default)
      encoder         : Lavc57.89.100 libx264
    Stream #0:1(und): Audio: aac (LC) ([64][0][0][0] / 0x0040), 44100 Hz, stereo, fltp, 128 kb/s (default)
      encoder         : Lavc57.89.100 aac

자, 이 비디오의 ffmpeg선택 libx264aac인코더를 볼 수 있습니다 . 다음에 이것을 입력 할 수 있습니다 melt:

melt inputvid.mp4 in=7235 out=7349 -consumer avformat:cut.mp4 acodec=aac vcodec=libx264

.... melt프레임 7235와 7349 사이의 조각으로 새 파일로 자릅니다 cut.mp4. 그런 다음 cut.mp4루프가 올바르게 있는지 확인 하려면 melt다시 사용하여 루프를 두 번 재생하고 SDL 창으로 재생하십시오.

melt cut.mp4 cut.mp4 -consumer sdl

... ffmpeg그리고이 파일에 대한 내용은 다음과 같습니다 .

ffmpeg -i cut.mp4 -f mp4 /dev/null 2>&1 | grep 'Stream\|encoder'    encoder         : Lavf54.20.4
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 640x360 [SAR 1:1 DAR 16:9], 526 kb/s, 23.98 fps, 23.98 tbr, 24k tbn, 47.95 tbc (default)
    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 182 kb/s (default)
y
File '/dev/null' already exists. Overwrite ? [y/N] Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
  Stream #0:1 -> #0:1 (aac (native) -> aac (native))
    encoder         : Lavf57.71.100
    Stream #0:0(und): Video: h264 (libx264) ([33][0][0][0] / 0x0021), yuv420p, 640x360 [SAR 1:1 DAR 16:9], q=-1--1, 23.98 fps, 24k tbn, 23.98 tbc (default)
      encoder         : Lavc57.89.100 libx264
    Stream #0:1(und): Audio: aac (LC) ([64][0][0][0] / 0x0040), 48000 Hz, stereo, fltp, 128 kb/s (default)
      encoder         : Lavc57.89.100 aac

설정을 코딩하는 동영상이 cut.mp4동일 할 것 inputvid.mp4비디오 비트 레이트가 389로 변경 제외시켰다 KB / s로 5백26킬로바이트 / s, 또한 오디오 인코딩 설정은 44,100에서 48,000 Hz로 변화 샘플링 레이트를 제외하고는 거의 동일하다; 그러나 다음과 같이 규제 할 수 있습니다.

melt inputvid.mp4 in=7235 out=7349 -consumer avformat:cut.mp4 acodec=aac ar=44100 ab=95k vcodec=libx264 vb=389k

... 그러나 이것으로도 최종 비디오 비트 전송률은 337 kb / s입니다. 여전히 루프에서 재생할 때 컷이 잘 반복되고 오디오가 포함되어 있으므로 실제로 프레임이 정확하다고 생각합니다 ...


1
melt비디오를 다시 인코딩하고 있으며 아래의 FFmpeg 라이브러리를 사용합니다. 다시 인코딩을 허용하면 ffmpeg가 동일한 출력을 생성 할 수 있습니다.
Gyan

감사합니다 @ Gyan-(특히 meltFFmpeg 라이브러리 를 사용 하는) 인식하지 못했습니다 !
sdaau

melt은 ffmpeg보다 사용하기 쉬워 보입니다. 시간, 특히 hr, min, sec 형식 또는 hr, min, sec, ms로 시간을 지정하여 올바른 프레임으로 변환하는 방법 만 있으면됩니다.
barlop

0

Baodad가 의견에서 말했듯이 (빠르게 읽으면 찾기가 쉽지 않기 때문에 게시) 더 좋은 방법은 ffmpeg로 오디오 / 비디오 인코더를 자동으로 감지하는 것입니다.

ffmpeg -ss 00:05:17.18 -i in.mp4 -t 00:06:29.10 -acodec copy -vcodec copy out.mp4 
  • @ 00 : 05 : 17.18에서 시작
  • 입력 = in.mp4
  • @ 00 : 06 : 29.10 중지
  • 출력 = 출력 .mp4

2
재 인코딩되지 않으며 프레임 정확도를 제공하지 않습니다.
Andrea Lazzarotto
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.