KTVHTTPCache + AVPlayerLayer
objectivec
复制代码
#import "AVPlayerVC.h"
#import "AVFoundation/AVFoundation.h"
#import "KTVHTTPCache/KTVHTTPCache.h"
@interface AVPlayerVC ()
@end
@implementation AVPlayerVC
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor redColor];
// 1.启动本地代理服务器
[KTVHTTPCache proxyStart:nil];
// 视频链接
NSString * urlStr = @"https://media.w3.org/2010/05/sintel/trailer.mp4?ss=2";
// 设置URL映射
NSArray *components = [urlStr componentsSeparatedByString:@"?"];
[KTVHTTPCache encodeSetURLConverter:^NSURL *(NSURL *URL) {
NSLog(@"URL Filter reviced URL Old : %@", URL);
NSLog(@"URL Filter reviced URL New : %@", components[0]);
return [NSURL URLWithString:components[0]];
}];
NSURL *videoURL = [NSURL URLWithString:urlStr];
// 2.生成代理 URL
NSURL *proxyURL = [KTVHTTPCache proxyURLWithOriginalURL:videoURL];
AVPlayer *player = [AVPlayer playerWithURL:proxyURL];
AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:player];
playerLayer.frame = CGRectMake(0, 0, 300, 160);
[self.view.layer addSublayer:playerLayer];
[player play];
}
@end
- 但我懒得再去写一个自定义控制层,我想用ZFPlayer
- 先把KTVHTTPCache 简单封装成个单例
KTVHTTPCache 封装
objectivec
复制代码
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface KTVHTTPCacheManager : NSObject
+ (instancetype)sharedManager;
///是否开启URL映射
@property (nonatomic ,assign)BOOL isConverter;
///获取视频链接
- (NSURL *)createProxyURL:(NSString *)urlStr;
///当前缓存 xxMB
- (NSString *)getAllCacheLength;
///清理所有缓存
- (void)clearAllCache;
@end
NS_ASSUME_NONNULL_END
objectivec
复制代码
#import "KTVHTTPCacheManager.h"
#import "KTVHTTPCache/KTVHTTPCache.h"
@implementation KTVHTTPCacheManager
+ (instancetype)sharedManager {
static KTVHTTPCacheManager *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[self alloc] init];
// 1.启动本地代理服务器
NSError *error = nil;
[KTVHTTPCache proxyStart:&error];
if (error) {
NSLog(@"Error starting proxy: %@", error);
}
// 缓存最大限制
//[KTVHTTPCache cacheSetMaxCacheLength:1024*1024*500]; //500M
[KTVHTTPCache cacheSetMaxCacheLength:1024LL*1024LL*1024LL*2LL]; //2G
});
return sharedInstance;
}
- (NSURL *)createProxyURL:(NSString *)urlStr{
if (self.isConverter) {
// 设置URL映射
NSArray *components = [urlStr componentsSeparatedByString:@"?"];
[KTVHTTPCache encodeSetURLConverter:^NSURL *(NSURL *URL) {
return [NSURL URLWithString:components[0]];
}];
}
NSURL *videoURL = [NSURL URLWithString:urlStr];
// 2.生成代理 URL
NSURL *proxyURL = [KTVHTTPCache proxyURLWithOriginalURL:videoURL bindToLocalhost:NO];
return proxyURL;
}
- (NSString *)getAllCacheLength{
long long int length = [KTVHTTPCache cacheTotalCacheLength];
NSString * ll = [NSString stringWithFormat:@"%lld MB",length/1024/1024];
return ll;
}
- (void)clearAllCache{
[KTVHTTPCache cacheDeleteAllCaches];
}
@end
KTVHTTPCache + ZFPlayer/AVPlayer
- 使用KTVHTTPCacheManager
-
- 启动本地代理服务器,并设置URL映射
[KTVHTTPCacheManager sharedManager].isConverter = YES;
-
- 获取播放链接
NSURL *proxyURL = [[KTVHTTPCacheManager sharedManager] createProxyURL:@""];
-
- 然后把这个链接直接给ZFPlayer播放就行了
self.player.assetURL = proxyURL;
- 但是我遇到一个问题:
-
-
- 排查到卡住的时候播放状态已改变成正在播放了,但是未播放成功
-
- 我又不想去改 pod 中的源码,避免以后每次重新pod都要改
-
- 我的解决办法是,播放后延迟1秒,判断播放进度是否有回调,没有的话就重新调用一次播放
- 代码如下
ini
复制代码
#import "ZFPlayerVC.h"
#import <ZFPlayer/ZFAVPlayerManager.h>
//#import <ZFPlayer/ZFPlayerControlView.h>
#import "ZFKWPlayerControlView.h" //自定义控制层
#import <ZFPlayer/UIView+ZFFrame.h>
#import <ZFPlayer/UIImageView+ZFCache.h>
#import <ZFPlayer/ZFPlayerConst.h>
#import "ZFUtilities.h"
#import "KTVHTTPCacheManager.h"
@import AVKit;
@interface ZFPlayerVC ()
@property (nonatomic, strong) ZFPlayerController *player;
@property (nonatomic, strong) ZFAVPlayerManager *playerManager;
@property (nonatomic, strong) ZFKWPlayerControlView *controlView;
@property (nonatomic, strong) UIImageView *containerView;
@property (nonatomic, assign) NSTimeInterval currentTime;
@end
@implementation ZFPlayerVC
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.player.viewControllerDisappear = NO;
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
self.player.viewControllerDisappear = YES;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
self.currentTime = -1;
[self.view addSubview:self.containerView];
ZFAVPlayerManager *playerManager = [[ZFAVPlayerManager alloc] init];
playerManager.shouldAutoPlay = YES;
self.playerManager = playerManager;
/// 播放器相关
self.player = [ZFPlayerController playerWithPlayerManager:playerManager containerView:self.containerView];
self.player.controlView = self.controlView;
// 1.启动本地代理服务器
[KTVHTTPCacheManager sharedManager].isConverter = YES;
[self startPlay];
__weak typeof(self) weakSelf = self;
self.player.playerPrepareToPlay = ^(id<ZFPlayerMediaPlayback> _Nonnull asset, NSURL * _Nonnull assetURL) {
NSLog(@"playerPrepareToPlay");
};
self.player.playerReadyToPlay = ^(id<ZFPlayerMediaPlayback> _Nonnull asset, NSURL * _Nonnull assetURL) {
NSLog(@"playerReadyToPlay");
};
self.player.playerPlayTimeChanged = ^(id<ZFPlayerMediaPlayback> _Nonnull asset, NSTimeInterval currentTime, NSTimeInterval duration) {
weakSelf.currentTime = currentTime;
NSLog(@"playerPlayTimeChanged \n🐯 %f🐯 %f🐯 %.2f%%",currentTime,duration,currentTime/duration);
};
self.player.playerBufferTimeChanged = ^(id<ZFPlayerMediaPlayback> _Nonnull asset, NSTimeInterval bufferTime) {
NSLog(@"playerBufferTimeChanged");
};
self.player.playerPlayStateChanged = ^(id<ZFPlayerMediaPlayback> _Nonnull asset, ZFPlayerPlaybackState playState) {
NSLog(@"playerPlayStateChanged %lu",(unsigned long)playState);
};
self.player.playerLoadStateChanged = ^(id<ZFPlayerMediaPlayback> _Nonnull asset, ZFPlayerLoadState loadState) {
NSLog(@"playerLoadStateChanged");
};
self.player.orientationDidChanged = ^(ZFPlayerController * _Nonnull player, BOOL isFullScreen) {
/* // 使用YYTextView转屏失败
for (UIWindow *window in [UIApplication sharedApplication].windows) {
if ([window isKindOfClass:NSClassFromString(@"YYTextEffectWindow")]) {
window.hidden = isFullScreen;
}
}
*/
};
/// 播放完成
self.player.playerDidToEnd = ^(id _Nonnull asset) {
[weakSelf.player stop];
};
self.player.playerPlayFailed = ^(id<ZFPlayerMediaPlayback> _Nonnull asset, id _Nonnull error) {
NSLog(@"playerPlayFailed");
};
self.player.presentationSizeChanged = ^(id<ZFPlayerMediaPlayback> _Nonnull asset, CGSize size) {
NSLog(@"presentationSizeChanged");
};
UIButton * btn = [[UIButton alloc]initWithFrame:CGRectMake(0, 300, 100, 100)];
btn.backgroundColor = [UIColor redColor];
[btn addTarget:self action:@selector(startPlay) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
}
- (void)startPlay{
self.currentTime = -1;
NSString * urlStr = @"https://www.apple.com/105/media/us/iphone-x/2017/01df5b43-28e4-4848-bf20-490c34a926a7/films/feature/iphone-x-feature-tpl-cc-us-20170912_1280x720h.mp4";
// NSString * urlStr = @"https://media.w3.org/2010/05/sintel/trailer.mp4?ss=3";
NSURL *proxyURL = [[KTVHTTPCacheManager sharedManager] createProxyURL:urlStr];
self.player.assetURL = proxyURL;
self.player.assetURLs = @[proxyURL];
[self.player playTheIndex:0];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
if (self.currentTime == -1) {
NSLog(@"//延迟执行");
[self.player playTheIndex:0];
}
});
}
- (void)viewWillLayoutSubviews {
[super viewWillLayoutSubviews];
CGFloat x = 0;
CGFloat y = CGRectGetMaxY(self.navigationController.navigationBar.frame);
CGFloat w = CGRectGetWidth(self.view.frame);
CGFloat h = w*9/16;
self.containerView.frame = CGRectMake(x, y, w, h);
}
- (UIStatusBarStyle)preferredStatusBarStyle {
return UIStatusBarStyleDefault;
}
- (BOOL)prefersStatusBarHidden {
return NO;
}
- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation {
return UIStatusBarAnimationNone;
}
- (BOOL)shouldAutorotate {
return NO;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
- (ZFKWPlayerControlView *)controlView {
if (!_controlView) {
_controlView = [ZFKWPlayerControlView new];
_controlView.isCanSlider = YES;
_controlView.fastViewAnimated = YES;
_controlView.autoHiddenTimeInterval = 5;
_controlView.autoFadeTimeInterval = 0.5;
_controlView.prepareShowLoading = YES;
_controlView.prepareShowControlView = NO;
_controlView.showCustomStatusBar = YES;
}
return _controlView;
}
- (UIImageView *)containerView {
if (!_containerView) {
_containerView = [UIImageView new];
_containerView.backgroundColor = [UIColor blackColor];
}
return _containerView;
}
@end