view类:
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
@interface PlayViwe : UIView
@property(nonatomic,strong)AVPlayer *player;
@property(nonatomic,strong)UIView *bottom;
@property(nonatomic,strong)AVPlayerItem *playerItem;
@property(nonatomic,strong)UISlider *slider;
- (id)initWithFrame:(CGRect)frame WithVideoStr:(NSString *)videoStr;
- (void)PlayOrPause;
@end
#import "PlayViwe.h"
#import <AVFoundation/AVFoundation.h>
static void *PlayViewCMTimeValue = &PlayViewCMTimeValue;
static void *AVPlayerDemoPlaybackViewControllerStatusObservationContext;
@implementation PlayViwe
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
}
*/
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
- (id)initWithFrame:(CGRect)frame WithVideoStr:(NSString *)videoStr{
self = [super init];
if (self) {
self.frame = frame;
NSURL *sourceMovieURL = [NSURL fileURLWithPath:videoStr];
AVAsset *movieAsset = [AVURLAsset URLAssetWithURL:sourceMovieURL options:nil];
self.playerItem = [AVPlayerItem playerItemWithAsset:movieAsset];
self.player = [AVPlayer playerWithPlayerItem:self.playerItem];
AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
playerLayer.frame = self.layer.bounds;
playerLayer.videoGravity = AVLayerVideoGravityResizeAspect;
[self.layer addSublayer:playerLayer];
[self.player play];
self.bottom = [[UIView alloc]initWithFrame:CGRectMake(0, self.frame.size.height - 40, self.frame.size.width, 40)];
self.bottom.backgroundColor = [UIColor grayColor];
UIButton *playBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[playBtn addTarget:self action:@selector(PlayOrPause) forControlEvents:UIControlEventTouchUpInside];
playBtn.frame = CGRectMake(5, 5, 30, 30);
playBtn.backgroundColor = [UIColor redColor];
[self.bottom addSubview:playBtn];
[self addSubview:self.bottom];
self.slider = [[UISlider alloc]initWithFrame:CGRectMake(45, 5, 200, 30)];
self.slider.minimumValue = 0.0;
self.slider.maximumValue = CMTimeGetSeconds(movieAsset.duration);
self.slider.value = 0.0;//指定初始值
[self.slider addTarget:self action:@selector(updateValue:) forControlEvents:UIControlEventTouchUpInside];//设置响应事件
[self.bottom addSubview:self.slider];
// 单击的 Recognizer
UITapGestureRecognizer* singleRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTapFrom)];
singleRecognizer.numberOfTapsRequired = 1; // 单击
[self addGestureRecognizer:singleRecognizer];
[self.playerItem addObserver:self
forKeyPath:@"status"
options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
context:AVPlayerDemoPlaybackViewControllerStatusObservationContext];
[self initScrubberTimer];
}
return self;
}
- (double)duration
{
AVPlayerItem *playerItem = [[self player] currentItem];
if ([playerItem status] == AVPlayerItemStatusReadyToPlay)
return CMTimeGetSeconds([[playerItem asset] duration]);
else
return 0.f;
}
- (double)currentTime
{
return CMTimeGetSeconds([[self player] currentTime]);
}
- (void)setCurrentTime:(double)time
{
[[self player] seekToTime:CMTimeMakeWithSeconds(time, 1)];
}
- (void)PlayOrPause{
if ([[self player] rate] != 1.f) {
if ([self currentTime] == [self duration])
[self setCurrentTime:0.f];
[[self player] play];
} else {
[[self player] pause];
}
CMTime time = [self.player currentTime];
NSLog(@"%lld",self.playerItem.duration.value/self.playerItem.duration.timescale);
NSLog(@"%lld",time.value/time.timescale);
}
#pragma mark - 手势方法
- (void)handleSingleTapFrom{
[UIView animateWithDuration:0.5 animations:^{
if (self.bottom.alpha == 0.0) {
self.bottom.alpha = 1.0;
}else{
self.bottom.alpha = 0.0;
}
} completion:^(BOOL finish){
}];
}
#pragma mark - slider
- (void)updateValue:(UISlider *)slider{
[self.player seekToTime:CMTimeMakeWithSeconds(slider.value, 1)];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
/* AVPlayerItem "status" property value observer. */
if (context == AVPlayerDemoPlaybackViewControllerStatusObservationContext)
{
AVPlayerStatus status = [[change objectForKey:NSKeyValueChangeNewKey] integerValue];
switch (status)
{
/* Indicates that the status of the player is not yet known because
it has not tried to load new media resources for playback */
case AVPlayerStatusUnknown:
{
}
break;
case AVPlayerStatusReadyToPlay:
{
/* Once the AVPlayerItem becomes ready to play, i.e.
[playerItem status] == AVPlayerItemStatusReadyToPlay,
its duration can be fetched from the item. */
[self initScrubberTimer];
}
break;
case AVPlayerStatusFailed:
{
}
break;
}
}
}
#pragma maik - 监听
-(void)initScrubberTimer
{
double interval = .1f;
CMTime playerDuration = [self playerItemDuration];
if (CMTIME_IS_INVALID(playerDuration))
{
return;
}
double duration = CMTimeGetSeconds(playerDuration);
if (isfinite(duration))
{
CGFloat width = CGRectGetWidth([self.slider bounds]);
interval = 0.5f * duration / width;
}
NSLog(@"interva === %f",interval);
__weak typeof(self) weakSelf = self;
/* Update the scrubber during normal playback. */
[weakSelf.player addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(interval, NSEC_PER_SEC)
queue:NULL /* If you pass NULL, the main queue is used. */
usingBlock:^(CMTime time)
{
[self syncScrubber];
}];
}
/* Set the scrubber based on the player current time. */
- (void)syncScrubber
{
NSLog(@"syncScrubber");
CMTime playerDuration = [self playerItemDuration];
if (CMTIME_IS_INVALID(playerDuration))
{
self.slider.minimumValue = 0.0;
return;
}
double duration = CMTimeGetSeconds(playerDuration);
if (isfinite(duration))
{
float minValue = [self.slider minimumValue];
float maxValue = [self.slider maximumValue];
double time = CMTimeGetSeconds([self.player currentTime]);
NSLog(@"时间 :: %f",(maxValue - minValue) * time / duration + minValue);
[self.slider setValue:(maxValue - minValue) * time / duration + minValue];
}
}
- (CMTime)playerItemDuration
{
AVPlayerItem *playerItem = [self.player currentItem];
NSLog(@"%ld",playerItem.status);
if (playerItem.status == AVPlayerItemStatusReadyToPlay)
{
return([playerItem duration]);
}
return(kCMTimeInvalid);
}
@end
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@end
//视图控制器类
#import "ViewController.h"
#import "PlayViwe.h"
@interface ViewController (){
PlayViwe *_playView;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSString *videoStr = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"mp4"];
_playView = [[PlayViwe alloc] initWithFrame:self.view.bounds WithVideoStr: videoStr];
[self.view addSubview:_playView];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
//横竖屏
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
return YES;
}
@end