视频播放 demo

GTVideoPlayer 源码:

GTVideoPlayer.h

#import 
#import 

NS_ASSUME_NONNULL_BEGIN

/**
 播放器
 */
@interface GTVideoPlayer : NSObject

/**
 全局播放器单例
 */
  (GTVideoPlayer *)Player;


/**
停止播放
*/
- (void)stopPlayer;

/**
 在指定View上 通过url播放视频
 */
- (void)playVideoWithUrl:(NSString *)videoUrl attachView:(UIView *)attachView;

@end

NS_ASSUME_NONNULL_END

GTVideoPlayer.m

#import "GTVideoPlayer.h"
#import 

@interface GTVideoPlayer ()

@property (nonatomic, strong, readwrite) AVPlayerItem *videoItem;
@property (nonatomic, strong, readwrite) AVPlayer *avPlayer;
@property (nonatomic, strong, readwrite) AVPlayerLayer *playerLayer;

@end

@implementation GTVideoPlayer

  (GTVideoPlayer *)Player {
    static GTVideoPlayer *player;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        player = [[GTVideoPlayer alloc] init];
    });
    return player;
}


- (void)stopPlayer {
    
    [_avPlayer pause];
    
    [self _stopPlay];
}

- (void)playVideoWithUrl:(NSString *)videoUrl attachView:(UIView *)attachView {

    //首先停止播放
    [self _stopPlay];

    NSURL *videoURL = [NSURL URLWithString:videoUrl];
    AVAsset *asset = [AVAsset assetWithURL:videoURL];
    _videoItem = [AVPlayerItem playerItemWithAsset:asset];

    //监听视频资源状态
    [_videoItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];

    //监听视频缓冲进度
    [_videoItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];

    //需要在状态变化后获取时间
    CMTime duration = _videoItem.duration;
    __unused CGFloat videoDuration = CMTimeGetSeconds(duration);

    //创建播放器
    _avPlayer = [AVPlayer playerWithPlayerItem:_videoItem];

    //监听播放器播放进度
    [_avPlayer addPeriodicTimeObserverForInterval:CMTimeMake(1, 1) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
         NSLog(@"播放进度:%@", @(CMTimeGetSeconds(time)));
     }];

    //展示playerLayer
    _playerLayer = [AVPlayerLayer playerLayerWithPlayer:_avPlayer];
    _playerLayer.frame = attachView.bounds;
    [attachView.layer addSublayer:_playerLayer];

    //接收播放完成Notification
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_handlePlayEnd) name:AVPlayerItemDidPlayToEndTimeNotification object:nil];
}

#pragma mark - private method

- (void)_stopPlay {
    //移除监听
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    [_videoItem removeObserver:self forKeyPath:@"status"];
    [_videoItem removeObserver:self forKeyPath:@"loadedTimeRanges"];

    //销毁播放器
    [_playerLayer removeFromSuperlayer];
    _videoItem = nil;
    _avPlayer = nil;
}

- (void)_handlePlayEnd {
    //播放完成后循环播放
    [_avPlayer seekToTime:CMTimeMake(0, 1)];
    [_avPlayer play];
}

#pragma mark - KVO

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {

    if ([keyPath isEqualToString:@"status"]) {
        if (((NSNumber *)[change objectForKey:NSKeyValueChangeNewKey]).integerValue == AVPlayerItemStatusReadyToPlay) {
            //在合适的时机开始播放
            [_avPlayer play];
        } else {
            //监控错误
        }
    } else if ([keyPath isEqualToString:@"loadedTimeRanges"]) {
        //缓冲进度监听
        NSLog(@"缓冲:%@", [change objectForKey:NSKeyValueChangeNewKey]);
    }
}

@end

效果图:

源码地址:

https://github.com/iJoeychang/VideoPlayerDemo

本文由博客一文多发平台 OpenWrite 发布!

你可能感兴趣的:(生活随笔)