如何在不重新启动管道的情况下更改gstreamer管道中当前播放的文件?

时间:2018-03-23 11:15:58

标签: gstreamer python-gstreamer gstreamer-1.0

出于某种原因,我们无法在线找到解决此问题的工作方案。

现在我们的源代码是filesrc元素。我们当前的非解决方案是将管道的状态更改为READY,更改location属性,并将管道的状态设置为PLAYING(请参阅下面的change_song方法)。

这会出现以下错误:

CHANGING SONG TO music2.mp3
('ERROR:', 'filesource', ':', 'Internal data stream error.')
('debugging info:', 'gstbasesrc.c(2950): gst_base_src_loop (): /GstPipeline:pipeline0/GstFileSrc:filesource:\nstreaming stopped, reason not-linked (-1)')

我们听到第一首歌曲正在播放,但尝试重新进入播放状态时管道崩溃。这是我们的代码:

import gi
import time
import threading
gi.require_version('Gst', '1.0')
from gi.repository import Gst, GObject, GLib
class Server:
    def __init__(self):
        self.pipeline = None
        bus = None
        message = None

        # initialize GStreamer
        Gst.init(None)

        # build the pipeline
        self.pipeline = Gst.parse_launch('filesrc name=filesource ! queue name=queueelement ! decodebin ! audioconvert ! audioresample ! opusenc ! rtpopuspay ! udpsink port=40401 host=224.1.1.1')
        self.filesrc = self.pipeline.get_by_name("filesource")        
        self.filesrc.set_property("location", "music.mp3")
        self.queue = self.pipeline.get_by_name("queueelement")

    def hang(self):
        # wait until EOS or error
        bus = self.pipeline.get_bus()
        msg = bus.timed_pop_filtered(Gst.CLOCK_TIME_NONE, Gst.MessageType.ERROR | Gst.MessageType.EOS)

        if msg:
            t = msg.type
            if t == Gst.MessageType.ERROR:
                err, dbg = msg.parse_error()
                print("ERROR:", msg.src.get_name(), ":", err.message)
                if dbg:
                    print("debugging info:", dbg)
            elif t == Gst.MessageType.EOS:
                print("End-Of-Stream reached")
            else:
                # this should not happen. we only asked for ERROR and EOS
                print("ERROR: Unexpected message received.")

        # free resources
        self.pipeline.set_state(Gst.State.NULL)

    def start(self):
        # start playing
        self.pipeline.set_state(Gst.State.PLAYING)

        t = threading.Thread(target=self.hang)
        t.start()

    def change_song(self, song_name):
        print("CHANGING SONG TO " + song_name)
        self.pipeline.set_state(Gst.State.READY)
        self.filesrc.set_property("location", song_name)
        self.pipeline.set_state(Gst.State.PLAYING)

s = Server()
s.start()
time.sleep(5)
s.change_song("music2.mp3")

我们还尝试了以下方法:

def change_song(self, song_name):
    print("CHANGING SONG TO " + song_name)
    self.pipeline.set_state(Gst.State.READY)
    self.filesrc.unlink(queue)
    self.filesrc.set_property("location", song_name)
    self.filesrc.link(queue)
    self.pipeline.set_state(Gst.State.PLAYING)

但这会产生同样的错误。

0 个答案:

没有答案