【问题标题】:Avoiding visual artifacts when embedding MPlayer in PyGTK在 PyGTK 中嵌入 MPlayer 时避免视觉伪影
【发布时间】:2013-05-18 21:28:39
【问题描述】:

我正在尝试创建一个基本的 PyGTK 应用程序来将 MPlayer 嵌入到一个窗口中(因为它不能很好地与我喜欢的平铺 WM 一起工作)。

到目前为止,我将把我的代码放在这篇文章的末尾,但基本上我的设置目前涉及一个包含一个 DrawingArea 的窗口,我使用 `-wid' 命令行选项将 MPlayer 嵌入到该窗口中。

我遇到的问题是,在调整大小时,我得到以下类型的视觉伪影(见红框内):

当配置事件发生时,我尝试在 DrawingArea 上调用 queue_draw(),但这似乎没有效果。有人有什么想法吗?

我的完整代码如下:(命令行用法是`$0 [ vid ]')

#!/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])

【问题讨论】:

    标签: python pygtk mplayer visual-artifacts


    【解决方案1】:

    解决了 - 解决方案是添加

    -vo gl
    

    对 mplayer 的调用。也就是我换了

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

    与

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

    在上面的代码中,现在它可以正确调整大小了。

    那个命令行选项实际上已经消除了我想首先创建这个包装脚本的全部原因(即将 mplayer 嵌入到一个黑色边框的窗口中,占用了电影本身不需要的空间,以便使用它在 dwm 中),但我想这个修复对于其他出于其他原因想要嵌入 mplayer 的人仍然有用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-29
      • 2019-07-14
      • 1970-01-01
      • 2014-02-20
      • 1970-01-01
      • 2012-04-13
      • 2019-06-08
      • 2014-10-10
      相关资源
      最近更新 更多