记录iOS对话。从哪儿开始? [英] Rec iOS conversations. Where to start?

查看:88
本文介绍了记录iOS对话。从哪儿开始?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想每次与MobilePhone App进行对话时都要记录。我的设备越狱了,所以appStore限制没问题。

I would like to rec each time I have a conversation with the MobilePhone App. My device is jailbroken, so no problem about the appStore restrictions.

当然我觉得公共框架什么都不提供。此外,我一直在看私有框架,但没有看到任何有用的东西。

Of course I guess the public framework will provide nothing. Also, I've been looking at the private frameworks, but haven't seen anything useful.

目前我可以从麦克风中录制,但是当会话开始时,它会将麦克风置于独占模式,并且不再接收数据。

Currently I am able to rec from the microphone, but when a conversation starts, it takes the microphone in exclusive mode, and the data is no longer received.

任何指导?

推荐答案

录音机确实是一个非常简单的调整。作者试图模糊他的调整的重要部分(这个函数被挂钩),但这是我发现的。

"Audio Recorder" is indeed a very simple tweak. The author tried to obfuscate important parts of his tweak (which function is being hooked), but here is what I found.

Tweak基本上只挂钩一个函数 - AudioConverterConvertComplexBuffer 来自 AudioToolbox.framework 。在启动时将Tweak加载到 mediaserverd 守护程序中。

Tweak basically hooks just one function - AudioConverterConvertComplexBuffer from AudioToolbox.framework. Tweak is loaded in mediaserverd daemon at startup.

首先,我们需要找出我们何时应该开始录制,因为即使你只是定期玩,也会调用 AudioConverterConvertComplexBuffer 音频文件。要实现该调整,请从 CTTelephonyCenter 收听 kCTCallStatusChangeNotification 通知。

First, we need to find out when we should start recording because AudioConverterConvertComplexBuffer is called even when you just playing regular audio files. To achieve that tweak is listening to kCTCallStatusChangeNotification notification from CTTelephonyCenter.

其次, AudioConverterConvertComplexBuffer 实施。我还没有完成它所以我将发布到目前为止我所拥有的内容。这是一个有用的例子,可以帮助你入门。

Second, AudioConverterConvertComplexBuffer implementation. I didn't finished it yet so I will post what I have so far. Here is somewhat working example that will get you started.

帮助类跟踪AudioConverterRef - ExtAudioFileRef对

@interface ConverterFile : NSObject

@property (nonatomic, assign) AudioConverterRef converter;
@property (nonatomic, assign) ExtAudioFileRef file;
@property (nonatomic, assign) BOOL failedToOpenFile;

@end

@implementation ConverterFile
@end

ConverterFile对象容器

NSMutableArray* callConvertersFiles = [[NSMutableArray alloc] init];

AudioConverterConvertComplexBuffer原始实现

OSStatus(*AudioConverterConvertComplexBuffer_orig)(AudioConverterRef, UInt32, const AudioBufferList*, AudioBufferList*);

AudioConverterConvertComplexBuffer挂钩声明

OSStatus AudioConverterConvertComplexBuffer_hook(AudioConverterRef inAudioConverter, UInt32 inNumberPCMFrames, const AudioBufferList *inInputData, AudioBufferList *outOutputData);

挂钩

MSHookFunction(AudioConverterConvertComplexBuffer, AudioConverterConvertComplexBuffer_hook, &AudioConverterConvertComplexBuffer_orig);

AudioConverterConvertComplexBuffer挂钩定义

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);
}

这大致是在调整中完成的。但是为什么这样做呢?正在进行电话呼叫将连续呼叫AudioConverterConvertComplexBuffer_hook 。但是inAudioConverter的说法会有所不同。我发现在一次通话期间可以有超过九种不同的inAudioConverter对象传递给我们的钩子。它们将具有不同的音频格式,因此我们无法在一个文件中写入所有内容。这就是为什么我们构建AudioConverterRef-ExtAudioFileRef对的数组 - 以跟踪保存到哪里的内容。此代码将创建与AudioConverterRef对象一样多的文件。所有文件都会包含不同的音频 - 一个或两个将是扬声器声音。其他的 - 麦克风。我已经在iOS 4的iPhone 4S上测试了这个代码,它可以运行。不幸的是,只有在开启扬声器时才能在4S上进行通话录音。在iPhone 5上没有这样的限制。这在tweak的描述中有提及。

This is roughly how it's done in the tweak. But why it's done like that? When phone call is in progress AudioConverterConvertComplexBuffer_hook will be called continuously. But inAudioConverter argument will be different. I've found that there can be more than nine different inAudioConverter objects passed to our hook during one phone call. They will have different audio formats so we can't write everything in one file. This is why we building array of AudioConverterRef-ExtAudioFileRef pairs - to keep track of what is being saved to where. This code will create as many file as there is AudioConverterRef objects. All files will containt different audio - one or two will be the speaker sound. Others - microphone. I've tested this code on iPhone 4S with iOS 6.1 and it works. Unfortunately, call recording on 4S can be done only when speaker is turned on. There is no such limitation on iPhone 5. This is mentioned in tweak's description.

唯一剩下的就是找出我们如何找到两个特定的inAudioConverter对象 - 一个用于扬声器音频和一个麦克风。其他一切都不是问题。

Only thing left is to find out how we can find just two specific inAudioConverter objects - one for speaker audio and one for microphone. Everything else is not a problem.

最后一件事 - mediaserverd 进程是沙箱,以便我们进行调整。我们无法在任何需要的地方保存文件。这就是我选择该文件路径的原因 - 它甚至可以从沙箱内部写入。

And one last thing - mediaserverd process is sandboxed so as our tweak. We can't save files anywhere we want. This is why I chose that file path - it can be written even from the inside of the sandbox.

PS即使我已发布此代码,也必须转到Elias Limneos。他已经完成了。

PS Even though I've posted this code credit has to go to Elias Limneos. He's done it.

这篇关于记录iOS对话。从哪儿开始?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆