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