Jak przekonwertować plik .MTS (AVCHD) do .mp4 przez ffmpeg bez ponownego kodowania strumienia wideo H264?

20

Uwaga: zadałem to samo pytanie do stackoverflow krótko przedtem, kiedy jeszcze nie znalazłem tej społeczności. Przekazuję to ponownie, ponieważ pytanie jest bardziej odpowiednie dla tej społeczności.

1. Co próbowałem

Mam niektóre pliki .MTS (format AVCHD) zapisane w mojej kamerze AVCHD . Jego specyfikacja jest pokazana poniżej:

$ ffprobe 140612_Canon-00000.MTS 
ffprobe version 2.2.1 Copyright (c) 2007-2014 the FFmpeg developers
(snip)
Input #0, mpegts, from '140612_Canon-00000.MTS':
  Duration: 00:48:58.40, start: 0.800300, bitrate: 5563 kb/s
  Program 1 
    Stream #0:0[0x1011]: Video: h264 (High) (HDMV / 0x564D4448), 
      yuv420p, 1440x1080 [SAR 4:3 DAR 16:9], 
      29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc
    Stream #0:1[0x1100]: Audio: ac3 (AC-3 / 0x332D4341), 48000 Hz, 
      stereo, fltp, 256 kb/s

Zwróć uwagę na część framerate / timebase: 29,97 fps, 29,97 tbr, 90k tbn, 59,94 tbc

Teraz chciałbym przekonwertować ten plik na plik .mp4, bez przekodowywania strumienia wideo H264 , z drugiej strony, z transkodowaniem jego strumienia audio do AAC . Więc spróbowałem następującego polecenia:

ffmpeg -i 140612_Canon-00000.MTS -t 60 -y -vcodec copy -acodec libfaac -ab 128k 140612_Canon-00001.MTS.mp4

2. Wynik

a specyfikacja pliku wyjściowego jest następująca:

$ ffprobe 140612_Canon-00000.MTS.mp4
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '140612_Canon-00000.MTS.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf55.33.100

  Duration: 00:01:00.04, start: 0.021333, bitrate: 4590 kb/s

    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 
        1440x1080 [SAR 4:3 DAR 16:9], 4448 kb/s, 
        59.94 fps, 59.94 tbr, 90k tbn, 59.94 tbc (default)
    Metadata:
      handler_name    : VideoHandler

    Stream #0:1(und): Audio: aac (mp4a / 0x6134706D), 
        48000 Hz, stereo, fltp, 128 kb/s (default)
    Metadata:
      handler_name    : SoundHandler

Spójrz na część framerate / timebase: 59,94 fps, 59,94 tbr, 90k tbn, 59,94 tbc . Chociaż ffmpeg właśnie skopiował strumień wideo, liczba klatek na sekundę i podstawa czasu zostały zmienione na dwukrotną wartość .

Kiedy więc otwieram i odtwarzam plik wyjściowy za pomocą QuickTime Player lub VLC Player, dźwięk nie ma problemu, jednak strumień wideo nie jest odtwarzany poprawnie. Wideo jest odtwarzane z kilkukrotnym drżeniem do przodu i do tyłu.

3. Pytanie

  1. Jak mogę przekonwertować plik .MTS (AVCHD) do .mp4 przez ffmpeg bez ponownego kodowania strumienia wideo H264 ?
  2. Jak mogę zachować oryginalne wartości klatek / podstawy czasu (fps / tbr / tbn / tbc), kiedy przekonwertuję kontener za pomocą ffmpegi jego -vcodec copyprzełącznika.
  3. Jak ustawić wartości framerate / timebase (fps / tbr / tbn / tbc) za pomocą opcji wiersza poleceń ffmpeg bez ponownego kodowania strumienia wideo.

Jakieś pomysły?


4. Dodanie -r 29.97opcji

Profesor Sparkles dał mi radę do dodania -r 29.97. Próbowałem:

ffmpeg -i 140612_Canon-00001.MTS -t 60 -r 29.97 -y -vcodec copy -acodec libfaac -ab 128k 140612_Canon-00001.MTS.mp4

Jednak plik wyjściowy nadal ma nieprawidłową liczbę klatek na sekundę / podstawę czasu:

Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 
1440x1080 [SAR 4:3 DAR 16:9], 4448 kb/s, 
59.94 fps, 59.94 tbr, 11988 tbn, 59.94 tbc (default)

5. Remux za pomocą MP4Box

Próbowałem demux i remux przy użyciu MP4Box, zgodnie z radą profesora Sparklesa.

brew install mp4box

ffmpeg -i 140612_Canon-00000.MTS -t 60 -y \
  -vcodec copy -an 140612_Canon-00000.MTS.h264

ffmpeg -i 140612_Canon-00000.MTS -t 60 -y \
  -vn -acodec libfaac -ab 128k 140612_Canon-00000.MTS.aac

mp4box -add 140612_Canon-00000.MTS.h264:fps=29.97 \
  -add 140612_Canon-00000.MTS.aac \
  -new 140612_Canon-00000.MTS.mp4

i wynik był:

$ ffprobe 140612_Canon-00000.MTS.mp4

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '140612_Canon-00000.MTS.mp4':
(snip)
  Duration: 00:02:00.22, start: 0.000000, bitrate: 2293 kb/s
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), 
          yuv420p, 1440x1080 [SAR 4:3 DAR 16:9], 2228 kb/s, 
          29.97 fps, 29.97 tbr, 30k tbn, 59.94 tbc (default)
    Metadata:
      creation_time   : 2014-07-14 00:38:23
      handler_name    : 140612_Canon-00000.MTS.h264:fps=29.97
       - Imported with GPAC 0.5.0-rev4065

    Stream #0:1(und): Audio: aac (mp4a / 0x6134706D), 48000 Hz, 
          stereo, fltp, 125 kb/s (default)

To wygląda na krok do przodu. Spójrz na część framerate / timebase: 29,97 fps, 29,97 tbr, 30k tbn, 59,94 tbc . Są one zgodne z oryginalnym strumieniem, z wyjątkiemtbn (wartości podstawy czasu z kontenera).

Jednak gdy odtwarzam plik wyjściowy za pomocą Quicktime Player lub VLC, wideo jest odtwarzane z połową prędkości .

Chociaż oryginalny plik ma 90k tbn(90000 tyknięć na sekundę), a nowy plik wyjściowy z MP4Box ma 30k tbnzaledwie jedną trzecią wartości oryginalnego pliku, plik wyjściowy jest odtwarzany z połową prędkości.

Nie wiem dlaczego. Ale myślę, że resztą jest sposób, w jaki mogę dostosować tbnwartość.


5-b. Raport MediaInfo na temat pliku wyjściowego

Próbowałem także narzędzia MediaInfo na pliku wyjściowym wygenerowanym przez 5. Remux przy użyciu MP4Box . Dane wyjściowe są tutaj: https://gist.github.com/kaorukobo/c5ab9eaa413dff6cd26a


6. Próbowanie avconv

Zgłoszona Wołodia avconvdziałała dobrze. Przygotowałem także krótki przykładowy plik filmowy (Canon-00006.MTS) nagrany tym samym aparatem. OK, spróbujmy:

brew install avconv
avconv -i Canon-00006.MTS -c:a copy -c:v copy -y Canon-00006.MTS.mp4
ffprobe Canon-00006.MTS.mp4

Informacje o pliku ffprobe pliku wyjściowego znajdują się tutaj: https://gist.github.com/kaorukobo/5b53244ade2632ff1211, a jego informacje o liczbie klatek na sekundę / podstawie czasu są następujące: 59,94 fps, 59,94 tbr, 90k tbn, 59,94 tbc

Plik wyjściowy był dobrze odtwarzany w VLC Player, jak donosi Volodya. Jednak otwierając go za pomocą Quicktime Player X, wideo było odtwarzane z normalną prędkością, ale z kilkakrotnie drżącą klatką do tyłu.


7. Dlaczego działa aplikacja „Free AVCHD to MOV”?

Jak wspomniałem w poprzednim komentarzu , funkcja „przewiń do MOV” w aplikacji AVCHD do MOV działała dobrze, mimo że nie tworzy MP4, tylko MOV.

Oprogramowanie wywołuje wewnętrznie własny program ffmpeg (lub avconv) i widziałem, jakie opcje są do niego przekazywane. Jest jak pokazano poniżej:

/Applications/Free AVCHD to Mov.app/Contents/Resources/bin/com.geranium-soft.convert \
  -i /path/to/140710_Canon-00003.MTS \
  -map 0:0 -map 0:1 -c:a libfaac -vol 256 -b:a 128k -c:v copy \
  -sn -movflags faststart -threads 0 -pix_fmt yuv420p -y \
  /path/to/140710_Canon-00003.mov

Próbowałem przekazać te same opcje (Ekstrakcyjnie takie same. Ustawiłem typ pojemnika wyjściowego na MOV i usunąłem nawet -t 60przełącznik.) Do programu ffmpeg i dokonałem konwersji. Ale wynik był taki sam jak dotychczas .

W każdym razie ta świetna aplikacja rozwiązała mój problem z „Jak przekonwertować plik .MTS (AVCHD) na .mp4 bez ponownego kodowania strumienia wideo H264?”, Z wyjątkiem „do .mp4” i „przez ffmpeg”. Ale nadal interesuje mnie, dlaczego ta aplikacja ma się dobrze, ale ffmpeg nie.

kaorukobo
źródło
Co rozumiesz przez „poprawnie”? Może usuń to z tytułu. Chciałbym pomóc, ale nigdy nie korzystałem z ffmpeg. Po prostu używam enkodera medialnego Adobe Tools.
eLouai
@eLouai W porządku, poprawiłem tytuł.
kaorukobo

Odpowiedzi:

8

Widząc, że w tekście pytania zacząłeś omawiać inne narzędzia, założę się, że nie jesteś zainteresowany trzymaniem się ffmpeg, ale raczej wykonaniem zadania.

Z mojego doświadczenia z libav i MTS nie miałem problemów z szybkością klatek, pliki zostały idealnie przemienione.

Właśnie próbowałem wykonać następujące czynności z jednym z moich plików:

avconv -i 00174.MTS -c:a copy -c:v copy 00174.mp4

Wynikowy plik MP4 odtwarzany poprawnie z VLC.

Mój plik to progresywny MTS, nie mam żadnych przeplotów, ale w razie potrzeby mogę więcej sprawdzić.

Zgłoś test pliku

Starter tematu był w stanie dostarczyć plik, który został przemieniony z MTS do MP4 i nie był odtwarzany na komputerze tej osoby za pomocą QuickTime Player (wersja nieznana). Grał jednak z odtwarzaczem VLC tej osoby.

Nie mam komputera z systemem Mac OS, ale wypróbowałem go z Ubuntu. Grałem w Ubuntu na VLC (2.0.8) i GNOME Video (wcześniej nazywał się Totem) (3.8.2); oba grają idealnie.

Następnie poprosiłem mojego przyjaciela, który jest na komputerze Mac, aby w nią zagrał. Jest na Mavericks (10.9.4) i grał dobrze z QuickTime Player 10.3 (727,4).

W tej chwili wydaje się, że jest to problem z konkretnym odtwarzaczem lub problem z ustawieniami konfiguracji na komputerze. Prawdopodobnie najlepiej jest spróbować zaktualizować do najnowszej wersji QTP, prawdopodobnie najpierw usuwając bieżącą wersję i całkowicie usuwając starą konfigurację.

Inna możliwość

Kiedy miałem stary komputer, niektóre pliki o wysokiej przepływności były odtwarzane niepoprawnie w niektórych odtwarzaczach i było to specyficzne dla kontenera. Na przykład VLC odmówiłoby odtworzenia pliku MTS, pokazało ramkę, a następnie pokazało następny tylko za półtorej sekundy. Filmy w GNOME grały dobrze. Ale gdy przełożyliśmy go na MKV, obaj gracze grali w niego całkiem dobrze. To może być pytanie o coś podobnego. Gracz może czytać określony kontener (w tym przypadku MP4) w sposób, który wymaga tylko tyle czasu procesora, aby sam zaczął się dusić. Efekt szarpnięcia można następnie przypisać dowolnemu podprocesowi, który zajmuje zakończenie procesora, a gracz zrzuca wszystkie klatki, które są bardzo opóźnione, po czym ponownie rozpoczyna się zły podproces i cykl trwa.

W tej możliwości najlepszą opcją jest nadal próba aktualizacji oprogramowania. Przy obecnych procesorach wielordzeniowych trudno byłoby przetestować potrzebę aktualizacji sprzętu bez jego uzyskania, ale być może możliwe jest sprawdzenie obciążenia procesora podczas korzystania z QuickTime Player i porównanie go z VLC. Jeśli widzisz 100% dla jednego rdzenia z QTP, może to wskazywać na to.

v010dya
źródło
Jest mało prawdopodobne, aby avconv wykonał dla niego inną pracę. avconv jest rozwidleniem ffmpeg, a ffmpeg łączy wiele zatwierdzeń z projektu avconv w ffmpeg, główne poprawki takich błędów prawdopodobnie byłyby obecne w ffmpeg.
PTS
@ProfessorSparkles Myślę, że fakt, że tutaj działał, jest wystarczającą podstawą, by sądzić inaczej. Zaczekam, aby zobaczyć, co mówi kaorukobo.
v010dya
@Volodya Dzięki za informacje. Dodałem raport z próbą avconv do mojego pytania.
kaorukobo
@kaorukobo Co dokładnie masz na myśli mówiąc „wielokrotnie podnosząc ramkę do tyłu”? Czy wyjście się trzęsie, czy w jakiś sposób przeskakuje do przodu i do tyłu?
v010dya
@Volodya Myślę, że twoje wyrażenie jest właściwe. Zobaczyć to uwierzyć. Przesłałem powstały Canon-00006.MTS.mp4 na filedropper.com/canon-00006mts Jeśli nie masz nic przeciwko, spróbuj odtworzyć ten plik za pomocą QuickTime Player (jeśli masz Mac ...), a nie VLC.
kaorukobo
5

Zgodnie z tym błędem ffmpeg

Pakiety H.264 z przeplotem są dzielone, powodując MP4 STTS

podczas remuxingu mpeg-ts z przeplotem H.264 do mp4, oba pola każdej klatki wideo są dzielone na osobne pakiety. Oprogramowanie takie jak Mediainfo używa STTS do określania liczby klatek na sekundę. Będzie wyświetlany jako 50 klatek na sekundę zamiast 25 klatek na sekundę

Zgłoszone tutaj niedopasowanie liczby klatek wydaje się wynikać z przeplatania strumieni MP4 ffmpeg z przeplotem strumieni MP4 zgodnie ze specyfikacją, zgodnie z którym każde pole jest podzielone na jeden pakiet. A zatem

„oprogramowanie, które wykorzystuje liczbę próbek w pliku MP4 do ustalenia liczby klatek, jest po prostu nieprawidłowe”. Komentarz 7

Nie zostanie to załatane, ponieważ scalenie par pól w jedną jednostkę dostępową narusza specyfikację MPEG-4, a zatem i kodery, które robią to samo.

Zauważ, że zmiksowane wyjście, takie jak to poniżej, gra dla mnie dobrze w Potplayer i VLC.

    ffmpeg version N-76741-g8eadabf Copyright (c) 2000-2015 the FFmpeg developers
  built with gcc 5.2.0 (GCC)

Input #0, mpegts, from '00007.MTS':
  Duration: 00:00:07.01, start: 1.033367, bitrate: 15935 kb/s
  Program 1 
    Stream #0:0[0x1011]: Video: h264 (High) (HDMV / 0x564D4448), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc
    Stream #0:1[0x1100]: Audio: ac3 (AC-3 / 0x332D4341), 48000 Hz, 5.1(side), fltp, 448 kb/s
    Stream #0:2[0x1200]: Subtitle: hdmv_pgs_subtitle ([144][0][0][0] / 0x0090), 1920x1080
[mp4 @ 054cf020] Codec for stream 0 does not use global headers but container format requires global headers
Output #0, mp4, to '00007.MTS.mp4':
  Metadata:
    encoder         : Lavf57.16.100
    Stream #0:0: Video: h264 ([33][0][0][0] / 0x0021), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 29.97 fps, 29.97 tbr, 90k tbn, 90k tbc
    Stream #0:1: Audio: aac ([64][0][0][0] / 0x0040), 48000 Hz, 5.1(side), fltp, 128 kb/s
    Metadata:
      encoder         : Lavc57.15.100 aac
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
  Stream #0:1 -> #0:1 (ac3 (native) -> aac (native))
Press [q] to stop, [?] for help
[mp4 @ 054cf020] Timestamps are unset in a packet for stream 0. This is deprecated and will stop working in the future. Fix your code to set the timestamps properly
[mp4 @ 054cf020] pts has no value
    Last message repeated 209 times
frame=  420 fps=0.0 q=-1.0 Lsize=   12478kB time=00:00:07.01 bitrate=14564.2kbits/s    
video:12458kB audio:6kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.111239%
[aac @ 052fd480] Qavg: 64863.176
Gyan
źródło
4

Możesz spróbować wyegzekwować oryginalną liczbę klatek na sekundę, używając -r 29.97. FFmpeg prawdopodobnie z jakiegoś powodu próbuje dostosować ilość klatek na sekundę. Twoja składnia jest poza tym poprawna i nie powinna powodować tego błędu.

Odnośnie twojego trzeciego pytania. Po prostu niemożliwe. Możesz pominąć klatki, gdy używasz kodeków, które kodują klatki indywidualnie, ale nie jest tak w przypadku h264, ale nawet w przypadku takiego kodeka nadal w jakiś sposób modyfikujesz strumień wideo. To samo dotyczy zwiększania liczby klatek na sekundę, musisz albo dodać obliczone klatki, albo powielić niektóre klatki.

Edycja: w odniesieniu do dodatkowych informacji z komentarza poniżej. Jeśli chcesz zmienić dane zapisane w nagłówku formatu bez zapisywania zupełnie nowego pliku, prawdopodobnie chcesz to zrobić w edytorze szesnastkowym. FFmpeg ma tylko opcję zmiany metadanych, które nie obejmują danych strumienia. Jak i gdzie wprowadzić zmiany w pliku, zależy od formatu kontenera.

Inną opcją byłoby demuxowanie kontenera i ponowne strumieniowanie strumienia wideo i audio do nowego kontenera z określonymi opcjami. Ile można ponownie określić, zależy od formatu kontenera. Pomocne może być narzędzie MP4Box. W takim przypadku można określić szybkość klatek podczas miksowania nieprzetworzonych strumieni wideo do nowego pliku mp4 przy użyciu następującej składni:

MP4Box -add input.h264:fps=29.97 -new output.mp4
PTS
źródło
Dzięki. Jeśli chodzi o -t 60przełącznik, istnieje możliwość określenia nie $ ffmpeg -h|grep -- -t-t duration record or transcode "duration" seconds of audio/video
liczby
No tak, to był inny koder, przepraszam za ten błąd.
PTS
Zobacz moją edycję odpowiedzi.
PTS
Dzięki jeszcze raz. Zredagowałem moje pytanie, aby dodać wynik, próbując uzyskać poradę. Niestety problem nadal występował ..
kaorukobo
Jeśli chodzi o twoją odpowiedź na moje trzecie pytanie, to w porządku w przypadku, w którym chciałbym zmienić liczbę klatek na sekundę strumienia wideo, a nie tylko „wartość”. Jednak w moim przypadku "set framerate/timebase values"oznacza to po prostu przepisywanie wartości umieszczonych w nagłówku kontenera / kodeka. Dlaczego? Istnieją pewne przypadki, z którymi należy sobie poradzić: przypadek, w którym jakiś koder (np. Transkoder h264 kompresora Apple) wstrzykuje do strumienia wideo niewłaściwą wartość podstawy czasu (tbc), i sprawa taka jak to, że ffmpeg wstrzykuje nieprawidłowe wartości klatek / podstawy czasu, które są różni się od oryginalnych plików wideo.
kaorukobo
2

Wiem, że to stare pytanie, ale pojawiło się ponownie w kanale, więc jest dla mnie nowe. (-:

Jednej rzeczy, o której nie widzę, to kolejność w terenie. Jest to plik z przeplotem, więc należy to rozważyć. OP wspomina o ramkach „drżących tam iz powrotem”, co zawsze oznacza flagę dla nieprawidłowej kolejności pól. Jeśli wideo nie jest w porządku, z wyjątkiem „drżenia”, spróbuj dodać wszystko, co ffmpeg potrzebuje, aby wymusić „najpierw górne pole”, a potem odwrotnie, jeśli nadal jest źle. Nie znam wystarczająco szczegółów ffmpeg, aby podać dokładne flagi.

Jim Mack
źródło
Chcę spróbować uruchomić komendy ffmepg w odpowiedzi. Jednak moja wersja ffmpeg 2.2.1 nie wydaje się mieć opcji obsługujących kolejność pól. Próbowałem, ffmpeg -h|egrep 'field|first'ale nic nie pokazuje. Poprzednia wersja (0.8.6) ffmpeg miała -topopcję, która może to obsłużyć.
kaorukobo
@kaorukobo Internet oferuje to: -vf "fieldorder = bff" lub = tff, gdzie t i b odnoszą się odpowiednio do góry i dołu. Opcja top = 1/0 jest najwyraźniej używana do zmiany kolejności odczytu, a nie zapisu pól. Ponownie używam ffmpeg / avconv tylko od niechcenia, więc nie ma gwarancji.
Jim Mack