Archive

Posts Tagged ‘Asterisk’

Google Speech + Python + Asterisk

janeiro 16, 2012 82 comentários

Olá Povo que acompanha o blog 🙂

Ainda falando sobre reconhecimento da fala utilizando o google, enviei uma mensagem na lista AsteriskBrasil onde expressava minhas idéias de como utilizar o serviço de reconhecimento de fala do google em tempo real com o Asterisk,  já se passou quase uma semana sem se quer um suspiro de interesse, então resolvi seguir sozinho !

A idéia é utilizar EAGI para controle do canal de entrada de áudio em conjunto com o File Descriptor, o Asterisk entrega o áudio em formato RAW diretamente no File Descriptor 3, então podemos utilizar esta informação da maneira que acharmos conveniente, para este caso a manipulação se torna muito prática, o que me desprende totalmente das APP’s prontas para gravações inseridas no Asterisk Ex. Record, nada melhor do que ser livre para voar, é claro várias análises se tornam possíveis com isso e o leque de aplicações possíveis se tornam infinitas.

Você certamente já pensou em ter um PABX com funcionalidade para reconhecimento da fala então certamente irá precisar partir para soluções cooporativas e caras certo???

A Partir de hoje não !

Tudo que irá precisar é ter internet para acessar o google o Script possue algumas dependencias:

https://github.com/ederwander/Asterisk-Google-Speech-Recognition/blob/master/README

Estou usando novamente o módulo audiolab para efetuar o encode do áudio em FLAC, caso exista alguma dificuldade para a instalação deste módulo poderei pensar em adaptar o código para uso externo do sox ou flac.

Como ele funciona?

  • Atende uma ligação
  • O usuário tem no máximo 10 segundos para efetuar a fala
  • Caso nao encontre atividade de voz encerra com timeout
  • Estratégia para atividade de voz verdadeira para os seguintes valores  RMS > 15 e Pitch > 75
  • Se atividade for encontrada o usuário poderá falar por no máximo 10 segundos
  • O script verifica blocos em tempo real com amostras de 1 em 1 segundo e verifica se a fala cessou
  • Caso sim o script interrompe a gravação automáticamente e envia o que foi gravado para o google
  • Caso não o script continua o seu curso até seu máximo de 10 segundos
  • Apos encontrada a resposta da fala no google o script seta a variável “GoogleUtterance”

 

Telas:

 

 

Source em:

https://github.com/ederwander/Asterisk-Google-Speech-Recognition

AGI Portabilidade para números móveis em Asterisk

janeiro 15, 2010 74 comentários

Postei estes dias um source em python para descobrir a portabilidade de números móveis na comunidade Asterisk e meu email começou a lotar sobre perguntas de como construir um AGI para rotear as chamadas por um gateway GSM etc etc.

Cada um tem um cenário diferente do outro vou postar a essencia do Script em Perl + Agi para descobrir para qual operadora um número móvel pertence a partir disso é simples, mas se precisarem de ajuda para algo estamos ae …

Já tem nego me Perguntado pq nao fez em Python o AGI??

R:  Acordei com vontade de fazer em perl …

Script Perl

#!/usr/bin/perl -w

use Asterisk::AGI;
use WWW::Mechanize;
use MIME::Base64;
my $AGI = new Asterisk::AGI;
my %input = $AGI->ReadParse();
my @operadoras = (“Eder”, “Claro”, “Tim”, “Vivo”, “Telemig”, “Oi”, “Nextel”, “Brasil telecom”, “Sercomtel”, “CTBC”);
my $num_saida = $AGI->get_variable(‘EXTEN’);
$num_saida = substr($num_saida,3,10);
$m = WWW::Mechanize->new();
my $data = decode_base64(‘aHR0cDovL3dlYnNlcnZpY2VzLnR3d3dpcmVsZXNzLmNvbS5ici9yZWx1emNhcC93c3JlbHV6Y2FwL’        . ‘mFzbXg=’);
$m->add_header(Referer => $data);
my $s = $data . “/VerOperadora?celular=55” . $num_saida;
$m->get($s);
$c = $m->content;
$c =~ m/>(\d+)</;
$AGI->exec(“NoOp”,”$num_saida”);
$AGI->exec(“NoOp”,”$operadoras[$1]”);

# O codigo se adapta conforme o cenario de cada um, mudar o DIAL para rotear a saida da operadora em questao
####$AGI->exec(“Dial”,”SIP/MUDE AQUI PARA SUA SAIDA SIP ou GSM ou ZAP ou DAHDI ou UNICALL ou DVG etc etc|10″);

# FIM

Extensions.conf

minha linha para a chamada do AGI de testes

exten => _999.,1,agi,pega.pl

ou seja só discar no seu telefoneIP ou sftphone “999+num_do_celular”

Tela:

UPDATE:

12/03/2014

É incrível a quantidade de emails que recebo pedindo para encontrar meios de mostrar números portados, hoje eu tive um tempinho e escrevi um novo código, se olharem no código vão perceber que eu inclui um proxy para enviar as requisições, o site é bem “esperto” e bloqueia todo o range de IP de sua rede pública se ocorrer muitos requests, (descobri isso  da pior maneira enquanto debugava o site), então vocês podem criar uma lista randômica com vários IPs que tenham proxy aberto para enviar as solicitações, código em https://gist.github.com/ederwander/9512693 !

Fui

Eng Eder de Souza

Monitor Realtime + Asterisk

novembro 6, 2009 11 comentários

Bom só quem brincou com AMI no Asterisk sabe como é complicado, Eventos jogados na tela nada parece ter sentido uma avalanche de informações sem padrões definidos, construir aplicações genéricas se torna uma missão. 

Eu iniciei a pouco mais de dois anos um projeto monitor em Realtime a principio era para monitoramento só para verificar quem estava fazendo ou recebendo ligações, pensei “Moleza Delphi + Socket + AMI”. 

Dores e mais dores de cabeça na época tinha um link R2 com uma placa da digium rodando com o Unicall para quem tinha placa E1 Digium era a única saida de conversar com a sinalização R2. Então olhando o retorno do AMI iniciei um esboço de como pegar o retorno no buffer do meu Socket em Delphi 6.0 e montar algo bonitinho para usuários ficarem vendo tudo que acontece de atividade no canal Unicall do Asterisk !! 

Então vamos ver o que um core show channels verbose nos retorna !! 

Channel              Context              Extension        Prio State   Application  Data                      CallerID        Duration Accountcode BridgedTo
UniCall/16-1         default              1579                1 Up      Bridged Call SIP/6007-00f839c0         80151333623971                       SIP/6007-00f839c0
SIP/6007-00f839c0    default              80151333623971     22 Up      Dial         Unicall/g1/0151333623971  6007            00:02:40             UniCall/16-1
UniCall/14-1         default              1599                1 Up      Bridged Call SIP/6004-00d2fe00         80151938622970                       SIP/6004-00d2fe00
SIP/6004-00d2fe00    default              80151938622970     22 Up      Dial         Unicall/g1/0151938622970  6004            00:03:52             UniCall/14-1
UniCall/11-1         default              1599                1 Up      Bridged Call SIP/6006-00ea6650         80151335689403                       SIP/6006-00ea6650
SIP/6006-00ea6650    default              80151335689403     22 Up      Dial         Unicall/g1/0151335689403  6006            00:05:18             UniCall/11-1
SIP/6008-00e46a10    default                                  1 Up      Bridged Call UniCall/12-1              1938323241                           UniCall/12-1
UniCall/12-1         default              91000               3 Up      Queue        atendimento|r|||90        1938323241      00:06:10             SIP/6008-00e46a10
UniCall/10-1         default              1599                1 Up      Bridged Call SIP/6002-00f034c0         881895124                            SIP/6002-00f034c0
SIP/6002-00f034c0    default              881895124          22 Up      Dial         Unicall/g1/81895124       6002            00:06:37             UniCall/10-1
UniCall/13-1         default              1599                1 Up      Bridged Call SIP/6005-00f15800         808007771007                         SIP/6005-00f15800
SIP/6005-00f15800    default              808007771007       22 Up      Dial         Unicall/g1/08007771007    6005            00:09:02             UniCall/13-1
12 active channels
6 active calls

Bagunça !!!! 

Então a idéia seria filtrar essa bagunça e procurar por palavras chaves Criando uma funçao Busca para isso !!

Function BuscaTexto(Text,Busca : string) : string;
var n : integer;
begin
  for n := 1 to length(Text) do
    begin
       if Copy(Text,n,length(Busca)) = Busca then
          begin
             Result := ‘ok’;
             RetornoBuscaPos:=n;

          end;

    end;
end;

Agora eu poderia pegar dentro do Buffer do socket qualquer palavra chave como a “Unicall/g1”  e depois caminhar com um ponteiro para recortar isso em qualquer lugar e depois só teria que colocar o valor no GRID. 

Entao como ficaria: 

if BuscaTexto(Msg,’Unicall/g1/’) = ‘ok’ then
        begin
        if Copy(Msg,86,RetornoBuscaPos-79) = ‘Unicall’ then
          //pega o ramal que originou a chamada
          MainForm.StringGrid1.Cells[0,contador]:= Copy(Msg,5,RetornoBuscaPos-82);
          //pega o numero discado para fora destino ‘ ‘Unicall/g1/’
          MainForm.StringGrid1.Cells[1,contador]:= Copy(Msg,97,RetornoBuscaPos-71);

  
Extremamente Trabalhoso Marinheiro de Primeira viagem um colega de cuiaba o Juniou tbm embarcou nessa aventura ele mal dormia, por fim segue algumas telas depois de todo o trabalho …   

voip-monitor 

Tela com opção de verificar chamadas recebidas

programa-asterisk  

Monitor 

Assim tudo em AMI eu teria o retorno de 5 em 5 segundos do comando “core show channels verbose” na qual montaria a tela de ligações em um intervalo de 5 em 5 segundos…. 

Até a Proxima

Eng Eder de Souza