2014-12-31 5 views
0

앱이 배경에있는 동안 소리를 재생하려고합니다. 다음 방법으로 사운드를 시작하면 코드에서 사운드가 올바르게 재생됩니다. 백그라운드로는 휴대 전화 화면이 꺼져있을 때 (예 : 주머니에 넣은 경우)를 의미합니다.백그라운드에서 앱 실행 중 소리 재생

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 

    [self startSilentBackgroundSound]; // works fine 

} 

나는 앱이 백그라운드에있는 동안은 하지가 사운드를 재생 않습니다 위의 코드를 제거하고 여기에 그것을 할 경우. 필요한 배경 모드에서

- (void)applicationDidEnterBackground:(UIApplication *)application { 

    self.newTaskId = UIBackgroundTaskInvalid; 
    self.newTaskId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:NULL]; 
    [self startSilentBackgroundSound]; // does NOT work 
} 

나는 다음과 같습니다

App plays audio or streams audio/video using AirPlay 
App downloads content from the network 
App registers for location updates 
App provides Voice over IP services 
App downloads content in response to push notifications 

사람이 나는 매우 감사하고자했다 GitHub의 프로젝트를 알고 있다면!

-(void)startSilentBackgroundSound { 
     AVAudioSession *audioSession = [AVAudioSession sharedInstance]; 
     NSError *error = nil; 
     NSLog(@"Activating audio session"); 
     if (![audioSession setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionDuckOthers error:&error]) { 
      NSLog(@"Unable to set audio session category: %@", error); 
     } 
     BOOL result = [audioSession setActive:YES error:&error]; 
     if (!result) { 
      NSLog(@"Error activating audio session: %@", error); 
     } 
     [[UIApplication sharedApplication] beginReceivingRemoteControlEvents]; 

     [self startAlarmSound]; 
    } 

    -(void)stopSilentBackgroundSound { 
     AVAudioSession *audioSession = [AVAudioSession sharedInstance]; 
     NSError *error = nil; 
     NSLog(@"Deactivating audio session"); 
     BOOL result = [audioSession setActive:NO error:&error]; 
     if (!result) { 
      NSLog(@"Error deactivating audio session: %@", error); 
     } 

     [self stopSounds]; 
    } 



    -(void)startAlarmSound { 
     self.silentAudioController = [[SilentAudioController alloc] init]; 
     [self.silentAudioController tryPlayMusic]; 
    } 

    -(void)stopSounds { 
     [self.silentAudioController tryStopMusic]; 
     self.silentAudioController = nil; 
    } 

//////// MY APP 대리자

//// 코드 /// HERE 핸들 MY FILE 모든 소리 STUFF

 #import "SilentAudioController.h" 

     @import AVFoundation; 

     @interface SilentAudioController() <AVAudioPlayerDelegate> 

     @property (strong, nonatomic) AVAudioSession *audioSession; 
     @property (strong, nonatomic) AVAudioPlayer *backgroundMusicPlayer; 
     @property (assign) BOOL backgroundMusicPlaying; 
     @property (assign) BOOL backgroundMusicInterrupted; 
     @property (assign) SystemSoundID pewPewSound; 

     @end 

     @implementation SilentAudioController 

     #pragma mark - Public 

     - (instancetype)init 
     { 
      self = [super init]; 
      if (self) { 
       [self configureAudioSession]; 
       [self configureAudioPlayer]; 
       [self configureSystemSound]; 
      } 
      return self; 
     } 

     - (void)tryPlayMusic { 
      // If background music or other music is already playing, nothing more to do here 
      if (self.backgroundMusicPlaying || [self.audioSession isOtherAudioPlaying]) { 
       return; 
      } 

      // Play background music if no other music is playing and we aren't playing already 
      //Note: prepareToPlay preloads the music file and can help avoid latency. If you don't 
      //call it, then it is called anyway implicitly as a result of [self.backgroundMusicPlayer play]; 
      //It can be worthwhile to call prepareToPlay as soon as possible so as to avoid needless 
      //delay when playing a sound later on. 
      [self.backgroundMusicPlayer prepareToPlay]; 
      [self.backgroundMusicPlayer play]; 
      self.backgroundMusicPlaying = YES; 
     } 

     - (void)tryStopMusic { 
      [self.backgroundMusicPlayer stop]; 
      self.backgroundMusicPlaying = NO; 
     } 

     - (void)playSystemSound { 
      AudioServicesPlaySystemSound(self.pewPewSound); 
     } 

     #pragma mark - Private 

     - (void) configureAudioSession { 
      // Implicit initialization of audio session 
      self.audioSession = [AVAudioSession sharedInstance]; 

      // Set category of audio session 
      // See handy chart on pg. 46 of the Audio Session Programming Guide for what the categories mean 
      // Not absolutely required in this example, but good to get into the habit of doing 
      // See pg. 10 of Audio Session Programming Guide for "Why a Default Session Usually Isn't What You Want" 

      NSError *setCategoryError = nil; 
      if ([self.audioSession isOtherAudioPlaying]) { // mix sound effects with music already playing 
       [self.audioSession setCategory:AVAudioSessionCategorySoloAmbient error:&setCategoryError]; 
       self.backgroundMusicPlaying = NO; 
      } else { 
       [self.audioSession setCategory:AVAudioSessionCategoryAmbient error:&setCategoryError]; 
      } 
      if (setCategoryError) { 
       NSLog(@"Error setting category! %ld", (long)[setCategoryError code]); 
      } 
     } 

     - (void)configureAudioPlayer { 
      // Create audio player with background music 
      NSString *backgroundMusicPath = [[NSBundle mainBundle] pathForResource:@"background-music-aac" ofType:@"caf"]; 
      NSURL *backgroundMusicURL = [NSURL fileURLWithPath:backgroundMusicPath]; 
      self.backgroundMusicPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:backgroundMusicURL error:nil]; 
      self.backgroundMusicPlayer.delegate = self; // We need this so we can restart after interruptions 
      self.backgroundMusicPlayer.numberOfLoops = -1; // Negative number means loop forever 
     } 

     - (void)configureSystemSound { 
      // This is the simplest way to play a sound. 
      // But note with System Sound services you can only use: 
      // File Formats (a.k.a. audio containers or extensions): CAF, AIF, WAV 
      // Data Formats (a.k.a. audio encoding): linear PCM (such as LEI16) or IMA4 
      // Sounds must be 30 sec or less 
      // And only one sound plays at a time! 
      NSString *pewPewPath = [[NSBundle mainBundle] pathForResource:@"pew-pew-lei" ofType:@"caf"]; 
      NSURL *pewPewURL = [NSURL fileURLWithPath:pewPewPath]; 
      AudioServicesCreateSystemSoundID((__bridge CFURLRef)pewPewURL, &_pewPewSound); 
     } 

     #pragma mark - AVAudioPlayerDelegate methods 

     - (void) audioPlayerBeginInterruption: (AVAudioPlayer *) player { 
      //It is often not necessary to implement this method since by the time 
      //this method is called, the sound has already stopped. You don't need to 
      //stop it yourself. 
      //In this case the backgroundMusicPlaying flag could be used in any 
      //other portion of the code that needs to know if your music is playing. 

      self.backgroundMusicInterrupted = YES; 
      self.backgroundMusicPlaying = NO; 
     } 

     - (void) audioPlayerEndInterruption: (AVAudioPlayer *) player withOptions:(NSUInteger) flags{ 
      //Since this method is only called if music was previously interrupted 
      //you know that the music has stopped playing and can now be resumed. 
      [self tryPlayMusic]; 
      self.backgroundMusicInterrupted = NO; 
     } 

     @end 

// UPDATE /////////////

이 예제와 같이 (hayageek.com/ios-long-running-background-task) 장기 실행 작업을 구현했습니다. 이제 사운드 파일은 백그라운드에서 재생되지만 시뮬레이터에서만 재생됩니다. ios7 전화 및 ios8 전화에서 시도했지만 사운드 파일을 재생하지 못합니까?

답변

0

솔루션이

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil]; 
0

이 경우 Apple Documentation을 보셨습니까? 문서에 지정된대로 장기 실행 작업을 구현해야합니다.

+0

그것은 긴 실행한다고 언급하는 작업이며 당신이 VOIP, 위치 또는 오디오 체크 박스 (PLIST 물건을) 확인해야했다. 장기간 실행하는 방법을 말하는 것은 아닙니다. 사운드를 재생하는 것은 장기간 실행해야합니다. 그러나 그것은 심지어 소리를 재생하기 시작하지 않습니다. – jdog

+0

이 http://hayageek.com/ios-long-running-background-task/을 찾았지만 appdelegate가 아니라 다른 사용자 정의 파일에서 사용중인 LocationManager를 사용하고 있습니다. 내 응용 프로그램에서 두 번 시작하는 것이 아플까? 누구든지 시도해 볼 또 다른 장기 실행 과제가 있습니까? – jdog

+0

나는 당신을 위해 요지를 만들었습니다. 사용해보기 : https://gist.github.com/EricAnderson-AAI/c4c6b2627d608c4e099b –

관련 문제