ffmpeg-supprimer les cadres sequentiellement dupliqués

y a-t-il un moyen de détecter les images dupliquées dans la vidéo en utilisant ffmpeg.

j'ai essayé -vf drapeau avec select=gt(scene,0.xxx) pour changement de scène. Mais, il ne fonctionne pas pour mon cas.

27
demandé sur combo_ci 2016-05-07 15:25:35

2 réponses

mpdecimate filtre, dont le but est de "supprimer les cadres qui ne diffèrent pas beaucoup du cadre précédent afin de réduire la cadence."

  • ceci générera une lecture de la console montrant les cadres que le filtre pense être des doublons.

    ffmpeg -i input.mp4 -vf mpdecimate -loglevel debug -f null -

  • Pour générer une vidéo avec les doublons supprimés

    ffmpeg -i input.mp4 -vf mpdecimate,setpts=N/FRAME_RATE/TB out.mp4


Th setpts l'expression filter génère des horodateurs lisses pour une vidéo à FRAME_RATE fps. Voir une explication pour les horodateurs à qu'est-Ce que la vidéo de l'échelle de temps, la base de temps, ou d'horodatage dans ffmpeg?

39
répondu Gyan 2018-08-27 19:41:59

j'ai aussi eu ce problème et L'excellente réponse de Gyan ci-dessus m'a permis de commencer mais le résultat était un audio désynchronisé donc j'ai dû Explorer plus d'options:

mpdecimate et décimer filtres

  • mpdecimate est la recommandation standard que j'ai trouvé partout ainsi et l'internet, mais je ne pense pas que ce devrait être le premier choix
    • il utilise des heuristiques de sorte qu'il peut et va sauter certaines en double les frames
    • vous pouvez modifier la détection frac paramètre, mais c'est un travail supplémentaire, vous voudrez peut-être éviter si vous pouvez
    • il n'est pas vraiment censé fonctionner mp4 container ( source), mais j'utilisais mkv donc cette limitation ne s'applique pas à mon cas, mais bon d'être conscient de cela
  • decimate supprime les cadres avec précision, mais il n'est utile que pour des situations périodiques les doublons

détectée vs cadence réelle

  • vous avez donc un fichier multimédia avec des images dupliquées, c'est une bonne idée de s'assurer que la fréquence d'images détectée corresponde à la fréquence réelle
  • ffprobe in.mkv produira les FPS détectés; il peut ressembler à ceci

    Stream #0:0: Video: h264 (Main), yuvj420p(pc, bt709, progressive), 1920x1080, SAR 1:1 DAR 16:9, 25 fps, 25 tbr, 1k tbn, 50 tbc (default)

  • la cadence réelle peut être trouvée si vous ouvrez les médias in.mkv dans un lecteur multimédia qui vous permet de passer à l'image à l'époque; puis compter les étapes nécessaires pour avancer le temps de lecture pendant 1 seconde, dans mon cas il était 30 fps

  • ce n'est pas une grande surprise pour moi, parce que chaque 6ème image était dupliquée (5 bonnes images et 1 duplicata), donc après 25 bonnes images il y avait aussi 5 duplicata

qu'est-ce que N/FRAME_RATE/TB

  • sauf l'utilisation de FRAME_RATE variable la N/FRAME_RATE/TB est égal à l'exemple ci-dessous de ffmpeg documentation ( source)

    Définir le taux fixe de 25 images par seconde:

    setpts=N/(25*TB)

  • les mathématiques derrière elle parfaitement expliqué dans Qu'est-ce que le timescale, timebase ou timestamp vidéo dans ffmpeg?

    • il calcule essentiellement timestamp pour chaque image et le multiplie avec timebase TB pour améliorer précision

FRAME_RATE variable vs valeur fps littérale (e.g. 25)

  • c'est pourquoi il est important de connaître vos FPS détectés et réels
  • si les FPS détectés correspondent à vos FPS réels (par exemple, les deux sont 30 fps) vous pouvez heureusement utilisation FRAME_RATE variable N/FRAME_RATE/TB
  • mais si le FPS détecté diffère de celui que vous devez calculer le FRAME_RATE sur votre propre
    • dans mon cas mon FPS actuel 30 images par seconde et j'ai enlevé tous les 6 cadre, de sorte que la cible FPS 25 ce qui mène à N/25/TB
      • si j'ai utilisé FRAME_RATE (et j'ai effectivement essayé), il allait prendre le mauvais détecté fps 25 images c'est à dire FRAME_RATE=25, le lancer à travers mpdecimate filtre qui supprimerait toutes les 6 images et mettrait à jour vers FRAME_RATE=20.833N/FRAME_RATE/TB serait N/20.833/TBqui est complètement mal

utiliser ou ne pas utiliser setpts

  • setpts le filtre est déjà assez compliqué surtout à cause du désordre FPS que les cadres dupliqués peuvent créer
  • la bonne nouvelle est que vous n'avez peut-être pas besoin du setpts filtrer du tout
  • voici ce que j'ai utilisé avec bonne résultats

    ffmpeg -i in.mkv -vf mpdecimate out.mkv

    ffmpeg -i in.mkv -vf decimate=cycle=6,setpts=N/25/TB out.mkv

  • mais ce qui suit m'a donné audio désynchronisé

    ffmpeg -i in.mkv -vf mpdecimate,setpts=N/FRAME_RATE/TB out.mkv

    ffmpeg -i in.mkv -vf mpdecimate,setpts=N/25/TB out.mkv

    ffmpeg -i in.mkv -vf decimate=cycle=6 out.mkv

  • comme vous le voyez

    • mpdecimate et décimer ne fonctionne pas de la même façon
    • mpdecimate a fonctionné mieux pour moi sans setpts filtre
    • décimer nécessaire setpts filtre et de plus je dois éviter FRAME_RATE variable et utiliser N/25/TB au lieu de cela parce que le FPS réel n'a pas été détecté correctement

remarque: asetpts

  • il fait le même travail que setpts mais pour l'audio
  • il n'a pas vraiment fixer désynchronisation audio pour moi, mais vous voulez utiliser quelque chose comme ceci -af asetpts=N/SAMPLE_RATE/TB
  • peut-être que vous êtes censé régler le SAMPLE_RATE selon le rapport des cadres dupliqués supprimés, mais il me semble qu'il y a un travail superflu surtout quand ma vidéo a l'audio synchronisé au début, donc il est préférable d'utiliser des commandes qui le maintiendront ainsi au lieu de le corriger plus tard

tl;dr

si la commande habituellement recommandée ffmpeg -i in.mkv -vf mpdecimate,setpts=N/FRAME_RATE/TB out.mkv ne fonctionne pas pour vous, essayez ceci:

ffmpeg -i in.mkv -vf mpdecimate out.mkv

ou

ffmpeg -i in.mkv -vf decimate=cycle=6,setpts=N/25/TB out.mkv

(cycle=6 parce que toutes les 6 images sont dupliquées et N/25/TB parce qu'après avoir supprimé les doublons, la vidéo aura 25 fps (évitez les FRAME_RATE variable); adapter à votre cas d'utilisation)

2
répondu Vlastimil Ovčáčík 2018-08-28 16:23:09