Implemented use of glimagesink
Added looping functions Removed separate quickplayer. Quickplayer is now integrated in normal player
This commit is contained in:
		
							parent
							
								
									acc3ec8f2b
								
							
						
					
					
						commit
						106a20ad33
					
				
					 21 changed files with 828 additions and 98 deletions
				
			
		
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										
										
										Normal file → Executable file
									
								
							|  | @ -1,3 +1,3 @@ | ||||||
| build/ | build/ | ||||||
| deb_dist/ | deb_dist/ | ||||||
| *.pyc | **/*.pyc | ||||||
|  |  | ||||||
							
								
								
									
										0
									
								
								VERSION.py
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								VERSION.py
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								debian/postinst
									
									
									
									
										vendored
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								debian/postinst
									
									
									
									
										vendored
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										6
									
								
								etc/init.d/mediaserver
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										6
									
								
								etc/init.d/mediaserver
									
									
									
									
									
										
										
										Normal file → Executable 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
									
								
							
							
						
						
									
										0
									
								
								mediacore-mediaserver
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								mediaserver/PKG_CONFIG.py
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								mediaserver/PKG_CONFIG.py
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								mediaserver/__init__.py
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								mediaserver/__init__.py
									
									
									
									
									
										
										
										Normal file → Executable 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
									
								
							
							
						
						
									
										9
									
								
								mediaserver/basicplayer.py
									
									
									
									
									
										
										
										Normal file → Executable 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
									
								
							
							
						
						
									
										357
									
								
								mediaserver/client.py
									
									
									
									
									
										Executable 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
									
								
							
							
						
						
									
										144
									
								
								mediaserver/dbus_smartobject.py
									
									
									
									
									
										Executable 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
									
								
							
							
						
						
									
										0
									
								
								mediaserver/event.py
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										117
									
								
								mediaserver/mediaserver.py
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										117
									
								
								mediaserver/mediaserver.py
									
									
									
									
									
										
										
										Normal file → Executable 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
									
								
							
							
						
						
									
										102
									
								
								mediaserver/monitoredplayer.py
									
									
									
									
									
										Executable 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
									
								
							
							
						
						
									
										4
									
								
								mediaserver/quickplayer.py
									
									
									
									
									
										
										
										Normal file → Executable 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
									
								
							
							
						
						
									
										0
									
								
								setup.py
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										2
									
								
								stdeb.cfg
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										2
									
								
								stdeb.cfg
									
									
									
									
									
										
										
										Normal file → Executable 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
									
								
							
							
						
						
									
										15
									
								
								test_basicplayer.py
									
									
									
									
									
										
										
										Normal file → Executable 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
									
								
							
							
						
						
									
										90
									
								
								test_client.py
									
									
									
									
									
										Executable 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
									
								
							
							
						
						
									
										0
									
								
								usr-share-mediaserver/background-image.png
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							| Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 74 KiB | 
							
								
								
									
										0
									
								
								usr-share-mediaserver/background-image.svg
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								usr-share-mediaserver/background-image.svg
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							| Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB | 
		Loading…
	
		Reference in a new issue
	
	 Miqra Developer
						Miqra Developer