2018-03-06

Busqueda de fondos de pantalla

bash script para Linux debian-based

Hace tiempo que no publicaba nada por estos lares, pero hoy se me ocurrió pulir y compartir un script que hice hace unas semanas cuando buscaba cambiar mi carpeta de fondos aleatorios de forma automática.
Como bien verán en la imágen, el script lista (y copia si se desea) todas las imagenes con cierta relación de aspecto que encuentre en la carpeta donde se ejecuta, aunque tambien puede hacerlo en forma recursiva si se quiere revisar una carpeta con varias en su interior.

fah_list-walls - Ayuda y modo de empleo

Para hacerlo un poco más cómodo al uso, el valor que se ingresa como "relación de aspecto", puede en realidad ser expresado de varias maneras: "X:Y" como suele usarse hoy en día (ej. 16:9, 4:3, etc), en decimal con coma o punto (ej. 1.77 o 1,33), o como medidas en pixeles específicas (ej. 1280x720, 800x600, etc); y si se le definen 2 valores (mínimo y máximo) separados por ";" (punto y coma), fah_list-walls buscará todas las imagenes que concuerden con tal rango.
De todas maneras todo lo comentado se encuentra escrito en la Ayuda y modo de empleo que pueden visualizar, una vez "instalado" el script, ejecutando:
fah_list-walls -h

El mismo hace uso de paquetes que ya suelen venir por defecto en cualquier distribución basada en debian (como Linux Mint ó MX Linux, x ej), pero por las dudas dejo el comando para instalar las dependencias más improbables (otras como cp o tr es casi imposible que no existan instaladas):
sudo apt install -y bc imagemagick


Sin más que comentar, si desean usarlo tendrán que crear un archivo llamado fah_capture-screen dentro de /usr/local/bin/:
sudo nano /usr/local/bin/fah_capture-screen

Pegar el código del script en el mismo (Ctrl+Shift+V):
#!/bin/bash

# Versión 20170306

# Ayuda y modo de empleo
mostrarAyuda () {
  echo -e "\n\tLista todas las imagenes que correspondan al rango de relacion de aspecto ingresado. El script crea un archivo .LOG de la misma lis$
  echo -e "\tSi no se especifica rango, se busca por la relacion de aspecto 16:9 (1.77)";
  echo -e "\nUSO:"
  echo -e "\t${0##*/} [ -a <VALOR> | -c <VALOR> | -h | -l [<VALOR>] | -r |-s ]"
  echo -e "\nOPCIONES:"
  echo -e '\t-a\tAspect Ratio: Relacion de aspecto a buscar escrita como division, decimal o medida especifica en pixeles; pueder ser una en espec$
  echo -e "\t-c\tCopy: Define la direccion del directorio (path) a donde copiar los archivos que coincidan con la busqueda."
  echo -e "\t-h\tHelp: Ayuda y modo de empleo."
  echo -e "\t-l\tLog: Define el archivo de log. Por defecto: \"./FECHA_HORA.log\""
  echo -e "\t-r\tRecursive: Define que la busqueda sera recursiva a partir del directorio raiz en el que se ejecuta la misma."
  echo -e "\t-s\tSilence: Realiza el proceso sin crear log aunque haya sido definido en -l"
  echo -e "\nEJEMPLOS:"
  echo -e '\t'${0##*/}
  echo -e '\t'${0##*/}' -a "4:3"'
  echo -e '\t'${0##*/}' -s -a "1.70;1.78"'
  echo -e '\t'${0##*/}' -a "1366x768" -c /mi/directorio/de/fondos/'
  echo -e '\t'${0##*/}' -l milog.log -a "1399x768"'
  echo -e '\t'${0##*/}' -r -l milog.log'
  echo -e ""
}

# Valores por defecto
FECHA=$(date +"%Y%m%d_%H%M%S");
LIST="./$FECHA.txt";
DIR="";
RECURSIVE="";
MIN_AR="1.77";
MAX_AR="1.77";
CANT=0;

# Procesamiento de parametros
while getopts 'a:c:hl:rs' OPCION ; do
  case $OPCION in
    a)
      AUX=$OPTARG ;
      MIN_AR=$(echo "${AUX%%;*}") ;
      MAX_AR=$(echo "${AUX##*;}") ;
      MIN_AR=$(echo "$MIN_AR" | tr \:Xx \/);
      MAX_AR=$(echo "$MAX_AR" | tr \:Xx \/);
      MIN_AR=$(echo "$MIN_AR" | tr , .);
      MAX_AR=$(echo "$MAX_AR" | tr , .);
      MIN_AR=$(echo "$MIN_AR"  | bc -l);
      MAX_AR=$(echo "$MAX_AR"  | bc -l);
      if [ $(echo "$MIN_AR > $MAX_AR" | bc) -eq 1 ] ; then
        echo -e "\nWARNING: MIN=$MIN_AR no puede ser mayor a MAX=$MAX_AR\n\tSe asume MIN=$MAX_AR y MAX=$MIN_AR" ;
        AUX=$MIN_AR;
        MIN_AR=$MAX_AR;
        MAX_AR=$AUX;
      fi
      ;;
    c)
      COPY=$OPTARG ;
      ;;
    h)
      mostrarAyuda ;
      exit 0 ;
      ;;
    l)
      LIST=$OPTARG ;
      ;;
    r)
      RECURSIVE="TRUE";
      ;;
    s)
      LIST="" ;
      ;;
    \?)
      echo -e "\nERROR: -$OPTARG no es un parametro valido" ;
      mostrarAyuda ;
      ;;
    :)
      echo -e "\nERROR: Opción -$OPTARG requiere un valor" ;
      mostrarAyuda ;
      exit 1 ;
      ;;
  esac
done

# BUSQUEDA DE IMAGENES
checkImages () {
  for FILE in "$DIR"*.{png,jpg,jpeg,bmp,tiff} ; do
    if [ -f "$FILE" ] ; then
      SIZE=$(identify -format '%w/%h' "$FILE");
      if [ ! -z "$SIZE" ] ; then
        AR=$(echo "$SIZE" | bc -l);
        if [ $(echo "$AR >= $MIN_AR" | bc) -eq 1 ] && [ $(echo "$AR <= $MAX_AR" | bc) -eq 1 ] ; then
          if [ -z "$LIST" ] ; then
            LIST="/dev/null" ;
          else
            echo -e "$FILE" > "$LIST" ;
            if [ -f "$LIST" ] ; then
              LIST=$(readlink -f "$LIST") ;
            else
              echo -e "\nERROR: No se encontro el listado de archivos";
              exit 1;
            fi
          fi
          echo "$FILE";
          let CANT+=1;
          if [ ! -z "$COPY" ] ; then
            cp "$FILE" "$COPY" ;
          fi
        fi
      fi
    fi
  done
}

checkImages ;
if [ ! -z "$RECURSIVE" ] ; then
  for DIR in */ ; do
    checkImages "$DIR";
  done
fi

echo -e "\nImagenes que corresponden a la busqueda: $CANT";

Cerrar el archivo (Ctrl+X) y aceptar guardar las modificaciones cuando nano lo pregunte.

Y por último darle permisos de ejecución:
sudo chmod +x /usr/local/bin/fah_list-walls


Que lo disfruten ^_^

2014-11-08

Capturar pantalla en video con FFmpeg

bash script para Linux debian-based

A pesar de que en Comandos útiles de FFmpeg ya publiqué cómo capturar la pantalla completa en video directamente pasando los valores por consola, la idea de este script es que se encargue de hablar con FFmpeg para simplificarte las cosas.
Funciona en cualquier distro basada en debian (Linux Mint, Ubuntu, etc) con los paquetes necesarios instalados (los cuáles podrán ver al final de esta entrada) y toma todos los valores que necesite automáticamente.
El mismo da la posibilidad de definirle a cuántos FPS (frames per second, cuadros por segundo) y de cuánto tiempo se quiere realizar la captura, así como también el lugar en donde se guardará el archivo de video resultante, por supuesto. En caso de no definirse la salida, el video se almacenará en formato mkv en el home o carpeta personal con la fecha y hora de inicio de grabación.

fah_capture-screen - Ayuda y modo de empleo

Entonces, para ponerlo en marcha tendremos que crear un archivo llamado fah_capture-screen dentro de /usr/local/bin/:
cd /usr/local/bin && sudo nano fah_capture-screen

En el cuál pegaremos (Ctrl+Shift+V) el código del script:
#!/bin/bash

# Versión 20141108_2

# Ayuda y modo de empleo
mostrarAyuda () {
   echo -e "\nfah_capture-screen: Captura pantalla completa en video."
   echo -e "\nUSO:"
   echo -e "\tfah_capture-screen [ -f <VALOR> | -t <VALOR> | -h | -o <SALIDA[.mkv|.mp4|.avi]> ]"
   echo -e "\nOPCIONES:"
   echo -e "\t-f\tFPS (Frames Por Segundo). Por defecto: 30."
   echo -e "\t-h\tAyuda y modo de empleo."
   echo -e "\t-o\tArchivo de salida donde se almacenará la captura. Por defecto: \"~/FECHA_HORA.mkv\""
   echo -e "\t-t\tTiempo hasta finalizar la captura, en segundos o del modo \"hh:mm:ss[.xxx]\". Por defecto: infinito."
   echo -e "\nEJEMPLOS:"
   echo -e "\tfah_capture-screen"
   echo -e "\tfah_capture-screen -o ./videos/mivideo.mp4"
   echo -e "\tfah_capture-screen -f 60 -o mivideo.mkv"
   echo -e "\tfah_capture-screen -f 25 -t 30 -o mivideo.avi"
   echo -e ""
}

# Procesamiento de parámetros
while getopts 'f:t:o:h' OPCION; do
   case $OPCION in
      f)
         FPS=$OPTARG
         ;;
      t)
         TIME=$OPTARG
         ;;
      o)
         OUTPUT=$OPTARG
         ;;
      h)
         mostrarAyuda
         exit 0;
         ;;
      \?)
         echo -e "\nERROR: -$OPTARG no es un parámetro válido."
         mostrarAyuda
         exit 1;
         ;;
       :)
         echo -e "\nERROR: Opción -$OPTARG requiere un parámetro."
         mostrarAyuda
         exit 1;
         ;;
   esac
done

# Valores por defecto
FPS=30
OUTPUT="$HOME/"$(date +"%Y%m%d_%H%M%S")".mkv"
LINE=$(xrandr -q | grep Screen);
WIDTH=$(echo ${LINE} | awk '{ print $8 }');
HEIGHT=$(echo ${LINE} | awk '{ print $10 }' | awk -F"," '{ print $1 }');

if [ ${TIME} ]; then
   ffmpeg -f x11grab \
    -r ${FPS} \
    -s ${WIDTH}x${HEIGHT} \
    -i ${DISPLAY} \
    -t ${TIME} \
    -vcodec libx264 \
    -vpre lossless_ultrafast \
    -y ${OUTPUT}
else
   ffmpeg -f x11grab \
    -r ${FPS} \
    -s ${WIDTH}x${HEIGHT} \
    -i ${DISPLAY} \
    -vcodec libx264 \
    -vpre lossless_ultrafast \
    -y ${OUTPUT}
fi
Cerramos el archivo (Ctrl+X) y aceptamos guardar las modificaciones cuando nano nos lo pregunte.

Luego le daremos permisos de ejecución y de lectura/escritura para evitar tener que usar sudo cuando queramos ejecutarlo:
sudo chmod +x fah_capture-screen && sudo chmod 775 fah_capture-screen

Y por último lo ponemos en práctica:
cd ~ && fah_capture-screen
Para finalizar la grabación: Ctrl+C. Esto guardará el video capturado en el home o carpeta personal.


EDIT 20141109: Agrego video de prueba del script ^_^ (música by Mariano Babich)


Nota importante: Estos paquetes pueden ser necesarios para el correcto funcionamiento de FFmpeg con casi todas sus funciones:
sudo apt-get install -y build-essential ubuntu-restricted-extras ffmpeg libavcodec-extra-53

Y estos son más a elección, depende de lo que vayan a hacer, puede q nunca los necestien, pero por las dudas se los dejo:
sudo apt-get install x264 libx264-123 libx264-dev