int omxplayer_StartPlaying(const char *filename) { char fullVideoPath[2048]; LogDebug(VB_MEDIAOUT, "omxplayer_StartPlaying(%s)\n", filename); bzero(&mediaOutputStatus, sizeof(mediaOutputStatus)); if (snprintf(fullVideoPath, 2048, "%s/%s", getVideoDirectory(), filename) >= 2048) { LogErr(VB_MEDIAOUT, "Unable to play %s, full path name too long\n", filename); return 0; } if (getFPPmode() == REMOTE_MODE) CheckForHostSpecificFile(getSetting("HostName"), fullVideoPath); if (!FileExists(fullVideoPath)) { LogErr(VB_MEDIAOUT, "%s does not exist!\n", fullVideoPath); return 0; } // Create Pipes to/from omxplayer pid_t omxplayerPID = forkpty(&pipeFromOMX[0], 0, 0, 0); if (omxplayerPID == 0) // omxplayer process { ShutdownControlSocket(); seteuid(1000); // 'pi' user execl("/opt/fpp/scripts/omxplayer", "/opt/fpp/scripts/omxplayer", fullVideoPath, NULL); LogErr(VB_MEDIAOUT, "omxplayer_StartPlaying(), ERROR, we shouldn't " "be here, this means that execl() failed\n"); exit(EXIT_FAILURE); } else // Parent process { mediaOutput->childPID = omxplayerPID; } // Clear active file descriptor sets FD_ZERO (&omx_active_fd_set); // Set description for reading from omxplayer FD_SET (pipeFromOMX[0], &omx_active_fd_set); mediaOutputStatus.status = MEDIAOUTPUTSTATUS_PLAYING; omxVolumeShift = omxplayer_GetVolumeShift(getVolume()); return 1; }
/* * Fork and run an event script */ int RunEventScript(FPPevent *e) { pid_t pid = 0; char userScript[1024]; char eventScript[1024]; // Setup the script from our user strcpy(userScript, getScriptDirectory()); strcat(userScript, "/"); strncat(userScript, e->script, 1024 - strlen(userScript)); userScript[1023] = '\0'; // Setup the wrapper memcpy(eventScript, getFPPDirectory(), sizeof(eventScript)); strncat(eventScript, "/scripts/eventScript", sizeof(eventScript)-strlen(eventScript)-1); pid = fork(); if (pid == 0) // Event Script process { #ifndef NOROOT struct sched_param param; param.sched_priority = 0; if (sched_setscheduler(0, SCHED_OTHER, ¶m) != 0) { perror("sched_setscheduler"); exit(EXIT_FAILURE); } #endif ShutdownControlSocket(); char *args[128]; char *token = strtok(userScript, " "); int i = 1; args[0] = strdup(userScript); while (token && i < 126) { args[i] = strdup(token); i++; token = strtok(NULL, " "); } args[i] = NULL; if (chdir(getScriptDirectory())) { LogErr(VB_EVENT, "Unable to change directory to %s: %s\n", getScriptDirectory(), strerror(errno)); exit(EXIT_FAILURE); } execvp(eventScript, args); LogErr(VB_EVENT, "RunEventScript(), ERROR, we shouldn't be here, " "this means that execvp() failed trying to run '%s %s': %s\n", eventScript, args[0], strerror(errno)); exit(EXIT_FAILURE); } return 1; }
void MainLoop(void) { int commandSock = 0; int controlSock = 0; int bridgeSock = 0; int prevFPPstatus = FPPstatus; int sleepms = 50000; fd_set active_fd_set; fd_set read_fd_set; struct timeval timeout; int selectResult; LogDebug(VB_GENERAL, "MainLoop()\n"); FD_ZERO (&active_fd_set); CheckExistanceOfDirectoriesAndFiles(); piFaceSetup(200); // PiFace inputs 1-8 == wiringPi 200-207 if (getFPPmode() == BRIDGE_MODE) { bridgeSock = Bridge_Initialize(); if (bridgeSock) FD_SET (bridgeSock, &active_fd_set); } else { InitMediaOutput(); } pluginCallbackManager.init(); InitializeChannelOutputs(); sequence->SendBlankingData(); InitEffects(); InitializeChannelDataMemoryMap(); commandSock = Command_Initialize(); if (commandSock) FD_SET (commandSock, &active_fd_set); #ifdef USEHTTPAPI APIServer apiServer; apiServer.Init(); #endif controlSock = InitControlSocket(); FD_SET (controlSock, &active_fd_set); SetupGPIOInput(); if (getFPPmode() & PLAYER_MODE) { if (getFPPmode() == MASTER_MODE) InitSyncMaster(); scheduler->CheckIfShouldBePlayingNow(); if (getAlwaysTransmit()) StartChannelOutputThread(); } LogInfo(VB_GENERAL, "Starting main processing loop\n"); while (runMainFPPDLoop) { timeout.tv_sec = 0; timeout.tv_usec = sleepms; read_fd_set = active_fd_set; selectResult = select(FD_SETSIZE, &read_fd_set, NULL, NULL, &timeout); if (selectResult < 0) { if (errno == EINTR) { // We get interrupted when media players finish continue; } else { LogErr(VB_GENERAL, "Main select() failed: %s\n", strerror(errno)); runMainFPPDLoop = 0; continue; } } if (commandSock && FD_ISSET(commandSock, &read_fd_set)) CommandProc(); if (bridgeSock && FD_ISSET(bridgeSock, &read_fd_set)) Bridge_ReceiveData(); if (controlSock && FD_ISSET(controlSock, &read_fd_set)) ProcessControlPacket(); // Check to see if we need to start up the output thread. // FIXME, possibly trigger this via a fpp command to fppd if ((!ChannelOutputThreadIsRunning()) && (getFPPmode() != BRIDGE_MODE) && ((UsingMemoryMapInput()) || (channelTester->Testing()) || (getAlwaysTransmit()))) { int E131BridgingInterval = getSettingInt("E131BridgingInterval"); if (!E131BridgingInterval) E131BridgingInterval = 50; SetChannelOutputRefreshRate(1000 / E131BridgingInterval); StartChannelOutputThread(); } if (getFPPmode() & PLAYER_MODE) { if ((FPPstatus == FPP_STATUS_PLAYLIST_PLAYING) || (FPPstatus == FPP_STATUS_STOPPING_GRACEFULLY)) { if (prevFPPstatus == FPP_STATUS_IDLE) { playlist->PlayListPlayingInit(); sleepms = 10000; } // Check again here in case PlayListPlayingInit // didn't find anything and put us back to IDLE if ((FPPstatus == FPP_STATUS_PLAYLIST_PLAYING) || (FPPstatus == FPP_STATUS_STOPPING_GRACEFULLY)) { playlist->PlayListPlayingProcess(); } } int reactivated = 0; if (FPPstatus == FPP_STATUS_IDLE) { if ((prevFPPstatus == FPP_STATUS_PLAYLIST_PLAYING) || (prevFPPstatus == FPP_STATUS_STOPPING_GRACEFULLY)) { playlist->PlayListPlayingCleanup(); if (FPPstatus != FPP_STATUS_IDLE) reactivated = 1; else sleepms = 50000; } } if (reactivated) prevFPPstatus = FPP_STATUS_IDLE; else prevFPPstatus = FPPstatus; scheduler->ScheduleProc(); } else if (getFPPmode() == REMOTE_MODE) { if(mediaOutputStatus.status == MEDIAOUTPUTSTATUS_PLAYING) { playlist->PlaylistProcessMediaData(); } } CheckGPIOInputs(); } StopChannelOutputThread(); ShutdownControlSocket(); if (getFPPmode() == BRIDGE_MODE) Bridge_Shutdown(); LogInfo(VB_GENERAL, "Main Loop complete, shutting down.\n"); }