2017-03-28 1 views
0

Je souhaite créer un maximum de 30 images à partir d'une vidéo (et les coller dans une feuille de sprite). J'ai essayé d'utiliser 'select' avec 'mod' mais si le nombre total d'images ne correspond pas parfaitement au nombre d'images désiré (30), je me retrouve parfois avec plus d'images, parfois moins. Par exemple, si ma vidéo fait 72 images, mon "mod" serait 72/30, ce qui est 2.4.ffmpeg - extrait le nombre exact d'images de la vidéo

Je suis en ce à partir d'un script python donc je fais quelque chose comme ce qui suit pour le filtre:

select='not(mod(n\," + str(mod) + "))' 

Je pense que le mod doit être un entier pour que je puisse soit autour (?) bas et utiliser 2 qui me donne 36 images ou arrondi qui me donne 24 images

Quel est le meilleur moyen d'obtenir exactement 30? - De toute évidence l'intervalle ne serait pas identique mais c'est bien. Peut-être que je pourrais utiliser une boucle for pour générer une liste des trames les plus proches de l'intervalle désiré, puis passer en tant que filtre de sélection?

par exemple. pour obtenir les images que je ferais quelque chose comme ceci:

nframes = 72 # number of frames in video 
outImages = 30 # number of images I want 
mod = float(nframes)/outImages # 2.4 

frames = [] 

idx = 1 

while i < nframes: 
    print str(idx) + ": " + str(math.floor(i+0.5)) 
    frames.append(int(math.floor(i+0.5))) 
    idx += 1 
    i += mod 

Je suis en mesure de passer que (la liste des cadres) dans la commande ffmpeg? Ou puis-je dire à ffmpeg de faire quelque chose de similaire?

Répondre

1

Si vous avez une liste de cadres, vous pouvez simplement lancer

ffmpeg -i in.mp4 -vf select='eq(n,5)+eq(n,11)+eq(n,15)..' -vsync 0 frames%d.jpg 

Il y a une façon de le faire directement avec filtre de sélection si vous pouvez décomposer la fréquence en un nombre rationnel (et faire un peu de maths). Nous prenons f = 2.4 qui est le même que 12/5. Cela signifie que vous avez besoin de 5 images sur 12. Vous pouvez décomposer cela en 1 sur 3 + 1 sur 12. Puisque, dans ce cas, cette dernière coïncidera avec la sélection précédente, nous pouvons choisir une image plus tôt, c'est-à-dire la 11ème de chaque 12ème image.

ffmpeg -i in.mp4 -vf select='not(mod(n,3))+not(mod(n+1,12))' -vsync 0 frames%d.jpg 

L'idée est de représenter votre fréquence comme une somme de valeurs réciproques, 1/f = 1/m + 1/n + 1/p. Vous pouvez utiliser le périphérique de décalage n+c ou n-c si l'un des dénominateurs est un multiple des autres.


Une façon plus grossière de le faire est

ffmpeg -i in.mp4 -vf select='not(mod(n,12))+not(mod(n+3,12))+not(mod(n+5,12))+not(mod(n+7,12))+not(mod(n+11,12))` -vsync 0 frames%d.jpg 

où nombre total de clauses de sélection est égal au nombre d'images nécessaires à partir de chaque ensemble de cadres X.


Dans tous les cas, vous pouvez limiter le nombre crûment total d'images en ajoutant -vframes 30

+0

C'est génial, merci beaucoup. Je pense que je vais utiliser votre première suggestion, c'est un peu maladroit mais logique et simple, et je ne suis pas toujours sûr de ce que sera le 'mod'. Merci encore –