GTVideoPlayer 源码:
GTVideoPlayer.h
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
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 <AVFoundation/AVFoundation.h>
@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<NSKeyValueChangeKey, id> *)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 发布!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。