Script para pegar subtítulos de forma masiva a tus videos

Mi novia me ha pedido que le haga un  script para pegar subtitulos en mansalva, ya que su play 3 no lee subtitulos. Mientras esperamos que sony actualize, me he hecho este script.

Suponed que teneis en una misma carpeta (el script no es recursivo ahora mismo) muchos videos con su correspondiente subtirulo en formato (.srt) con el mismo nombre que el video pero cuya extensión es «.srt». Simplemente con esa carpeta como directorio de trabajo ponemos sin parametro ninguno «pegarSubtitulos» y empieza a ripear todos los videos con extension: avi , mpg, mkv, mpg2, mpg4, mp4,flv y wmv (si se os ocurren más extensiones, decirmelo). El script tambien acepta una lista de N parametros, donde podemos enumerar concretamente los videos que queremos en concreto, tambien acepta expresiones regulares gracias a la librería de python glob.

Actualización: jueves, 22 de enero de 2009

Características:

  • Ejecutando el script sin parametros busca en el directorio actual (sin recursividad), los archivos con alguna de las siguientes extensiones: «avi»,»mpg»,»mkv»,»mpg2″,»mpg4″,»mp4″,»flv» y «wmv». Automaticamente busca su .srt para pegarlo en el video. Y además ahora hago algo que en la primera versión no hacía dando como fallo problemas con los acentos, ahora mencoder espera un formato latin1. Por lo tanto si un subtitulo esta utf8 lo convierto a latin1 con el comando iconv
  • -forzar|-f            Fuerza a sobreescribir el archivo de salida : _ripeado.avi
  • -verbose|-v            Muestra mas informacion de salida
  • -recursive|-r|-recursivo    Busca videos recursivamente
  • -help|-h|-ayuda            Muestra la ayuda
  • Importante:
    – Todo parametro desconocido se considerara un video para ripear
    – Si no se especifican videos, los videos se listaran de manera automatica, recursiva o no dependiendo si has puesto el -r
  • Cualquier bug que encontreis en los comentarios por favor.
  • Vamos a preparar el script, además de python necesitas mencoder: sudo apt-get install mencoder
  • En una carpeta que tengamos «PATHeada» creamos el sctipt escribiendo en consola: gedit pegarSubtitulos (despues no olvideis los permisos con chmod +x pegarSubtitulos) y pasteamos el script:
#!/usr/bin/python
#
# :: Invasion Tux
# :: Ultima modificacion : jueves, 22 de enero de 2009
# :: Script realizado por makiolo (makiolo@gmail.com) (Licencia Creative Commons con reconocimiento)
# :: Ultima version : https://blogricardo.wordpress.com/2008/09/28/script-para-pegar-subtitulos-de-forma-masiva/
# :: Dependencias : python , mencoder
#

import sys,os,fnmatch,glob

#CONFIGURACION
FUENTE = "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf"
TAM_LETRA = "3.8"
FORMATOS_VALIDOS = ["avi","mpg","mkv","mpg2","mpg4","mp4","flv","wmv"]
RETRASO_SUBTITULOS_SEG = 0 # Con -10 aparecen los subtitulos 10 segundos mas tarde
AUDIO_CODEC = "copy"
VIDEO_CODEC = "xvid -xvidencopts pass=1" # bitrate=1030:pass=1
SUFIJO_SALIDA="_ripeado"
EXTENSION_SALIDA="avi"

#AUXILIARES,  no modificar
FORZAR=False
VERBOSE=False
LISTADO_VIDEOS_AUTOMATICO=True
MOSTRAR_AYUDA=False
RECURSIVO=False

def comprobarExistencia(fichero):
	if(os.path.exists(fichero)):
		return True
	else:
		return False

def getExtension(fichero):
	posPunto = video.rfind(".")
	return fichero[posPunto+1:len(fichero)]

def nombreFichero(fichero):
	posPunto = video.rfind(".")
	return fichero[0:posPunto]

def extensionEsValida(fichero):
	posPunto = video.rfind(".")
	if posPunto != -1:
		extension = getExtension(fichero)
		try:
			FORMATOS_VALIDOS.index(extension)
			return True
		except ValueError:
			return False
	else:
		return False

def glob_get_dirs(path):
	'''
		Devuelve una lista de directorios del directorio "path"
		http://newspiritcompany.infogami.com/recursive_glob_py
	'''
	d = []
	try:
		for i in os.listdir(path):
			if os.path.isdir(path+i):
				d.append(os.path.basename(i))

	except NameError, ne:
		print "NameError thrown=", ne
	except:
		print sys.exc_info()[0]
		print "ERROR en get_dirs()"

	return d

def rec_glob(path, mask):
	'''
		Recursivo glob en el actual directorio
		http://newspiritcompany.infogami.com/recursive_glob_py
	'''
	l = []
	if (sys.platform[:5] == "linux"):
		if path[-1] != '/':
			path = path + '/'
	else: # Realmente no lo he probado en windows
		if path[-1] != '\\':
			path = path + '\\'

	for i in glob_get_dirs(path):
		res = rec_glob(path + i, mask)
		l = l + res

	try:
		for i in os.listdir(path):
			ii = i
            		i = path + i
			if os.path.isfile(i):
                		if fnmatch.fnmatch(ii, mask):
                    			l.append(i)

	except NameError, ne:
		print "NameError=", ne
	except:
		print sys.exc_info()[0]
		print "ERROR en rec_glob()"

	return l  

correctos = []
erroneos = []
listaVideos = []

if(len(sys.argv) > 1):
	for i in range(1,len(sys.argv)):
		parametro = sys.argv[i]
		if(parametro == "-forzar" or parametro == "-f"):
			FORZAR=True
		elif(parametro == "-verbose" or parametro == "-v"):
			VERBOSE=True
		elif(parametro == "-recursive" or parametro == "-r" or parametro == "-recursivo"):
			RECURSIVO=True
		elif(parametro == "-help" or parametro == "-h" or parametro == "-ayuda"):
			MOSTRAR_AYUDA=True
		else:
			LISTADO_VIDEOS_AUTOMATICO = False
			print "Parametro desconocido : "+parametro+" se considera un video para pegar subtitulos"
			expresionExpandida = glob.glob(parametro)
			for j in expresionExpandida:
				listaVideos.append(j)

if(MOSTRAR_AYUDA):
	print "Uso: "+os.path.basename(sys.argv[0])+" [-f] [-v] [-r] [-h] [video1 video2 video3 ... videoN]"
	print "-forzar|-f\t\t\tFuerza a sobreescribir el archivo de salida : "+SUFIJO_SALIDA+"."+EXTENSION_SALIDA
	print "-verbose|-v\t\t\tMuestra mas informacion de salida"
	print "-recursive|-r|-recursivo\tBusca videos recursivamente"
	print "-help|-h|-ayuda\t\t\tMuestra esta ayuda"
	print "Importante:"
	print " - Todo parametro desconocido se considerara un video para ripear"
	print " - Si no se especifican videos, los videos se listaran de manera automatica"
	exit(0)

if (LISTADO_VIDEOS_AUTOMATICO):
	for extension in FORMATOS_VALIDOS:
		if(RECURSIVO):
			listaVideos += rec_glob(".", "*."+extension)
		else:
			listaVideos += glob.glob("*."+extension)
	#Borrar todos los videos que terminan _ripeado.avi
	final = SUFIJO_SALIDA+"."+EXTENSION_SALIDA
	lenFinal = len(final)
	copia = []
	for video in listaVideos:
		if(video[-lenFinal:] != final):
			copia.append(video)
	listaVideos = copia
	#Ordenamos la lista
	listaVideos.sort()

numVideos = len(listaVideos)
videosProcesados=0

if numVideos > 0:

	listaSubtitulos = ""
	for video in listaVideos:
		nombreVideo = nombreFichero(video)
		if comprobarExistencia(nombreVideo+".srt"):
			listaSubtitulos += "\""+nombreVideo+".srt\" " # nombre del subtitulo entre comillas + un espacio
	if(len(listaSubtitulos) > 0):
		print "===================== Preparar subtitulos con la codificacion LATIN1 ===================="
		print "{"
		os.system("file "+listaSubtitulos+" | grep UTF-8 | cut -d: -f1 | sed 's/\ /\\\\ /g' | awk -F. 'BEGIN{n=0} { system(\"iconv \"$0\" -f UTF-8 -t LATIN1 > \"$0\"2 && mv \"$0\"2 \"$0); print \"Se ha convertido la codificacion desde UTF-8 a Latin1 en el archivo : \"$0; n++;} END{ print \"Se han modificado \"n\" subtitulos.\" }'")
		print "}"		

	for video in listaVideos:
		try:
			videosProcesados = videosProcesados + 1
			print "===================== "+video+" ("+str(videosProcesados)+"/"+str(numVideos)+") ===================="
			print "{"
			if comprobarExistencia(video):
				if(extensionEsValida(video)):
					extension = getExtension(video)
					nombreVideo = nombreFichero(video)
					if comprobarExistencia(nombreVideo+".srt"):
						videoSalida = nombreVideo+SUFIJO_SALIDA+"."+EXTENSION_SALIDA
						# Si el video existe ---> ripeo si forzar = TRUE
						# Si el video no existe ---> ripeo sin importar forzar
						if 	(
								(comprobarExistencia(videoSalida) and FORZAR) or
								(comprobarExistencia(videoSalida) == False)
							):
							print "Ripeando (esto puede llevar bastante tiempo) ..."
							if (VERBOSE):
								mencoderVerbose = ""
							else:
								mencoderVerbose = " -really-quiet"

							estadoSalida = os.system("mencoder \""+video+"\" -sub \""+nombreVideo+".srt\" -oac "+AUDIO_CODEC+" -ovc "+VIDEO_CODEC+" -o \""+videoSalida+"\" -subcp latin1 -subdelay \""+str(RETRASO_SUBTITULOS_SEG)+"\" -font \""+FUENTE+"\" -subfont-text-scale \""+TAM_LETRA+"\""+mencoderVerbose)
							if(comprobarExistencia("divx2pass.log")):
								os.remove("divx2pass.log")
							if(estadoSalida == 0):
								mensaje = "OK - "+video+": Se ha ripeado correctamente como "+videoSalida
								print "OK"
								print "}"
								print
								correctos.append(mensaje)
							else:
								mensaje = "ERROR - "+video+": Mencoder no finalizo correctamente"
								print "ERROR"
								print "}"
								print
								erroneos.append(mensaje)
						else:
							mensaje = "ERROR - "+video+": El video ya se ripeo como "+videoSalida+". Utilize -f|-forzar para sobreescribir el ripeado"
							print "ERROR"
							print "}"
							print
							erroneos.append(mensaje)
					else:
						mensaje = "ERROR - "+video+": El video requiere un archivo de subtitulos llamado: "+nombreVideo+".srt"
						print "ERROR"
						print "}"
						print
						erroneos.append(mensaje)
				else:
					mensaje = "ERROR - "+video+": Formato de video no valido"
					print "ERROR"
					print "}"
					print
					erroneos.append(mensaje)
			else:
				mensaje = "ERROR - "+video+": No existe el fichero"
				print "ERROR"
				print "}"
				print
				erroneos.append(mensaje)
		except KeyboardInterrupt:
			mensaje = "ERROR - "+video+": Se ha interrumpido el proceso en el "+str(videosProcesados)+" y todavian quedaban "+str(numVideos-videosProcesados)+" videos"
			print "ERROR"
			print "}"
			print
			erroneos.append(mensaje)

	print "================= INFORME DE RESULTADOS ========================="
	print "{"

	if(len(correctos) == videosProcesados):
		print "\t{"
		print "\t================= Todo ripeado correctamente ==================="
		print "\t}"
	else:
		if(len(correctos) > 0):
			print "\t================ Videos correctos ("+str(len(correctos))+"/"+str(videosProcesados)+") =============="
			print "\t{"
			for mensaje in correctos:
				print "\t"+mensaje
			print "\t}"

	if(len(erroneos) > 0):
		print "\t=================== Videos erroneos ("+str(len(erroneos))+"/"+str(videosProcesados)+") ================="
		print "\t{"
		for mensaje in erroneos:
			print "\t"+mensaje
		print "\t}"

	print "}"
else:
	print
	print "\t\tNo hay videos que ripear O_O"
	print

print ":: Invasion Tux (makiolo@gmail.com) https://blogricardo.wordpress.com"

Si os ha sido útil, por lo menos dejar un comentario :D

23 respuestas

  1. Muy bueno.

    Lo estoy probando y me funciona de maravilla. La mejor forma de insertar subtilos a mis series favoritas.

    Muchas gracias makiolo

  2. Hola: te quiero dar las gracias por el aporte que haces, pèrdona la conchudes pero como devo hacer si el str e el avi no están sincronizados, ¿como los puedo sincronizar?
    Me explico, el str empieza al 1: 15,183 y ese audio en el avi salió a los 23 segundos. ¿Qué hago?
    Carlos Alvarez

  3. Si te fijes arriba, pongo unas variables:

    «# Con -10 aparecen los subtirulos 10 segundos mas tarde
    RETRASO_SUBTITULOS_SEG = 0»

    en tu caso deberías anticipar el subtitulo, es decir en vez de negativo como el ejemplo que pongo, positivo muy positivo al tener un desfase de más de una
    hora, prueba editando el script y pon 75*60=4500

    RETRASO_SUBTITULOS_SEG = 4500

    Cuando termines vuelvelo a poner a 0. No he facilitado el desfase por paso por parametro por que realmente yo sincronizo con el Gaupol (esta en los repositorios y en getdeb). Pero vamos si lo veo realmente necesario puede que lo actualize para que el formato sea en plan pegarSubtitulos video.avi -retraso=5

  4. woow, justamente lo que yo andaba buscando, cuando hagas el recursivo nos avisas,

    chao

  5. Hola!

    Gracias por el script, estaba intendo hacer algo similar, pero no lo lograba. Muchas gracias por el aporte……..

    bye

  6. […] he hecho importantes actualizaciones en el script de pegar subtitulos. Esta mejor explicado en su correspondiente post. Asi que me limito a pegaros el help que devuelve el script. (Antes no tenía ni parametros xD) […]

  7. duda, sobre que corro el script, es java, python, o necesito alguna especie de compilador extra

  8. es python, como sabrás un lenguaje interpretado aunque internamente hace una precompilación. No requieres nada especial, sólo como digo en el post, el script depende de mencoder.

  9. muchisimas gracias, lo probare hoy por la tarde, espero funcione con full hd.

    GRACiAS

  10. Hola, estuve probando el script y me da este error:

    «usuario@usuario-desktop:~/Videos/X-Files/x-files-season-4/XFiles04x01-Herrenvolk$ sudo pegarSubtitulos X-Files 4×01 – Herrenvolk
    File «/usr/local/bin/pegarSubtitulos», line 270
    print «:: Invasion Tux (makiolo@gmail.com) http://blogricardo.wordpress
    ^
    SyntaxError: EOL while scanning single-quoted string
    usuario@usuario-desktop:~/Videos/X-Files/x-files-season-4/XFiles04x01-Herrenvolk$»

    Me gustaria saber como puedo solucionarlo ya que necesito armar 5 temporadas de X-Files y esto me sirve muy mucho!!!

    Gracias!!!

    Federico

  11. aisla el video en una carpeta y simplemente pon «pegarSubtitulos» en esa carpeta de trabajo.

    Tu problema viene de que no metes entre comillas los parametros o escapas los espacios. Para evitarte eso haz lo que te he comentado.

    Un saludo

  12. wow, que buenas mejoras has echo al script, yo aun no aprendo python, pero de hacer algo lo posteare en el blog,

    saludos ati y a tu novia(con respeto por habertelo pedido)

  13. Muchas gracias por el script, funciona de maravilla.

    Saludos

  14. Es genial este script, muchas gracias… me ha facilitado muchisimo la tarea de pegar subtitulos.

  15. muchas gracias
    probandolo a ver que tal
    aunque tengo una duda. Me gusta tener los subtitulos en amarillo. Que habria que cambiar en el script para que modifique el color?
    un saludo

  16. recien acabo de probarlo
    el unico problema es que me ha pasado el archivo de ocupar 350mb a 462 mb, mucha diferencia

  17. Mil gracias, justo lo que buscaba!

  18. Gracias, me ha sido de gran utilidad.

    sigue así!

  19. Hola amigo, copié el script y lo coloqué en la carpeta donde está el vídeo al que le quiero incrustar los subtitulos pero al correr el script el cursor del mouse cambia a una cruz y al hacer click terminta la ejecución del script con los siguientes errores:
    Blitz$ sh subs
    subs: 13: subs: FUENTE: not found
    subs: 14: subs: TAM_LETRA: not found
    subs: 15: subs: FORMATOS_VALIDOS: not found
    subs: 16: subs: RETRASO_SUBTITULOS_SEG: not found
    subs: 17: subs: AUDIO_CODEC: not found
    subs: 18: subs: VIDEO_CODEC: not found
    subs: 29: subs: Syntax error: «(» unexpected

    Espero me puedas ayudar, saludos

    • has encontrado una solucion?
      Con respecto a ese error tienes que eliminar el espacio que hay entre la variable y el =.
      No pude solucionar aun el error de sintaxis de la linea 29 si sabes como me seria de ayuda.

  20. Hola! Estoy intentando ejecutar eso para pegar subtitulos a muchas series pero no consigo ejecutarlo, como tendria que hacerlo y con que programas? Un saludo

Deja una respuesta

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Salir /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Salir /  Cambiar )

Conectando a %s

A %d blogueros les gusta esto: