我想每次与MobilePhone App进行对话时都要记录。我的设备已越狱,因此对appStore限制没有任何问题。
当然我猜公共框架什么都不提供。此外,我一直在寻找私有框架,但没有看到任何有用的东西。
目前我可以从麦克风中录制,但是当会话开始时,它会将麦克风置于独占模式,并且不再接收数据。
任何指导?
答案 0 :(得分:9)
“Audio Recorder”确实是一个非常简单的调整。作者试图模糊他调整的重要部分(这个函数被挂钩),但这是我发现的。
Tweak基本上只挂了一个函数 - AudioConverterConvertComplexBuffer
来自AudioToolbox.framework
。 Tweak在启动时加载到mediaserverd
守护程序中。
首先,我们需要找出何时开始录制,因为即使您只是播放常规音频文件,也会调用AudioConverterConvertComplexBuffer
。要实现该调整,请收听来自kCTCallStatusChangeNotification
的{{1}}通知。
其次,CTTelephonyCenter
实施。我还没完成它所以我会发布到目前为止我所拥有的内容。这是一个有用的例子,可以帮助你入门。
帮助类跟踪AudioConverterRef - ExtAudioFileRef对
AudioConverterConvertComplexBuffer
ConverterFile对象容器
@interface ConverterFile : NSObject
@property (nonatomic, assign) AudioConverterRef converter;
@property (nonatomic, assign) ExtAudioFileRef file;
@property (nonatomic, assign) BOOL failedToOpenFile;
@end
@implementation ConverterFile
@end
AudioConverterConvertComplexBuffer原始实现
NSMutableArray* callConvertersFiles = [[NSMutableArray alloc] init];
AudioConverterConvertComplexBuffer挂钩声明
OSStatus(*AudioConverterConvertComplexBuffer_orig)(AudioConverterRef, UInt32, const AudioBufferList*, AudioBufferList*);
挂钩
OSStatus AudioConverterConvertComplexBuffer_hook(AudioConverterRef inAudioConverter, UInt32 inNumberPCMFrames, const AudioBufferList *inInputData, AudioBufferList *outOutputData);
AudioConverterConvertComplexBuffer挂钩定义
MSHookFunction(AudioConverterConvertComplexBuffer, AudioConverterConvertComplexBuffer_hook, &AudioConverterConvertComplexBuffer_orig);
这大致是在调整中完成的。但为什么这样做呢?当正在进行电话呼叫时,将连续呼叫OSStatus AudioConverterConvertComplexBuffer_hook(AudioConverterRef inAudioConverter, UInt32 inNumberPCMFrames, const AudioBufferList *inInputData, AudioBufferList *outOutputData)
{
//Searching for existing AudioConverterRef-ExtAudioFileRef pair
__block ConverterFile* cf = nil;
[callConvertersFiles enumerateObjectsUsingBlock:^(ConverterFile* obj, NSUInteger idx, BOOL *stop){
if (obj.converter == inAudioConverter)
{
cf = obj;
*stop = YES;
}
}];
//Inserting new AudioConverterRef
if (!cf)
{
cf = [[[ConverterFile alloc] init] autorelease];
cf.converter = inAudioConverter;
[callConvertersFiles addObject:cf];
}
//Opening new audio file
if (!cf.file && !cf.failedToOpenFile)
{
//Obtaining input audio format
AudioStreamBasicDescription desc;
UInt32 descSize = sizeof(desc);
AudioConverterGetProperty(cf.converter, kAudioConverterCurrentInputStreamDescription, &descSize, &desc);
//Opening audio file
CFURLRef url = CFURLCreateWithFileSystemPath(NULL, (CFStringRef)[NSString stringWithFormat:@"/var/mobile/Media/DCIM/Call%u.caf", [callConvertersFiles indexOfObject:cf]], kCFURLPOSIXPathStyle, false);
ExtAudioFileRef audioFile = NULL;
OSStatus result = ExtAudioFileCreateWithURL(url, kAudioFileCAFType, &desc, NULL, kAudioFileFlags_EraseFile, &audioFile);
if (result != 0)
{
cf.failedToOpenFile = YES;
cf.file = NULL;
}
else
{
cf.failedToOpenFile = NO;
cf.file = audioFile;
//Writing audio format
ExtAudioFileSetProperty(cf.file, kExtAudioFileProperty_ClientDataFormat, sizeof(desc), &desc);
}
CFRelease(url);
}
//Writing audio buffer
if (cf.file)
{
ExtAudioFileWrite(cf.file, inNumberPCMFrames, inInputData);
}
return AudioConverterConvertComplexBuffer_orig(inAudioConverter, inNumberPCMFrames, inInputData, outOutputData);
}
。但是inAudioConverter的说法会有所不同。我发现在一次通话期间可以有超过九种不同的inAudioConverter对象传递给我们的钩子。它们将具有不同的音频格式,因此我们无法在一个文件中写入所有内容。这就是为什么我们构建AudioConverterRef-ExtAudioFileRef对的数组 - 以跟踪保存到哪里的内容。此代码将创建与AudioConverterRef对象一样多的文件。所有文件都会包含不同的音频 - 一个或两个将是扬声器声音。其他的 - 麦克风。我已经在iOS 4的iPhone 4S上测试了这个代码并且它可以工作。不幸的是,只有在开启扬声器时才能在4S上进行通话录音。在iPhone 5上没有这样的限制。这在tweak的描述中提到。
唯一剩下的就是找出我们如何找到两个特定的inAudioConverter对象 - 一个用于扬声器音频,一个用于麦克风。其他一切都不是问题。
最后一件事 - AudioConverterConvertComplexBuffer_hook
进程是沙箱,以便我们进行调整。我们无法在任何地方保存文件。这就是我选择该文件路径的原因 - 它甚至可以从沙盒内部写入。
PS虽然我已经发布了这个代码,但是必须去Elias Limneos。他已经完成了。
答案 1 :(得分:1)
您想要计算来电还是想要录制来自这些来电的音频?前者很简单,只需要一个通知。对于后者我没有找到任何东西。我做了研究,没有找到任何可以帮助我在电话呼叫过程中录制音频的API。我不知道是谁做到了。
我唯一能想到的是CommCenter。该守护进程与基带通信,并可能从麦克风向他发送音频流。这只是一个猜测,但看着CommCenter反汇编我发现它负责重定向音频流的线索。较新的Qualcomm基带和iOS仅通过使用专有QMI协议的USB管道相互通信。该协议所做的一件事是在电话呼叫期间处理音频流 - 它被称为Core sound driver service
。因此,我唯一能想到的就是反汇编CommCenter并找到一种方法来重定向音频流,通过你将要记录它们的处理程序。这显然需要广泛的逆向工程知识,QMI协议,用于与USB设备通信的IOKit等等。我认为没有一个API可以为您做到这一点,或者您可以通过简单的挂钩技术来实现这一点。我们谈论的是C ++代码,它比obj-c更难以进行逆向工程,而且更难以加入。