【发布时间】:2015-11-12 18:14:52
【问题描述】:
我正在为我的树莓派编写一个媒体服务器。我能够创建一个使用 popen 通过遥控器控制 omxplayer 的程序。
我现在想控制 mpg123 播放音乐。我采用了在 omxplayer 程序中使用 popen 工作的相同代码并将其应用于 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 表示随机播放)。
【问题讨论】:
-
您确定您的 mpg123 使用正确(在 shell 中手动检查)?例如,
-@选项不应该暗示播放列表是在标准输入上给出的,而不是在文件中? -
@J.F.Sebastian 是的,用法是正确的。我通过打印 popen 使用的完整命令并在命令行上运行它来测试它。像它应该的那样工作。
-
您是从键盘输入命令还是使用
{ echo -n command; sleep 5; echo -n command; } | mpg123 ..?它是直接从终端读取命令还是从其标准输入读取命令?无关:在 I/O 期间检查错误(fflush()之后) -
@J.F.Sebastian 是的,它应该来自键盘,因为我只是剪切并粘贴了它输出的内容。用回声做这件事似乎不起作用。 fflush() 没有报告错误。
-
阅读第一个原因:Q: Why not just use a pipe (popen())?。找出是否有一个命令行开关会强制
mpg123从标准输入(或其他一些 fd)读取命令。否则,您可能需要自己提供一个伪 tty。 Here's an example in Python that shows how to read output printed to a tty directly (your case is writing)