Bagaimana saya bisa mengonversi file .MTS (AVCHD) ke .mp4 oleh ffmpeg tanpa menyandikan ulang aliran video H264?

20

Catatan: Saya memposting pertanyaan yang sama ke stackoverflow beberapa saat sebelumnya, ketika saya belum menemukan komunitas ini. Saya memposting ulang ini karena pertanyaannya lebih cocok untuk komunitas ini.

1. Apa yang saya coba

Saya memiliki beberapa file .MTS (format AVCHD) yang direkam dengan kamera AVCHD saya . Spesifikasinya adalah seperti yang ditunjukkan di bawah ini:

$ 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

Perhatikan framerate / timebase: 29,97 fps, 29,97 tbr, 90k tbn, 59,94 tbc

Sekarang saya ingin mengonversi file ini ke file .mp4, tanpa menyandikan ulang aliran video H264 , di sisi lain, dengan transcoding stream audionya ke AAC . Jadi saya mencoba perintah berikut:

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

2. Hasil

dan spesifikasi file output adalah seperti yang ditunjukkan di bawah ini:

$ 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

Lihatlah bagian framerate / timebase: 59,94 fps, 59,94 tbr, 90k tbn, 59,94 tbc . Meskipun ffmpeg baru saja menyalin aliran video, framerate dan timebase telah diubah menjadi dua kali lipat nilainya .

Jadi, ketika saya membuka dan memutar file output dengan QuickTime Player atau VLC Player, audio tidak memiliki masalah, namun, aliran video tidak diputar dengan benar. Video diputar ulang dengan memiliki frame maju dan mundur bergetar berulang kali.

3. Pertanyaan

  1. Bagaimana saya bisa mengonversi file .MTS (AVCHD) ke .mp4 oleh ffmpeg tanpa menyandikan ulang aliran video H264 dengan benar ?
  2. Bagaimana saya bisa menyimpan nilai framerate / timebase asli (fps / tbr / tbn / tbc) ketika saya mengonversi wadah dengan ffmpegdan sakelarnya-vcodec copy .
  3. Bagaimana cara menetapkan nilai framerate / timebase (fps / tbr / tbn / tbc) dengan opsi baris perintah ffmpeg tanpa meng -encode ulang aliran video.

Ada ide?


4. Menambahkan -r 29.97opsi

Profesor Sparkles memberi saya saran untuk ditambahkan -r 29.97. Saya mencobanya:

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

Namun, file output masih salah framerate / timebase:

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 menggunakan MP4Box

Saya mencoba demux dan remux menggunakan MP4Box, menurut saran Profesor Sparkles.

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

dan outputnya adalah:

$ 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)

Itu terlihat sedikit maju. Lihatlah bagian framerate / timebase: 29,97 fps, 29,97 tbr, 30k tbn, 59,94 tbc . Itu cocok dengan aliran asli, kecuali untuktbn (nilai timebase dari wadah).

Namun, ketika saya memutar file output dengan Quicktime Player atau VLC, video diputar ulang dengan kecepatan setengah .

Meskipun file asli memiliki 90k tbn(90000 ticks per second) dan file output baru dari MP4Box memiliki nilai 30k tbnhanya sepertiga dari yang asli, file output diputar ulang dengan kecepatan setengah.

Saya tidak tahu alasannya. Tapi saya pikir masalahnya adalah bagaimana saya bisa menyesuaikan tbnnilainya.


5-b. Laporan MediaInfo tentang file output

Saya juga mencoba alat MediaInfo pada file output yang dihasilkan oleh 5. Remux menggunakan MP4Box . Outputnya ada di sini: https://gist.github.com/kaorukobo/c5ab9eaa413dff6cd26a


6. Mencoba avconv

Volodya dilaporkan avconvbekerja dengan baik. Saya juga menyiapkan file film sampel pendek (Canon-00006.MTS) yang direkam dengan kamera yang sama. Oke, mari kita coba:

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

Informasi ffprobe file output ada di sini: https://gist.github.com/kaorukobo/5b53244ade2632ff1211 dan informasi framerate / timebase adalah sebagai berikut: 59,94 fps, 59,94 tbr, 90k tbn, 59kb tbc

File keluaran diputar dengan baik dengan VLC Player seperti yang dilaporkan Volodya. Namun, membukanya dengan Quicktime Player X, video diputar ulang dengan kecepatan normal tetapi dengan memiliki frame mundur berulang kali bergetar.


7. Mengapa aplikasi "AVCHD to MOV" gratis berfungsi?

Seperti yang saya sebutkan di komentar saya sebelumnya , fitur "rewrap to MOV" AVCHD ke MOV aplikasi berfungsi dengan baik, meskipun itu bukan MP4 tapi MOV.

Perangkat lunak memanggil program ffmpeg (atau avconv) sendiri secara internal, dan saya melihat opsi apa yang diberikan padanya. Seperti yang ditunjukkan di bawah ini:

/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

Saya mencoba melewati opsi yang sama (Extractly sama. Saya mengatur tipe wadah keluaran ke MOV dan menghapus bahkan -t 60beralih.) Ke program ffmpeg dan mengkonversi. Namun hasilnya sama dengan yang dilaporkan sejauh ini .

Pokoknya aplikasi hebat itu menyelesaikan masalah saya pada "Bagaimana saya bisa mengonversi file .MTS (AVCHD) ke .mp4 tanpa menyandikan ulang aliran video H264?", Kecuali pada "to .mp4" dan "by ffmpeg". Tapi saya masih tertarik pada mengapa aplikasi itu bekerja dengan baik tetapi ffmpeg tidak.

kaorukobo
sumber
Apa yang Anda maksud dengan "benar"? Mungkin menghapusnya dari judul. Saya ingin membantu tetapi saya belum pernah menggunakan ffmpeg. Saya hanya menggunakan alat adobe media encoder.
eLouai
@ Elouai Baiklah, saya memperbaiki judulnya.
kaorukobo

Jawaban:

8

Melihat bahwa dalam teks pertanyaan Anda, Anda sudah mulai membahas utilitas lain, saya akan berasumsi bahwa Anda tidak tertarik untuk tetap menggunakan ffmpeg, tetapi lebih pada menyelesaikan pekerjaan.

Dalam pengalaman saya dengan libav dan MTS saya tidak punya masalah dengan framerate, file-file tersebut dapat di-remux dengan sempurna.

Saya baru saja mencoba yang berikut ini dengan salah satu file saya:

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

File MP4 yang dihasilkan diputar dengan benar dengan VLC.

File saya adalah progresif MTS, saya tidak punya interlaced bertelur, tetapi jika perlu saya bisa melakukan lebih banyak memeriksa dengan itu.

Laporkan tentang pengujian file

Starter topik dapat menyediakan file, yang diremuxing dari MTS ke MP4 dan tidak diputar di komputer orang itu dengan QuickTime Player (versi tidak diketahui). Itu, bagaimanapun, bermain dengan pemain VLC individu itu.

Saya tidak memiliki komputer Mac OS, tetapi saya telah mencobanya dengan Ubuntu. Saya telah memutarnya di Ubuntu di VLC (2.0.8) dan Video GNOME (dulu disebut Totem) (3.8.2); keduanya bermain dengan sempurna.

Saya kemudian meminta seorang teman saya, yang menggunakan Mac untuk memainkannya. Dia ada di Mavericks (10.9.4), dan itu dimainkan dengan baik dengan QuickTime Player 10.3 (727.4).

Pada saat ini tampaknya ada masalah dengan pemain tertentu atau masalah dengan pengaturan konfigurasi di komputer. Dan mungkin yang terbaik adalah mencoba memperbarui ke versi terbaru dari QTP, mungkin dengan menghapus versi saat ini terlebih dahulu dan sepenuhnya menghapus konfigurasi lama.

Kemungkinan lain

Ketika saya memiliki mesin lama saya memiliki beberapa file bitrate tinggi yang diputar salah di beberapa pemain, dan itu adalah wadah khusus. Misalnya, VLC akan menolak untuk memutar file MTS, itu akan menampilkan bingkai, dan kemudian menunjukkan yang berikutnya hanya dalam satu setengah detik. Video GNOME memutarnya dengan baik. Tetapi ketika remuxing ke MKV, kedua pemain memainkannya dengan cukup baik. Ini mungkin pertanyaan yang serupa. Seorang pemain mungkin membaca wadah tertentu (MP4 dalam kasus ini) dengan cara yang hanya membutuhkan waktu CPU yang cukup, sehingga mulai tersedak sendiri. Efek tersentak dapat kemudian dikaitkan dengan apa pun subproses memakan waktu penyelesaian CPU, dan pemain membuang semua frame yang tertinggal sangat cepat, setelah itu subproses buruk lagi menendang, dan siklus terus berjalan.

Dalam kemungkinan ini, opsi terbaik adalah tetap mencoba memutakhirkan perangkat lunak. Dengan prosesor multicore saat ini, akan sulit untuk menguji kebutuhan untuk meningkatkan perangkat keras tanpa benar-benar mendapatkannya, tetapi mungkin dimungkinkan untuk melihat beban CPU selama penggunaan QuickTime Player dan membandingkannya dengan VLC. Jika Anda melihat 100% untuk satu inti dengan QTP, itu mungkin mengindikasikan hal ini.

v010dya
sumber
Agak tidak mungkin avconv akan melakukan pekerjaan yang berbeda untuknya. avconv adalah fork dari ffmpeg dan ffmpeg menggabungkan banyak komit dari proyek avconv ke ffmpeg, perbaikan bug utama seperti itu kemungkinan akan ada di ffmpeg.
PTS
@ProfessorSparkles Saya pikir fakta bahwa itu bekerja di sini adalah alasan yang cukup untuk percaya sebaliknya. Saya akan menunggu untuk melihat apa kata kaorukobo.
v010dya
@Vododya Terima kasih atas informasi Anda. Saya menambahkan laporan dengan mencoba avconv ke pertanyaan saya.
kaorukobo
@kaorukobo Apa sebenarnya yang Anda maksud dengan "dengan memiliki bingkainya mundur bergetar berulang kali"? Apakah output bergetar atau apakah dalam beberapa cara melompat maju dan mundur?
v010dya
@Vododya saya pikir ekspresimu benar. Melihat adalah percaya. Saya telah mengunggah Canon-00006.MTS.mp4 yang dihasilkan ke ajropper.com/canon-00006mts Jika Anda tidak keberatan, coba mainkan file itu dengan QuickTime Player (jika Anda memiliki Mac ...) bukan VLC.
kaorukobo
5

Sesuai bug ffmpeg ini

Paket H.264 interlaced terpecah menyebabkan MP4 STTS

saat memasang kembali mpeg-ts yang mengandung H.264 interlaced ke mp4, kedua bidang dari masing-masing bingkai video dibagi menjadi paket terpisah. Perangkat lunak seperti Mediainfo menggunakan STTS untuk menentukan frame rate. Ini akan ditampilkan sebagai 50fps, bukan 25fps

Ketidakcocokan frame rate yang dilaporkan di sini nampaknya merupakan hasil dari ffmpeg muxing aliran MP4 interlaced sesuai dengan spesifikasi, karena setiap bidang dipisahkan menjadi satu paket. Dan dengan demikian

"Perangkat lunak yang menggunakan jumlah sampel dalam file MP4 untuk menentukan laju bingkai sama sekali salah." Komentar 7

Ini tidak akan ditambal karena menggabungkan pasangan bidang ke dalam satu unit akses melanggar spesifikasi MPEG-4, dan karenanya demikian juga enkode yang melakukan hal yang sama.

Perhatikan bahwa output muxed, seperti di bawah ini, memainkan baik bagi saya di Potplayer dan 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
sumber
4

Anda mungkin ingin mencoba memberlakukan frame rate asli dengan menggunakan -r 29.97. FFmpeg mungkin mencoba menyesuaikan framerate karena suatu alasan. Sintaks Anda dinyatakan benar dan tidak seharusnya menghasilkan kesalahan itu.

Mengenai pertanyaan ketiga Anda. Tidak mungkin. Anda dapat menghilangkan frame ketika menggunakan codec yang mengkodekan frame secara individual tapi itu tidak terjadi dengan h264 tetapi bahkan dengan codec seperti itu Anda masih memodifikasi aliran video dengan beberapa cara. Hal yang sama berlaku untuk meningkatkan frame rate, Anda harus menambahkan frame terhitung atau menduplikasi beberapa frame.

Sunting: Mengenai info tambahan dari komentar di bawah ini. Jika Anda perlu mengubah data yang ditulis dalam format header tanpa menulis file yang sama sekali baru, Anda mungkin ingin melakukannya di hex editor. FFmpeg hanya memiliki opsi untuk mengubah metadata yang tidak termasuk aliran data. Bagaimana dan di mana membuat perubahan dalam file tergantung pada format wadah.

Pilihan lain adalah dengan mendemuxing wadah dan memundurkan video dan audio stream ke dalam wadah baru dengan opsi yang Anda tentukan. Seberapa banyak Anda dapat menentukan kembali tergantung pada format wadah. Alat MP4Box mungkin bisa membantu dengan itu dalam hal ini, Anda dapat menentukan framerate ketika memadukan stream video mentah ke mp4 baru menggunakan sintaks berikut:

MP4Box -add input.h264:fps=29.97 -new output.mp4
PTS
sumber
Terima kasih. Mengenai -t 60switch, itu adalah opsi untuk menentukan bukan framerate tetapi durasi pemrosesan ( $ ffmpeg -h|grep -- -t-> -t duration record or transcode "duration" seconds of audio/video)
kaorukobo
Oh benar itu encoder yang berbeda, maaf atas kesalahan itu.
PTS
Lihat edit saya untuk jawabannya.
PTS
Terima kasih lagi. Saya mengedit pertanyaan saya untuk menambahkan hasilnya dengan mencoba saran Anda. Sayangnya, masalahnya masih ada ..
kaorukobo
Mengenai tanggapan Anda terhadap pertanyaan ketiga saya, tidak apa-apa untuk kasus saya ingin mengubah framerate aliran video, bukan hanya "nilai". Namun, dalam kasus saya, "set framerate/timebase values"berarti hanya menulis ulang nilai yang diletakkan di header container / codec-stream. Mengapa? Ada beberapa kasus yang harus dihadapi: kasus bahwa beberapa encoder (mis. Transcoder h264 dari Apple Compressor) menyuntikkan nilai timebase yang salah (tbc) ke aliran video, dan kasus seperti pertanyaan ini bahwa ffmpeg menyuntikkan nilai framerate / timebase yang salah, yang merupakan berbeda dengan file video asli.
kaorukobo
2

Saya tahu ini adalah pertanyaan lama, tetapi baru saja muncul kembali di feed sehingga baru bagi saya. (-:

Satu hal yang saya tidak lihat disebutkan adalah pesanan lapangan. Ini adalah file interlaced, jadi itu pertimbangan. OP menyebutkan frame "bergetar bolak-balik" yang selalu merupakan bendera untuk urutan bidang yang salah. Jika video dinyatakan OK kecuali untuk 'quivering', coba tambahkan ffmpeg apa pun yang perlu memaksa "bidang pertama", maka kebalikannya jika itu masih salah. Saya tidak cukup akrab dengan detail ffmpeg untuk memberikan flag yang tepat untuk itu.

Jim Mack
sumber
Saya ingin mencoba menjalankan beberapa perintah ffmepg pada jawaban Anda. Namun ffmpeg versi 2.2.1 saya tampaknya tidak memiliki opsi yang menangani urutan bidang. Saya mencoba ffmpeg -h|egrep 'field|first'tetapi tidak menunjukkan apa-apa. Versi sebelumnya (0.8.6) dari ffmpeg memiliki -topopsi yang dapat menanganinya.
kaorukobo
@kaorukobo Internet menawarkan ini: -vf "fieldorder = bff" atau = tff di mana t dan b masing-masing merujuk ke atas dan bawah. Opsi top = 1/0 tampaknya digunakan untuk mengubah urutan bidang mana yang dibaca, bukan ditulis. Sekali lagi, saya menggunakan ffmpeg / avconv hanya dengan santai, jadi tidak ada jaminan.
Jim Mack