1

I have written the following code as a frontend for mplayer using tkinter. However, I'm stuck trying to use commands like 'get_time_pos' from mplayer because the answer is very sporadically written into the PIPE. By this I mean that sometimes, it doesn't write it at all and isn't read until the program is closed and sometimes it does. But every time, the video gets paused even though the toggle for pause is set to play (since it was already paused) due to passing in the other command (get time pos).

I'm at a loss, honestly and don't know how to fix this or even how to adequately describe the issue...

FOLLOWUP: Im modifying the post by posting only the relevant code parts

from Tkinter import *
from ttk import Frame
from tkFileDialog import askopenfilename, askopenfile
from tkMessageBox import showerror, showinfo
from subprocess import *
from threading import Thread
from Queue import Queue, Empty, LifoQueue
import os, sys
import socket
import select

def command_player(self, comd):
    if self.mplayer_isrunning():
        try:
            self.player_process.stdin.write("%s\r\n"%comd)
            self.player_process.stdin.flush()
        except :
            showerror("Error","Error passing command to mplayer\n%s"%sys.exc_info()[1])

self.player_process = Popen(["mplayer","-fs","-slave","-quiet","-wid",str(winid),self.filenm],stdin=PIPE, stdout=PIPE)

#TRYING TO GET VIDEO POSITION IN TERMS OF % AND THEN PAUSE
self.command_player("get_percent_pos")
output = self.player_process.stdout.readline()
self.command_player("pause")

The above does read the percent position but then it always keeps the video paused no matter what. If I keep only the pause command, the pause works as intended (it toggles b/w play and pause)

Also, the select() portion was me trying out a different way but it doesn't work on windows since it's not a socket. Any more help fixing the subprocess input/output issue will be appreciated.

g0d
  • 57
  • 1
  • 7
  • you could [use `createfilehandler()` to register a callback instead of manually calling `select()`](https://gist.github.com/zed/9294978). Don't dump all the code, [create a minimal complete code example instead](http://stackoverflow.com/help/mcve) – jfs Jun 17 '15 at 00:23
  • Thanks but createfilehandler() from tkinter is used to just show the stdout output in the GUI. I don't want that. The rest of the asynchronous reading from stdout using threads and queues, I've tried already. I guess it's not possible to make a working frontend for mplayer using python. – g0d Jun 17 '15 at 05:25
  • You do understand that you can do something else in the callback. Also, your example can't be run. Read the link I've provided. – jfs Jun 17 '15 at 05:27
  • I gave a runnable example before. You said that it was too long. Then I posted snippets out of the code to show what I was doing. It's obviously not going to run. Should I be rewriting the code to make it "minimal" while keep it working and then posting it here? I don't think it's worth the effort. I haven't gotten a specific answer to my issue which is with read/write on the pipe. – g0d Jun 17 '15 at 06:51
  • yes. Your example should be both minimal and complete. It is up to you whether you want to help others to help you. And `createfilehandler` works for writing too. – jfs Jun 17 '15 at 12:06
  • The Tkinter.createfilehandler() method isn't supported on Windows, only on Unix and Mac. Actually I've come across many methods to solve this problem but it has turned out every time that it would only be applicable to UNIX platforms. Thanks for the help though. Like I said, it is impossible to make it work on windows using python. There are some nice ways to do it using win32 apis readily available within C#. – g0d Jun 18 '15 at 05:04
  • `createfilehandler()` has been suggested because the first revision of your question uses `select()` with non-socket fd (that doesn't work on Windows as you know) and you hadn't mentioned that you need Windows support in the 1st revision. You need nonblocking io or threads for a portable solution. Here's [code example that uses threads](https://gist.github.com/zed/42324397516310c86288). – jfs Jun 18 '15 at 06:03

1 Answers1

0

Not sure but I think the problem is that a pipe is buffered. I see you are trying to address this issue on the stdin side with sending line breaks and calling flush(). Maybe this isn't enough. Try sending 8 KB of line breaks.

For readline(), you need an end-of-line character ('\n') but mplayer normally writes its progress information on the same line (with '\r').

It must be possible to get in- and output of a subprocess directly (without buffers) as terminal applications can print output immediately. It may involve attaching your processes to a pseudo-terminal device. A starting point may be How to use pseudo-terminals in Linux with C?

Community
  • 1
  • 1
Joachim Wagner
  • 860
  • 7
  • 16
  • related: [Python subprocess readlines() hangs](http://stackoverflow.com/q/12419198/4279) – jfs Oct 29 '16 at 10:11