ラズベリーパイ2で映画を再生し、特別なメッセージが届いたときに別のトラック/ビデオに移動するか、ビデオを一時停止/一時停止解除するプログラムを作成しようとしています。
外界への接続は、そのコードにはない別のスレッドに存在します。これをメイン関数の sleep() 部分に置き換えました。
問題は、再生中にビデオファイルを変更すると(を呼び出してplayer.setFile(filesrc)
)、次のようなエラーメッセージが表示されることです。
glGetError 0x505
** (python2:3186): WARNING **: Use gst_egl_image_allocator_alloc() to allocate from this allocator
また
** (python2:3269): CRITICAL **: gst_omx_component_close_tunnel: assertion 'port1->tunneled && port2->tunneled' failed
時にはセグメンテーション違反。
質問: gstreamer1.0 と python を使用して、すべてのプレーヤーを再初期化せずに再生中のビデオを変更するにはどうすればよいですか (rpi2 では、かなり時間がかかります - 約 2 秒かかります) setFile(filesrc)
。
私のコードからの抜粋:
#!/usr/bin/python2
imports ....
videoPause = "video.mp4"
class gst_decodebin:
def __init__(self):
self.mainloop = GObject.MainLoop()
self.pipeline = Gst.Pipeline.new('playallpipeline')
self.filesrc = Gst.ElementFactory.make('filesrc', 'filesrc')
self.filesrc.set_property('location', videoPause)
self.pipeline.add(self.filesrc)
self.decode = Gst.ElementFactory.make('decodebin', 'decode')
self.pipeline.add(self.decode)
self.decode.connect('pad-added', self.decode_src_created)
self.audioconvert = Gst.ElementFactory.make('audioconvert', 'audioconvert')
self.videoconvert = Gst.ElementFactory.make('videoconvert', 'videoconvert')
self.queueaudio = Gst.ElementFactory.make('queue', 'queueaudio')
self.queuevideo = Gst.ElementFactory.make('queue', 'queuevideo')
self.videosink = Gst.ElementFactory.make('eglglessink', 'videosink')
self.audiosink = Gst.ElementFactory.make('alsasink', 'audiosink')
#self.audiosink.set_property('device', 'hw:1,0')
self.audiosink.set_property('device', 'hw:0,0')
# Zur Pipeline adden
self.pipeline.add(self.audioconvert)
self.pipeline.add(self.videoconvert)
self.pipeline.add(self.queueaudio)
self.pipeline.add(self.queuevideo)
self.pipeline.add(self.videosink)
self.pipeline.add(self.audiosink)
# Elemente verlinken
self.filesrc.link(self.decode)
self.queueaudio.link(self.audioconvert)
self.audioconvert.link(self.audiosink)
self.queuevideo.link(self.videoconvert)
self.videoconvert.link(self.videosink)
# Bus für Nachrichten aufsetzen
self.bus = self.pipeline.get_bus()
self.bus.add_signal_watch()
self.bus.connect('message', self.message)
# Callback für decode.connected
def decode_src_created(self, element, pad):
pad.link(self.queuevideo.get_static_pad('sink'))
pad.link(self.queueaudio.get_static_pad('sink'))
def play(self):
print "PLAY"
self.playmode = "play";
self.pipeline.set_state(Gst.State.PLAYING)
def pause(self):
self.playmode = "pause";
self.pipeline.set_state(Gst.State.PAUSED)
def setFile(self, filesrc):
self.audioconvert.unlink(self.audiosink)
self.videoconvert.unlink(self.videosink)
self.pipeline.set_state(Gst.State.READY)
if os.path.isfile(filesrc):
print "Setting File to %s" % filesrc
self.filesrc.set_property('location', filesrc)
else:
print "Setting File to Pause"
self.filesrc.set_property('location', videoPause)
self.audioconvert.link(self.audiosink)
self.videoconvert.link(self.videosink)
self.play()
def stop(self):
self.playmode = "stop";
self.pipeline.set_state(Gst.State.NULL)
def message(self, bus, message):
mtype = message.type
if mtype == Gst.MessageType.EOS:
self.exit()
elif mtype == Gst.MessageType.ERROR:
err, debug = message.parse_error()
print 'Error: %s' % err, debug
self.exit()
if __name__ == "__main__":
GObject.threads_init()
Gst.init(None)
player = gst_decodebin()
player.setFile("/media/source/first/other/video.mp4")
player.play();
time.sleep(3)
player.setFile("/media/source/to/other/video.mp4")
time.sleep(10)