繁体   English   中英

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

[英]In AVAudioplayer multiple songs play at once.how to fix single song play at a time

我正在尝试以编程方式创建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];
}

简而言之,发生了以下情况:

  1. 您单击表格单元格
  2. 您创建一个音频播放器视图控制器
  3. 您播放音频-音频播放器本身由于某种原因被保留(不清楚原因-您使用的是ARC吗?)
  4. 您单击后退按钮-音频播放器视图控制器被释放
  5. 您再次单击表格单元格-并使用其自己的播放器创建一个新的音频播放器视图控制器!

基本上-如果您希望即使退出音频播放器视图控制器时仍继续播放上一首歌曲-并且只有一个音频播放器-我会将其放在管理播放器的singleton类中,或者作为应用程序委托。

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

  1. 如果不存在玩家-创建它并为其分配物品-准备开始游戏
  2. 如果存在玩家,但它是同一物品-只需更新控件以显示其当前的游戏状态即可。
  3. 如果存在播放器但它是另一项-不更新控件-并且当用户点击播放时-替换播放器中的该项并开始更新控件-或在显示音频播放器视图控制器时停止播放歌曲。 (由您决定-我显然不知道您的应用程序的设计)

我认为问题出在这里

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

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

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

然后创建对象。

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

因此,在您的.h文件中,如下所示:

@property (nonatomic, strong) AVAudioPlayer *myAVAudioPlayer;

然后在您的.m文件中使用相应的@synthesize。

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

通过不管理有关播放的变量,您可能会更轻松一些(看起来就像您从帖子中所做的那样)。 使用您的财产,并通过访问属性的设置器/获取器来检查玩家的状态:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM