Publicado em linux, mobile, python

Do YouTube para o Smartphone – Parte 1

Conversando com um amigo sobre desenvolvimento de software, desenvolvimento dirigido a testes,integração contínua, entre outras coisas, veio a vontade de automatizar um processo de extração de mp3 de vídeos do Youtube e depois enviar o arquivo do notebook para o smartphone, a fim de ouvi-lo com um aplicativo para podcasts.

Até agora não escrevi nada, tão pouco pesquisei profundamente sobre as bibliotecas e ferramentas necessárias. Vou explicar aqui apenas as ideias que tenho no momento.

Problema

Eu tenho pouco tempo para assistir vídeos mas tenho conseguido ouvir meus podcasts favoritos. Por isso, para continuar consumindo alguns canais do Youtube, estou extraindo o mp3 dos vídeos para ouvir no smartphone. Depois eu jogo esses arquivos no Dropbox ou diretamente do smartphone via USB. O aplicativo para ouvir podcasts que uso atualmente é Podcast Addict. Eu trato uma pasta como um fonte de podcasts.

Módulo Desktop

Eu tenho um notebook Dell rodando a última versão do Ubuntu no momento da edição desse post.

Atualmente uso o programa de linha de comando youtube-dl para extrair o mp3 dos vídeos do Youtube.

Minha ideia é escrever um programa que acesse os canais do Youtube que consumo e verifique se há novos vídeos. Gostaria aqui de usar a API do Twitter para me enviar uma mensagem privada me perguntando se eu gostaria do mp3 do vídeo. Eu responderia por mensagem, igualmente, um sim ou um não.

Se a resposta for sim, o programa executaria o youtube-dl e jogaria o arquivo para uma determinada pasta do Dropbox.

Módulo Smartphone

Eu tenho um smartphone Quantum Go rodando Android Lollipop no momento da edição desse post.

Do lado do smartphone, basta ter o Dropbox instalado e uma de suas pastas servindo como fonte de podcasts do Podcast Addict. Terei de pesquisar se o Addict conseguirá acessar o mp3, uma vez que no dispositivo móvel o download é sob demanda.

Nos próximos posts, continuaremos a tratar desse assunto com o resultado de pesquisas e códigos.

Anúncios
Publicado em desenvolvimento, linux, mobile, open source, python, Uncategorized

DiceDnd 1.1

Depois de um final de semana complicado e acamado, voltei a escrever na segunda-feira os melhoramentos do DiceDnd. Pretendia melhorar o visual, habilitar o modo fullscreen e ainda fazer um pacote debian para distribuir o programa. Devido às dificuldades encontradas, fiquei somente no melhoramento visual. Pois bem, tirei umas fotos do aplicativo funcionando (não descobri uma função print screen no N800) e ainda estou disponibilizando uma nova versão abaixo.

Vou ficar devendo o fullscreen e o pacote.

DiceDnd no Nokia N800
DiceDnd no Nokia N800
DiceDnD com o resultado da jogada de dados
DiceDnD com o resultado da jogada de dados

fonte do dicednd.py (atualizado)

#!/usr/bin/python2.5

import osso
import gtk
import hildon

def labela(texto):
    fonte = '%s'
    etiqueta = gtk.Label(fonte % texto)
    etiqueta.set_use_markup(True)
    return etiqueta

def string_jogada(vezes, dado, soma):
    if soma > 0:
        sinal = '+'
    elif soma == 0:
        sinal = ''
    else:
        sinal = '-'
    return '%dd%d%s%s' % (vezes, dado, sinal, abs(soma) or '')

class DiceDnD(hildon.Program):
    def __init__(self):
        self.dado_atual = 0
        self.vezes = 0
        self.soma = 0
        hildon.Program.__init__(self)
        self.window = hildon.Window()
        self.window.set_title('DiceDnd')
        self.window.set_border_width(40)
        self.window.connect("destroy", self.quit)
        self.add_window(self.window)

        tabela = gtk.Table(5,4,False)
        self.window.add(tabela)        

        self.dado4 = gtk.Button()
        self.dado4.add(labela('4'))
        self.dado6 = gtk.Button()
        self.dado6.add(labela('6'))
        self.dado8 = gtk.Button()
        self.dado8.add(labela('8'))
        self.dado10 = gtk.Button()
        self.dado10.add(labela('10'))
        self.dado12 = gtk.Button()
        self.dado12.add(labela('12'))
        self.dado20 = gtk.Button()
        self.dado20.add(labela('20'))
        self.botaoMais = gtk.Button()
        self.botaoMais.add(labela('+'))
        self.botaoMenos = gtk.Button()
        self.botaoMenos.add(labela('-'))
        self.botaoJogar = gtk.Button()
        self.botaoJogar.add(labela('Jogar'))
        self.frame = gtk.Frame()
        self.montagem = gtk.Label('Jogada')
        self.frame.add(self.montagem)
        
        tabela.attach(self.dado4,0,1,0,1)
        tabela.attach(self.dado6,1,2,0,1)
        tabela.attach(self.dado8,2,3,0,1)
        tabela.attach(self.dado10,0,1,1,2)
        tabela.attach(self.dado12,1,2,1,2)
        tabela.attach(self.dado20,2,3,1,2)
        tabela.attach(self.botaoMais,0,1,2,3)
        tabela.attach(self.botaoJogar,1,2,2,3)
        tabela.attach(self.botaoMenos,2,3,2,3)
        tabela.attach(self.frame,0, 3, 3, 4)
        
        self.dado4.connect('clicked',self.preparar,4)
        self.dado6.connect('clicked',self.preparar,6)
        self.dado8.connect('clicked',self.preparar,8)
        self.dado10.connect('clicked',self.preparar,10)
        self.dado12.connect('clicked',self.preparar,12)
        self.dado20.connect('clicked',self.preparar,20)
        self.botaoMais.connect('clicked',self.incrementar,1)
        self.botaoMenos.connect('clicked',self.incrementar,-1)
        self.botaoJogar.connect('clicked',self.mostrar)
        
        self.window.show_all()
        
    def mostrar(self, button):
        if self.dado_atual == 0:
            return
        import random
        total = 0
        for i in range(self.vezes):
            total += random.randint(1,self.dado_atual)
        total = total + self.soma
        jogada = string_jogada(self.vezes, self.dado_atual, self.soma)
        self.show_message('%s' % total)

    def preparar(self, button,valor):
        if valor  self.dado_atual:
            self.dado_atual = valor
            self.vezes = 1
            self.soma = 0
        else:
            self.vezes += 1
        self.montagem.set_text(string_jogada(self.vezes, self.dado_atual, self.soma))
            
    def incrementar(self, button,valor):
        self.soma = self.soma + valor
        self.montagem.set_text(string_jogada(self.vezes, self.dado_atual, self.soma))


    def show_message(self, message):
        dlg = hildon.Note('information', (self.window, message))
        dlg.run()
        dlg.destroy()
        #pango_markup = '%s\n%s' % ('DiceDnD', message)
        #hildon.hildon_banner_show_information_with_markup(gtk.Label(''), None, pango_markup)

    def quit(self, evt):
        gtk.main_quit()
        
    def run(self):
        gtk.main()

def main():
    prog = DiceDnD()
    prog.run()

if __name__ == "__main__":
    main()

Publicado em desenvolvimento, linux, mobile, python

DiceDnd

Os dados usados no RPG D&D
Os dados usados no RPG D&D

A minha idéia exploratória de criar um aplicativo para gerar jogada de dados no meu N800  ocupou umas horas da noite de sexta e início de madrugada do sábado.

O objetivo da aplicação é bem simples. Eu vou voltar a mestrar campanhas de RPG. Comprei o recente D&D 4ª Edição em português mais uma aventura para personagens iniciantes. Não tenho todos os tipos de dados necessários. São 6 tipos, por quantidade de faces: 4, 6, 8, 10, 12 e 20. Assim, queria simular a parada de dados pelo meu N800, um internet tablet da Nokia.

Uma das principais linguagens para programar nesses dispositivos é Python. Apesar de não conhecer muito a biblioteca Gtk (biblioteca gráfica), conheço a linguagem razoavelmente bem, por isso acreditava que conseguiria implementar o aplicativo no final de semana.

A primeira providência foi procurar documentação. A idéia do projeto já estava toda na minha cabeça mas não sabia por onde começar. Depois de um tempo, encontrei algumas coisas. Foram importantes os seguintes documentos:

A versão do sistema operacional é o OS 2008 (Diablo). O Python 2.5 já estava instalado. De fato, não precisei instalar outra coisa. Algumas documentações diziam que eu tinha de instalar o interpretador da linguagem. Talvez eu tenha feito isso algum tempo atrás.

Outra coisa que ajudou bastante, para ir escrevendo e testando rapidamente, foi acessar via SSH o dispositivo pelo Nautilus (num notebook com Ubuntu). Criei o arquivo da aplicação no cartão do N800 e depois abrir com o editor TextFlow. Daí era só escrever, salvar e ir no PDA executar a aplicação.

O cliente e servidor do SSH não vem instalado por default no N800. Nem o terminal. Por ele é que eu rodava o Python. Pelo notebook, eu usava também um terminal para acessar o N800 via ssh. Era útil para testar algumas coisas no interpretador interativo do Python.

As próximas tarefas envolvem melhorar o aspecto visual da aplicação e preparar um instalador para ficar mais fácil de dispobilizar. O código-fonte encontra-se abaixo:

#!/usr/bin/python2.5

import osso
import gtk
import hildon

def string_jogada(vezes, dado, soma):
    if soma > 0:
        sinal = '+'
    elif soma == 0:
        sinal = ''
    else:
        sinal = '-'
    return '%dd%d%s%s' % (vezes, dado, sinal, abs(soma) or '')

class DiceDnD(hildon.Program):
    def __init__(self):
        self.dado_atual = 0
        self.vezes = 0
        self.soma = 0
        hildon.Program.__init__(self)
        self.window = hildon.Window()
        self.window.set_title('DiceDnd')
        self.window.connect("destroy", self.quit)
        self.add_window(self.window)

        tabela = gtk.Table(5,4,True)
        self.window.add(tabela)

        self.dado4 = gtk.Button('4')
        self.dado6 = gtk.Button('6')
        self.dado8 = gtk.Button('8')
        self.dado10 = gtk.Button('10')
        self.dado12 = gtk.Button('12')
        self.dado20 = gtk.Button('20')
        self.botaoMais = gtk.Button('+')
        self.botaoMenos = gtk.Button('-')
        self.botaoJogar = gtk.Button('Jogar')
        self.frame = gtk.Frame()
        self.montagem = gtk.Label('Jogada')
        self.frame.add(self.montagem)

        tabela.attach(self.dado4,0,1,0,1)
        tabela.attach(self.dado6,1,2,0,1)
        tabela.attach(self.dado8,2,3,0,1)
        tabela.attach(self.dado10,0,1,1,2)
        tabela.attach(self.dado12,1,2,1,2)
        tabela.attach(self.dado20,2,3,1,2)
        tabela.attach(self.botaoMais,0,1,2,3)
        tabela.attach(self.botaoJogar,1,2,2,3)
        tabela.attach(self.botaoMenos,2,3,2,3)
        tabela.attach(self.frame,0, 3, 3, 4)

        self.dado4.connect('clicked',self.preparar,4)
        self.dado6.connect('clicked',self.preparar,6)
        self.dado8.connect('clicked',self.preparar,8)
        self.dado10.connect('clicked',self.preparar,10)
        self.dado12.connect('clicked',self.preparar,12)
        self.dado20.connect('clicked',self.preparar,20)
        self.botaoMais.connect('clicked',self.incrementar,1)
        self.botaoMenos.connect('clicked',self.incrementar,-1)
        self.botaoJogar.connect('clicked',self.mostrar)

        self.window.show_all()

    def mostrar(self, button):
        if self.dado_atual == 0:
            return
        import random
        total = 0
        for i in range(self.vezes):
            total += random.randint(1,self.dado_atual)
        total = total + self.soma
        jogada = string_jogada(self.vezes, self.dado_atual, self.soma)
        self.show_message('%s' % total)

    def preparar(self, button,valor):
        if valor  self.dado_atual:
            self.dado_atual = valor
            self.vezes = 1
            self.soma = 0
        else:
            self.vezes += 1
        self.montagem.set_text(string_jogada(self.vezes, self.dado_atual, self.soma))

    def incrementar(self, button,valor):
        self.soma = self.soma + valor
        self.montagem.set_text(string_jogada(self.vezes, self.dado_atual, self.soma))

    def show_message(self, message):
        dlg = hildon.Note('information', (self.window, message))
        dlg.run()
        dlg.destroy()
        #pango_markup = '%s\n%s' % ('DiceDnD', message)
        #hildon.hildon_banner_show_information_with_markup(gtk.Label(''), None, pango_markup)

    def quit(self, evt):
        gtk.main_quit()

    def run(self):
        gtk.main()

def main():
    prog = DiceDnD()
    prog.run()

if __name__ == "__main__":
    main()
Publicado em desenvolvimento, mobile, python

Idéia exploratória

Uma boa idéia me surgiu agora, útil para o momento e ótima pedida para iniciar a exploração no mundo da programação de dispositivos Nokia que usam o sistema operacional Maemo: um rolador de dados.

Bobo, né? Inclusive, acho que já existe um. Mas é diferente do que eu estou pensando.

Gostaria que a tela do aplicativo mostrasse um quadrado com todos os tipos de dados usados no RPG D&D ou seja, os de 4, 6, 8, 10, 12 e 20 faces. E mais três botões: para o sinal de mais, o de menos e o de igual.

Ao apertar um dos dados ele saberá que quero jogar com ele. Ele esperará eu apertar no sinal de igual para a operação randômica executar. Os sinais servem para aumentar ou diminuir o que resultar do dado. Cada vez que eu apertar num deles incrementa-se ou descrementa-se em um.

Logicamente vou escrever esse aplicativo em Python. Vamos ver se tenho a sorte e produtividade de terminá-lo ainda neste final de semana. Quando concluir, posto por aqui.

Publicado em linux, mobile

Nokia N800

Adquiri recentemente o Nokia N800, um internet tablet. Meu intuito na sua compra é substituir o Palm (Tungsten E2) com vantagens, no caso internet wireless e sistema operacional Linux.
A grande tarefa inicial é encontrar programas tão úteis quanto os do Palm no quesito organização pessoal. Descobri que seu foco não é organização pessoal, mas sim Internet. A vantagem na busca de softwares em relação ao Palm é que procuramos e instalamos a la Debian, ou seja, nenhuma necessidade de sincronização com o Windows.
No segundo dia de uso, atualizei o seu firmware, como recomendado. Foi uma tarefa simples. Uma coisa que não gostei nele, foi a duração da bateria, entretanto, suspeito que seu suporte a redes sem fio contribua para isso. Nesse ponto, vou ter de me acostumar a desligar o aparelho.
Outra dificuldade que tenho é em relação a ambientes com proxy; somente o browser solicita o usuário e senha, conseguindo assim acesso à Internet.
No geral estou satisfeito com meu novo brinquedo. Antes que perguntem, o N800 não é um celular. Nesse caso, recomendo que comprei os novos celulares com Android.

Publicado em linux, mobile

DO YOUTUBE PARA O CELULAR

Com a febre dos vídeos disponibilizados por sites como YouTube e Google Video, aliada à minha vontade de colocar alguns em meu computador ou celular, descobri como fazer algumas coisas.
Umas das coisas que encontrei foi um script chamado downtube, escrito em Python, que baixa vídeos do YouTube em formato FVL. Eu o instalei no meu PC com Linux Ubuntu, mas há binários para o Windows. Não testei no Windows e sim no Linux, então mostro agora como é por linha de comando no shell:

downtube -o nome_file_sem_extensao http://www.youtube.com/watch?v=1VX0NPEgS7g

Ele então baixará um arquivo para o diretório onde foi executado o script. Normalmente converto o formato FVL para AVI com o comando ffmpeg. É possível que ele já exista em seu PC. Digite “which ffmpeg” para saber se vc o tem. Senão instale com:

sudo apt-get install ffmpeg

Depois de baixados o video e o ffmpeg vamos converter para AVI.

ffmpeg -i nome_file_sem_extensao.fvl nome_file_sem_extensao.avi

O ffmpeg é muito poderoso e aceita diversos codecs. Execute “man ffmpeg” para mais informações sobre o mesmo. Infelizmente a versão disponível para o Ubuntu (talvez até para as outras) não suporta os codecs de áudio AMR e AAC, comumente usados nos celulares. Podemos, pelo menos, converter o vídeo (sem audio) para o celular.

ffmpeg -i nome_file_sem_extensao.avi
-s qcif -r 12
-ac 1 -ar 8000
-b 30
-ab 12
-an
nome_file_sem_extensao.3gp

Bom, agora para passar para seu celular a história complica. No meu caso, eu costumo usar um adaptador USB de cartões SD para jogar o arquivo para o cartão e daí para um PDA. Do PDA uso infravermelho (IrDA) ou Bluetooth para enviar ao celular. Mais fácil mesmo é você ter o programa desktop do seu celular para enviá-lo via USB. Você possivelmente usará o Windows para isso.
Para vocês terem seu vídeo com som terão que baixar a versão em desenvolvimento via svn e configurar de acordo. Tenho vários links a esse respeito em http://del.icio.us/claudiotorcato/celular e http://del.icio.us/claudiotorcato/ffmpeg, além de outros.