📄 crenderer.cc.svn-base
字号:
write(PARENT_WRITE,cmd,strlen(cmd)); if(output) { string out = this->showOutput(); cout << "answer from mplayer: " << out << endl << "===============================================" << endl; return (char*)out.c_str(); } return ""; } else { cout << "mplayer not running!" << endl; return ""; } }void cRenderer::wakeup(int in){ cRenderer* cp = (cRenderer*) pt2obj; if (strcmp(cp->services[AVTransport]->value[cAVTransport::AV_TransportState],"STOPPED")!=0) { cp->mplayer_is_running = false; cp->services[AVTransport]->setVar(AVTransport,2,cAVTransport::AV_TransportState,"STOPPED"); // notification IXML_Document* LCdoc = NULL; IXML_Node* node = NULL; IXML_Element* Ele = NULL; LCdoc = ixmlParseBuffer("<Event xmlns=\"urn:schemas-upnp-org:metadata-1-0/AVT/\"></Event>"); node = ixmlNode_getFirstChild( (IXML_Node*) LCdoc ); Ele = ixmlDocument_createElement( LCdoc, "InstanceID" ); ixmlElement_setAttribute(Ele, "val","0"); ixmlNode_appendChild( node,(IXML_Node*) Ele); IXML_Element* Ele2 = NULL; Ele2 = ixmlDocument_createElement(LCdoc, cp->services[AVTransport]->name[cAVTransport::AV_TransportState]); ixmlElement_setAttribute(Ele2, "val", cp->services[AVTransport]->value[cAVTransport::AV_TransportState]); ixmlNode_appendChild((IXML_Node*)Ele,(IXML_Node*) Ele2); IXML_Document* myDoc2 = UpnpCreatePropertySet(1, "LastChange", ixmlPrintDocument(LCdoc) ); UpnpNotifyExt(cp->renderer_hdl,cp->udn,cp->services[AVTransport]->service_id,myDoc2); cout << "SIGCHLD" << endl; }}/* * CREATE THE PAIR OF PIPES * * Pipes have two ends but just one direction: to get a two-way * conversation you need two pipes. It's an error if we cannot make * them both, and we define these macros for easy reference. */int cRenderer::mypopen(char* uri){ if ( pipe(readpipe) < 0 || pipe(writepipe) < 0 || pipe(errpipe) < 0 ) { /* FATAL: cannot create pipe */ cout << "cannot create pipe" << endl; } if ( (childpid = fork()) < 0) { /* FATAL: cannot fork child */ cout << "cannot fork child" << endl; } else if ( childpid == 0 ) /* in the child */ { close(PARENT_WRITE); close(PARENT_READ); close(errpipe[0]); //Hier siehe auch http://www.unixwiz.net/techtips/remap-pipe-fds.htm //Ich habe einfach alles kopiert. if ( CHILD_READ == 0 && CHILD_WRITE == 1 ) { //perror("case 1"); DUP2CLOSE(CHILD_READ, 0); DUP2CLOSE(CHILD_WRITE, 1); } if ( CHILD_READ >= 1 && CHILD_WRITE > 1 ) { DUP2CLOSE(CHILD_READ, 0); DUP2CLOSE(CHILD_WRITE, 1); } if ( CHILD_READ == 0 && CHILD_WRITE >= 1 ) DUP2CLOSE(CHILD_WRITE, 1); if ( CHILD_READ >= 1 && CHILD_WRITE == 1 ) DUP2CLOSE(CHILD_READ, 0); if ( CHILD_READ >= 1 && CHILD_WRITE == 0 ) { DUP2CLOSE(CHILD_WRITE, 1); DUP2CLOSE(CHILD_READ, 0); } if ( CHILD_READ == 1 && CHILD_WRITE == 0 ) { const int tmp = dup(CHILD_WRITE); //NOTE! this is not dup2() ! //tmp > 1 close(CHILD_WRITE); DUP2CLOSE(CHILD_READ, 0); DUP2CLOSE(tmp,1); } DUP2CLOSE(errpipe[1],2); //DUP2CLOSE(CHILD_READ, 0); //DUP2CLOSE(CHILD_WRITE, 1); /* do child stuff */ char* ar[5]; ar[0]=this->mplayer_bin; ar[1]="-slave"; ar[2]="-quiet"; ar[3]=uri; ar[4]=fullscreen; //mplayer_is_running = true; execvp(ar[0],ar); perror("mplayer(failed)"); /* we only arrive here on error! */ } else /* in the parent */ { struct sigaction sigact; sigset_t sigset; /* set up handler for SIGCHLD, but get the sig from parent */ sigemptyset(&sigset); /* create an empty signal mask set */ sigact.sa_handler = cRenderer::wakeup; /* use the wakeup() handler */ sigact.sa_mask = sigset; /* use the empty sigset */ sigact.sa_flags = 0; /* no flags needed */ sigaction(SIGCHLD, &sigact, NULL); struct sigaction sigact2; sigset_t sigset2; sigemptyset(&sigset2); //create an empty signal mask set sigact2.sa_handler = cRenderer::wakeup; //use the wakeup() handler sigact2.sa_mask = sigset; //use the empty sigset sigact2.sa_flags = 0; //no flags needed sigaction(SIGPIPE, &sigact2, NULL); /* do parent stuff */ close(CHILD_READ); close(CHILD_WRITE); close(errpipe[1]); //make read pipe noblocking int flags; flags = fcntl(PARENT_READ, F_GETFL, 0); //flags |= O_NONBLOCK; fcntl(PARENT_READ, F_SETFL, flags); readfp=fdopen(PARENT_READ,"r"); //output //sleep(1); //showOutput(); char * line = NULL; size_t len = 0; getline(&line,&len,readfp); cout << line << endl; while(strcmp(line,"Starting playback...\n")!=0) { getline(&line,&len,readfp); cout << line << endl; if(strstr(line,"Exiting... (End of file)")!=NULL) { wait(0); return 0; } } mplayer_is_running = true; (services[AVTransport])->setVar(AVTransport,12, cAVTransport::AV_TransportState,"PLAYING", cAVTransport::AV_CurrentTrack,"1", cAVTransport::AV_NumberOfTracks,"1", cAVTransport::AV_CurrentTrackURI,(services[AVTransport])->value[cAVTransport::AV_AVTransportURI], cAVTransport::AV_CurrentTrackMetaData,"", cAVTransport::AV_AbsoluteTimePosition,(services[AVTransport])->value[cAVTransport::AV_AbsoluteTimePosition]); cout << "raus" << endl; if(line) { free(line); } //int speed = 1; bool first=true; while(mplayer_is_running) { // get_time_pos nur wenn PLAYING (TODO) if (strcmp(services[AVTransport]->value[cAVTransport::AV_TransportState],"PLAYING")==0) { if(first) { char tstamp[20]; string tmp = mplayer_cmd("get_time_length",true); tmp = tmp.substr(tmp.find_first_of('=')+1); seconds2tstamp(tstamp,(char* )tmp.c_str()); cout << tstamp << "###############################\n########" << endl; if (strcmp(tmp.c_str(),"00.0")!=0) { // setVar(AV_id,2,cAVTransport::AV_CurrentTrackDuration,"99:59:59"); (services[AVTransport])->setVar(AVTransport,2,cAVTransport::AV_CurrentTrackDuration,"NOT_IMPLEMENTED"); } else { (services[AVTransport])->setVar(AVTransport,2,cAVTransport::AV_CurrentTrackDuration,tstamp); } first=false; } string length = mplayer_cmd("get_time_pos",true); if(strcmp(length.c_str(),"")!=0) { length=length.substr(length.find_first_of('=')+1); char returnvalue[100]; strcpy(returnvalue,length.c_str()); char tstamp[20]; seconds2tstamp(tstamp,returnvalue); cout << tstamp << endl; (services[AVTransport])->setVar(AVTransport,2,cAVTransport::AV_RelativeTimePosition,tstamp); } } sleep(1); } //wait for child process wait(0); //wakeup(0); //wait(0); } return 0;}/* * mplayer thread start */void* cRenderer::threadCreate( void *ptr ){ cRenderer *cp = (cRenderer*) pt2obj; char *message; message = (char *) ptr; cp->mypopen(message); return (void*)NULL;}/* * read output from mplayer and show it */string cRenderer::showOutput(){ char * line = NULL; size_t len = 0; string returnvalue=""; /*char buffer[256]; int i; usleep(100000); while((i=read(PARENT_READ,buffer,256))>0) { buffer[i-1]='\0'; returnvalue+=buffer; }*/ if(readfp==NULL) { cout << "readfp is NULL (error)" << endl; exit(1); } getline(&line,&len,readfp); cout << line << endl; while(strstr(line,"ANS_LENGTH=")==NULL && strstr(line,"ANS_TIME_POSITION=")==NULL) { getline(&line,&len,readfp); cout << line << endl; } returnvalue=line; if(line) { free(line); } return returnvalue;}void cRenderer::mplayer_start(){ iret = pthread_create( &thread, NULL, threadCreate, (void*) services[AVTransport]->value[cAVTransport::AV_AVTransportURI]);}void cRenderer::seconds2tstamp(char* out, char* in){ int ihours = 0; int iminutes = 0; int iseconds = atoi(in); iminutes = iseconds/60; iseconds = iseconds - iminutes*60; ihours = iminutes/60; iminutes = iminutes - ihours*60; char chours[3]; char cminutes[3]; char cseconds[3]; if (ihours<10) sprintf(chours,"0%i",ihours); else sprintf(chours,"%i",ihours); if (iminutes<10) sprintf(cminutes,"0%i",iminutes); else sprintf(cminutes,"%i",iminutes); if (iseconds<10) sprintf(cseconds,"0%i",iseconds); else sprintf(cseconds,"%i",iseconds); sprintf(out,"%s:%s:%s",chours,cminutes,cseconds);}int cRenderer::time2seconds(char* in){ string length = in; string cHours = length.substr(0,length.find_first_of(':')); length = length.substr(length.find_first_of(':')+1); string cMinutes = length.substr(0,length.find_first_of(':')); length = length.substr(length.find_first_of(':')+1); string cSeconds = length.substr(0,length.find_first_of(':')); int iHours = atoi(cHours.c_str()); int iMinutes = atoi(cMinutes.c_str()); int iSeconds = atoi(cSeconds.c_str()); iSeconds = iSeconds + (60*iMinutes) + (3600*iHours); return iSeconds;}void cRenderer::parseConfigFile(){ char* home=getenv("HOME"); ifstream myfile; char home_conf[50]; sprintf(home_conf,"%s/.renderer/renderer.conf",home); myfile.open(home_conf,ifstream::in); if (myfile.is_open()) { cout << "using config " << home_conf << endl; } else { cout << "config not found" << endl; cout << "generating config" << endl; FILE* file=fopen(home_conf,"w"); fputs("#This file is automatically created\n\n",file); fputs("#Set a friendly name for your renderer\n",file); fputs("#FRIENDLYNAME=Linux-Renderer(%h)\n\n",file); fputs("#Set a ip address.\n",file); fputs("#IP_ADDRESS=192.168.1.1\n\n",file); fputs("#Set the path to mplayer\n",file);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -