viernes, 23 de abril de 2010

Convertir videos con FFMPEG


He tenido la necesidad de convertir algunos videos avi a flv para su visualización el la web, se que existen varios programas en windows y linux para realizar esa sencilla tarea, pero lo interesante del asunto es que yo recibo diariamente viarios videos grabados por mi cámara IP y la tarea se vuelve tediosa cuando por la noche tengo que convertir esos videos, asi que la forma mas a adecuada de realizar esa tarea es mediante un script corriendo bajo un cron.
Así que en este post explicare la forma de realizar el script.
Primero que nada debemos saber en donde estan alojados nuestros videos y que estructura tienen las carpetas que los contienen, la estructura de mis carpetas es sencilla:
-Dia
-Hora
-Video1.avi
-Video2.avi
-Video3.avi
-....avi


únicamente tengo carpetas por día, que a su vez contienen carpetas por hora y dentro de esas están los videos, así que lo que el script tiene que hacer es entrar a la carpeta del día actual, entrar en cada una de las carpetas por hora y convertir los videos contenidos en ellas.

Los videos los guardara en una carpeta llamada flvs que se encuentra en el mismo nivel que las carpetas por dia, y dentro de esta seguira la misma estructura original Dia:Hora:Videos.

Hasta aqui la logica bien no?, ahora vamos a lo interesante, necesitamos saber que instruccion es la que me va a sacar el avi en flv, para eso utilizaremos FFMPEG y algunos parametros de conversion, la instruccion es:
ffmpeg -i video1.avi -ar 22050  -ab 32k  -r 25  -s 640x480  -vcodec flv video1.flv
donde:

-i Archivo origen
-ar Frecuencia de audio (Hz)
-ab Audio bit-rate
-r Video frame-rate
-s Resolution de salida
-vcodec Codec de salida
Adicionalmente como voy a mostrarlo en la web el link que quiero para representar cada dia va a ser una imagen, asi que necesito sacar una imagen de cualquier video, para ello utilizo nuevamente ffmpeg con parametros diferentes:
ffmpeg -i video1.flv -r 1 -t 1 -s qvga imagen1.jpg
donde:

-i Archivo origen
-r Video frame-rate
-t Tiempo
-s Resolucion

Esta instruccion me va a sacar una imagen del video video1.flv forzandolo a que sea de 1 frame y del segundo 1 del video.


Porteriormente se unen las tres partes: navegacion entre carpetas, convercion de video y obtencion de imagen, en un solo script getVideos.sh:
#!/bin/bash

 DIRECTORIO=$1
 echo "Entrando en $DIRECTORIO"
 echo "Creando flvs/$DIRECTORIO"
 mkdir "flvs/$DIRECTORIO"
 VAR=0
 DIR="flvs/$DIRECTORIO"
 for Dia in $(ls $1)
 do
  echo "Entrando en $DIRECTORIO/$Dia"
  for Hora in $(ls "$DIRECTORIO/$Dia")
  do
   for f in $(ls "$DIRECTORIO/$Dia/$Hora")
   do
    if [ ${f#*.} == 'avi' ]
    then
     TEMPFILE=$(basename $f)
     FILE=${TEMPFILE%.*}
     echo "Convirtiendo: $f y almacenando en $DIR/$FILE.flv"
     ffmpeg -i $f -ar 22050  -ab 32k  -r 25  -s 640x480  -vcodec flv -qscale 9.5 $DIR/$FILE.flv
    fi
    if [ $VAR -eq 0 ]
    then
     echo "Sacando imagen : $DIR.flv y almacenando en $DIR.jpg"
     ffmpeg -i $DIR/$FILE.flv -r 1 -t 1 -s qvga $DIR/1.jpg
    fi
    VAR=1
   done
  done
 done
Este script recibe como unico argumento el nombre de la carpeta por dia, navega por la carpeta del dia y recorre las carpetas de horas,crea la carpeta flvs/Dia/Hora si no existe, convierte el video a flv y lo guarda en dicha carpeta, obtiene la imagen del primer video solamente y la guarda en la misma carpeta, asi recursivamente hasta terminar con todos los videos almacenados en el dia.

Ahora solo tenemos que ejecutarlo asi:

$./getVideos.sh Lunes

No hay comentarios:

Publicar un comentario