Python: Send command to mplayer under slave mode

前端 未结 2 1235
时光说笑
时光说笑 2021-01-14 06:56

I\'m trying to send command via pipe to mplayer when running it under slave mode like this:

import subprocess, time
# start mplayer
song = \'mysong.mp3\'
cmd         


        
相关标签:
2条回答
  • 2021-01-14 07:22

    I'm now doing it this way and I start to get output:

     while True:
        cmd = '\nget_meta_artist\n'
        p.stdin.write(cmd)
        output = p.stdout.readline()
        print("output: {}".format(output.rstrip()))
        sys.stdout.flush()
    

    Although I still need to figure out a way to bypass the first flush of mplayer's own initialization stdout but I consider my problem solved.

    Thanks to glglgl for giving me useful hints.

    0 讨论(0)
  • 2021-01-14 07:33

    You can only use .communicate() once per subprocess. So using it in a while loop doesn't work.

    Instead, you should parse the output of p.stdout directly. There seems to be one line per answer if there is an answer.

    In order to prevent blocking, you have 3 options:

    1. Work with threads. You have a separate thread who reads from p.stdout and sends its data to the main thread. It blocks if no data is available.

    2. Set p.stdout to non-blocking mode. Essentially, you'll have to do this:

      import fcntl, os
      fcntl.fcntl(p.stdout.fileno(), fcntl.F_SETFL,
          fcntl.fcntl(p.stdout.fileno(), fcntl.F_GETFL) | os.O_NONBLOCK)
      

      If you read then without data being available, you get an exception (IOError: [Errno 11] Resource temporarily unavailable).

    3. Work with select.select(): perform p.stdout.readline() only if select.select([p.stdout], [], [], <timeout>)[0] is a non-empty list. In that case, the given file object is guaranteed to have data available and to not block on reading.

    In order to separate "garbage output" from "useful" output, you could do this:

    def perform_command(p, cmd, expect):
        import select
        p.stdin.write(cmd + '\n') # there's no need for a \n at the beginning
        while select.select([p.stdout], [], [], 0.05)[0]: # give mplayer time to answer...
            output = p.stdout.readline()
            print("output: {}".format(output.rstrip()))
            split_output = output.split(expect + '=', 1)
            if len(split_output) == 2 and split_output[0] == '': # we have found it
                value = split_output[1]
                return value.rstrip()
    

    and then do

    print perform_command(p, 'get_meta_artist', 'ANS_META_ARTIST')
    print perform_command(p, 'get_time_pos', 'ANS_TIME_POSITION')
    
    0 讨论(0)
提交回复
热议问题