Contenido

Web SQL Database, tu base de datos en HTML5

22 Feb

+ 18

HTML5 nos introduce la posibilidad de disponer de un base de datos local almacenada en el navegador del usuario. Mediante Web SQL Database, la W3C ofrece una API estándar destinada a manipular bases de datos en el lado del cliente mediante peticiones SQL de forma asíncrona. Un complemento ideal al Almacenamiento DOM que ya hemos visto en otras ocasiones.

Al igual que Google Gears SQL, con HTML5 será posible realizar peticiones complejas mediante SQL. Los chicos de HTML5Rocks ha creado una pequeña aplicación de ejemplo que funciona sobre Google Chrome y de la que he podido crear una pequeña versión reutilizable que podremos usar en nuestras aplicaciones web.

var webdb = {};
webdb.db = null;

// Función para crear la base de datos
webdb.open = function(options) {
	if (typeof openDatabase == "undefined") return;

	// Opciones por defecto
   	var options = options || {};
	options.name = options.name || 'noname';
	options.mb = options.mb || 5;
	options.description = options.description || 'no description';
	options.version = options.version || '1.0';

	// Definimos el tamaño en MB
   	var dbSize = options.mb * 1024 * 1024;

	// Cargamos la base de datos
   	webdb.db = openDatabase(options.name, options.version, options.description, dbSize);
}
// ExecuteSql
webdb.executeSql = function(sql, data, onSuccess, onError){
	if (!webdb.db) return;
	webdb.db.transaction(function(tx){tx.executeSql(sql, data,onSuccess,onError);});
}

Este código, nos permite realizar peticiones SQL tales como crear una nueva tabla, leer, borrar o modificar de ella, está claro que únicamente en los navegadores que lo permitan.

// Ejemplo
var opt = {
	name: "ejemplo",
	mb: 1,
	description: "Base de datos de ejemplo",
	version: "1.0"
};

// Abrimos la base de datos
webdb.open(opt);

// Creamos la tabla
webdeb.executeSql('CREATE TABLE IF NOT EXISTS ejemplo (ID INTEGER PRIMARY KEY ASC, texto TEXT, added_on DATETIME"', [],
			function(tx, r){
				alert("Tabla creada");
			},
			function(tx, e){
				alert("Se ha producido un error: "e.message);
			});

// Insertamos un nuevo elemento
webdb.executeSql('INSERT INTO ejemplo (texto, added_on) VALUES (?,?)', ['Mensaje de ejemplo', new Date()],
			function(tx, r){
				alert("Elemento introducido");
			},
			function(tx, e){
				alert("Se ha producido un error: "e.message);
			});

Esto nos permitirá crear aplicaciones más complejas gracias al almacenamiento de datos en la capa del cliente. Eso si, será mucho más útil cuando todos los navegadores lo incorporen :D

Plupload, sube ficheros como quieras, pero súbelos

10 Feb

+ 3

Ajaxian publica un artículo sobre Plupload, una aplicación Javascript que nos permite seleccionar de entre una serie de opciones posibles las herramientas con las que queremos permitir subir ficheros a nuestros usuarios.

  • Google Gears
  • Silverlight
  • Flash
  • BrowserPlus
  • HTML5

Simplemente tendremos que especificar uno o varios de ellos y los parámetros necesarios para poder cargar las herramientas necesarias para cada tecnología.

var uploader = new plupload.Uploader({
	runtimes : 'gears,html5,flash,silverlight,browserplus',
	browse_button : 'pickfiles',
	max_file_size : '10mb',
	resize : {width : 320, height : 240, quality : 90},
	url : 'upload.php',
	flash_swf_url : '/plupload/js/plupload.flash.swf',
	silverlight_xap_url : '/plupload/js/plupload.silverlight.xap',
	filters : [
		{title : "Image files", extensions : "jpg,gif,png"},
		{title : "Zip files", extensions : "zip"}
	]
});

Tenemos una API disponible y un ejemplo para verlo funcionando.

Sketchpad, paint online con tecnología HTML5

10 Feb

+ 4

Hace unos días descubrí via delicious, Sketchpad, un paint enriquecido completamente online que se aprovecha de las nuevas herramientas que HTML5 pone a nuestra disposición.

sketchpad
(Ver Imagen)

El resultado, como se puede ver, es realmente sorprendente. No solo por lo elegante del diseño, sinó por la soltura con la que se mueve y las posibilidades que ofrece:

  • Uso de degradados
  • Uso de patrones
  • Paleta de colores
  • Historial de modificaciones
  • Posibilidad de salvar el dibujo con Data URI

Sin duda una muestra lo que nos vamos a ir encontrando por Internet en un futuro no muy lejano.

Gordon, el reproductor flash en Javascript

2 Feb

+ 7

Mucho se está hablando de la muerte de Flash con la llegada de HTML5, principalmente por que sitios como YouTube o Vimeo están implementando ya versiones del tag <video /> de HTML5 en ciertas secciones y para navegadores que lo soporten. Aunque Adobe parece no verlo igual.

Por otro lado, Tobias Scheneider ha desarrollado “Gordon“, una implementación en Javascript de un reproductor de Flash usando SVG para ello.

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
	<head>
		<script type="text/javascript" src="../gordon.js"></script>
		<script type="text/javascript">
 			window.onload = function(){
 				// Opciones
 				var opt = { id: 'stage', // ID del contenedor
 					width: 500,
 					height: 400};

 				// Definimos la nueva película
 				new Gordon.Movie('blue.swf', opt);
 			}
		</script>
	</head>
 	<body>
 		<div id="stage"></div>
 	</body>
</html>

El resultado es realmente sorprendente, y podemos disfrutar de algunos ejemplos directamente aquí (aún está un poco verde y solo está disponible para Firefox y WebKit). Además, tenemos disponible el código en GitHub.

HTML5 Video, más problemas de estándares

26 Ene

+ 8

HTML5 ha llegado, y aunque sea pronto para que el usuario pueda disfrutar de todo su potencial, los desarrolladores hace ya unos meses que podemos ir viendo lo que será el Internet de dentro de unos años.

El tag <video /> es el que más revuelo está teniendo, y no solo por su integración en sitios como Youtube o Vimeo, sinó por los estándares soportados por cada navegador.

Mozilla se ha puesto firme al respecto y ha anunciado que no piensa incluir el estandar h264, ya que este no es un codec abierto y existen otros que si lo son (y como vimos ofrecen mejor calidad).

Esto nos deja en una situación en la que los navegadores web que actualmente soportan el tag <video /> de HTML5:

  • Presto/Opera: HTML5 mediante GStreamer (incluye sólo Ogg/Theora).
  • WebKit/Chrome: HTML5 mediante ffmpeg (Ogg/Theora y H.264/MP4).
  • Gecko/Firefox: HTML5 con Ogg/Theora.
  • WebKit/Epiphany: HTML5 mediante GStreamer (Ogg/Theora garantizado).
  • WebKit/Safari: HTML5 mediante QuickTime (H.264/MOV/M4V, puede reproducir Ogg/Theora con XiphQT components).

Nos encontramos frente a una guerra en la que empresas como Apple y Microsoft, forman parte de la MPEG-LA, empresa que tiene la patente del codec h264, frente a Mozilla (por el momento) que se ha posicionado en contra de usar una tecnología propietaria que condicione la red.

Las palabras de Asa Dotzler no pueden ser más claras:

La web no sería lo que es hoy si cada blogger tuviera que pagar por una licencia para publicar imágenes y texto en una página. Los vídeos tampoco tendrían que requerir el pago de licencias.

La Free Software Fundation pone a nuestra disposición la página de sugerencias de Google para que votemos por el uso de estándares libres en Youtube. No dudes en dejar tu voto.

Por una internet más libre y menos controlada por las patentes.

Añade subtítulos a tus videos con Javascript

14 Ene

+ 6

El tag <video /> del nuevo estándar HTML5 cada día nos sorprende más y es que aunque se detectaron problemas a la hora de interpretar el estandar en los diferentes navegadores, cada nueva noticia sobre él aporta una idea interesante.

Bruce Lawson, gurú de HTML5, nos ofrece una interesante implementación que nos ofrece subtítulos a nuestros videos mediante Javascript.

HTML

La principal ventaja que nos ofrece esta técnica es que nos permite tener elementos HTML con el texto del video en nuestra página, que aunque nos hará páginas más largas y pesadas, nos permite ofrecer a usuarios sin capacidad de reproducir videos una solución alternativa (aunque no completa) de saber de que vá el video.

<video width=600 src="leverage-a-synergy.ogv" ontimeupdate="timeupdate()"
 style="background:black" autobuffer controls>
 <p>This page is to demonstrate open HTML5 video, so if you're not using a
 browser that can display the open Ogg Theora codec, there's not  much to see. Sorry!</p>
 </video>
 <div id="transcript">
 <h3>Transcript</h3>
 <p>
 <span data-begin=1 data-end=6>Hi, my name's Dr Archimedes Einstein and I'm a Doctor of Science at the University of Science</span>
 <span data-begin=6 data-end=9>in a very famous town that you're too stupid to have heard of.</span>
 <span data-begin=9.5 data-end=11.5>Anyway, today we're going to talk about "synergies".</span>
 <span data-begin=12 data-end=15>A lot of people are worried about synergies, but I can tell you that</span>
 <!-- ... -->
 </p>
 </div>

Como podemos ver, se trata de una estructura bastante lógica, un video y una serie de líneas con el texto que compone la transcripción de dicho video. Hay que destacar la función timeupdate() que se ejecutará en el evento ontimeupdate del elemento <video /> (que vemos en negrita), ya que es la encargada de hacer mágia y convertir ese texto en los subtítulos del video.

Por otro lado, en el texto podemos ver que los <span /> ofrecen información sobre cuando deben empezar y terminar cada línea, vinculando los data-begin y data-end al tiempo de reproducción del video medianante los atributos data disponibles en el estandar.

Javascript

Ahora necesitamos que el texto y el video se entrelazen y ofrezcan el resultado que estamos buscando, para ello primero hemos de cargarlo y posteriormente ir actualizando el texto a medida que el video va reproduciendose.

var captions = [];
window.onload = function() {
  var caption = document.createElement('div');
  caption.id = 'caption';
  // Cargamos el primer elemento
  var ref = document.getElementsByTagName('video')[0];
  ref.parentNode.insertBefore(caption, ref.nextSibling);

  // Cargamos todos los subtítulos
  var nodes = document.querySelectorAll('#transcript span');
  for (var i = 0; i < nodes.length; i++) {
    // Generamos un objeto con la información de cada línea
    var c = {'start': parseFloat(nodes[i].getAttribute('data-begin')),
             'end': parseFloat(nodes[i].getAttribute('data-end')),
             'text': nodes[i].textContent};
    captions.push(c);
  }
}
// Función que actualizar el texto dependiendo del tiempo
function timeupdate() {
  var v = document.querySelector('video');
  var now = v.currentTime;
  var text = "";
  for (var i = 0; i < captions.length; i++) {
    if (now >= captions[i].start && now <= captions[i].end)
    {
      text = captions[i].text;
      break;
    }
  }
  document.getElementById('caption').innerHTML = text;
}
// Ocultamos los subtítulos
document.write('<style>#transcript{display:none}</style>');

Al terminar de cargar la página, recogemos los textos y los almacenamos en una variable global en un formato más cómodo para trabajar con él. En la función timeupdate(), que recordemos usamos en el evento ontimeupdate del tag <video /> nos irá comprobando los cambios y actualizando el mensaje visible a medida que va transcurriendo el tiempo de reproducción.

Para terminar, ocultamos el texto mediante Javascript ya que en caso de no estar disponible, además de no aplicar ninguna de las funcionalidades anteriores nos permitirá visualizar el texto perfectamente.

CSS

Los estilos nos permiten ubicar los subtítulos en el video, y además podremos especificar el tamaño, color y fuente de ellos.

#caption {
 position: absolute;
 width: 100%;
 bottom: 0;
 bottom:30px; /* space for the video controls */
 left: 0;
 text-align: center;
 font-family: sans-serif;
 font-weight: bold;
 color: white;
 text-shadow: black 1px 1px 3px;
 padding-bottom: .5em;
}
#transcript span {display:table-row;}

Básicamente, lo que estamos haciendo es ubicar el texto al pie del video, dejando espacio para los controles.

Bruce, además incluye unos estilos que nos inserta información extra para ciertos usuarios al mostrar mediante CSS información del tiempo de inicio y fin de los textos leyendo directamente de los atributos.

#transcript [data-begin]:before{
  content: " [" attr(data-begin) "s-" attr(data-end)"s]   ";
  font-size:80%;
  display:table-cell;
  padding-right:1em;
}

Resultado

video-span
(Ver Imagen)

El resultado es realmente sorprendente ya que no tiene nada que envidiarle (a este nivel) a los reproductores de escritorio.

Actualización (17:00)

Nukeador me muestra otro sistema, también basado en Javascript que además de permitir conseguir el mismo efecto nos permitirá usar los ficheros .srt que tenemos disponibles por Internet.

video-srt
(Ver Imagen)

Un sistema basado en la lectura mediante Ajax de ficheros .srt (SubRip) y de un posterior parseo para obtener el tiempo y el texto que mostraremos como subtítulo.

Fichero srt

Si alguna vez has necesitado ver una película con subtítulos, te habrás encontrado con que has tenido que descargar un fichero .srt para poder verla. Eso es por que existen una gran cantidad de herramientas que permiten la edición de subtítulos fácilmente con la obtención de este tipo de ficheros. Además, es soportado por la mayoría de todos los reproductores multimédia.

...
5
00:00:07,100 --> 00:00:09,000
Tiene subtitulos son en Español

6
00:00:09,100 --> 00:00:10,500
Gracias a las nuevas technologias

7
00:00:10,500 --> 00:00:20,000
<img src="foo.png"/><img src="foo.png"/><img src="foo.png"/> Gracias! <img src="foo.png"/><img src="foo.png"/><img src="foo.png"/>
....

El formato de un fichero .srt nos permite generar estructuras como las que vemos. Como podemos ver, se trata de un sistema muy cómodo y a mi entender más correcto que el presentado por Bruce.

jai, jugando con audio desde Javascript

13 Ene

+ 1

La llegada de HTML5 nos mostró el elemento <audio /> que nos permite hacer que el navegador se convierta en un reproductor de audio con Javascript como controlador. Aprovechando esta nueva característica del lenguaje aparece jai que nos permite generar listados gráficos de las canciones encontradas en nuestra página.

<!-- HTML -->
<div id="jai">
  <canvas id="jai-transport" width="320" height="20"></canvas>
  <ul>
   <li><a href="@F1LT3R - Cryogenic Unrest.ogg" title="Play">F1LT3R - Cryogenic Unrest<span title="Download"></span></a><audio src="@F1LT3R - Cryogenic Unrest.ogg">Your browser does not support the <code>audio</code> element. Get <a href="http://www.mozilla.com/en-US/firefox/all-beta.html">Firefox 3.5</a>.</audio></li>
   <li><a href="@F1LT3R - Ghosts in HyperSpace.ogg">F1LT3R - Ghosts in HyperSpace</a><audio src="@F1LT3R - Ghosts in HyperSpace.ogg">Your browser does not support the <code>audio</code> element. Get <a href="http://www.mozilla.com/en-US/firefox/all-beta.html">Firefox 3.5</a></audio></li>
   <li><a href="@F1LT3R - SOS Distress.ogg">F1LT3R - SOS Distress</a><audio src="@F1LT3R - SOS Distress.ogg">Your browser does not support the <code>audio</code> element. Get <a href="http://www.mozilla.com/en-US/firefox/all-beta.html">Firefox 3.5</a></audio></li>
   <li><a href="@F1LT3R - Disturbed Orbit.ogg">F1LT3R - Disturbed Orbit</a><audio src="@F1LT3R - Disturbed Orbit.ogg">Your browser does not support the <code>audio</code> element. Get <a href="http://www.mozilla.com/en-US/firefox/all-beta.html">Firefox 3.5</a></audio></li>
   <li><a href="@F1LT3R - Binary Lovers.ogg">F1LT3R - Binary Lovers</a><audio src="@F1LT3R - Binary Lovers.ogg">Your browser does not support the <code>audio</code> element. Get <a href="http://www.mozilla.com/en-US/firefox/all-beta.html">Firefox 3.5</a></audio></li>
  </ul>
</div>

El script es muy limitado en cuanto a configuración se refiere, ya que nos obliga a usar una estructura similar a la mostrada arriba, pero se encarga de renderizar mediante un elemento <canvas /> el listado de elementos <audio /> detectados en la página permitiendo disponer de un reproductor avazando en nuestra aplicación.

Todo lo que necesitas saber sobre los formularios HTML5

9 Ene

+ 5

En DiveintoHTML5 nos muestran todo lo que necesitamos saber sobre los formularios HTML5 y las novedades que podremos llegar a usar en cuando estén más extendidas entre los principales navegadores. Artículo realmente interesante y recomendado.

Aplicaciones web offline, para que la conexión no sea problema

9 Ene

+ 2

Las aplicaciones web, como su nombre indican son aplicaciones ligadas a la Web, eso significa que necesitaremos una conexión a Internet para poder acceder a ellas.

Ya hace unos años Google se adelantó a esta necesidad ofreciendo Google Gears como solución a este problema, esencialmente se componía de ofrecer la posibilidad de usar una base de datos local (usando SQLite) y un almacenaje de HTML/JS/CSS en local permitiendo que nuestras aplicaciones pudieran trabajar en modo offline.

Se crearon una gran cantidad de utilidades que aprovechaban estas nuevas características de las aplicaciones web. Pero no era oro todo lo que relucía, esta maravilla requería una instalación por parte del usuario para poder disfrutar de ellas, igual que para disfrutar de aplicaciones Flash.

HTML5 introduce el almacenamiento DOM, algo de lo que ya hemos hablado en infinidad de ocasiones, y es que estas cookies avanzadas nos dan mucho juego y al depender del navegador nos ahorra tener que hacer que el usuario haya de actualizar nada, simplemente el navegador (algo que generalmente se hace automáticamente).

Mozilla Hacks desarrolla una aplicación a modo de demostración que nos permite disponer de una lista de tareas alojada en nuestro navegador, podéis verla aquí.

Cacheamos datos

Para cachear nuestros datos tenemos una serie de métodos DOM que ya hemos visto anteriormente.

function sendLocalStatus() {
	// Leemos el estado en local
  	var status = readStatus();

	// Si hay estados
  	if (status) {
		// Lo enviamos al server online
    	sendToServer(status);

		// Borramos la copia local
    	window.localStorage.removeItem("status");
  	}
}

// Evento onload
window.addEventListener("load", function() {
	// Comprobamos que estemos online
   	if (navigator.onLine) {
		// Si lo estamos enviamos datos de local
		// así actualizamos los cambios hechos offline
		// en nuestro servidor online
     	sendLocalStatus();
   	}
}, true);

// Evento online
window.addEventListener("online", function() {
	// Evento que se activa cuando detecta que estamos online
  	sendLocalStatus();
}, true);

// Evento offline
window.addEventListener("offline", function() {
	// Evento que detecta cuando perdemos la conexión
  	alert("You're now offline. If you update your status, it will be sent when you go back online");
}, true);

Como podemos ver, el navegador nos ofrece una serie de eventos que nos permiten controlar el estado de nuestra conexión, de esta forma, podemos enviar los datos modificados cuando estamos desconectados para ser enviados a nuestros servidores al recuperar la conexión.

Cacheando ficheros

Por otro lado, tenemos los ficheros HTML/CSS/JS que debemos cachear para que nuestra aplicación funcione en modo offline. Para ello, usamos un fichero Manifest que indica que ficheros deben ser cacheados:

// HTML
<html manifest="offline.manifest">

// offline.manifest
CACHE MANIFEST
fonts/MarketingScript.ttf
css/main.css
css/fonts.css
img/face.gif
js/main.js
index.xhtml

En resumen, una serie de herramientas muy útiles para enriquecer cualquier aplicación web. Por que la conexión no debería ser una limitación :D

HTML5 video con problemas en todos los navegadores

24 Dic

+ 4

Hace ya un tiempo que vimos que el nuevo HTML5 nos ofrecía un nuevo tag HTML destinado al contenido multimedia, concretamente para los vídeos. Este tag, aparece para reemplazar a Flash como reproductor de video y además nos permitirá que el navegador gestione el vídeo directamente. Pero al parecer, las implementaciones actuales no funcionan todo lo bien que deberían.

Como todos sabemos, Internet Explorer no lo soporta, algo que no nos sorprende pero nos fastidia. Por otro lado, el tag dispone de un atributo que especifica que el vídeo debe autodescargarse a modo de buffer, este atributo no es tratado por todos los navegadores de igual forma, Google Chrome y Safari si que lo soportan pero empiezan a descargar los videos ignorando la inclusión del atributo en cambio, Firefox si que detecta este atributo y lo tiene en cuenta para auto-iniciar la descarga.

<video controls autobuffer>
<source type="video/mp4" src="http://videos.mozilla.org/serv/blizzard/video-brownbag/video-codec-discussion.m4v"/>
<source type="video/ogg" src="http://videos.mozilla.org/serv/blizzard/video-brownbag/video-codec-discussion.ogv"/>
</video>

Como podemos intuir, el problema llega en forma de tiempo de carga innecesario de vídeos que posiblemente no queramos ver.

Al parecer el problema radica en la especificación de la W3C que especifica que el atributo puede ser ignorado por completo, algo que no debería alarmarnos ya que aún se trata de borrador en el que están trabajando y mejorando.