论坛: 编程破解 标题: unix下为realplayer制作播放列表.pls文件 复制本贴地址    
作者: kert_t8 [kert_t8]    论坛用户   登录
linux下的realplayer没有播放列表功能,但是可以播放.pls这样的列表文件,因此我就想做一个.pls文件的制作器.下面是原型:


代码:

#include <string.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>

int main(int argc, char *argv[]) {
  if (argc<3)
    printf("Command Usage: %s <dirName> <fileName>\n",argv[0]);
  char txtLength[]="length=-1";
  char txtFile[]="file=";
  char txtTitle[]="title=";
  FILE *fileName;
  DIR *curDir;
  struct dirent *deDir;
  struct stat fileStatBuf;

  if ((curDir=opendir(argv[1]))==NULL) {
    printf("Can't open direcotry: %s\n",argv[1]);
    exit (-1);
  }
  if ((fileName=fopen(argv[2], "a"))==NULL) {
    printf("Open file %s failed.\n Exit program\n",argv[2]);
    exit(-1);
  }
  if (fputs("[playlist]", fileName)<0) {
    printf("Write file error:\nfile name: %s\n",argv[2]);
    exit(-1);
  }
  else
    fputc('\n', fileName);

  chdir(argv[1]);
  while ((deDir=readdir(curDir))!=NULL) {
    lstat(deDir->d_name, &fileStatBuf);
    printf("fileName: %s%s\n",argv[1],deDir->d_name);
    if (S_ISREG(fileStatBuf.st_mode)) {
      fputs(txtFile, fileName);
      fputs(argv[1], fileName);
      fputs(deDir->d_name, fileName);
      fputc('\n', fileName);
      fputs(txtTitle, fileName);
      fputs(deDir->d_name, fileName);
      fputc('\n', fileName);
      fputs(txtLength, fileName);
      fputc('\n', fileName);
    }
  }
  if (fputs("[end]", fileName)<0) {
    printf ("Write file error");
    exit(-1);
  }
  closedir(curDir);
  fclose(fileName);
  exit(0);
}



问题是realplayer的这个linux版本做的也很垃圾,对.pls文件的位置要求也很高(需要与文件内部的相对路径相配合对声音文件进行定位),因此,我的程序生成的.pls文件只能在根目录(/)下起作用.并且,为了简便起见,我假设目录下所有的文件都是声音文件(因为符合我的实际情况),并且所有的文件都将被送入播放列表.后续版本中将改进这些问题

以下是我用上面的程序生成的我的一个播放列表
引用:

[playlist]
file=/englishSong/I just call to say you.mp3
title=I just call to say you.mp3
length=-1
file=/englishSong/how can I told her.mp3
title=how can I told her.mp3
length=-1
file=/englishSong/for your eyes only.mp3
title=for your eyes only.mp3
length=-1
file=/englishSong/Say you say me.mp3
title=Say you say me.mp3
length=-1
file=/englishSong/4:55.mp3
title=4:55.mp3
length=-1
file=/englishSong/Magic Boulevard.mp3
title=Magic Boulevard.mp3
length=-1
file=/englishSong/Eyes on me.mp3
title=Eyes on me.mp3
length=-1
file=/englishSong/the sound of silence.mp3
title=the sound of silence.mp3
length=-1
file=/englishSong/endless love.mp3
title=endless love.mp3
length=-1
file=/englishSong/Baby one more time.mp3
title=Baby one more time.mp3
length=-1
file=/englishSong/Right here waiting.mp3
title=Right here waiting.mp3
length=-1
file=/englishSong/super star.mp3
title=super star.mp3
length=-1
file=/englishSong/Casabianca.mp3
title=Casabianca.mp3
length=-1
file=/englishSong/I want it that way.mp3
title=I want it that way.mp3
length=-1
file=/englishSong/Will you wait for me.mp3
title=Will you wait for me.mp3
length=-1
file=/englishSong/smoke gets in your eye.mp3
title=smoke gets in your eye.mp3
length=-1
file=/englishSong/On the califonia high way.mp3
title=On the califonia high way.mp3
length=-1
file=/englishSong/every time you go.mp3
title=every time you go.mp3
length=-1
file=/englishSong/Everything I do.mp3
title=Everything I do.mp3
length=-1
file=/englishSong/birds in the river.mp3
title=birds in the river.mp3
length=-1
file=/englishSong/Unclined melody.mp3
title=Unclined melody.mp3
length=-1
file=/englishSong/that's the love.mp3
title=that's the love.mp3
length=-1
file=/englishSong/wind flowers.mp3
title=wind flowers.mp3
length=-1
file=/englishSong/Take my breath away.mp3
title=Take my breath away.mp3
length=-1
file=/englishSong/love is love.mp3
title=love is love.mp3
length=-1
file=/englishSong/Because I love you.mp3
title=Because I love you.mp3
length=-1
file=/englishSong/nothing gonna change my love for you.mp3
title=nothing gonna change my love for you.mp3
length=-1
file=/englishSong/Power of love.mp3
title=Power of love.mp3
length=-1
[end]




[此贴被 月之御者(kert_t8) 在 02月08日15时22分 编辑过]

地主 发表时间: 05-02-08 15:20

回复: kert_t8 [kert_t8]   论坛用户   登录
嘻嘻,我把发贴子的时候把测试结果中的路径都改了,结果还不错,看不出来

B1层 发表时间: 05-02-08 15:25

回复: kert_t8 [kert_t8]   论坛用户   登录
现在这个程序仅仅可以生成一个简单的.pls文件,但是我希望realplayer可以实现重复播放,随机播放等功能,于是想到通过在.pls文件中随机打乱文件顺序,以及重复引用相同的item

这样,数据(文件名)就不可以从目录中读出以后直接写到文件中,必需以某种方式存储并进行操作.自然想到链表.下面实现的就是这个数据结构

为了增加代码的可复用性,我将数据项(代码中的 struct playNode),链表节点(struct Node)以及链表本身(struct table)分开,并且将针对数据项的代码与针对节点及链表的代码分开到两组文件中

makefile
代码:

table: table.o node.o
gcc -o table table.o node.o

table.o: table.c
gcc -c -o table.o table.c

node.o: node.c node.h
gcc -c -o node.o node.c



node.h
代码:

#include <string.h>
#include <stdlib.h>

#define DIR_LENGTH 1024
#define NAME_LENGTH 512
#define TITLE_LENGTH 100
#define AUTHOR_LENGTH 50

typedef struct playNode {
char dirPath[DIR_LENGTH];
char fileName[NAME_LENGTH];
char title[TITLE_LENGTH];
char author[AUTHOR_LENGTH];
} song;

song *newNode (char *, char *);
song *dieNode(song *);
void output(song *);



node.c
代码:

#include "node.h"

song *newNode (char *path, char *filename) {
song *mySong;
mySong=malloc(sizeof(song));
int length;
if ((length=strlen(path))>DIR_LENGTH) {
printf("Error: length of path is too long. %d characters\n", length);
free(mySong);
return NULL;
}
else
strncpy(mySong->dirPath, path, length);

if ((length=strlen(filename))>NAME_LENGTH) {
printf("Error: length of file name is too long. %d characters\n", length);
free(mySong);
return NULL;
}
else
strncpy(mySong->fileName, filename, length);

return mySong;
}

song *dieNode(song *node) {
if (node!=NULL)
free(node);
return NULL;
}

void output(song *node) {
printf("------ Node Information ------\n");
printf("Directory: %s\n",node->dirPath);
printf("File Name: %s\n",node->fileName);
printf("----- End of Information -----\n");
}

/* test for correctness */
/*
int main(int argc, char *argv[]) {
char abc[]="abcdefghijklmnopqrstuvwxyz";
char num[]="1234567890";

struct playNode *oneSong;
oneSong=newNode(argv[1], argv[2], NULL, NULL);
output(oneSong);
oneSong=dieNode(oneSong);
return 0;
}
*/
/* end of test */



table.c
代码:

#include <stdlib.h>
#include "node.h"

#define nodeType song

/*
* This program could provide an abstract link table. This table conserns nothing
* about the data structure it will contain. With `#define nodeType xxxx' we could make
* this program suitable for any data structure.
*
* struct Node defines a Node which have two pointers pointing to the previous node
* and next node and another pointer pointing to the data which should be contained in
* this node.
*
* struct table defines a real link table which has tree pointers. One head, one end
* and one operating pointer. Those pointers will point to struct Node which will be nodes
* in the program.
*
*/

typedef struct Node {
struct Node *nextNode;
struct Node *preNode;
nodeType *thisNode;
} typNode;

typedef struct table {
typNode *headerPtr;
typNode *nowPtr;
typNode *endPtr;

// int numOfNodes;
} linkTable;



/*
* genNode() and killNode() are two functions which will generate and kill a typNode
* from the data provided by users.
*
*/

typNode *genNode(nodeType *node) {
typNode *myNode;
myNode=malloc(sizeof(typNode));
if ((myNode->thisNode=node)==NULL) {
free(myNode);
return NULL;
}
myNode->nextNode=NULL;
myNode->preNode=NULL;
return myNode;
}

typNode *killNode(typNode *node) {
free(node->thisNode);
free(node);
return NULL;
}


/*
* In section below, we have creatTable(), insert(), move(), del(), delTable() which
* could manage the link table with creation, insertion, op-pointer moving forward and
* backward, removing node, and closing the whole table. Also, we have readTable() which
* returns a pointer pointing to the content of op-pointer (that is pointer *thisNode in
* struct Node).
* For convenience, we also have dispTable() which could print all the items in the
* table, but because it concerns too much about `NodeType', it may not appear when we reuse
* this program.
*
*/

linkTable *creatTable(nodeType *head) {
linkTable *myTable;
typNode *firstNode;
myTable=malloc(sizeof(linkTable));
firstNode=genNode(head);
myTable->headerPtr=firstNode;
myTable->nowPtr=firstNode;
myTable->endPtr=firstNode;
// myTable->numOfNodes=1;
return myTable;
}

void insert(linkTable *myTable, nodeType *thisNode) {
typNode *nodePtr;
nodePtr=genNode(thisNode);
if (myTable->nowPtr==myTable->endPtr) {
myTable->endPtr=nodePtr;
nodePtr->preNode=myTable->nowPtr;
myTable->nowPtr->nextNode=nodePtr;
}
else {
nodePtr->preNode=myTable->nowPtr;
move(myTable, 1);
myTable->nowPtr->preNode=nodePtr;
nodePtr->nextNode=myTable->nowPtr;
nodePtr->preNode->nextNode=nodePtr;
}
myTable->nowPtr=nodePtr;
}

/*
void search(linkTable *myTable) {

}
*/


// int move(linkTable *, int) will move linkTable op-pointer forward [step] steps.
// if step>0, op-pointer will move forward, or it will move backward. once op-pointer
// reaches the bottom, or the top, of the table, it will stop. The value move() return
// will be ([step]-[steps actually moved]), that is how many steps left -- didn't move.

int move(linkTable *myTable, int step) {
if (step<0)
while (myTable->nowPtr->preNode!=NULL && step++!=0)
myTable->nowPtr=myTable->nowPtr->preNode;
else if (step>0)
while (myTable->nowPtr->nextNode!=NULL && step--!=0)
myTable->nowPtr=myTable->nowPtr->nextNode;
return step;
}

linkTable *del(linkTable *myTable) {
if (myTable->nowPtr==myTable->headerPtr) {
if (move(myTable, 1)==1) {
myTable->nowPtr=killNode(myTable->nowPtr);
myTable->endPtr=NULL;
myTable->headerPtr=NULL;
free(myTable);
return NULL;
}
else {
myTable->nowPtr->preNode=NULL;
myTable->headerPtr=killNode(myTable->headerPtr);
myTable->headerPtr=myTable->nowPtr;
return myTable;
}
}
else if (myTable->nowPtr==myTable->endPtr) {
move(myTable, -1);
myTable->nowPtr->nextNode=NULL;
myTable->endPtr=killNode(myTable->endPtr);
myTable->endPtr=myTable->nowPtr;
return myTable;
}
else {
typNode *tmp;
tmp=myTable->nowPtr;
move(myTable, -1);
tmp->preNode->nextNode=tmp->nextNode;
tmp->nextNode->preNode=tmp->preNode;
tmp=killNode(tmp);
return myTable;
}
}

linkTable *delTable(linkTable *myTable) {
// del all the nodes;
myTable->nowPtr=myTable->headerPtr;
while((myTable=del(myTable))!=NULL)
;
return NULL;
}

nodeType *readNode(linkTable *myTable) {
return myTable->nowPtr->thisNode;
}

void dispTable(linkTable *myTable) {
typNode *tmpPtr;
tmpPtr=myTable->nowPtr;
myTable->nowPtr=myTable->headerPtr;
do {
output(readNode(myTable));
} while (move(myTable, 1)!=1);
myTable->nowPtr=tmpPtr;
}

/* Test for correctness */
int main(int argc, char *argv[]) {
int i=0;
song *mySong;
mySong=newNode(argv[0],argv[0]);
linkTable *myTable;
myTable=creatTable(mySong);
for (i=1;i<argc;i++) {
mySong=newNode(argv[i],argv[i]);
insert(myTable, mySong);
}
myTable->nowPtr=myTable->headerPtr;
do {
output(readNode(myTable));
} while (move(myTable, 1)!=1);
printf("\n\n************ Here's another version of the table ***************\n\n");
dispTable(myTable);

myTable=delTable(myTable);
return 0;
}
/* End of Test */



一个运行实例
引用:

Script started on 2005年02月12日 星期六 01时02分18秒
]0;macavity@Macavity:~/cpractice/plsMaker[macavity@Macavity plsMaker]$ make

gcc -c -o table.o table.c

gcc -c -o node.o node.c

gcc -o table table.o node.o

]0;macavity@Macavity:~/cpractice/plsMaker[macavity@Macavity plsMaker]$ ./table

------ Node Information ------

Directory: ./table

File Name: ./table

----- End of Information -----





************ Here's another version of the table ***************



------ Node Information ------

Directory: ./table

File Name: ./table

----- End of Information -----

]0;macavity@Macavity:~/cpractice/plsMaker[macavity@Macavity plsMaker]$ ./table a b c

------ Node Information ------

Directory: ./table

File Name: ./table

----- End of Information -----

------ Node Information ------

Directory: a

File Name: a

----- End of Information -----

------ Node Information ------

Directory: b

File Name: b

----- End of Information -----

------ Node Information ------

Directory: c

File Name: c

----- End of Information -----





************ Here's another version of the table ***************



------ Node Information ------

Directory: ./table

File Name: ./table

----- End of Information -----

------ Node Information ------

Directory: a

File Name: a

----- End of Information -----

------ Node Information ------

Directory: b

File Name: b

----- End of Information -----

------ Node Information ------

Directory: c

File Name: c

----- End of Information -----

]0;macavity@Macavity:~/cpractice/plsMaker[macavity@Macavity plsMaker]$ exit

exit


Script done on 2005年02月12日 星期六 01时02分33秒




B2层 发表时间: 05-02-12 16:04

回复: kert_t8 [kert_t8]   论坛用户   登录
正在练习使用指针

有些晕

B3层 发表时间: 05-02-12 16:08

回复: kert_t8 [kert_t8]   论坛用户   登录
makefile
代码:

plsMaker: table.o node.o plsMaker.o
gcc -o plsMaker table.o node.o plsMaker.o

plsMaker.o: plsMaker02.c
gcc -c -o plsMaker.o plsMaker02.c

table.o: table.c table.h
gcc -c -o table.o table.c

node.o: node.c node.h
gcc -c -o node.o node.c




table.c
代码:
#include "table.h"


/*
* This program could provide an abstract link table. This table conserns nothing
* about the data structure it will contain. With `#define nodeType xxxx' we could make
* this program suitable for any data structure.
*
* struct Node defines a Node which have two pointers pointing to the previous node
* and next node and another pointer pointing to the data which should be contained in
* this node.
*
* struct table defines a real link table which has tree pointers. One head, one end
* and one operating pointer. Those pointers will point to struct Node which will be nodes
* in the program.
*
*/




/*
* genNode() and killNode() are two functions which will generate and kill a typNode
* from the data provided by users.
*
*/

typNode *genNode(nodeType *node) {
typNode *myNode;
myNode=malloc(sizeof(typNode));
if ((myNode->thisNode=node)==NULL) {
free(myNode);
return NULL;
}
myNode->nextNode=NULL;
myNode->preNode=NULL;
return myNode;
}

typNode *killNode(typNode *node) {
node->thisNode=dieNode(node->thisNode);
free(node);
return NULL;
}


/*
* In section below, we have creatTable(), insert(), move(), del(), delTable() which
* could manage the link table with creation, insertion, op-pointer moving forward and
* backward, removing node, and closing the whole table. Also, we have readTable() which
* returns a pointer pointing to the content of op-pointer (that is pointer *thisNode in
* struct Node).
* For convenience, we also have dispTable() which could print all the items in the
* table, but because it concerns too much about `NodeType', it may not appear when we reuse
* this program.
*
*/

linkTable *creatTable(nodeType *head) {
linkTable *myTable;
typNode *firstNode;
myTable=malloc(sizeof(linkTable));
firstNode=genNode(head);
myTable->headerPtr=firstNode;
myTable->nowPtr=firstNode;
myTable->endPtr=firstNode;
// myTable->numOfNodes=1;
return myTable;
}

void insert(linkTable *myTable, nodeType *thisNode) {
typNode *nodePtr;
nodePtr=genNode(thisNode);
if (myTable->nowPtr==myTable->endPtr) {
myTable->endPtr=nodePtr;
nodePtr->preNode=myTable->nowPtr;
myTable->nowPtr->nextNode=nodePtr;
}
else {
nodePtr->preNode=myTable->nowPtr;
move(myTable, 1);
myTable->nowPtr->preNode=nodePtr;
nodePtr->nextNode=myTable->nowPtr;
nodePtr->preNode->nextNode=nodePtr;
}
myTable->nowPtr=nodePtr;
}

/*
void search(linkTable *myTable) {

}
*/


// int move(linkTable *, int) will move linkTable op-pointer forward [step] steps.
// if step>0, op-pointer will move forward, or it will move backward. once op-pointer
// reaches the bottom, or the top, of the table, it will stop. The value move() return
// will be ([step]-[steps actually moved]), that is how many steps left -- didn't move.

int move(linkTable *myTable, int step) {
if (step<0)
while (myTable->nowPtr->preNode!=NULL && step++!=0)
myTable->nowPtr=myTable->nowPtr->preNode;
else if (step>0)
while (myTable->nowPtr->nextNode!=NULL && step--!=0)
myTable->nowPtr=myTable->nowPtr->nextNode;
return step;
}

linkTable *del(linkTable *myTable) {
if (myTable->nowPtr==myTable->headerPtr) {
if (move(myTable, 1)==1) {
myTable->nowPtr=killNode(myTable->nowPtr);
myTable->endPtr=NULL;
myTable->headerPtr=NULL;
free(myTable);
return NULL;
}
else {
myTable->nowPtr->preNode=NULL;
myTable->headerPtr=killNode(myTable->headerPtr);
myTable->headerPtr=myTable->nowPtr;
return myTable;
}
}
else if (myTable->nowPtr==myTable->endPtr) {
move(myTable, -1);
myTable->nowPtr->nextNode=NULL;
myTable->endPtr=killNode(myTable->endPtr);
myTable->endPtr=myTable->nowPtr;
return myTable;
}
else {
typNode *tmp;
tmp=myTable->nowPtr;
move(myTable, -1);
tmp->preNode->nextNode=tmp->nextNode;
tmp->nextNode->preNode=tmp->preNode;
tmp=killNode(tmp);
return myTable;
}
}

linkTable *delTable(linkTable *myTable) {
// del all the nodes;
myTable->nowPtr=myTable->headerPtr;
while((myTable=del(myTable))!=NULL)
;
return NULL;
}

nodeType *readNode(linkTable *myTable) {
return myTable->nowPtr->thisNode;
}

void dispTable(linkTable *myTable) {
typNode *tmpPtr;
tmpPtr=myTable->nowPtr;
myTable->nowPtr=myTable->headerPtr;
do {
output(readNode(myTable));
} while (move(myTable, 1)!=1);
myTable->nowPtr=tmpPtr;
}

/* Test for correctness */
/*
int main(int argc, char *argv[]) {
int i=0;
song *mySong;
mySong=newNode(argv[0],argv[0]);
linkTable *myTable;
myTable=creatTable(mySong);
for (i=1;i<argc;i++) {
mySong=newNode(argv[i],argv[i]);
insert(myTable, mySong);
}
myTable->nowPtr=myTable->headerPtr;
do {
output(readNode(myTable));
} while (move(myTable, 1)!=1);
printf("\n\n************ Here's another version of the table ***************\n\n");
dispTable(myTable);

myTable=delTable(myTable);
return 0;
}
*/
/* End of Test */




table.h
代码:

#include <stdlib.h>
#include "node.h"

#define nodeType song

typedef struct Node {
struct Node *nextNode;
struct Node *preNode;
nodeType *thisNode;
} typNode;

typedef struct table {
typNode *headerPtr;
typNode *nowPtr;
typNode *endPtr;

// int numOfNodes;
} linkTable;

typNode *genNode(nodeType *);
typNode *killNode(typNode *);
linkTable *creatTable(nodeType *);
void insert(linkTable *, nodeType *);
int move(linkTable *, int);
linkTable *del(linkTable *);
linkTable *delTable(linkTable *);
nodeType *readNode(linkTable *);
void dispTable(linkTable *);
linkTable *creatTable(nodeType *);




node.c
代码:

#include "node.h"

song *newNode (char *path, char *filename) {
song *mySong;
mySong=malloc(sizeof(song));
int length;
if ((length=strlen(path))>DIR_LENGTH-1) {
printf("Error: length of path is too long. %d characters\n", length);
free(mySong);
return NULL;
}
else
strncpy(mySong->dirPath, path, length);
if (getPath(path)==0)
strcat(mySong->dirPath, "/");

if ((length=strlen(filename))>NAME_LENGTH-1) {
printf("Error: length of file name is too long. %d characters\n", length);
free(mySong);
return NULL;
}
else
strncpy(mySong->fileName, filename, length);

return mySong;
}

song *dieNode(song *node) {
if (node!=NULL)
free(node);
return NULL;
}

void output(song *node) {
printf("------ Node Information ------\n");
printf("Directory: %s\n",node->dirPath);
printf("File Name: %s\n",node->fileName);
printf("----- End of Information -----\n");
}

int getPath(const char *path) {
for (;*path!='\0';path++);
path--;
if (*path=='/')
return 1;
else
return 0;
}

/* test for correctness */
/*
int main(int argc, char *argv[]) {
struct playNode *oneSong;
oneSong=newNode(argv[1], argv[2]);
output(oneSong);
oneSong=dieNode(oneSong);
return 0;
}
*/
/* end of test */




node.h
代码:

#include <string.h>
#include <stdlib.h>

#define DIR_LENGTH 1024
#define NAME_LENGTH 512
#define TITLE_LENGTH 100
#define AUTHOR_LENGTH 50

typedef struct playNode {
char dirPath[DIR_LENGTH];
char fileName[NAME_LENGTH];
char title[TITLE_LENGTH];
char author[AUTHOR_LENGTH];
} song;

song *newNode (char *, char *);
song *dieNode(song *);
void output(song *);
int getPath(const char *);



plsMaker02.c
代码:

#include <string.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
#include "table.h"


/*
* In this program, we will search all files in the given directory. Then, play them
* in realplayer one by one.
*
*
*
*
*/

int main(int argc, char *argv[]) {
if (argc!=3) {
printf("Command Usage: %s <dirName> <fileName>\n",argv[0]);
exit(-1);
}
char txtCommand[]="/usr/share/RealPlayer/realplay -q ";
char txtLength[]="length=-1";
char txtFile[]="file=";
char txtTitle[]="title=";
FILE *fileName;
DIR *curDir;
struct dirent *deDir;
struct stat fileStatBuf;
if ((curDir=opendir(argv[1]))==NULL) {
printf("Can't open direcotry: %s\n",argv[1]);
exit (-1);
} else {
chdir(argv[1]);
}

song *mySong=NULL;
linkTable *myPls=NULL;

while ((deDir=readdir(curDir))!=NULL) {
lstat(deDir->d_name, &fileStatBuf);
if (S_ISREG(fileStatBuf.st_mode)) {
mySong=newNode(argv[1], deDir->d_name);
if (myPls==NULL)
myPls=creatTable(mySong);
else
insert(myPls, mySong);
}
}
mySong=NULL;
dispTable(myPls);

char *command;
for (myPls->nowPtr=myPls->headerPtr;myPls->nowPtr->nextNode!=NULL;move(myPls,1)) {
command=malloc(2048);
command=strcpy(command, txtCommand);
command=strcat(command, readNode(myPls)->dirPath);
command=strcat(command, readNode(myPls)->fileName);
printf("Command: %s\n", command);
fileName=popen(command, "r");
pclose(fileName);
}
myPls=delTable(myPls);
return 0;
}



B4层 发表时间: 05-02-16 01:04

回复: kert_t8 [kert_t8]   论坛用户   登录
这一次上传的文件中,根据plsMaker02.c的需要对node和table都作了适量修改。

plsMaker02.c不再像上一个plsMaker一样真正的生成.pls文件,因为我们生成.pls文件不是根本目的,根本目的是希望让realplayer实现播放列表和播放控制的功能。而且如果生成真正的.pls文件所产生的相对路径的问题不好解决。更好的办法是使得plsMaker作为一个控制台,输出一些数据,使得realplayer来播放这些数据,播放完毕以后,又将控制权转交给plsMaker使得可以继续输出数据让realplayer来放

理想的方法当然是让plsMaker对realplayer有完全的控制,不过这个需要时间,我们现在希望我们做的每一步都不要花费太长时间,因为我们的空余时间不多,而且我们很急切地向获得最新的功能

所以我们使用popen工具:
引用:

POPEN(3)            Linux Programmer's Manual            POPEN(3)

NAME
      popen, pclose - process I/O

SYNOPSIS
      #include <stdio.h>

      FILE *popen(const char *command, const char *type);

      int pclose(FILE *stream);

DESCRIPTION
      The  popen()  function opens a process by creating a pipe, forking, and invoking the shell.  Since a pipe
      is by definition unidirectional, the type argument may specify only reading or  writing,  not  both;  the
      resulting stream is correspondingly read-only or write-only.

      The command argument is a pointer to a null-terminated string containing a shell command line.  This com-
      mand is passed to /bin/sh using the -c flag; interpretation, if any, is performed by the shell.  The type
      argument  is  a pointer to a null-terminated string which must be either `r' for reading or `w' for writ-
      ing.

      The return value from popen() is a normal standard I/O stream in all respects save that it must be closed
      with  pclose()  rather  than fclose().  Writing to such a stream writes to the standard input of the com-
      mand; the command's standard output is the same as that of the process that called popen(),  unless  this
      is  altered  by  the  command  itself.  Conversely, reading from a ``popened'' stream reads the command's
      standard output, and the command's standard input is the same as that of the process that called popen.

      Note that output popen streams are fully buffered by default.

      The pclose function waits for the associated process to terminate and returns the exit status of the com-
      mand as returned by wait4.

RETURN VALUE
      The popen function returns NULL if the fork(2) or pipe(2) calls fail, or if it cannot allocate memory.

      The pclose function returns -1 if wait4 returns an error, or some other error is detected.

ERRORS
      The  popen  function  does  not set errno if memory allocation fails.  If the underlying fork() or pipe()
      fails, errno is set appropriately.  If the type argument is invalid,  and  this  condition  is  detected,
      errno is set to EINVAL.

      If pclose() cannot obtain the child status, errno is set to ECHILD.

CONFORMING TO
      POSIX.2

BUGS
      Since  the  standard  input  of a command opened for reading shares its seek offset with the process that
      called popen(), if the original process has done a buffered read, the command's input position may not be
      as  expected.  Similarly, the output from a command opened for writing may become intermingled with that
      of the original process.  The latter can be avoided by calling fflush(3) before popen.

      Failure to execute the shell is indistinguishable from the shell's failure  to  execute  command,  or  an
      immediate exit of the command.  The only hint is an exit status of 127.

HISTORY
      A popen() and a pclose() function appeared in Version 7 AT&T UNIX.

SEE ALSO
      fork(2), sh(1), pipe(2), wait4(2), fflush(3), fclose(3), fopen(3), stdio(3), system(3)

BSD MANPAGE                1998-05-07                  POPEN(3)



我就不翻译了,意思是进行shell调用。而realplayer有这么一个用法:
./realplay -q filename.mp3
这样可以播放一个mp3文件,播放完毕返回退出realplayer。这个简直让我欣喜若狂。所以就出现了这个 plsMaker02.c

当然,我们的终极目标是模拟windows下面的播放列表功能,差的还有一点远。不要紧,慢慢来,慢慢来。雄关漫道真如铁,而且从头越了一小步

目前,我们还没有实现由控制的播放--1 重复播放; 2 随机播放
当然,我们更不能掌握realplayer播放时的动作,这个让我很不爽。接下来搞定他

B5层 发表时间: 05-02-16 01:32

回复: kert_t8 [kert_t8]   论坛用户   登录
to raojianhua:

写了太久了,自己都不懂了

自己先看一看吧,哪个地方不清楚我们在讨论

BTW,你是不是姓啊?

B6层 发表时间: 05-08-26 11:24

回复: kert_t8 [kert_t8]   论坛用户   登录
只需要看第一个程序就可以了,其他程序都是没事儿瞎写的,与你的程序关系也不大

B7层 发表时间: 05-08-26 11:26

回复: TecZm [teczm]   版主   登录
晕 看不懂 惭愧

B8层 发表时间: 05-08-26 12:54

论坛: 编程破解

20CN网络安全小组版权所有
Copyright © 2000-2010 20CN Security Group. All Rights Reserved.
论坛程序编写:NetDemon

粤ICP备05087286号