Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在gstreamer中获取视频的高度和宽度?_Python_Linux_Gstreamer - Fatal编程技术网

Python 在gstreamer中获取视频的高度和宽度?

Python 在gstreamer中获取视频的高度和宽度?,python,linux,gstreamer,Python,Linux,Gstreamer,我正在为linux开发一个wx Python media ctrl,它使用gstreamer(感觉wx widgets版本必须是自定义编译的)。。。我发现gstreamer要么很糟糕,要么就是没有好的文档,因为它是有史以来最令人困惑的东西。这是我当前的代码,我想我要做的是获取消息_tagtype MESSAGE并从中执行一些操作,但我现在还不确定,当我当前运行它时,我得到了一个错误 代码 “” 调整GStreamer以适合wx.media.MediaCtrl 为什么? -是,wx.media.M

我正在为linux开发一个wx Python media ctrl,它使用gstreamer(感觉wx widgets版本必须是自定义编译的)。。。我发现gstreamer要么很糟糕,要么就是没有好的文档,因为它是有史以来最令人困惑的东西。这是我当前的代码,我想我要做的是获取消息_tagtype MESSAGE并从中执行一些操作,但我现在还不确定,当我当前运行它时,我得到了一个错误

代码

“”
调整GStreamer以适合wx.media.MediaCtrl
为什么?
-是,wx.media.MediaCtrl有一个gstreamer后端
但它是无用的,甚至不起作用
因为显然是WX小部件C++代码
需要使用gstreamer支持进行编译
现在他们为什么不在linux上这么做
将在Linux上运行的具有
使用gstreamer的可能原因我没有
我知道为什么,但他们不知道。
主要从wxWidgets旧代码移植。
'''
导入操作系统
导入wx
从wx.lib.newevent导入NewCommandEvent
进口商品及服务税
导入gobject
从twisted.python导入日志
#启动线程,否则观察来自其他线程的消息会给我们一个错误
gobject.threads_init()
#州
#可能不是wx.media.MediaCtrl使用的数字
MEDIASTATE_播放=0
MEDIASTATE_=1
MEDIASTATE_已停止=2
#事件
媒体加载事件,EVT\U媒体加载=事件()
媒体播放事件,EVT媒体播放=NewCommandEvent()
媒体暂停事件,EVT\U媒体暂停=事件()
媒体停止事件,EVT媒体停止=NewCommandEvent()
媒体完成事件,EVT\U媒体完成=事件()
GstreamerCtrl类(wx.面板):
定义初始化(自身、父项、id):
wx.Panel.uuuu init_uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
loop=gobject.MainLoop()
self.context=loop.get_context()
#使用GetState获取新状态
self.state=gst.state_NULL#当前状态
self.no_resource=True
self.video_size=(0,0)
self.caps=[]
self.paused\u playback\u position=0
wx.CallLater(500,self.gstreamer\u循环)
self.playbin=gst.element\u factory\u make(“playbin 2”)
#代码来自http://www.majorsilence.com/pygtk_audio_and_video_playback_gstreamer
总线=self.playbin.get_总线()
总线.添加信号\u手表()
总线.启用\u同步\u消息\u发射()
总线连接(“消息”,自接通消息)
总线连接('sync-message::element',self.on\u sync\u消息)
self.Bind(wx.EVT\u WINDOW\u DESTROY、self.OnWinDestroy、self)
def on_sync_消息(自身、总线、消息):
#代码来自http://pythonide.blogspot.com/2008/03/howto-write-wxpython-video-player-with.html
#另见http://pygstdocs.berlios.de/pygst-tutorial/videomixer.html
打印“===============================”
如果message.structure为无:
返回
message\u name=message.structure.get\u name()
打印邮件名称
如果消息_name==“准备xwindow id”:
imagesink=message.src
imagesink.set_属性('force-aspect-ratio',True)
imagesink.set_xwindow_id(self.GetHandle())
def SetInitialSize(自身):
通过#与其他人进行交叉比较,但gstreamer会自动通过
def on_消息(自身、总线、消息):
如果message.type==gst.message\u STATE\u已更改:
# http://pygstdocs.berlios.de/pygst-reference/class-gstmessage.htm
state=message.parse_state_changed()#当前状态[旧状态、新状态、挂起状态]
self.state=state[1]#更新状态(如果是重复,我们不必这样做,因为它是第一次设置的)
如果self.state==gst.state_READY:#如果这是第一个加载状态(感觉它不是重复,而是状态_READY)
打印“启动EVT\u媒体加载”
自发送事件(媒体加载事件)
#获取gstreamer信息
elif message.type==gst.message_标记:
self.caps.append(消息)
#这就是我们得到尺寸的地方;为什么这么不清楚
#检测流结束并将状态设置为NULL
#代码来自http://www.majorsilence.com/pygtk_audio_and_video_playback_gstreamer
elif message.type==gst.message_EOS:
log.msg(“Gstreaner[Debug]:EOS”)
#文件结束了,停下来,在结尾说
self.Stop()
#在文件末尾
自我发送事件(媒体完成事件)
elif message.type==gst.message\u错误:
(err,debug)=message.parse_error()
打印“Gstreamer[错误]:%s”%err
打印“Gstreamer[Debug]:%s”%Debug
#某些未知错误必须设置为null,否则可能是路径名错误
self.playbin.set_state(gst.state_NULL)
自我发送事件(媒体停止事件)
自我发送事件(媒体完成事件)
def gstreamer_回路(自):
self.context.iteration(True)
wx.CallLater(500,self.gstreamer\u循环)
定义发送事件(自身、事件):
打印“触发事件”
evt=事件(self.GetId())
wx.PostEvent(自我,evt)
def加载(自身,文件路径):
self.no_resource=False
self.paused\u playback\u position=0
file\u path=os.path.abspath(file\u path)
打印“加载文件”+文件路径
打印“通过URI文件加载://”
LoadURI(“文件:/”+文件路径)
返回真值
def LoadURI(自我,uri):
self.no_resource=False
log.msg(“URI:%s”%URI)
self.paused\u playback\u position=0
self.playbin.set_state(gst.state_NULL)
self.playbin.set_属性(“uri”,uri)
打印自我状态
#开始下载
self.playbin.set_state(gst.state_PLAYING)
self.playbin.set_状态(gst.state_暂停)
返回真值
def播放(自我):
如果self.no_资源:
雷图
'''
Adapts GStreamer to fit wx.media.MediaCtrl
Why?
    - Yes wx.media.MediaCtrl has a gstreamer backend
      but it is useless and well doesn't even work 
      because apparently the wx widgets C++ code
      needs to be compiled with gstreamer support
      now why they don't do that for the linux
      build that will be running on Linux with 
      a likely hood of using gstreamer I have no
      clue why but they don't.

Largely Ported from wxWidgets old code.
'''
import os

import wx
from wx.lib.newevent import NewCommandEvent
import gst
import gobject

from twisted.python import log


# Start threads otherwise watching messages from other threads gives us a segfault
gobject.threads_init()

# States
# might not be the numbers wx.media.MediaCtrl uses
MEDIASTATE_PLAYING = 0
MEDIASTATE_PAUSED =  1 
MEDIASTATE_STOPPED = 2

# Events
media_loaded_event  , EVT_MEDIA_LOADED   = NewCommandEvent()
media_play_event    , EVT_MEDIA_PLAY     = NewCommandEvent()
media_pause_event   , EVT_MEDIA_PAUSE    = NewCommandEvent()
media_stop_event    , EVT_MEDIA_STOP     = NewCommandEvent()
media_finished_event, EVT_MEDIA_FINISHED = NewCommandEvent()

class GstreamerCtrl(wx.Panel):

    def __init__(self, parent, id):
        wx.Panel.__init__(self, parent, id, size = (0,0))
        loop = gobject.MainLoop()
        self.context = loop.get_context()

        # use GetState to get new state
        self.state = gst.STATE_NULL # current state 

        self.no_resource = True

        self.video_size = (0,0)

        self.caps = []

        self.paused_playback_position = 0

        wx.CallLater(500, self.gstreamer_loop)

        self.playbin = gst.element_factory_make("playbin2")

        # Code from http://www.majorsilence.com/pygtk_audio_and_video_playback_gstreamer
        bus = self.playbin.get_bus()
        bus.add_signal_watch()
        bus.enable_sync_message_emission()
        bus.connect("message", self.on_message)
        bus.connect('sync-message::element', self.on_sync_message)

        self.Bind(wx.EVT_WINDOW_DESTROY, self.OnWinDestroy, self)

    def on_sync_message(self, bus, message):
        # Code from http://pythonide.blogspot.com/2008/03/howto-write-wxpython-video-player-with.html
        # See  also http://pygstdocs.berlios.de/pygst-tutorial/videomixer.html
        print "===================="
        if message.structure is None:
            return
        message_name = message.structure.get_name()
        print message_name
        if message_name  == 'prepare-xwindow-id':
            imagesink = message.src
            imagesink.set_property('force-aspect-ratio', True)
            imagesink.set_xwindow_id(self.GetHandle())

    def SetInitialSize(self):
        pass# for cross compartibilitry with others but gstreamer does it automatically

    def on_message(self, bus, message):
        if message.type == gst.MESSAGE_STATE_CHANGED:
            # http://pygstdocs.berlios.de/pygst-reference/class-gstmessage.htm
            state = message.parse_state_changed()#current state [oldstate, newstate, pendingstate]
            self.state = state[1]# update the state (we don't have to do this if it is a repeat because it was set the first time around)
            if self.state == gst.STATE_READY:# if this is the first load state (sense it isn't a repeat and it is a STATE_READY)
                print "Firing EVT_MEDIA_LOADED"
                self._send_event(media_loaded_event)

        # get gstreamer information
        elif message.type == gst.MESSAGE_TAG:
            self.caps.append(message)
            # is this where we get the size; why is it so unclear  

        # Detect end of stream and set state to to NULL
        # Code From http://www.majorsilence.com/pygtk_audio_and_video_playback_gstreamer
        elif message.type == gst.MESSAGE_EOS:
            log.msg("Gstreaner [Debug]: EOS")
            # end of file so stop and say at the end
            self.Stop()
            # at end of file
            self._send_event(media_finished_event)

        elif message.type == gst.MESSAGE_ERROR:
            (err, debug) = message.parse_error()
            print "Gstreamer [ERROR]: %s" % err
            print "Gstreamer [Debug]: %s" % debug
            # Some unknown error have to set to null not anything else cause could be error with path name
            self.playbin.set_state(gst.STATE_NULL)
            self._send_event(media_stop_event)
            self._send_event(media_finished_event)


    def gstreamer_loop(self):
        self.context.iteration(True)
        wx.CallLater(500, self.gstreamer_loop)

    def _send_event(self, event):
        print "Firing an event"
        evt = event(self.GetId())
        wx.PostEvent(self, evt)

    def Load(self, file_path):
        self.no_resource = False
        self.paused_playback_position = 0
        file_path = os.path.abspath(file_path)
        print "Loading File " + file_path
        print "Loading through URI file://"
        self.LoadURI("file://" + file_path )
        return True

    def LoadURI(self, uri):
        self.no_resource = False
        log.msg("URI: %s" % uri)
        self.paused_playback_position = 0
        self.playbin.set_state(gst.STATE_NULL) 
        self.playbin.set_property("uri", uri)
        print self.state
        # Start download
        self.playbin.set_state(gst.STATE_PLAYING)
        self.playbin.set_state(gst.STATE_PAUSED)
        return True

    def Play(self):
        if self.no_resource:
            return False # see stop() for why false here but true for stop
        self.playbin.set_state(gst.STATE_PLAYING)
        print "Firing EVT_MEDIA_PLAY"
        self._send_event(media_play_event)
        return True


    def Pause(self):
        if self.no_resource:
            return False # see stop() for why false here but true for stop
        self.paused_playback_position = self.Tell() 
        self.playbin.set_state(gst.STATE_PAUSED)        
        print "Firing EVT_MEDIA_PAUSE"
        self._send_event(media_pause_event)
        return True

    def Stop(self):
        # it seeems that to stop on gstreamer you set the state to paused
        # and then set the stream position to 0
        # why not just have STOPPED state or have NULL be stopped
        # What is used in wxWidgets code now set
        if self.no_resource:
            # confirms stop was good because we are "stopped" play pause however say they failed because not "playing" or "paused"
            print "Firing EVT_MEDIA_STOPPED"
            self._send_event(media_stop_event)
            return True
        self.paused_playback_position = 0
        self.Seek(0)
        self.playbin.set_state(gst.STATE_PAUSED)
        print "Firing EVT_MEDIA_STOPPED"
        self._send_event(media_stop_event)
        return True

    def GetState(self):
        # Stop  - 0
        # Pause - 1
        # Play  - 2    
        state = self.state
        # see http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstElement.html#gst-element-get-state
        if state == gst.STATE_PAUSED:
            if self.paused_playback_position == 0:
                return MEDIASTATE_STOPPED
            else:
                return MEDIASTATE_PAUSED
        elif state == gst.STATE_PLAYING:
            return MEDIASTATE_PLAYING
        else:# Other states (NULL, READY, etc)
            return MEDIASTATE_STOPPED


    def SetVolume(self, volume):
        # wx media media ctrl takes a value between 0.0 and 1.0
        # gstreamer takes a value between 0 and 10
        # maybe not volume seems funny
        # try setting it to * 10 again still weird setting it back
        self.playbin.set_property("volume", volume)

    def Tell(self):
        if self.state != gst.STATE_PLAYING:
            # Any other state other than playing return the paused time otherwise something strange could be returned
            return self.paused_playback_position
        time_format = gst.Format(gst.FORMAT_TIME) #time in nanoseconds
        try:
            data = self.playbin.query_position(time_format)
        except gst.QueryError:
            return -1
        position = int(data[0] / 1000000.0)
        return position

    def Length(self):
        time_format = gst.Format(gst.FORMAT_TIME) #time in nanoseconds
        try:
            data = self.playbin.query_duration(time_format)
        except gst.QueryError:
            return -1
        length = int(data[0] / 1000000.0)
        return length

    def Seek(self, position):
        if self.no_resource:
            return False
        print "Seeking to %s" % position
        if position < 0 or position > self.Length():
            return
        self.paused_playback_position = position
        position_ns = position * 1000000
        self.playbin.seek_simple(gst.FORMAT_TIME, gst.SEEK_FLAG_FLUSH, position_ns)
        return True

    def OnWinDestroy(self, event):
        self.playbin.set_state(gst.STATE_NULL)


if __name__ == "__main__":
    a = wx.App(False)
    f = wx.Frame(None, -1, size = (500,300))

    PlayerSizer = wx.BoxSizer(wx.VERTICAL)
    PlayerSizer.Add(self.player, flag = wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border = 10, proportion = 1)
    f.d = GstreamerCtrl(f, -1)
    f.Show()
    wx.CallLater(10000, f.d.LoadURI,  "http://www.tools4movies.com/dvd_catalyst_profile_samples/Harold%20Kumar%203%20Christmas%20bionic.mp4")
    a.MainLoop()