基于AVPlayer的自定义视频播放器

最近一时兴起,就简单基于AVPlayer自定义了一个视频播放器,包含了自动播放、全屏播放、播放器进度控制等功能的封装,如果能对大家有所帮助,欢迎 Star !!!。

源码github地址: https://github.com/RockChanel/SelVideoPlayer

基于AVPlayer的自定义视频播放器_第1张图片
player.gif

1. 前言

  • AVPlayer是一个可以播放任何格式的全功能影音播放器,使用AVPlayer需导入AVFoundation.h。
  • 支持视频格式: WMV,AVI,MKV,RMVB,RM,XVID,MP4,3GP,MPG等。
  • 支持音频格式:MP3,WMA,RM,ACC,OGG,APE,FLAC,FLV等。
  • 在开发中,单纯使用AVPlayer类是无法显示视频的,要将视频层添加至AVPlayerLayer中,这样才能将视频显示出来。
  • AVPlayer并未提供视频操作组件,需用户自定义。

2. 自定义Player创建方式

SelPlayerConfiguration *configuration = [[SelPlayerConfiguration alloc]init];
configuration.shouldAutoPlay = YES;     //自动播放
configuration.supportedDoubleTap = YES;     //支持双击播放暂停
configuration.shouldAutorotate = YES;   //自动旋转
configuration.repeatPlay = YES;     //重复播放
configuration.statusBarHideState = SelStatusBarHideStateFollowControls;     //设置状态栏隐藏
configuration.sourceUrl = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_02.mp4"];     //设置播放数据源
configuration.videoGravity = SelVideoGravityResizeAspect;   //拉伸方式
    
CGFloat width = self.view.frame.size.width;
_player = [[SelVideoPlayer alloc]initWithFrame:CGRectMake(0, 100, width, 300) configuration:configuration];
[self.view addSubview:_player];

3. Player相关配置参数

/** 视频数据源 */
@property (nonatomic, strong) NSURL *sourceUrl;
/** 是否自动播放 */
@property (nonatomic, assign) BOOL shouldAutoPlay;
/** 视频拉伸方式 */
@property (nonatomic, assign) SelVideoGravity videoGravity;
/** 是否重复播放 */
@property (nonatomic, assign) BOOL repeatPlay;
/** 是否支持双击暂停或播放 */
@property (nonatomic, assign) BOOL supportedDoubleTap;
/** 是否支持自动转屏 */
@property (nonatomic, assign) BOOL shouldAutorotate;
/** 隐藏控制面板延时时间 缺省5s */
@property (nonatomic, assign) NSTimeInterval hideControlsInterval;
/** 全屏状态下状态栏显示方式 */
@property (nonatomic, assign) SelStatusBarHideState statusBarHideState; 

4. 创建AVPlayerLayer

- (void)_setupPlayer
{
    //AVPlayerItem是一个媒体资源管理类,负责数据的获取与分发
    self.playerItem = [AVPlayerItem playerItemWithURL:_playerConfiguration.sourceUrl];
    //AVPlayer负责解码数据
    self.player = [AVPlayer playerWithPlayerItem:self.playerItem];
    //AVPlayerLayer 是图层显示,用于数据的展示
    self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
    [self _setVideoGravity:_playerConfiguration.videoGravity];
    self.backgroundColor = [UIColor blackColor];

    /** 创建进度监听器 */
    [self createTimer];

    if (_playerConfiguration.shouldAutoPlay) {
        [self _playVideo];
    }
}

5. 屏幕翻转(全屏实现)

一般想要实现屏幕翻转只需要将LandscapeLeft 或 Landscape 开启即可。但是在本项目中只需要部分界面实现界面翻转,故并没有像常规设置一样,而是将屏幕翻转设置关闭。通过UIViewAnimation将播放器View进行旋转以实现屏幕翻转以及全屏播放。
基于AVPlayer的自定义视频播放器_第2张图片
Landscpe设置.png
//播放器翻转
[UIView animateWithDuration:duration animations:^{
        if (orientation == UIInterfaceOrientationLandscapeLeft){
            self.transform = CGAffineTransformMakeRotation(-M_PI/2);
        }else if (orientation == UIInterfaceOrientationLandscapeRight) {
            self.transform = CGAffineTransformMakeRotation(M_PI/2);
        }
    }completion:^(BOOL finished) {
        
    }];
//播放器还原
[UIView animateWithDuration:duration animations:^{
        self.transform = CGAffineTransformMakeRotation(0);
    }completion:^(BOOL finished) {
        
    }];

6. 播放进度控制

AVPlayer控制进度跳转有很seekToTime类似的进度调整方法。

- (void)seekToTime:(CMTime)time toleranceBefore:(CMTime)toleranceBefore toleranceAfter:(CMTime)toleranceAfter;

但是经过比较以上方法是最为精确的。

CGFloat totalTime = (CGFloat)_playerItem.duration.value / _playerItem.duration.timescale;
CGFloat dragedSeconds = totalTime * slider.value;
//转换成CMTime才能给player来控制播放进度
CMTime dragedCMTime = CMTimeMake(dragedSeconds, 1);
[_player seekToTime:dragedCMTime toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero];
NSInteger currentTime = (NSInteger)CMTimeGetSeconds(dragedCMTime);
[_playbackControls _setPlaybackControlsWithPlayTime:currentTime totalTime:totalTime sliderValue:slider.value];

除了以上所介绍的,项目中同时也封装了包括网络差视频缓冲机制、点击隐藏播放器控制面板、控制面板自动隐藏、播放失败重新播放等等。希望能够为大家自定义视频播放器提供方法与思路。

你可能感兴趣的:(基于AVPlayer的自定义视频播放器)