fenrir/src/fenrirscreenreader/soundDriver/gstreamerDriver.py

114 lines
4.1 KiB
Python

#!/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
from fenrirscreenreader.core import debug
import time, threading
from fenrirscreenreader.core.soundDriver import soundDriver
_gstreamerAvailable = False
try:
import gi
from gi.repository import GLib
gi.require_version('Gst', '1.0')
from gi.repository import Gst
_gstreamerAvailable, args = Gst.init_check(None)
except Exception as e:
_gstreamerAvailable = False
_availableError = str(e)
class driver(soundDriver):
def __init__(self):
soundDriver.__init__(self)
self._source = None
self._sink = None
def initialize(self, environment):
self.env = environment
global _gstreamerAvailable
self._initialized = _gstreamerAvailable
if not self._initialized:
global _availableError
self.environment['runtime']['debug'].writeDebugOut('Gstreamer not available ' + _availableError,debug.debugLevel.ERROR)
return
self._player = Gst.ElementFactory.make('playbin', 'player')
bus = self._player.get_bus()
bus.add_signal_watch()
bus.connect("message", self._onPlayerMessage)
self._pipeline = Gst.Pipeline(name='fenrir-pipeline')
bus = self._pipeline.get_bus()
bus.add_signal_watch()
bus.connect("message", self._onPipelineMessage)
self._source = Gst.ElementFactory.make('audiotestsrc', 'src')
self._sink = Gst.ElementFactory.make('autoaudiosink', 'output')
self._pipeline.add(self._source)
self._pipeline.add(self._sink)
self._source.link(self._sink)
self.mainloop = GLib.MainLoop()
self.thread = threading.Thread(target=self.mainloop.run)
self.thread.start()
def shutdown(self):
if not self._initialized:
return
self.cancel()
self.mainloop.quit()
def _onPlayerMessage(self, bus, message):
if not self._initialized:
return
if message.type == Gst.MessageType.EOS:
self._player.set_state(Gst.State.NULL)
elif message.type == Gst.MessageType.ERROR:
self._player.set_state(Gst.State.NULL)
error, info = message.parse_error()
self.env['runtime']['debug'].writeDebugOut('GSTREAMER: _onPlayerMessage'+ str(error) + str(info),debug.debugLevel.WARNING)
def _onPipelineMessage(self, bus, message):
if not self._initialized:
return
if message.type == Gst.MessageType.EOS:
self._pipeline.set_state(Gst.State.NULL)
elif message.type == Gst.MessageType.ERROR:
self._pipeline.set_state(Gst.State.NULL)
error, info = message.parse_error()
self.env['runtime']['debug'].writeDebugOut('GSTREAMER: _onPipelineMessage'+ str(error) + str(info),debug.debugLevel.WARNING)
def _onTimeout(self, element):
if not self._initialized:
return
element.set_state(Gst.State.NULL)
def playSoundFile(self, fileName, interrupt=True):
if not self._initialized:
return
if interrupt:
self.cancel()
self._player.set_property('uri', 'file://%s' % fileName)
self._player.set_state(Gst.State.PLAYING)
def playFrequence(self, frequence, duration, adjustVolume, interrupt=True):
if not self._initialized:
return
if interrupt:
self.cancel()
self._source.set_property('volume', tone.volume)
self._source.set_property('freq', tone.frequency)
self._source.set_property('wave', tone.wave)
self._pipeline.set_state(Gst.State.PLAYING)
duration = int(1000 * tone.duration)
GLib.timeout_add(duration, self._onTimeout, self._pipeline)
def cancel(self, element=None):
if not self._initialized:
return
if element:
element.set_state(Gst.State.NULL)
return
self._player.set_state(Gst.State.NULL)
self._pipeline.set_state(Gst.State.NULL)