2015-07-31 11:33:37 yangxinca 阅读数 1330

目录

  1. 导入框架
    导入

NSString *str = @"http://vmovier.qiniudn.com/559b918dbf717.mp4";
NSString *urlStr =[str stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];//链接接口中的汉字会导致请求失败
NSURL *url=[NSURL URLWithString:urlStr];
AVPlayerItem *playerItem=[AVPlayerItem playerItemWithURL:url];//主要创建方法,创建媒体资源管理对象
AVPlayer *player = [AVPlayer playerWithPlayerItem:playerItem];//根据媒体资源管理对象创建AVPlayer对象
AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:player];//AVPlayer要显示视频,必须创建一个播放器层AVPlayerLayer用于展示

(2)视频的播放、暂停功能。
这也是最基本的功能,AVPlayer对应着两个方法play、pause来实现。
[player play];//播放
[player pause];//暂停
通常我们会需要得知当前的播放状态来进行主动地改变播放状态,问题的关键是如何判断当前视频是否在播放。很不幸的是AVPlayer没有这样的状态属性,但是很幸运的是我们可以通过判断播放器的播放速度来获得播放状态。AVPlayer类包含一个极其重要的属性:

**@property (nonatomic) float rate;**

其代码注释为:/* indicates the current rate of playback; 0.0 means “stopped”, 1.0 means “play at the natural rate of the current item” */
解释为:”表示当前的播放速度;0表示“停止”,1表示“在当前的PlayerItem下以正常速率播放”。
通过监控这个属性,可以间接获取当前播放状态,获取这个属性值对于视频播放器的功能完善具有不可代替的作用。

(3)播放进度及缓存进度
MPMoviePlayerController拥有自己的进度条,AVPlayer想要要展示播放进度就没有那么简单了。视频播放器通常是使用通知来获得播放器的当前状态,媒体加载状态等,但是无论是AVPlayer还是AVPlayerItem(AVPlayer有一个属性currentItem是AVPlayerItem类型,表示当前播放的视频对象)都无法获得这些信息。当然AVPlayerItem是有通知的,但是对于获得播放状态和加载状态有用的通知只有一个:播放完成通知AVPlayerItemDidPlayToEndTimeNotification。
在播放视频时,特别是播放网络视频往往需要知道视频加载情况、缓冲情况、播放情况,这些信息可以通过KVO监控AVPlayerItem的status、loadedTimeRanges属性来获得。当AVPlayerItem的status属性为AVPlayerStatusReadyToPlay是说明正在播放,只有处于这个状态时才能获得视频时长等信息;当loadedTimeRanges的改变时(每缓冲一部分数据就会更新此属性)可以获得本次缓冲加载的视频范围(包含起始时间、本次加载时长),这样一来就可以实时获得缓冲情况。然后就是依靠AVPlayer的

- (id)addPeriodicTimeObserverForInterval:(CMTime)interval queue:(dispatch_queue_t)queue usingBlock:(void (^)(CMTime time))block

方法获得播放进度,这个方法会在设定的时间间隔内定时更新播放进度,通过time参数通知客户端。有了这些视频信息,播放进度就不成问题了,事实上通过这些信息就算是平时看到的其他播放器的缓冲进度显示以及拖动播放的功能也可以顺利的实现。

  1. 具体实现
    具体实现的效果图:
    exp_1
    exp_2

具体代码:
(注:自知自己水平有限,代码优化处理方面做的也不是太好,但是幸好实现效果勉强可以,请各位读者勿喷就好)
(1)ViewController里的调用情况:

ViewController.h文件

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

@interface ViewController : UIViewController
**//AVPlayer_S 为我自己创建的类,继承于UIView,用于承载AVPlayer**
@property (nonatomic, retain) AVPlayer_S *myVideoPlayer;
@end

ViewController.m文件

#import "ViewController.h"
@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];    
    self.view.backgroundColor = [UIColor whiteColor];

    //AVPlayer_S 为我自己创建的类,继承于UIView,用于承载AVPlayer,此处用了固定的frame,自己在使用时可以根据需要设定具体的frame
    self.myVideoPlayer = [[AVPlayer_S alloc] initWithFrame:CGRectMake(20, 60, 335, 280) videoURL:@"http://vmovier.qiniudn.com/559b918dbf717.mp4"];

    [self.view addSubview:self.myVideoPlayer];
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
@end

AVPlayer_S.h文件

 #import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#import "MBProgressHUD.h"//为视频添加缓冲时候的菊花旋转,此第三方可以再Github上下载,直接搜索MBProgressHUD即可下载使用,假如你不想用可以把与之相关的全部删除
//附加MBProgressHUD的下载地址:https://github.com/jdg/MBProgressHUD

@interface AVPlayer_S : UIView<MBProgressHUDDelegate>

@property (nonatomic, retain) AVPlayer *player;//AVPlayer对象
@property (nonatomic, retain) AVPlayerLayer *playerLayer;//视频播放器的layer层视图,若不明白为何创建,请看目录2.AVPlayer类介绍

@property (nonatomic, retain) NSString *video_url;//接收视频连接
@property (nonatomic, assign) CMTime totalTime;//记录视频总时长
@property (nonatomic, assign) BOOL hidenBar;//视频UI控件是否显示的标识
@property (nonatomic, assign) BOOL didPlay;//缓冲结束立即播放的标识
@property (nonatomic, assign) BOOL isFullScreen;//全屏状态标识
@property (nonatomic, assign) CGRect originalFrame;//记录播放器原始frame

@property (nonatomic, retain) UIImageView *backIamge;//背景图
@property (nonatomic, retain) UILabel *didTimeLabel;//显示已完成的播放时长
@property (nonatomic, retain) UILabel *totalTimeLabel;//显示视频的总播放时长
@property (nonatomic, retain) UIButton *playButton;//播放暂停按钮
@property (nonatomic, retain) UIProgressView *playProgress;//缓冲条
@property (nonatomic, retain) UISlider *playSlider;//播放进度条
@property (nonatomic, retain) UIButton *fullScreenButton;
@property (nonatomic, retain) UIView *barView;//承载上述控件的UIView
@property (nonatomic, retain) UIView *superView;//记录下全屏前的父视图,便于退出全屏后视频处在正确的位置

- (instancetype)initWithFrame:(CGRect)frame videoURL:(NSString *)url;//自定义初始化方法,只需要给定frame和视频连接即可返回一个具有该frame的承载视频播放器的UIView
- (void)removeNotification;//移除通知
- (void)removeObserverFromPlayerItem:(AVPlayerItem *)playerItem;//移除playerItem的观察者

@end

AVPlayer_S.m文件

#import "AVPlayer_S.h"
@implementation AVPlayer_S

//自定义初始化方法
- (instancetype)initWithFrame:(CGRect)frame videoURL:(NSString *)url
{
    self = [super initWithFrame:frame];
    if (self) {
        self.didPlay = NO;
        self.originalFrame = frame;
        self.hidenBar = NO;
        self.isFullScreen = NO;
        self.video_url = url;
        self.backgroundColor = [UIColor blackColor];
        [self creatView:frame];//创建UI视图
        [self createPlayer:self.originalFrame];//创建layer层,用于播放视频
        [MBProgressHUD showHUDAddedTo:self animated:YES];//添加小菊花,若不想用就删除与之相关的东西
    }

    return self;
}

- (void)createPlayer:(CGRect)frame {

    NSString *urlStr =[self.video_url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    NSURL *url=[NSURL URLWithString:urlStr];
    //开辟线程执行AVPlayerItem的创建,若不开辟线程则会占用主线程,造成视图加载完成后暂时无法对页面进行操作的卡顿现象
    dispatch_queue_t globalQueue = dispatch_get_global_queue(0, 0);
    dispatch_async(globalQueue, ^{
    //创建AVPlayerItem
         AVPlayerItem *playerItem=[AVPlayerItem playerItemWithURL:url];
        dispatch_async(dispatch_get_main_queue(), ^{
            if (playerItem) {
                if (!_player) {
                    _player = [AVPlayer playerWithPlayerItem:playerItem];
                    if (_player) {
                    //保证AVPlayer对象存在,然后再为其添加进度观察,以便获取当前播放进度
                        [self addProgressObserver];
                        //给AVPlayerItem添加监控(最重要的监控)
                        [self addObserverToPlayerItem:playerItem];
                    }
                }
            } else {
                UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"无法连接到视频资源" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];
                [alert show];
                [self removeFromSuperview];
            }

        });
    });
    //创建播放层(layer层)
    self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
    self.playerLayer.frame = CGRectMake(0, 0, frame.size.width, frame.size.height);
    [self.layer addSublayer:self.playerLayer];
}


#pragma mark - 通知
//添加通知

- (void)addNotification {
    //添加 播放结束 通知
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackFinished:) name:AVPlayerItemDidPlayToEndTimeNotification object:self.player.currentItem];
}

//移除所有通知
- (void)removeNotification {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

// 播放完成通知执行的方法:移除播放视图及小菊花假如想执行此操作可以解除注释

- (void)playbackFinished:(NSNotification *)notification {
/*
    [MBProgressHUD hideHUDForView:self animated:YES];
    [self removeFromSuperview];
*/
}

#pragma mark - 监控
// 给播放器添加进度更新

- (void)addProgressObserver {

    UISlider *slider = self.playSlider;//获取当前滑动条
    __block AVPlayer_S *av_s = self;

    //这里设置每秒执行一次
    [self.player addPeriodicTimeObserverForInterval:CMTimeMake(1.0, 10.0) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {

        float current = CMTimeGetSeconds(time);//获取当前的播放时间

        if (current) {
            [slider setValue:current animated:YES];//实时设置滑动条当前值
            int currentTime = (int)current;
            int m = currentTime / 60;
            int s = currentTime % 60;
            NSString *strM = nil;
            NSString *strS = nil;
            if (m < 10) {
                strM = [NSString stringWithFormat:@"0%d", m];
            } else {
                strM = [NSString stringWithFormat:@"%d", m];
            }
            if (s < 10) {
                strS = [NSString stringWithFormat:@"0%d", s];
            } else {
                strS = [NSString stringWithFormat:@"%d", s];
            }
            //设置UILabel视图显示当前播放时长
            av_s.didTimeLabel.text = [NSString stringWithFormat:@"%@:%@", strM, strS];
        }

    }];
}
// 给AVPlayerItem添加监控

- (void)addObserverToPlayerItem:(AVPlayerItem *)playerItem {
    //监控状态属性,注意AVPlayer也有一个status属性,通过监控它的status也可以获得播放状态
    [playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
    //监控网络加载情况属性
    [playerItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];

}

//通知移除方法
- (void)removeObserverFromPlayerItem:(AVPlayerItem *)playerItem {
    [playerItem removeObserver:self forKeyPath:@"status"];
    [playerItem removeObserver:self forKeyPath:@"loadedTimeRanges"];
}

/*
 *  通过KVO监控播放器状态
 *  @param keyPath 监控属性
 *  @param object  监视器
 *  @param change  状态改变
 *  @param context 上下文
 */
 //通知所执行的方法
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {

    AVPlayerItem *playerItem = object;//获取监控对象
    if ([keyPath isEqualToString:@"status"]) {
        //获取status值
        AVPlayerStatus status = [[change objectForKey:@"new"] intValue];
        //暂停状态
        if (status == AVPlayerStatusReadyToPlay) {
            self.totalTime = playerItem.duration;//获取视频总时长
            [self customVideoSlider:playerItem.duration];//设置播放进度最大值
            int totalTime = (int)CMTimeGetSeconds(playerItem.duration);
            int m = totalTime / 60;
            int s = totalTime % 60;
            NSString *strM = nil;
            NSString *strS = nil;
            if (m < 10) {
                strM = [NSString stringWithFormat:@"0%d", m];
            } else {
                strM = [NSString stringWithFormat:@"%d", m];
            }
            if (s < 10) {
                strS = [NSString stringWithFormat:@"0%d", s];
            } else {
                strS = [NSString stringWithFormat:@"%d", s];
            }
            //设置视频时长的UILabel视图显示值
            self.totalTimeLabel.text = [NSString stringWithFormat:@"%@:%@", strM, strS];
        }
    } else if ([keyPath isEqualToString:@"loadedTimeRanges"]) {
    //播放状态
        [self addNotification];//添加播放完成通知
        NSArray *array = playerItem.loadedTimeRanges;
        CMTimeRange timeRange = [array.firstObject CMTimeRangeValue];//本次缓冲时间范围
        float startSeconds = CMTimeGetSeconds(timeRange.start);
        float durationSeconds = CMTimeGetSeconds(timeRange.duration);
        NSTimeInterval totalBuffer = startSeconds + durationSeconds;//缓冲总长度
        //设置缓存条
        [self.playProgress setProgress:totalBuffer/CMTimeGetSeconds(self.totalTime) animated:YES];
        float currentPlayTime =  CMTimeGetSeconds([self.player currentTime]);//获取当前播放时长
        //设定当缓冲总时长超过播放时长3秒时开始播放视频
        if (totalBuffer - currentPlayTime > 3.0) {
            if (!self.didPlay) {
                [self createPlayer:self.frame];
                [self.player play];
                [MBProgressHUD hideHUDForView:self animated:YES];
                [self bringSubviewToFront:self.barView];
                [self.playButton setImage:[UIImage imageNamed:@"pause_64"] forState:UIControlStateNormal];
                self.didPlay = YES;
            }
        } else {
            [self.player pause];
            [MBProgressHUD showHUDAddedTo:self animated:YES];
            self.didPlay = NO;
            [self.playButton setImage:[UIImage imageNamed:@"play_64"] forState:UIControlStateNormal];
        }

    }
}
//播放视图的创建
- (void)creatView:(CGRect)frame {

    self.backIamge = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)];
    self.backIamge.image = [UIImage imageNamed:@"back_Image.png"];

    self.barView = [[UIView alloc] initWithFrame:CGRectMake(0, frame.size.height-40, frame.size.width, 40)];
    self.barView.backgroundColor = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:0.5];

    self.playProgress = [[UIProgressView alloc] initWithFrame:CGRectMake(50, 15, self.barView.frame.size.width-100, 10)];
    [self.playProgress setProgressTintColor:[UIColor orangeColor]];

    self.playSlider = [[UISlider alloc] initWithFrame:CGRectMake(47, 11.2, self.playProgress.frame.size.width+10, 10)];
    [self.playSlider setThumbImage:[UIImage imageNamed:@"ball_16"] forState:UIControlStateNormal];

    self.didTimeLabel = [[UILabel alloc] initWithFrame:CGRectMake(50, 25, 50, 10)];
    self.didTimeLabel.font = [UIFont systemFontOfSize:14];
    self.totalTimeLabel = [[UILabel alloc] initWithFrame:CGRectMake(self.barView.frame.size.width-100, 25, 50, 10)];
    self.totalTimeLabel.font = [UIFont systemFontOfSize:14];
    //=================
    UIGraphicsBeginImageContextWithOptions((CGSize){ 2, 2 }, NO, 0.0f);
    UIImage *transparentImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    [self.playSlider setMinimumTrackTintColor:[UIColor blueColor]];
    [self.playSlider setMaximumTrackImage:transparentImage forState:UIControlStateNormal];
    //=================
    [self.playSlider addTarget:self action:@selector(sliderAction:) forControlEvents:UIControlEventValueChanged];

    self.playButton = [UIButton buttonWithType:UIButtonTypeCustom];
    self.playButton.frame = CGRectMake(5, 5, 30, 30);
    [self.playButton addTarget:self action:@selector(playButtonAction:) forControlEvents:UIControlEventTouchUpInside];
    [self.playButton setBackgroundColor:[UIColor clearColor]];
    [self.playButton setImage:[UIImage imageNamed:@"play_64.png"] forState:UIControlStateNormal];

    self.fullScreenButton = [UIButton buttonWithType:UIButtonTypeCustom];
    self.fullScreenButton.frame = CGRectMake(self.barView.frame.size.width - 40, 5, 30, 30);
    [self.fullScreenButton addTarget:self action:@selector(fullScreenButtonAction:) forControlEvents:UIControlEventTouchUpInside];
    [self.fullScreenButton setBackgroundColor:[UIColor clearColor]];
    [self.fullScreenButton setImage:[UIImage imageNamed:@"fullScreen_64.png"] forState:UIControlStateNormal];

    [self.barView addSubview:self.playButton];
    [self.barView addSubview:self.playProgress];
    [self.barView addSubview:self.playSlider];
    [self.barView addSubview:self.didTimeLabel];
    [self.barView addSubview:self.totalTimeLabel];
    [self.barView addSubview:self.fullScreenButton];
    [self addSubview:self.barView];

    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction:)];
    [self addGestureRecognizer:tap];
}

- (void)tapAction:(UITapGestureRecognizer *)tap {

    if (self.hidenBar) {
        self.hidenBar = NO;
        [self bringSubviewToFront:self.barView];
    } else {
        self.hidenBar = YES;
    }
    self.barView.hidden = self.hidenBar;
}

- (void)playButtonAction:(UIButton *)button
{
    NSLog(@"%f", self.player.rate);
    if(self.player.rate == 0){ //说明是暂停
        [button setImage:[UIImage imageNamed:@"pause_64"] forState:UIControlStateNormal];
        self.backIamge.hidden = YES;
        if (self.didPlay) {
            [self.player play];
        }
    }else if(self.player.rate == 1){//正在播放
        [self.player pause];
        [button setImage:[UIImage imageNamed:@"play_64"] forState:UIControlStateNormal];
    }
}

//全屏设置
- (void)fullScreenButtonAction:(UIButton *)button {

    if (self.isFullScreen) {
        self.isFullScreen = NO;
        [self.fullScreenButton setImage:[UIImage imageNamed:@"fullScreen_64.png"] forState:UIControlStateNormal];

        [UIView animateWithDuration:0.2 animations:^{

            self.transform = CGAffineTransformRotate(self.transform, -M_PI_2);

            self.frame = self.originalFrame;
            [self.playerLayer removeFromSuperlayer];
            [self createPlayer:self.originalFrame];

            self.barView.frame = CGRectMake(0, self.originalFrame.size.height-40, self.originalFrame.size.width, 40);
            [self bringSubviewToFront:self.barView];

            self.center = CGPointMake(self.originalFrame.origin.x + self.originalFrame.size.width/2.0, self.originalFrame.origin.y + self.originalFrame.size.height/2.0);

            self.backIamge.frame = CGRectMake(0, 0, self.originalFrame.size.width, self.originalFrame.size.height);
            self.playProgress.frame = CGRectMake(50, 15, self.barView.frame.size.width-100, 10);
            self.playSlider.frame = CGRectMake(45, 11, self.playProgress.frame.size.width+10, 10);
            self.playButton.frame = CGRectMake(5, 5, 30, 30);
            self.fullScreenButton.frame = CGRectMake(self.barView.frame.size.width - 40, 5, 30, 30);

            [self.superView addSubview:self];
        }];

    } else {
        self.isFullScreen = YES;
        self.superView = self.superview;

        [self.fullScreenButton setImage:[UIImage imageNamed:@"exitFullScreen_64.png"] forState:UIControlStateNormal];
        [self.window addSubview:self];
        [self.window bringSubviewToFront:self];

        [UIView animateWithDuration:0.2 animations:^{
            self.frame = CGRectMake(20, 0, [UIScreen mainScreen].bounds.size.height-20, [UIScreen mainScreen].bounds.size.width);
            [self.playerLayer removeFromSuperlayer];

            [self createPlayer:self.frame];

            self.barView.frame = CGRectMake(0, [UIScreen mainScreen].bounds.size.width-40, [UIScreen mainScreen].bounds.size.height-20, 40);
            [self bringSubviewToFront:self.barView];
            self.backIamge.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.height-20, [UIScreen mainScreen].bounds.size.width);

            self.transform = CGAffineTransformRotate(self.transform, M_PI_2);
            self.center = CGPointMake([UIScreen mainScreen].bounds.size.width/2.0, ([UIScreen mainScreen].bounds.size.height+20)/2.0);
            self.playProgress.frame = CGRectMake(50, 15, self.barView.frame.size.width-100, 10);
            self.playSlider.frame = CGRectMake(45, 11, self.playProgress.frame.size.width+10, 10);
            self.playButton.frame = CGRectMake(5, 5, 30, 30);
            self.fullScreenButton.frame = CGRectMake(self.barView.frame.size.width - 40, 5, 30, 30);
            self.totalTimeLabel.frame = CGRectMake(self.barView.frame.size.width-100, 25, 50, 10);
        }];

    }
}

//UISlider基本设置
- (void)customVideoSlider:(CMTime)duration {

    self.playSlider.maximumValue = CMTimeGetSeconds(duration);
    self.playSlider.minimumValue = 0.0;
}

//拖动进度条到任何位置播放
- (void)sliderAction:(UISlider *)slider {

    if (self.player.rate == 0) {
        [self.player seekToTime:CMTimeMake((int)slider.value*10, 10.0)];
        [self.player play];
        [self.playButton setImage:[UIImage imageNamed:@"pause_64.png"] forState:UIControlStateNormal];
    } else if(self.player.rate == 1) {
        [self.player pause];
        [self.player seekToTime:CMTimeMake((int)slider.value*10, 10.0)];
        [self.player play];
        [self.playButton setImage:[UIImage imageNamed:@"pause_64.png"] forState:UIControlStateNormal];
    }
}

@end

Demo :http://download.csdn.net/detail/yangxinca/8949003

2015-11-06 16:58:14 MyCSDN_FanJinxin 阅读数 6317

首先需要创建AVPlayer  这时候要先包含头文件,因为是9.0了,所以不用包含库,直接导入头文件即可

#import <AVFoundation/AVFoundation.h>

在这里可以把播放器作为成员变量,方便全局使用,当然,也可以不用,我在这里是作为全局变量来使用的,方便内存的管理

@property (nonatomic,strong) AVPlayer *player;//视频播放
@property (nonatomic,strong)AVPlayerLayer *playerLayer;

接着就是创建了

//创建视频播放器
NSString *filePath =[[NSBundle mainBundle]pathForResource:@"flash" ofType:@"mp4"];
NSURL *sourceMovieURL = [NSURL fileURLWithPath:filePath];
//初学者这里先不要管,但是必须要创建
AVAsset *movieAsset    = [AVURLAsset URLAssetWithURL:sourceMovieURL options:nil];        
AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:movieAsset];
_player = [AVPlayer playerWithPlayerItem:playerItem];
_playerLayer = [AVPlayerLayer playerLayerWithPlayer:_player];
//大小
_playerLayer.frame = CGRectMake(ScreenWidth/4.4, ScreenHeight/3.3, _coverView.pictureAndAvView.frame.size.width, _coverView.pictureAndAvView.frame.size.height+100);
_playerLayer.videoGravity = AVLayerVideoGravityResizeAspect;
_playerLayer.backgroundColor  = [UIColor blackColor].CGColor;
//要添加的地方
[_coverView.AirBubble.layer addSublayer:_playerLayer];
[_player play];            



用完是需要注意要对其进行释放:写在你退出的点击事件当中,比如说要pop视图了

[self.playerLayer removeFromSuperlayer];
self.playerLayer=nil;   
self.player=nil;


搞定!


2016-05-23 16:57:46 u013282507 阅读数 5016

*说明:利用AVPlayer可以制作视频播放器、音频播放器;使用AVPlayer播放过的格式有 .mp4  .m3u8   .mp3

1、创建播放器:

_player = [[AVPlayer alloc] initWithPlayerItem:[AVPlayerItem playerItemWithURL:[NSURL URLWithString:@""]]];

2、切换播放地址

    AVPlayerItem *item = [AVPlayerItem playerItemWithURL:mediaUrl];
    [_player replaceCurrentItemWithPlayerItem:item];

3、跳转进度, 参数second秒

    CMTime changedTime = CMTimeMakeWithSeconds(second, 1);
    [_player seekToTime:changedTime completionHandler:^(BOOL finished) {
    }];

4、改变播放速率 0.5为正常速度的一半 默认rate是1 

    [_player setRate:0.5];

5、暂停/继续

    [_player pause];
    [_player play];

6、播放时间(单位:秒)

    CGFloat currentPlayTime =_player.currentItem.currentTime.value/_player.currentItem.currentTime.timescale;

7、缓冲时间

    NSArray *loadedTimeRanges = [[_player currentItem] loadedTimeRanges];
    CMTimeRange timeRange = [loadedTimeRanges.firstObject CMTimeRangeValue];//获取缓冲区域
    float startSeconds = CMTimeGetSeconds(timeRange.start);
    float durationSeconds = CMTimeGetSeconds(timeRange.duration);
    NSTimeInterval result = startSeconds + durationSeconds;//计算缓冲总进度
2016-12-07 15:42:53 u011315300 阅读数 2038

## AVPlayer的简单使用 ##
自己写得并不好(刚学swift,语法可能有点奇怪,偏向OC),只是试试看能不能有什么帮助吧。。。没有的话,下次努力
1.导入系统头文件 AVFoundation
2*.创建界面UI*
3.播放功能实现

在此要向各位推荐一下b站开源项目ijkplayer 。目前本人用得就是此开源框架,它是对ffmpeg的封装,能满足直播(拉流用ijkplayer即可,推流可以用来疯框架 LFLiveKit)以及视频播放功能,

这里是一些重要的代码片段

系统自带的avplayer的创建初始化

 //创建player
    *fileprivate func createPlayer() {
        playerItem = AVPlayerItem.init(url: NSURL.init(string: "http://krtv.qiniudn.com/150522nextapp") as! URL)
        playerItem.addObserver(self, forKeyPath: "loadedTimeRanges", options: .new, context: nil)
        player = AVPlayer.init(playerItem: playerItem)
        let playerLayer = AVPlayerLayer.init(player: player)
        playerLayer.frame = CGRect.init(x: 0, y: 0, width: screenW, height: screenH)
        playerLayer.videoGravity = AVLayerVideoGravityResize
        self.view.layer.addSublayer(playerLayer)
        player.play()

        addTimer()*

    }

下一个视频的实现。有兴趣可以试试只换url会产生什么效果.

//下一曲,这里应该重新创建  AVPlayerItem
    func nextVideo()  {
        //        player = nil
        player.pause()
        removeTimer()
        playerItem.removeObserver(self, forKeyPath: "loadedTimeRanges", context: nil)
        playerItem = nil
        //        player = nil
        let playerI = AVPlayerItem.init(url: NSURL.init(string: "http://wvideo.spriteapp.cn/video/2016/0328/56f8ec01d9bfe_wpd.mp4") as! URL)
        //
        player.replaceCurrentItem(with: playerI)

        //        let play = AVPlayer.init(playerItem: playerI)
        //        player = play
        playerItem = playerI
        playerItem.addObserver(self, forKeyPath: "loadedTimeRanges", options: .new, context: nil)
        player.play()
        addTimer()
    }

进度条,用观察者模式实现

func progressSliderValueChange()  {
        //        拖动改变视频播放进度
        if player.status == .readyToPlay {
            let total = Float(playerItem.duration.value/Int64(playerItem.duration.timescale))
            let dragedSeconds = floorf(total * progressSlider.value)

            let dragedCMTime = CMTime.init(value: CMTimeValue(dragedSeconds), timescale: 1)
            player.pause()
            removeTimer()
            player.seek(to: dragedCMTime, completionHandler: { (finish) in
                if finish  {
                    self.player.play()
                    self.addTimer()
                }
            })

        }
    }
    // 观察者模式 进行进度条的改变
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        if keyPath == "loadedTimeRanges" {
            //            let timeinterval = self.availableDuration()//缓冲速度
            let duration = playerItem.duration
            let total = CMTimeGetSeconds(duration)
            progress.setProgress(Float(total), animated: false)
        }

    }

下面是计算时间的方法,可以不看,相信有很多大神比我写的好

 func availableDuration() -> TimeInterval{
        let loadedTimeRanges = player.currentItem?.loadedTimeRanges
        let timeRange = loadedTimeRanges?.first?.timeRangeValue as CMTimeRange?
        let startSeconds = CMTimeGetSeconds(timeRange!.start)
        let durationSeconds = CMTimeGetSeconds(timeRange!.duration)
        let result = (startSeconds + durationSeconds)
        return result

    }
    //计算时间的方法
    func timerProgress()  {
        if playerItem.duration.timescale != 0 {
            progressSlider.maximumValue = 1.0
            let total = Float(playerItem.duration.value/Int64(playerItem.duration.timescale))
            progressSlider.value = Float(CMTimeGetSeconds(playerItem.currentTime()))/total
            let promin = NSInteger(CMTimeGetSeconds(playerItem.currentTime()))/60//当前秒
            let prosec = NSInteger(CMTimeGetSeconds(playerItem.currentTime()))%60//当前分

            let durmin = NSInteger(total)/60
            let dursec = NSInteger(total)%60

            let leftmin = durmin - promin
            let leftsec = dursec - prosec


            timeLable.text = NSString.init(format: "%02ld:%02ld", promin,prosec,durmin,dursec) as String

            leftLable.text = NSString.init(format: "-%02ld:%02ld", leftmin,leftsec) as String

        }
    }

Demo 的 github 地址 : https://github.com/aasdsjk/AVPlayer
avplayer的简单使用大概就是这样的了,项目中用的是第三方。。。这个是自己有空写的一个简单的demo
有兴趣的可以看一看

另外推荐一个自己写的弹出自定义视图的工具,支持pod 给个Star

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