美文网首页
AVPlayer 当前播放时间问题 、 seek

AVPlayer 当前播放时间问题 、 seek

作者: monkey姜啦 | 来源:发表于2019-07-08 10:25 被阅读0次

一、AVPlayer 播放时间问题

AVPlayer 播放时间、总时间提供了两种方式去获取,
一个是监听AVPlayerItem 的currentTime属性值变化,我们可以通过实时监听到的时间变化去做先关UI的改变,所有的监听都要在播放器即将销毁时移除监听,否则会收到一个大的惊喜,crush

- (void)abserverCurrentPlayerItem{
// 监听当前状态
    [self.playerItem addObserver:self forKeyPath:@"status"
                    options:NSKeyValueObservingOptionNew
                    context:nil];
    // 监听当前播放时间变化
    [self.playerItem addObserver:self
                 forKeyPath:@"loadedTimeRanges"
                    options:NSKeyValueObservingOptionNew
                    context:nil];
    // 播放完成
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didPlayToEndTime:) name:AVPlayerItemDidPlayToEndTimeNotification object:self.playerItem];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{
    if ([keyPath isEqualToString:@"status"]) {
        if (self.playerItem.status == AVPlayerItemStatusReadyToPlay) {
    
        }
        else if (self.playerItem.status == AVPlayerItemStatusFailed) {
            self.state = CLPlayerStateFailed;
        }
    } else if ([keyPath isEqualToString:@"loadedTimeRanges"]) {
        // 计算缓冲进度
        CMTime duration             = self.playerItem.duration;
        CGFloat totalDuration       = CMTimeGetSeconds(duration);
    } else if ([keyPath isEqualToString:@"playbackBufferEmpty"]) {
        // 当缓冲是空的时候
        NSLog(@"当缓冲是空的时候");
        if (self.playerItem.isPlaybackBufferEmpty) {
            [self bufferingSomeSecond];
        }
    } else if ([keyPath isEqualToString:@"playbackLikelyToKeepUp"]) {
        // 当缓冲好的时候
        NSLog(@"当缓冲好的时候");
        if(!self.isStop){
            if (!_isEnd) {
                [self playVideo];
                self.state = CLPlayerStatePlaying;
            }
        }
    }
}

另一个是播放器的回调,能在回调中获取当前的播放进度和总时长,相对于监听的方式,,我在项目中使用的是这个,感觉比较方便。

- (void) abserverCurrentPlayerTime{
    __weak typeof(self)weakSelf = self;
    [self.player addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(1,1) queue:nil usingBlock:^(CMTime time) {
        __strong typeof(weakSelf)self = weakSelf;
        AVPlayerItem* currentItem = self.player.currentItem;
        NSArray* loadedRanges = currentItem.seekableTimeRanges;
        if (loadedRanges.count > 0){
            CMTimeRange range = [[loadedRanges objectAtIndex:0] CMTimeRangeValue];
            NSTimeInterval duration = CMTimeGetSeconds(range.start) + CMTimeGetSeconds(range.duration);
            // 当前播放总时间
            NSTimeInterval curDuration = CMTimeGetSeconds(time);
            NSLog(@"eidt player:%g", curDuration);
            self.model.curTime = curDuration;
            self.model.totalTime = duration;
            if (self.callBack) {
                self.callBack(self.model);
            }
        }
    }];
    // 播放完成
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didPlayToEndTime:) name:AVPlayerItemDidPlayToEndTimeNotification object:self.playerItem];
}

二、AVPlayer seek问题

//seek到第一帧
[self.player seekToTime:CMTimeMake(0, 1)];
[self.player seekToTime:kCMTimeZero toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero];

//seek 到滑动条滑动到位置
- (void)setProgress:(float)progress{
    _progress = progress;
    [self.player seekToTime:CMTimeMake(progress, 1)];
}

//另一个seek的方法也是比较推荐的方法,当seek完成之后再做播放的操作
       [self.player seekToTime:kCMTimeZero toleranceBefore:(CMTime)kCMTimeZero toleranceAfter:kCMTimeZero completionHandler:^(BOOL finished) {
            [self.player play];
        }];
      

//弄了很久的问题:因为在外部的block中调用了play方法,使得seek的操作可能没有在主线程中调用,所以导致seek一直没起作用,如下放在主线程调用就OK了。
- (void)play{
    dispatch_async(dispatch_get_main_queue(), ^{
        if (self.model.isEnd) {
             [self.player seekToTime:kCMTimeZero toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero];
        }
        [self.player play];
        self.model.isEnd = NO;
        self.model.isPause = NO;
        if (self.callBack) {
            self.callBack(self.model);
        }
    });
}

相关文章

  • AVPlayer 当前播放时间问题 、 seek

    一、AVPlayer 播放时间问题 AVPlayer 播放时间、总时间提供了两种方式去获取,一个是监听AVPlay...

  • AVPlayer实现边下边播

    声明两个对象,avplayer是播放器,avplayeritem是播放条目信息 处理观察者 可用seek方法跳转指...

  • 使用AVPlayer播放在线音乐

    1、创建AVPlayer播放器 2、播放 3、暂停 4、播放状态监听 处理状态 最后别忘了移除KVO 5、更新当前...

  • Swift 播放url 和本地 音频文件

    avplayer 播放URL 示例中url 地址,不对 AVAudioPlayer 播放 avplayer 播放本...

  • iOS AVPlayer监听视频播放进度

    AVPlayer视频播放时 我们常常需要获取当前视频的播放进度 来自定义一些操作 比如重复播放 播放结束后弹出广告...

  • AVPlayer 视频播放seek 导致视频卡住不播放

    iOS开发中经常视频开发,使用AV Foundation 提供的AVPlayer播放视频是,需要通过进度条进行拖拽...

  • iOS 视频播放的那点事

    AVPlayer视频播放 1、初始化AVPlayer + (instancetype)playerWithURL:...

  • 音视频

    最近做了一个用AVPlayer来实现的视频播放 主要功能有 播放 暂停 快进 后退 实时更新当前时间 重播 刚开...

  • avplayer

    参考1.iOS通过AVPlayer打造自己的视频播放器2.基于 AVPlayer 自定义播放器3.AVPlayer...

  • iOS 视频播放

    方式1:AVPlayer 通过AVPlayer播放视频,视频播放样式如上图所示。可以看到没有对视频播放的控制(暂停...

网友评论

      本文标题:AVPlayer 当前播放时间问题 、 seek

      本文链接:https://www.haomeiwen.com/subject/vhunhctx.html