
我正在嘗試編寫一個程序,幫助在樹莓派上使用開源程式用 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
確保客戶端上的主機名稱和主機不是本地主機,但沒有成功
所以我想也許有一些東西我沒有在C程序中添加,也許需要添加一個頭文件或類似的東西......Gtk+安裝在我的樹莓派上......
或者也許我不應該將其作為 C 程式來執行,而應該在 bash 或 php 中執行所有操作...
如果我使用 aplay 播放 wav 文件,我會得到聲音輸出,唯一的區別是我需要帶有命令列和用戶界面的東西。這樣我就可以從程式發送命令,用戶也可以隨時暫停和播放檔案。
請需要一些建議......這是程式碼
#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 上。
透過谷歌搜索,我無法確定,即使對於其他作業系統來說,情況確實如此,但嘗試修復這個問題非常容易,無論如何都值得一試。我建議您用可執行腳本取代該命令,將其命名為 /home/my_name/bin/my_script ,當然可以使其可執行chmod 755
,在其中放置以下 3 行程式碼:
#!/bin/bash
export XAUTHORITY=/home/my_name/.Xauthority
xmms2 play file.wav &
由於system
呼叫首先分叉,然後使用呼叫者環境變數啟動 shell 實例,因此您的程式知道(並證明它知道)您的顯示是,但必須在執行10.0
命令的子 shell 內授予對它的存取權限。xmms2
此修改可確保您做到這一點。
答案2
我現在對上面的程式碼做了一些修改,並將建議添加到其中
包括
包括
包括
包括
typedef enum {WAIT, TEXT, PDF, DOC}STATES; typedef 字元狀態;狀態當前狀態;
char readcmd() //從文字檔 /home/pi/cmdrdy.txt 讀取第一個字元 { FILE *stream;整數通道; if( (stream = fopen("/home/pi/cmdrdy.txt", "r")) == NULL ) 回傳 0; ch =fgetc( 流 ); fclose( 流 );返回(ch-'0'); }
void reset()
{ 文件 *ft;字符ch; ft = fopen( "/home/pi/cmdrdy.txt", "w" ); ch = '0'; fprintf(ft, "%c", ch ); fclose(ft); }
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();
} }
它就像魅力一樣......感謝一百萬