2009-12-02 2 views
16

В настоящее время я работаю над проектом, который включает в себя воспроизведение музыки из музыкальной библиотеки iphone внутри приложения. Я использую MPMediaPickerController, чтобы пользователь мог выбирать свою музыку и воспроизводить ее с помощью музыкального плеера iPod в iPhone.Как программно обнаружить динамик в iphone?

Однако, я столкнулся с проблемой, когда пользователь вставил свой динамик и удалил его. Музыка внезапно перестанет играть без причины. После некоторого тестирования я узнал, что проигрыватель iPod приостанавливает воспроизведение, когда пользователь отключает наушник от устройства. Итак, есть ли способ программно определить, отключен ли наушник, чтобы я мог возобновить воспроизведение музыки? Или есть ли способ предотвратить переключение iPod-плеера, когда пользователь отключает наушник?

ответ

9

Вы должны зарегистрироваться AudioRoute изменены уведомления и реализации, как вы хотите, чтобы справиться с разгромом изменения

// Registers the audio route change listener callback function 
    AudioSessionAddPropertyListener (kAudioSessionProperty_AudioRouteChange, 
            audioRouteChangeListenerCallback, 
            self); 

и в течение обратного вызова вы можете получить причину для изменения маршрута

CFDictionaryRef routeChangeDictionary = inPropertyValue; 

    CFNumberRef routeChangeReasonRef = 
    CFDictionaryGetValue (routeChangeDictionary, 
      CFSTR (kAudioSession_AudioRouteChangeKey_Reason)); 

    SInt32 routeChangeReason; 

     CFNumberGetValue (routeChangeReasonRef, kCFNumberSInt32Type, &routeChangeReason); 

    if (routeChangeReason == kAudioSessionRouteChangeReason_OldDeviceUnavailable) 
    { 
     // Headset is unplugged.. 

    } 
    if (routeChangeReason == kAudioSessionRouteChangeReason_NewDeviceAvailable) 
    { 
     // Headset is plugged in..     
    } 
+0

ERM Я имею 2 ошибки при компиляции 1) Ват inPropertyValue? Он не угасает либо в параметре метода 2) CFDictionaryGetValue возвращает указатель на пустоту, который не поддается CFNumberRef. Нужно ли делать какие-либо кастинга, прежде чем возвращать значение? –

+0

Хмм мне удалось скомпилировать мои коды, и все работает нормально, но когда я подключаю или отсоединяю наушники, ничего не происходит. Функция audioRouteChangeListenerCallback не вызывается. Есть ли что-то еще, что мне не хватает рядом с вышеперечисленными функциями? –

+0

Вы должны зарегистрироваться для функции прослушивания ПОСЛЕ вашего вызова инициализации AudioSession .. Вы делаете это? – prakash

2

Я вижу, что вы используете MPMediaPlayer Framework, однако обработка микрофона выполняется с использованием среды AVAudioPlayer, которую вам нужно будет добавить в свой проект.

Веб-сайт Apple имеет код из рамки AVAudioPlayer, который я использую для обработки прерываний от пользователя, подключающего или удаляющего наушники микрофона Apple.

Отъезд Apple's iPhone Dev Center Audio Session Programming Guide.

- (void) beginInterruption { 
    if (playing) { 
     playing = NO; 
     interruptedWhilePlaying = YES; 
     [self updateUserInterface]; 
    } 
} 

NSError *activationError = nil; 
- (void) endInterruption { 
    if (interruptedWhilePlaying) { 
     [[AVAudioSession sharedInstance] setActive: YES error: &activationError]; 
     [player play]; 
     playing = YES; 
     interruptedWhilePlaying = NO; 
     [self updateUserInterface]; 
    } 
} 

Мой код немного отличается, и некоторые это может помочь вам:

void interruptionListenerCallback (
            void *inUserData, 
            UInt32 interruptionState 
) { 
    // This callback, being outside the implementation block, needs a reference 
    // to the AudioViewController object 
    RecordingListViewController *controller = (RecordingListViewController *) inUserData; 

    if (interruptionState == kAudioSessionBeginInterruption) { 

     //NSLog (@"Interrupted. Stopping playback or recording."); 

     if (controller.audioRecorder) { 
      // if currently recording, stop 
      [controller recordOrStop: (id) controller]; 
     } else if (controller.audioPlayer) { 
      // if currently playing, pause 
      [controller pausePlayback]; 
      controller.interruptedOnPlayback = YES; 
     } 

    } else if ((interruptionState == kAudioSessionEndInterruption) && controller.interruptedOnPlayback) { 
     // if the interruption was removed, and the app had been playing, resume playback 
     [controller resumePlayback]; 
     controller.interruptedOnPlayback = NO; 
    } 
} 

void recordingListViewMicrophoneListener (
         void      *inUserData, 
         AudioSessionPropertyID inPropertyID, 
         UInt32     inPropertyValueSize, 
         const void    *isMicConnected 
         ) { 

    // ensure that this callback was invoked for a change to microphone connection 
    if (inPropertyID != kAudioSessionProperty_AudioInputAvailable) { 
     return; 
    } 

    RecordingListViewController *controller = (RecordingListViewController *) inUserData; 

    // kAudioSessionProperty_AudioInputAvailable is a UInt32 (see Apple Audio Session Services Reference documentation) 
    // to read isMicConnected, convert the const void pointer to a UInt32 pointer 
    // then dereference the memory address contained in that pointer 
    UInt32 connected = * (UInt32 *) isMicConnected; 

    if (connected){ 
     [controller setMicrophoneConnected : YES]; 
    } 
    else{ 
     [controller setMicrophoneConnected: NO];  
    } 

    // check to see if microphone disconnected while recording 
    // cancel the recording if it was 
    if(controller.isRecording && !connected){ 
     [controller cancelDueToMicrophoneError]; 
    } 
} 
4

Если вы просто хотите, чтобы проверить, является ли подключены наушники в любой момент времени, не слушая изменения маршрута, вы можете просто сделать следующее:

OSStatus error = AudioSessionInitialize(NULL, NULL, NULL, NULL); 
if (error) 
    NSLog("Error %d while initializing session", error); 

UInt32 routeSize = sizeof (CFStringRef); 
CFStringRef route; 

error = AudioSessionGetProperty (kAudioSessionProperty_AudioRoute, 
           &routeSize, 
           &route); 

if (error) 
    NSLog("Error %d while retrieving audio property", error); 
else if (route == NULL) { 
    NSLog(@"Silent switch is currently on"); 
} else if([route isEqual:@"Headset"]) { 
    NSLog(@"Using headphones"); 
} else { 
    NSLog(@"Using %@", route); 
} 

Приветствия, Raffaello Colasante

+1

. Лучшую реализацию этого можно найти здесь: http://stackoverflow.com/questions/3728781/detect-if-headphones-not-microphone-are-plugged- в-к-ан-КСН-устройства –

2

Эй ребята просто проверяют приложение AddMusic. Будет ли решить все связанные с IPOD вопросы

Первый регистр IPOD плеер для уведомления с помощью следующего кода

NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; 

    [notificationCenter 
    addObserver: self 
    selector: @selector (handle_PlaybackStateChanged:) 
    name:  MPMusicPlayerControllerPlaybackStateDidChangeNotification 
    object:  musicPlayer]; 

    [musicPlayer beginGeneratingPlaybackNotifications]; 

и реализовать следующий код в уведомлении

- (void) handle_PlaybackStateChanged: (id) notification 
{ 

    MPMusicPlaybackState playbackState = [musicPlayer playbackState]; 

    if (playbackState == MPMusicPlaybackStatePaused) 
    { 
      [self playiPodMusic]; 
    } 
    else if (playbackState == MPMusicPlaybackStatePlaying) 
    { 

    } 
    else if (playbackState == MPMusicPlaybackStateStopped) 
    { 
     [musicPlayer stop]; 
    } 
} 
Смежные вопросы