当前位置:   article > 正文

AVPlayer进行视频播放_av視屏观看

av視屏观看

一、说明

AVPlayer是AVFoundation框架中的一个类,它比较接近于底层,可以利用该类进行自定义样式的视频播放。AVPlayer本身并不能显示视频,如果AVPlayer要显示视频,则它必须要创建一个播放器层AVPlayerLayer来用于展示视频,播放器层继承了CALayer,我们只需要把AVPlayerLayer添加到控制器view的layer中即可。我们在了解AVPlayer之前,首先需要了解以下几个常用类:
AVAsset : 用于获取多媒体信息,是一个抽象类。
AVURLAsset : 媒体资源管理类,管理视频的一些基本信息和状态,一个AVPlayerItem对应着一个视频资源。

eg:一个视频播放的例子
这里写图片描述

//
//  ViewController.m
//  AVPlayerDemo
//

#import "ViewController.h"
#import <AVFoundation/AVFoundation.h>
@interface ViewController ()
@property (nonatomic,strong) AVPlayer *player;  // 播放器对象
@property (nonatomic,strong) AVPlayerLayer *playerLayer;

@property (weak, nonatomic) IBOutlet UIView *container;
@property (weak, nonatomic) IBOutlet UIButton *playOrPause;
@property (weak, nonatomic) IBOutlet UIProgressView *progress;

@end

@implementation ViewController

- (AVPlayer *)player
{
    if (!_player) {
        AVPlayerItem *playerItem = [self getPlayItem:1];
        _player = [AVPlayer playerWithPlayerItem:playerItem];
        [self addProgressObserver];
        [self addobserToPlayerItem:playerItem];
        [self addNotification];
    }
    return _player;
}

- (AVPlayerLayer *)playerLayer
{
    if (!_playerLayer) {
        _playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
        _playerLayer.frame = self.container.bounds;
    }
    return _playerLayer;
}

- (void)setupUI
{
    AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
    playerLayer.frame = self.container.bounds;
    [self.container.layer addSublayer:playerLayer];

    [self.playOrPause setTitle:@"Pause" forState:UIControlStateNormal];
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // 创建播放器层
    [self setupUI];
    [self.player play];
}

#pragma mark -UI事件
- (IBAction)playClick:(UIButton *)btn {
    if (self.player.rate == 0)  // 如果当前是暂停状态
    {
        [btn setTitle:@"Pause" forState:UIControlStateNormal];
        [self.player seekToTime:CMTimeMake(playCurrent, 1.0)];
        [self.player play];
    }
    if (self.player.rate == 1)  // 如果当前是正在播放状态
    {
        [self.player pause];
        [btn setTitle:@"Play" forState:UIControlStateNormal];
    }
}

- (IBAction)navigationButtonClick:(UIButton *)sender {
        [self removeNotification];
        [self removeObserverFromPlayerItem:self.player.currentItem];
        AVPlayerItem *playerItem = [self getPlayItem:(int)sender.tag];
        [self addobserToPlayerItem:playerItem];
        // 切换视频
        [self.player replaceCurrentItemWithPlayerItem:playerItem];
        [self initUI];
        [self addNotification];

}

- (void)initUI
{
    [self.progress setProgress:0.0];
    [self.playOrPause setTitle:@"Pause" forState:UIControlStateNormal];
    [self.player seekToTime:CMTimeMake(0, 1)];
}



- (AVPlayerItem *)getPlayItem:(int)videoIndex
{
    NSURL *url = [[NSURL alloc] initFileURLWithPath:[[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"%i",videoIndex] ofType:@"mp4"]];
    AVPlayerItem *playerItem = [AVPlayerItem playerItemWithURL:url];
    return playerItem;
}

- (void)playbackFinished:(NSNotification *)notification
{
    [self.player seekToTime:CMTimeMake(0, 1)];  // 视频播放完成以后,从新设置到起点
    NSLog(@"视频播放完成");
    [self removeNotification];
}

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

-(void)removeNotification{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

static float playCurrent = 0;

- (void)addProgressObserver
{
    AVPlayerItem *playerItem = self.player.currentItem;
    UIProgressView *progress = self.progress;

    // 设置每秒执行一次
    [self.player addPeriodicTimeObserverForInterval:CMTimeMake(1.0, 1.0) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
        float current = CMTimeGetSeconds(time);

        playCurrent = current;

        float total = CMTimeGetSeconds([playerItem duration]);
        NSLog(@"当前已经播放了%.2fs",current);
        if (current) {
            [progress setProgress:(current/total) animated:YES];
        }
    }];
}

// 为AVPlayerItem添加监控
- (void)addobserToPlayerItem:(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"]) {
        AVPlayerStatus status = [[change objectForKey:@"new"] intValue];
        if (status == AVPlayerStatusReadyToPlay) {
            NSLog(@"正在播放...视频总长度:%.2f",CMTimeGetSeconds(playerItem.duration));
        }
    }else if([keyPath isEqualToString:@"loadedTimeRanges"]){
        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);
    }
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
@end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/138760
推荐阅读
相关标签
  

闽ICP备14008679号