martes, 24 de julio de 2012

Modificar MKV desde el RaspberryPi

... para las teles que no son muy smarts

Hace unos días, mi colega Xesco me preguntó si con el RaspberryPi y mi tele no-smart, podía cambiar de idioma en un MKV. Como sabéis, uso minidlna para reproducir las películas y series, así que probé y efectivamente no podía, mi tele no es compatible con el cambio de idiomas. No le di mayor importancia, hasta que me topé con una película ES-EN que en realidad estaba en EN-ES, por lo que el idioma por defecto era el inglés. Busqué un poco como solucionar esto y no hay solución, PEEEERO podemos rodear el problema. Os cuento como ...

Por si aún no lo sabías, un MKV es un contenedor (como un zip o un rar) que contiene una o más pistas de video, una o más pistas de audio y diversas cosas "extra" como subtítulos, trailers, carátulas ... Las pistas de video y audio, están etiquetadas (entre otras cosas) por idiomas y además tienen un orden de preferencia. La idea es cambiar este orden o incluso, eliminar los idiomas que queramos. Para esto vamos a usar mkvtools ¡¡OJO!! lo pongo paso a paso y al final el resumen con script, así veis un poco mi maquiavelica forma de scriptear:
apt-get install mkvtoolnix
vamos a ver la información que devuelve de un MKV EN-ES:
mkvinfo archivo_EN-ES.mkv
pufff vaya tocho, paso de leerlo todo, filtrando:
mkvinfo archivo_EN-ES.mkv | grep -e "Track number" -e "Track type" -e "Language"
|  + Track number: 1 (track ID for mkvmerge & mkvextract: 0)
|  + Track type: video
|  + Track number: 2 (track ID for mkvmerge & mkvextract: 1)
|  + Track type: audio
|  + Track number: 3 (track ID for mkvmerge & mkvextract: 2)
|  + Track type: audio
|  + Language: spa
|  + Track number: 4 (track ID for mkvmerge & mkvextract: 3)
|  + Track type: subtitles
|  + Language: spa
|  + Track number: 5 (track ID for mkvmerge & mkvextract: 4)
|  + Track type: subtitles
|  + Language: spa
Mucho mejor, así vemos los traks (pistas) y el idioma. Ahora podemos actuar de dos formas:

1- Eliminación del track en no-español:

Con lo que ademas el archivo resultante ocuparía un poco menos. Del archivo anterior, queremos las pistas 0, 2, 3 y 4, vamos las que están en español:
mkvinfo archivo_EN-ES.mkv | grep -e "Track number" -e "Track type" -e "Language" | grep -B 2 spa
|  + Track number: 3 (track ID for mkvmerge & mkvextract: 2)
|  + Track type: audio
|  + Language: spa
|  + Track number: 4 (track ID for mkvmerge & mkvextract: 3)
|  + Track type: subtitles
|  + Language: spa
|  + Track number: 5 (track ID for mkvmerge & mkvextract: 4)
|  + Track type: subtitles
|  + Language: spa
Ahora me quedo sólo con el número de la pista:
mkvinfo archivo_EN-ES.mkv | grep -e "Track number" -e "Track type" -e "Language" | grep -B 2 spa | cut -f3 -d: | cut -f1 -d\) | sed 's/\ //g' | grep ^[0-9]
2
3
4
Fácil, ahora la pista de video:
mkvinfo archivo_EN-ES.mkv | grep -e "Track number" -e "Track type" -e "Language" | grep -B 1 video | cut -f3 -d: | cut -f1 -d\) | sed 's/\ //g' | grep ^[0-9]
0
Y ahora con un poco de magia linux:
echo $(echo 0:$(mkvinfo archivo_EN-ES.mkv | grep -e "Track number" -e "Track type" -e "Language" | grep -B 1 video | cut -f3 -d: | cut -f1 -d\) | sed 's/\ //g' | grep ^[0-9]) && echo $(for n in $(mkvinfo archivo_EN-ES.mkv | grep -e "Track number" -e "Track type" -e "Language" | grep -B 2 spa | cut -f3 -d: | cut -f1 -d\) | sed 's/\ //g' | grep ^[0-9]); do echo 0:$n; done)) | sed 's/\ /,/g'
0:0,0:2,0:3,0:4
jejeje grep, sed, cut ... ¿para qué más?, ahora podemos hacer el script /usr/local/bin/saca_mkv.sh:
#!/bin/bash
#desarrollado por Juanmol para http://rsppi.blogspot.com
echo se va a tratar el archivo $1/$2
if [ "$(echo "$2" | grep -i ".mkv" | wc -l)" = "1" ];
then
        echo es un mkv;
        if [ "$(mkvinfo "$1/$2"  | grep "Language: spa" | wc -l)" -gt "0" ];
        then
                echo y tiene idiomas espanoles;
                pistas=$(echo $(echo 0:$(mkvinfo "$1/$2" | grep -e "Track number" -e "Track type" -e "Language" | grep -B 1 video | cut -f3 -d: | cut -f1 -d\) | sed 's/\ //g' | grep ^[0-9]) && echo $(for n in $(mkvinfo "$1/$2" | grep -e "Track number" -e "Track type" -e "Language" | grep -B 2 spa | cut -f3 -d: | cut -f1 -d\) | sed 's/\ //g' | grep ^[0-9]); do echo 0:$n; done)) | sed 's/\ /,/g');
                echo las pistas son $pistas;
                mkvmerge -o "$3/$2" --track-order $pistas -a 2 -d 0 -s 3 -T --no-global-tags --no-chapters "(" "$1/$2" ")"
        else
                echo no tiene idiomas espanolos;
        fi
else
        echo no es un mkv;
fi
le damos permisos:
chmod +x /usr/local/bin/saca_mkv.sh
la forma de usarlo es:
saca_mkv.sh "/directorio/origen/" "nombre_del_video.mkv" "/directorio/destino/"
el proceso tarda entre 30 y 40 minutos en el RaspberryPi. En siguientes posts, usaremos este script de forma automática.

2- Reorganizar las pistas y priorizar las españolas

Si no queremos perder el idioma inglés, podemos reorganizar las pistas. El proceso es casi el mismo que el anterior, así que paso directamente al script /usr/local/bin/reorganiza_mkv.sh
#!/bin/bash
#desarrollado por Juanmol para http://rsppi.blogspot.com
echo se va a tratar el archivo $1/$2
if [ "$(echo "$2" | grep -i ".mkv" | wc -l)" = "1" ];
then
        echo es un mkv;
        if [ "$(mkvinfo "$1/$2"  | grep "Language: spa" | wc -l)" -gt "0" ];
        then
                echo y tiene idiomas espanoles;
                audios=$(echo $(mkvinfo "$1/$2" | grep -e "Track number" -e "Track type" -e "Language" | grep -b1 audio | grep "Track number" | cut -f3 -d\: | sed 's/\ //g' | sed 's/)//g') | sed 's/\ /,/g');
                subtitulos=$(echo $(mkvinfo "$1/$2" | grep -e "Track number" -e "Track type" -e "Language" | grep -b1 subtitles | grep "Track number" | cut -f3 -d\: | sed 's/\ //g' | sed 's/)//g') | sed 's/\ /,/g' | sed 's/\ /,/g' );
                spa=$(mkvinfo "$1/$2" | grep -e "Track number" -e "Track type" -e "Language" | grep -B2 -A1 "Language: spa" | grep -B1 "Track type: audio" | cut -f3 -d\: | sed 's/\ //g' | sed 's/)//g' | grep ^[0-9]);
                resto=$(echo $(mkvinfo "$1/$2" | grep -e "Track number" -e "Track type" -e "Language" | grep -B1 "Track type: audio"  | grep "Track number" | grep -v "mkvextract: $spa" | cut -f3 -d\: | sed 's/\ //g' | sed 's/)//g' | grep ^[0-9]) | sed 's/\ /,0\:/g' );
                resto_sub=$(echo $(mkvinfo "$1/$2" | grep -e "Track number" -e "Track type" -e "Language" | grep -b1 subtitles | grep "Track number" | cut -f3 -d\: | sed 's/\ //g' | sed 's/)//g') | sed 's/\ /,0\:/g');
                video=$(mkvinfo "$1/$2" | grep -e "Track number" -e "Track type" -e "Language" | grep -B 1 video | cut -f3 -d: | cut -f1 -d\) | sed 's/\ //g' | grep ^[0-9]);
                mkvmerge -o "$3/$2.mkv" --track-order 0:$video,0:$spa,0:$resto,0:$resto_sub -a $audios -d 0 -s $subtitulos -T --no-global-tags --no-chapters "(" "$1/$2" ")"
        else
                echo no tiene idiomas espanolos;
        fi
else
        echo no es un mkv;
fi
le damos permisos:
chmod +x /usr/local/bin/reorganiza_mkv.sh
la forma de usarlo es:
reorganiza_mkv.sh "/directorio/origen/" "nombre_del_video.mkv" "/directorio/destino/"
el proceso tarda entre 30 y 40 minutos en el RaspberryPi. En siguientes posts, usaremos este script de forma automática.

4 comentarios:

  1. Por favor Juanlu !!! Qué me sangran los ojos!! Usa Perl o Python !!

    Estás hecho un artista!
    Saludos!
    PD: A ver unos consejos:
    1 Usa -q en grep:
    if [ "$(mkvinfo "$1/$2" | grep "Language: spa" | wc -l)" -gt "0" ];
    ==
    if mkvinfo "$1/$2" | grep -q "Language: spa";

    2 Antes de perl / python .. usa awk .. (una vez que te manejes salta a perl / python). Por ponerte un ejemplo:
    |awk '/Track number/ {track=$5-1; lang=""}
    /Track type/ {type=$5}
    /Language/ {lang=$4}
    lang ~ /spa/ {print track,type,lang;}'

    3. Dale al intro cuando la línea se te vaya de desmadre, justo después del pipe "|", no pasa nada y es más legible !

    ResponderEliminar
    Respuestas
    1. muy bueno lo del grep -q lo usaré a partir de ahora, pero me mola mas el mio, ya que te permite cambiar de filtro o comando para filtrar, sin saber si el nuevo filtro tiene salida "silenciosa", de forma que te permite hacer millones de cambios sin tener ni idea de todas las opciones de los comandos, que es lo que me pasa a mi ;) Pero insisto, a partir de ahora usare -q en los greps.
      Y me pasa más o menos lo mismo con perl y python, es aprender más ... yo soy feliz con mis 4 comandos ... no hay tiempo ni neuronas libres para aprender más lenguajes.
      Casi siempre que hago una burrada de estas pienso "Javi seguro que hace esto mismo en una linea con dos parametros ..."

      Eliminar
  2. Gracias por compartirlo!

    ...y para incrustar la carátula y metadatos?

    Con XBMC (o raspbmc en este caso), podemos exportar todos los metadatos que el scrapper nos ha encontrado, de tal forma que nos deja en cada carpeta de la película todas las carátulas, fanarts... y metadatos en un archivito .nfo

    Gracias!!

    ResponderEliminar
    Respuestas
    1. estoy en ello, a ver si para este fin de semana.

      Eliminar