我正在尝试让PyObjC应用程序在用户单击按钮时录制音频。我正在尝试使用AVAuidioRecorder类。我的代码是:
@IBAction
def startRecording_(self, sender):
audioPath = '~/Desktop/recordTest.mp3'
audioPathStr = NSString.stringByExpandingTildeInPath(audioPath)
audioURL = NSURL.fileURLWithPath_(audioPathStr)
audioSettings = {'AVFormatIDKey': 'kAudioFormatAppleIMA4', 'AVSampleRateKey': 1600.0, 'AVNumberOfChannelsKey': 1 }
audioDict = NSDictionary.dictionaryWithDictionary_(audioSettings)
(recorder, error) = AVAudioRecorder.alloc().initWithURL_settings_error_(audioURL, audioDict, objc.nil)
recorder.record()
当我运行上面的代码时,我收到以下错误:
<type 'exceptions.TypeError'>: 'NoneType' object is not iterable
似乎initWithURL_settings_error_
方法期望可迭代对象作为其第三个参数。但是,我想当我使用调用错误参数的PyObjC方法时,我可以将objc.nil
或None
传递给该参数。
当我在NSString方法上使用类似语法时:
(names, error) = NSString.stringWithContentsOfFile_encoding_error_(u"/usr/share/dict/propernames", NSASCIIStringEncoding, objc.nil)
代码运行。
为什么我对AVAudioRecord方法的调用不起作用?是因为当NSString方法调用错误时,该方法需要 outError 吗?
答案 0 :(得分:2)
该代码不适用于此AVFoundation类,因为PyObjC没有该框架的元数据描述。因此它确实知道最后一个参数是什么类型的参数,它只知道它是指向一个对象的指针,但不知道它被用作传递引用的输出参数。
手动检查PyObjC对此参数的了解::
>> import AVFoundation
>>> AVFoundation.AVAudioRecorder.initWithURL_settings_error_.__metadata__( ['arguments'][-1]
{'null_accepted': True, 'already_retained': False, 'type': '^@', 'already_cfretained': False}
这里的类型应该是“o ^ @”。
这是Apple的PyObjC版本:您可以在该版本中使用“import AVFoundation”,这将使用AVFoundation框架内的BridgeSupport数据文件。遗憾的是,数据不完整,并且没有关于此方法的信息,这就是为什么类型错误的原因。
通过使用PyObjCs元数据API来解决此特定方法相当容易:
import objc
objc.registerMetaDataForSelector(b"AVAudioRecorder", b"initWithURL:settings:error:",
dict(
arguments={
4: dict(type_modifier=objc._C_OUT),
}
))
修复所有AVFoundation的元数据将会更有效: - (