
Estoy intentando escribir un programa que me ayude a leer documentos de texto y PDF en C utilizando programas de código abierto en Raspberry Pi.
el programa es sencillo, nada complicado.....
Me estoy conectando a Raspberry Pi a través de ssh desde mi computadora portátil... El reenvío de X funciona bien porque puedo iniciar aplicaciones X desde la línea de comandos sin ningún problema.
Estoy usando apache2 en raspberry pi y he creado una interfaz de usuario para este programa donde puedes pegar texto, cargar archivos de texto o archivos pdf.
El texto se convierte a voz con espeak, que guarda el resultado en un archivo wave.
Ahora el problema es que uso:
system("xmms2 play file.wav &")
en el código C ........solo una breve descripción
se compila... cuando lo intento desde la página web muestra errores:
Gtk-WARNING **: cannot open display: localhost:10.0
cannot start xmms2d.....failed to start xmms2 server
Incluso probé con otro reproductor de audio llamado aqualung y funcionó una vez, pero al día siguiente, cuando reinicio la computadora, ya no funciona.
Busqué en Google y hice todo, desde export DISPLAY=:0.0
asegurarme de que el nombre de host en el cliente y el host no sea localhost, pero no tuve éxito.
Entonces creo que tal vez hay algo que no agregué en el programa C, tal vez un archivo de encabezado que deba agregarse o algo así... Gtk+ está instalado en mi Raspberry...
O tal vez no debería hacerlo como un programa en C sino hacer todo en bash o php....
si uso aplay para reproducir el archivo wav, obtengo salida de sonido, la única diferencia es que necesito algo con línea de comando e interfaz de usuario. así puedo enviar comandos desde el programa y además el usuario puede pausar y reproducir el archivo cuando quiera.
Por favor, se necesita algún consejo... aquí está el 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();
}
}
Respuesta1
Yo no me he encontrado con este problema, pero puedo aventurarme a hacer una suposición fundamentada de por qué sucede esto: por lo que parece, parece que xauth no se extiende al proceso secundario. De hecho, no pude ubicar XAUTHORITY en la salida de
export -p
en una Raspberry ejecutando Raspian.
No pude establecer con certeza, buscando en Google, que este sea el caso incluso para otros sistemas operativos, pero es tan fácil intentar solucionarlo que vale la pena intentarlo de todos modos. Te sugiero que sustituyas el comando por un script ejecutable, llámalo /home/my_name/bin/my_script, hecho ejecutable mediante, chmod 755
por supuesto, en el que coloques las siguientes 3 líneas de código:
#!/bin/bash
export XAUTHORITY=/home/my_name/.Xauthority
xmms2 play file.wav &
Dado que la system
llamada primero se bifurca y luego inicia una instancia del shell con las variables de entorno de la persona que llama, su programa sabe (y demuestra que sabe) que su pantalla es , pero se debe otorgar acceso a ella dentro del subshell en el que se ejecuta 10.0
el comando . xmms2
Esta modificación te garantiza esto.
Respuesta2
Modifiqué un poco el código anterior y le agregué los consejos.
incluir
incluir
incluir
incluir
typedef enum {ESPERAR, TEXTO, PDF, DOC}ESTADOS; typedef char ESTADO; ESTADO estado_actual;
char readcmd() //lectura del archivo de texto /home/pi/cmdrdy.txt se lee el primer carácter { ARCHIVO *stream; int ch; if( (stream = fopen("/home/pi/cmdrdy.txt", "r")) == NULL ) devuelve 0; ch =fgetc( flujo ); fclose(corriente); retorno (ch-'0'); }
void reset()
{ ARCHIVO *pies; char ch; ft = fopen( "/home/pi/cmdrdy.txt", "w" ); ch = '0'; fprintf(ft, "%c", ch); fclose(pies); }
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();
} }
Y funciona a las mil maravillas...un millón de gracias.