
저는 라즈베리 파이의 오픈 소스 프로그램을 사용하여 C에서 텍스트와 PDF 문서를 읽는 데 도움이 되는 프로그램을 작성하려고 합니다.
프로그램은 간단하고 복잡하지 않습니다.....
내 노트북에서 SSH를 통해 라즈베리 파이에 연결하고 있습니다... X 전달은 아무 문제 없이 명령줄에서 X 응용 프로그램을 시작할 수 있기 때문에 제대로 작동합니다.
저는 라즈베리 파이에서 apache2를 사용하고 있으며 텍스트를 붙여넣거나 텍스트 파일 또는 PDF 파일을 업로드할 수 있는 이 프로그램에 대한 사용자 인터페이스를 만들었습니다.
텍스트는 출력을 웨이브 파일에 저장하는 espeak를 사용하여 음성으로 변환됩니다.
이제 문제는 다음을 사용한다는 것입니다.
system("xmms2 play file.wav &")
C 코드에서 .......간단한 설명
컴파일됩니다.....웹 페이지에서 시도하면 오류가 표시됩니다.
Gtk-WARNING **: cannot open display: localhost:10.0
cannot start xmms2d.....failed to start xmms2 server
aqualung이라는 다른 오디오 플레이어도 사용해 보았는데 한 번은 작동했지만 다음 날 컴퓨터를 다시 시작하면 더 이상 작동하지 않습니다.
나는 검색을 통해 export DISPLAY=:0.0
클라이언트와 호스트의 호스트 이름이 localhost가 아닌지 확인하는 것까지 모든 작업을 수행했지만 성공하지 못했습니다.
그래서 아마도 C 프로그램에 추가하지 않은 것이 있을 수도 있고, 추가해야 할 헤더 파일 등이 있을 수도 있습니다. Gtk+가 내 라즈베리에 설치되어 있을 수도 있습니다....
아니면 C 프로그램으로 하지 말고 bash나 PHP로 모든 것을 해야 할 수도 있습니다....
aplay를 사용하여 wav 파일을 재생하면 사운드 출력이 표시됩니다. 유일한 차이점은 명령줄과 사용자 인터페이스가 필요하다는 점입니다. 그래서 프로그램에서 명령을 보낼 수 있고 사용자는 원할 때마다 파일을 일시 중지하고 재생할 수 있습니다.
Pls 몇 가지 조언이 필요합니다.... 코드는 다음과 같습니다.
#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();
}
}
답변1
나는 이 문제에 직접 부딪히지는 않았지만 왜 이런 일이 일어나고 있는지에 대해 교육받은 추측을 할 수 있습니다. 겉으로 보기에는 xauth가 하위 프로세스로 확장되지 않는 것처럼 보입니다. 실제로 출력에서 XAUTHORITY를 찾을 수 없었습니다.
export -p
Raspian을 실행하는 Raspberry에서.
인터넷 검색을 통해 다른 OS에서도 이것이 실제로 해당되는지 확실히 확인할 수는 없었지만 이 문제를 시도하고 수정하는 것은 매우 쉽기 때문에 어쨌든 시도해 볼 가치가 있습니다. 명령을 실행 가능한 스크립트로 대체하는 것이 좋습니다. 이름은 /home/my_name/bin/my_script입니다. 당연히 실행 가능하게 만들어 chmod 755
다음 3줄의 코드를 배치합니다.
#!/bin/bash
export XAUTHORITY=/home/my_name/.Xauthority
xmms2 play file.wav &
호출 system
은 먼저 분기된 다음 호출자 환경 변수를 사용하여 셸의 인스턴스를 시작하므로 프로그램은 디스플레이가 임을 알고 있지만(그리고 알고 있음을 증명) 10.0
이에 대한 액세스는 명령이 실행되는 하위 셸 내에서 부여되어야 합니다 xmms2
. 이 수정을 통해 이를 보장합니다.
답변2
이제 위의 코드를 약간 수정하고 조언을 추가했습니다.
포함하다
포함하다
포함하다
포함하다
typedef enum {WAIT, TEXT, PDF, DOC}STATES; typedef char STATE; STATE 현재_상태;
char readcmd() //텍스트 파일에서 읽기 /home/pi/cmdrdy.txt 첫 번째 문자를 읽습니다. { FILE *stream; int ch; if( (stream = fopen("/home/pi/cmdrdy.txt", "r")) == NULL ) return 0; ch =fgetc(스트림); fclose(스트림); 반환(ch-'0'); }
void reset()
{ 파일 *ft; 문자 ch; ft = fopen( "/home/pi/cmdrdy.txt", "w" ); ch = '0'; fprintf(ft, "%c", ch ); fclose(피트); }
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();
} }
정말 매력적이네요......정말 감사합니다