Added client code

This commit is contained in:
pmkuipers 2025-06-11 15:23:38 +02:00
parent 9689d254e3
commit 5a67358fbf

356
mediaserver/mediaclient.py Normal file
View file

@ -0,0 +1,356 @@
import dbus
import dbus.service
import dbus.mainloop.glib
from . import dbus_smartobject
from . import event
import os
import gi
from gi.repository import GLib
from gi.repository import GObject
class MediaClient(dbus_smartobject.DBusSmartObject):
def __init__(self,quickfolder=None):
if not quickfolder is None:
self._quickfolder = quickfolder
else:
self._quickfolder = os.path.dirname(os.getcwd())
self.Playing = False
self.Paused = False
self.Stopped = True
self.Buffering = False
self.status_url = None
self.status_position = 0
self.status_reloading = False
# initialize the events
self.OnLoading = event.Event()
self.OnReady = event.Event()
self.OnPlaying = event.Event()
self.OnPaused = event.Event()
self.OnReconnectReady = event.Event()
self.OnReconnectPlaying = event.Event()
self.OnReconnectPaused = event.Event()
self.OnStopped = event.Event()
self.OnFinished = event.Event()
self.OnFinishing = event.Event()
self.OnLoadFail = event.Event()
self.OnRunFail = event.Event()
self.OnConnect = event.Event()
self.OnReconnect = event.Event()
self.OnDisconnect = event.Event()
self.OnBuffering = event.Event()
# init base object
dbus_smartobject.DBusSmartObject.__init__( self,
service='nl.miqra.MediaCore.Media',
path='/nl/miqra/MediaCore/Media',
interface='nl.miqra.MediaCore.Media',
systembus=True)
self.statusticker()
def init_busobject(self,busobject):
# this is what gives us the multi media keys.
# connect_to_signal registers our callback function.
busobject.connect_to_signal('OnLoading', self._onLoading)
# connect_to_signal registers our callback function.
busobject.connect_to_signal('OnReady', self._onReady)
# connect_to_signal registers our callback function.
busobject.connect_to_signal('OnPlaying', self._onPlaying)
# connect_to_signal registers our callback function.
busobject.connect_to_signal('OnPaused', self._onPaused)
# connect_to_signal registers our callback function.
busobject.connect_to_signal('OnStopped', self._onStopped)
# connect_to_signal registers our callback function.
busobject.connect_to_signal('OnFinished', self._onFinished)
# connect_to_signal registers our callback function.
busobject.connect_to_signal('OnFinishing', self._onFinishing)
# connect_to_signal registers our callback function.
busobject.connect_to_signal('OnLoadFail', self._onLoadFail)
# connect_to_signal registers our callback function.
busobject.connect_to_signal('OnRunFail', self._onRunFail)
# connect_to_signal registers our callback function.
busobject.connect_to_signal('OnBuffering', self._onBuffering)
def on_connection_lost(self):
self.OnDisconnect()
def on_connection_made(self):
self.OnConnect()
def on_connection_regained(self):
if self.status_url is not None:
self.status_reloading = True
self.LoadUrl(self.status_url)
def statusticker(self):
if self.connected():
if not self.status_reloading and (self.Playing or self.Paused):
self.status_position = self.Position()
#print "backed up position: {0}".format(self.status_position)
GObject.timeout_add(1000, self.statusticker)
#callback function
def _onLoading(self,url):
""" gets called when a source has been requested for playback
"""
self.OnLoading(url)
def _onBuffering(self,pct):
""" gets called when a source has been requested for playback
"""
if pct < 100:
self.Buffering = True
else:
self.Buffering = False
self.OnBuffering(pct)
def _onReady(self,url,tags):
""" gets called when a source is ready for playback
"""
if not self.status_reloading:
self.Playing = False
self.Paused = False
self.Stopped = True
self.status_url = url
self.OnReady(url,tags)
else:
if self.Playing or self.Paused:
self.Play()
else:
self.status_reloading = False
self.OnReconnectReady()
def _onPlaying(self):
""" gets called when a playback has started
"""
if not self.status_reloading:
self.Playing = True
self.Paused = False
self.Stopped = False
self.OnPlaying()
else:
self.Seek(self.status_position)
if self.Paused:
self.Pause()
else:
self.status_reloading = False
self.OnReconnectPlaying()
pass
def _onPaused(self):
""" gets called when a playback is paused
"""
if not self.status_reloading:
self.Playing = False
self.Paused = True
self.Stopped = False
self.OnPaused()
else:
self.status_reloading = False
self.OnReconnectPaused()
def _onStopped(self):
""" gets called when playback has stopped
"""
self.Playing = False
self.Paused = False
self.Stopped = True
self.status_position = 0
self.OnStopped()
def _onFinished(self):
""" gets called when playback has completed
"""
self.Playing = False
self.Paused = False
self.Stopped = True
self.status_position = 0
self.OnFinished()
def _onFinishing(self):
self.OnFinishing()
def _onLoadFail(self,reason):
""" gets called when loading a source for playback fails
"""
self.OnLoadFail(reason)
def _onRunFail(self,reason):
""" gets called when playback fails
"""
self.OnRunFail(reason)
def QuickPlay(self, file, duration = None):
""" Directly play back a local file
"""
path = file
# check if the file exists, if not, try to find it in the base folder for quickplay or else as a subfolder of the __main__ folder
if not os.path.isfile(path):
path = os.path.join(self._quickfolder,file)
if not os.path.isfile(path):
path = os.path.join(os.getcwd(),file)
try:
if duration is None or duration <= 0:
self.call("QuickPlay",file)
else:
self.call("QuickPlayFor",file,duration)
except dbus_smartobject.NoConnectionError:
print("Could not call QuickPlay function because of no connection")
pass
def QuickPlayUrl(self, url, duration = None):
""" Directly play back a URL
"""
try:
if duration is None or duration <= 0:
self.call("QuickPlayUrl",url)
else:
self.call("QuickPlayUrlFor",url,duration)
except dbus_smartobject.NoConnectionError:
print("Could not call QuickPlayUrl function because of no connection")
pass
def QuickLoop(self, file):
""" Directly play back a local file
"""
path = file
# check if the file exists, if not, try to find it in the base folder for quickplay or else as a subfolder of the __main__ folder
if not os.path.isfile(path):
path = os.path.join(self._quickfolder,file)
if not os.path.isfile(path):
path = os.path.join(os.getcwd(),file)
try:
self.call("QuickLoop",file)
except dbus_smartobject.NoConnectionError:
print("Could not call QuickPlay function because of no connection")
pass
def QuickLoopUrl(self, url):
""" Directly play back a URL
"""
try:
self.call("QuickLoopUrl",url)
except dbus_smartobject.NoConnectionError:
print("Could not call QuickPlayUrl function because of no connection")
pass
def LoadFile(self, file):
""" Load a local file for playback
"""
try:
self.call("LoadFile",file)
except dbus_smartobject.NoConnectionError:
print("Could not call LoadFile because of no connection")
pass
def LoadUrl(self, url):
""" Load an url for playback
"""
try:
self.call("LoadUrl",url)
except dbus_smartobject.NoConnectionError:
print("Could not call LoadUrl because of no connection")
pass
def PlayFor(self, duration):
""" Starts playback for [duration] seconds
"""
try:
self.call("PlayFor",duration)
except dbus_smartobject.NoConnectionError:
print("Could not call PlayFor because of no connection")
pass
def Play(self):
""" Starts/resumes playback
"""
try:
self.call("Play")
except dbus_smartobject.NoConnectionError:
print("Could not call Play because of no connection")
pass
def Loop(self):
""" Starts/resumes playback
"""
try:
self.call("Loop")
except dbus_smartobject.NoConnectionError:
print("Could not call Loop because of no connection")
pass
def Pause(self):
""" Pauses playback
"""
try:
self.call("Pause")
except dbus_smartobject.NoConnectionError:
print("Could not call Pause because of no connection")
pass
def Stop(self):
""" Stops playback
"""
try:
self.call("Stop")
except dbus_smartobject.NoConnectionError:
print("Could not call Stop because of no connection")
pass
def Length(self):
""" returns length of currently loaded source
"""
try:
return self.call("Length")
except dbus_smartobject.NoConnectionError:
print("Could not call Length because of no connection")
return 0
def Position(self):
""" returns current position in the source
"""
try:
return self.call("Position")
except dbus_smartobject.NoConnectionError:
print("Could not call Position because of no connection")
return 0
def Seek(self,position):
""" jump to new position in the source
"""
try:
self.call("Seek",position)
self.status_position = position
except dbus_smartobject.NoConnectionError:
print("Could not call because of no connection")
pass