欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

iOS开发——AVPlayer自定义播放器(持续更新,学习中)

程序员文章站 2022-06-24 18:33:47
文章目录一、 前言二、相关知识点2.1 AVplayerItem2.2 AVplayer2.3 AVPlayerLayer三、代码部分四、demo一、 前言边学边记录AVPlayer封装一个功能十分 全的自定义播放器,目前在学习阶段,demo和文章会根据学习进度与总结情况去更新,欢迎各位批评指正。二、相关知识点AVPlayer本身并不显示视频!需要一个AVPlayerLayer播放层来显示视频,然后添加到父视图的layer中。AVPlayer只负责视频管理和调控!而视频资源是由AVPlayerI...

一、 前言

边学边记录AVPlayer封装一个功能十分 全的自定义播放器,目前在学习阶段,demo和文章会根据学习进度与总结情况去更新,欢迎各位批评指正。

二、相关知识点

  • AVPlayer本身并不显示视频!需要一个AVPlayerLayer播放层来显示视频,然后添加到父视图的layer中。
  • AVPlayer只负责视频管理和调控!而视频资源是由AVPlayerItem提供的,每个AVPlayerItem对应一个视频地址。
  • 工程内需要引入AVFoundation库
  • 持续补充……

2.1 AVplayerItem

(instancetype)playerItemWithURL:(NSURL *)URL; 初始化视频资源方法
duration 视频总时长
status 视频资源的状态 (需要监听的属性)
loadedTimeRanges 在线视频的缓冲进度 (需要监听的属性)
playbackBufferEmpty 进行跳转,无缓冲 (可选监听)
playbackLikelyToKeepUp 进行跳转,有缓冲 (可选监听)

2.2 AVplayer

(void) play;
(void) pause; 播放暂停
(void) seekToTime:(CMTime)time;跳转到指定时间
(CMTime) currentTime;获取当前播放进度
(void)removeTimeObserver:(id)observer;移除监听 (销毁播放器的时候调用)
(void)replaceCurrentItemWithPlayerItem:(nullable AVPlayerItem *)item;切换视频资源

2.3 AVPlayerLayer

videoGravity 视频的填充方式

  1. AVQueuePlayer:这个是用于处理播放列表的操作,待学习…

三、代码部分

  1. 声明相关属性
// AVAsset对象
@property (nonatomic, strong) AVAsset *videoAsset;
// 播放器对象
@property (nonatomic, strong) AVPlayer *player;
// 播放属性 
@property (nonatomic, strong) AVPlayerItem *playerItem; 
// 播放容器,用于放playerlayer
@property (nonatomic, strong) UIView *videoView;  
// 用于播放的layer
@property (nonatomic, strong) AVPlayerLayer *playLayer; 
  1. 实现播放器
- (UIView *)createPlayViewFrame:(CGRect)frame withStringURL:(NSString *)stringURL isLocalFile:(BOOL)isTrue{
    if (isTrue == YES){
        self.videoAsset = [[AVURLAsset alloc] initWithURL:[NSURL fileURLWithPath:stringURL] options:nil];
    } else  {
        self.videoAsset = [[AVURLAsset alloc] initWithURL:[NSURL URLWithString:stringURL] options:nil];
    }
    
    self.playerItem = [AVPlayerItem playerItemWithAsset:self.videoAsset];
    // 添加观察者
    [self.playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
    
    // 获取当前视频的尺寸
    [self getVideoSize:self.videoAsset];
    
    self.player = [AVPlayer playerWithPlayerItem:self.playerItem];
    // 监听是否 播放完毕
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playBackFinished:withBlock:) name:AVPlayerItemDidPlayToEndTimeNotification object:self.playerItem];
    
    
    self.playLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
    self.playLayer.frame = frame;
    // 填充模式
    self.playLayer.videoGravity = AVLayerVideoGravityResizeAspect;
    
    UIView *videoView = [[UIView alloc] initWithFrame:frame];
    [videoView.layer addSublayer:self.playLayer];
    
    return videoView;
}
  1. 调用
- (void)viewDidLoad {
    [super viewDidLoad];
    UIView *videoView = [[UIView alloc] initWithFrame:self.view.frame];
    videoView = [[SMZVideoManager sharedInstance] createPlayViewFrame:CGRectMake(0, 0, creenWidth, creenHeight) withStringURL:videoUrl isLocalFile:NO];
    [self.view addSubview:videoView];
    // 也可以将视频播放完毕的监听加在这里,需要将manager中的移除掉
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playBackFinished:) name:AVPlayerItemDidPlayToEndTimeNotification object:[[SMZVideoManager sharedInstance] getCurrentPlayerItem]];
    
    [[SMZVideoManager sharedInstance] startVideo];
}
  1. 观察者监听相关
#pragma mark - 观察者相关
- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
    if ([keyPath isEqualToString:@"status"]){
        AVPlayerItem *playItem = (AVPlayerItem *)object;
        if (playItem.status ==  AVPlayerStatusReadyToPlay){
            // 可以播放
        } else if (playItem.status == AVPlayerStatusFailed){
            // 失败
        } else {
            // 未知错误AVPlayerStatusUnknown
        }
    }
}

- (void)playBackFinished:(NSNotification *)notification withBlock:(void (^)(void))code{
    // 播放完毕的操作,这里 提供重新播放的能力
    self.playerItem = [notification object];
    [self.playerItem seekToTime:kCMTimeZero completionHandler:nil];
    code();
}

四、demo

文章只是记录一下相关部分代码,会在慢慢进行改善。
demo会持续更新,完善功能 ,一次比一次好。

本文地址:https://blog.csdn.net/qq_42009978/article/details/107599374

相关标签: iOS开发