Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  mpris.py   Sprache: Python

 

#!/usr/bin/env python
# -*- coding: utf8 -*-
#
# Copyright © 2006-2011 Rafaël Carré <funman at videolanorg>
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
#

#
# NOTE: This controller is a SAMPLE, and thus doesn't use all the
# Media Player Remote Interface Specification (MPRIS for short) capabilities
#
# MPRIS: http://www.mpris.org/2.1/spec/
#
# You'll need pygtk >= 2.12
#
# TODO
#   Ability to choose the Media Player if several are connected to the bus

# core dbus stuff
import dbus
import dbus.glib

# core interface stuff
import gtk

# timer
from gobject import timeout_add

# file loading
import os

global win_position # store the window position on the screen

global playing
playing = False

global shuffle

global root
global player
global tracklist
global props

global bus          # Connection to the session bus

mpris='org.mpris.MediaPlayer2'

# If a Media Player connects to the bus, we'll use it
# Note that we forget the previous Media Player we were connected to
def NameOwnerChanged(name, new, old):
    if old != '' and mpris in name:
        Connect(name)

def PropGet(prop):
    global props
    return props.Get(mpris + '.Player', prop)

def PropSet(prop, val):
    global props
    props.Set(mpris + '.Player', prop, val)

# Callback for when 'TrackChange' signal is emitted
def TrackChange(Track):
    try:
        a = Track['xesam:artist']
    except:
        a = ''
    try:
        t = Track['xesam:title']
    except:
        t = Track['xesam:url']
    try:
        length = Track['mpris:length']
    except:
        length = 0
    if length > 0:
        time_s.set_range(0, length)
        time_s.set_sensitive(True)
    else:
        # disable the position scale if length isn't available
        time_s.set_sensitive(False)
    # update the labels
    l_artist.set_text(a)
    l_title.set_text(t)

# Connects to the Media Player we detected
def Connect(name):
    global root, player, tracklist, props
    global playing, shuffle

    root_o = bus.get_object(name, '/org/mpris/MediaPlayer2')
    root        = dbus.Interface(root_o, mpris)
    tracklist   = dbus.Interface(root_o, mpris + '.TrackList')
    player      = dbus.Interface(root_o, mpris + '.Player')
    props       = dbus.Interface(root_o, dbus.PROPERTIES_IFACE)

    # FIXME : doesn't exist anymore in mpris 2.1
    # connect to the TrackChange signal
    # root_o.connect_to_signal('TrackChange', TrackChange, dbus_interface=mpris)

    # determine if the Media Player is playing something
    if PropGet('PlaybackStatus') == 'Playing':
        playing = True
        TrackChange(PropGet('Metadata'))

    window.set_title(props.Get(mpris, 'Identity'))

#plays an element
def AddTrack(widget):
    mrl = e_mrl.get_text()
    if mrl != None and mrl != '':
        tracklist.AddTrack(mrl, '/', True)
        e_mrl.set_text('')
    else:
        mrl = bt_file.get_filename()
        if mrl != None and mrl != '':
            tracklist.AddTrack('directory://' + mrl, '/', True)
    update(0)

# basic control

def Next(widget):
    player.Next(reply_handler=(lambda *args: None), error_handler=(lambda *args: None))
    update(0)

def Prev(widget):
    player.Prev(reply_handler=(lambda *args: None), error_handler=(lambda *args: None))
    update(0)

def Stop(widget):
    player.Stop(reply_handler=(lambda *args: None), error_handler=(lambda *args: None))
    update(0)

def Quit(widget):
    global props
    if props.Get(mpris, 'CanQuit'):
        root.Quit(reply_handler=(lambda *args: None), error_handler=(lambda *args: None))
        l_title.set_text('')
        window.set_title('')

def Pause(widget):
    player.PlayPause()
    if PropGet('PlaybackStatus') == 'Playing':
        icon = gtk.STOCK_MEDIA_PAUSE
    else:
        icon = gtk.STOCK_MEDIA_PLAY
    img_bt_toggle.set_from_stock(icon, gtk.ICON_SIZE_SMALL_TOOLBAR)
    update(0)

def Shuffle(widget):
    global shuffle
    shuffle = not shuffle
    PropSet('Shuffle', shuffle)

# update status display
def update(widget):
    Track = PropGet('Metadata')
    vol.set_value(PropGet('Volume') * 100.0)
    TrackChange(Track)
    GetPlayStatus(0)

# callback for volume change
def volchange(widget):
    PropSet('Volume', vol.get_value_as_int() / 100.0)

# callback for position change
def timechange(widget, x=None, y=None):
    player.SetPosition(PropGet('Metadata')['mpris:trackid'],
                time_s.get_value(),
                reply_handler=(lambda *args: None),
                error_handler=(lambda *args: None))

# refresh position change
def timeset():
    global playing
    if playing == True:
        try:
            time_s.set_value(PropGet('Position'))
        except:
            playing = False
    return True

# toggle simple/full display
def expander(widget):
    if exp.get_expanded() == False:
        exp.set_label('Less')
    else:
        exp.set_label('More')

# close event : hide in the systray
def delete_event(self, widget):
    self.hide()
    return True

# shouldn't happen
def destroy(widget):
    gtk.main_quit()

# hide the controller when 'Esc' is pressed
def key_release(widget, event):
    if event.keyval == gtk.keysyms.Escape:
        global win_position
        win_position = window.get_position()
        widget.hide()

# callback for click on the tray icon
def tray_button(widget):
    global win_position
    if window.get_property('visible'):
        # store position
        win_position = window.get_position()
        window.hide()
    else:
        # restore position
        window.move(win_position[0], win_position[1])
        window.show()

# hack: update position, volume, and metadata
def icon_clicked(widget, event):
    update(0)

# get playing status, modify the Play/Pause button accordingly
def GetPlayStatus(widget):
    global playing
    global shuffle

    playing = PropGet('PlaybackStatus') == 'Playing'
    if playing:
        img_bt_toggle.set_from_stock('gtk-media-pause', gtk.ICON_SIZE_SMALL_TOOLBAR)
    else:
        img_bt_toggle.set_from_stock('gtk-media-play', gtk.ICON_SIZE_SMALL_TOOLBAR)
    shuffle = PropGet('Shuffle')
    bt_shuffle.set_active( shuffle )

# loads UI file from the directory where the script is,
# so we can use /path/to/mpris.py to execute it.
import sys
xml = gtk.Builder()
gtk.Builder.add_from_file(xml, os.path.join(os.path.dirname(sys.argv[0]) , 'mpris.xml'))

# ui setup
bt_close    = xml.get_object('close')
bt_quit     = xml.get_object('quit')
bt_file     = xml.get_object('ChooseFile')
bt_next     = xml.get_object('next')
bt_prev     = xml.get_object('prev')
bt_stop     = xml.get_object('stop')
bt_toggle   = xml.get_object('toggle')
bt_mrl      = xml.get_object('AddMRL')
bt_shuffle  = xml.get_object('shuffle')
l_artist    = xml.get_object('l_artist')
l_title     = xml.get_object('l_title')
e_mrl       = xml.get_object('mrl')
window      = xml.get_object('window1')
img_bt_toggle=xml.get_object('image6')
exp         = xml.get_object('expander2')
expvbox     = xml.get_object('expandvbox')
audioicon   = xml.get_object('eventicon')
vol         = xml.get_object('vol')
time_s      = xml.get_object('time_s')
time_l      = xml.get_object('time_l')

# connect to the different callbacks

window.connect('delete_event',  delete_event)
window.connect('destroy',       destroy)
window.connect('key_release_event', key_release)

tray = gtk.status_icon_new_from_icon_name('audio-x-generic')
tray.connect('activate', tray_button)

bt_close.connect('clicked',     destroy)
bt_quit.connect('clicked',      Quit)
bt_mrl.connect('clicked',       AddTrack)
bt_toggle.connect('clicked',    Pause)
bt_next.connect('clicked',      Next)
bt_prev.connect('clicked',      Prev)
bt_stop.connect('clicked',      Stop)
bt_shuffle.connect('clicked',   Shuffle)
exp.connect('activate',         expander)
vol.connect('changed',          volchange)
time_s.connect('adjust-bounds', timechange)
audioicon.set_events(gtk.gdk.BUTTON_PRESS_MASK) # hack for the bottom right icon
audioicon.connect('button_press_event', icon_clicked)
time_s.set_update_policy(gtk.UPDATE_DISCONTINUOUS)

library = '/media/mp3' # editme

# set the Directory chooser to a default location
try:
    os.chdir(library)
    bt_file.set_current_folder(library)
except:
    bt_file.set_current_folder(os.path.expanduser('~'))

# connect to the bus
bus = dbus.SessionBus()
dbus_names = bus.get_object( 'org.freedesktop.DBus', '/org/freedesktop/DBus' )
dbus_names.connect_to_signal('NameOwnerChanged', NameOwnerChanged, dbus_interface='org.freedesktop.DBus') # to detect new Media Players

dbus_o = bus.get_object('org.freedesktop.DBus', '/')
dbus_intf = dbus.Interface(dbus_o, 'org.freedesktop.DBus')

# connect to the first Media Player found
for n in dbus_intf.ListNames():
    if mpris in n:
        Connect(n)
        vol.set_value(PropGet('Volume') * 100.0)
        update(0)
        break

# run a timer to update position
timeout_add( 1000, timeset)

window.set_icon_name('audio-x-generic')
window.show()

window.set_icon(gtk.icon_theme_get_default().load_icon('audio-x-generic',24,0))
win_position = window.get_position()

gtk.main() # execute the main loop

Messung
CHZG
839610093

¤ Dauer der Verarbeitung: 0.4 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover


Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=1104848
#Domains=416959