I am very much a noob with Python and Linux commands but I'm trying to wrap my head around it.
My application is bigger than this sample but I am trying to get this working before expanding.
I am using mplayer in slave mode to play a video clip but I want to automatically kill it when the clip is done. So my idea is to start mplayer in slave mode then command 'get_time_length', store that value, sleep for that value, kill it and return to the main routine.
import os
import commands
import glob
#Global Commands
glcmd = 'get_time_length'
print("Preparing for kiosk mode! Press CTRL+C to exit")
try:
while 1:
path = '/media/*/button1/*'
os.system('mplayer -fs -quiet -slave path')
line = os.popen(glcmd).readline().strip() #Get the duration from mplayer
duration = line.split('=')[1] #Get just the length of video in Seconds
print(duration)
sleep(duration) #Wait until the video is done
os.system('quit')
The problem that I am having is that once the video clip starts playing, it never runs any commands during play. I'm also not sure if my syntax is right in order to retrieve the command line but I at least want to figure out how to be able to send commands with to mplayer with my script while a video is playing.
Thanks!
You can use the subprocess lib as recommended in the docs which say about os.popen Deprecated since version 2.6: This function is obsolete, all you need to do is use check_call the program will end when the video does.
from subprocess import check_call
path = '/media/*/button1/*'
check_call(['mplayer',"-fs", '-quiet' ,'-slave',path])
If you wanted to communicate somehow you would use subprocess.Popen, this will print all the output in a loop and terminate the process if the user enter ctrl-c:
from time import sleep
from subprocess import Popen, PIPE
path = '/media/*/button1/*'
try:
p = Popen(['mplayer', '-quiet' ,'-slave', path],stdout=PIPE, stdin=PIPE)
for line in iter(p.stdout.readline,""):
print(line)
except KeyboardInterrupt:
p.terminate()
If you wanted to send commands you would write to p.stdin
Related
I have multiple python files to run. How would I launch all those files within one .py script? This is what I came up with but it shows the screen action and really doesn't begin the other stuff unless I exit out of it. Here's the code, not much:
import os
print("Launching Bot, just for you.")
print("Loading up shard 0")
try:
os.system("screen python3.5 run_0.py > /dev/null")
except:
print("Shard 0 failed")
print("Loading up shard 1")
try:
os.system("screen python3.5 run_1.py > /dev/null")
except:
print("Shard 1 failed")
print("Done running shards...")
I was doing some research and they said to use subprocess but when I used it, it didn't run my command properly. (I don't have a copy of that code, I lost it).
The problem is that I want to run the python script and it works fine but I have to close the screen to start the other one and I just want it to run the command w/o showing the output. Can you help?
You should use import subprocess in a python file. You can then start other instance of other programs with :
subprocess.Popen([sys.executable, "newprogram.py"])
You can mix that with multiprocessing package to launch one thread by new program
p = multiprocessing.Process(target= mp_worker , args=( ))
p.start()
where mp_worker launches the other program.
I'm trying to write a python script that start a process and do some operations atferward.
The commands that I want to automate by script are circled as red in the picture.
The problem is that after performing first command, qemu environment will be run and the other commands should be executed on the qemu environment. So I want to know how can I do these commands by an script in python? Because as I know I can do the first command but I do not know how can I do those commands when I am going to qemu environment.
Could you help me how can I do this process?
First thing that came to mind was pexpect, a quick search on google turned up this blog post automatically-testing-vms-using-pexpect-and-qemu which seems to be pretty much along the lines of what you are doing:
import pexpect
image = "fedora-20.img"
user = "root"
password = "changeme"
# Define the qemu cmd to run
# The important bit is to redirect the serial to stdio
cmd = "qemu-kvm"
cmd += " -m 1024 -serial stdio -net user -net nic"
cmd += " -snapshot -hda %s" % image
cmd += " -watchdog-action poweroff"
# Spawn the qemu process and log to stdout
child = pexpect.spawn(cmd)
child.logfile = sys.stdout
# Now wait for the login
child.expect('(?i)login:')
# And login with the credentials from above
child.sendline(user)
child.expect('(?i)password:')
child.sendline(password)
child.expect('# ')
# Now shutdown the machine and end the process
if child.isalive():
child.sendline('init 0')
child.close()
if child.isalive():
print('Child did not exit gracefully.')
else:
print('Child exited gracefully.')
You could do it with subprocess.Popen also, checking the stdout for the (qemu) lines and writing to stdin. Something roughly like this:
from subprocess import Popen,PIPE
# pass initial command as list of individual args
p = Popen(["./tracecap/temu","-monitor",.....],stdout=PIPE, stdin=PIPE)
# store all the next arguments to pass
args = iter([arg1,arg2,arg3])
# iterate over stdout so we can check where we are
for line in iter(p.stdout.readline,""):
# if (qemu) is at the prompt, enter a command
if line.startswith("(qemu)"):
arg = next(args,"")
# if we have used all args break
if not arg:
break
# else we write the arg with a newline
p.stdin.write(arg+"\n")
print(line)# just use to see the output
Where args contains all the next commands.
Don't forget that Python has batteries included. Take a look of the Suprocess module in the standard lib. There a lot of pitfalls managing processes, and the module take care of them all.
You probably want to start a qemu process and send the next commands writing to its standard input (stdin). Subprocess module will allow you to do it. See that qemu has command line options to connect to stdi: -chardev stdio ,id=id
I am trying to use the Python 2.7 subprocess library to programmatically add songs to the VLC player queue.
From here and here, I am able to launch VLC Player and play a song (or queue songs from the outset);
from subprocess import Popen
vlcpath = r'C:\Program Files (x86)\VideoLAN\VLC\vlc.exe'
musicpath1 = r'path\to\song1.mp3'
musicpath2 = r'path\to\song2.mp3'
p = Popen([vlcpath,musicpath1]) # launch VLC and play song
p = Popen([vlcpath,musicpath1,musicpath2]) # launch VLC and play/queue songs
The problem is that I do not know the entire queue playlist at launch. I want to be able to add songs to the queue of the VLC process already running. How do I accomplish this, please?
From here, I think the appropriate command line entry is:
vlc.exe --started-from-file --playlist-enqueue "2.wmv"
But I do not know the syntax to execute this in subprocess. I tried a couple of things, but couldn't get either to work:
calling Popen again (opens a new process)
calling p.communicate (I thought this is how to enter stdin commands)
To run the command: vlc.exe --started-from-file --playlist-enqueue "2.wmv"
using subprocess module on Windows:
from subprocess import Popen
cmd = 'vlc.exe --started-from-file --playlist-enqueue "2.wmv"'
p = Popen(cmd) # start and forget
assert not p.poll() # assert that it is started successfully
To wait for the command to finish:
from subprocess import check_call
check_call(cmd) # start, wait until it is done, raise on non-zero exit status
But how do I run that command a second time on the same p process?
Your code starts a new instance of VLC, rather than running that on
top of the p that was already open. I found that if I run the vlc.exe --started-from-file --playlist-enqueue "2.wmv" command multiple times manually (in a command prompt window), it correctly launches vlc (the
first time) and then adds to queue (on subsequent calls). So I think I
just need to be able to run the code you suggested multiple times "on
top of itself"
Each Popen() starts a new process. Each time you run the command manually in the command-line it starts a new process. It might be upto the current vlc configuration on your system whether it keeps multiple vlc instances or you are running a different command (different command-line arguments).
I am using my Raspberry Pi to play songs. I am trying to control the mplayer through a simple python programme. I have chosen python because I new to coding and have set up some simple imput driven menus to choose songs.
I found this code here to play the song :-
import os
SOUND = 'music.mp3'
command = 'mplayer %s 1>/dev/null 2>&1' % SOUND
os.system(command)
But I can't work out how to stop it part way through a track and return to my simple python menu to choose another option. Please help . . .
You can use subprocess.Popen and kill the process whenever you want to end the song:
from subprocess import Popen
SOUND = 'music.mp3'
proc = Popen(['mplayer', '%s', '1>/dev/null', '2>&1',SOUND])
import time
time.sleep(3)
proc.kill()
ok, so my google-fu really kind of sucks and I was unable to find an answer, hopefully you folks can help me ^_^
ok, so what I thought would be a simple script is seemingly not communicating with its subprocess correctly, I'm running this line by line. I'm also using the mpg123 player, this is a Linux system (well, Raspberry Pi)
from subprocess import Popen, PIPE, STDOUT
p = Popen(["mpg123", "-C", "test.mp3"], stdout=PIPE, stdin=PIPE, stderr=STDOUT)
#wait a few seconds to enter this, "q" without a newline is how the controls for the player work to quit out if it were ran like "mpg123 -C test.mp3" on the command line
p.communicate(input='q')[0]
I can run stdout.read() on it just fine, but using communicate for input just makes it hang and p.stdin.write('q') does seemingly nothing at all. This is python related though I have a feeling I'm also not looking in the right place in the mpg123 documentation. Please be kind as I'm exceptionally new to this ^_^
Check what arguments your mpg123 version understands. The following works on my machine:
#!/usr/bin/env python3
import time
from subprocess import Popen, PIPE, DEVNULL, STDOUT
p = Popen(["mpg123", "-K", "test.mp3"], stdin=PIPE, stdout=DEVNULL, stderr=STDOUT)
# wait a little
time.sleep(3)
# send command "Skip song", wait for the player to exit
p.communicate(b'n')[0]
It starts playing the file, waits ~3 seconds, and exits.
This is an awful solution, but it works in a pinch. I'm using this as a patch because for some reason, I cannot get Python libraries to play properly on my Raspberry Pi.
If you start mpg123 in remote mode (mpg123 -R), you can send commands to it far more easily:
proc = sp.Popen(["mpg123", "-R"], stdin=sp.PIPE)
Then, you can send commands to its stdin attribute.
Note:
The commands are different. To pause, it's "pause", not " " for example. Run mpg123 -R in a console, then send it the help command to see a list of commands.
The commands need to be newline terminated.
From the docs:
-R, --remote
Activate generic control interface. mpg123 will then read and execute commands from stdin. Basic usage is ''load '' to play some file and the obvious ''pause'', ''command. ''jump '' will jump/seek to a given point (MPEG frame number). Issue ''help'' to get a full list of commands and syntax.