#import "ViewController.h"

#import <AVFoundation/AVFoundation.h>

@interface ViewController ()

{

    AVPlayer *player;

    AVPlayerItem *playerItem;

    

    UIProgressView * progressView;

    UISlider *_slider;

    

    //推断slider是否按下,

    BOOL isOpen;

}

@end



@implementation ViewController



- (void)viewDidLoad {

    [super viewDidLoad];

    [self createUI];

    //进行初始化创建

    NSURL *url = [NSURL fileURLWithPath:@"/Users/qianfeng01/Downloads/千锋Swift视频教程-1.Swift语言介绍.mp4"];

    playerItem  = [[AVPlayerItem alloc]initWithURL:url];

    //创建player

    player = [[AVPlayer alloc]initWithPlayerItem:playerItem];

    //生成layer层

    AVPlayerLayer *layer = [AVPlayerLayer playerLayerWithPlayer:player];

    //设置坐标

    layer.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);

    

    //把layer层假如到self.view.layer中

    [self.view.layer addSublayer:layer];

    //进行播放

    [player play];

    

    /**以上是主要的播放界面。可是没有前进后退**/

    //观察是否播放,KVO进行观察,观察playerItem.status

    [playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];

    

    //观察缓存如今的进度,KVO进行观察,观察loadedTimeRanges

    [playerItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];

}



//观察是否播放

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{

    if ([keyPath isEqualToString:@"status"]) {

        if (playerItem.status == AVPlayerStatusReadyToPlay) {

            NSLog(@"開始播放");

            //须要開始获取数据,包含播放的总时长。播放的缓存,播放的当时时间

            [self loadData];

        }else{

            NSLog(@"播放失败");

        }

    }else{

        //kvo触发的另外一个属性

        NSArray *array = [playerItem loadedTimeRanges];

        //获取范围i

        CMTimeRange range = [array.firstObject CMTimeRangeValue];

        //从哪儿開始的

        CGFloat start = CMTimeGetSeconds(range.start);

        //缓存了多少

        CGFloat duration = CMTimeGetSeconds(range.duration);

        //一共缓存了多少

        CGFloat allCache = start+duration;

        NSLog(@"缓存了多少数据:%f",allCache);

        

        //设置缓存的百分比

        CMTime allTime = [playerItem duration];

        //转换

        CGFloat time = CMTimeGetSeconds(allTime);

        CGFloat y = allCache/time;

        NSLog(@"缓存百分比:--------%f",y);

        progressView.progress = y;

    }

}





#pragma mark -- 获取播放数据

- (void)loadData{

    

    __weak AVPlayerItem *xx = playerItem;

    __weak UISlider *cc = _slider;

    //第一个參数是每隔多长时间调用一次。在这里设置的是每隔1秒调用一次

    [player addPeriodicTimeObserverForInterval:CMTimeMake(1, 1) queue:NULL usingBlock:^(CMTime time) {

        //当前播放时间

        CGFloat current = xx.currentTime.value/xx.currentTime.timescale;

        

        //获取总时长

        CMTime time1 = xx.duration;

        float x = CMTimeGetSeconds(time1);

        NSLog(@"当前播放的秒数------- %f --------%f",current,x);

        

        //设置滑动条进度

        float v = current/x;

        

        //推断slider是否按下,按下去就先别赋值

        if (!isOpen) {

            cc.value = v;

        }

        

    }];



}



#pragma mark --- 创建UI

- (void)createUI{

    progressView = [[UIProgressView alloc]initWithProgressViewStyle:UIProgressViewStyleBar];

    progressView.frame = CGRectMake(0, 460, self.view.frame.size.width, 20);

    

    [self.view addSubview:progressView];

    

    _slider = [[UISlider alloc]initWithFrame:CGRectMake(0, 480, self.view.frame.size.width, 20)];

    [self.view addSubview:_slider];

    

    

    //加入点击事件

    [_slider addTarget:self action:@selector(sliderClick:) forControlEvents:UIControlEventTouchUpInside];

    //抬起来的事件

    [_slider addTarget:self action:@selector(sliderClickUp:) forControlEvents:UIControlEventTouchUpInside];

}



    //加入点击事件

- (void)sliderClick:(UISlider *)slider{

    NSLog(@"加入点击事件");

    isOpen = YES;

}



    //抬起来的事件

- (void)sliderClickUp:(UISlider *)slider{

    NSLog(@"抬起来的事件");

    isOpen = NO;

    

    //从这里開始播放

    CGFloat g = slider.value;

    //获取总时长

    CMTime time1 = playerItem.duration;

    float x = CMTimeGetSeconds(time1);

    //进行播放

    [player seekToTime:CMTimeMake(x * g,1)];

    //播放

    [player play];

    

}





@end

AVPlayer的使用,带缓冲的更多相关文章

  1. JavaScript原生折叠扩展收缩菜单带缓冲动画

    JavaScript原生折叠扩展收缩菜单带缓冲动画 @落雨 <div id="div_two" style="display: none;"> &l ...

  2. js+css实现带缓冲效果右键弹出菜单

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  3. 文件I/O(不带缓冲)之原子操作

    一.添写至一个文件 考虑一个进程,它要将数据添加到一个文件尾端.早期的UNIX系统并不支持open的O_APPEND选项,所以程序被编写成下列形式: ) < ) /* position to E ...

  4. 文件I/O(不带缓冲)概述

    一.引言 UNIX系统中大多数文件I/O只需用到5个函数:open.read.write.lseek以及close.这些函数经常被称为不带缓冲的I/O(unbuffered I/O).术语不带缓冲指的 ...

  5. 带缓冲I/O和不带缓冲I/O的区别与联系

    转自:http://blog.csdn.net/lmh12506/article/details/6803847 首先要明白不带缓冲的概念:所谓不带缓冲,并不是指内核不提供缓冲,而是只单纯的系统调用, ...

  6. 带缓冲的IO和不带缓冲的IO

    文件描述符: 文件描述符是一个小的非负整数,是内核用来标识特定进程正在访问的文件 标准输入/输出/出错: shell为每个程序打开了三个文件描述符,STDIN_FILEON,STDOUT_FILEON ...

  7. 带缓冲I/O 和不带缓冲I/O的区别与联系

    首先要明白不带缓冲的概念:所谓不带缓冲,并不是指内核不提供缓冲,而是只单纯的系统调用,不是函数库的调用.系统内核对磁盘的读写都会提供一个块缓冲(在有些地方也被称为内核高速缓存),当用write函数对其 ...

  8. UNIX环境编程学习笔记(2)——文件I/O之不带缓冲的 I/O

    lienhua342014-08-25 1 文件描述符 对于内核而言,所有打开的文件都通过文件描述符引用.文件描述符是一个非负整数.当打开一个现有文件或创建一个新文件时,内核向进程返回一个文件描述符. ...

  9. 第十三篇:带缓冲的IO( 标准IO库 )

    前言 在之前,学习了 read write 这样的不带缓冲IO函数. 而本文将讲解标准IO库中,带缓冲的IO函数. 为什么要有带缓冲IO函数 标准库提供的带缓冲IO函数是为了减少 read 和 wri ...

  10. Java 带缓冲的字节流和字符流

    输入流就是文件从硬盘到内存的中间媒介,那么输出流就是文件从内存到硬盘的中间媒介.首先来看看FileOutputStream的继承了哪些类, java.lang.Object java.io.Outpu ...

随机推荐

  1. Kafka详解与总结(四)

    Kafka消息分发和消费者push.pull机制 1. 消息分发 Producer客户端负责消息的分发 kafka集群中的任何一个broker都可以向producer提供metadata信息,这些me ...

  2. asp.net core 2.0 Json结果的格式

    asp.net core 2.0 默认返回的结果格式是Json, 并使用json.net对结果默认做了camel case的转化(大概可理解为首字母小写). 这一点与老.net web api 不一样 ...

  3. 342 Power of Four 4的幂

    给定一个整数 (32位有符整数型),请写出一个函数来检验它是否是4的幂.示例:当 num = 16 时 ,返回 true . 当 num = 5时,返回 false.问题进阶:你能不使用循环/递归来解 ...

  4. Emoji过滤

    private static boolean isNotEmojiCharacter(char codePoint) { return (codePoint == 0x0) || (codePoint ...

  5. SVN系列学习(三)-TortoiseSVN的基本操作

    1.添加(Add) 在ZJHZXS_01中,新建一个记事本,在记事本中写上一下内容,然后保存,再打开,再保存 这个时候,在选中文件夹ZJHZXS_01,并右击[SVN Commit] 提交成功,加了一 ...

  6. Struts之 拦截器配置 ( Interceptor )

    struts2体系结构的核心就是拦截器. 以链式执行,对真正要执行的方法(execute())进行拦截.首先执行Action配置的拦截器,在Action和Result执行之后,拦截器再一次执行(与先前 ...

  7. javascript特殊值常量

    Infinity 表示无穷大的特殊值.当数字运算结果超出javascript能表示的数字范围时. Nan 特殊的非数字值(not a number).0除0.数字运算符的操作数为字符等情况. Numb ...

  8. drupal-使用hook_preprocess_field在paragraph的accordion中添加自定义数据

    描述:我的accordion类型原先只有两个字段,分别是title和content.显示在页面上会默认隐藏其内容,点击“+”会显示内容.然而现在有一个新需求,就是加一个开关使编辑内容者可以选择默认“展 ...

  9. Hive扩展功能(七)--Hive On Spark

    软件环境: linux系统: CentOS6.7 Hadoop版本: 2.6.5 zookeeper版本: 3.4.8 主机配置: 一共m1, m2, m3这五部机, 每部主机的用户名都为centos ...

  10. java攻城师之路--复习java web之Cookie_Session

    Servlet技术 用来动态生成 网页数据资源Servlet生成HTML 页面数据时,所有内容都是通过 response.getWriter response.getOutputStream 向浏览器 ...