4 # Copyright (C) 2006 Rafaël Carré <funman at videolanorg>
8 # This program is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 2 of the License, or
11 # (at your option) any later version.
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with this program; if not, write to the Free Software
20 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
24 # NOTE: this controller is a SAMPLE, and thus doesn't implement all the D-Bus Media Player specification. http://wiki.videolan.org/index.php/DBus-spec
25 # This is an unfinished document (on the 12/06/2006) and has been designed to be as general as possible.
26 # So don't expect that much from this, but basic capabilities should work out of the box (Play/Pause/Next/Add)
28 # Also notice it has been designed first for a previous specificaiton, and thus some code may not work/be disabled
30 # You'll need pygtk >= 2.10 to use gtk.StatusIcon
44 def itemchange_handler(item
):
45 gobject
.timeout_add( 2000, timeset
)
55 bus
= dbus
.SessionBus()
56 player_o
= bus
.get_object("org.freedesktop.MediaPlayer", "/Player")
57 tracklist_o
= bus
.get_object("org.freedesktop.MediaPlayer", "/TrackList")
59 tracklist
= dbus
.Interface(tracklist_o
, "org.freedesktop.MediaPlayer")
60 player
= dbus
.Interface(player_o
, "org.freedesktop.MediaPlayer")
62 player_o
.connect_to_signal("TrackChange", itemchange_handler
, dbus_interface
="org.freedesktop.MediaPlayer")
68 mrl
= e_mrl
.get_text()
69 if mrl
!= None and mrl
!= "":
70 tracklist
.AddTrack(mrl
, True)
72 mrl
= bt_file
.get_filename()
73 if mrl
!= None and mrl
!= "":
74 tracklist
.AddTrack("directory://" + mrl
, True)
79 player
.Next(reply_handler
=(lambda *args
: None), error_handler
=(lambda *args
: None))
83 player
.Prev(reply_handler
=(lambda *args
: None), error_handler
=(lambda *args
: None))
87 player
.Stop(reply_handler
=(lambda *args
: None), error_handler
=(lambda *args
: None))
90 #update status display
92 item
= tracklist
.GetMetadata(tracklist
.GetCurrentTrack())
93 vol
.set_value(player
.VolumeGet())
102 #get playing status from remote vlc
103 def GetPlayStatus(widget
):
105 status
= player
.GetStatus()
107 img_bt_toggle
.set_from_stock("gtk-media-pause", gtk
.ICON_SIZE_SMALL_TOOLBAR
)
110 img_bt_toggle
.set_from_stock("gtk-media-play", gtk
.ICON_SIZE_SMALL_TOOLBAR
)
114 player
.Quit(reply_handler
=(lambda *args
: None), error_handler
=(lambda *args
: None))
119 status
= player
.GetStatus()
121 img_bt_toggle
.set_from_stock(gtk
.STOCK_MEDIA_PAUSE
, gtk
.ICON_SIZE_SMALL_TOOLBAR
)
122 gobject
.timeout_add( 2000, timeset
)
124 img_bt_toggle
.set_from_stock(gtk
.STOCK_MEDIA_PLAY
, gtk
.ICON_SIZE_SMALL_TOOLBAR
)
128 def volchange(widget
, data
):
129 player
.VolumeSet(vol
.get_value_as_int(), reply_handler
=(lambda *args
: None), error_handler
=(lambda *args
: None))
131 #callback for position change
132 def timechange(widget
, x
=None, y
=None):
133 player
.PositionSet(int(time_s
.get_value()), reply_handler
=(lambda *args
: None), error_handler
=(lambda *args
: None))
138 time_s
.set_value(player
.PositionGet())
142 def expander(widget
):
143 if exp
.get_expanded() == False:
144 exp
.set_label("Less")
146 exp
.set_label("More")
149 def delete_event(self
, widget
):
156 def key_release(widget
, event
):
158 if event
.keyval
== gtk
.keysyms
.Escape
:
159 position
= window
.get_position()
162 #click on the tray icon
163 def tray_button(widget
):
165 if window
.get_property('visible'):
166 position
= window
.get_position()
169 window
.move(position
[0], position
[1])
172 xml
= gtk
.glade
.XML('dbus-vlc.glade')
174 bt_close
= xml
.get_widget('close')
175 bt_quit
= xml
.get_widget('quit')
176 bt_file
= xml
.get_widget('ChooseFile')
177 bt_mrl
= xml
.get_widget('AddMRL')
178 bt_next
= xml
.get_widget('next')
179 bt_prev
= xml
.get_widget('prev')
180 bt_stop
= xml
.get_widget('stop')
181 bt_toggle
= xml
.get_widget('toggle')
182 l_item
= xml
.get_widget('item')
183 e_mrl
= xml
.get_widget('mrl')
184 window
= xml
.get_widget('window1')
185 img_bt_toggle
=xml
.get_widget('image6')
186 exp
= xml
.get_widget('expander2')
187 expvbox
= xml
.get_widget('expandvbox')
188 vlcicon
= xml
.get_widget('eventicon')
189 vol
= xml
.get_widget('vol')
190 time_s
= xml
.get_widget('time_s')
191 time_l
= xml
.get_widget('time_l')
193 window
.connect('delete_event', delete_event
)
194 window
.connect('destroy', destroy
)
195 window
.connect('key_release_event', key_release
)
197 tray
= gtk
.status_icon_new_from_icon_name("vlc")
198 tray
.connect('activate', tray_button
)
200 def icon_clicked(widget
, event
):
203 bt_close
.connect('clicked', destroy
)
204 bt_quit
.connect('clicked', Quit
)
205 bt_mrl
.connect('clicked', AddTrack
)
206 bt_toggle
.connect('clicked', Pause
)
207 bt_next
.connect('clicked', Next
)
208 bt_prev
.connect('clicked', Prev
)
209 bt_stop
.connect('clicked', Stop
)
210 exp
.connect('activate', expander
)
211 vol
.connect('change-value', volchange
)
212 vol
.connect('scroll-event', volchange
)
213 time_s
.connect('adjust-bounds', timechange
)
214 vlcicon
.set_events(gtk
.gdk
.BUTTON_PRESS_MASK
)
215 vlcicon
.connect('button_press_event', icon_clicked
)
216 time_s
.set_update_policy(gtk
.UPDATE_DISCONTINUOUS
)
217 gobject
.timeout_add( 2000, timeset
)
219 library
= "/media/mp3"
223 bt_file
.set_current_folder(library
)
225 print "edit this file to point to your media library"
227 window
.set_icon_name('vlc')
228 window
.set_title("VLC - D-Bus ctrl")
236 icon_theme
= gtk
.icon_theme_get_default()
238 pix
= icon_theme
.load_icon("vlc",24,0)
242 position
= window
.get_position()
243 vol
.set_value(player
.VolumeGet())