我有一个使用PyQt4和Phonon(带有gstreamer0.1后端)的音乐应用程序。我想使用一些GStreamer代码添加一些音频分析。这两组代码都可以独立工作,但是当我尝试将它们组合在同一个应用程序中时,我会遇到以下错误并且应用程序挂起。测试代码如下。有什么想法吗?
> (python3:11922): GStreamer-WARNING **: Element factory metadata for 'bin' has no valid long-name field
> phonon_gstreamer.py:110: Warning: cannot register existing type `GstObject'
self.audioOutput = Phonon.AudioOutput(Phonon.MusicCategory, self)
> phonon_gstreamer.py:110: Warning: g_once_init_leave: assertion `result != 0' failed
self.audioOutput = Phonon.AudioOutput(Phonon.MusicCategory, self)
> phonon_gstreamer.py:110: Warning: g_type_register_static: assertion `parent_type > 0' failed
self.audioOutput = Phonon.AudioOutput(Phonon.MusicCategory, self)
> phonon_gstreamer.py:110: Warning: g_object_newv: assertion `G_TYPE_IS_OBJECT (object_type)' failed
self.audioOutput = Phonon.AudioOutput(Phonon.MusicCategory, self)
from PyQt4 import QtGui
from PyQt4.phonon import Phonon
import gi
gi.require_version('Gst', '1.0')
from gi.repository import GObject, Gst
class AudioAnalysis(Gst.Bin):
def __init__(self):
super().__init__()
# Create elements
q1 = Gst.ElementFactory.make('queue', None)
convert = Gst.ElementFactory.make("audioconvert", None)
resample = Gst.ElementFactory.make("audioresample", None)
self.analysis = Gst.ElementFactory.make("rganalysis", None)
self.analysis.set_property("num-tracks", 1)
q2 = Gst.ElementFactory.make('queue', None)
# Add elements to Bin
self.add(q1)
self.add(convert)
self.add(resample)
self.add(self.analysis)
self.add(q2)
# Link elements
q1.link(convert)
convert.link(resample)
resample.link(self.analysis)
self.analysis.link(q2)
# Add Ghost Pads
self.add_pad(
Gst.GhostPad.new('sink', q1.get_static_pad('sink'))
)
self.add_pad(
Gst.GhostPad.new('src', q2.get_static_pad('src'))
)
def bus_message_tag(self, bus, message):
pass
class Example:
def __init__(self):
self.mainloop = GObject.MainLoop()
self.pipeline = Gst.Pipeline()
# Create elements
self.src = Gst.ElementFactory.make('filesrc', None)
self.dec = Gst.ElementFactory.make('decodebin', None)
self.audio = AudioAnalysis()
self.sink = Gst.ElementFactory.make('fakesink', None)
# Add elements to pipeline
self.pipeline.add(self.src)
self.pipeline.add(self.dec)
self.pipeline.add(self.audio)
self.pipeline.add(self.sink)
# Set properties
self.src.set_property('location', 'foo.mp3')
# Connect signal handlers
self.dec.connect('pad-added', self.on_pad_added)
self.dec.connect('pad-removed', self.removed_decoded_pad)
# Link elements
self.src.link(self.dec)
self.audio.link(self.sink)
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)
self.bus.connect("message::tag", self.audio.bus_message_tag)
def run(self):
self.pipeline.set_state(Gst.State.PLAYING)
self.mainloop.run()
def kill(self):
self.pipeline.set_state(Gst.State.NULL)
self.mainloop.quit()
def removed_decoded_pad(self, dbin, pad):
pad.unlink(self.audio.get_static_pad("sink"))
def on_pad_added(self, element, pad):
string = pad.query_caps(None).to_string()
if string.startswith('audio/'):
pad.link(self.audio.get_static_pad('sink'))
def on_eos(self, bus, msg):
self.kill()
def on_error(self, bus, msg):
print('on_error():', msg.parse_error())
self.kill()
#example = Example()
#example.run()
class Window(QtGui.QPushButton):
def __init__(self):
QtGui.QPushButton.__init__(self, '')
self.mediaObject = Phonon.MediaObject(self)
self.audioOutput = Phonon.AudioOutput(Phonon.MusicCategory, self)
Phonon.createPath(self.mediaObject, self.audioOutput)
self.mediaObject.stateChanged.connect(self.handleStateChanged)
self.mediaObject.setCurrentSource(Phonon.MediaSource(sys.argv[1]))
self.mediaObject.play()
def handleStateChanged(self, newstate, oldstate):
if newstate == Phonon.PlayingState:
self.setText('Playing')
elif newstate == Phonon.StoppedState:
self.setText('Stopped')
elif newstate == Phonon.ErrorState:
source = self.mediaObject.currentSource().fileName()
print('ERROR: could not play:', source.toLocal8Bit().data())
if __name__ == '__main__':
GObject.threads_init()
Gst.init(None)
import sys
app = QtGui.QApplication(sys.argv)
app.setApplicationName('Phonon')
win = Window()
win.resize(200, 100)
win.show()
sys.exit(app.exec_())
答案 0 :(得分:1)
这是不可能的。 Gstreamer 0.10和1.x不可并联。
尝试使用此分支:https://projects.kde.org/projects/kdesupport/phonon/phonon-gstreamer/repository/show?rev=1.0-porting(不稳定的AFAIK)
或使用非gstreamer声子后端。或者您可以在separete过程中实现分析代码,而不是直接调用它。