码迷,mamicode.com
首页 > 其他好文 > 详细

AVPlayer

时间:2016-01-25 22:53:09      阅读:674      评论:0      收藏:0      [点我收藏+]

标签:

AVPlayer的功能很强大,既可以播放视频, 也可以播放音频, 既可以播放本地的, 也可以播放网络的;

下面是我封装的一个AVPlayer的Demo,在ViewController中实现

工程中的所有东西如下:

技术分享

创建一个PlayView类,PlayView.h中的代码如下

#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>

@class PlayView;
@protocol PlayViewDelegate  <NSObject>

@optional

//向左转全屏播放
- (void)fullScreen:(PlayView *)playerView;
//左全屏转回小窗口播放
- (void)normalScreen:(PlayView *)playerView;
//向右转全屏播放
- (void)turnRight:(PlayView *)playerView;
//右全屏转窗口播放
- (void)rtghtTurnBack:(PlayView *)playerView;
//播放失败
- (void)AVPlayerStatusFailed:(PlayView *)playerView;

@end

@interface PlayView : UIView

@property (nonatomic, strong) NSURL *url;
@property (nonatomic, strong) AVPlayer *player;
@property (nonatomic, strong) UIView *container;
@property (nonatomic, strong) AVPlayerItem *playerItem;
@property (nonatomic, strong) UIButton *playButton;
@property (nonatomic, strong) UIButton *fullButton;
@property (nonatomic, strong) UILabel *startTime;
@property (nonatomic, strong) UILabel *endTime;
@property (nonatomic, strong) UILabel *gang;
@property (nonatomic, strong) UISlider *progress;
@property (nonatomic, strong) UISlider *playableProgress;
@property (nonatomic, strong) UISlider *volume;
@property (nonatomic, strong) UIView *backView;
@property (nonatomic, strong) UIActivityIndicatorView *actiity;
@property (nonatomic, assign) BOOL isSliding;
@property (nonatomic, assign) BOOL istouched;
@property (nonatomic, strong) NSTimer *timer;
@property (nonatomic, strong)UIImageView *imageView;
@property (nonatomic, assign)BOOL _isSmall;
@property (nonatomic, strong) NSString *urlStr;
@property (nonatomic, strong)AVPlayerLayer *playerLayer;

@property (nonatomic, assign)id<PlayViewDelegate> delegate; 

@end

PlayView.m中的代码如下

#import "PlayView.h"

#define KScreenWidth [[UIScreen mainScreen]bounds].size.width
#define KScreenHeight [[UIScreen mainScreen]bounds].size.height

#define WIDTH [UIScreen mainScreen].bounds.size.width
#define HEIGHT [UIScreen mainScreen].bounds.size.height

@implementation PlayView

/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code
}
*/

- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        //设置活跃, 声音才有
        AVAudioSession *session = [AVAudioSession sharedInstance];
        [session setCategory:AVAudioSessionCategoryPlayback error:nil];
        [session setActive:YES error:nil];

        AVPlayerItem *playerItem = [AVPlayerItem playerItemWithURL:[NSURL URLWithString:self.urlStr]];
        self.player = [AVPlayer playerWithPlayerItem:playerItem];
//        _playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
//        _playerLayer.frame = self.frame;
//        [self.layer addSublayer:_playerLayer];
        
//        [self addSubview:self.backView];
        
        
//        UITapGestureRecognizer *singRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hideTap)];
//        [self addGestureRecognizer:singRecognizer];
//        _imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"play_1"]];
//        _imageView.frame = CGRectMake(KScreenWidth / 2 - 30, 340, 30, 30);
//        [self addSubview:self.imageView];
//        [self tap];
       
    }
    return self;
}


- (void)layoutSubviews {
    [super layoutSubviews];
    self.playerLayer.frame = self.bounds;
    [self.backView removeFromSuperview];
  
    //长条视图
    _backView = [[UIView alloc] initWithFrame:CGRectMake(0, self.bounds.size.height - WIDTH /10, self.bounds.size.width, WIDTH /10)];
    _backView.backgroundColor = [UIColor brownColor];
//    _backView.hidden = YES;
    [self addSubview:self.backView];
    
    //播放暂停按钮
    self.playButton = [UIButton buttonWithType:UIButtonTypeCustom];
    _playButton.frame = CGRectMake(WIDTH / 37.5, WIDTH / 70, WIDTH / 16.5, WIDTH / 16.5);
    _playButton.layer.cornerRadius = WIDTH / 16.5 / 2;
    _playButton.clipsToBounds = YES;
        [_playButton addTarget:self action:@selector(playClick) forControlEvents:UIControlEventTouchUpInside];
    [_playButton setImage:[UIImage imageNamed:@"pause"] forState:UIControlStateNormal];
    [_playButton setImage:[UIImage imageNamed:@"play"] forState:UIControlStateSelected];
    [self.backView addSubview:self.playButton];
    
    //进度条
    _playableProgress = [[UISlider alloc] initWithFrame:CGRectMake(40, 10, KScreenWidth - 100, 15)];
    _playableProgress.minimumTrackTintColor = [UIColor whiteColor];
    _playableProgress.maximumTrackTintColor = [UIColor clearColor];
    [_playableProgress setThumbImage:[[UIImage alloc] init] forState:UIControlStateNormal];
    [_playableProgress setThumbImage:[[UIImage alloc] init] forState:UIControlStateSelected];
    [self.backView addSubview:self.playableProgress];
    
    //状态条
    self.progress = [[UISlider alloc] initWithFrame:CGRectMake(40, 10, KScreenWidth - 100, 15)];
    _progress.minimumTrackTintColor = [UIColor whiteColor];
    _progress.maximumTrackTintColor = [UIColor clearColor];
    UIImage *image = [UIImage imageNamed:@"ThumBut"];
    [_progress setThumbImage:image forState:UIControlStateNormal];
    [_progress setThumbImage:image forState:UIControlStateSelected];
    [self.progress addTarget:self action:@selector(valueChange:other:) forControlEvents:UIControlEventValueChanged];
    [self.backView addSubview:self.progress];
    
    //起始时间 Label
    self.startTime = [[UILabel alloc] initWithFrame:CGRectMake(CGRectGetMaxX(self.progress.frame) - WIDTH / 6.25, 25, WIDTH / 6.25, WIDTH / 37.5)];
    _startTime.text = @"00:00";
    _startTime.font = [UIFont systemFontOfSize:12];
    _startTime.textColor = [UIColor redColor];
    [self.backView addSubview:self.startTime];
    
    //结束时间 Label
    self.endTime = [[UILabel alloc] initWithFrame:CGRectMake(CGRectGetMaxX(self.progress.frame) - WIDTH / 16.25, 25, WIDTH / 6.25, WIDTH / 37.5)];
    _endTime.text = @"00:00";
    _endTime.font = [UIFont systemFontOfSize:12];
    _endTime.textColor = [UIColor redColor];
    [self.backView addSubview:self.endTime];
    
    //中间 / Label
    self.gang = [[UILabel alloc] initWithFrame:CGRectMake(CGRectGetMaxX(self.progress.frame) - WIDTH / 13.25, 25, WIDTH / 6.25, WIDTH / 37.5)];
    _gang.text = @"/";
    _gang.font = [UIFont systemFontOfSize:12];
    _gang.textColor = [UIColor redColor];
    [self.backView addSubview:self.gang];
    
    //全屏按钮
    self.fullButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [_fullButton setImage:[UIImage imageNamed:@"quanping"] forState:UIControlStateNormal];
    _fullButton.frame = CGRectMake(self.bounds.size.width - WIDTH / 10, 10,   WIDTH / 16.5,  WIDTH / 16.5);
    [_fullButton addTarget:self action:@selector(bigOrSmall) forControlEvents:(UIControlEventTouchUpInside)];
    [self.backView addSubview:self.fullButton];
    
    //隐藏长条的手势
    UITapGestureRecognizer *singRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hideTap)];
    [self addGestureRecognizer:singRecognizer];

}



- (void)setUrlStr:(NSString *)urlStr {
    
//    [self.playerLayer removeFromSuperlayer];
   
    AVPlayerItem *playerItem = [AVPlayerItem playerItemWithURL:[NSURL URLWithString:urlStr]];
    [self addObserverToPlayerItem:_playerItem];
    [self.player replaceCurrentItemWithPlayerItem:playerItem];
    self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];//设置播放层
    self.playerLayer.frame = self.layer.bounds;
    self.playerLayer.videoGravity = AVLayerVideoGravityResizeAspect;
    
    [self.layer addSublayer:self.playerLayer];
    //开始播放
    [self.player play];
    self.backView.hidden = YES;
    [self addProgressObserver];
    [self addNotification];
    [self.player addObserver:self forKeyPath:@"currentItem.status" options:NSKeyValueObservingOptionNew context:nil];
    [self.player addObserver:self forKeyPath:@"currentItem.loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];
    
}

//定时器隐藏状态条
- (void)hideTap{
    [UIView animateWithDuration:0.5 animations:^{
        if (self.backView.hidden == NO) {
            self.backView.hidden = YES;
        } else {
            self.backView.hidden = NO;
            [self useTimerToHiddenBackView];//定时器隐藏状态条
        }
    } completion:^(BOOL finish){
        
    }];
}

//定时器隐藏状态条的时间
- (void)useTimerToHiddenBackView {
    [self.timer invalidate];
    if (!self.backView.hidden) {
        self.timer = [NSTimer scheduledTimerWithTimeInterval:3 target:self selector:@selector(hiddenBackView) userInfo:nil repeats:YES];
    }
}

//隐藏状态条
- (void)hiddenBackView {
    self.backView.hidden = YES;
}

//获取播放时间
- (void)addProgressObserver{
    AVPlayerItem *playerItem = self.player.currentItem;
    __weak typeof(self) weakSelf = self;
    [self.player addPeriodicTimeObserverForInterval:CMTimeMake(1.0, 1.0) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
        float current = CMTimeGetSeconds(time);
        float total =CMTimeGetSeconds([playerItem duration]);
        if (current) {
            if (!weakSelf.isSliding) {
                weakSelf.progress.value = current/total;
            }
            weakSelf.startTime.text = [weakSelf currentTimeToString:current];
        }
    }];
}


- (void)addObserverToPlayerItem:(AVPlayerItem *)playerItem{
    [playerItem addObserver:self forKeyPath:@"currentItem.status" options:NSKeyValueObservingOptionNew context:nil];
    [playerItem addObserver:self forKeyPath:@"currentItem.loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];
}



- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{
    AVPlayer *avPlayer = (AVPlayer *)object;
    if ([keyPath isEqualToString:@"currentItem.status"]) {
//        AVPlayerStatus status = [[change objectForKey:@"new"] intValue];
        NSInteger minit;
        NSInteger sceond;
        if (avPlayer.currentItem.status ==AVPlayerStatusReadyToPlay) {
            [self playClick];
            minit = CMTimeGetSeconds(avPlayer.currentItem.duration)/60;
            sceond = CMTimeGetSeconds(avPlayer.currentItem.duration)- 60 * minit;
            self.endTime.text = [NSString stringWithFormat:@"%02ld:%02ld",(long)minit,sceond];
        }
    }else if ([keyPath isEqualToString:@"currentItem.loadedTimeRanges"]){
        NSArray *array = avPlayer.currentItem.loadedTimeRanges;
        CMTimeRange timeRange = [array.firstObject CMTimeRangeValue];
        float startSeconds = CMTimeGetSeconds(timeRange.start);
        float durationSeconds = CMTimeGetSeconds(timeRange.duration);
        NSTimeInterval totalBuffer = startSeconds + durationSeconds;
        self.playableProgress.value = totalBuffer/100;
        if (!_istouched) {
            if (self.player.rate==0) {
                [_actiity startAnimating];
            } else{
                [_actiity stopAnimating];
            }
        }
    }
}



- (void)removeObserverFromPlayerItem:(AVPlayerItem *)playerItem{
    [playerItem removeObserver:self forKeyPath:@"currentItem.status"];
    [playerItem removeObserver:self forKeyPath:@"currentItem.loadedTimeRanges"];
}

- (void)playClick{
    if (self.player.rate==1) {
        self.istouched = YES;
        [self.player pause];
        self.playButton.selected = YES;
    }else{
        [self.backView isHidden];
        self.istouched = NO;
        self.playButton.selected = NO;
        [self.player play];
    }
}

- (void)fullScreen:(PlayView *)playerView {
    
         _playerLayer.videoGravity = AVLayerVideoGravityResizeAspect;
    //    playerLayer.transform = CATransform3DMakeRotation(M_PI_2, 0 , 0, 1);
    //    playerLayer.frame = self.view.bounds;
    
    self.transform = CGAffineTransformRotate(self.transform, M_PI_2);
    
    self.backView.frame = CGRectMake(0, 0, 667, 414);
    self.backView.transform = CGAffineTransformRotate(self.backView.transform, M_PI_2);
//        [[UIApplication sharedApplication].windows.firstObject.layer addSublayer:_playerLayer];
//        [[UIApplication sharedApplication].windows.firstObject addSubview:self.backView];
    
    
    __isSmall = NO;
}

- (void)normalScreen:(PlayView *)playerView {
    
    _playerLayer.videoGravity = AVLayerVideoGravityResizeAspect;
    //    playerLayer.transform = CATransform3DMakeRotation(-M_PI_2, 0 , 0, -1);
    //    playerLayer.frame = self.view.bounds;
    //    self.backView.frame = CGRectMake(0, 450, KScreenWidth, 40);
    self.backView.transform = CGAffineTransformRotate(self.backView.transform, -M_PI_2);
    
    self.transform = CGAffineTransformRotate(self.transform, -M_PI_2);
    
    //    [[UIApplication sharedApplication].windows.firstObject.layer addSublayer:playerLayer];
    //    [[UIApplication sharedApplication].windows.firstObject addSubview:self.backView];
    __isSmall = YES;
}

- (void)bigOrSmall{
    if (__isSmall) {
        if ([self.delegate respondsToSelector:@selector(fullScreen:)]) {
            [self.delegate fullScreen:self];
        }
    } else {
        if ([self.delegate respondsToSelector:@selector(normalScreen:)]) {
            [self.delegate normalScreen:self];
        }
    }
    __isSmall = !__isSmall;
}


- (void)valueChange:(UISlider *)progress other:(UIEvent *)event{
    
    NSTimeInterval currenttime;
    UITouch *touch = [[event allTouches] anyObject];
    switch (touch.phase) {
        case UITouchPhaseBegan:
            NSLog(@"start");
            self.isSliding = YES;
            
            break;
        case UITouchPhaseMoved:
            [_player pause];
            currenttime = self.progress.value *CMTimeGetSeconds([self.player.currentItem duration]);
            self.startTime.text = [self currentTimeToString:currenttime];
            NSLog(@"%@", self.startTime.text);
            break;
        case UITouchPhaseEnded:
            self.isSliding = NO;
            [self play];
            NSLog(@"qewrwr");
            
            break;
        default:
            break;
    }
    
}

- (void)play{
    CMTime dragedCmTime = CMTimeMake(self.progress.value*CMTimeGetSeconds([self.player.currentItem duration]), 1);
    [self.player seekToTime:dragedCmTime completionHandler:^(BOOL finished) {
        [self playClick];
    }];
}

- (NSString *)currentTimeToString:(NSTimeInterval)currentTime{
    NSInteger static minit;
    NSInteger static second;
    minit = currentTime / 60;
    second = currentTime - 60 * minit;
    return [NSString stringWithFormat:@"%02ld:%02ld", (long)minit, (long)second];
}

- (void)addNotification{
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playEnd:) name:AVPlayerItemDidPlayToEndTimeNotification object:self.player.currentItem];
}
- (void) playEnd:(NSTimeInterval)currentTime{
    NSLog(@"播放完成");
}

- (void) tap {
    UITapGestureRecognizer *gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(clickPhoto)];
    self.imageView.userInteractionEnabled = YES;
    [self.imageView addGestureRecognizer:gesture];
}

- (void)clickPhoto{
    NSLog(@"43435");
    //    if (self.player.rate==1) {
    //        self.istouched = YES;
    //        [self.player pause];
    //    }else{
    //        self.imageView.hidden = YES;
    //        self.istouched = NO;
    //        [self.player play];
    //    }
    
    //    _player = [[AVPlayer alloc] initWithPlayerItem:self.playerItem];
    //    _playerItem = [AVPlayerItem playerItemWithURL:[NSURL URLWithString:@"http://baobab.cdn.wandoujia.com/14463059939521445330477778425364388_x264.mp4"]];
    //    [self addObserverToPlayerItem:_playerItem];
    
}




@end

ViewController.m中的代码

#define KScreenWidth [[UIScreen mainScreen]bounds].size.width
#define KScreenHeight [[UIScreen mainScreen]bounds].size.height
#define WIDTH [UIScreen mainScreen].bounds.size.width
#define HEIGHT [UIScreen mainScreen].bounds.size.height
#import "ViewController.h"
#import <AVFoundation/AVFoundation.h>
#import "PlayView.h"

@interface ViewController ()<PlayViewDelegate>
@property (nonatomic,strong) NSURL *url;
@property (nonatomic,strong) AVPlayer *player;
@property (nonatomic,strong) UIView *container;
@property (nonatomic,strong) AVPlayerItem *playerItem;
@property (nonatomic,strong) UIButton *playButton;
@property (nonatomic,strong) UIButton *fullButton;
@property (nonatomic,strong) UILabel *startTime;
@property (nonatomic,strong) UILabel *endTime;
@property (nonatomic,strong) UISlider *progress;
@property (nonatomic,strong) UISlider *playableProgress;
@property (nonatomic,strong) UISlider *volume;
@property (nonatomic,strong) UIView *backView;
@property (nonatomic,strong) UIActivityIndicatorView *actiity;
@property (nonatomic,assign) BOOL isSliding;
@property (nonatomic,assign) BOOL istouched;
@property (nonatomic,strong) NSTimer *timer;
@property (nonatomic,strong)UIImageView *imageView;

@property (nonatomic, assign) CGRect nowFrame;//现在的
@property (nonatomic, assign) CGRect currentFrame2;//滚出的


@property (nonatomic,strong)PlayView *playView;


@end

@implementation ViewController{
    AVPlayerLayer *playerLayer;
    BOOL _isSmall;

}

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor yellowColor];
    
    
    self.actiity = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
    _actiity.frame = CGRectMake(0, 0, 30, 30);
    _actiity.center = CGPointMake(KScreenWidth / 2, KScreenHeight / 2);
    [self.playView addSubview:_actiity];
    
    self.playView = [[PlayView alloc] initWithFrame:CGRectMake(0, 0, WIDTH, HEIGHT / 2.2)];
    self.playView.backgroundColor = [UIColor blackColor];
    self.playView.urlStr = @"http://baobab.cdn.wandoujia.com/14463059939521445330477778425364388_x264.mp4";
    self.playView.delegate = self;
    [self.view addSubview:self.playView];
    
    
}

- (void)normalScreen:(PlayView *)playerView {
    
    playerView.transform = CGAffineTransformRotate(playerView.transform, M_PI_2);
    playerView.frame = [UIScreen mainScreen].bounds;
    NSLog(@"%f",self.backView.frame.size.width);
    playerView.playerLayer.videoGravity = AVLayerVideoGravityResizeAspect;
  
}


- (void)fullScreen:(PlayView *)playerView {
    
    playerView.transform = CGAffineTransformRotate(playerView.transform, -M_PI_2);
    playerView.frame = CGRectMake(0, 0, WIDTH, HEIGHT / 2.2);
    playerView.playerLayer.videoGravity = AVLayerVideoGravityResizeAspect;
    

}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

 

AVPlayer

标签:

原文地址:http://www.cnblogs.com/wsn1993/p/5158715.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!