CustomAVPlayer

来源:互联网 发布:网络的英文单词怎么写 编辑:程序博客网 时间:2024/06/02 03:46


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







0 0
原创粉丝点击