Esta utilidad ‘dirs2vid.py‘ es un nuevo script escrito en lenguaje Python y con licencia libre GPL, basada en una utilidad que propusimos hace ya un tiempo dir2avi.py‘.

Mejoras:
Las mejoras son significativas y justifican el cambio de nombre. Para empezar el anterior script tomaba un directorio y lo convertía en un avi. ‘dirs2vi.py’ puede tomar varios directorios de fotogramas, con lo cual resulta muy útil para hacer un montaje final. Además, el formato por defecto es avi, pero puede ser variado a cualquier otro formato compatible con ffmpeg que continúa siendo la base del nuevo script.

Entre otras novedades podemos pasar un fichero de audio para que lo use como audio del vídeo. Nuevamente resulta muy útil para montajes finales de vídeo partiendo de directorios de fotogramas.

Se ha añadido una opción –exif para evitar que cierto tipo de imágenes que vienen con información exif conflictiva para ffmpeg causen distorsiones del color en la imagen. En definitiva hace el proceso más lento, pero más seguro.

Está pensado para su uso en Linux, y resulta especialmente útil para los aficionados a realizar Timelapses.

Portabilidad:
Dado que existe un intérprete de Python para Windows, y un ffmpeg para Windows, su adaptación no debería ser complicada. (Por ejemplo: Algunos comandos Linux contenidos en el script, deberían ser reconvertidos a sus equivalentes en Windows).

Código fuente de ‘dirs2vid.py’
#!/usr/bin/python
# -*- coding: latin1 -*-
"""
Sinopsis: 'dirs2vid.py': Procesa las imagenes contenidas en los directorios indicados y crea un vídeo usando 'ffmpeg.
Autor**: Antonio Castro Snurmacher (acastro0841@gmail.com) (http://www.ciberdroide.com)
Licencia: GPL.
Version: version 1.0 (marzo-2011)
"""

import sys, os, Image
import string

##################
def comando(comm):
print comm
os.system(comm)

#######################################
def GetOpcion(cadopcion):
'''
Capturar y procesar las opciones.
'''
opc_val= string.split(cadopcion, '=')
if opc_val[0] not in [ '--help', '-help', '-h', '-exif', '-vcodec', '-fimg', '-size', '-audio', '-out' ]:
Uso("Opción '%s' desconocida" % opc_val[0])
if len(opc_val)==1:
return opc_val[0], ''
else:
opc_val[1]=opc_val[1].strip()
if opc_val[0]=='-size': # Expandir uso abreviado
if opc_val[1]=='720p':
opc_val[1]='1280x720'
if opc_val[1]=='1080p':
opc_val[1]='1920x1080'
return opc_val[0], opc_val[1]

############
def Uso(cad):
print "Error: %s" % cad
Help()

################################################################
def GetFilesDir(dir, ExtImg):
if not os.path.isdir(dir):
Uso("'%s' no es un directorio" % dir)
if (dir[len(dir)-1]=='/'):
dir=dir[:-1]
finamelist=[]
ListaFicheros=os.listdir(dir)

n=0
for fi in ListaFicheros:
finame, ext= os.path.splitext(fi)
if ext in ExtImg:
finamelist.append(finame)
n=n+1
if n==0:
Uso("El directorio '%s' no contiene ficheros '%s'" % (dir, ExtImg))
finamelist.sort()
return finamelist, ext

####################################################
def CompilaDir(n, finamelist, dir, ext, DirDest, Opc_Exif):
# Las listas se pasan por referencia (no es variable local)
for fi in finamelist:
FiNum="img_%06d%s" % ( n, ext.lower())
if Opc_Exif:
img=Image.open("%s/%s%s" % (dir, fi, ext))
(x,y)=img.size
img.resize(img.size) # Redimensionamos al mismo tamaño. (truco para suprimir toda la info exif)
img.save("%s/%s" % (DirDest, FiNum))
print "%s/%s" % (DirDest, FiNum)

else:
comando ("cd %s ; ln -s ../%s/%s%s %s" % (DirDest, dir, fi, ext, FiNum))
n=n+1
return n

####################
def Timestamp():
"Un Timestamp de 4 digitos se considera suficiente."
import time
return int(time.time()) % 10000

####################
def Help():

print """
USO:
dirs2vid.py [ Opciones... ] Dir...

OPCIONES:
-help # Muestra esta ayuda y finaliza.
-exif # Suprime la información exif. Necesario para evitar cierto bub y forzar el correcto procesado
de los canales RGB de algunas imágenes que contienen información exif erronea.
-fimg= # Para indicar el formato de la imagen que por defecto se considera '.jpg' o '.JPG'.
-size= # Para indicar la resolución del video de salida que por defecto conserva la resolución de las
imagenes originales.
-audio= # Para indicar el fichero que contiene el audio.
-vcodec= # Para especificar un codec de vídeo concreto a ffmpeg.
-out= # Especificar un nombre de fichero de video que por defecto sería del tipo 'd2v9999.avi'
"""
raw_input('Pulse la tecla [Intro] para continuar...')
print """
SINOPSIS:
'dirs2vid.py': Procesa las imágenes contenidas en los directorios indicados (dir...) y crea un vídeo usando 'ffmpeg.

REQUERIMIENTOS:
Dentro de cada directorio las imágenes serán procesadas siguiendo el orden alfabético del nombre del fichero.
Todas las imágenes de todos los directorios deben tener la misma resolución.

EJEMPLOS:
# Obtener un video 'avi' a partir del directorio 'dir_fotogramas' donde los ficheros son de la forma '*.jpg' o '*.JPG'
# (coincide con con los valores de las opciones por defecto)
dirs2vid.py dir_fotogramas

# Obtener un video con nombre 'video.avi' a partir del directorio 'dir_fotogramas' donde los ficheros son de la forma
# '*.jpg' o '*.JPG' e incluir el audido contenido en 'audio.mp3'
dirs2vid.py -out=video.avi -audio=audio.mp3 dir_fotogramas

# Obtener un video 'avi' de 1280x720 a partir del directorio 'dir_fotogramas' donde los ficheros son de la forma '*.jpg' o
# '*.JPG' suprimendo previamente la informacion exif de las imágenes. (Proteccion de ffmpeg frente a BUGS EXIF en JPG)
dirs2vid.py -exif -size=1280x720 dir_fotogramas

# Obtener un video 'mp4' con vcodec='libxvid' a partir del directorio dir_fotogramas donde los ficheros son de la forma '*.PNG' '
dirs2vid.py -fimg=PNG -fvidOut=mp4 -vcodec=libxvid dir_fotogramas

Para más detalle consulte el artículo de referencia en http://www.ciberdroide.com/fotos
Este programa se ofrece bajo licencia GPL. Si llegara a serle de alguna utilidad y tiene oportunidad, incluya desde su web una
referencia (link) a la web de ciberdroide. Si desea comunicar con el autor, localice el artículo de referencia y ponga allí un
comentario. Con mucho gusto resolveré las dudas que tenga.

Antonio Castro.
"""
sys.exit()

#######################################################
def main():
'''
Vease Help().
'''
import sys, os, Image

opc={}
while (len(sys.argv)>1 and sys.argv[1][0]=='-'):
opcion, valor=GetOpcion(sys.argv[1])
print opcion, valor
opc[opcion]=valor
del sys.argv[1]
for h in [ '--help', '-help', '-h']:
if h in opc.keys():
Help()
Opc_Exif = '-exif' in opc.keys()
if '-vcodec' in opc.keys():
Opc_Vcodec= " -vcodec %s " % opc['-vcodec']
else:
Opc_Vcodec='' # default
if '-fimg' in opc.keys():
ExtImg=[ '.'+ opc['-fimg'] ]
else:
ExtImg=['.jpg', '.JPG'] # default
if '-size' in opc.keys():
Opc_Size=" -s %s " % opc['-size']
else:
Opc_Size=''
if '-audio' in opc.keys():
Audio=" -i %s -acodec copy " % opc['-audio']
else:
Audio=' -an '
# print opc
# print "exif=%s, vcodec=%s, fvidOut=%s, fimg=%s," % (Opc_Exit, Opc_Vcode, ExtVidOut, ExtImg)
if (len(sys.argv)<2): Uso("Debe indicar como mínimo un directorio origen.") directorios=sys.argv del directorios[0] if '-out' in opc.keys(): Out=opc['-out'] else: Out="d2v%d.avi" % Timestamp() n=1 DirDest="tmp_fotogramas" comando("rm -r %s; mkdir %s" % (DirDest, DirDest)) for dir in directorios: if dir[-1:]=='/': # Si termina en '/' eliminarlo dir=dir[:-1] finamelist, ext =GetFilesDir(dir, ExtImg) n=CompilaDir(n, finamelist, dir, ext, DirDest, Opc_Exif) comando("ffmpeg %s -f image2 -i %s/img_%%06d%s %s -sameq %s -y %s" % (Audio, DirDest, ext.lower(), Opc_Vcodec, Opc_Size, Out ) ) ############################################################# if __name__ == "__main__": main()