来自/dev/video0的python播放输出

来自/dev/video0的python播放输出,python,Python,我将此代码用于在python窗口中使用mplayer进行文件播放。对于文件,它播放得很好(使用未注释的fifo部分)。但现在我正在尝试对其进行调整,以播放来自source/dev/video0的视频。但是运气不好。 我做错了什么 我的代码: #!/usr/bin/env python2 import sys import os import subprocess import time import string import gtk import gobject import pygtk

我将此代码用于在python窗口中使用mplayer进行文件播放。对于文件,它播放得很好(使用未注释的fifo部分)。但现在我正在尝试对其进行调整,以播放来自source/dev/video0的视频。但是运气不好。 我做错了什么

我的代码:

#!/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 = string.split("mplayer -slave -wid %d tv:// -tv device=/dev/video0 -hardframedrop" % \
        #cmd = string.split("mplayer -slave -wid %d -input file=%s" % \
        cmd = string.split("mplayer -slave -wid %d tv:// -tv device=/dev/video0 -hardframedrop" % \
                (self.draw.window.xid))
        #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])
    wrapper.play('')
编辑: 文件video.mp4(python script.py video.mp4)的工作示例:


在本例中,它一起播放video.mp4和/dev/video0。我想删除video.mp4,所以我评论了self.fifo行。也许这是错误的…

我想我找到了解决方案-这是我的视频代码,仅适用于/dev/video0

#!/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, draw):
        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 tv:// -tv driver=v4l2:norm=PAL:width=640:height=480:outfmt=uyvy:device=/dev/video0 -hardframedrop -input file=%s" % \
                (self.draw.window.xid, self.fifo))

        self.devnull = open(os.devnull)
        process = subprocess.Popen(cmd)

        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()
        self.window.set_decorated(False)
        self.window.resize(640,480)
        self.window.set_position(gtk.WIN_POS_CENTER)

        self.play()

    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):       
        with MPlayer(self.draw) as self.mplayer:
            gobject.child_watch_add(self.mplayer.pid, gtk.main_quit)


if __name__ == "__main__":
    wrapper = MPlayerWrapper()
    gtk.main()

请澄清“运气不佳”。如果你也能创建一个,那就是godo。只是一个旁注:
Popen
的命令是作为一个列表给出的,这是出于安全考虑。从拆分字符串构造它的方式就是破坏该安全特性。使用列表并将参数添加为列表项。您好,谢谢。我用工作示例编辑了我的问题。现在,我正在尝试删除video.mp4的播放,而只保留/dev/video0中的播放源
#!/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, draw):
        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 tv:// -tv driver=v4l2:norm=PAL:width=640:height=480:outfmt=uyvy:device=/dev/video0 -hardframedrop -input file=%s" % \
                (self.draw.window.xid, self.fifo))

        self.devnull = open(os.devnull)
        process = subprocess.Popen(cmd)

        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()
        self.window.set_decorated(False)
        self.window.resize(640,480)
        self.window.set_position(gtk.WIN_POS_CENTER)

        self.play()

    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):       
        with MPlayer(self.draw) as self.mplayer:
            gobject.child_watch_add(self.mplayer.pid, gtk.main_quit)


if __name__ == "__main__":
    wrapper = MPlayerWrapper()
    gtk.main()