2009-05-25 3 views

ответ

9

Хорошо. Это решение для фонового звука на iOS iOS5 (определенно работает до iOS 5.0.1), и я тестировал его только с помощью AVPlayer. Вероятно, он должен работать и для MPMusicPlayerController.

Необходимые рамки:

  • AVFoundation.framework
  • AudioToolbox.framework

В вашем Info.plist, для ключа UIBackgroundModes, добавьте audio.

В MyAppDelegate.h:

  • ссылка <AVFoundation/AVFoundation.h> & <AudioToolbox/AudioToolbox.h>
  • реализации протокола AVAudioSessionDelegate:

    @interface MyAppDelegate : NSObject <UIApplicationDelegate, AVAudioSessionDelegate> 
    
  • определить метод ensureAudio:

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

В MyAppDelegate.m:

  • реализовать 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; 
    } 
    
  • в методе application:didFinishLaunchingWithOptions:, прежде чем назначить контроллер представления корня, запустите [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; 
    } 
    
  • реализовать AVAudioSessionDelegate методы, как это:

    #pragma mark - AVAudioSessionDelegate 
    
    - (void) beginInterruption 
    { 
    
    } 
    
    - (void) endInterruption 
    { 
        // Sometimes the audio session will be reset/stopped by an interruption 
        [self ensureAudio]; 
    } 
    
    - (void) inputIsAvailableChanged:(BOOL)isInputAvailable 
    { 
    
    } 
    
  • убедитесь, что ваше приложение продолжает работать в фоновом режиме. Вы можете использовать ol '[[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler], если хотите, но я думаю, что есть лучшие способы.

  • играть фактическое аудио (обратите внимание, я использую ARC, поэтому нет release звонков):

    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]; 
    }]; 
    
  • И shooooooooooooould работать!

+0

Если вы используете MPMusicPlayerController для воспроизведения музыки, обязательно используйте [MPMusicPlayerController iPodMusicPlayer], а не использовать [MPMusicPlayerController applicationMusicPlayer]. Также смотрите здесь: http://stackoverflow.com/questions/1507541/avaudioplayer-turns-off-ipod-how-to-work-around, который покажет вам, что делать, если вы не хотите, чтобы ваше приложение останавливало любую музыку играя, когда пользователь запускает ваше приложение. –

+0

Проверьте это поведение на физическом устройстве. Для меня это не работает в Simulator. Он работает на физическом устройстве. – Webdevotion

+0

Спасибо! Это действительно работает! – kizzx2

0

Если вы используете приложение также для записи - то не забудьте изменить setCategory к AVAudioSessionCategoryPlayAndRecord.В другом случае вы не сможете записывать

[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayAndRecord error:&setCategoryErr]; 
Смежные вопросы