2013-05-23 7 views
2

나는 MPlayer를 윈도우에 내장하기 위해 기본 PyGTK 앱을 만들려고합니다. (그렇지 않으면, 내가 좋아하는 타일링 WM에서 잘 작동하지 않기 때문에).PyGTK에서 MPlayer를 임베딩 할 때 시각적 인 인공물을 피하기

필자는이 포스트의 끝에 지금까지 코드를 넣겠지만, 기본적으로 내 설치에는 현재 MPlayer를`-wid '명령 행 옵션을 사용하여 삽입 한 DrawingArea가 포함 된 창이 포함됩니다.

제가하는 데 문제는 크기 조정 때, 나는 시각적 결함의 다음과 같은 종류가 (빨간색 상자 안에 참조) 얻을 수 있습니다 :

MPlayer artifact

내가 queue_draw를 호출하려고했습니다()에 구성 이벤트가 발생하면 DrawingArea가 발생하지만 효과가없는 것으로 보입니다. 누구든지 아이디어가 있습니까? 다음과 같이

내 전체 코드는 다음과 같습니다 그것을 해결

#!/usr/bin/env python2 

import sys 
import os 
import subprocess 
import time 
import string 

import gtk 
import gobject 
import pygtk 

pygtk.require('2.0') 

class MPlayer: 
    def __init__(self, path, draw, show_output=True): 
     self.path = path 
     self.draw = draw 
     self.fifo = "/tmp/%s.%d" % (os.path.basename(__file__), time.time()) 

     # Start mplayer in draw 
     cmd = string.split("mplayer -slave -wid %d -input file=%s" % \ 
       (self.draw.window.xid, self.fifo)) 
     cmd.append(self.path) 
     if show_output: 
      process = subprocess.Popen(cmd) 
     else: 
      self.devnull = open(os.devnull) 
      process = subprocess.Popen(cmd, stdout=self.devnull, \ 
        stderr=self.devnull) 

     self.pid = process.pid 

    def __enter__(self): 
     os.mkfifo(self.fifo) 
     return self 

    def __exit__(self, ext_type, exc_value, traceback): 
     if hasattr(self, "devnull"): 
      self.devnull.close() 
     os.unlink(self.fifo) 

    # Send cmd to mplayer via fifo 
    def exe(self, cmd, *args): 
     if not self.pid: return 
     full_cmd = "%s %s\n" % (cmd, string.join([str(arg) for arg in args])) 
     with open(self.fifo, "w+") as fifo: 
      fifo.write(full_cmd) 
      fifo.flush() 

class MPlayerWrapper: 
    def __init__(self): 
     self.window = gtk.Window(gtk.WINDOW_TOPLEVEL) 
     self.draw = gtk.DrawingArea() 
     self.mplayer = None 
     self.setup_widgets() 

    def setup_widgets(self): 
     self.window.connect("destroy", gtk.main_quit) 
     self.window.connect("key_press_event", self.key_press_event) 
     self.draw.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("black")) 
     self.draw.connect("configure_event", self.redraw) 
     self.window.add(self.draw) 
     self.window.show_all() 

    def mplayer_exe(self, cmd, *args): 
     if self.mplayer: 
      self.mplayer.exe(cmd, *args) 

    def key_press_event(self, widget, event, data=None): 
     self.mplayer_exe("key_down_event", event.keyval) 

    def redraw(self, draw, event, data=None): 
     self.draw.queue_draw() 

    def play(self, path): 
     with MPlayer(path, self.draw, True) as self.mplayer: 
      gobject.child_watch_add(self.mplayer.pid, gtk.main_quit) 
      gtk.main() 

if __name__ == "__main__": 
    wrapper = MPlayerWrapper() 
    wrapper.play(sys.argv[1]) 

답변

1

(명령 줄 사용법은 '`$ 0 ℃ VID]입니다) - 솔루션 통화에

-vo gl 

을 추가했다 mplayer에게. 즉, 위 코드에서

cmd = string.split("mplayer -slave -vo gl -wid %d -input file=%s" % \ 
     (self.draw.window.xid, self.fifo)) 

cmd = string.split("mplayer -slave -wid %d -input file=%s" % \ 
     (self.draw.window.xid, self.fifo)) 

교체, 지금은 제대로 크기를 조정합니다.

그 명령 줄 옵션은 실제로 처음부터이 래퍼 스크립트를 만들고 싶었던 모든 이유를 제거했습니다. 즉, mplayer를 영화 자체에 필요하지 않은 공간을 차지하는 검은 경계선이있는 창에 포함하려는 것입니다. dwm에서 사용). 그러나이 수정은 여전히 ​​다른 이유로 mplayer를 포함하려는 다른 사람들에게 유용 할 것이라고 상상합니다.