在AVAudioplayer多首歌曲播放一次.如何修复单个歌曲播放的时间



我试图以编程方式创建AVAudioplayer。音频播放器播放成功。但我有一些问题。我在UITableview中显示12个音频项目。如果我点击第一项,它会导航到音频播放器视图控制器。然后我点击播放按钮,歌曲就会播放。如果我点击后退按钮,歌曲继续播放。但是如果我再次点击相同的项目音频视图控制器,视图将显示初始状态,如进度条不应该移动,当前时间和歌曲持续时间是空的。但歌曲不停地播放。还有一个问题。如果我点击第一个项目,相应的歌曲将播放。我不应该点击任何pass按钮。我点击后退按钮,然后点击第二项。如果我点击第二项音频视图控制器就会显示出来。我点击播放按钮,歌曲显示。在后台播放第一首歌和第二首歌。这是我的第二个问题。如何解决这两个问题。请任何人帮助我。

-(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];
}

我认为问题就在这里

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

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

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

然后创建对象。

简而言之,情况如下:

  1. 点击表格单元格
  2. 你创建了一个音频播放器视图控制器
  3. 你播放音频-你的音频播放器本身保留了一些原因(不清楚为什么-你使用ARC?)
  4. 你点击后退按钮-音频播放器视图控制器被释放
  5. 你再次点击表格单元格-并创建一个新的音频播放器视图控制器与它自己的播放器!

基本上-如果你想要之前的歌曲继续播放,即使你退出音频播放器视图控制器-并且只有一个播放器的音频-我会保持它在一个单一的类,将管理播放器,或作为一个应用程序委托的属性。

这样,当你进入Audio Player视图控制器时,它将检查以下内容:

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

在使用AVAudioPlayer时,我使用属性来跟上播放器。基于查看你的代码,我不清楚你是否让玩家留在身边,或者你是否每次都实例化一个新实例。根据你的描述,这听起来像你正在实例化一个新的实例-不要认为你想要这样。

在你的。h文件中,像这样:
@property (nonatomic, strong) AVAudioPlayer *myAVAudioPlayer;

,然后在你的。m文件中相应的@synthesize。

当您想从一首歌曲移动到下一首时,只需停止播放当前-然后使用init为您自己重新加载一个新的URL。myAVAudioPlayer财产。然后你必须为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

最新更新