AVPlayer在视图控制器加载时更新UISlider的当前时间

9

我正在使用 AVPlayer 播放歌曲。我为我的媒体播放器和初始化创建了一个单独的视图控制器,我在同一个视图控制器中使用的所有方法(播放、暂停、重复、随机播放)都在那里。

我这样更新滑块:

[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(sliderUpdate:) userInfo:nil repeats:YES];`


- (void) sliderUpdate:(id) sender{
    int currentTime =   (int)((song.player.currentTime.value)/song.player.currentTime.timescale);
    slider.value=currentTime;
    NSLog(@"%i",currentTime);

    song.currentTime=currentTime;
    int currentPoint=(int)((song.player.currentTime.value)/song.player.currentTime.timescale);
    int pointMins=(int)(currentPoint/60);
    int pointSec=(int)(currentPoint%60);

    NSString *strMinlabel=[NSString stringWithFormat:@"%02d:%02d",pointMins,pointSec];
    lblSlidermin.text=strMinlabel;
    song.strslidermin=strMinlabel;
}

当我退出视图控制器并再次进入时,歌曲正在播放,但问题是滑块没有更新。因此,我创建了一个单例类来分配当前播放的歌曲详细信息。在滑块更新中,我为单例类变量指定了playerCurrentTime(滑块当前值)。在我的viewdidload方法中,我像这样进行了分配:

if (song.isPlaying==NO) {
    [self prePlaySong];
}else{
    lblAlbum.text=song.currentAlbum;
    lblArtist.text=song.currentArtist;
    lblSong.text=song.currentSong;
    slider.value=song.currentTime;
    slider.maximumValue=song.sliderMax;
    slider.minimumValue=song.sliderMin;
    imgSong.image=song.songImage;
    [btnMiddle setBackgroundImage:[UIImage imageNamed:@"pause.png"] forState:UIControlStateNormal];
}

但是滑块没有更新。为什么会这样,我该如何解决这个问题?
2个回答

22

您不应该使用计时器,AVPlayer提供了一个API可以观察时间。

注册一个观察者(例如在viewWillAppear中),像这样:

CMTime interval = CMTimeMakeWithSeconds(1.0, NSEC_PER_SEC); // 1 second
self.playbackTimeObserver =
    [self.player addPeriodicTimeObserverForInterval:interval 
                                              queue:NULL usingBlock:^(CMTime time) {
    // update slider value here...
}];

要注销观察者(例如在viewDidDisappear中),请执行以下操作:

[self.player removeTimeObserver:self.playbackTimeObserver];

希望能有所帮助。


2

Swift 3 版本。

注册观察者:

// Invoke callback every second
let interval = CMTime(seconds:1.0, preferredTimescale: CMTimeScale(NSEC_PER_SEC))

// Queue on which to invoke the callback
let mainQueue = DispatchQueue.main

// Keep the reference to remove
self.playerObserver = player.addPeriodicTimeObserver(forInterval: interval, queue: mainQueue) { time in
    print(time)
}

移除观察者:

if let observer = self.playerObserver {
    self.player.removeTimeObserver(observer)
    self.playerObserver = nil
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接