iOS - AVAudioPlayer在后台播放时不会继续播放下一首歌曲

Kev*_*ers 10 background touch avaudioplayer ios avaudiosession

所以我有一个应用程序播放一堆歌曲,而用户可以浏览漫画书.我使用AVAudioPlayer,我将它设置为按设定顺序播放歌曲.所以当一首歌结束时,下一首歌将播出.当应用程序打开时,这可以完美运行.当应用程序在后台时出现问题.我将应用程序设置为在后台播放,并且工作正常.因此,当用户按下主屏幕时,音乐继续播放.当歌曲结束时会出现问题,假设播放应用程序打开时播放下一首歌曲.相反没有任何反应 根据我的NSLog语句,正在调用正确的方法,但没有任何反应.这是我的代码:

- (void)audioPlayerDidFinishPlaying: (AVAudioPlayer *)player successfully: (BOOL) flag {

NSLog(@"Song finished");

if ([songSelect isEqualToString: @"01icecapades"]) {
    isPlay = @"yes";
    songSelect = @"02sugarcube";
    imageSelect = @"playbanner02";
    [self performSelector:@selector(triggerSong) withObject:nil afterDelay:0];
    [self performSelector:@selector(triggerBanner) withObject:nil afterDelay:0];
}
else if ([songSelect isEqualToString: @"02sugarcube"]) {
    isPlay = @"yes";
    songSelect = @"03bullets";
    imageSelect = @"playbanner03";
    [self performSelector:@selector(triggerSong) withObject:nil afterDelay:0];
    [self performSelector:@selector(triggerBanner) withObject:nil afterDelay:0];
}
else if ([songSelect isEqualToString: @"03bullets"]) {
    isPlay = @"yes";
    songSelect = @"04satanama";
    imageSelect = @"playbanner04";
    [self performSelector:@selector(triggerSong) withObject:nil afterDelay:0];
    [self performSelector:@selector(triggerBanner) withObject:nil afterDelay:0];
}
else if ([songSelect isEqualToString: @"04satanama"]) {
    isPlay = @"yes";
    songSelect = @"05uglyjoke";
    imageSelect = @"playbanner05";
    [self performSelector:@selector(triggerSong) withObject:nil afterDelay:0];
    [self performSelector:@selector(triggerBanner) withObject:nil afterDelay:0];
}
else if ([songSelect isEqualToString: @"05uglyjoke"]) {
    isPlay = @"yes"; 
    songSelect = @"01icecapades";
    imageSelect = @"playbanner01";
    [self performSelector:@selector(triggerSong) withObject:nil afterDelay:0];
    [self performSelector:@selector(triggerBanner) withObject:nil afterDelay:0];
}}
Run Code Online (Sandbox Code Playgroud)

以上是识别正在播放哪首歌曲的代码,然后设置正确的歌曲.然后它触发另一个设置播放器的方法.

- (void)triggerSong {
NSLog(@"triggerSong called");
NSString       *path;
NSError        *error;
// Path the audio file
path = [[NSBundle mainBundle] pathForResource:songSelect ofType:@"mp3"];
// If we can access the file...
if ([[NSFileManager defaultManager] fileExistsAtPath:path]) 
{    
    // Setup the player
    player = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:&error];
    //player = [initWithContentsOfURL:[NSURL fileURLWithPath:path] error:&error];
    [player setDelegate: self];
    // Set the volume (range is 0 to 1)
    player.volume = 1.0f;     
    [player prepareToPlay];
    [player setNumberOfLoops:0];
    [player play];
    NSLog(@"player play");
    [error release];
    player.delegate = self;
    // schedules an action every second for countdown
    [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(updateTimeLeft) userInfo:nil repeats:YES];
}}
Run Code Online (Sandbox Code Playgroud)

现在我假设这不是最好的方法,但是当应用程序处于前台状态时它会很好用.我一直在查看文档,我似乎无法找到这个问题的原因.我希望有人能够看到我的方法出错.就像我之前说过的那样,triggerSong方法中的两个NSLog被调用,所以我看不出为什么没有调用AVAudioPlayer(播放器).

另外我在info.plist中有正确的设置,我在viewDidLoad中有这个:

//Make sure the system follows our playback status
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
[[AVAudioSession sharedInstance] setActive: YES error: nil];
Run Code Online (Sandbox Code Playgroud)

感谢您的任何见解.非常感激.

Squ*_*tch 27

相关讨论

简短的回答:

您需要在第一个视图控制器的init或viewDidLoad方法中使用此代码:

[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
Run Code Online (Sandbox Code Playgroud)

长期答案:样品:

这是我的例子.和你一样,我开始使用的应用程序可以在后台播放音乐但在第一个剪辑结束后无法继续播放.我制作了原始Music.mp3的副本,并将其命名为Music2.mp3.我的意图是在Music.mp3结束后立即播放Music2.mp3(audioPlayerDidFinishPlaying :).我在背景任务中闲逛了一会儿,直到我完成了这项工作而没有后台任务:

-(id)init{
    self = [super initWithNibName:@"MediaPlayerViewController" bundle:nil];
    if(self){

        //Need this to play background playlist
        [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];

        //MUSIC CLIP
        //Sets up the first song...
        NSString *musicPath = [[NSBundle mainBundle] pathForResource:@"Music" ofType:@"mp3"];
        if(musicPath){
            NSURL *musicURL = [NSURL fileURLWithPath:musicPath];
            audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:musicURL error:nil]; 
            [audioPlayer setDelegate:self];
        }
    }
    return self;
}


-(IBAction)playAudioFile:(id)sender{

    if([audioPlayer isPlaying]){
        //Stop playing audio and change test of button
        [audioPlayer stop];
        [sender setTitle:@"Play Audio File" forState:UIControlStateNormal];
    }
    else{
        //Start playing audio and change text of button so
        //user can tap to stop playback
        [audioPlayer play];
        [sender setTitle:@"Stop Audio File" forState:UIControlStateNormal];
    }
}


-(void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{
    [audioButton setTitle:@"Play Audio File" forState:UIControlStateNormal];
    [playRecordingButton setTitle:@"Play Rec File" forState:UIControlStateNormal];

    //PLAY THE SECOND SONG
    NSString *musicPath2 = [[NSBundle mainBundle] pathForResource:@"Music2" ofType:@"mp3"];
    if(musicPath2){

        NSURL *musicURL2 = [NSURL fileURLWithPath:musicPath2];
        audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:musicURL2 error:nil];
        [audioPlayer setDelegate:self];
        NSLog(@"Play it again: \n%@", musicPath2);
        [audioPlayer play];
    } 
}
Run Code Online (Sandbox Code Playgroud)

最终结果是我的应用程序正在连续循环播放Music2.mp3,即使应用程序在后台.

  • 当我们使用远程URL播放音乐时,它也将不起作用,它会在背景中的一首歌结束后停止 (2认同)

Erk*_*ken 5

只是为了确认Squatch所说的,这也是Swift中的解决方案:

UIApplication.sharedApplication().beginReceivingRemoteControlEvents()
Run Code Online (Sandbox Code Playgroud)