Generar pantallazo de un vídeo.

La íºltima función que he tenido que crear para un proyecto era una para generar un pantallazo en jpg de un fotograma de un ví­deo .flv. No recuerdo en qué web encontré la respuesta, pero pasaba por utilizar ffmpeg.

Este es el método que me ha quedado:

function Genera_Pantallazo($origen,$fotograma) {
	$destino=substr_replace($origen,".jpg",-4);
								       
	$segundos=$fotograma;
	$horas = intval($segundos/3600);
	$segundos -= $horas*3600;
	$minutos = intval($segundos/60);
	$segundos -= $minutos*60;
	$tiempo=$horas.":".$minutos.":".$segundos;
				
	$comando="ffmpeg -i $origen -vcodec mjpeg -ss $tiempo -vframes 1 -f image2 $destino";

	// echo "Ejecutamos $comando
"; <--- Para comprobar que formábamos bien el comando exec($comando); return basename($destino); }

Como véis, es bastante sencillo. Recibimos 2 variables: la ruta origen al fichero de ví­deo y el níºmero del segundo del que queremos generar el pantallazo. Lo primero que hacemos es especificar la ruta destino, que será la misma que la de origen, pero cambiando la extensión a .jpg.

Después realizamos el cálculo de horas, minutos y segundos a partir de los segundos que hemos pasado, para componer una cadena del tipo HH:MM:SS, que es la que pasaremos, a continuación, a ffmpeg, al cual le indicamos el codec de salida, el níºmero de frames (1 para el pantallazo) y las rutas.

Por íºltimo, devuelvo el nombre del fichero generado. Modificar al gusto ;)

Primera experiencia con ExtJS

Y lo que me ha costado. Ya me habí­an avisado que utilizar ExtJS era jodido, sobre todo al principio. Alguna vez habí­a que ponerse…

En resumen, lo que tení­a que hacer un grid selector de los ficheros de un directorio, para una vez seleccionado actualizar un registro de una tabla de una base de datos.

Lo primero era, como no, incluir en el html (en mi caso, en una plantilla de smarty .tpl), los enlaces a los ficheros css y js de extjs, además del enlace al script ficheros_server.js, éste de creación propia, que utilizaremos para mostrar el grid selector de ficheros.

link rel="stylesheet" type="text/css" href="{$includes_dir}js/ext-2.0.2/resources/css/ext-all.css" /> 
script type="text/javascript" src="{$includes_dir}js/ext-2.0.2/adapter/ext/ext-base.js">
script type="text/javascript" src="{$includes_dir}js/ext-2.0.2/ext-all.js">
script type="text/javascript" src="{$includes_dir}js/ficheros_server.js">

Lo segundo a modificar es el archivo .php que llama a la plantilla, y al cual añadiremos un caso para que devuelva el listado de ficheros de un directorio, tal que así­:

case 'listado_ficheros_json':
	$ficheros=json_encode($objFichero->ListadoFicherosServer($ruta));
	echo'({"results":'.$ficheros.'})';
	exit();
	break;

Lo íºnico que hemos hecho es llamar al método ListadoFicherosServer, con la ruta que queramos, y devolver, y esto es lo importante, el array codificado con json de resultados, con la forma {“results”: [array_ficheros]}. Es importante la sintaxis de esta lí­nea, ya que es la que va a tratar ficheros_server.js para obtener el listado de ficheros.

El método ListadoFicherosServer incluye lo siguiente:

function ListadoFicherosServer($directorio) {
	$dir_item='';
	$archivos=array();
		
	$dir=opendir($directorio);
	$i=0;
	while($dir_item=readdir($dir)) {
		if(is_file($directorio."/".$dir_item)) {
     $archivos[]=array("nombre"=>$dir_item,"tamanyo"=>filesize($directorio."/".$dir_item),"fecha"=>date("Y-m-d H:i:s", filemtime($directorio."/".$dir_item)));
	        }
	        $i++;
        }
	return $archivos;
}

Como véis, en el array de archivos devuelvo tres campos: el nombre, el tamaño y la fecha.

Ahora viene el tema, el ficheros_server.js :D Lo pongo y lo explicamos:

Ext.onReady(function() {

	var myRecordObj = Ext.data.Record.create([
            {name: 'nombre', sortDir: 'ASC'},
            {name: 'tamanyo', type: 'float'}, 
            {name: 'fecha', type: 'date', dateFormat: 'Y-m-d H:i:s'}
         ]);
 
	var myReader = new Ext.data.JsonReader({
		root: 'results',
		id: 'nombre'},
		myRecordObj
	);
	
	var myDataStore = new Ext.data.Store({
		proxy: new Ext.data.HttpProxy({
                url: 'comun_ficheros.php', 
                method: 'POST'
            }),   
            baseParams:{a: "listado_ficheros_json"},
            reader: myReader,
            sortInfo:{field: 'nombre', direction: "ASC"}
        });
 	
 	myDataStore.load();
 	
	var grid = new Ext.grid.GridPanel({
		store: myDataStore,
		columns: [
			{header: 'Archivo', width: 120, sortable: true, dataIndex: 'nombre'},
			{header: 'Tamaño', width: 90, sortable: true, dataIndex: 'tamanyo'},
			{header: 'Fecha', width: 120, sortable: true, 
				renderer: Ext.util.Format.dateRenderer('m/d/Y'), 
	                        dataIndex: 'fecha'}
		],
		viewConfig: {
			forceFit: true
		},
		renderTo: 'ficheros_server',
		title: 'Listado de archivos en el servidor',
		width: 350,
		frame: true,
		border: true
	});
 
 	grid.on('rowclick', function(grid){
		var record=grid.getSelectionModel().getSelected();
		Ext.get('fichero').dom.value=record.get('nombre');});	
});

Lo primero que hacemos en el .js es crear un objeto Record, con tres campos (los mismos que vamos a devolver en el array): el nombre, el tamaño y la fecha. Tras esto, creamos un objetos Lector de json, para leer la cadena que devuelve el .php anterior, indicando que el root va a ser “results” (lo que devolví­amos en el php al principio), que el campo identificador va a ser el nombre, y que lo que lea, lo guarde en el objeto Record que hemos creado anteriormente.

Una vez tenemos el lector y el objeto Record, creamos el almacén de datos. Lo primero que definimos es de donde obtenemos los datos, en este caso a través de una llamada al fichero php donde hemos añadido el caso para devolver el array de ficheros. Con baseParam pasamos las opciones que queramos, en este caso a=listado_ficheros_json, que será el caso del php. Por íºltimo, indicamos que lector vamos a utilizar y la ordenación de los datos. Una vez creado el objeto, lo cargamos con los datos mediante el método .load().

Ya tenemos todos los ficheros en el almacén de datos, sólo nos falta dibujar el grid selector con esos datos dentro. Esto es lo más sencillo: creamos un objeto GridPanel, indicando, primero, que los datos están en el almacén de datos recién cargado; segundo, las columnas del grid panel, y tercero diferentes opciones de visualición, entre ellas, y quizás la más importante, renderTo, que será el id del div donde queremos dibujar el grid.

Finalmente, añadimos un evento al grid, el “rowclick”, que lo íºnico que hace es cambiar el valor de un campo del html con el nombre del fichero que hayamos pinchado en el grid.

Visto así­ parece fácil, pero hasta dar con todas las cosillas, ufff.

Seguiré contando mis aventuras con ExtJS… ;)

El nuevo MacBook Air…

Habí­a mucha espectación ayer con la Keynote del tito Jobs. Al final, unas cuantas novedades, nada impresionantes. Lo que más ha llamado la atención ha sido el Macbook Air, el cual no me acaba de convencer: poquí­sima conectividad, no se puede ampliar y es cariiiií­simo. Antes me compro el Asus EEE por 300 euros. Me quedo con mi Macbook sin dudarlo ;)

La imagen, de Gizmodo:

comparacion_macbook_air.jpg

Ideas en mente: JS y PHP por un tubo

Llevo varias semanas intentando ponerme y nunca lo hago. Por un lado, quiero aprender “bien”, de una vez, JavaScript y, de paso, echarle un ojo tanto a ExtJS (las malas compañí­as…) como a famosas librerí­as JS tipo jQuery o Prototype.

De paso, quiero meterme a fondo con algíºn framework PHP, seguramente Symfony, aunque no descarto CakePHP o Zend Framework (¿alguna sugerencia para inclinarme por uno de ellos?).

Y para practicar un poco de todo esto, llevarlo a la práctica mediante el desarrollo de una aplicación web para la gestión de aulas-alumnos-clases tipo Siestta.

Ya veremos en qué queda todo, si en sólo buenas intenciones o en algo más… :D

Un par de aplicaciones para Mac OSX: Sapiens y Anxiety

Las dos íºltimas aplicaciones que he instalado en Leopard y que creo se van a quedar un tiempo, por la buena pinta que tienen, son Sapiens y Anxiety, las dos en su versión 1.0.

Primero, Sapiens, un lanzador de aplicaciones muy rápido, que se puede abrir mediante un gesto con el ratón (por defecto, un cí­rculo) o con una combinación de teclas. Esto íºltimo le hace perder un poco de gracia, es como si abriera spotlight para utilizarlo como lanzador. La ventaja respecto a esta opción es que no tocas el teclado en ningíºn momento, a no ser que la aplicación que quieras utilizar no esté en el meníº que aparece. Se “supone” que Sapiens va aprendiendo de tus usos y presenta las aplicaciones que más probabilidades tienes de utilizar. En caso de no aparecer, igual que en Spotlight: introduces las primeras letras del nombre de la aplicación y la muestra.

sapiens.jpg

La segunda aplicación es Anxiety, un programa para anotar tareas pendientes, y que se integra perfectamente con iCal o Mail. Muy rápido, lo puedes dejar en la barra de meníºs y acceder en un segundo para realizar cualquier anotación.

anxiety.jpg

ImageWell, realmente útil

A través de Denken íœber descubro esta pequeña maravilla de programa, ImageWell, para todos los que tenemos que estar manejando imágenes continuamente y realizar operaciones sencillas con ellas. Es muy ligero, muy rápido y con las funciones más utilizadas: cambiar tamaño, recortar, editar… hasta capturar la pantalla o una zona de ella rápidamente. A partir de hoy, uno de mis imprescindibles en Mac OSX.

imagewell.jpg

Leopard 10.5.1 y VMWare Fusion 1.1

Dos actualizaciones en poco tiempo, Leopard ayer a la versión 10.5.1 y VMWare Fusion a la versión 1.1.

Primero Leopard, instalado hace un par de semanas: instalación limpia, sin ningíºn tipo de problema. Y muy bien, muy muy rápido (da la sensación de ir más suelto que Tiger) y con algunas mejoras considerables respecto a Tiger: el visor rápido funciona de maravilla y spotlight ha mejorado una barbaridad, nada que ver con el anterior, realizando maravillosamente la función de lanzador de aplicaciones (que antes realizaba con Quicksilver). Visualmente no ha cambiado mucho, dirí­a que en algunas cosas a peor, como el dock y la barra tridimensionales-semitransparentes… Ayer se actualizó a la versión 10.5.1 y, la verdad, no he notado ningíºn cambio apreciable, todo sigue igual de bien ;)

Y hace unos dí­as VMWare Fusion. La versión 1.0 funcionaba de maravilla y, no sé si es por actualizar máquinas que estaban ya configuradas, al actualizar a la versión 1.1 todo va más lento. No muy muy lento, pero sí­ que se nota, y por lo que he leido en los foros, creo que no soy al íºnico al que le pasa. Me falta probar con máquinas virtuales nuevas (tengo por ahí­ ArchLinux esperando), pero me da que se comportará igual. Espero que arreglen pronto esos pequeños fallos, utilizo bastante las máquinas virtuales para dar clase y mostrar los diferentes sistemas operativo…

Acceder a carpetas compartidas en NT desde Windows Vista

Vaya historia, me he tirado buena parte de la tarde intentando acceder desde un portátil nuevo, con Windows Vista Home Basic, al servidor donde tenemos compartidos todos los documentos de la empresa, que está bajo Windows NT 4.0.

No habí­a manera: aparecí­a el cuadro de diálogo pidiendo usuario y contraseña, pero siempre daba error de autentificación. Buscando por SanGoogle siempre encontraba la solución de modificar la polí­tica local cargando secpol.msc y bla, bla, bla… el tema es que Vista ha actualizado su método de autentificación a NTLM v2, que no es compatible con NT (y SAMBA…), por lo que hay que cambiarlo al NTLM anterior.

Problema: Vista Home Basic no tiene el editor de polí­ticas de seguridad secpol.msc, por lo que hay que tocar directamente el registro. Finalmente he encontrado la clave de registro correcta en el blog HermanoTemblon (muchí­simas gracias).

Solución: Abrir el editor del registro (regedit) y cambiar en
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa el valor de LmCompatibilityLevel a 1 (en lugar de 3, que viene por defecto). Reinicio del sistema y listo.