Ticket #1984: sound.5.diff

File sound.5.diff, 11.0 kB (added by ressu@…, 2 years ago)

Updated gstreamer patch (again ;) This time with ACE support.

  • (a) /dev/null vs. (b) src/common/sound.py

    === added file 'src/common/sound.py'
    a b  
     1##      common/gst.py 
     2## 
     3## Contributors for this file: 
     4##      - Sami Haahtinen <ressu@ressukka.net> 
     5## 
     6## Copyright (C) 2006 Sami Haahtinen <ressu@ressukka.net> 
     7## 
     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 
     10## by the Free Software Foundation; version 2 only. 
     11## 
     12## This program is distributed in the hope that it will be useful, 
     13## but WITHOUT ANY WARRANTY; without even the implied warranty of 
     14## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
     15## GNU General Public License for more details. 
     16 
     17import gajim 
     18import os 
     19 
     20class GajimPlayer: 
     21  player = None 
     22 
     23  def __init__(self): 
     24    # For now, lets default to GStreamer, winsound, and then try External player 
     25    # FIXME: This really needs elegance! 
     26    if not gajim.config.get('sounds_on'): 
     27      raise NoSound 
     28       
     29    try: 
     30      if not gajim.config.get('use_gstreamer'): 
     31        raise self.PlayerUnavailable 
     32      self.player = GajimGstPlayer() 
     33    except self.PlayerUnavailable: 
     34      try: 
     35        self.player = GajimWin32Player() 
     36      except self.PlayerUnavailable: 
     37        try: 
     38          self.player = GajimExtPlayer() 
     39        except self.PlayerUnavailable: 
     40          self.player = None # Make sure that player is still set to None 
     41          raise NoSound 
     42 
     43  class NoSound(Exception): 
     44    '''Notifies the system that we should be silent''' 
     45 
     46  class BeepOnly(Exception): 
     47    '''Notifies the system that we should just beep''' 
     48   
     49  class PlayerUnavailable(Exception): 
     50    '''Notifies that the player is unavailable''' 
     51 
     52  def event_to_soundfile(self, event): 
     53    '''Returns the full file path for sound file of an event''' 
     54    # Check if we should play sound at all 
     55    if self.player is None: 
     56      raise NoSound 
     57 
     58    # Get soundevent 
     59    path_to_soundfile = gajim.config.get_per('soundevents', event, 'path') 
     60     
     61    if path_to_soundfile is None or not os.path.exists(path_to_soundfile): 
     62      raise NoSound 
     63 
     64    return path_to_soundfile 
     65 
     66  def play(self, soundfile): 
     67    if soundfile == 'beep': 
     68      beep() 
     69     
     70    if self.player is None: 
     71      return 
     72     
     73    self.player.play_sound(soundfile) 
     74 
     75  def beep(self): 
     76    '''Play a single beep''' 
     77    # FIXME: There must be a better way 
     78    print "\a" 
     79 
     80# FIXME: This class hasn't gotten any testing! 
     81class GajimWin32Player: 
     82  '''User native Win32 layer to play sounds''' 
     83 
     84  def __init__(self): 
     85    try: 
     86      import winsound 
     87    except ImportError: 
     88      # gst module is not available... 
     89      raise GajimPlayer.PlayerUnavailable, "Winsound library not available" 
     90   
     91  def play_sound(self,soundfile): 
     92    try: 
     93      winsound.PlaySound(soundfile, winsound.SND_FILENAME|winsound.SND_ASYNC) 
     94    except: 
     95      pass 
     96 
     97class GajimExtPlayer: 
     98  '''Use external application to play the sounds''' 
     99 
     100  def __init__(self): 
     101    self.player = gajim.config.get('soundplayer') 
     102    if self.player == '': 
     103      raise GajimPlayer.PlayerUnavailable, "External player not set" 
     104    # FIXME: We should check if the player exists! 
     105 
     106  def play_sound(self,soundfile): 
     107    soundfile = soundfile.replace('"', '\\"') 
     108    command = self.player + ' "' + soundfile + '" &' 
     109    os.system(command) 
     110 
     111class GajimGstPlayer: 
     112  '''Player that plays sound events through the GStreamer framework''' 
     113 
     114  def __init__(self): 
     115    try: 
     116      import gst 
     117    except ImportError: 
     118      # gst module is not available... 
     119      raise GajimPlayer.PlayerUnavailable, "Python Gstreamer modules not available" 
     120    self.gst = gst 
     121    self.GstBin = self.gst.parse_launch("playbin") 
     122 
     123    # Create a sink for video, if someone decides to use a video file ;) 
     124    fakesink = self.gst.element_factory_make("fakesink") 
     125    self.GstBin.set_property("video-sink", fakesink) 
     126 
     127    # Attach a message handler to the pipeline 
     128    bus = self.GstBin.get_bus() 
     129    bus.add_signal_watch() 
     130    bus.connect('message', self.gstevent) 
     131 
     132  def play_sound(self,soundfile): 
     133    self.GstBin.set_state(self.gst.STATE_NULL) 
     134 
     135    # since playbin takes input in URI format, add file:// prefix 
     136    sounduri = "file://" + os.path.abspath(soundfile) 
     137    self.GstBin.set_property('uri', sounduri) 
     138     
     139    self.GstBin.set_state(self.gst.STATE_PLAYING) 
     140 
     141  def gstevent(self, bus, message): 
     142    t = message.type 
     143    if t == self.gst.MESSAGE_EOS: 
     144      self.reset_player() 
     145 
     146  def reset_player(self): 
     147    '''Simply Reset the player''' 
     148    self.GstBin.set_state(self.gst.STATE_NULL) 
     149 
     150def play_event(event): 
     151  global Player 
     152  try: 
     153    try: 
     154       soundfile = Player.event_to_soundfile(event) 
     155    except NameError: 
     156       Player = GajimPlayer() 
     157       soundfile = Player.event_to_soundfile(event) 
     158  except GajimPlayer.NoSound: 
     159    # No sound. 
     160    return 
     161 
     162  # Ok, we should be clear to play the sound 
     163  Player.play(soundfile) 
  • src/common/config.py

    === modified file 'src/common/config.py'
     
    202202                'chat_merge_consecutive_nickname': [opt_bool, False, _('Merge consecutive nickname in chat window')], 
    203203                'chat_merge_consecutive_nickname_indent': [opt_str, '  ', _('Indentation when using merge consecutive nickame')], 
    204204                'gc_nicknames_colors': [ opt_str, '#a34526:#c000ff:#0012ff:#388a99:#38995d:#519938:#ff8a00:#94452d:#244b5a:#32645a', _('List of colors that will be used to color nicknames in groupchats'), True ], 
     205                'use_gstreamer': [opt_bool, False, _('Try to use gstreamer as the sound system'), True], 
    205206        } 
    206207 
    207208        __options_per_key = { 
  • src/common/helpers.py

    === modified file 'src/common/helpers.py'
     
    3030from xmpp_stringprep import nodeprep, resourceprep, nameprep 
    3131 
    3232try: 
    33         import winsound # windows-only built-in module for playing wav 
    3433        import win32api 
    3534        import win32con 
    3635except: 
     
    414413                except: 
    415414                        pass 
    416415 
    417 def play_sound(event): 
    418         if not gajim.config.get('sounds_on'): 
    419                 return 
    420         path_to_soundfile = gajim.config.get_per('soundevents', event, 'path') 
    421         if path_to_soundfile == 'beep': 
    422                 print '\a' # make a speaker beep 
    423                 return 
    424         if path_to_soundfile is None or not os.path.exists(path_to_soundfile): 
    425                 return 
    426         if os.name == 'nt': 
    427                 try: 
    428                         winsound.PlaySound(path_to_soundfile, 
    429                                 winsound.SND_FILENAME|winsound.SND_ASYNC) 
    430                 except: 
    431                         pass 
    432         elif os.name == 'posix': 
    433                 if gajim.config.get('soundplayer') == '': 
    434                         return 
    435                 player = gajim.config.get('soundplayer') 
    436                 # we add the path in "" so we have good parsing from shell 
    437                 path_to_soundfile = path_to_soundfile.replace('"', '\\"') # escape " 
    438                 command = player + ' "' + path_to_soundfile + '" &' 
    439                 #FIXME: when we require 2.4+ use subprocess module 
    440                 os.system(command) 
    441  
    442416def get_file_path_from_dnd_dropped_uri(uri): 
    443417        path = urllib.url2pathname(uri) # escape special chars 
    444418        path = path.strip('\r\n\x00') # remove \r\n and NULL 
  • src/config.py

    === modified file 'src/config.py'
     
    3737from common import helpers 
    3838from common import gajim 
    3939from common import connection 
     40from common import sound 
    4041 
    4142#---------- PreferencesWindow class -------------# 
    4243class PreferencesWindow: 
     
    978979                if not iter: 
    979980                        return 
    980981                snd_event_config_name = model[iter][3] 
    981                 helpers.play_sound(snd_event_config_name) 
     982                sound.play_event(snd_event_config_name) 
    982983 
    983984        def on_open_advanced_editor_button_clicked(self, widget, data = None): 
    984985                if gajim.interface.instances.has_key('advanced_config'): 
  • src/gajim.py

    === modified file 'src/gajim.py'
     
    4040from chat_control import ChatControlBase 
    4141 
    4242from common import exceptions 
     43from common import sound 
    4344 
    4445try: 
    4546        import gtk 
     
    617618                msg = array[1] 
    618619                # do not play sound when standalone chatstate message (eg no msg) 
    619620                if msg and gajim.config.get_per('soundevents', 'message_sent', 'enabled'): 
    620                         helpers.play_sound('message_sent') 
     621                        sound.play_event('message_sent') 
    621622                 
    622623        def handle_event_subscribe(self, account, array): 
    623624                #('SUBSCRIBE', account, (jid, text, user_nick)) user_nick is JEP-0172 
  • src/groupchat_control.py

    === modified file 'src/groupchat_control.py'
     
    3535 
    3636from common import gajim 
    3737from common import helpers 
     38from common import sound 
    3839 
    3940from chat_control import ChatControl 
    4041from chat_control import ChatControlBase 
     
    530531 
    531532                if kind == 'incoming': # it's a message NOT from us 
    532533                        # highlighting and sounds 
    533                         (highlight, sound) = self.highlighting_for_message(text, tim) 
     534                        (highlight, sound_event) = self.highlighting_for_message(text, tim) 
    534535                        gc_class=self.__class__ 
    535536                        if gc_class.gc_custom_colors.has_key(contact): 
    536537                                other_tags_for_name.append('gc_nickname_color_' + \ 
     
    548549                                self.parent_win.redraw_tab(self, 'attention') 
    549550                                other_tags_for_name.append('bold') 
    550551                                other_tags_for_text.append('marked') 
    551                         if sound == 'received': 
    552                                 helpers.play_sound('muc_message_received') 
    553                         elif sound == 'highlight': 
    554                                 helpers.play_sound('muc_message_highlight') 
     552                        if sound_event == 'received': 
     553                                sound.play_event('muc_message_received') 
     554                        elif sound_event == 'highlight': 
     555                                sound.play_event('muc_message_highlight') 
    555556 
    556557                        self.check_and_possibly_add_focus_out_line() 
    557558 
     
    561562        def highlighting_for_message(self, text, tim): 
    562563                '''Returns a 2-Tuple. The first says whether or not to highlight the 
    563564                text, the second, what sound to play.''' 
    564                 highlight, sound = (None, None) 
     565                highlight, sound_event = (None, None) 
    565566 
    566567                # Do we play a sound on every muc message? 
    567568                if gajim.config.get_per('soundevents', 'muc_message_received', 'enabled'): 
    568569                        if gajim.config.get('notify_on_all_muc_messages'): 
    569                                 sound = 'received' 
     570                                sound_event = 'received' 
    570571 
    571572                # Are any of the defined highlighting words in the text? 
    572573                if self.needs_visual_notification(text): 
    573574                        highlight = True 
    574575                        if gajim.config.get_per('soundevents', 'muc_message_highlight', 
    575576                                                                        'enabled'): 
    576                                 sound = 'highlight' 
     577                                sound_event = 'highlight' 
    577578 
    578579                # Is it a history message? Don't want sound-floods when we join. 
    579580                if tim != time.localtime(): 
    580                         sound = None 
    581  
    582                 return (highlight, sound) 
     581                        sound_event = None 
     582 
     583                return (highlight, sound_event) 
    583584 
    584585        def check_and_possibly_add_focus_out_line(self): 
    585586                '''checks and possibly adds focus out line for room_jid if it needs it 
  • src/notify.py

    === modified file 'src/notify.py'
     
    2424 
    2525from common import gajim 
    2626from common import helpers 
     27from common import sound 
    2728 
    2829import dbus_support 
    2930if dbus_support.supported: 
     
    164165        if (do_sound): 
    165166                if (event == 'new_message'): 
    166167                        if first: 
    167                                  helpers.play_sound('first_message_received') 
     168                                 sound.play_event('first_message_received') 
    168169                        else: 
    169                                  helpers.play_sound('next_message_received') 
     170                                 sound.play_event('next_message_received') 
    170171                elif (event == 'contact_connected' or event == 'contact_disconnected'): 
    171                         helpers.play_sound(event)        
     172                        sound.play_event(event)  
    172173          
    173174 
    174175def popup(event_type, jid, account, msg_type = '', path_to_image = None,