我正在为我的覆盆子皮写一个媒体服务器。我能够创建一个程序,使用popen通过远程控制omxplayer。
我现在想控制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, "-@ ");
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表示随机播放)。
最佳答案
正如J.F.塞巴斯蒂安在评论中所说,“你自己提供一个伪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 = "-@";
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);
}
}
关于c - 为什么Popen无法与mpg123通信?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33678441/