在树莓派上使用 GstVideo
运行 Python 程序,可以通过 GStreamer 库来实现。GstVideo
是 GStreamer 的一个视频处理模块,你可以利用它来处理视频流、视频解码、编码、显示和处理等。
1、问题背景
用户想要在树莓派上使用 GstVideo 运行 Python 程序,但在运行时遇到了错误。错误信息是“ImportError: cannot import name GstVideo”。
2、解决方案
GstVideo 是 GStreamer 的一部分,因此需要先在树莓派上安装 GStreamer。可以在命令行中运行以下命令来安装 GStreamer:
sudo apt-get update
sudo apt-get install gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-ugly gstreamer1.0-plugins-bad gstreamer1.0-libav
在安装了 GStreamer 之后,就可以安装 GstVideo 了。可以在命令行中运行以下命令来安装 GstVideo:
sudo apt-get install libgstvideo-dev
在安装了 GstVideo 之后,需要对代码进行一些修改。具体来说,需要在代码的开头添加以下两行代码:
import gi
gi.require_version('GstVideo', '1.0')
在修改了代码之后,就可以在树莓派上运行代码了。可以在命令行中运行以下命令来运行代码:
python3 DO.py
代码例子
以下是修改后的代码:
#!/usr/bin/python3
from os import path
import gi
gi.require_version('Gst', '1.0')
gi.require_version('GstVideo', '1.0')
from gi.repository import GObject, Gst, Gtk
# Needed for window.get_xid(), xvimagesink.set_window_handle(), respectively:
from gi.repository import GdkX11, GstVideo
GObject.threads_init()
Gst.init(None)
class Player(object):
def __init__(self):
self.window = Gtk.Window()
self.window.connect('destroy', self.quit)
self.window.set_default_size(800, 450)
self.drawingarea = Gtk.DrawingArea()
self.window.add(self.drawingarea)
# Create GStreamer pipeline
self.pipeline = Gst.Pipeline()
self.pipeline_A = Gst.Pipeline()
# Create bus to get events from GStreamer pipeline
self.bus = self.pipeline.get_bus()
self.bus.add_signal_watch()
self.bus.connect('message::eos', self.on_eos)
self.bus.connect('message::error', self.on_error)
# This is needed to make the video output in our DrawingArea:
self.bus.enable_sync_message_emission()
self.bus.connect('sync-message::element', self.on_sync_message)
##############################################################################
#VIDEO Pipeline
#|
#|
#V
##############################################################################
self.tcpsrc = Gst.ElementFactory.make('tcpclientsrc','tcpsrc')
self.tcpsrc.set_property("host", '192.168.1.12')
self.tcpsrc.set_property("port", 5000)
self.gdepay = Gst.ElementFactory.make('gdpdepay', 'gdepay')
self.rdepay = Gst.ElementFactory.make('rtph264depay', 'rdepay')
self.avdec = Gst.ElementFactory.make('avdec_h264', 'avdec')
self.vidconvert = Gst.ElementFactory.make('videoconvert', 'vidconvert')
self.asink = Gst.ElementFactory.make('autovideosink', 'asink')
self.asink.set_property('sync', False)
#self.asink.set_property('emit-signals', True)
#self.set_property('drop', True)
self.pipeline.add(self.tcpsrc)
self.pipeline.add(self.gdepay)
self.pipeline.add(self.rdepay)
self.pipeline.add(self.avdec)
self.pipeline.add(self.vidconvert)
self.pipeline.add(self.asink)
self.tcpsrc.link(self.gdepay)
self.gdepay.link(self.rdepay)
self.rdepay.link(self.avdec)
self.avdec.link(self.vidconvert)
self.vidconvert.link(self.asink)
##############################################################################
#^
#|
#|
#VIDEO Pipeline
##############################################################################
##############################################################################
#AUDIO Pipeline
#|
#|
#V
##############################################################################
self.udpsrc = Gst.ElementFactory.make('udpsrc', 'udpsrc')
self.udpsrc.set_property("port",5001)
audioCaps = Gst.Caps.from_string("application/x-rtp")
self.udpsrc.set_property("caps", audioCaps)
self.queue = Gst.ElementFactory.make('queue', 'queue')
self.rtppcmudepay = Gst.ElementFactory.make('rtppcmudepay', 'rtppcmudepay')
self.mulawdec = Gst.ElementFactory.make('mulawdec', 'mulawdec')
self.audioconvert = Gst.ElementFactory.make('audioconvert', 'audioconvert')
self.autoaudiosink = Gst.ElementFactory.make('autoaudiosink', 'autoaudiosink')
self.autoaudiosink.set_property('sync', False)
self.pipeline_A.add(self.udpsrc)
self.pipeline_A.add(self.queue)
self.pipeline_A.add(self.rtppcmudepay)
self.pipeline_A.add(self.mulawdec)
self.pipeline_A.add(self.audioconvert)
self.pipeline_A.add(self.autoaudiosink)
self.udpsrc.link(self.queue)
self.queue.link(self.rtppcmudepay)
self.rtppcmudepay.link(self.mulawdec)
self.mulawdec.link(self.audioconvert)
self.audioconvert.link(self.autoaudiosink)
##############################################################################
#^
#|
#|
#AUDIO Pipeline
##############################################################################
def run(self):
self.window.show_all()
# You need to get the XID after window.show_all(). You shouldn't get it
# in the on_sync_message() handler because threading issues will cause
# segfaults there.
self.xid = self.drawingarea.get_property('window').get_xid()
self.pipeline.set_state(Gst.State.PLAYING)
self.pipeline_A.set_state(Gst.State.PLAYING)
Gtk.main()
def quit(self, window):
self.pipeline.set_state(Gst.State.NULL)
Gtk.main_quit()
def on_sync_message(self, bus, msg):
if msg.get_structure().get_name() == 'prepare-window-handle':
print('prepare-window-handle')
msg.src.set_window_handle(self.xid)
def on_eos(self, bus, msg):
print('on_eos(): seeking to start of video')
self.pipeline.seek_simple(
Gst.Format.TIME,
Gst.SeekFlags.FLUSH | Gst.SeekFlags.KEY_UNIT,
0
)
def on_error(self, bus, msg):
print('on_error():', msg.parse_error())
p = Player()
p.run()
在树莓派上使用 GstVideo
运行 Python 程序,通常涉及安装 GStreamer 和相关插件,创建视频处理管道,并通过 gst-python
将 GStreamer 的功能与 Python 代码集成。你可以使用 appsink
获取处理后的帧数据,并使用 OpenCV 等库进一步处理这些数据。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。