2009-05-25 7 views

Répondre

9

OK. Ceci est une solution pour le bruit de fond sur iOS4 & iOS5 (fonctionne définitivement jusqu'à iOS 5.0.1), et je l'ai testé uniquement avec AVPlayer. Cela devrait probablement fonctionner aussi pour MPMusicPlayerController.

cadres requis:

  • AVFoundation.framework
  • AudioToolbox.framework

Dans votre Info.plist, pour la UIBackgroundModes clé, ajouter audio.

MyAppDelegate.h

Dans:

  • référence <AVFoundation/AVFoundation.h> & <AudioToolbox/AudioToolbox.h>
  • mettre en œuvre le protocole AVAudioSessionDelegate:

    @interface MyAppDelegate : NSObject <UIApplicationDelegate, AVAudioSessionDelegate> 
    
  • définir une méthode ensureAudio:

    // Ensures the audio routes are setup correctly 
    - (BOOL) ensureAudio; 
    

En MyAppDelegate.m:

  • mettre en œuvre la méthode ensureAudio:

    - (BOOL) ensureAudio 
    { 
        // Registers this class as the delegate of the audio session (to get background sound) 
        [[AVAudioSession sharedInstance] setDelegate: self]; 
    
        // Set category 
        NSError *categoryError = nil; 
        if (![[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&categoryError]) { 
         NSLog(@"Audio session category could not be set"); 
         return NO; 
        } 
    
        // Activate session 
        NSError *activationError = nil; 
        if (![[AVAudioSession sharedInstance] setActive: YES error: &activationError]) { 
         NSLog(@"Audio session could not be activated"); 
         return NO; 
        } 
    
        // Allow the audio to mix with other apps (necessary for background sound) 
        UInt32 doChangeDefaultRoute = 1; 
        AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryMixWithOthers, sizeof(doChangeDefaultRoute), &doChangeDefaultRoute); 
    
        return YES; 
    } 
    
  • dans la méthode application:didFinishLaunchingWithOptions:, avant d'attribuer le contrôleur de vue racine, exécutez [self ensureAudio]:

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
    { 
        // Configure audio session 
        [self ensureAudio]; 
    
        // Add the navigation controller's view to the window and display. 
        self.window.rootViewController = self.navigationController; 
        [self.window makeKeyAndVisible]; 
    
        return YES; 
    } 
    
  • mettre en œuvre les méthodes AVAudioSessionDelegate comme ceci:

    #pragma mark - AVAudioSessionDelegate 
    
    - (void) beginInterruption 
    { 
    
    } 
    
    - (void) endInterruption 
    { 
        // Sometimes the audio session will be reset/stopped by an interruption 
        [self ensureAudio]; 
    } 
    
    - (void) inputIsAvailableChanged:(BOOL)isInputAvailable 
    { 
    
    } 
    
  • assurez-vous que votre application continue à fonctionner en arrière-plan. Vous pouvez utiliser le '[[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler] si vous voulez, mais je pense qu'il y a de meilleurs moyens.

  • jouer l'audio réelle (notez que je utilise ARC, c'est la raison pour laquelle il n'y a pas release appels):

    NSURL * file = [[NSBundle mainBundle] URLForResource:@"beep" withExtension:@"aif"];  
    AVURLAsset * asset = [[AVURLAsset alloc] initWithURL:file options:nil]; 
    AVPlayerItem * item = [[AVPlayerItem alloc] initWithAsset:asset]; 
    __block AVPlayer * player = [[AVPlayer alloc]initWithPlayerItem:item]; 
    __block id finishObserver = [[NSNotificationCenter defaultCenter] addObserverForName:AVPlayerItemDidPlayToEndTimeNotification 
                         object:player.currentItem 
                         queue:[NSOperationQueue mainQueue] 
                        usingBlock:^(NSNotification *note) { 
        [[NSNotificationCenter defaultCenter] removeObserver:finishObserver]; 
    
        // Reference the 'player' variable so ARC doesn't release it until it's 
        // finished playing. 
        player = nil; 
    }]; 
    
    // Trigger asynchronous load 
    [asset loadValuesAsynchronouslyForKeys:[NSArray arrayWithObject:@"tracks"] completionHandler:^{ 
        // Start playing the beep (watch out - we're not on the main thread here)! 
        [player play]; 
    }]; 
    
  • Et ce shooooooooooooould travail!

+0

Si vous utilisez MPMusicPlayerController pour lire la musique, assurez-vous d'utiliser [MPMusicPlayerController iPodMusicPlayer] et de ne pas utiliser [MPMusicPlayerController applicationMusicPlayer]. Regardez aussi ici: http://stackoverflow.com/questions/1507541/avaudioplayer-turns-off-ipod-how-to-work-around qui vous montrera quoi faire si vous ne voulez pas que votre application arrête la musique jouait lorsque l'utilisateur démarre votre application –

+0

Testez ce comportement sur un périphérique physique. Cela ne fonctionne pas dans le simulateur pour moi. Cela fonctionne sur un périphérique physique. – Webdevotion

+0

Merci! Cela fonctionne réellement! – kizzx2

0

Si vous utilisez votre application aussi pour l'enregistrement - puis ne pas oublier de changer setCategory à AVAudioSessionCategoryPlayAndRecord.Dans d'autres cas, vous ne serez pas en mesure d'enregistrer

[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayAndRecord error:&setCategoryErr]; 
Questions connexes