
Estou tentando escrever um programa que ajude a ler documentos de texto e PDF em C usando programas de código aberto no Raspberry Pi.
o programa é simples, nada complicado.....
Estou me conectando ao Raspberry Pi através do ssh do meu laptop... O encaminhamento do X está funcionando bem porque posso iniciar aplicativos X a partir da linha de comando sem problemas.
Estou usando o Apache2 no Raspberry Pi e criei uma interface de usuário para este programa onde você pode colar texto, fazer upload de arquivos de texto ou arquivos PDF.
O texto é convertido em fala com espeak, que salva a saída em um arquivo wave.
Agora o problema é que eu uso:
system("xmms2 play file.wav &")
no código C ........ apenas uma breve descrição
ele compila ..... quando tento na página da web, ele exibe erros:
Gtk-WARNING **: cannot open display: localhost:10.0
cannot start xmms2d.....failed to start xmms2 server
até tentei outro reprodutor de áudio chamado aqualung e funcionou uma vez, mas no dia seguinte, quando reinicio o computador, ele não funciona mais.
pesquisei no Google e fiz de tudo, desde export DISPLAY=:0.0
garantir que o nome do host no cliente e no host não seja localhost, mas sem sucesso
Então eu acho que talvez haja algo que eu não adicionei no programa C, talvez um arquivo de cabeçalho que precisa ser adicionado ou algo parecido.....Gtk+ está instalado no meu framboesa....
Ou talvez eu não deva fazer isso como um programa C, mas sim fazer tudo em bash ou php....
se eu usar o aplay para reproduzir o arquivo wav, obtenho saída de som, a única diferença é que preciso de algo com linha de comando e interface de usuário. para que eu possa enviar comandos do programa e também o usuário possa pausar e reproduzir o arquivo quando quiser.
Por favor, alguns conselhos são necessários... aqui está o código
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <wiringPi.h>
char readcmd(void) //reading from text file /home/pi/cmdrdy.txt first character is read
{ //whenever text is received a 1 is written to this file, 2 for file received
FILE *stream;
int ch;
if( (stream = fopen("/home/pi/txtrdy.txt", "r")) == NULL )
return 0;
ch = fgetc( stream );
fclose( stream );
return (ch-'0');
}
void reset()
{
FILE *ft;
char ch;
ft = fopen( "/home/pi/cmdrdy.txt", "w" );
ch = '0';
fprintf(ft, "%c", ch );
fclose(ft);
}
void checktxt(){
if(readcmd() == 1)
{
system("espeak -v en -f /home/pi/book.txt -w /home/pi/text.wav &");
reset(); //to reset the text received flag to 0
system("xmms2 play /home/pi/text.wav &");
}
if(readcmd2() == 2)
{
system("pdftotext -layout /home/pi/upload/*.pdf /home/pi/converted.txt &");
delay(300);
system("espeak -v en -f /home/pi/converted.txt -w /home/pi/book.wav &");
delay(500);
system("sudo rm /home/pi/converted.txt");
system("sudo rm /home/pi/upload/*.pdf");
system("xmm2 play /home/pi/book.wav &");
}
}
void main(){
while(1){
checktxt();
}
}
Responder1
Eu mesmo não me deparei com esse problema, mas posso me aventurar a adivinhar por que isso está acontecendo: pelo que parece, parece que xauth não se estende ao processo filho. Na verdade, não consegui localizar XAUTHORITY na saída de
export -p
em um Raspberry rodando Raspian.
Não consegui estabelecer com certeza, pesquisando no Google, que esse é realmente o caso mesmo para outros sistemas operacionais, mas é tão fácil tentar consertar isso que vale a pena tentar de qualquer maneira. Sugiro que você substitua o comando por um script executável, chame-o de /home/my_name/bin/my_script, tornado executável por meio, chmod 755
é claro, no qual você coloca as seguintes 3 linhas de código:
#!/bin/bash
export XAUTHORITY=/home/my_name/.Xauthority
xmms2 play file.wav &
Como a system
chamada primeiro se bifurca e depois inicia uma instância do shell com as variáveis de ambiente do chamador, seu programa sabe (e prova que sabe) que seu display é 10.0
, mas o acesso a ele deve ser concedido dentro do subshell no qual o comando xmms2
é executado. Esta modificação garante isso.
Responder2
Eu modifiquei um pouco o código acima e adicionei o conselho a ele
incluir
incluir
incluir
incluir
typedef enum {WAIT, TEXT, PDF, DOC}STATES; typedef char ESTADO; ESTADO estado_atual;
char readcmd() //lendo do arquivo de texto /home/pi/cmdrdy.txt o primeiro caractere é lido { FILE *stream; int ch; if( (stream = fopen("/home/pi/cmdrdy.txt", "r")) == NULL ) return 0; ch =fgetc(fluxo); fclose(fluxo); retornar (ch-'0'); }
void reset()
{ ARQUIVO *ft; char; ft = fopen( "/home/pi/cmdrdy.txt", "w" ); ch = '0'; fprintf(ft, "%c", ch); ffechar(pés); }
char convtts() { //convert text to speech
system("espeak -v en -f /home/pi/book.txt -w /home/pi/text.wav &");
return (0);
}
char pdf2txt(){ //convert pdf to text
system("pdftotext -layout /usr/lib/cgi-bin/upload/*.pdf /home/pi/converted.txt");
return (0);
}
char pdftts(){ //convert converted text to speech
system("espeak -v en -f /home/pi/converted.txt -w /home/pi/book.wav &");
return(0);
}
void state_machine(void){ //creating a state machine
switch(current_state){
case WAIT:
if(readcmd() == 1)
{
reset();
current_state = TEXT;
}
if(readcmd() == 2)
{
reset();
current_state = PDF;
}
break;
case TEXT:
convtts();
while(convtts()==1);
system("/home/pi/bin/text_script");
current_state = WAIT;
break;
case PDF:
pdf2txt();
while(pdf2txt()==1);
pdftts();
while(pdftts()==1);
system("/home/pi/bin/book_script");
system("sudo rm /usr/lib/cgi-bin/upload/*.pdf");
current_state = WAIT;
break;
} }
void main(){
while(1){
state_machine();
} }
E funciona perfeitamente... um milhão de obrigados