Comment puis-je convertir un fichier .MTS (AVCHD) en .mp4 par ffmpeg sans ré-encoder le flux vidéo H264?

20

Remarque: j'ai posté la même question à stackoverflow peu de temps auparavant, alors que je n'ai pas encore trouvé cette communauté. Je republie cela car la question est plus adaptée à cette communauté.

1. Ce que j'ai essayé

J'ai des fichiers .MTS (format AVCHD) enregistrés avec mon appareil photo AVCHD . Sa spécification est comme indiqué ci-dessous:

$ 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

Faites attention à la partie de la fréquence d'images / base de temps: 29,97 ips, 29,97 tbr, 90k tbn, 59,94 tbc

Maintenant, je voudrais convertir ce fichier en fichier .mp4, sans ré-encoder le flux vidéo H264 , d'autre part, avec transcoder son flux audio en AAC . J'ai donc essayé la commande suivante:

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

2. Résultat

et les spécifications du fichier de sortie sont les suivantes:

$ 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

Regardez la partie de la fréquence d'images / base de temps: 59,94 ips, 59,94 tbr, 90k tbn, 59,94 tbc . Bien que ffmpeg ait simplement copié le flux vidéo, la fréquence d'images et la base de temps ont été modifiées en deux fois .

Ainsi, lorsque j'ouvre et lit le fichier de sortie avec QuickTime Player ou VLC Player, l'audio n'a aucun problème, cependant, le flux vidéo n'est pas lu correctement. La vidéo est lue avec son image en avant et en arrière de façon répétée.

3. Question

  1. Comment puis-je convertir un fichier .MTS (AVCHD) en .mp4 par ffmpeg sans ré-encoder correctement le flux vidéo H264 ?
  2. Comment puis-je conserver les valeurs d'origine de la fréquence d'images / base de temps (fps / tbr / tbn / tbc) lorsque je convertis le conteneur avec ffmpeget son -vcodec copycommutateur.
  3. Comment puis-je définir des valeurs de framerate / base de temps (fps / tbr / tbn / tbc) par les options de ligne de commande de ffmpeg sans ré-encoder un flux vidéo.

Des idées?


4. Ajout d'une -r 29.97option

Le professeur Sparkles m'a donné un conseil à ajouter -r 29.97. J'ai essayé ça:

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

Cependant, le fichier de sortie a toujours une mauvaise fréquence d'images / base de temps:

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 en utilisant MP4Box

J'ai essayé le demux et le remux en utilisant MP4Box, selon les conseils du professeur 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

et la sortie était:

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

Cela semble un peu plus avancé. Regardez la partie de la fréquence d'images / base de temps: 29,97 ips, 29,97 tbr, 30k tbn, 59,94 tbc . Celles-ci correspondent au flux d'origine, à l' exception detbn (valeur de la base de temps du conteneur).

Cependant, lorsque je lis le fichier de sortie avec Quicktime Player ou VLC, la vidéo est lue à mi-vitesse .

Bien que le fichier d'origine ait 90k tbn(90000 ticks par seconde) et que le nouveau fichier de sortie de MP4Box ait 30k tbnseulement un tiers de la valeur d'origine, le fichier de sortie est lu à mi-vitesse.

Je ne sais pas pourquoi. Mais je pense que le reste est de savoir comment je peux ajuster la tbnvaleur.


5-b. Rapport de MediaInfo sur le fichier de sortie

J'ai également essayé l' outil MediaInfo sur le fichier de sortie généré par 5. Remux en utilisant MP4Box . La sortie est ici: https://gist.github.com/kaorukobo/c5ab9eaa413dff6cd26a


6. Essayer avconv

Volodya a indiqué qu'il avconvfonctionnait bien. J'ai également préparé un court exemple de fichier vidéo (Canon-00006.MTS) enregistré avec le même appareil photo. D'accord, essayons:

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

Les informations ffprobe du fichier de sortie sont ici: https://gist.github.com/kaorukobo/5b53244ade2632ff1211 et ses informations de fréquence d'images / base de temps sont les suivantes: 59,94 ips, 59,94 tbr, 90k tbn, 59,94 tbc

Le fichier de sortie a été bien lu avec VLC Player comme l'a rapporté Volodya. Cependant, en l'ouvrant avec Quicktime Player X, la vidéo a été lue à la vitesse normale mais avec son image en arrière de façon répétée et tremblante.


7. Pourquoi l'application "Free AVCHD to MOV" fonctionne-t-elle?

Comme je l'ai mentionné dans mon commentaire précédent , la fonction de «reconditionnement vers MOV» de l' application Free AVCHD to MOV a bien fonctionné, même si elle ne fait pas MP4 mais MOV.

Le logiciel appelle son propre programme ffmpeg (ou avconv) en interne, et j'ai vu quelles options lui sont transmises. C'est comme indiqué ci-dessous:

/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

J'ai essayé de passer les mêmes options (Extrêmement identiques. J'ai défini le type de conteneur de sortie sur MOV et supprimé même le -t 60commutateur.) Au programme ffmpeg et à la conversion. Mais le résultat était le même que celui rapporté jusqu'à présent .

Quoi qu'il en soit, cette excellente application a résolu mon problème sur "Comment puis-je convertir un fichier .MTS (AVCHD) en .mp4 sans réencoder le flux vidéo H264?", Sauf dans "en .mp4" et "par ffmpeg". Mais je suis toujours curieux de savoir pourquoi cette application fonctionne bien, mais pas ffmpeg.

kaorukobo
la source
Qu'entendez-vous par «correctement»? Peut-être supprimer cela du titre. Je voudrais aider mais je n'ai jamais utilisé ffmpeg. J'utilise simplement l'encodeur multimédia d'Adobe Tools.
eLouai
@eLouai Très bien, j'ai fixé le titre.
kaorukobo

Réponses:

8

Voyant que dans le texte de votre question, vous avez commencé à discuter d'autres utilitaires, je suppose que vous n'êtes pas intéressé à rester avec ffmpeg, mais plutôt à faire le travail.

D'après mon expérience avec libav et MTS, je n'ai eu aucun problème avec le framerate, les fichiers sont parfaitement remuxés.

Je viens d'essayer ce qui suit avec l'un de mes fichiers:

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

Le fichier MP4 résultant a été lu correctement avec VLC.

Mon fichier est MTS progressif, je n'ai pas de trame entrelacée, mais si besoin est je peux faire plus de vérification avec ça.

Rapport sur le test de fichier

Le sujet de démarrage a pu fournir un fichier qui a été reconduit de MTS en MP4 et n'a pas pu être lu sur la machine de cette personne avec QuickTime Player (version inconnue). Il a cependant joué avec le lecteur VLC de cet individu.

Je n'ai pas d'ordinateur Mac OS, mais je l'ai essayé avec Ubuntu. Je l'ai joué sur Ubuntu sur VLC (2.0.8) et GNOME Videos (anciennement appelé Totem) (3.8.2); les deux jouent parfaitement.

J'ai alors demandé à un de mes amis, qui est sur un Mac, de le jouer. Il est sur Mavericks (10.9.4), et cela a bien fonctionné avec QuickTime Player 10.3 (727.4).

À l'heure actuelle, il semble que ce soit un problème avec le lecteur particulier ou un problème avec les paramètres de configuration de l'ordinateur. Et il est probablement préférable d'essayer de mettre à jour vers la dernière version de QTP, éventuellement en supprimant d'abord la version actuelle et en effaçant complètement l'ancienne configuration.

Une autre possibilité

Lorsque j'ai eu une vieille machine, certains fichiers à débit binaire élevé ne fonctionnaient pas correctement sur certains lecteurs, et c'était spécifique au conteneur. Par exemple, VLC refuserait de lire le fichier MTS, il afficherait une image, puis afficherait la suivante uniquement dans une seconde et demie. Les vidéos GNOME l'ont bien joué. Mais lors du remuxage en MKV, les deux joueurs l'ont assez bien joué. C'est peut-être une question de quelque chose de similaire. Un joueur peut lire un conteneur particulier (MP4 dans ce cas) d'une manière qui nécessite juste assez de temps CPU, pour qu'il commence à s'étouffer. L'effet de secousse peut ensuite être attribué à tout sous-processus qui prend la finition du processeur, et le joueur vide toutes les images qui étaient en retard très rapidement, après quoi le mauvais sous-processus se déclenche à nouveau et le cycle continue.

Dans cette possibilité, la meilleure option est toujours d'essayer de mettre à niveau le logiciel. Avec les processeurs multicœurs actuels, il serait difficile de tester la nécessité de mettre à niveau le matériel sans vraiment l'obtenir, mais il est peut-être possible de regarder la charge du processeur pendant l'utilisation de QuickTime Player et de la comparer à VLC. Si vous voyez 100% pour n'importe quel cœur avec QTP, cela peut être indicatif de cela.

v010dya
la source
Il est peu probable qu'avconv fasse un travail différent pour lui. avconv est un fork de ffmpeg et ffmpeg fusionne beaucoup de commits du projet avconv dans ffmpeg, des corrections de bugs majeurs comme celui-ci seraient probablement présentes dans ffmpeg.
PTS
@ProfessorSparkles Je pense que le fait que cela a fonctionné ici est un motif suffisant pour croire le contraire. J'attendrai de voir ce que dit Kaorukobo.
v010dya
@Volodya Merci pour vos informations. J'ai ajouté le rapport en essayant avconv à ma question.
kaorukobo
@kaorukobo Qu'entendez-vous exactement par «avoir son cadre en arrière de façon répétée et tremblante»? La sortie tremble-t-elle ou saute-t-elle d'une manière ou d'une autre?
v010dya
@Volodya Je pense que votre expression est juste. Voir c'est croire. J'ai téléchargé le fichier Canon-00006.MTS.mp4 résultant sur depositedropper.com/canon-00006mts. Si cela ne vous dérange pas, essayez de lire ce fichier avec QuickTime Player (si vous avez Mac ...) et non VLC.
kaorukobo
5

Selon ce bogue ffmpeg

Les paquets H.264 entrelacés sont divisés, provoquant MP4 STTS

lors du remuxage d'un mpeg-ts contenant du H.264 entrelacé en mp4, les deux champs de chaque trame vidéo sont divisés en paquets séparés. Un logiciel tel que Mediainfo utilise le STTS pour déterminer la fréquence d'images. Il apparaîtra comme 50fps au lieu de 25fps

La non-concordance de la fréquence d'images rapportée ici semble être le résultat du multiplexage ffmpeg des flux MP4 entrelacés conformément à la spécification, selon laquelle, chaque champ est séparé en un paquet. Et ainsi

"Un logiciel qui utilise le nombre d'échantillons dans le fichier MP4 pour déterminer la fréquence d'images est tout simplement faux." Commentaire 7

Cela ne sera pas corrigé car la fusion de paires de champs en une seule unité d'accès viole la spécification MPEG-4, et donc tout codeur qui fait de même.

Notez que la sortie multiplexé, comme celui ci - dessous, joue - moi bien dans PotPlayer et 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
la source
4

Vous souhaiterez peut-être essayer d'appliquer la fréquence d'images d'origine à l'aide de -r 29.97. FFmpeg essaie probablement d'ajuster le framerate pour une raison quelconque. Votre syntaxe est par ailleurs correcte et ne devrait pas produire cette erreur.

Concernant votre troisième question. Tout simplement pas possible. Vous pouvez omettre des images lorsque vous utilisez des codecs qui encodent des images individuellement, mais ce n'est pas le cas avec h264 mais même avec un tel codec, vous modifiez toujours le flux vidéo d'une manière ou d'une autre. Il en va de même pour l'augmentation de la fréquence d'images, vous devez soit ajouter des images calculées ou dupliquer certaines images.

Edit: Concernant les informations supplémentaires du commentaire ci-dessous. Si vous devez modifier les données écrites dans l'en-tête de format sans écrire un fichier complètement nouveau, vous voudrez probablement le faire dans un éditeur hexadécimal. FFmpeg n'a que l'option de modifier les métadonnées qui n'incluent pas les données de flux. Comment et où apporter vos modifications dans le fichier dépend du format du conteneur.

Une autre option serait de démultiplexer le conteneur et de remuxer le flux vidéo et audio dans un nouveau conteneur avec vos options spécifiées. La quantité que vous pouvez spécifier à nouveau dépend du format du conteneur. L'outil MP4Box peut être utile dans ce cas, vous pouvez spécifier un taux de rafraîchissement lors du multiplexage de flux vidéo bruts dans un nouveau mp4 en utilisant la syntaxe suivante:

MP4Box -add input.h264:fps=29.97 -new output.mp4
PTS
la source
Merci. Concernant le -t 60switch, c'est une option pour spécifier non pas un framerate mais une durée de traitement ( $ ffmpeg -h|grep -- -t-> -t duration record or transcode "duration" seconds of audio/video)
kaorukobo
Oh oui, c'était un encodeur différent, désolé pour cette erreur.
PTS
Voir ma modification à la réponse.
PTS
Merci encore. J'ai édité ma question pour ajouter le résultat en essayant vos conseils. Malheureusement, le problème était toujours là ..
kaorukobo
En ce qui concerne votre réponse à ma troisième question, c'est bien pour le cas où je voudrais changer le framerate du flux vidéo, pas seulement la "valeur". Cependant, dans mon cas, "set framerate/timebase values"signifie simplement réécrire les valeurs placées sur l'en-tête du conteneur / flux de codec. Pourquoi? Il y a quelques cas à traiter: le cas où un encodeur (par exemple le transcodeur h264 d'Apple Compressor) injecte une mauvaise valeur de base de temps (tbc) dans le flux vidéo, et le cas comme cette question où ffmpeg injecte de mauvaises valeurs de framerate / base de temps, qui sont différent de ceux des fichiers vidéo originaux.
kaorukobo
2

Je sais que c'est une vieille question, mais elle est apparue à nouveau dans le flux, donc c'est nouveau pour moi. (-:

Une chose que je ne vois pas mentionnée est l'ordre des champs. Il s'agit d'un fichier entrelacé, c'est donc une considération. L'OP mentionne les trames "tremblant d'avant en arrière" qui est toujours un indicateur pour un ordre de champ incorrect. Si la vidéo est par ailleurs OK, sauf pour le «tremblement», essayez d'ajouter tout ce que ffmpeg a besoin pour forcer le "champ supérieur en premier", puis l'inverse si c'est toujours faux. Je ne connais pas assez les détails de ffmpeg pour donner les drapeaux exacts pour cela.

Jim Mack
la source
Je veux essayer d'exécuter certaines commandes ffmepg sur votre réponse. Cependant, ma version 2.2.1 de ffmpeg ne semble pas avoir d'options qui gèrent l'ordre des champs. J'ai essayé ffmpeg -h|egrep 'field|first'mais ça ne montre rien. La version précédente (0.8.6) de ffmpeg avait une -topoption qui pouvait le gérer.
kaorukobo
@kaorukobo Internet offre ceci: -vf "fieldorder = bff" ou = tfft et b font respectivement référence au haut et au bas. L' option top = 1/0 est apparemment utilisée pour changer l'ordre dans lequel les champs sont lus et non écrits. Encore une fois, j'utilise ffmpeg / avconv uniquement de manière décontractée, donc aucune garantie.
Jim Mack