avplayer简介 ios
2017-07-13 12:53:42 shihuboke 阅读数 509
//联系人:石虎  QQ: 1224614774昵称:嗡嘛呢叭咪哄

苹果在视频播放方面提供了多个框架供我们选择使用。
分别为:
  • 基于mediaPlayer类库的MPMediaPlayerController(iOS9后遭到废弃,被AVPlayerViewController所替代
  • 基于AVFounditon类库的AVPlayer
  • 基于AVKit类库的AVPlayerViewController(iOS8后才可使用

正文AVPlayer与MPMediaPlayerController比较:
  • AVplayer有更多的灵活性,当然,也需要你去自定义构建UI。还有一大优势,例如其扩展的AVQueuePlayer,可以实现视频无缝队列播放、多视频同时播放、视频转换、编解码等功能。
  • MPMediaPlayerController实际上是基于AVPlayer的简单UI封装,对于一般的播放要求,几行代码就可实现,省心省事。因为MPMediaPlayerController是对AVPlayer进行的单例封装,所以不能进行多视频播放。

播放器Demo(全屏)已实现功能点:
  • push到播放器页面,横屏显示。
  • 单机隐藏or显示上方标题栏与下方操作栏。
  • 呼出右侧设置栏。
  • 视频播放操作与进度条设置。
  • 在屏幕上左右拖动,进行视频快进与快退。
  • 在屏幕左侧上下拖动,进行亮度调整。
  • 在屏幕右侧上下拖动,进行音量调整。
想到但是暂未实现的功能点:(大多为优化或与业务相关)
  • 屏幕或进度条拖动快进操作时,添加提示框进行快进时间的实时提示。
  • 用户无操作两三秒之后自动隐藏上下View。
  • 视频清晰度调整按钮。(更换视频源)操作加锁按钮。(加锁后未进行解锁操作之前不可进行操作)
  • 弹幕相关。
  • 用户允许横屏状态下,横屏竖屏自动进行页面切换与动画效果等。
  • 网络视频的缓存、下载等。
  • 软硬解码模式切换等。

谢谢!!!



2018-12-19 09:30:18 weixin_33810006 阅读数 3

AVPlayer

在iOS开发中,播放视频通常有两种方式,一种是使用MPMoviePlayerController(需要导入MediaPlayer.Framework),还有一种是使用AVPlayer。AVPlay既可以用来播放音频也可以用来播放视频,AVPlay在播放音频方面可以直接用来播放网络上的音频。在使用AVPlay的时候我们需要导入AVFoundation.framework框架,再引入头文件#import<AVFound ation/AVFoundation.h>。

AVPlayer视频播放

在开发中,单纯的使用AVPlayer类是无法现实视频的,要将视频添加到AVPlayerLayer中,这样才能将视频现实出来,所以我们先在@interface中添加一下属性

@property (strong, nonatomic)AVPlayer *myPlayer;//播放器
@property (strong, nonatomic)AVPlayerItem *item;//播放单元
@property (strong, nonatomic)AVPlayerLayer *playerLayer;//播放界面(layer)
复制代码

我们简单介绍一下这三个属性之间的关系吧 首先我们之所以能够看到视频是因为AVPlayerLayer帮我们把视频呈现出来了,可以说是AVPlayerLayer就是一个视频播放器的载体,它负责需要播放的画面。用MVC比喻,就是AVPlayerLayer属于V层,负责对用户的呈现。从AVPlayerLayer的便利构造器方法中可以看出我们在创建一个AVPlayerLayer的时候需要一个AVPlayer类型的参数。所以在创建AVPlayerLayer的时候,我们需要先有一个AVPlayer,它用MVC来分类的话就相当于MVC中的C层,负责播放单元和播放界面的协调工作,我们在它的便利构造器方法中可以看到他需要我们传入一个AVPlayerItem也就是播放单元,所谓的播放单元就是给播放器提供了一个数据的来源,用MVC来类比的话,它就属于M层,在创建一个播放单元的时候,我们首先得需要一个网址。 综上所述,将一个视频播放出来可分为如下几个步骤。 第一步:首先我们需要一个播放的网址

    NSURL *mediaURL = [NSURL URLWithString:@"http://baobab.wdjcdn.com”]
复制代码

第二步:初始化一个播放单元

 self.item = [AVPlayerItem playerItemWithURL:mediaURL];
复制代码

第三步:初始化一个播放器对象

self.myPlayer = [AVPlayer playerWithPlayerItem:self.item];
复制代码

第四步:初始化一个播放器的Layer

self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.myPlayer];
self.playerLayer.frame = CGRectMake(0, 0, self.view.bounds.size.width, 500);
[self.view.layer addSublayer:self.playerLayer];
复制代码

第五步:开始播放

[self.myPlayer play];
复制代码

只要顺序执行上面的五个步骤,就可以将一个视频播放到界面上。当然现在还只是能够播放了而已,要具体实现视频的快进快退功能,请继续往下看。 ##AVPlayer视频快进快退 播放进度 CMTime类型一般是用来表示视频或者动画的时间类型。CMTime对象的Value属性是用来得到当前视频或者动画一共有多少帧,timescale指的是每秒多少帧;timescale指的是每秒多少帧,value/timescale = 视频的总时长(秒) 视频的快进快退,首先我们声明了两个属性

@property (strong, nonatomic)UISlider *avSlider;//用来现实视频的播放进度,并且通过它来控制视频的快进快退。
@property (assign, nonatomic)BOOL isReadToPlay;//用来判断当前视频是否准备好播放。
复制代码

在这里我们将上面前四个步骤封装到一个方法中,并且在这个方法中给播放单元也就是AVPlayerItem添加一个监听,来监听它的状态。

-(void)avPlayerMethod{
//构建播放网址
    NSURL *mediaURL = [NSURL URLWithString:@"http://baobab.wdjcdn.com/1455782903700jy.mp4"];
//构建播放单元
    self.item = [AVPlayerItem playerItemWithURL:mediaURL];
//构建播放器对象
    self.myPlayer = [AVPlayer playerWithPlayerItem:self.item];
//构建播放器的layer
    self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.myPlayer];
    self.playerLayer.frame = CGRectMake(0, 66, self.view.bounds.size.width, 300);
    [self.view.layer addSublayer:self.playerLayer];
    //通过KVO来观察status属性的变化,来获得播放之前的错误信息
    [self.item addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
}
复制代码

KVO的回调方法

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:
(NSDictionary<NSString *,id> *)change context:(void *)context{
    if ([keyPath isEqualToString:@"status"]) {
        //取出status的新值
        AVPlayerItemStatus status = [change[NSKeyValueChangeNewKey]intValue];
        switch (status) {
            case AVPlayerItemStatusFailed:
                NSLog(@"item 有误");
                self.isReadToPlay = NO;
                break;
            case AVPlayerItemStatusReadyToPlay:
                NSLog(@"准好播放了");
                self.isReadToPlay = YES;
                self.avSlider.maximumValue = self.item.duration.value / self.item.duration.timescale;
                break;
            case AVPlayerItemStatusUnknown:
                NSLog(@"视频资源出现未知错误");
                self.isReadToPlay = NO;
                break;
            default:
                break;
        }
    }
    //移除监听(观察者)
    [object removeObserver:self forKeyPath:@"status"];
}
复制代码

视频的播放按钮

    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    button.frame = CGRectMake(250, 600, 100, 100);
    button.backgroundColor = [UIColor redColor];
    [button setTitle:@"按钮" forState:UIControlStateNormal];
    [button addTarget:self action:@selector(playAction) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:button];
复制代码

button的回调方法

- (void)playAction{
    if ( self.isReadToPlay) {
        [self.myPlayer play];
    }else{
        NSLog(@"视频正在加载中");
    }
}
复制代码

创建一个进度条来控制视频的进度 使用懒加载的方式,将进度条添加到View上面

- (UISlider *)avSlider{
    if (!_avSlider) {
        _avSlider = [[UISlider alloc]initWithFrame:CGRectMake(0, 55, self.view.bounds.size.width, 30)];
        [self.view addSubview:_avSlider];
    }return _avSlider;
}
复制代码

在viewDidLoad中个slider(进度条)添加一个回调。

[self.avSlider addTarget:self action:@selector(avSliderAction) forControlEvents:
UIControlEventTouchUpInside|UIControlEventTouchCancel|UIControlEventTouchUpOutside];
复制代码

回调方法

- (void)avSliderAction{
    //slider的value值为视频的时间
    float seconds = self.avSlider.value;
    //让视频从指定的CMTime对象处播放。
    CMTime startTime = CMTimeMakeWithSeconds(seconds, self.item.currentTime.timescale);
    //让视频从指定处播放
    [self.myPlayer seekToTime:startTime completionHandler:^(BOOL finished) {
        if (finished) {
            [self playAction];
        }
    }];
}
复制代码

以上就是实现一个视频的播放和快进快退的方法与步骤。

转载于:https://juejin.im/post/5c1a0dfd518825314b0be9d6

2018-02-06 10:35:09 wsl2ls 阅读数 87

GOVVideoPlayer/GOVVideoController 是一个基于AVPlayer封装的视频播放器,支持播放/暂停、左右退拽快进、上下滑动调节音量、自动手动全屏、全屏时横屏Or竖屏、有缓冲进度指示条、卡顿指示器、切换视频源。


更新于2017/8/10,增加了GOVVideoController

GOVVideoPlayer是在继承于UIView的基础上封装的视频View;
GOVVideoController是在继承于UIViewController的基础上封装的视频视图控制器,用起来更方便简洁,解耦性强,几行代码就足够了。
两者最大的不同是在全屏和取消全屏的处理上面:前者是一个视图View,可以直接加在父视图上面,全屏时是加在 [UIApplication sharedApplication].keyWindow上的,而后者,小屏时是取GOVVideoController的View加在父视图上,全屏和取消全屏时是采用present和dismiss模态化转场的方法 。

总效果如下:

总效果.gif
主要代码如下:

//监测屏幕旋转
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChange:) name:UIDeviceOrientationDidChangeNotification object:nil];

    //添加AVPlayerItem播放结束通知
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playFinished:) name:AVPlayerItemDidPlayToEndTimeNotification object:self.avPlayer.currentItem];

    //添加AVPlayerItem开始缓冲通知
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(bufferStart:) name:AVPlayerItemPlaybackStalledNotification object:self.avPlayer.currentItem];

//KOV监控 播放器进度更新
- (void)addObserverForAVPlayer
{
    AVPlayerItem *playerItem = self.avPlayer.currentItem;

    // 给AVPlayer添加观察者 必须实现 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context;

    //监控播放速率
    [self.avPlayer addObserver:self forKeyPath:@"rate" options:NSKeyValueObservingOptionNew context:nil];
    //监控状态属性(AVPlayer也有一个status属性,通过监控它的status也可以获得播放状态)
    [playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
    //监控网络加载缓冲情况属性
    [playerItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];
    //监控是否可播放
    [playerItem addObserver:self forKeyPath:@"playbackLikelyToKeepUp" options:NSKeyValueObservingOptionNew context:nil];


    //播放进度观察者  //设置每0.1秒执行一次
    __weak GOVVideoView *weakSelf = self;
    _playerTimeObserver =  [self.avPlayer addPeriodicTimeObserverForInterval:CMTimeMake(1.0, 10.0) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {

        if (weakSelf.dragSlider) {
            return ;
        }

        CGFloat current = CMTimeGetSeconds(time);
        weakSelf.current = current;
        CMTime totalTime = weakSelf.avPlayer.currentItem.duration;
        CGFloat total = CMTimeGetSeconds(totalTime);
        weakSelf.total = total;
        weakSelf.slider.value = current/total;
        weakSelf.currentTimeLabel.text = [weakSelf timeFormatted:current];
        weakSelf.totalTimeLabel.text = [NSString stringWithFormat:@"/%@",[weakSelf timeFormatted:total]] ;

    }];
}

//通过KVO监控回调
//keyPath 监控属性 object 监视器 change 状态改变 context 上下文
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{

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

        //监控网络加载情况属性
        NSArray *array = self.avPlayer.currentItem.loadedTimeRanges;
        //本次缓冲时间范围
        CMTimeRange timeRange = [array.firstObject CMTimeRangeValue];
        CGFloat startSeconds = CMTimeGetSeconds(timeRange.start);
        CGFloat durationSeconds = CMTimeGetSeconds(timeRange.duration);
        //现有缓冲总长度
        CGFloat totalBuffer = startSeconds + durationSeconds;
        //视频总时长
        CMTime totalTime = self.avPlayer.currentItem.duration;
        CGFloat total = CMTimeGetSeconds(totalTime);
        if (totalBuffer/total <= 1.0 ) {
            [self.progressView setProgress:totalBuffer/total animated:YES];
        }

    }else if([keyPath isEqualToString:@"playbackLikelyToKeepUp"]){

        if (self.avPlayer.currentItem.playbackLikelyToKeepUp == YES) {

            if (_activityView != nil) {
                [self.activityView startAnimating];
                [self.activityView removeFromSuperview];
                _activityView = nil;
            }
        }
    }else if ([keyPath isEqualToString:@"status"]){

        //监控状态属性
        AVPlayerStatus status = [[change objectForKey:@"new"] intValue];

        switch ((status)) {
            case AVPlayerStatusReadyToPlay:

                break;
            case AVPlayerStatusUnknown:

                break;
            case AVPlayerStatusFailed:

                break;

        }
    }else if ([keyPath isEqualToString:@"rate"]){
        if (self.avPlayer.rate == 1) {
        }
    }

}

#pragma mark -- 隐藏/显示状态栏的方法
/*[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone];这个方法在iOS9之后弃用了,并且需要
 将View controller-based status bar appearance设置为NO;而下面的重写方法需要将View controller-based status bar appearance设置为YES,这个方法在iOS7之后就有了;
//刷新状态栏状态
 [self setNeedsStatusBarAppearanceUpdate];
 */
//设置样式
- (UIStatusBarStyle)preferredStatusBarStyle {
    return UIStatusBarStyleLightContent;
}
//设置是否隐藏
- (BOOL)prefersStatusBarHidden {
    return self.isHiddenStatusBar;
}
//设置隐藏动画
- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation {
    return UIStatusBarAnimationNone;
}

亲,赞一下呗❤️么么哒.jpg

2018-03-05 14:40:09 qq_33632048 阅读数 1742

AVPlayer

在iOS开发中,播放视频通常有两种方式,一种是使用MPMoviePlayerController(需要导入MediaPlayer.Framework),还有一种是使用AVPlayer。AVPlay既可以用来播放音频也可以用来播放视频,AVPlay在播放音频方面可以直接用来播放网络上的音频。在使用AVPlay的时候我们需要导入AVFoundation.framework框架,再引入头文件#import<AVFound
ation/AVFoundation.h>。

AVPlayer视频播放

在开发中,单纯的使用AVPlayer类是无法现实视频的,要将视频添加到AVPlayerLayer中,这样才能将视频现实出来,所以我们先在@interface中添加一下属性

@property (strong, nonatomic)AVPlayer *myPlayer;//播放器
@property (strong, nonatomic)AVPlayerItem *item;//播放单元
@property (strong, nonatomic)AVPlayerLayer *playerLayer;//播放界面(layer)

我们简单介绍一下这三个属性之间的关系吧
首先我们之所以能够看到视频是因为AVPlayerLayer帮我们把视频呈现出来了,可以说是AVPlayerLayer就是一个视频播放器的载体,它负责需要播放的画面。用MVC比喻,就是AVPlayerLayer属于V层,负责对用户的呈现。从AVPlayerLayer的便利构造器方法中可以看出我们在创建一个AVPlayerLayer的时候需要一个AVPlayer类型的参数。所以在创建AVPlayerLayer的时候,我们需要先有一个AVPlayer,它用MVC来分类的话就相当于MVC中的C层,负责播放单元和播放界面的协调工作,我们在它的便利构造器方法中可以看到他需要我们传入一个AVPlayerItem也就是播放单元,所谓的播放单元就是给播放器提供了一个数据的来源,用MVC来类比的话,它就属于M层,在创建一个播放单元的时候,我们首先得需要一个网址。
综上所述,将一个视频播放出来可分为如下几个步骤。
第一步:首先我们需要一个播放的网址

    NSURL *mediaURL = [NSURL URLWithString:@"http://baobab.wdjcdn.com

第二步:初始化一个播放单元

 self.item = [AVPlayerItem playerItemWithURL:mediaURL];

第三步:初始化一个播放器对象

self.myPlayer = [AVPlayer playerWithPlayerItem:self.item];

第四步:初始化一个播放器的Layer

self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.myPlayer];
self.playerLayer.frame = CGRectMake(0, 0, self.view.bounds.size.width, 500);
[self.view.layer addSublayer:self.playerLayer];

第五步:开始播放

[self.myPlayer play];

只要顺序执行上面的五个步骤,就可以将一个视频播放到界面上。当然现在还只是能够播放了而已,要具体实现视频的快进快退功能,请继续往下看。

AVPlayer视频快进快退

播放进度 CMTime类型一般是用来表示视频或者动画的时间类型。CMTime对象的Value属性是用来得到当前视频或者动画一共有多少帧,timescale指的是每秒多少帧;timescale指的是每秒多少帧,value/timescale = 视频的总时长(秒)
视频的快进快退,首先我们声明了两个属性

@property (strong, nonatomic)UISlider *avSlider;//用来现实视频的播放进度,并且通过它来控制视频的快进快退。
@property (assign, nonatomic)BOOL isReadToPlay;//用来判断当前视频是否准备好播放。

在这里我们将上面前四个步骤封装到一个方法中,并且在这个方法中给播放单元也就是AVPlayerItem添加一个监听,来监听它的状态。

-(void)avPlayerMethod{
//构建播放网址
    NSURL *mediaURL = [NSURL URLWithString:@"http://baobab.wdjcdn.com/1455782903700jy.mp4"];
//构建播放单元
    self.item = [AVPlayerItem playerItemWithURL:mediaURL];
//构建播放器对象
    self.myPlayer = [AVPlayer playerWithPlayerItem:self.item];
//构建播放器的layer
    self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.myPlayer];
    self.playerLayer.frame = CGRectMake(0, 66, self.view.bounds.size.width, 300);
    [self.view.layer addSublayer:self.playerLayer];
    //通过KVO来观察status属性的变化,来获得播放之前的错误信息
    [self.item addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
}

KVO的回调方法

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:
(NSDictionary<NSString *,id> *)change context:(void *)context{
    if ([keyPath isEqualToString:@"status"]) {
        //取出status的新值
        AVPlayerItemStatus status = [change[NSKeyValueChangeNewKey]intValue];
        switch (status) {
            case AVPlayerItemStatusFailed:
                NSLog(@"item 有误");
                self.isReadToPlay = NO;
                break;
            case AVPlayerItemStatusReadyToPlay:
                NSLog(@"准好播放了");
                self.isReadToPlay = YES;
                self.avSlider.maximumValue = self.item.duration.value / self.item.duration.timescale;
                break;
            case AVPlayerItemStatusUnknown:
                NSLog(@"视频资源出现未知错误");
                self.isReadToPlay = NO;
                break;
            default:
                break;
        }
    }
    //移除监听(观察者)
    [object removeObserver:self forKeyPath:@"status"];
}

视频的播放按钮

    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    button.frame = CGRectMake(250, 600, 100, 100);
    button.backgroundColor = [UIColor redColor];
    [button setTitle:@"按钮" forState:UIControlStateNormal];
    [button addTarget:self action:@selector(playAction) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:button];

button的回调方法

- (void)playAction{
    if ( self.isReadToPlay) {
        [self.myPlayer play];
    }else{
        NSLog(@"视频正在加载中");
    }
}

创建一个进度条来控制视频的进度
使用懒加载的方式,将进度条添加到View上面

- (UISlider *)avSlider{
    if (!_avSlider) {
        _avSlider = [[UISlider alloc]initWithFrame:CGRectMake(0, 55, self.view.bounds.size.width, 30)];
        [self.view addSubview:_avSlider];
    }return _avSlider;
}

在viewDidLoad中个slider(进度条)添加一个回调。

[self.avSlider addTarget:self action:@selector(avSliderAction) forControlEvents:
UIControlEventTouchUpInside|UIControlEventTouchCancel|UIControlEventTouchUpOutside];

回调方法

- (void)avSliderAction{
    //slider的value值为视频的时间
    float seconds = self.avSlider.value;
    //让视频从指定的CMTime对象处播放。
    CMTime startTime = CMTimeMakeWithSeconds(seconds, self.item.currentTime.timescale);
    //让视频从指定处播放
    [self.myPlayer seekToTime:startTime completionHandler:^(BOOL finished) {
        if (finished) {
            [self playAction];
        }
    }];
}

以上就是实现一个视频的播放和快进快退的方法与步骤。


2016-07-25 23:40:00 weixin_33743703 阅读数 13

需要导入系统的 AVFoundation

一、基本使用

(1).AVPlayerItem 播放对象

AVPlayerItem* item = [AVPlayerItem playerItemWithURL:_url];

根据url可以获取到播放对象

(2). AVPlayer 播放器对象

AVPlayer * player = [AVPlayerplayerWithPlayerItem:_playerItem]; 

根据item获取播放器

(3).AVPlayerLayer 播放器图层

AVPlayerLayer*playerLayer=[AVPlayerLayerplayerLayerWithPlayer:self.player];

根据播放器获取播放图层,AVPlayerLayer 是layer,需要将它添加到view的layer上面显示

[view.layer addSublayer:playerLayer]



///// 播放和暂停、播放速度//////

[player play];// 播放视频

[player pause]; // 暂停

player.rate=0.1; // 设置视频的播放速度

二、视频播放状态


(1)// 视频播放完的系统通知

[[NSNotificationCenterdefaultCenter]addObserver:selfselector:@selector(playbackFinished:)name:AVPlayerItemDidPlayToEndTimeNotificationobject:self.player.currentItem];

(2)// 跳转到那个时间

[player seekToTime:CMTimeMake(0,1)];


(3)// 时间变化

AVPlayerItem*playerItem=self.player.currentItem;

//这里设置每秒执行一次

__weaktypeof(self) weakSelf=self;//设置self的弱应用放置block循环引用

[self.player addPeriodicTimeObserverForInterval:CMTimeMake(1.0,10)queue:dispatch_get_main_queue()usingBlock:^(CMTimetime) {

// 当前时间

float current=CMTimeGetSeconds(time);

// 总得时间

float total=CMTimeGetSeconds([playerItemduration]);

//NSLog(@"当前已经播放%.2fs.",current);

}

}];

(4) // kvo 监听 视频开始状态 还有 缓冲进度

// 视频状态变化

[_playerItemaddObserver:selfforKeyPath:@"status"options:NSKeyValueObservingOptionNewcontext:nil];

// 视频缓冲

[_playerItemaddObserver:selfforKeyPath:@"loadedTimeRanges"options:NSKeyValueObservingOptionNewcontext:nil];

// 在这里 实现

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

{

if([keyPathisEqualToString:@"status"]) {

NSLog(@"%@",change);

NSIntegerne = [[changeobjectForKey:@"new"]integerValue];

if(ne ==AVPlayerStatusReadyToPlay) {

[_player play];

float total=CMTimeGetSeconds([_playerItemduration]);

}else{

}

}else{

float total=CMTimeGetSeconds([_playerItem duration]);

NSArray*array=_playerItem.loadedTimeRanges;

CMTimeRange timeRange = [array.firstObject CMTimeRangeValue];//本次缓冲时间范围

float startSeconds =CMTimeGetSeconds(timeRange.start);

float durationSeconds =CMTimeGetSeconds(timeRange.duration);

NSTimeInterval totalBuffer = startSeconds + durationSeconds;//缓冲总长度

//NSLog(@"共缓冲:%.2f",totalBuffer);

//NSLog(@" %f ~~~~~~~%f",totalBuffer,total);

}

}

}

(5)最后 加上  iOS自定义系统音量

iOS - AVPlayer (译)

阅读数 6

没有更多推荐了,返回首页