File: gstreamer.py

package info (click to toggle)
python-snapcast 2.3.7-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 184 kB
  • sloc: python: 1,564; makefile: 9
file content (66 lines) | stat: -rw-r--r-- 2,034 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
""" GStreamer-related items. """

import gi
from gi.repository import GObject, Gst

gi.require_version('Gst', '1.0')
GObject.threads_init()
Gst.init(None)


class GstreamerAppSrc:
    """ GStreamer 1.0 App Source.

    Pipeline is like this:
    App Source -> Decode -> Queue -> Convert -> Sink

    App Source: The snapcast client pushes buffers into the source.
    Decode: Will decode for codecs supported by GStreamer (ogg, flac, etc)
    Queue: Queue for converting.
    Convert: Convert to suitable representation for Alsa.
    Sink: Alsa.
    """

    def __init__(self):
        """ Initialize app src. """
        self._mainloop = GObject.MainLoop()
        self._pipeline = Gst.Pipeline()

        # Make elements.
        self._src = Gst.ElementFactory.make('appsrc', 'appsrc')
        decode = Gst.ElementFactory.make("decodebin", "decode")
        self._queueaudio = Gst.ElementFactory.make('queue', 'queueaudio')
        audioconvert = Gst.ElementFactory.make('audioconvert', 'audioconvert')
        sink = Gst.ElementFactory.make('alsasink', 'sink')

        self._src.set_property('stream-type', 'stream')

        # Add to pipeline.
        self._pipeline.add(self._src)
        self._pipeline.add(decode)
        self._pipeline.add(self._queueaudio)
        self._pipeline.add(audioconvert)
        self._pipeline.add(sink)

        # Link elements.
        self._src.link(decode)
        self._queueaudio.link(audioconvert)
        audioconvert.link(sink)
        decode.connect('pad-added', self._decode_src_created)

    def play(self):
        """ Play. """
        self._pipeline.set_state(Gst.State.PLAYING)

    def run(self):
        """ Run - blocking. """
        self._mainloop.run()

    def push(self, buf):
        """ Push a buffer into the source. """
        self._src.emit('push-buffer', Gst.Buffer.new_wrapped(buf))

    # pylint: disable=unused-argument
    def _decode_src_created(self, element, pad):
        """ Link pad to queue. """
        pad.link(self._queueaudio.get_static_pad('sink'))