Existe-t-il un moyen de détecter les images dupliquées dans la vidéo à l'aide de la fonction ffmpeg
?
J'ai essayé -vf
drapeau avec select=gt(scene\,0.xxx)
pour le changement de scène. Mais, cela n'a pas fonctionné dans mon cas.
Existe-t-il un moyen de détecter les images dupliquées dans la vidéo à l'aide de la fonction ffmpeg
?
J'ai essayé -vf
drapeau avec select=gt(scene\,0.xxx)
pour le changement de scène. Mais, cela n'a pas fonctionné dans mon cas.
Utilisez le mpdecimate dont le but est de "supprimer les images qui ne diffèrent pas beaucoup de l'image précédente afin de réduire la fréquence d'images".
Cela va générer un affichage sur la console montrant les images que le filtre considère comme 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
El setpts L'expression du filtre génère des timestamps lisses pour une vidéo à FRAME_RATE
FPS. Pour une explication de l'horodatage, voir Qu'est-ce que l'échelle de temps vidéo, la base de temps ou le timestamp dans ffmpeg ?
C'est ce que j'ai fait, et ça a très bien marché, merci. En prime, le fichier mp4 contenait beaucoup moins de mégaoctets, même s'il ne contenait que quelques images.
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 un son désynchronisé et j'ai dû explorer d'autres options :
mpdecimate
est la recommandation standard que j'ai trouvée partout dans SO et sur internet, mais je ne pense pas qu'il devrait être le premier choix.
frac
mais c'est un travail supplémentaire que vous voudrez peut-être éviter si vous pouvezmp4
conteneur ( source ), mais j'utilisais mkv
Cette limitation ne s'applique donc pas à mon cas, mais il est bon d'en être conscient.decimate
supprime les cadres avec précision, mais n'est utile que pour les doublons qui se produisent périodiquement.si vous avez un fichier multimédia avec des images en double, il est bon de s'assurer que la fréquence d'images détectée correspond à la fréquence réelle.
ffprobe in.mkv
affichera le nombre d'images par seconde détectées ; cela 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)
le taux de trame réel peut être trouvé si vous ouvrez le média in.mkv
dans un lecteur multimédia qui vous permet d'avancer d'une image à la fois, puis de compter les étapes nécessaires pour avancer la lecture d'une seconde, dans mon cas c'était 30 fps
pas une grande surprise pour moi, parce que chaque 6ème image était un double (5 bonnes images et 1 double), donc après 25 bonnes images il y avait aussi 5 doubles
N/FRAME_RATE/TB
sauf l'utilisation de FRAME_RATE
variable le N/FRAME_RATE/TB
est égal à l'exemple ci-dessous tiré de la documentation de ffmpeg ( source )
Définir une fréquence fixe de 25 images par seconde :
setpts=N/(25*TB)
les mathématiques derrière tout cela parfaitement expliquées dans Qu'est-ce que l'échelle de temps vidéo, la base de temps ou le timestamp dans ffmpeg ?
TB
pour améliorer la précisionFRAME_RATE
valeur FPS variable ou littérale (par exemple 25)FRAME_RATE
variable dans N/FRAME_RATE/TB
FRAME_RATE
sur votre propre
N/25/TB
FRAME_RATE
(et j'ai vraiment essayé) il prendrait les mauvaises fps détectées de 25 cadres, c'est-à-dire FRAME_RATE=25
et le faire passer par mpdecimate
qui supprimerait toutes les 6 images et mettrait à jour FRAME_RATE=20.833
donc N/FRAME_RATE/TB
serait en fait N/20.833/TB
ce qui est complètement faux
donc le setpts Le filtre est déjà assez compliqué, surtout à cause des problèmes de FPS que les images dupliquées peuvent créer.
la bonne nouvelle est que vous n'avez peut-être pas besoin de la setpts filtre du tout
Voici ce que j'ai utilisé avec bons résultats
[ffmpeg](https://linux.die.net/man/1/ffmpeg) -i in.mkv -vf [mpdecimate](https://ffmpeg.org/ffmpeg-filters.html#mpdecimate) out.mkv
[ffmpeg](https://linux.die.net/man/1/ffmpeg) -i in.mkv -vf [decimate](https://ffmpeg.org/ffmpeg-filters.html#decimate-1)=cycle=6,[setpts](https://ffmpeg.org/ffmpeg-filters.html#setpts)=N/25/TB out.mkv
mais ce qui suit m'a donné audio désynchronisé
[ffmpeg](https://linux.die.net/man/1/ffmpeg) -i in.mkv -vf [mpdecimate](https://ffmpeg.org/ffmpeg-filters.html#mpdecimate),[setpts](https://ffmpeg.org/ffmpeg-filters.html#setpts)=N/FRAME_RATE/TB out.mkv
[ffmpeg](https://linux.die.net/man/1/ffmpeg) -i in.mkv -vf [mpdecimate](https://ffmpeg.org/ffmpeg-filters.html#mpdecimate),[setpts](https://ffmpeg.org/ffmpeg-filters.html#setpts)=N/25/TB out.mkv
[ffmpeg](https://linux.die.net/man/1/ffmpeg) -i in.mkv -vf [decimate](https://ffmpeg.org/ffmpeg-filters.html#decimate-1)=cycle=6 out.mkv
comme vous le voyez
FRAME_RATE
et utiliser la variable N/25/TB
au lieu de cela, parce que le FPS réel n'a pas été détecté correctement.-af [asetpts](https://ffmpeg.org/ffmpeg-filters.html#setpts_002c-asetpts)=N/SAMPLE_RATE/TB
SAMPLE_RATE
en fonction du ratio d'images dupliquées supprimées, mais cela me semble être un travail supplémentaire inutile, en particulier lorsque ma vidéo avait l'audio synchronisé au début, il est donc préférable d'utiliser des commandes qui maintiendront cette situation au lieu de la corriger plus tard.Si la commande habituellement recommandée [ffmpeg](https://linux.die.net/man/1/ffmpeg) -i in.mkv -vf [mpdecimate](https://ffmpeg.org/ffmpeg-filters.html#mpdecimate),[setpts](https://ffmpeg.org/ffmpeg-filters.html#setpts)=N/FRAME_RATE/TB out.mkv
ne fonctionne pas pour vous, essayez ceci :
[ffmpeg](https://linux.die.net/man/1/ffmpeg) -i in.mkv -vf [mpdecimate](https://ffmpeg.org/ffmpeg-filters.html#mpdecimate) out.mkv
o
[ffmpeg](https://linux.die.net/man/1/ffmpeg) -i in.mkv -vf [decimate](https://ffmpeg.org/ffmpeg-filters.html#decimate-1)=cycle=6,[setpts](https://ffmpeg.org/ffmpeg-filters.html#setpts)=N/25/TB out.mkv
_( cycle=6
parce qu'une image sur six est dupliquée et N/25/TB
parce qu'après avoir supprimé les doublons, la vidéo aura 25 fps (éviter les FRAME_RATE
variable) ; adaptez à votre cas d'utilisation)_
Le setpts est nécessaire avec le mp4 parce que c'est un muxer à frame rate constant. Ajouter -vsync vfr
et supprimer setpts dans ma commande pour garder les images dédupliquées avec le même timestamp lors de la sauvegarde en mp4
Add -vsync vfr and remove setpts in my command
@Gyan --- C'est exactement ce que j'ai fait pour le cas d'utilisation avec mpdecimate
En particulier, j'ai retiré le setpts
et je n'ai même pas eu besoin du -vsync vfr
. Tout est dans tl;dr
section.
The setpts is needed with mp4 because it is a constant frame rate muxer
@Gyan --- c'est intéressant, mais remarquez aussi que si j'ai pu supprimer setpts
du filtre de la mpdecimate
cas d'utilisation du filtre (comme vous le suggérez), je a dû utiliser setpts
pour le decimate
usecase. Les deux sont mkv
. Allez comprendre !
J'ai essayé les solutions proposées ici et aucune d'entre elles ne semble fonctionner lorsqu'il s'agit de découper la vidéo et de conserver l'audio. Il existe une mpdecimate_trim qui fait un bon travail. Il liste essentiellement toutes les trames à abandonner (en utilisant mpdecimate
) et crée ensuite un filtre complexe pour couper toutes ces images (et l'audio correspondant) de la vidéo en divisant la vidéo et en n'incluant que la partie sans images dupliquées.
J'ai cependant dû modifier quelques options dans le code. Par exemple, dans mpdecimate_trim.py
j'ai dû modifier cette ligne :
dframes2 = get_dframes(ffmpeg(True, "-vf", "mpdecimate=hi=576", "-loglevel", "debug", "-f", "null", "-").stderr)
Je devais détecter les doublons de manière un peu plus agressive, j'ai donc modifié le mpdecimate
option pour mpdecimate=hi=64*32:lo=64*24:frac=0.05
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.