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: 8341 $" 
 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 119 m.id = mid 120 result.add(m) 121 122 return defer.succeed(result) 123 124
125 -def checkMixerTracks(source_factory, device, mid=None):
126 """ 127 Probe the given GStreamer element factory with the given device for 128 audio mixer tracks. 129 Return a deferred firing a result. 130 131 The result is either: 132 - succesful, with a None value: no device found 133 - succesful, with a human-readable device name and a list of mixer 134 track labels. 135 - failed 136 137 @rtype: L{twisted.internet.defer.Deferred} 138 """ 139 result = messages.Result() 140 141 def get_tracks(element): 142 # Only mixers have list_tracks. Why is this a perm error? FIXME in 0.9? 143 if not element.implements_interface(gst.interfaces.Mixer): 144 msg = 'Cannot get mixer tracks from the device. '\ 145 'Check permissions on the mixer device.' 146 log.debug('checks', "returning failure: %s" % msg) 147 raise check.CheckProcError(msg) 148 149 devName = element.get_property('device-name') 150 tracks = [track.label for track in element.list_tracks()] 151 structs = [] 152 for structure in element.get_pad('src').get_caps(): 153 structDict = dict(structure) 154 for key, value in structDict.items()[:]: 155 # Filter items which are not serializable over pb 156 if isinstance(value, gst.IntRange): 157 structDict[key] = (value.high, value.low) 158 structs.append(structDict) 159 return (devName, tracks, structs)
160 161 def errbackAlsaBugResult(failure, result, mid, device): 162 # alsasrc in gst-plugins-base <= 0.10.14 was accidentally reporting 163 # GST_RESOURCE_ERROR_WRITE when it could not be opened for reading. 164 if not failure.check(errors.GStreamerGstError): 165 return failure 166 if source_factory != 'alsasrc': 167 return failure 168 version = gstreamer.get_plugin_version('alsasrc') 169 if version > (0, 10, 14): 170 return failure 171 172 source, gerror, debug = failure.value.args 173 log.debug('check', 174 'GStreamer GError: %s (domain %s, code %d, debug %s)' % ( 175 gerror.message, gerror.domain, gerror.code, debug)) 176 177 if gerror.domain == "gst-resource-error-quark": 178 if gerror.code == int(gst.RESOURCE_ERROR_OPEN_WRITE): 179 m = messages.Error(T_( 180 N_("Could not open device '%s' for reading. " 181 "Check permissions on the device."), device)) 182 result.add(m) 183 return result 184 185 return failure 186 187 pipeline = ('%s name=source device=%s ! fakesink') % ( 188 source_factory, device) 189 d = do_element_check(pipeline, 'source', get_tracks, 190 set_state_deferred=True) 191 192 d.addCallback(check.callbackResult, result) 193 d.addErrback(check.errbackNotFoundResult, result, mid, device) 194 d.addErrback(errbackAlsaBugResult, result, mid, device) 195 d.addErrback(check.errbackResult, result, mid, device) 196 197 return d 198