Search code examples
pythonstdinpopenkillomxplayer

python how to kill a popen process, shell false [why not working with standard methods]


I'm trying to kill a subprocess started with:

playing_long = Popen(["omxplayer", "/music.mp3"], stdout=subprocess.PIPE)

and after a while

pid = playing_long.pid
playing_long.terminate()
os.kill(pid,0)
playing_long.kill()

Which doesn't work. Neither the solution pointed out here

How to terminate a python subprocess launched with shell=True

Noting that I am using threads, and it is not recommended to use preexec_fn when you use threads (or at least this is what I read, anyway it doesn't work either).

Why it is not working? There's no error message in the code, but I have to manually kill -9 the process to stop listening the mp3 file.

Thanks

EDIT: From here, I have added a wait() after the kill(). Surprisingly, before re-starting the process I check if this is still await, so that I don't start a chorus with the mp3 file.

  • Without the wait(), the system sees that the process is alive.

  • With the wait(), the system understands that the process is dead and starts again it.

  • However, the process is still sounding. Definitively I can't seem to get it killed.

EDIT2: The problem is that omxplayer starts a second process that I don't kill, and it's the responsible for the actual music.

  • I've tried to use this code, found in several places in internet, it seems to work for everyone but not for me

    playing_long.stdin.write('q')
    playing_long.stdin.flush()
    

And it prints 'NoneType' object has no attribute 'write'. Even when using this code immediately after starting the popen process, it fails with the same message

playing_long = subprocess.Popen(["omxplayer", "/home/pi/Motion_sounds/music.mp3"], stdout=subprocess.PIPE)
time.sleep(5)
playing_long.stdin.write('q')
playing_long.stdin.flush()

EDIT3: The problem then was that I wasn't establishing the stdin line in the popen line. Now it is

playing_long = subprocess.Popen(["omxplayer", "/home/pi/Motion_sounds/music.mp3"], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
time.sleep(5)
playing_long.stdin.write(b'q')
playing_long.stdin.flush()

*needing to specify that it is bytes what I write in stdin


Solution

  • Final solution then (see the process edited in the question):

    playing_long = subprocess.Popen(["omxplayer", "/home/pi/Motion_sounds/music.mp3"], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
    time.sleep(5)
    playing_long.stdin.write(b'q')
    playing_long.stdin.flush()