在AVAudioplayer中,一次播放多首歌曲。如何一次修复单首歌曲播放

时间:2014-03-24 07:28:42

标签: ios iphone objective-c

我正在尝试以编程方式创建AVAudioplayer。音频播放器成功播放。但是我有一些问题。我在UITableview中显示12个音频项目。如果我点击应该导航音频播放器视图控制器的第一个项目。并且我点击歌曲将播放的播放按钮。如果我点击后退按钮,歌曲会连续播放。但如果我再次点击同一项目音频视图控制器,视图将显示初始状态,如进度条不应移动,当前时间和歌曲持续时间为空。但歌曲不断播放。 还有另外一个问题。如果我点击相应歌曲将播放的第一个项目。我不应该点击任何传递按钮。我点击后退按钮并点击第二个项目。如果我点击第二个项目,音频视图控制器将显示。我点击播放按钮歌曲显示。在后台第一首歌和第二首歌也在播放。这是我的第二个问题。如何解决这两个问题。请帮助我任何身体。

-(void)playOrPauseButtonPressed:(id)sender
{
    if(playing==NO)
    {
        [playButton setBackgroundImage:[UIImage imageNamed:@"Pause.png"] forState:UIControlStateNormal];
        // Here Pause.png is a image showing Pause Button.
        NSError *err=nil;
        AVAudioSession *audioSession=[AVAudioSession sharedInstance];
        [audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
        NSLog(@"%@ %d",urlsArray,selectedIndex);
        NSString *sourcePath=[urlsArray objectAtIndex:selectedIndex];
        NSData *objectData=[NSData dataWithContentsOfURL:[NSURL URLWithString:sourcePath]];
        audioPlayer = [[AVAudioPlayer alloc] initWithData:objectData error:&err];
        audioPlayer.numberOfLoops = 0;
        [audioPlayer prepareToPlay];
        audioPlayer.delegate=self;
        [audioPlayer play];
        playing=YES;
    }
    else if (playing==YES)
    {
        [playButton setBackgroundImage:[UIImage imageNamed:@"play.png"] forState:UIControlStateNormal];
        [audioPlayer pause];
        playing=NO;
    }
    if (self.audioPlayer)
    {
        [self updateViewForPlayerInfo];
        [self updateViewForPlayerState];
        [self.audioPlayer setDelegate:self];
    }
}
-(void)updateViewForPlayerInfo
{
    self.songDuration.text = [NSString stringWithFormat:@"%d:%02d", (int)self.audioPlayer.duration / 60, (int)self.audioPlayer.duration % 60, nil];
    NSLog(@"%f", self.audioPlayer.duration);
    self.progressBar.maximumValue = self.audioPlayer.duration;
    self.volumeSlider.value = self.audioPlayer.volume;
}
-(void)updateViewForPlayerState
{
    [self updateCurrentTime];
    if (self.updatedTimer)
    {
        [self.updatedTimer invalidate];
    }
    if (self.audioPlayer.playing)
    {
        self.updatedTimer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(updateCurrentTime) userInfo:self.audioPlayer repeats:YES];
    }
}
-(void)updateCurrentTime
{
    //NSLog(@"self.audioPlayer.currentTime = %f", self.audioPlayer.currentTime);
    self.currentTime.text = [NSString stringWithFormat:@"%d:%02d", (int)self.audioPlayer.currentTime / 60, (int)self.audioPlayer.currentTime % 60, nil];
    self.progressBar.value = self.audioPlayer.currentTime;
}
-(void)volumeSliderMoved:(UISlider *)sender
{
    self.audioPlayer.volume=[sender value];
}

3 个答案:

答案 0 :(得分:0)

简而言之,以下是:

  1. 点击表格单元格
  2. 您创建了一个音频播放器视图控制器
  3. 您播放音频 - 您的音频播放器本身因某些原因而被保留(不清楚为什么 - 您使用ARC吗?)
  4. 您单击后退按钮 - 音频播放器视图控制器已发布
  5. 再次单击表格单元格 - 并使用它自己的播放器创建一个新的音频播放器视图控制器!
  6. 基本上 - 如果您希望前一首歌继续播放,即使您退出音频播放器视图控制器 - 并且只有一个播放器用于音频 - 我会将其保存在将管理播放器的单例类中,或者应用代表的属性。

    这样 - 当您进入音频播放器视图控制器时 - 它将检查以下内容:

    1. 如果玩家不存在 - 创建它并为其指定项目 - 准备好玩
    2. 如果玩家存在,但它是相同的项目 - 只需更新控件以显示其当前的播放状态。
    3. 如果玩家存在,但它是另一个项目 - 要么不更新控件 - 当用户点击播放时 - 替换播放器中的项目并开始更新控件 - 或者将歌曲停止为显示音频播放器视图控制器。 (由你决定 - 我显然不知道你的应用程序的设计)

答案 1 :(得分:0)

我认为问题出在这里

audioPlayer = [[AVAudioPlayer alloc] initWithData:objectData error:&err];

每次创建audioPlayer对象时。所以我的建议是在创建像这样的对象之前检查audioPlayer

if(audioPlayer)
{
audioPlayer.delegate=nil;
audioPlayer=nil;
}

然后创建对象。

答案 2 :(得分:0)

在使用AVAudioPlayer时,我使用一个属性来跟上播放器。基于查看您的代码,我不清楚您是在保持玩家,还是每次都没有实例化新实例。根据您的描述,听起来您正在实例化一个新实例 - 不要以为您想要它。

所以在你的.h文件中,就像这样:

@property (nonatomic, strong) AVAudioPlayer *myAVAudioPlayer;

然后在你的.m文件中找到相应的@synthesize。

当您想要从一首歌曲移动到下一首歌曲时,只需停止播放当前歌曲 - 然后使用init为您的self.myAVAudioPlayer属性重新加载新的URL。然后,您必须再次为AVAudioPlayer选项调用prepareToPlay方法。

你可能会通过不管理有关游戏的变量来使自己变得更容易(看起来你是从你的帖子那样做的)。使用您的属性并通过访问该属性的setter / getter来检查播放器的状态:

if(!self.myAVAudioPlayer)
{
// allocate and initialize using the code you have

[self.myAVAudioPlayer prepareToPlay];
} else 

if  ([self.myAVAudioPlayer isPlaying])
{
//do whatever you need for isPlaying - looks like pause
} else

if (![self.myAVAudioPlayer isPlaying])
{
// do whatever you need to do if the player isn't playing when the button is pressed
// at this point you will likely just re-init with a new URL and reset other items
// don't forget to call -prepareToPlay again
}

这是一个利用AVPlayerItem的另一种方法的链接 - >点击https://stackoverflow.com/a/22254588/3563814