zoukankan      html  css  js  c++  java
  • AVPlayer

    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
  • 相关阅读:
    记忆碎片:我的2007
    查看 Oracle 是用spfile 启动还是 pfile 启动
    Oracle 10g OCP 042 题库 71120 题 共168题
    Oracle OLAP 与 OLTP 介绍
    Oracle Data Guard Switchover 切换
    Linux 终端访问 FTP 及 上传下载 文件
    多表连接的三种方式详解 HASH JOIN MERGE JOIN NESTED LOOP
    Oracle 表连接方式(内连接/外连接/自连接) 详解
    Oracle 表连接方式(内连接/外连接/自连接) 详解
    查看 Oracle 是用spfile 启动还是 pfile 启动
  • 原文地址:https://www.cnblogs.com/wsn1993/p/5158715.html
Copyright © 2011-2022 走看看