=== modified file 'data/ui/preferences/playback.ui' --- data/ui/preferences/playback.ui 2010-11-28 11:33:25 +0000 +++ data/ui/preferences/playback.ui 2011-10-09 22:48:26 +0000 @@ -196,6 +196,44 @@ + + False + + + True + 0 + 1 + Device: + + + 0 + + + + + True + model3 + 0 + + + + 1 + + + + + False + False + 1 + + + + + False + 6 + + + True 3 @@ -224,7 +262,7 @@ False - 6 + 7 @@ -261,6 +299,14 @@ + + + + + + + + === modified file 'xl/player/pipe.py' --- xl/player/pipe.py 2010-09-25 02:51:40 +0000 +++ xl/player/pipe.py 2011-10-10 00:51:12 +0000 @@ -307,30 +307,47 @@ "auto" : { "name" : _("Automatic"), "pipe" : "autoaudiosink", + "has_enum" : False }, "gconf" : { "name" : "GNOME", - "pipe" : "gconfaudiosink profile=music", + "pipe" : "gconfaudiosink", + "pipeargs" : "profile=music", + "has_enum" : False }, "alsa" : { "name" : "ALSA", "pipe" : "alsasink", + "has_enum" : True }, "oss" : { "name" : "OSS", "pipe" : "osssink", + "has_enum" : False }, "pulse" : { "name" : "PulseAudio", "pipe" : "pulsesink", + "has_enum" : True }, "jack" : { "name" : "JACK", "pipe" : "jackaudiosink", + "has_enum" : False } } def sink_from_preset(preset): + + device_name = '' + + if preset != 'auto': + dname = settings.get_option('player/audiosink_device') + if dname is not None and dname != '': + device_name = ' device=%s' % dname + + print 'Preset: %s Device name: %s' % (preset, device_name) + if preset == "custom": pipe = settings.get_option("player/custom_sink_pipe", "") if not pipe: @@ -342,8 +359,12 @@ if not d: logger.error("Could not find sink preset %s."%preset) return None - pipe = d['pipe'] + pipe = d['pipe'] + device_name name = d['name'] + + if 'pipeargs' in d: + name += ' ' + d['pipeargs'] + try: sink = AudioSink(name, pipe) return sink @@ -351,6 +372,43 @@ common.log_exception(log=logger, message="Could not enable audiosink %s."%preset) return None + +def sink_enumerate_devices(preset): + ''' + Enumerate all availables devices for a particular sink type + in [device, device-name] pairs. Returns None if no devices + can be enumerated for that preset type + ''' + + p = SINK_PRESETS[preset] + if not p['has_enum']: + return None + + # create a temporary sink, probe it + try: + tmpsink = gst.element_factory_make(p['pipe'],'tmp') + except: + # If we can't create an instance of the sink, probably doesn't exist... + return None + + tmpsink.probe_property_name('device') + devices = tmpsink.probe_get_values_name('device') + + if len(devices) == 0: + return None + + ret = [['','Auto']] + + for device in devices: + tmpsink.set_property('device', device) + devname = tmpsink.get_property('device-name') + if devname is None or devname == '': + devname = device + + ret.append([device,devname]) + + return ret + class AudioSink(gst.Bin): def __init__(self, name, pipeline): === modified file 'xlgui/preferences/playback.py' --- xlgui/preferences/playback.py 2010-07-04 16:17:48 +0000 +++ xlgui/preferences/playback.py 2011-10-10 00:58:07 +0000 @@ -29,6 +29,7 @@ from xlgui.preferences import widgets from xl import main, xdg +from xl.player import pipe from xl.nls import gettext as _ name = _('Playback') @@ -68,6 +69,61 @@ return True return False + +class SelectDeviceForSinkPreference(widgets.ComboPreference, widgets.Conditional): + default = '' + name = "player/audiosink_device" + condition_preference_name = 'player/audiosink' + + restart_required = True + + def __init__(self, preferences, widget): + widgets.ComboPreference.__init__(self, preferences, widget) + widgets.Conditional.__init__(self) + + def on_check_condition(self): + + iter = self.condition_widget.get_active_iter() + value = self.condition_widget.get_model().get_value(iter, 0) + + devices = pipe.sink_enumerate_devices(value) + if devices is not None: + + # disable because the clear() causes a settings write + self.is_enabled = False + + model = self.widget.get_model() + model.clear() + + for device in devices: + model.append(device) + + self.is_enabled = True + self._set_value() + return True + + self.is_enabled = False + return False + + def on_condition_met(self): + self.widget.get_parent().show() + + def on_condition_failed(self): + self.widget.get_parent().hide() + self.widget.get_model().clear() + + def _setup_changed(self): + self.widget.connect('changed', self._change) + + def _change(self, *args): + if self.is_enabled: + self.change(args) + + def _get_value(self): + if self.is_enabled: + return widgets.ComboPreference._get_value(self) + + return '' class ResumePreference(widgets.CheckPreference): default = True