Implemented use of glimagesink

Added looping functions
Removed separate quickplayer. Quickplayer is now integrated in normal player
This commit is contained in:
Miqra Developer 2018-09-26 19:14:21 +00:00
parent acc3ec8f2b
commit 106a20ad33
21 changed files with 828 additions and 98 deletions

2
.gitignore vendored Normal file → Executable file
View File

@ -1,3 +1,3 @@
build/ build/
deb_dist/ deb_dist/
*.pyc **/*.pyc

0
VERSION.py Normal file → Executable file
View File

0
debian/postinst vendored Normal file → Executable file
View File

6
etc/init.d/mediaserver Normal file → Executable file
View File

@ -47,8 +47,8 @@ VERBOSE=yes
# #
do_start() do_start()
{ {
# start background image # start background image (No, fbdrawer can be used for that now)
fbi -a -noverbose -t 1 -T 1 -d /dev/fb0 /usr/share/mediaserver/background-image.png >/dev/null 2> /dev/null & # fbi -a -noverbose -t 1 -T 1 -d /dev/fb0 /usr/share/mediaserver/background-image.png >/dev/null 2> /dev/null &
# Return # Return
# 0 if daemon has been started # 0 if daemon has been started
@ -71,7 +71,7 @@ do_start()
do_stop() do_stop()
{ {
# kill background image (fbi) # kill background image (fbi)
killall fbi # killall fbi
# Return # Return
# 0 if daemon has been stopped # 0 if daemon has been stopped

0
mediacore-mediaserver Normal file → Executable file
View File

0
mediaserver/PKG_CONFIG.py Normal file → Executable file
View File

0
mediaserver/__init__.py Normal file → Executable file
View File

View File

@ -1,68 +0,0 @@
# perform gstreamer imports (python3 style)
import gi
gi.require_version('Gst','1.0')
from gi.repository import GObject
from threading import Thread
import time
# import from this module
from basicplayer import BasicPlayer
class MonitorThread(Thread):
def __init__(self,player):
self.player = player
Thread.__init__(self)
self.daemon = True # as in: don't wait on this thread to quit
self._running = False
def stop(self):
if self._running:
self._running = False
#self.join(0.5)
def run(self):
self._running = True
while self._running:
if self.player.player_state == "PLAYING" and self.player.playtime > 0:
position = self.player.position()
if (position - self.player.startpos) >= self.player.playtime:
self.player._finished()
if self._running and time is not None:
time.sleep(0.2)
pass
class AudioPlayer(BasicPlayer):
def __init__(self):
BasicPlayer.__init__(self)
# setup monitor thread
self.monitor = MonitorThread(self)
self.monitor.start()
self.playtime = -1
def __del__(self):
self.monitor.stop()
def playfor(self,duration):
if duration > 0: # not much point in wasting system resources otherwise
self.startpos = self.position()
self.playtime = duration
# self.monitor.start()
BasicPlayer.play(self)
elif duration < 0: # same as normal play
self.play()
def play(self):
if self.player_state != "PAUSED":
self.playtime = -1;
BasicPlayer.play(self)
def stop(self):
self.playtime = -1;
BasicPlayer.stop(self)
#self.monitor.stop()
GObject.type_register(AudioPlayer)

9
mediaserver/basicplayer.py Normal file → Executable file
View File

@ -101,7 +101,6 @@ class BasicPlayer(GObject.GObject):
self.player_state = "LOADING" self.player_state = "LOADING"
self.tags.clear() self.tags.clear()
def stop(self): def stop(self):
if self.player_state in ["PLAYING","PAUSED",]: if self.player_state in ["PLAYING","PAUSED",]:
self._running = False self._running = False
@ -109,25 +108,27 @@ class BasicPlayer(GObject.GObject):
self.player_state = "READY" self.player_state = "READY"
self.emit('playback-stopped') self.emit('playback-stopped')
def pause(self): def pause(self,notify=True):
# cannot pause/unpause if we're waiting for buffer # cannot pause/unpause if we're waiting for buffer
if self.player_state in ["PLAYING",] and not self.buffering: if self.player_state in ["PLAYING",] and not self.buffering:
self.player_state = "PAUSED" self.player_state = "PAUSED"
self.pipeline.set_state(Gst.State.PAUSED) self.pipeline.set_state(Gst.State.PAUSED)
if notify:
self.emit('playback-paused') self.emit('playback-paused')
def _finished(self): def _finished(self):
self._running = False self._running = False
self.pipeline.set_state(Gst.State.READY) self.pipeline.set_state(Gst.State.READY)
self.seek(0) self.seek(0)
self.player_state = "READY" self.player_state = "PAUSED"
self.emit('playback-finished') self.emit('playback-finished')
def prepare_gstreamer(self): def prepare_gstreamer(self):
# bin containing the recorder stuff # bin containing the recorder stuff
self.pipeline = Gst.ElementFactory.make("playbin", None) self.pipeline = Gst.ElementFactory.make("playbin", None)
videosink = Gst.ElementFactory.make("eglglessink", None) videosink = Gst.ElementFactory.make("glimagesink", None)
alsasink = Gst.ElementFactory.make("alsasink", None) alsasink = Gst.ElementFactory.make("alsasink", None)
# set output device # set output device

357
mediaserver/client.py Executable file
View File

@ -0,0 +1,357 @@
import dbus
import dbus.service
import dbus.mainloop.glib
import dbus_smartobject
import event
import __main__
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(__main__.__file__)
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.path.dirname(__main__.__file__),file)
try:
if duration is None or duration <= 0:
self.call("QuickPlay",file)
else:
self.call("QuickPlayFor",file,duration)
except dbus_smartobject.NoConnectionError as x:
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 as x:
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.path.dirname(__main__.__file__),file)
try:
self.call("QuickLoop",file)
except dbus_smartobject.NoConnectionError as x:
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 as x:
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 as x:
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 as x:
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 as x:
print "Could not call PlayFor because of no connection"
pass
def Play(self):
""" Starts/resumes playback
"""
try:
self.call("Play")
except dbus_smartobject.NoConnectionError as x:
print "Could not call Play because of no connection"
pass
def Loop(self):
""" Starts/resumes playback
"""
try:
self.call("Loop")
except dbus_smartobject.NoConnectionError as x:
print "Could not call Loop because of no connection"
pass
def Pause(self):
""" Pauses playback
"""
try:
self.call("Pause")
except dbus_smartobject.NoConnectionError as x:
print "Could not call Pause because of no connection"
pass
def Stop(self):
""" Stops playback
"""
try:
self.call("Stop")
except dbus_smartobject.NoConnectionError as x:
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 as x:
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 as x:
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 as x:
print "Could not call because of no connection"
pass

144
mediaserver/dbus_smartobject.py Executable file
View File

@ -0,0 +1,144 @@
import dbus
import dbus.service
import dbus.mainloop.glib
import event
class NoConnectionError(Exception):
pass
class DBusSmartObject:
def __init__(self,service,path,interface,systembus=False):
# store service name and object path
self._service = service
self._object_path = path
self._interface = interface
if systembus == True:
self._bus_type = dbus.Bus.TYPE_SYSTEM
else:
self._bus_type = dbus.Bus.TYPE_SESSION
# prepare flex object
self._bus = None
self.busobject = None
self._beenconnected = False
# set up the glib main loop.
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
# connect to the dbus object to get information about existing connections
self._dbus = dbus.Bus(dbus.Bus.TYPE_SYSTEM)
self._dbus_object = self._dbus.get_object('org.freedesktop.DBus', '/org/freedesktop/DBus')
# this is what gives us the multi media keys.
self._dbus_interface='org.freedesktop.DBus'
# connect_to_signal registers our callback function.
self._dbus_object.connect_to_signal('NameOwnerChanged', self._onNameOwnerChanged)
# start initializing the connection
self._initialize_new_connection()
def close(self):
if self._bus is not None:
self._bus = None
self.busobject = None
if self._dbus is not None:
self._dbus = None
def init_busobject(self,busobject):
''' Override in child class to initialize bus signals on connect and reconnect
'''
pass
def on_connection_lost(self):
''' Override in child class to handle connection lost
'''
pass
def on_connection_made(self):
''' Override in child class to handle connection made
'''
pass
def on_connection_regained(self):
''' Override in child class to handle connection regained
'''
pass
def _initialize_new_connection(self):
# test if service is available on the selected bus. Skip otherwise
if self._dbus_object.NameHasOwner(self._service, dbus_interface=self._dbus_interface):
print "Initializing new connection to {0}".format(self._service)
self._bus = dbus.Bus(self._bus_type)
self.busobject = self._bus.get_object(self._service, self._object_path)
self.init_busobject(self.busobject)
self.on_connection_made()
if self._beenconnected == True:
self.on_connection_regained()
else:
self._beenconnected = True
else:
print "Could not create connection to {0}".format(self._service)
# bus object is not available - so disconnect the bus
if self._bus is not None:
self._bus = None
self.busobject = None
def _close_existing_connection(self):
if self._bus is not None:
print "Lost connection to {0}".format(self._service)
#self._bus.close()
self._bus = None
self.busobject = None
self.on_connection_lost()
def _onNameOwnerChanged(self,name,old_adr,new_adr):
''' Detects changes in service availablility
'''
if name == self._service:
if old_adr == "": # Service just became available
self._initialize_new_connection()
elif new_adr == "": # Service just became unavailable
self._close_existing_connection()
else: # service changed address
self._initialize_new_connection()
def call(self,method, *args, **kwargs):
if kwargs.has_key("interface"):
interface = kwargs["interface"]
else:
interface = self._interface
if self.busobject is not None:
#print "Attempting to call {0}".format(method)
method = self.busobject.get_dbus_method(method,dbus_interface=interface)
#print "Got method - calling with arguments: {0}".format(args)
return method(*args)
else:
raise NoConnectionError("Currently no connection to service {0}".format(self._service))
def trycall(self,method, *args, **kwargs):
# see if we have an default return value in case of error
if 'default' in kwargs:
default = kwargs['default']
del kwargs['default']
else:
default = None
try:
return self.call(method, *args, **kwargs)
except NoConnectionError as x:
print "Could not call {0} because there is currently no connection to {1}".format(method,self._service)
return default
def connected(self):
if self.busobject is not None:
return True
else:
return False

0
mediaserver/event.py Normal file → Executable file
View File

117
mediaserver/mediaserver.py Normal file → Executable file
View File

@ -26,7 +26,7 @@ from dbus.mainloop.glib import DBusGMainLoop
DBusGMainLoop(set_as_default=True) DBusGMainLoop(set_as_default=True)
# imports from module # imports from module
from audioplayer import AudioPlayer from monitoredplayer import MonitoredPlayer
from quickplayer import QuickPlayer from quickplayer import QuickPlayer
@ -36,7 +36,7 @@ class MediaService(dbus.service.Object):
bus_name = dbus.service.BusName('nl.miqra.MediaCore.Media', bus=dbus.SystemBus()) bus_name = dbus.service.BusName('nl.miqra.MediaCore.Media', bus=dbus.SystemBus())
dbus.service.Object.__init__(self, bus_name, '/nl/miqra/MediaCore/Media') dbus.service.Object.__init__(self, bus_name, '/nl/miqra/MediaCore/Media')
self.player = AudioPlayer() self.player = MonitoredPlayer()
self.quickplayer = QuickPlayer() self.quickplayer = QuickPlayer()
self.player.connect('playback-ready',self.onPlayerReady) # parameters: source_file tag_dict self.player.connect('playback-ready',self.onPlayerReady) # parameters: source_file tag_dict
@ -51,29 +51,102 @@ class MediaService(dbus.service.Object):
self.loadcount = 0; self.loadcount = 0;
self.loadmax = 1; self.loadmax = 1;
self.quickplay = False
self.quickplayduration = 0
self.quickplayloop = False
self.tick()
# Keepalive timer to help react to Keyboard interrupts
def tick(self):
GObject.timeout_add(100, self.tick)
@dbus.service.method(dbus_interface='nl.miqra.MediaCore.Media', in_signature='s', out_signature='') @dbus.service.method(dbus_interface='nl.miqra.MediaCore.Media', in_signature='s', out_signature='')
def QuickPlay(self, file,): def QuickPlay(self, file,):
""" Directly play back a local file """ Directly play back a local file
""" """
self.quickplayer.play(file) if self.loadcount < self.loadmax:
print "Quickplaying file {0}".format(file)
self.quickplay = True
self.quickplayduration = 0
self.quickplayloop = False
self.player.load(file)
self.loadcount += 1;
else:
print "Skipping load of file {0} because maximum simultaneous loads ({1}) was reached. Wait until ready....".format(file,self.loadmax);
@dbus.service.method(dbus_interface='nl.miqra.MediaCore.Media', in_signature='sd', out_signature='') @dbus.service.method(dbus_interface='nl.miqra.MediaCore.Media', in_signature='sd', out_signature='')
def QuickPlayFor(self, file, duration): def QuickPlayFor(self, file, duration):
""" Directly play back a local file """ Directly play back a local file
""" """
self.quickplayer.playfor(file,duration) if self.loadcount < self.loadmax:
print "Quickplaying file {0} for {1} seconds".format(file,duration)
self.quickplay = True
self.quickplayduration = duration
self.quickplayloop = False
self.player.load(file)
self.loadcount += 1;
else:
print "Skipping load of file {0} because maximum simultaneous loads ({1}) was reached. Wait until ready....".format(file,self.loadmax);
# self.quickplayer.playfor(file,duration)
@dbus.service.method(dbus_interface='nl.miqra.MediaCore.Media', in_signature='s', out_signature='') @dbus.service.method(dbus_interface='nl.miqra.MediaCore.Media', in_signature='s', out_signature='')
def QuickPlayUrl(self, url,): def QuickPlayUrl(self, url,):
""" Directly play back a url """ Directly play back a url
""" """
self.quickplayer.playurl(url) if self.loadcount < self.loadmax:
print "Quickplaying file {0}".format(file)
self.quickplay = True
self.quickplayduration = 0
self.quickplayloop = False
self.player.load_uri(file)
self.loadcount += 1;
else:
print "Skipping load of file {0} because maximum simultaneous loads ({1}) was reached. Wait until ready....".format(file,self.loadmax);
@dbus.service.method(dbus_interface='nl.miqra.MediaCore.Media', in_signature='sd', out_signature='') @dbus.service.method(dbus_interface='nl.miqra.MediaCore.Media', in_signature='sd', out_signature='')
def QuickPlayUrlFor(self, url, duration): def QuickPlayUrlFor(self, url, duration):
""" Directly play back a url """ Directly play back a url
""" """
self.quickplayer.playurlfor(url,duration) if self.loadcount < self.loadmax:
print "Quickplaying file {0} for {1} seconds".format(file,duration)
self.quickplay = True
self.quickplayduration = duration
self.quickplayloop = False
self.player.load_uri(file)
self.loadcount += 1;
else:
print "Skipping load of file {0} because maximum simultaneous loads ({1}) was reached. Wait until ready....".format(file,self.loadmax);
@dbus.service.method(dbus_interface='nl.miqra.MediaCore.Media', in_signature='s', out_signature='')
def QuickLoop(self, file,):
""" Directly play back a url
"""
if self.loadcount < self.loadmax:
print "Quickplaying file {0}".format(file)
self.quickplay = True
self.quickplayduration = 0
self.quickplayloop = True
self.player.load(file)
self.loadcount += 1;
else:
print "Skipping load of file {0} because maximum simultaneous loads ({1}) was reached. Wait until ready....".format(file,self.loadmax);
@dbus.service.method(dbus_interface='nl.miqra.MediaCore.Media', in_signature='s', out_signature='')
def QuickLoopUrl(self, url,):
""" Directly play back a url
"""
if self.loadcount < self.loadmax:
print "Quickplaying url {0}".format(uri)
self.quickplay = True
self.quickplayduration = 0
self.quickplayloop = True
self.player.load_uri(url)
self.loadcount += 1;
else:
print "Skipping load of file {0} because maximum simultaneous loads ({1}) was reached. Wait until ready....".format(file,self.loadmax);
@dbus.service.method(dbus_interface='nl.miqra.MediaCore.Media', in_signature='s', out_signature='') @dbus.service.method(dbus_interface='nl.miqra.MediaCore.Media', in_signature='s', out_signature='')
@ -82,7 +155,7 @@ class MediaService(dbus.service.Object):
""" """
if self.loadcount < self.loadmax: if self.loadcount < self.loadmax:
print "Loading file {0}".format(file) print "Loading file {0}".format(file)
print file self.quickplay = False
self.player.load(file) self.player.load(file)
self.loadcount += 1; self.loadcount += 1;
self.OnLoading("file://{0}".format(file)) self.OnLoading("file://{0}".format(file))
@ -95,6 +168,7 @@ class MediaService(dbus.service.Object):
""" """
if self.loadcount < self.loadmax: if self.loadcount < self.loadmax:
print "Loading url {0}".format(uri) print "Loading url {0}".format(uri)
self.quickplay = False
self.player.load_uri(uri) self.player.load_uri(uri)
self.loadcount += 1; self.loadcount += 1;
self.OnLoading(uri) self.OnLoading(uri)
@ -116,6 +190,14 @@ class MediaService(dbus.service.Object):
print "Starting playback at timestamp {0}".format(pos) print "Starting playback at timestamp {0}".format(pos)
self.player.play() self.player.play()
@dbus.service.method(dbus_interface='nl.miqra.MediaCore.Media', in_signature='', out_signature='')
def Loop(self):
""" Starts/resumes playback
"""
pos = self.player.position()
print "Starting playback at timestamp {0}".format(pos)
self.player.loop()
@dbus.service.method(dbus_interface='nl.miqra.MediaCore.Media', in_signature='', out_signature='') @dbus.service.method(dbus_interface='nl.miqra.MediaCore.Media', in_signature='', out_signature='')
def Pause(self): def Pause(self):
""" Pauses playback """ Pauses playback
@ -163,6 +245,17 @@ class MediaService(dbus.service.Object):
# reset load counter # reset load counter
self.loadcount = 0; self.loadcount = 0;
if self.quickplay:
if self.quickplayloop:
print("Direct looping")
self.player.loop()
elif self.quickplayduration > 0:
print("Direct playing for {0} s".format(self.quickplayduration))
self.player.playfor(self.quickplayduration)
else:
print("Direct playing")
self.player.play()
else:
# signal ready # signal ready
self.OnReady(filename,taglist) self.OnReady(filename,taglist)
@ -238,6 +331,12 @@ class MediaService(dbus.service.Object):
""" """
pass pass
@dbus.service.signal(dbus_interface='nl.miqra.MediaCore.Media', signature='')
def OnFinishing(self):
""" gets called when playback is nearly completed
"""
pass
@dbus.service.signal(dbus_interface='nl.miqra.MediaCore.Media', signature='s') @dbus.service.signal(dbus_interface='nl.miqra.MediaCore.Media', signature='s')
def OnLoadFail(self,reason): def OnLoadFail(self,reason):
""" gets called when loading a source for playback fails """ gets called when loading a source for playback fails
@ -262,4 +361,8 @@ def Run():
signal.signal(signal.SIGINT, onsigint) signal.signal(signal.SIGINT, onsigint)
print "Starting..." print "Starting..."
try:
loop.run() loop.run()
except KeyboardInterrupt:
print "Quitting"
loop.quit()

102
mediaserver/monitoredplayer.py Executable file
View File

@ -0,0 +1,102 @@
# perform gstreamer imports (python3 style)
import gi
gi.require_version('Gst','1.0')
from gi.repository import GObject
from threading import Thread
import time
# import from this module
from basicplayer import BasicPlayer
class MonitorThread:#(Thread):
def __init__(self,player):
self.player = player
#Thread.__init__(self)
self.daemon = True # as in: don't wait on this thread to quit
self._running = False
def stop(self):
if self._running:
self._running = False
#self.join(0.5)
def start(self):
self._running = True
self.run()
def run(self):
if self.player.player_state == "PLAYING":
position = self.player.position()
duration = self.player.duration()
if position < 0: # handle invalid operation
position = duration
print("\rTime Left: {0}".format(duration - position))
# handle finishing of limited playtime
if self.player.playtime > 0:
if (position - self.player.startpos) - self.player.playtime <= 0:
#self._player.pause(notify=False)
print "Finished limited play"
self.player._finished()
if self._running and time is not None:
GObject.timeout_add(20, self.run)
class MonitoredPlayer(BasicPlayer):
def __init__(self):
BasicPlayer.__init__(self)
# setup monitor thread
self.monitor = MonitorThread(self)
self.monitor.start()
self.playtime = -1
self.looping=False
def __del__(self):
self.monitor.stop()
def playfor(self,duration,loop=False):
loop = False
if duration > 0: # not much point in wasting system resources otherwise
self.startpos = self.position()
self.playtime = duration
BasicPlayer.play(self)
elif duration < 0: # same as normal play
self.play()
def loop(self):
self.looping = True
if self.player_state != "PAUSED":
self.startpos = 0
self.playtime = -1;
BasicPlayer.play(self)
def play(self):
self.looping = False
if self.player_state != "PAUSED":
self.startpos = 0
self.playtime = -1;
BasicPlayer.play(self)
def stop(self):
self.playtime = -1;
BasicPlayer.stop(self)
#self.monitor.stop()
def _finished(self):
if self.looping:
print("Finished - looping")
self.seek(0)
if self.player_state in ["READY","PAUSED",]:
self.player_state = "PLAYING"
self.pipeline.set_state(Gst.State.PLAYING)
else:
BasicPlayer._finished(self)
GObject.type_register(MonitoredPlayer)

4
mediaserver/quickplayer.py Normal file → Executable file
View File

@ -5,13 +5,13 @@ gi.require_version('Gst','1.0')
from gi.repository import GObject from gi.repository import GObject
# import from this module # import from this module
from audioplayer import AudioPlayer from monitoredplayer import MonitoredPlayer
class QuickPlayer(GObject.GObject): class QuickPlayer(GObject.GObject):
def __init__(self): def __init__(self):
GObject.GObject.__init__(self) GObject.GObject.__init__(self)
self.player = AudioPlayer() self.player = MonitoredPlayer()
self._duration = -1; self._duration = -1;
self.player.connect("playback-ready",self.onReady) self.player.connect("playback-ready",self.onReady)
self.player.connect("playback-error",self.onError) self.player.connect("playback-error",self.onError)

0
setup.py Normal file → Executable file
View File

2
stdeb.cfg Normal file → Executable file
View File

@ -1,6 +1,6 @@
[DEFAULT] [DEFAULT]
Depends: python-dbus, python-gi, fbi, gir1.2-gstreamer-1.0, gir1.2-gst-plugins-base-1.0, gstreamer1.0-plugins-good, gstreamer1.0-plugins-ugly, gstreamer1.0-plugins-bad, gstreamer1.0-alsa, gstreamer1.0-omx, gstreamer1.0-libav Depends: python-dbus, python-gi, gir1.2-gstreamer-1.0, gir1.2-gst-plugins-base-1.0, gstreamer1.0-plugins-good, gstreamer1.0-plugins-ugly, gstreamer1.0-plugins-bad, gstreamer1.0-alsa, gstreamer1.0-omx, gstreamer1.0-libav
XS-Python-Version: >= 2.6 XS-Python-Version: >= 2.6
Section: sound Section: sound
Package: mediaserver Package: mediaserver

15
test_basicplayer.py Normal file → Executable file
View File

@ -3,7 +3,7 @@
from mediaserver.audioplayer import AudioPlayer from mediaserver.audioplayer import AudioPlayer
from mediaserver.quickplayer import QuickPlayer from mediaserver.quickplayer import QuickPlayer
from gi.repository import GObject from gi.repository import GObject
import sys
def onReady(player, file, tags): def onReady(player, file, tags):
print "Starting {0} ...\n".format(file) print "Starting {0} ...\n".format(file)
@ -29,13 +29,14 @@ def onStop(player):
print "Quitting...." print "Quitting...."
loop.quit() loop.quit()
player = AudioPlayer() player = QuickPlayer()
player.connect("playback-ready",onReady) #player.connect("playback-ready",onReady)
player.connect("playback-playing",onPlaying) #player.connect("playback-playing",onPlaying)
player.connect("playback-finished",onStop) #player.connect("playback-finished",onStop)
player.connect("playback-stopped",onStop) #player.connect("playback-stopped",onStop)
player.load("/opt/mediacore/mediaserver2/snnw_E_138.mp3") #print "Attempting to play {0}".format(sys.argv[1])
player.play(sys.argv[1])

90
test_client.py Executable file
View File

@ -0,0 +1,90 @@
#!/usr/bin/python
from mediaserver.client import MediaClient
#!/usr/bin/env python
import sys, os, glob
import signal
import gi
from gi.repository import GLib
from gi.repository import GObject
#import Resources
class TestController:
def __init__(self):
#initialize loop
self.mainloop = GLib.MainLoop() # main loop
#initialize sensing
self.player = MediaClient()
self.player.OnPlaying += self.onPlayerPlaying
self.player.OnStopped += self.onPlayerStopped
self.player.OnPaused += self.onPlayerPaused
self.player.OnFinished += self.onPlayerFinished
self.player.OnFinishing += self.onPlayerFinishing
self.player.OnLoading += self.onPlayerLoading
self.player.OnReady += self.onPlayerReady
GObject.timeout_add(10, self.tick)
def tick(self):
self.player.QuickLoop("/opt/src/robotvideo/ogen open.mp4")
#GObject.timeout_add(3000, self.reboot)
pass
def onStarting(self):
pass
def onStopped(self):
pass
def onPlayerPlaying(self):
pass
def onPlayerStopped(self):
pass
def onPlayerPaused(self):
pass
def onPlayerFinished(self):
pass
def onPlayerFinishing(self):
pass
def onPlayerLoading(self, uri):
pass
def onPlayerReady(self,url,tags):
print('Trigger Ready')
pass
def Start(self):
print("Starting Mainloop")
# initia
self.onStarting()
try:
self.mainloop.run()
except KeyboardInterrupt:
self.Stop()
def Stop(self):
print("Stopping controller")
self.player.Stop()
self.mainloop.quit()
self.onStopped()
# Sigterm Callback function
def signalSIGTERM(self,signum):
controller.Stop()
signal.signal(signal.SIGTERM, signalSIGTERM)
controller = TestController()
controller.Start();

0
usr-share-mediaserver/background-image.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 74 KiB

After

Width:  |  Height:  |  Size: 74 KiB

0
usr-share-mediaserver/background-image.svg Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB