domingo, 13 de novembro de 2011

Atualização no programa encode-xvid - Agora com interface gráfica

Olá novamente. Neste post venho com uma notícia: o programa que estou desenvolvendo - encode-xvid agora está com uma interface gráfica. Desenvolvi uma em python usando a biblioteca gráfica pyGTK. Este é um wrapper onde eu posso montar a linha de comando com mais facilidade - mas ao mesmo tempo é um hobby onde posso desenvolver em python, que gosto tanto.

Quem quiser conferir o projeto, é só ir lá na página no google code e pegar instruções de como fazer svn checkout, ou conferir os fontes lá mesmo - http://code.google.com/p/encode-xvid/

Por enquanto só vai funcionar no GNU/Linux, porque o script está em shell script, mas pretendo reescrever em python, aí vai rodar em outros SO também, desde que tenham o ambiente instalado.

Grande abraço e até a próxima.

Artigo completo (View Full Post)

segunda-feira, 7 de novembro de 2011

Script para encode xvid agora no google code

O script que criei em outro post para gerar arquivos para dvd agora está no google code. Resolvi colocar ele lá para ficar mais fácil compartilhar o desenvolvimento e manter atualizado.

Se quiser acompanhar a evolução deste script é só pegar em https://code.google.com/p/encode-xvid/

Sei que este script não é coisa muito grande, mas é meu primeiro esforço em desenvolver software livre. vou tentar melhorá-lo com o tempo.

Artigo completo (View Full Post)

domingo, 6 de novembro de 2011

Shell script para gerar arquivos xvid com áudio mp3

Olá pessoal. Neste post vou colocar um script que eu mesmo fiz para fazer encode de arquivos de vídeo no formato avi com o codec de vídeo xvid e áudio mp3.

Faço essa conversão porque tenho dois probleminhas: 1 - meu dvd é velhinho e roda arquivos com legendas, mas não arquivos muito grandes - nesse caso tenho que reduzir o bitrate. 2 - meu xbox 360 não carrega legendas externas (srt) de vídeos e só roda xvid.

O software que eu uso para encode é o mencoder, o SO é GNU/Linux distro Slackware 13.37. O mplayer foi compilado por mim. Versão:

MPlayer SVN-r34308-4.5.2 (C) 2000-2011 MPlayer Team


Meu mplayer foi compilado com as bibliotecas adicionais xvid e libmp3lame, mas para encode do xvid eu estou usando lavc. Para audio estou usando mp3lame.

Antes de postar o script, vale lembrar que é minha primeira aventura de script shell para automatizar alguma tarefa minha, então o código pode não ser o melhor possível. Dicas são muito bem vindas!

Abaixo o script:


#!/bin/bash

function usage {
echo "uso: video-encode -v video -l legenda -ab audio-bitrate -vb video-bitrate [-vol volume] [-sim] -o arqiuvo-output"
}

function error_exit {
echo "$1" 1>&2
exit 1
}

while [ "$1" != "" ]; do
case $1 in
-v )
shift
video=$1
;;
-l )
shift
legenda=$1
;;
-vb )
shift
vb=$1
;;
-ab )
shift
ab=$1
;;
-o )
shift
output=$1
;;
-vol )
shift
vol=":vol=$1"
;;
-sim )
sim=true
;;
* )
usage
error_exit "Parâmetro não reconhecido: $1"
;;
esac
shift
done


# Verificando se o arquivo de vídeo é válido
test -n "$video" -a -f "$video" || error_exit "Arquivo inválido: $video"

# Verificando se o arquivo de legenda (se informado) é válido
test -z "$legenda" -o -f "$legenda" || error_exit "Legenda inválida: $legenda"

# Verificando se o arquivo de legenda (se informado) está no format utf-8
test -f "$legenda" -a $(file -bi "$legenda" | sed 's/\(.*\)charset=//') == "utf-8" || error_exit "A legenda não está no formato utf-8: $legenda"

# Tenta criar o arquivo de saída
touch "$output" > /dev/null 2>&1 || error_exit "Erro ao criar o arquivo de saída: $output"

echo
echo "******************************************************"
echo "Ambiente"
echo "video: $video"
echo "legenda: $legenda"
echo "vbitrate: $vb"
echo "abitrate: $ab"
echo "******************************************************"
echo

function echo_exec {
echo $1
echo $2

if [ -z $sim ]; then
eval $2 || error_exit "Operação cancelada"
fi
}

cmd="mencoder \"$video\" -sub \"$legenda\" -ovc lavc -lavcopts vcodec=mpeg4:vpass=1 -oac mp3lame -ffourcc XVID -o /dev/null"
echo_exec "Encoding 2-pass - parte 1" "$cmd"

cmd="mencoder \"$video\" -sub \"$legenda\" -ovc lavc -lavcopts vcodec=mpeg4:vpass=2:vbitrate=$vb -oac mp3lame -lameopts abr:br=$ab$vol -ffourcc XVID -o \"$output\" -utf8"
echo_exec "Encoding 2-pass - parte 2" "$cmd"


Explicando em termos gerais, o script aceita os seguintes parâmetros de linha de comando:
-v arquivo de vídeo origem
-l arquivo de legendas
-vb bitrate do vídeo
-ab bitrate do áudio
-o arquivo de output
-vol volume do áudio - opcional (para aplicar ganho - pode distorcer)
-sim modo simulação (na verdade só exibe os comandos na tela, sem executar nada)

Estou usando o método 2pass do mencoder porque achei que tive videos de melhor performance assim.

Alguns pontos a melhorar:

O mencoder está sempre usando -utf8, por isso precisa do arquivo de legendas em formato utf-8. Vou tentar criar uma função para converter automaticamente o arquivo para utf-8 caso não seja - atualmente o programa retorna um erro e não prossegue.

Antes de rodar o programa é preciso saber de antemão o bitrate de áudio e vídeo que serão usados. Vou tentar identificar no arquivo de origem e dar suporte ao usuário entrar com as informações através de prompt.

Tornar a seleção da legenda opcional. Embora era minha intenção, ainda não está funcionando.

Acabei de executar o script e na minha máquina está funcionando (bem, na nossa máquina sempre funciona, né...), então espero que ajude outras pessoas da mesma forma que me ajuda aqui.

Grande abraço a todos e até a próxima.

Artigo completo (View Full Post)

domingo, 30 de outubro de 2011

Problema de conexão tcp/ip com MySQL no Slackware13.37 - Resolvido

Olá a todos mais uma vez.

Neste post vou relatar um problema que aconteceu comigo e o que eu fiz para resolver.

Neste fim de semana montei uma instalação GNU/Linux para desenvolver alguns projetos em Java com JBoss Seam e MySQl - minha primeira escolha era o postgres, mas o mysql já estava instalado e eu encontrei dificuldades instalando o postgres no Slackware, mas fica para outro post - A distro escolhida foi o Slackware, em sua versão recentemente lançada 13.37.

SO, BD, eclipse e Jboss instalados, banco de teste criado, fui criar uma conexão no eclipse para começar a trabalhar na IDE. Quando veio o problema: Não conseguia conectar no banco pelo software.

Horas e horas procurando consegui resolver.

Primeira orientação que vi foi procurar no arquivo my.cnf - no meu caso fica no /etc/my.cnf - se existe alguma entrada skip-networking não comentada.

Esta entrada skip-networking desabilita o suporte a rede: Só é possível conectar ao servidor na mesma máquina e pelo socket /var/lib/mysql/mysql.sock.

O meu problema era que não havia esta configuração no meu servidor, e mesmo assim não conseguia conectar via tcp/ip. Foi quando encontrei no arquivo de script que inicia o meu servidor que o script estava passando esse parâmetro pela linha de comando.

No meu é /etc/rc.d/rc.mysqld. Na linha 32 do script tem a seguinte linha:

SKIP="--skip-networking"

Essa linha deve ser comentada para o servidor aceitar conexões tcp/ip.

Grande abraço e até a próxima.

Artigo completo (View Full Post)

quinta-feira, 27 de outubro de 2011

Rational Team Concert - JazzHub

Atenção, pessoal do RJ!

Para o corajoso que estiver disposto a encarar o trânsito na Gávea na hora do rush ....

O pessoal da IBM vai ministrar uma palestra a qual pretende demonstrar a ferramenta Rational Team Concert. No site da IBM aondhttp://www.blogger.com/img/blank.gife o evento esta sendo anunciado cita que haverá demonstração de como criar um projeto e demonstrará os principais recursos da ferramenta. Acho que vale dar uma conferida.
O evento vai ser na PUC-RIO no RIO DE JANEIRO 28/10/11, 19h30

Auditório: B8 Edifício Frings – 8ª andar - Rua Marquês de São Vicente, 225 – Gávea

OBS:
O Palestrante será o Gerente de Desenvolvimento Sênior da IBM Estados Unidos que também é responsável pelos projetos “jazz.net” e “JazzHub”, Robin D Garside.

Artigo completo (View Full Post)

segunda-feira, 27 de junho de 2011

Tortoise/SVN Command Bat execute

Pode ser uma boa solução automatizar os comandos que fazemos repetidamente pelo Tortoise. Por exemplo, o comando update nas pastas que você precisa atualizar. Existem casos em que, dependendo da configuração do SVN, somos obrigados a dar update em diretório por diretório, o que além de ser extremante chato ainda corremos o risco de esquecer alguma atualização.
Ainda existem os casos dos que não precisam dar o update na raiz de diretórios porque vai atualizar coisas demais que não são necessárias.
Em fim, se for o caso de um "bat" lhe ser útil para executar ações do Tortoise, segue o exemplo abaixo de um script que o Felipe Guerço criou e agilizou bastante as coisas aqui. Obrigado Felipe!
Segue exemplo:


Segue referência, TortoiseSVN Commands ...
@echo off

FOR %%A IN (

"C:\sorteJayk\projeto\GLADY07\Implementation"
"C:\sorteJayk\projeto\GLADY07\Req"
"C:\sorteJayk\projeto\GLADY08\AChecklist"
"C:\sorteJayk\projeto\GLADY08\ZYZ"
"C:\sorteJayk\projeto\GLADY08\Homologacao_interna"
"C:\sorteJayk\projeto\GLADY09\Projetc_first"
"C:\sorteJayk\projeto\GLADY09\Projetc_log"
"C:\sorteJayk\projeto\GLADY09\Requist"
"D:\PROJETOS sorteJayk\TI\ACESSO"
"D:\PROJETOS sorteJayk\TI\GLADY"
"D:\PROJETOS sorteJayk\TI\MVC"
"D:\PROJETOS sorteJayk\TI\PTR_MAIN"

) DO "C:\Arquivos de programas\TortoiseSVN\bin\TortoiseProc.exe" /notempfile /command:update /path:%%A /closeonend:3



Artigo completo (View Full Post)

sexta-feira, 30 de julho de 2010

Commitou o que não era pra comittar? Dá "Rollback"!

Fala ai, pessoal!

Se você é de TI, com certeza já passou por uma situação como essa:
Atualizando dados de uma tabela em um banco de dados Oracle, você alterou um ou vários campos com o valor errado, ou até mesmo excluiu um ou mais registros e deu COMMIT. E agora?!?! Fedeu?!?! NÃO!!! Você pode recuperar os dados...
Fala ai, pessoal!

Se você é de TI, com certeza já passou por uma situação como essa:
Atualizando dados de uma tabela em um banco de dados Oracle, você alterou um ou vários campos com o valor errado, ou até mesmo excluiu um ou mais registros e deu COMMIT. E agora?!?! Fedeu?!?! NÃO!!! Você pode recuperar os dados através do Oracle Flashback.

Para isso, a tarefa é muito simples. Basta fazer um select na tal tabela, normal mesmo, com os campos e condições que você quer e, no from, após o nome da tabela, colocar "as of timestamp systimestamp - interval 'X' minute", onde esse "X" é o tempo que passou desde a bobagem que você fez até agora.

Por exemplo: Tenho uma tabela CLIENTE na minha base de dados Oracle e vou atualizar os clientes que não fazem compras há mais de 1 mês para Inativos.

Então fiz lá meu update, atualizando o campo STATUS_CLIENTE para "I", depois de fazer um select que retorna os tais clientes que não compraram no último mês. Dei o COMMIT. Alguns desses clientes estavam com o STATUS "A" de Ativo, "D" de Devedor, "V" de VIP.

Daí, chega o meu chefe, 30 minutos depois que eu fiz o update, dizendo que esse update não pode ser feito em clientes VIP e eu... DANÇO? Não! Eu faço o seguinte:

select ID_CLIENTE
from CLIENTE
as of timestamp systimestamp - interval '30' minute
where STATUS_CLIENTE = 'V';

PRONTO! Peguei todo mundo que tava com o campo STATUS_CLIENTE = 'V' 30 minutos atrás.
Com os IDs, eu faço um novo update, passando essa galera, que está com o STATUS = 'I', pra 'V'.

Salvei meu emprego e deixei meu chefe feliz!

PS.: Agradecimentos ao camarada Willian Rodrigues que ajudou nesse post!

Abraço a todos!

Artigo completo (View Full Post)

segunda-feira, 26 de abril de 2010

D2010 e Data Snap - Por Bruno Lichot

Sobre o D2010:
Vale apena ficar antenado, Bruno Lichot esta publicando uma série de artigos sobre DataSnap 2010 na revista Acitve Delphi.
O exemplo publicado nesta edição pode ser baixado aqui!

Artigo completo (View Full Post)

segunda-feira, 24 de agosto de 2009

Delphi - Intraweb: Passar e recuperar parâmetros entre requisições HTTP

Inicie uma aplicação Intraweb no Delphi. O Assunto é sobre passar, e recuperar, parâmetros entre requisições HTTP. Especificamente, pretendo exemplificar como chamar uma outra aplicação web, sendo que nesta chamada passaremos parâmetros, os quais, obviamente, serão recuperados e processados pela aplicação que foi requisitada.


Neste artigo criaremos duas aplicações Intraweb ISAPI. Um delas (“AppEstacaoZNSubmit”) servirá para passar parâmetros para outra (“AppRequestQueryFieldsEstacaoZN”). Esta segunda por sua vez, recupera os valores destes parâmetros processa e os exibe.
Ok, definido o que pretendemos fazer passamos agora a parte prática.

A seguir o código fonte da aplicação ISAPI que chama e passa os parâmetros. Salvei essa app de com o nome “AppEstacaoZNSubmit”.

O Form principal e único desta aplicação “IWUnit1.pas”:

unit IWUnit1;
{PUBDIST}

interface

uses
IWAppForm, IWApplication, IWTypes, IWCompButton, Classes, Controls,
IWControl, IWCompEdit, IWCompLabel;

type
TformMain = class(TIWAppForm)
IWEdit1: TIWEdit;
IWButton1: TIWButton;
IWLabel1: TIWLabel;
EdtURLZN: TIWEdit;
IWLabel2: TIWLabel;
procedure IWAppFormCreate(Sender: TObject);
procedure IWButton1Click(Sender: TObject);
public
end;

implementation
{$R *.dfm}

uses
ServerController, SysUtils, IWForm;

procedure TformMain.IWAppFormCreate(Sender: TObject);
begin
IWEdit1.Text := '';
IWButton1.Caption := 'Enviar - ZN';
IWLabel1.Caption := 'Digite o valor que será enviado';
IWLabel2.Caption := 'Digite a URL da aplicação ISAPI que será chamada' +
'e exibirá o valor digitado acima.';
EdtURLZN.Text := '';
end;

procedure TformMain.IWButton1Click(Sender: TObject);
const
AJSComando = 'window.open("%s?estacaoZnValor=%s")';
begin
AddToInitProc(Format(AJSComando, [EdtURLZN.Text, IWEdit1.Text]));
end;

end.


Em seguida o “.dpr”:

library AppEstacaoZNSubmit;

uses
IWInitISAPI,
ServerController in 'ServerController.pas' {IWServerController: TIWServerControllerBase},
IWUnit1 in 'IWUnit1.pas' {formMain: TIWForm1};

{$R *.RES}

begin
IWRun(TFormMain, TIWServerController);
end.


Não editei nada no “IWServerController”, portanto após compilar e efetuar o deploy da “AppEstacaoZNSubmit.dll” no IIS damos por encerrada esta etapa do nosso exemplo.


O próximo passo é codificar a segunda aplicação. Logo, novamente inicie um novo projeto Intraweb ISAPI, salve com o nome de “AppRequestQueryFieldsEstacaoZN”. No evento “OnRender” do IWForm1 implementaremos o que especificamos anteriormente. Abaixo, o fonte da IWUnit1.pas:

unit IWUnit1;
{PUBDIST}

interface

uses
IWAppForm, IWApplication, IWTypes, Classes, Controls, IWControl,
IWCompLabel, IWCompListbox, IWCompMemo;

type
TformMain = class(TIWAppForm)
IWLabel1: TIWLabel;
procedure IWAppFormRender(Sender: TObject);
public
end;

implementation
{$R *.dfm}

uses
ServerController, IWForm, SysUtils;

procedure TformMain.IWAppFormRender(Sender: TObject);
const
ZnMsg = 'www.estacaozn.blogspot.com O Valor recebido de "%s" é: %s';
begin
IWLabel1.Caption := Format(ZnMsg,
[WebApplication.Request.RemoteAddr,
WebApplication.Request.QueryFields.Values['estacaoZnValor']]);
IWLabel1.Font.Size := 20;
end;


Vejamos o “.dpr” da “AppRequestQueryFieldsEstacaoZN.dpr”.


library AppRequestQueryFieldsEstacaoZN;

uses
IWInitISAPI,
ServerController in 'ServerController.pas' {IWServerController: TIWServerControllerBase},
IWUnit1 in 'IWUnit1.pas' {formMain: TIWForm1};

{$R *.RES}

begin
IWRun(TFormMain, TIWServerController);
end.


Após proceder a implementação deste módulo conforme ilustrado acima, semelhante ao exemplo anterior compile e efetue o deploy da “AppRequestQueryFieldsEstacaoZN.dll” no ISS.
Feito isso já é possível testar. No browser, chame o diretório virtual definido no deploy da primeira aplicação (AppEstacaoZNSubmit.dll).




Digite no “IWEdit1” o valor para parâmetro “estacaoZnValor”, o qual será exibido. Digite também a URL da segunda aplicação no “EdtURLZN”, para somente então clicar no IWButton1.






Na primeira aplicação, no evento OnClick do IWButton1, chamamos o método “AddToInitProc” de “TformMain”. Este método nos permite “colocar” scripts (Javascript) que serão executados quando a função “Initialize()" padronizada pelo framework Intraweb, quando o browser estiver interpretando a tag “body”, da página construída pelo Intraweb. No body onload é definida a chamada a função “Initialize()".





function Initialize() {
InitSubmitter();
StaticInit();
if (document.body.leftMargin < 0 && document.body.topMargin < 0) {
document.body.leftMargin = 0;
document.body.topMargin = 0;
}
InitRects(614, 451);
InitIWCLObjects();

window.open("http://localhost/requesestacaozn/?estacaoZnValor=Landjah Estação ZN")
}



Então, podemos concluir que, no Intraweb quando você precisar executar uma função qualquer no evento “onload” no body basta para isso passá-la como parâmetro no método “AddToInitProc” do TIWForm em questão.

Na segunda aplicação, “AppEstacaoZNSubmit”, o comando
"WebApplication.Request.QueryFields.Values" pode ser entendido da mesma forma que o Webbrocker trabalha com o protocolo http.
Podemos também recuperas outras variáveis através do objeto “WebApplication”, sua propriedade “Request”, tais como o “RemoteHost”, “UserAgent” e etc..

Por hora é só .... Até a próx!!!


Artigo completo (View Full Post)

JSP e Oracle - Para apresentar uma Treeview

Olá pessoal!

Dando manutenção em um sistema java web com interface jsp precisei usar uma treeview para apresentar as categorias de produtos para o usuário. Vou relatar aqui a experiência.


As categorias estão modeladas no banco em uma tabela com autorelacionamento.



No oracle para consultar uma table com autorelacionamento podemos utilizar a seguinte query:


select id, LEVEL, SYS_CONNECT_BY_PATH(nome, '@') as caminho
from categoria CONNECT BY parent_id = PRIOR id START WITH id = categoria_inicial


A categoria_inicial é a primeira categoria de uma árvore, nesse sistemas existem várias árvores de categorias.

O resultado fica assim para a categoria_inicial igual a 30:

id level caminho
30 1 @Material de escritório
31 2 @Material de escritório@Informática
34 3 @Material de escritório@Informática@Tinta
55 4 @Material de escritório@Informática@Tinta@Tinta Impressoras
60 3 @Material de escritório@Informática@Armazenamento
63 4 @Material de escritório@Informática@Armazenamento@DAT/DLT/DVD/DDS
64 4 @Material de escritório@Informática@Armazenamento@Disquetes
92 3 @Material de escritório@Informática@Teste
93 4 @Material de escritório@Informática@Teste@Teste1
113 4 @Material de escritório@Informática@Teste@Teste2
120 4 @Material de escritório@Informática@Teste@Test3

Ai no java criei uma classe para representar a estrutura da categoria, ficou assim:

public class CategoriaTreeView {
public String id;
public int level;
public String path;

public CategoriaTreeView(String id, int level, String path){
this.id = id;
this.level = level;
this.path = path;
}
}


Como essa classe vai ser utilizada somente como uma estrutura de dados para representar o dado que será exibido na tela ela não tem gets e sets. Nem toda classe java precisa ter gets e sets. Gets e sets aqui são desnecessários e não acresentam nada. Acredite. Mas isso é assunto para outro post.

Também tenho um DAO que acessa o banco e entrega um List com os objetos CategoriaTreeView.

Antes disso fiz uma pesquisa na internet sobre como criar uma treeview no jsp (ou html) e encontrei o jQuery plugin: Treeview que transforma uma lista não ordenada do html <ul> em uma árvore.

Agora o problema é transformar a minha coleção de CategoriaTreeView em uma lista não ordenada com <ul> e <li>. Para isso eu criei a seguinte função recursiva que retorna uma String que será utilizada dentro do html:


private String processa(int atual, List<CategoriaTreeView> lista){
if(lista == null) return "";
String out = "";
if(lista.size() == 0) {
if(atual > 0){
out += "</li>\n";
out += "</ul>\n";
out += processa(atual - 1, lista);
}
}else if(lista.size()>0){
CategoriaTreeView item = lista.remove(0);
if(item.level == atual){
out += "</li>\n";
out += "<li><span>" + subString(item.level, item.path) + "</span>\n";
out += processa(item.level, lista);
}else if(item.level > atual){
out += "<ul>\n";
out += "<li><span>" + subString(item.level, item.path) + "</span>\n";
out += processa(item.level, lista);
}else if(item.level < atual){
out += "</li>\n";
out += "</ul>\n";
// adiciono o cara de volta na lista pois ainda não foi processado. estou voltando um nivel na árvore.
lista.add(0, item);
out += processa(atual - 1, lista);
}
}
return out;
}

Também temos a função para retornar a categoria de dentro do caminho:


private String subString(int i, String s){
String[] ss = s.split("@");
return ss[i];
}


Dentro do meu servlet eu tenho o seguinte código:

ArrayList categorias = dao.categorias(categoria_inicial);
String treeView = processa(0, categorias);
treeView = treeView.replaceFirst("<ul>", "<ul id=\"browser\">");
request.setAttribute("treeView", treeView);

Para exibir a treeview no jsp eu utilizei o exemplo simple.html que vem no download do jQuery plugin: Treeview. A única mudança foi que eu fiz o download do jquery ao invés de usar o link direto do ajax.googleapis.com.

Adicionei o seguinte ao jsp:


<link rel="stylesheet" href="../jquery.treeview.css" />
<link rel="stylesheet" href="../red-treeview.css" />
<link rel="stylesheet" href="screen.css" />

<script type="text/javascript" src="jquery-1.3.2.min.js"></script>
<script src="../lib/jquery.cookie.js" type="text/javascript"></script>
<script src="../jquery.treeview.js" type="text/javascript"></script>

<script type="text/javascript">
$(document).ready(function(){
$("#browser").treeview({control: "#treecontrol", animated:"normal", persist: "cookie"});
});
</script>

<%
String s = (String)request.getAttribute("treeView");
if(s != null && !s.trim().equals("")){
%>
<tr>
<td>
<br>
<div id="treecontrol">
<a title="Collapse the entire tree below" href="#">Fechar Tudo</a>
<a title="Expand the entire tree below" href="#">Abrir Tudo</a>
</div>

</td>
</tr>
<tr>
<td>
<br>
<div><%= s %></div>
</td>
</tr>
<%
}
%>


O resultado fica parecido com esse demo que está no site.



Abraços, Rodrigo Alencar.

Artigo completo (View Full Post)

 
BlogBlogs.Com.Br