diff --git a/README b/README index 34607da..1384968 100644 --- a/README +++ b/README @@ -95,7 +95,7 @@ Configuration: - channels.conf - TV4;IPTV:4:IPTV|EXT|/video/iptvradio.sh|4321:P:0:0:680:0:0:4:0:0:0 + TV4;IPTV:4:IPTV|EXT|/video/iptvstream.sh|4321:P:0:0:680:0:0:4:0:0:0 TV3;IPTV:3:IPTV|FILE|/media/video.ts|5:P:0:514:670:2321:0:3:0:0:0 TV2;IPTV:2:IPTV|HTTP|127.0.0.1/TS/2|3000:P:0:513:660:2321:0:2:0:0:0 TV1;IPTV:1:IPTV|UDP|127.0.0.1|1234:P:0:512:650:2321:0:1:0:0:0 diff --git a/iptv/iptvstream.sh b/iptv/iptvstream.sh new file mode 100755 index 0000000..62797c7 --- /dev/null +++ b/iptv/iptvstream.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +URL="" + +if [ -z "${URL}" ]; then + logger "$0: error: URL not defined!" + exit 1; +fi + +if [ $# -ne 1 ]; then + logger "$0: error: Invalid parameter count '$#' $*" + exit 1; +fi + +exec vlc ${URL} --sout \"#transcode{vcodec=mp2v,acodec=mpga,vb=800,ab=192}:standard{access=udp,mux=ts,dst=127.0.0.1:${1}}\" --intf dummy diff --git a/protocolext.c b/protocolext.c index 5a2a71b..85a182a 100644 --- a/protocolext.c +++ b/protocolext.c @@ -3,9 +3,10 @@ * * See the README file for copyright information and how to reach the author. * - * $Id: protocolext.c,v 1.3 2007/10/16 22:13:44 rahrenbe Exp $ + * $Id: protocolext.c,v 1.4 2007/10/18 19:33:15 rahrenbe Exp $ */ +#include #include #include #include @@ -20,7 +21,8 @@ #include "protocolext.h" cIptvProtocolExt::cIptvProtocolExt() -: listenPort(4321), +: pid(-1), + listenPort(4321), socketDesc(-1), readBufferLen(TS_SIZE * IptvConfig.GetReadBufferTsCount()), isActive(false) @@ -99,6 +101,62 @@ void cIptvProtocolExt::CloseSocket(void) } } +void cIptvProtocolExt::ExecuteCommand(void) +{ + debug("cIptvProtocolExt::ExecuteCommand()\n"); + // Let's fork + if ((pid = fork()) == -1) { + char tmp[64]; + error("ERROR: fork(): %s", strerror_r(errno, tmp, sizeof(tmp))); + return; + } + + // Check if child process + if (pid == 0) { + // Close all dup'ed filedescriptors + int MaxPossibleFileDescriptors = getdtablesize(); + for (int i = STDERR_FILENO + 1; i < MaxPossibleFileDescriptors; i++) + close(i); + // Execute the external script + char* cmd = NULL; + asprintf(&cmd, "%s %d", streamAddr, listenPort); + debug("cIptvProtocolExt::ExecuteCommand(child): %s\n", cmd); + if (execl("/bin/sh", "sh", "-c", cmd, NULL) == -1) { + free(cmd); + error("ERROR: Command failed: %s", streamAddr); + _exit(-1); + } + free(cmd); + _exit(0); + } + else { + isActive = true; + debug("cIptvProtocolExt::ExecuteCommand(): pid=%d\n", pid); + } +} + +void cIptvProtocolExt::TerminateCommand(void) +{ + debug("cIptvProtocolExt::TerminateCommand(): pid=%d\n", pid); + if (pid > 0) { + const unsigned int timeoutms = 100; + unsigned int waitms = 0; + // signal and wait for termination + kill(pid, SIGTERM); + while (waitpid(pid, NULL, WNOHANG) == 0) { + waitms += timeoutms; + // Signal kill every 2 seconds + if ((waitms % 2000) == 0) { + error("ERROR: Script '%s' won't terminate - killing it", streamAddr); + kill(pid, SIGKILL); + } + // Sleep for awhile + cCondWait::SleepMs(timeoutms); + } + pid = -1; + isActive = false; + } +} int cIptvProtocolExt::Read(unsigned char* *BufferAddr) { @@ -164,22 +222,14 @@ int cIptvProtocolExt::Read(unsigned char* *BufferAddr) bool cIptvProtocolExt::Open(void) { - debug("cIptvProtocolExt::Open(): streamAddr=%s\n", streamAddr); - + debug("cIptvProtocolExt::Open(): streamAddr=%s listenPort=%d\n", streamAddr, listenPort); // Reject completely empty stream addresses if (!strlen(streamAddr)) return false; - // Create the listening socket OpenSocket(); - if (!isActive) { - char* cmd = NULL; - asprintf(&cmd, "%s start", streamAddr); - int retval = SystemExec(cmd); - free(cmd); - if (!retval) - isActive = true; - } + if (!isActive) + ExecuteCommand(); return isActive; } @@ -188,15 +238,8 @@ bool cIptvProtocolExt::Close(void) debug("cIptvProtocolExt::Close(): streamAddr=%s\n", streamAddr); // Close the socket CloseSocket(); - if (isActive) { - char* cmd = NULL; - asprintf(&cmd, "%s stop", streamAddr); - int retval = SystemExec(cmd); - free(cmd); - if (!retval) - isActive = false; - } - + if (isActive) + TerminateCommand(); return !isActive; } diff --git a/protocolext.h b/protocolext.h index b4620f2..40e340b 100644 --- a/protocolext.h +++ b/protocolext.h @@ -3,7 +3,7 @@ * * See the README file for copyright information and how to reach the author. * - * $Id: protocolext.h,v 1.2 2007/10/16 22:13:44 rahrenbe Exp $ + * $Id: protocolext.h,v 1.3 2007/10/18 19:33:15 rahrenbe Exp $ */ #ifndef __IPTV_PROTOCOLEXT_H @@ -14,6 +14,7 @@ class cIptvProtocolExt : public cIptvProtocolIf { private: + int pid; char* listenAddr; int listenPort; char* streamAddr; @@ -26,6 +27,8 @@ private: private: bool OpenSocket(void); void CloseSocket(void); + void TerminateCommand(void); + void ExecuteCommand(void); public: cIptvProtocolExt();