2015-11-12 28 views
1

我正在爲我的覆盆子pi編寫一個媒體服務器。我能夠創建一個使用popen通過遙控器控制omplayer的程序。爲什麼不會與mpg123交流?

我現在想控制mpg123的音樂。我用popen在omxplayer程序中使用了相同的代碼並將其應用到mpg123,但它不起作用。它啓動,但不會確認發送給它的任何輸入。我不知道爲什麼一個人會工作,其他人不會。

這裏是我的代碼:

void play_music (char *list, int random) 
{ 
    FILE *pp; 
    char c; 
    char command[501]; 
    struct stat buf; 

    if(access(list, R_OK) == -1) 
    { 
     fprintf(stderr, "%s: play_music: access failed (%s) (%s)\n", program_name, strerror(errno), list); 
     exit(EXIT_FAILURE); 
    } 

    if(stat(list, &buf) == -1) 
    { 
     fprintf(stderr, "%s: play_music: stat failed (%s) (%s)\n", program_name, strerror(errno), list); 
     exit(EXIT_FAILURE); 
    } 

    strcpy(command, "/usr/bin/mpg123 -C "); 

    if(random == 1) 
     strcat(command, "-z "); 

    if(S_ISREG(buf.st_mode) == 1) 
    { 
     strcat(command, "[email protected] "); 
     strcat(command, list); 
    } 
    else if(S_ISDIR(buf.st_mode) == 1) 
    { 
     strcat(command, list); 

     if(list[strlen(list) - 1] != '*') 
     { 
      if(list[strlen(list) - 1] != '/') 
       strcat(command, "/"); 

      strcat(command, "*"); 
     } 
    } 
    else 
    { 
     fprintf(stderr, "%s: play_music: stat reported unknown (%s)\n", program_name, list); 
     exit(EXIT_FAILURE); 
    } 

    strcat(command, " > /dev/null 2>&1"); 

    if((pp = popen(command, "w")) == NULL) 
    { 
     fprintf(stderr, "%s: play_music popen failed (%s)\n", program_name, strerror(errno)); 
     exit(EXIT_FAILURE); 
    } 

    while((c = get_code())) 
    { 
     if(system("pidof mpg123 > /dev/null") != 0) 
      return; 

     switch(c) 
     { 
      case 31: 
       fputc('f', pp); 
       break; 
      case 32: 
       fputc('d', pp); 
       break; 
      case 33: 
       fputc('s', pp); 
       break; 
      case 34: 
       fputc('q', pp); 
     } 

     if(fflush(pp) == EOF) 
     { 
      fprintf(stderr, "%s: play_music fflush failed (%s)\n", program_name, strerror(errno)); 
      exit(EXIT_FAILURE); 
     } 
    } 
} 

我一直在試圖算出這個時間太長了,可有人請幫助!

注:

  • GET_CODE()是基於被按下其遙控器上的按鈕返回int一個工作功能。

  • 變量'list'是目錄路徑或播放列表文件名。

  • 變量'random'是一個int標誌(1表示隨機播放)。

+0

你確定你的mpg123的用法是正確的(手動檢查它的外殼)?例如,不應該' - @'選項暗示播放列表是在stdin上給出的,而不是在文件中給出的? – jfs

+0

@ J.F.Sebastian是的,用法是正確的。我通過打印popen使用的完整命令並在命令行上運行它來測試它。像它應該的那樣工作。 – Deanie

+0

您是從鍵盤輸入命令還是使用'{echo -n command;睡5次; echo -n命令; } | mpg123 ..'?它是否直接從終端讀取命令或從其stdin讀取命令?無關:在I/O期間檢查錯誤(在'fflush()'後面) – jfs

回答

1

正如J.F. Sebastian在評論中所述,「自己提供一個僞tty」原來是我需要做的。創建一個僞終端以充當來自鍵盤的輸入是需要工作的。

下面是修改後的代碼:

void play_music (char *playlist, int random) 
{ 
    char c; 
    int fdm; 
    int fds = 0; 
    int x = 0; 
    pid_t pid; 
    char *flag1 = "/usr/bin/mpg123"; 
    char *flag2 = "-C"; 
    char *flag3 = "-z"; 
    char *flag4 = "[email protected]"; 
    char *flag5 = TEMP_FILE; // /tmp/temp_playlist.pls 
    char *slave_name; 
    char *argv[6]; 
    struct stat buf; 

    if(stat(playlist, &buf) == -1) 
    { 
     fprintf(stderr, "%s: play_music: stat failed (%s) (%s)\n", program_name, strerror(errno), playlist); 
     exit(EXIT_FAILURE); 
    } 

    if((fdm = posix_openpt(O_RDWR)) == -1) 
    { 
     fprintf(stderr, "%s: posix_openpt failed (%s)\n", program_name, strerror(errno)); 
     exit(EXIT_FAILURE); 
    } 

    if(grantpt(fdm) == -1) 
    { 
     fprintf(stderr, "%s: grantpt failed (%s)\n", program_name, strerror(errno)); 
     close(fdm); 
     exit(EXIT_FAILURE); 
    } 

    if(unlockpt(fdm) == -1) 
    { 
     fprintf(stderr, "%s: unlockpt failed (%s)\n", program_name, strerror(errno)); 
     close(fdm); 
     exit(EXIT_FAILURE); 
    } 

    if((slave_name = ptsname(fdm)) == NULL) 
    { 
     fprintf(stderr, "%s: ptsname failed\n", program_name); 
     close(fdm); 
     exit(EXIT_FAILURE); 
    } 

    if((pid = fork()) == -1) 
    { 
     fprintf(stderr, "%s: fork failed (%s)\n", program_name, strerror(errno)); 
     close(fdm); 
     exit(EXIT_FAILURE); 
    } 

    if(pid == 0) // Child 
    { 
     if(setsid() == -1) 
     { 
      fprintf(stderr, "%s: setsid failed (%s)\n", program_name, strerror(errno)); 
      close(fdm); 
      exit(EXIT_FAILURE); 
     } 

     if((fds = open(slave_name, O_RDWR)) == -1) 
     { 
      fprintf(stderr, "%s: open failed (%s)\n", program_name, strerror(errno)); 
      close(fdm); 
      exit(EXIT_FAILURE); 
     } 

     if(dup2(fds, STDIN_FILENO) == -1) 
     { 
      fprintf(stderr, "%s: dup2(1) failed (%s)\n", program_name, strerror(errno)); 
      close(fdm); 
      close(fds); 
      exit(EXIT_FAILURE); 
     } 

     if(dup2(fds, STDOUT_FILENO) == -1) 
     { 
      fprintf(stderr, "%s: dup2(2) failed (%s)\n", program_name, strerror(errno)); 
      close(fdm); 
      close(fds); 
      exit(EXIT_FAILURE); 
     } 

     if(dup2(fds, STDERR_FILENO) == -1) 
     { 
      fprintf(stderr, "%s: dup2(3) failed (%s)\n", program_name, strerror(errno)); 
      close(fdm); 
      close(fds); 
      exit(EXIT_FAILURE); 
     } 

     argv[x++] = flag1; 
     argv[x++] = flag2; 

     if(random == 1) 
      argv[x++] = flag3; 

     argv[x++] = flag4; 

     if(S_ISREG(buf.st_mode) == 1) 
      argv[x++] = playlist; 
     else if(S_ISDIR(buf.st_mode) == 1) 
     { 
      if(make_playlist(playlist) == RETURN_FAILURE) 
      { 
       fprintf(stderr, "%s: play_music: make_playlist failed (%s)\n", program_name, playlist); 
       close(fdm); 
       close(fds); 
       exit(EXIT_FAILURE); 
      } 

      argv[x++] = flag5; 
     } 
     else 
     { 
      fprintf(stderr, "%s: play_music: stat reported unknown (%s)\n", program_name, playlist); 
      close(fdm); 
      close(fds); 
      exit(EXIT_FAILURE); 
     } 

     argv[x++] = NULL; 

     if(execv("/usr/bin/mpg123", argv) == -1) 
     { 
      fprintf(stderr, "%s: execv failed (%s)\n", program_name, strerror(errno)); 
      close(fdm); 
      close(fds); 
      exit(EXIT_FAILURE); 
     } 
    } 
    else // Parent 
    { 
     while((c = get_code()) != 31) 
     { 
      switch(c) 
      { 
       case 30: 
       case 19: 
        write(fdm, " ", 1); 
        break; 
       case 20: // Up 
        write(fdm, "+", 1); 
        break; 
       case 22: // Down 
        write(fdm, "-", 1); 
        break; 
       case 21: // Right 
        write(fdm, "f", 1); 
        break; 
       case 23: // Left 
        write(fdm, "d", 1); 
        break; 
      } 
     } 

     write(fdm, "q", 1); 
     wait(&pid); 
     close(fdm); 

     if(fds != 0) 
      close(fds); 
    } 

} 
相關問題