Package flumotion :: Package worker :: Package checks :: Module audio
[hide private]

Source Code for Module flumotion.worker.checks.audio

  1  # -*- Mode: Python -*- 
  2  # vi:si:et:sw=4:sts=4:ts=4 
  3  # 
  4  # Flumotion - a streaming media server 
  5  # Copyright (C) 2004,2005,2006,2007 Fluendo, S.L. (www.fluendo.com). 
  6  # All rights reserved. 
  7   
  8  # This file may be distributed and/or modified under the terms of 
  9  # the GNU General Public License version 2 as published by 
 10  # the Free Software Foundation. 
 11  # This file is distributed without any warranty; without even the implied 
 12  # warranty of merchantability or fitness for a particular purpose. 
 13  # See "LICENSE.GPL" in the source distribution for more information. 
 14   
 15  # Licensees having purchased or holding a valid Flumotion Advanced 
 16  # Streaming Server license may use this file in accordance with the 
 17  # Flumotion Advanced Streaming Server Commercial License Agreement. 
 18  # See "LICENSE.Flumotion" in the source distribution for more information. 
 19   
 20  # Headers in this file shall remain intact. 
 21   
 22  __version__ = "$Rev: 8057 $" 
 23   
 24  import gst 
 25  import dbus 
 26   
 27  from flumotion.common import messages, log, errors, gstreamer 
 28  from flumotion.common.i18n import N_, gettexter 
 29  from flumotion.worker.checks import check 
 30  from twisted.internet import defer 
 31   
 32  from gst010 import do_element_check 
 33   
 34  T_ = gettexter() 
 35   
 36   
37 -def getAudioDevices(source_factory, mid=None):
38 """ 39 Search the available devices in worker for the specified factory. 40 Return a deferred firing a result. 41 42 The result is either: 43 - succesful, with an empty list: no device found 44 - succesful, with the list of found devices 45 - failed 46 47 @rtype: L{twisted.internet.defer.Deferred} 48 """ 49 result = messages.Result() 50 devices = [] 51 52 def getOssDevices(): 53 bus = dbus.SystemBus() 54 hal = dbus.Interface(bus.get_object('org.freedesktop.Hal', 55 '/org/freedesktop/Hal/Manager'), 56 'org.freedesktop.Hal.Manager') 57 udis = hal.FindDeviceStringMatch('oss.type', 'pcm') 58 59 for udi in udis: 60 dev = dbus.Interface(bus.get_object('org.freedesktop.Hal', udi), 61 'org.freedesktop.Hal.Device') 62 if not dev.PropertyExists('oss.device'): 63 continue 64 if dev.GetProperty('oss.device') != 0: 65 continue 66 67 devices.append((str(dev.GetProperty('info.product')), 68 str(dev.GetProperty('oss.device_file'))))
69 70 def getAlsaDevices(): 71 source = gst.element_factory_make('alsasrc') 72 pipeline = 'alsasrc name=source device=%s ! fakesink' 73 74 for device in source.probe_get_values_name('device'): 75 p = gst.parse_launch(pipeline % device) 76 p.set_state(gst.STATE_READY) 77 s = p.get_by_name('source') 78 devices.append((s.get_property('device-name'), 79 device.split(',')[0])) 80 p.set_state(gst.STATE_NULL) 81 82 try: 83 {'alsasrc': getAlsaDevices, 84 'osssrc': getOssDevices}[source_factory]() 85 86 except dbus.DBusException, e: 87 devices = [("/dev/dsp", "/dev/dsp"), 88 ("/dev/dsp1", "/dev/dsp1"), 89 ("/dev/dsp2", "/dev/dsp2")] 90 91 result.succeed(devices) 92 93 failure = defer.failure.Failure() 94 m = messages.Warning(T_( 95 N_("There has been an error while fetching the OSS audio devices " 96 "through Hal.\nThe listed devices have been guessed and may " 97 "not work properly.")), debug=check.debugFailure(failure)) 98 m.id = mid 99 result.add(m) 100 return defer.succeed(result) 101 except: 102 failure = defer.failure.Failure() 103 log.debug('check', 'unhandled failure: %r (%s)\nTraceback:\n%s' % ( 104 failure, failure.getErrorMessage(), failure.getTraceback())) 105 m = messages.Error(T_(N_("Could not probe devices.")), 106 debug=check.debugFailure(failure)) 107 108 m.id = mid 109 result.add(m) 110 return defer.fail(result) 111 else: 112 result.succeed(devices) 113 if not devices: 114 m = messages.Error(T_( 115 N_("Could not find any device in the system.\n" 116 "Please check whether the device is correctly plugged " 117 "in and whether the modules are correctly loaded."), 118 sound_system)) 119 120 m.id = mid 121 result.add(m) 122 123 return defer.succeed(result) 124 125
126 -def checkMixerTracks(source_factory, device, mid=None):
127 """ 128 Probe the given GStreamer element factory with the given device for 129 audio mixer tracks. 130 Return a deferred firing a result. 131 132 The result is either: 133 - succesful, with a None value: no device found 134 - succesful, with a human-readable device name and a list of mixer 135 track labels. 136 - failed 137 138 @rtype: L{twisted.internet.defer.Deferred} 139 """ 140 result = messages.Result() 141 142 def get_tracks(element): 143 # Only mixers have list_tracks. Why is this a perm error? FIXME in 0.9? 144 if not element.implements_interface(gst.interfaces.Mixer): 145 msg = 'Cannot get mixer tracks from the device. '\ 146 'Check permissions on the mixer device.' 147 log.debug('checks', "returning failure: %s" % msg) 148 raise check.CheckProcError(msg) 149 150 devName = element.get_property('device-name') 151 tracks = [track.label for track in element.list_tracks()] 152 structs = [] 153 for structure in element.get_pad('src').get_caps(): 154 structDict = dict(structure) 155 for key, value in structDict.items()[:]: 156 # Filter items which are not serializable over pb 157 if isinstance(value, gst.IntRange): 158 structDict[key] = (value.high, value.low) 159 structs.append(structDict) 160 return (devName, tracks, structs)
161 162 def errbackAlsaBugResult(failure, result, mid, device): 163 # alsasrc in gst-plugins-base <= 0.10.14 was accidentally reporting 164 # GST_RESOURCE_ERROR_WRITE when it could not be opened for reading. 165 if not failure.check(errors.GStreamerGstError): 166 return failure 167 if source_factory != 'alsasrc': 168 return failure 169 version = gstreamer.get_plugin_version('alsasrc') 170 if version > (0, 10, 14): 171 return failure 172 173 source, gerror, debug = failure.value.args 174 log.debug('check', 175 'GStreamer GError: %s (domain %s, code %d, debug %s)' % ( 176 gerror.message, gerror.domain, gerror.code, debug)) 177 178 if gerror.domain == "gst-resource-error-quark": 179 if gerror.code == int(gst.RESOURCE_ERROR_OPEN_WRITE): 180 m = messages.Error(T_( 181 N_("Could not open device '%s' for reading. " 182 "Check permissions on the device."), device)) 183 result.add(m) 184 return result 185 186 return failure 187 188 pipeline = ('%s name=source device=%s ! fakesink') % ( 189 source_factory, device) 190 d = do_element_check(pipeline, 'source', get_tracks, 191 set_state_deferred=True) 192 193 pipeline = ('%s name=source device=%s ! fakesink') % ( 194 source_factory, device) 195 d = do_element_check(pipeline, 'source', get_tracks, 196 set_state_deferred=True) 197 198 d.addCallback(check.callbackResult, result) 199 d.addErrback(check.errbackNotFoundResult, result, mid, device) 200 d.addErrback(errbackAlsaBugResult, result, mid, device) 201 d.addErrback(check.errbackResult, result, mid, device) 202 203 return d 204