About admin

Sou nerd

Vote no BeerCheck.in no RailsRumble

Ola
Vc conhece o BeerCheck.in http://beercheck.in/ ?
É um site desenvolvido em 48 horas por amigos meus para a competição Rails Rumble.
Ele é muito simples: vc loga com a sua conta do twitter e ganha uma “estante” onde vc pode colocar as suas cervejas favoritas. Para que os outros vejam a sua estante basta acessar o seu perfil.
Se vc curtiu, vote no Beer Check.in no site do Rails Rumble.

http://railsrumble.com

A votação vai ate o dia 23. Acho que realmente vale a pena votar pois se em dois dias ficou maneiro, depois da competição muitas outras melhorias podem ser adicionadas! Sem falar que existem outras aplicações divertidas no railsrumble para vc votar, algumas feitas por Brasileiros.
o meu

http://beercheck.in/pac_man

Como saber se uma musica parou de tocar em html 5

Anteriormente vimos como descobrir que uma musica parou de tocar em ActionScript 3. Hoje em dia temos uma quantidade interessante de browsers que suportam alguma coisa de html 5 (safari, chrome, firefox…), portanto nada mais justo que analisar também esta solução.

Vejamos como tocar o nosso jazz.mp3

<audio id="mp3" src="jazz.mp3" type="audio/mpeg" controls/>

Apenas esta tag vai gerar um pequeno player com controles customizados pelo browser. E como saber que a musica parou? Basta escutar pelo evento ended

var mp3 = document.getElementById('mp3');
 
mp3.addEventListener('ended', function(){ 
	alert("fim"); 
});

Para customizar os controles basta omitir o atributo controls na tag audio e usar os métodos play e pause, por exemplo.

Um bom exemplo pode ser encontrado aqui:
http://ajaxian.com/archives/html5-media-support-video-and-audio-tags-and-scriptability

E documentação sobre html 5 vc encontra aqui:
http://www.w3schools.com/html5/html5_reference.asp

A tag video segue a mesma idéia, mas será assunto para um próximo post.

Como saber que uma musica acabou em actionscript

Para fazer um tocador de mp3, por exemplo, em actionscript 3, basta vc criar uma instância da classe Sound e invocar os métodos load e play para carregar o arquivo e toca-lo, respectivamente.

Porém como saber que a musica acabou? A classe sound possui um listener para o evento COMPLETE porém isto é para completar o donwload da musica, não o final da mesma. E ai, comofas/

Simples: o método play retorna uma instância SoundChannel que, por sua vez, possui um listener para o evento SOUND_COMPLETE, logo bastaria fazer

var snd:Sound = new Sound();
snd.load(new URLRequest("jazz.mp3"));
var channel:SoundChannel = snd.play();
channel.addEventListener(Event.SOUND_COMPLETE, 
      soundCompleteHandler);
 
private function soundCompleteHandler(e:Event):void{
  /* insira aqui o que deve fazer quando a musica acabar */
}

Compatibilidade Binária em C

Programar em C é sempre divertido, principalmente se vc sabe o que faz. Um exemplo disso é como trabalhar com estruturas de dados complexas, ponteiros e casting.

Imaginem as duas estruturas abaixo:

typedef struct {
	int id;
	char name[128];
} tpessoa;
 
typedef struct {
	int id;
	char name[128];
	char rg[128];
} tpessoafisica;

Ok, tenho um tipo tpessoa e um tpessoafisica que representam um tipo básico (pessoa) e um tipo propositalmente extendido, especializado para algum fim (pessoa fisica). Posso ter um tipo para pessoa juridica, por exemplo.

Imagine que eu posso ter diversas operações com o tipo básico e, por acaso, quero utilizar também com o tipo extendido (tpessoafisica). Como fazer? Em algumas linguagens eu posso fazer isso:

tpessoafisica x = {...};
tpessoa y = (tpessoa) x;

Entretanto em C isso gera um erro de conversion to non-scalar type requested. Eu posso converter int para float, float para int, int para long, char para int, etc, mas conversão de estruturas não é bem por ai: até porque não existe uma clara noção do que deveria acontecer, certo?

Para isso temos que clamar pelo conceito de compatibilidade binária: Sendo duas estruturas de dados, A e B, se B especializa A de forma ter todos os mesmos atributos na ordem que foi definida em A (e, opcionalmente, alguma coisa a mais no final), eu posso fazer um cast de um ponteiro do tipo B para um ponteiro do tipo A.

Vejamos, o tpessoafisica tem no começo os mesmos atributos (id e name) que a tpessoa e, por acaso, tem um atributos rg a mais no final. Dessa forma eu posso fazer o cast dos ponteiros na ordem apropriada.

void mostra_pessoa(tpessoa *x){
	printf("Pessoa { id = %d, name = %s }\n",x->id,x->name);
}
 
int main(){
	tpessoafisica x = {100, "pacman", "666"};
	// cast vale para ponteiros, por isso uso o operador &
	mostra_pessoa((tpessoa *) &x);
	return 0;
}

Ou seja, mostra pessoa esta preparado para receber um ponteiro do tipo tpessoa mas, graças a um habil cast de ponteiros aproveitando o principio de compatibilidade binária eu posso passar o endereço de uma estrutura diferente, no caso de tpessoafisica.

Perceba que eu preciso de um cast entre ponteiros, por isso eu preciso apelar para um & na frente da variavel, pegando o endereço de memória associado aquela variavel. Este recurso é util em muitas situações, desde simular interfaces e herança até coisas mais divertidas como fazer perl 5.x rodar perl 6.

Brincando com a libavcodec e libavformat

Vou contar uma histórinha. Pesquisando sobre http streamming para iPhone eu cheguei ate esta solução open source que utiliza, entre outras coisas, o ffmpeg. Eis que chego até este interessante trecho:

If you are interested in how the segmenter works you can find out more on how to use libavformat at the following resources: an older libavformat tutorial, some sample libavformat code, How to Write a Video Player in Less Than 1000 Lines, and more sample libavformat code.

Ora… não pensei duas vezes e cliquei no link sobre escrever um video player, curioso que sou. É um tutorial bem proveitoso,
que ja dá frutos na primeira lição. Deixo aqui um pequeno exemplo que analisa arquivos de video e informa dados do codec de cada stream (audio, video e o que mais tiver la dentro).

#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
 
int main(int argc, char **argv){
   int i;
   char buf[256];
   AVFormatContext *pFormatCtx;
 
   av_register_all();
 
   while(*(++argv)){
     printf("analisando arquivo '%s'\n",*argv);
     if(av_open_input_file(&pFormatCtx, *argv, NULL, 0, NULL)!=0 || 
	av_find_stream_info(pFormatCtx)<0){ 
		puts("nao foi possivel analisar este arquivo!");
		continue;
	}
     for(i=0;i<pFormatCtx->nb_streams;i++){
	avcodec_string(buf, sizeof(buf), pFormatCtx->streams[i]->codec, 0);
	printf("\tstream[%d]=%s\n",i,buf);
     }
   }
 
   return 0;
}

Para compilar basta adicionar a libavcodec e a libavformat (apt-get nelas).

gcc -lavformat -lavcodec -Wall a.c

A execução é simples:

$ ./a.out *
analisando arquivo 'teste.bin'
	stream[0]=Video: wmv2, yuv420p, 320x240
	stream[1]=Audio: mp3, 48000 Hz, stereo, s16, 128 kb/s

Não apenas voltei a programar em C (que é uma delícia) como produzi um executavel bem enxuto (12 k) e util para determinar os codecs presentes em dado arquivo. Divertido. Vamos ver o que é possivel fazer agora.