Existe-t-il un moyen de détecter les images en double dans la vidéo à l'aide de ffmpeg
.
J'ai essayé le drapeau -vf
Avec select=gt(scene\,0.xxx)
pour changer de scène. Mais cela n'a pas fonctionné pour mon cas.
Utilisez le filtre mpdecimate , dont le but est de "supprimer des images qui ne diffèrent pas beaucoup de l'image précédente afin de réduire la fréquence d'images".
Cela générera une lecture de la console indiquant les images 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 de filtre génère des horodatages fluides pour une vidéo à FRAME_RATE fps. Voir une explication des horodatages sur Qu'est-ce que l'échelle de temps vidéo, la base de temps ou l'horodatage dans ffmpeg?
J'ai également eu ce problème et l'excellente réponse de Gyan ci-dessus m'a permis de démarrer, mais le résultat était une audio désynchronisée, j'ai donc dû explorer plus d'options:
mpdecimate
est la recommandation standard que j'ai trouvée partout SO et Internet, mais je ne pense pas que ce devrait être le premier choix frac
, mais c'est un travail supplémentaire que vous voudrez peut-être éviter si vous le pouvezmp4
( source ), mais j'utilisais mkv
donc cette limitation ne s'appliquait pas sur mon cas, mais bon d'en être conscientdecimate
supprime les cadres avec précision, mais il n'est utile que pour les doublons périodiquesffprobe in.mkv
Affichera le FPS détecté; ça peut ressembler à ça
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 fréquence d'images réelle peut être déterminée si vous ouvrez le média in.mkv
dans un lecteur multimédia qui vous permet de passer d'une image à la fois; puis comptez les étapes nécessaires pour faire avancer le temps de lecture pendant 1 seconde, dans mon cas c'était 30 fps
N/FRAME_RATE/TB
sauf l'utilisation de la variable FRAME_RATE
, le N/FRAME_RATE/TB
est égal à l'exemple ci-dessous de la documentation ffmpeg ( source )
Réglez un taux fixe de 25 images par seconde:
setpts=N/(25*TB)
les mathématiques derrière cela sont parfaitement expliquées dans Qu'est-ce que l'échelle de temps vidéo, la base de temps ou l'horodatage dans ffmpeg?
TB
pour améliorer la précisionFRAME_RATE
Vs valeur FPS littérale (par exemple 25)FRAME_RATE
dans N/FRAME_RATE/TB
FRAME_RATE
par vous-même N/25/TB
FRAME_RATE
(et j'ai vraiment essayé) cela prendrait les mauvais fps détectés de 25 trames ie FRAME_RATE=25
, exécutez-le via le filtre mpdecimate
qui supprimerait toutes les 6 trames et il serait mis à jour vers FRAME_RATE=20.833
afin que N/FRAME_RATE/TB
soit en fait N/20.833/TB
qui est complètement faux voici ce que j'ai utilisé avec de bons 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é un son 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
comme tu vois
FRAME_RATE
et utiliser N/25/TB
à la place parce que le FPS réel n'a pas été détecté correctement-af asetpts=N/SAMPLE_RATE/TB
SAMPLE_RATE
en fonction du ratio d'images dupliquées supprimées, mais cela me semble être un travail inutile supplémentaire, surtout lorsque ma vidéo avait l'audio synchronisé au début, il est donc préférable d'utiliser des commandes qui le garderont ainsi au lieu de le réparer plus tardSi 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
Car chaque 6ème image est en double et N/25/TB
Car après avoir supprimé les doublons, la vidéo aura 25 ips (évitez la variable FRAME_RATE
); Ajustez en fonction de votre cas d'utilisation)