Changeset 4832c1e5dd8d1b8a435fd410ae6afeb2ec26ca32

Show
Ignore:
Timestamp:
09/15/07 13:01:48 (1 year ago)
Author:
Rafaël Carré <funman@videolan.org>
git-committer:
Rafaël Carré <funman@videolan.org> 1189854108 +0000
git-parent:

[191a84f4c769601a6ea4a0134ea60a8a84d73fc2]

git-author:
Rafaël Carré <funman@videolan.org> 1189854108 +0000
Message:

Minor fixes, add comments

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • extras/mpris.py

    r41bb970 r4832c1e  
    22# -*- coding: utf8 -*- 
    33# 
    4 # Copyright (C) 2006 Rafaël Carré <funman at videolanorg> 
     4# Copyright © 2006-2007 Rafaël Carré <funman at videolanorg> 
    55# 
    66# $Id$ 
     
    2222 
    2323# 
    24 # NOTE: this controller is a SAMPLE, and thus doesn't implement all the 
    25 # Media Player Remote Interface Specification (MPRIS for short) available at 
    26 # http://wiki.xmms2.xmms.se/index.php/Media_Player_Interfaces 
     24# NOTE: This controller is a SAMPLE, and thus doesn't use all the 
     25# Media Player Remote Interface Specification (MPRIS for short) capabilities 
     26
     27# MPRIS:  http://wiki.xmms2.xmms.se/index.php/Media_Player_Interfaces 
    2728# 
    2829# You'll need pygtk >= 2.10 to use gtk.StatusIcon 
    2930# 
     31# TODO 
     32#   Ability to choose the Media Player if several are connected to the bus 
     33 
     34# core dbus stuff 
    3035import dbus 
    3136import dbus.glib 
     37 
     38# core interface stuff 
    3239import gtk 
    3340import gtk.glade 
     41 
     42# timer 
    3443import gobject 
     44 
     45# file loading 
    3546import os 
    3647 
    37 global positio
    38 global timer 
     48global win_position # store the window position on the scree
     49 
    3950global playing 
    4051playing = False 
    4152 
    42 global shuffle 
    43 global repeat 
    44 global loop 
    45 #mpris doesn't support getting the status of these (at the moment) 
     53global shuffle      # playlist will play randomly 
     54global repeat       # repeat the playlist 
     55global loop         # loop the current element 
     56 
     57# mpris doesn't support getting the status of these (at the moment) 
    4658shuffle = False 
    4759repeat = False 
    4860loop = False 
    4961 
    50 global root 
    51 global player 
    52 global tracklist 
    53  
    54 global bus 
    55  
    56 def player_change(newname, a, b): 
    57     if b != "" and "org.mpris." in newname: 
    58         Connect(newname) 
    59  
    60 def itemchange_handler(item): 
     62# these are defined on the mpris detected unique name 
     63global root         # / org.freedesktop.MediaPlayer 
     64global player       # /Player org.freedesktop.MediaPlayer 
     65global tracklist    # /Tracklist org.freedesktop.MediaPlayer 
     66 
     67global bus          # Connection to the session bus 
     68global identity     # MediaPlayer Identity 
     69 
     70 
     71# If a Media Player connects to the bus, we'll use it 
     72# Note that we forget the previous Media Player we were connected to 
     73def NameOwnerChanged(name, new, old): 
     74    if old != "" and "org.mpris." in name: 
     75        Connect(name) 
     76 
     77# Callback for when "TrackChange" signal is emitted 
     78def TrackChange(Track): 
     79    # the only mandatory metadata is "URI" 
    6180    try: 
    62         a = item["artist"] 
     81        a = Track["artist"] 
    6382    except: 
    6483        a = "" 
    6584    try: 
    66         t = item["title"] 
     85        t = Track["title"] 
    6786    except: 
    68         t = "" 
    69     if t == "": 
    70         t = item["URI"] 
     87        t = Track["URI"] 
     88    # update the labels 
    7189    l_artist.set_text(a) 
    7290    l_title.set_text(t) 
    7391 
    74 #find the first media player available 
     92# Connects to the Media Player we detected 
    7593def Connect(name): 
    76     global root 
    77     global player 
    78     global tracklist 
    79     global bus 
    80     global playing 
    81  
     94    global root, player, tracklist 
     95    global playing, identity 
     96 
     97    # first we connect to the objects 
    8298    root_o = bus.get_object(name, "/") 
    8399    player_o = bus.get_object(name, "/Player") 
    84100    tracklist_o = bus.get_object(name, "/TrackList") 
    85101 
     102    # there is only 1 interface per object 
    86103    root = dbus.Interface(root_o, "org.freedesktop.MediaPlayer") 
    87104    tracklist  = dbus.Interface(tracklist_o, "org.freedesktop.MediaPlayer") 
    88105    player = dbus.Interface(player_o, "org.freedesktop.MediaPlayer") 
    89     player_o.connect_to_signal("TrackChange", itemchange_handler, dbus_interface="org.freedesktop.MediaPlayer") 
     106 
     107    # connect to the TrackChange signal 
     108    player_o.connect_to_signal("TrackChange", TrackChange, dbus_interface="org.freedesktop.MediaPlayer") 
     109 
     110    # determine if the Media Player is playing something 
    90111    if player.GetStatus() == 0: 
    91112        playing = True 
    92     window.set_title(root.Identity()) 
     113 
     114    # gets its identity (name and version) 
     115    identity = root.Identity() 
     116    window.set_title(identity) 
    93117 
    94118#plays an element 
     
    104128    update(0) 
    105129 
    106 #basic control 
     130# basic control 
     131 
    107132def Next(widget): 
    108133    player.Next(reply_handler=(lambda *args: None), error_handler=(lambda *args: None)) 
     
    117142    update(0) 
    118143 
    119 #update status display 
     144def Quit(widget): 
     145    player.Quit(reply_handler=(lambda *args: None), error_handler=(lambda *args: None)) 
     146    l_title.set_text("") 
     147 
     148def Pause(widget): 
     149    player.Pause() 
     150    status = player.GetStatus() 
     151    if status == 0: 
     152        img_bt_toggle.set_from_stock(gtk.STOCK_MEDIA_PAUSE, gtk.ICON_SIZE_SMALL_TOOLBAR) 
     153    else: 
     154        img_bt_toggle.set_from_stock(gtk.STOCK_MEDIA_PLAY, gtk.ICON_SIZE_SMALL_TOOLBAR) 
     155    update(0) 
     156 
     157def Repeat(widget): 
     158    global repeat 
     159    repeat = not repeat 
     160    player.Repeat(repeat) 
     161 
     162def Shuffle(widget): 
     163    global shuffle 
     164    shuffle = not shuffle 
     165    tracklist.Random(shuffle) 
     166 
     167def Loop(widget): 
     168    global loop 
     169    loop = not loop 
     170    tracklist.Loop(loop) 
     171 
     172# update status display 
    120173def update(widget): 
    121174    item = tracklist.GetMetadata(tracklist.GetCurrentTrack()) 
     
    136189    GetPlayStatus(0) 
    137190 
    138 #get playing status from remote player 
     191# callback for volume change 
     192def volchange(widget, data): 
     193    player.VolumeSet(vol.get_value_as_int(), reply_handler=(lambda *args: None), error_handler=(lambda *args: None)) 
     194 
     195# callback for position change 
     196def timechange(widget, x=None, y=None): 
     197    player.PositionSet(int(time_s.get_value()), reply_handler=(lambda *args: None), error_handler=(lambda *args: None)) 
     198 
     199# refresh position change 
     200def timeset(): 
     201    global playing 
     202    if playing == True: 
     203        time_s.set_value(player.PositionGet()) 
     204    return True 
     205 
     206# toggle simple/full display 
     207def expander(widget): 
     208    if exp.get_expanded() == False: 
     209        exp.set_label("Less") 
     210    else: 
     211        exp.set_label("More") 
     212 
     213# close event : hide in the systray 
     214def delete_event(self, widget): 
     215    self.hide() 
     216    return True 
     217 
     218# shouldn't happen 
     219def destroy(widget): 
     220    gtk.main_quit() 
     221 
     222# hide the controller when 'Esc' is pressed 
     223def key_release(widget, event): 
     224    if event.keyval == gtk.keysyms.Escape: 
     225        global win_position 
     226        win_position = window.get_position() 
     227        widget.hide() 
     228 
     229# callback for click on the tray icon 
     230def tray_button(widget): 
     231    global win_position 
     232    if window.get_property('visible'): 
     233        # store position 
     234        win_position = window.get_position() 
     235        window.hide() 
     236    else: 
     237        # restore position 
     238        window.move(win_position[0], win_position[1]) 
     239        window.show() 
     240 
     241# hack: update position, volume, and metadata 
     242def icon_clicked(widget, event): 
     243    update(0) 
     244 
     245# get playing status, modify the Play/Pause button accordingly 
    139246def GetPlayStatus(widget): 
    140247    global playing 
     
    147254        playing = False 
    148255 
    149 def Quit(widget): 
    150     player.Quit(reply_handler=(lambda *args: None), error_handler=(lambda *args: None)) 
    151     l_title.set_text("") 
    152  
    153 def Pause(widget): 
    154     player.Pause() 
    155     status = player.GetStatus() 
    156     if status == 0: 
    157         img_bt_toggle.set_from_stock(gtk.STOCK_MEDIA_PAUSE, gtk.ICON_SIZE_SMALL_TOOLBAR) 
    158     else: 
    159         img_bt_toggle.set_from_stock(gtk.STOCK_MEDIA_PLAY, gtk.ICON_SIZE_SMALL_TOOLBAR) 
    160     update(0) 
    161  
    162 def Repeat(widget): 
    163     global repeat 
    164     repeat = not repeat 
    165     player.Repeat(repeat) 
    166  
    167 def Shuffle(widget): 
    168     global shuffle 
    169     shuffle = not shuffle 
    170     tracklist.Random(shuffle) 
    171  
    172 def Loop(widget): 
    173     global loop 
    174     loop = not loop 
    175     tracklist.Loop(loop) 
    176  
    177 #callback for volume 
    178 def volchange(widget, data): 
    179     player.VolumeSet(vol.get_value_as_int(), reply_handler=(lambda *args: None), error_handler=(lambda *args: None)) 
    180  
    181 #callback for position change 
    182 def timechange(widget, x=None, y=None): 
    183     player.PositionSet(int(time_s.get_value()), reply_handler=(lambda *args: None), error_handler=(lambda *args: None)) 
    184  
    185 #refresh position 
    186 def timeset(): 
    187     global playing 
    188     if playing == True: 
    189         time_s.set_value(player.PositionGet()) 
    190     return True 
    191  
    192 #simple/full display 
    193 def expander(widget): 
    194     if exp.get_expanded() == False: 
    195         exp.set_label("Less") 
    196     else: 
    197         exp.set_label("More") 
    198  
    199 #close event 
    200 def delete_event(self, widget): 
    201     self.hide() 
    202     return True 
    203  
    204 def destroy(widget): 
    205     gtk.main_quit() 
    206  
    207 def key_release(widget, event): 
    208     global position 
    209     if event.keyval == gtk.keysyms.Escape: 
    210         position = window.get_position() 
    211         widget.hide() 
    212  
    213 #click on the tray icon 
    214 def tray_button(widget): 
    215     global position 
    216     if window.get_property('visible'): 
    217         position = window.get_position() 
    218         window.hide() 
    219     else: 
    220         window.move(position[0], position[1]) 
    221         window.show() 
    222  
    223 #loads glade file from the directory where the script is, 
    224 #so we can use /path/to/mpris.py to execute it. 
     256# loads glade file from the directory where the script is, 
     257# so we can use /path/to/mpris.py to execute it. 
    225258import sys 
    226259xml = gtk.glade.XML(os.path.dirname(sys.argv[0]) + '/mpris.glade') 
    227260 
    228 #ui setup 
     261# ui setup 
    229262bt_close    = xml.get_widget('close') 
    230263bt_quit     = xml.get_widget('quit') 
     
    250283time_l      = xml.get_widget('time_l') 
    251284 
     285# connect to the different callbacks 
     286 
    252287window.connect('delete_event',  delete_event) 
    253288window.connect('destroy',       destroy) 
     
    256291tray = gtk.status_icon_new_from_icon_name("audio-x-generic") 
    257292tray.connect('activate', tray_button) 
    258  
    259 def icon_clicked(widget, event): 
    260     update(0) 
    261293 
    262294bt_close.connect('clicked',     destroy) 
     
    274306vol.connect('scroll-event',     volchange) 
    275307time_s.connect('adjust-bounds', timechange) 
    276 audioicon.set_events(gtk.gdk.BUTTON_PRESS_MASK)  
     308audioicon.set_events(gtk.gdk.BUTTON_PRESS_MASK) # hack for the bottom right icon 
    277309audioicon.connect('button_press_event', icon_clicked)  
    278310time_s.set_update_policy(gtk.UPDATE_DISCONTINUOUS) 
    279311 
    280 library = "/media/mp3" #editme 
    281  
     312library = "/media/mp3" # editme 
     313 
     314# set the Directory chooser to a default location 
    282315try: 
    283316    os.chdir(library) 
     
    286319    bt_file.set_current_folder(os.path.expanduser("~")) 
    287320 
    288 #connect to the bus 
     321# connect to the bus 
    289322bus = dbus.SessionBus() 
    290323dbus_names = bus.get_object( "org.freedesktop.DBus", "/org/freedesktop/DBus" ) 
    291 dbus_names.connect_to_signal("NameOwnerChanged", player_change, dbus_interface="org.freedesktop.DBus") 
     324dbus_names.connect_to_signal("NameOwnerChanged", NameOwnerChanged, dbus_interface="org.freedesktop.DBus") # to detect new Media Players 
    292325 
    293326dbus_o = bus.get_object("org.freedesktop.DBus", "/") 
    294327dbus_intf = dbus.Interface(dbus_o, "org.freedesktop.DBus") 
    295328name_list = dbus_intf.ListNames() 
    296 name = "" 
     329 
     330# connect to the first Media Player found 
    297331for n in name_list: 
    298332    if "org.mpris." in n: 
    299         name = n 
     333        Connect(n) 
     334        window.set_title(identity) 
     335        vol.set_value(player.VolumeGet()) 
     336        update(0) 
    300337        break 
    301338 
    302 if name != "": 
    303     Connect(name) 
    304     window.set_title(root.Identity()) 
    305     vol.set_value(player.VolumeGet()) 
    306  
    307 #runs timer to update position 
     339# run a timer to update position 
    308340gobject.timeout_add( 1000, timeset) 
    309341 
    310342window.set_icon_name('audio-x-generic') 
    311343window.show() 
    312  
    313 try: 
    314     update(0) 
    315 except: 
    316     True 
    317344 
    318345icon_theme = gtk.icon_theme_get_default() 
     
    322349except: 
    323350    True 
    324 position = window.get_position() 
    325  
    326 gtk.main() 
     351 
     352win_position = window.get_position() 
     353 
     354gtk.main() # execute the main loop