2

I'm trying to make a python script that starts the program livestreamer (that starts the program mplayer) and after 10 seconds it should kill the program, or the subprocess. here is my current code that doesn't work, I think I know why but I don't know how to solve it. I think the problem is that the subprocess starts livestreamer and then the program livestreamer starts the program mplayer. Python doesn't know about mplayer and can't close it. How would I be able to kill both livestreamer and mplayer after 10 second and then start them again as a loop? I'm using Ubuntu 14.04 (Linux) and Python 2.7.6

import subprocess
import time
import os
import sys
import signal

url = "http://new.livestream.com/accounts/398160/events/3155348"
home = os.environ['HOME']

if not os.geteuid() == 0:
    if not os.path.exists('/%s/.config/livestreamer' % home):
        os.makedirs('/%s/.config/livestreamer' % home)
    lscfg = open('%s/.config/livestreamer/config' % home, 'w+')
    lscfg.write("player=mplayer -geometry 0%:0% -nomouseinput -loop 100 -noborder -fixed-vo")
    lscfg.close()

cmd = "livestreamer %s best --player-continuous-http --player-no-close" % url
while True:
    proc1 = subprocess.Popen(cmd.split(), shell=False)
    time.sleep(10)
    proc1.kill()

Solution:

import subprocess
import time
import os
import sys
import signal

url = "http://new.livestream.com/accounts/398160/events/3155348"
home = os.environ['HOME']

if not os.geteuid() == 0:
    if not os.path.exists('/%s/.config/livestreamer' % home):
        os.makedirs('/%s/.config/livestreamer' % home)
    lscfg = open('%s/.config/livestreamer/config' % home, 'w+')
    lscfg.write("player=mplayer -geometry 0%:0% -nomouseinput -loop 100 -noborder -fixed-vo")
    lscfg.close()
cmd = "livestreamer %s best --player-continuous-http --player-no-close" % url
#restarting the player every 10th minute to catch up on possible delay
while True:
    proc1 = subprocess.Popen(cmd.split(), shell=False)
    time.sleep(600)
    os.system("killall -9 mplayer")
    proc1.kill()

As you can see os.system("killall -9 mplayer") was the command to kill the process mplayer.

  • After runnig the livesteamer you can run another command to get pid of livesteamer.Then after 10 secs you can kill it. :) – vks Oct 23 '14 at 11:57
  • Your solution will work but is not very flexible and i hope nothing else on your system will call mplayer because killall will kill all of them :) – SkyDream Oct 23 '14 at 14:33
  • Yes I understand that but this is not a problem in my case, but it may be for other cases. :) – Markus Rexhepi-Lindberg Oct 24 '14 at 07:47

2 Answers2

0

In your code you kill livestreamer but not mplayer so mplayer will continue running.

By using kill on your subprocess you send a signal SIGKILL and unless the subprocess do handle the signal interruption it will simply close itself fast and without killing his own childs so mplayer will live (and may become a zombie process).

You have no reference to your subprocess child 'mplayer' but if you can get his PID you can kill it with os.kill(...)

os.kill(process_pid, signal.SIGTERM)
SkyDream
  • 382
  • 1
  • 10
  • Do you know how I would be able to get the PID from mplayer? Currently it's livestreamer that handle mplayer, livestreamer starts mplayer by reading livestreamers config (as you can seed in the code). Normally if you want to start livestreamer with mplayer you have to issue the command `livestreamer someurl --player mplayer`. Doesn't it create like a process tree, livestreamer being the parent and mplayer being the child, thereof I could kill the whole tree? – Markus Rexhepi-Lindberg Oct 23 '14 at 12:06
  • You can get the list of running process and pid with "tasklist" (Windows) or "ps" (Unix). – SkyDream Oct 23 '14 at 14:09
  • http://stackoverflow.com/a/6481337/3816698 an elegant solution using an Unix script. – SkyDream Oct 23 '14 at 14:17
  • I tried that way but I only made it more complicated than it need to be. But I've come up with a solution see original post. :) – Markus Rexhepi-Lindberg Oct 23 '14 at 14:24
0

Using os.system("killall -9 mplayer") was the easy way to solve this. Mind using this option will kill all process of mplayer though this is not a problem in my case but may be a problem for other cases.

while True:
        proc1 = subprocess.Popen(cmd.split(), shell=False)
        time.sleep(600)
        os.system("killall -9 mplayer")
        proc1.kill()