Получение микрофона гарнитуры для работы с AVAudioRecorder на iOS - PullRequest
2 голосов
/ 13 января 2011

Когда подключен микрофон, мое приложение продолжает запись со встроенного микрофона (я хотел бы использовать подключенный микрофон). Я использую:

[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:&err];

Я надеюсь избежать служб очереди или чего-нибудь более глубокого из-за чего-то более простого.

После некоторого исследования (с документацией на яблоки) я не могу найти способ сделать это с очередями ...

После дальнейших исследований я не могу понять, как это сделать вообще. Это не упомянуто ни в документации Apple, ни в каких-либо константах и ​​т. Д. Существует приложение под названием «FiRe», которое делает это, поэтому я знаю, что это возможно.

1 Ответ

0 голосов
/ 22 сентября 2012

Я понимаю, что это старый вопрос, но подумал, что кому-то это может пригодиться.

Может быть, я не понимаю твою проблему на самом деле. Хотите ли вы иметь возможность записи с помощью встроенного микрофона, а затем легко переключаться на запись с гарнитуры, когда она подключена? Или вам просто сложно записывать с гарнитуры?

Я сам использую этот код для устранения проблем с маршрутизацией. Просто поиграйте со своим приложением, подключите гарнитуру и посмотрите, что вышло из консоли. Убедитесь, что подключенная гарнитура вызывает изменение маршрута «HeadsetInOut». Если это только «наушники», он будет воспроизводить звук в гарнитуре, но записывать со встроенного микрофона.

У меня не было проблем с использованием AudioQueues для записи с гарнитуры.

void interruptionListener(  void *  inClientData,
                          UInt32    inInterruptionState)
{
    if (inInterruptionState == kAudioSessionBeginInterruption) {
        // handle interruption
    }
    else if (inInterruptionState == kAudioSessionEndInterruption) {
        // handle interruption
    }
}

void propListener(  void *                  inClientData,
                  AudioSessionPropertyID    inID,
                  UInt32                  inDataSize,
                  const void *            inData)
{
    FooBar *self = (__bridge FooBar*)inClientData;

    if (inID == kAudioSessionProperty_AudioRouteChange) {
        CFDictionaryRef routeDictionary = (CFDictionaryRef)inData;          

        CFNumberRef reason = (CFNumberRef)CFDictionaryGetValue(routeDictionary, CFSTR(kAudioSession_AudioRouteChangeKey_Reason));
        SInt32 reasonVal;

        CFNumberGetValue(reason, kCFNumberSInt32Type, &reasonVal);
        if (reasonVal != kAudioSessionRouteChangeReason_CategoryChange) {
            // Check the old route

            CFStringRef oldRoute = (CFStringRef)CFDictionaryGetValue(routeDictionary, CFSTR(kAudioSession_AudioRouteChangeKey_OldRoute));
            if (oldRoute) {
                NSLog(@"Changed audio route from route:");
                CFShow(oldRoute);
            } else {
                NSLog(@"Error getting old audio route.\n");
            }

            CFStringRef newRoute;
            UInt32 size; size = sizeof(CFStringRef);
            OSStatus error = AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &size, &newRoute);
            if (error) {
                NSLog(@"Error getting new audio route: %ld\n", error);
            }
            else {
                NSLog(@"Changed audio route to:\n");
                CFShow(newRoute);

                if (CFStringCompare(newRoute, CFSTR("HeadsetInOut"), 0) == kCFCompareEqualTo) 
                {
                    // you can do some recording, yay.
                }
            }

            if (reasonVal == kAudioSessionRouteChangeReason_OldDeviceUnavailable)
            {
                NSLog(@"kAudioSessionRouteChangeReason_OldDeviceUnavailable");
            }
        }   
    }
}

-(id) init
{
    self = [super init];
    if (self) {
        OSStatus error = AudioSessionInitialize(NULL, NULL, interruptionListener, (__bridge void *)(self));
        if (error) 
        {
            NSLog(@"Error initializing audio session: %ld\n", error); 
        } else {            
            error = AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, propListener, (__bridge void *)(self));
            if (error) {
                NSLog(@"Error adding audio session property listener (route change): %ld\n", error);
            } 

            UInt32 inputAvailable = 0;
            UInt32 size = sizeof(inputAvailable);

            error = AudioSessionGetProperty(kAudioSessionProperty_AudioInputAvailable, &size, &inputAvailable);
            if (error) {
                NSLog(@"Error getting input availability: %ld\n", error);
            }

            error = AudioSessionAddPropertyListener(kAudioSessionProperty_AudioInputAvailable, propListener, (__bridge void *)(self));
            if (error) {
                NSLog(@"Error adding audio session property listener (input availability): %ld\n", error);
            }

            // Activate the session
            error = AudioSessionSetActive(true); 
            if (error) {
                NSLog(@"Failed to activate audio session: %ld\n", error);
            }            
        }
    }
    return self;
}
...