Код AudioQueue из SpeakHere не работает на iPad

Я использую аудио классы SpeakHere в создаваемом приложении, которое должно одновременно воспроизводить и записывать.

Я использую новейший SDK с целевым устройством 3.2 в универсальной сборке приложений (для iPad и iPhone).

Приложение воспроизводит потоковые фильмы с использованием MPMoviePlayerController и одновременно записывает аудио.

Это прекрасно работает на iPhone.

Тем не менее, это не удается 100% на моих клиентов iPad. Журналы показывают ошибки! Act, которые AudioSession просто отказывается активировать! И каждый файл журнала, который я получил от него, содержит многочисленные прерывания и изменения маршрута (а именно Категория), которые возвращаются в функции обратного вызова. ** На iPhone я не вижу ничего подобного. Журналы показывают только то, что запись была создана и записана в указанный файл. Без перерывов, без изменений маршрута, без глупостей.

Вот соответствующие журналы:

Jul 10 07:15:21 iPad mediaserverd[15502] <Error>: [07:15:21.464 <0x1207000>] AudioSessionSetClientPlayState: Error adding running client - session not active
Sat Jul 10 07:15:21 iPad mediaserverd[15502] <Error>: [07:15:21.464 <AudioQueueServer>] AudioQueue: Error '!act' from AudioSessionSetClientPlayState(15642)

Я заглушил обе функции обратного вызова, чтобы просто регистрировать случаи прерываний и изменения маршрута (с указанием причин). Поэтому я не буду публиковать код, поскольку он буквально ничего не делает. Я вижу эти журналы много раз за одну попытку начать запись на iPad.

Я прочитал практически все посты, которые я могу найти на форуме Apple Dev и в Stackru, но не могу найти кого-то с той же проблемой или каких-либо соответствующих заметок в Apple Docs, которые объясняют разницу в поведении iPad. - Примечание: iPad действительно отображал некоторые другие дефектные поведения, которые были исправлены, такие как несовпадающие вызовы Begin Interrupt, которые никогда не заканчивались (поэтому я никогда не деактивирую сеанс).

Я никогда не получаю никаких журналов, указывающих какие-либо неудачные вызовы инициализации или активации из кода AudioQueue или AudioSession. Это просто терпит неудачу, когда я пытаюсь начать запись. - Я даже пытался форсировать AudioSessionSetActive(true); звонки до каждой попытки использования звуковой системы, и я все еще получаю эти ошибки.

Вот соответствующий код для вызовов инициализации:

//Initialize the Sound System
    OSStatus error = AudioSessionInitialize(NULL, NULL, interruptionListener, self);
    if (error){ printf("ERROR INITIALIZING AUDIO SESSION! %d\n", (int)error); }
    else {
        //must set the session active first according to devs talking about some defect....         
        error = AudioSessionSetActive(true); 
        if (error) NSLog(@"AudioSessionSetActive (true) failed");

        UInt32 category = kAudioSessionCategory_PlayAndRecord;  
        error = AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(category), &category);
        if (error) printf("couldn't set audio category!\n");

        error = AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, propListener, self);
        if (error) printf("ERROR ADDING AUDIO SESSION PROP LISTENER! %d\n", (int)error);

        //Force mixing!
        UInt32 allowMixing = true;
        error = AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryMixWithOthers, sizeof (allowMixing), &allowMixing );
        if (error) printf("ERROR ENABLING MIXING PROPS! %d\n", (int)error);

        UInt32 inputAvailable = 0;
        UInt32 size = sizeof(inputAvailable);           
        // we do not want to allow recording if input is not available
        error = AudioSessionGetProperty(kAudioSessionProperty_AudioInputAvailable, &size, &inputAvailable);
        if (error) printf("ERROR GETTING INPUT AVAILABILITY! %d\n", (int)error);
        isInputAvailable = (inputAvailable) ? YES : NO;


        //iPad doesn't require the routing changes, branched to help isolate iPad behavioral issues
        if(! [Utils GetMainVC].usingiPad){
            //redirect to speaker?  //this only resets on a category change!
            UInt32 doChangeDefaultRoute = 1;        
            error = AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryDefaultToSpeaker, sizeof (doChangeDefaultRoute), &doChangeDefaultRoute);
            if (error) printf("ERROR CHANGING DEFAULT ROUTE PROPS! %d\n", (int)error);

            //this resets with interruption and/or route changes
            UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker; 
            error = AudioSessionSetProperty(kAudioSessionProperty_OverrideAudioRoute,sizeof (audioRouteOverride),&audioRouteOverride);
            if (error) printf("ERROR SPEAKER ROUTE PROPS! %d\n", (int)error);
        }

        // we also need to listen to see if input availability changes
        error = AudioSessionAddPropertyListener(kAudioSessionProperty_AudioInputAvailable, propListener, self);
        if (error) printf("ERROR ADDING AUDIO SESSION PROP LISTENER! %d\n", (int)error);

        error = AudioSessionSetActive(true); 
        if (error) NSLog(@"AudioSessionSetActive (true) failed");
    }

    // Allocate our singleton instance for the recorder & player object
    myRecorder = new AQRecorder();
    myPlayer = new AQPlayer();

Позже в обратном вызове loadstate для видео я просто пытаюсь начать запись в заранее определенный путь к файлу:

myRecorder->StartRecord((CFStringRef)myPathStr);

И аудиозапись полностью проваливается.

Спасибо за ваше время и помощь в этом.

1 ответ

Оказывается, это странная проблема.

1) Используйте только звукозапись и воспроизводите, и код отлично работает на iPad.

2) Добавьте воспроизведение фильма и НЕ вызывайте никаких изменений в маршрутизации, и на iPad все работает нормально.

Каким-то образом наличия воспроизведения проигрывателя Movie Player достаточно, чтобы изменить AudioSession таким образом, что принудительное изменение маршрута (например, использование динамика устройства вместо наушников) приводит к тому, что AudioSession становится неактивным.

Другие вопросы по тегам