AVPlayer播放视频(本地视频,或网络视频)

https://github.com/potato512/SYAVPlayer

使用AVPlayer播放本地视频,或网络视频,需要添加AVFoundation框架。

使用AVPlayer播放视频的优势在于,开发者可以自定义视频界面。同时可以通过通知模式、观察者模式、时间观察者模式监测播放时的各种状态。

效果图


关键源码

// 导入头文件
#import "AVMoviePlayer.h"
// 定义属性
@property (nonatomic, strong) AVPlayer *player;
// 实例化
- (void)playMovie
{
    // 播放本地视频
    NSString *urlStr = [[NSBundle mainBundle] pathForResource:@"movie02" ofType:@"mov"];
    NSURL *url = [NSURL fileURLWithPath:urlStr];
    
    // 播放网络视频
//    NSString *urlStr = @"http://devimages.apple.com/iphone/samples/bipbop/gear4/prog_index.m3u8";
//    NSURL *url = [NSURL URLWithString:urlStr];
    
    if (self.player)
    {
        // 已经创建则不再创建
        return;
    }
    
    AVPlayerItem *item = [AVPlayerItem playerItemWithURL:url];
    self.player = [AVPlayer playerWithPlayerItem:item];
    AVPlayerLayer *layer = [AVPlayerLayer playerLayerWithPlayer:self.player];
    layer.frame = CGRectMake(10.0, 10.0, (self.view.bounds.size.width - 10.0 * 2), 200.0);
    [self.view.layer addSublayer:layer];
    [self.player play];
    
    // 设置KVC 播放结束
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playEndNotification:) name:AVPlayerItemDidPlayToEndTimeNotification object:nil];
    // 设置KVO
    [item addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
    // 设置每秒执行一次进度更新
    AVPlayerVC __weak *weakSelf = self;
    [self.player addPeriodicTimeObserverForInterval:CMTimeMake(1.0, 1.0) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
        float current = CMTimeGetSeconds(time);
        NSLog(@"1 current time = %.2f", current);
        
        float total = CMTimeGetSeconds([weakSelf.player.currentItem duration]);
        NSLog(@"2 total time = %.2f", total);
        
        if (current)
        {
            CGFloat progress = current / total;
            NSLog(@"3 progress = %.2f", progress);
        }
    }];
}
// 通知模式
// 视频播放完成
- (void)playEndNotification:(NSNotification *)notification
{
    NSLog(@"视频播放完成");
    [self.player seekToTime:kCMTimeZero];
}
// 观察者模式
// 通过KVO监控播放器的状态
- (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)playPause:(id)sender
{
    [self playMovie];
    if (self.player.rate == 0)
    {
        // 暂停时,继续播放
        [self.player play];
    }
    else if (self.player.rate == 1)
    {
        // 正在播放时,暂停
        [self.player pause];
    }
}








你可能感兴趣的:(iOS,多媒体)