2012-07-27 6 views
0

가능한 중복 : 그것은 시간 매개 변수에 올 때
ffmpeg: videos before and after conversion aren't the same length는 FFmpeg 부정확 한 출력

최근

, 나는 매우 정확한 조작을 필요로하는 응용 프로그램에는 FFmpeg를 사용하려고했습니다 (밀리 초 해상도). 불행히도 FFmpeg의 조작 기능이 일부 부정 확한 결과를 반환한다는 사실에 놀랐습니다. ,의 난 'foo.mov'의 오디오 트랙을 추출 할 가정하자 이제

ffmpeg version 0.11.1 Copyright (c) 2000-2012 the FFmpeg developers 
    built on Jul 25 2012 19:55:05 with gcc 4.2.1 (Apple Inc. build 5664) 
    configuration: --enable-gpl --enable-shared --enable-pthreads --enable-libx264 --enable-libmp3lame 
    libavutil  51. 54.100/51. 54.100 
    libavcodec  54. 23.100/54. 23.100 
    libavformat 54. 6.100/54. 6.100 
    libavdevice 54. 0.100/54. 0.100 
    libavfilter  2. 77.100/2. 77.100 
    libswscale  2. 1.100/2. 1.100 
    libswresample 0. 15.100/0. 15.100 
    libpostproc 52. 0.100/52. 0.100 

: 여기

이 '는 FFmpeg'의 출력입니다. : 00 : 40.38

당신은 아마 눈치
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'foo.mov': 
    Metadata: 
    major_brand  : qt 
    minor_version : 0 
    compatible_brands: qt 
    creation_time : 2012-07-24 23:16:08 
    Duration: 00:00:40.38, start: 0.000000, bitrate: 805 kb/s 
    Stream #0:0(und): Video: h264 (Baseline) (avc1/0x31637661), yuv420p, 480x360, 733 kb/s, 24.46 fps, 29.97 tbr, 600 tbn, 1200 tbc 
    Metadata: 
     rotate   : 90 
     creation_time : 2012-07-24 23:16:08 
     handler_name : Core Media Data Handler 
    Stream #0:1(und): Audio: aac (mp4a/0x6134706D), 44100 Hz, mono, s16, 63 kb/s 
    Metadata: 
     creation_time : 2012-07-24 23:16:08 
     handler_name : Core Media Data Handler 

, 비디오 파일의 지속 시간이 00 : 여기에 '는 FFmpeg -i foo.mov'관련 출력됩니다.

가 출력

'는 FFmpeg -i foo.mov의 foo.wav' : 당신이 볼 수 있듯이

Output #0, wav, to 'foo.wav': 
    Metadata: 
    major_brand  : qt 
    minor_version : 0 
    compatible_brands: qt 
    creation_time : 2012-07-24 23:16:08 
    encoder   : Lavf54.6.100 
    Stream #0:0(und): Audio: pcm_s16le ([1][0][0][0]/0x0001), 44100 Hz, mono, s16, 705 kb/s 
    Metadata: 
     creation_time : 2012-07-24 23:16:08 
     handler_name : Core Media Data Handler 
Stream mapping: 
    Stream #0:1 -> #0:0 (aac -> pcm_s16le) 
Press [q] to stop, [?] for help 
size=3482kB time=00:00:40.42 bitrate= 705.6kbits/s  
video:0kB audio:3482kB global headers:0kB muxing overhead 0.001290% 

는, 출력 파일이 이상하다 다음 명령을 사용하여, 나는 그것이 오디오 트랙의 리핑 입력 파일.

또 다른 예는 오디오 (및 비디오) 파일 트리밍입니다. 오디오 파일 트리밍에 ffmpeg를 사용한다고 가정합시다. 나는 다음 명령을 사용 :

'는 FFmpeg은 -t 00 : 00 : 10.000 -i foo.wav의 trimmed_foo.wav -ss 00 : 00 : 25.000'

출력 :

[wav @ 0x10180e800] max_analyze_duration 5000000 reached at 5015510 
Guessed Channel Layout for Input Stream #0.0 : mono 
Input #0, wav, from 'foo.wav': 
    Duration: 00:00:40.42, bitrate: 705 kb/s 
    Stream #0:0: Audio: pcm_s16le ([1][0][0][0]/0x0001), 44100 Hz, mono, s16, 705 kb/s 
Output #0, wav, to 'trimmed_foo.wav': 
    Metadata: 
    encoder   : Lavf54.6.100 
    Stream #0:0: Audio: pcm_s16le ([1][0][0][0]/0x0001), 44100 Hz, mono, s16, 705 kb/s 
Stream mapping: 
    Stream #0:0 -> #0:0 (pcm_s16le -> pcm_s16le) 
    Press [q] to stop, [?] for help 
size=864kB time=00:00:10.03 bitrate= 705.6kbits/s  
video:0kB audio:864kB global headers:0kB muxing overhead 0.005199% 

다시, 출력 파일은 예상보다 30 밀리 초 더 길다.

오랫동안 아무런 문제없이 연구를 시도했습니다. 동일한 기능에 대해 대담성을 사용하면 매우 정확하게 수행됩니다.

누구든지이 문제를 해결하는 방법을 알고 있습니까?

답변

10

TL; DR : FFmpeg 및 iOS 기기가 사용자의 필요에 맞는 잘못된 도구입니다.

, 충당하기 위해 문제의 호스트가 있습니다 특별한 순서없이 너무 :

  • 무엇보다도도는 FFmpeg 또는 시간 해상도의 정렬을 위해 설계 작업중인 기본 코덱 네가 원해. 40ms는 25fps에서 1 프레임이며 대부분의 비디오 및 오디오 파일과 관련이 없습니다. 부정확 한 타이밍은 소스 AAC 데이터와 같은 일반적인 오디오 코덱의 설계 기능이 아니며 FFmpeg가 적합합니다.

  • 트랜스 코딩을하지 마십시오! 가능한 한 데이터를 변경하지 않으려면 변경하지 마십시오. ffmpeg -i in.mov -c:a copy out.m4a을 사용하여 오디오 스트림을 wav 형식으로 변환하는 대신 정확하게 추출 할 수 있습니다.

  • FFmpeg 대신 FFprobe를 사용하여 파일 정보를 가져옵니다. FFmpeg는 기본 로깅이 지나치게 길기 때문에 입력 및 출력 파일에 대한 간단한 정보를 제공합니다. FFprobe는 일반적으로 FFmpeg와 번들로 제공되며 정보를 편리한 형태로 추출하도록 특별히 설계되었습니다. 정보를 얻으려면 ffprobe -show_streams -show_format in.mov을 사용하십시오.

  • -analyzeduration을 늘리십시오! 출력에 max_analyze_duration reached에 대한 메모를 보셨을 것입니다. 에서 얼마나 많은가 마이크로 초일은 실제로 FFmpeg 전에 파일을 읽을 것입니다. 총 길이입니다. 다시 말하지만 대부분의 경우 파일의 길이를 마이크로 초 단위로 알면 실현 불가능하거나 바람직하지 않으며 입니다. 정확도를 높이려면 해당 매개 변수가 실제 입력보다 훨씬 높게 설정되어 있는지 확인하십시오.

  • 옵션 배치에 조금 더주의하십시오. 이것은 아주 사소한 일이지만, 당신이 알지 못하는 경우를 대비해서 내가 가져야한다고 생각했습니다. 많은 FFmpeg의 옵션은 입력과 출력에 대해 주어진 순서에 따라 다르게 동작합니다. 주목할만한 것은 -ss입니다. 당신은 그것을 원하는 곳에있는 입력 이후에 가지고 있지만 시작 부분에 출력 전용 옵션 -t이 있습니다 ... 이상합니다. 그 명령을 주문하는 자연적인 방법은 다음과 같습니다

    ffmpeg -i foo.wav -ss 00:00:25.000 -t 00:00:10.000 trimmed_foo.wav 
    
  • 그냥 참고로, 모든 타이밍 명령 (소수 초 포함) 초 단위로 입력을받을, 그래서 당신은 00:00:으로 모든 것을 앞에 추가 할 필요가 없습니다.

  • 컨테이너 길이와 실제 스트림 길이를 구별합니다. 나는 Audacity를 사용하지 않지만 그것이하고있는 일에 대해 당신에게 거짓말을하고 있기 때문에 극도의 정확성을 보여 준다면 놀라지 않을 것입니다. 실제로 밀리 초 단위의 정확도로 오디오 또는 비디오 데이터를 트리밍하려면 입력에서 어떤 프레임이 출력에 포함되는지 (25ms에서 40ms로 정확합니다!) 최종 프레임에 무음을 삽입하도록 프레임 데이터를 변경해야합니다. 프레임 포함을 기반으로 트리밍 한 다음 컨테이너 파일 메타 데이터에 매우 정확한 길이를 넣는 것이 훨씬 쉬울 것입니다. 일부 재생 소프트웨어는 실제로 그 숫자에 따라 차단 될 수 있지만, 대부분의 AV 소프트웨어는 그 수준의 정확성을 위해 설계되지 않았습니다. 나는 FFmpeg가 Audacity에 의해 정돈 된 파일의 길이로 무엇을 보여 주는지 궁금 할 것이다.

이제 마음이 샘솟 았지만 위의 일부를 통합 할 수있게되면 더 많은 의견을 보내 게되어 기쁩니다. 내 생각 엔 이런 종류의 정확성이 연구 조사에 필요하다는 것입니다. 그럴 경우 행복하게 조사하십시오!

+0

덕분에 많은 도움을 받았습니다. – Shlomi

+0

명령 문제에 대한 요점이 내 문제를 해결했습니다.이 문제는 거칠 었습니다 (분 단위가 아닌 초 단위). – klausnrooster